From: Ander Conselvan de Oliveira <ander.conselvan.de.olive...@intel.com>
The DRI image extension gained a lot of new entry points lately. Some of the new additions have a slightly different signature. The planar image introduces the concept of an image without a format from which different well structured images can be created. The way this has been done means that one can't aways rely on all of the fields in a __DRIimage to be valid or useable. This patch tries to make the whole implementation more consistent. All images become planar with a valid intel_image_format. The dri_image and gl_format fields are dropped, and when creating an image from a texture or renderbuffer, a custom intel_image_format is allocated to match that of the original object. Every image has at least one plane and a field inside the image tells to which plane that particular image refers to. For allocating the image, both DRI_FORMAT_* and DRI_FOURCC_* were used. Now the allocation code always takes fourcc and the extension entry points convert from dri format when necessary. Also, intel_image_format now holds a regular gl_format, so dri_format is not used internally anymore. The bulk of the image code is moved to a separate file and the part in intel_screen.c only does some parameter conversion and calls into the other file. --- src/mesa/drivers/dri/i965/Makefile.sources | 1 + src/mesa/drivers/dri/i965/intel_fbo.c | 11 +- src/mesa/drivers/dri/i965/intel_image.c | 390 ++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_image.h | 73 +++++ src/mesa/drivers/dri/i965/intel_regions.h | 9 +- src/mesa/drivers/dri/i965/intel_screen.c | 427 +++++---------------------- src/mesa/drivers/dri/i965/intel_tex_image.c | 8 +- 7 files changed, 559 insertions(+), 360 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/intel_image.c create mode 100644 src/mesa/drivers/dri/i965/intel_image.h diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 5724458..abd9890 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -10,6 +10,7 @@ i965_FILES = \ intel_debug.c \ intel_extensions.c \ intel_fbo.c \ + intel_image.c \ intel_mipmap_tree.c \ intel_regions.c \ intel_resolve_map.c \ diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c index ae978f1..87c3b33 100644 --- a/src/mesa/drivers/dri/i965/intel_fbo.c +++ b/src/mesa/drivers/dri/i965/intel_fbo.c @@ -254,6 +254,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, struct intel_renderbuffer *irb; __DRIscreen *screen; __DRIimage *image; + gl_format format; screen = brw->intelScreen->driScrnPriv; image = screen->dri2.image->lookupEGLImage(screen, image_handle, @@ -261,7 +262,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, if (image == NULL) return; - if (image->planar_format && image->planar_format->nplanes > 1) { + if (image->format->nplanes > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetRenderbufferStorage(planar buffers are not " "supported as render targets."); @@ -276,7 +277,9 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, } /* __DRIimage is opaque to the core so it has to be checked here */ - switch (image->format) { + format = image->format->planes[0].format; + + switch (format) { case MESA_FORMAT_RGBA8888_REV: _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetRenderbufferStorage(unsupported image format"); @@ -290,7 +293,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, intel_miptree_release(&irb->mt); irb->mt = intel_miptree_create_for_bo(brw, image->region->bo, - image->format, + format, image->region->offset, image->region->width, image->region->height, @@ -302,7 +305,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, rb->InternalFormat = image->internal_format; rb->Width = image->region->width; rb->Height = image->region->height; - rb->Format = image->format; + rb->Format = format; rb->_BaseFormat = _mesa_base_fbo_format(ctx, image->internal_format); rb->NeedsFinishRenderTexture = true; } diff --git a/src/mesa/drivers/dri/i965/intel_image.c b/src/mesa/drivers/dri/i965/intel_image.c new file mode 100644 index 0000000..cb258cf --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_image.c @@ -0,0 +1,390 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "main/formats.h" +#include "main/macros.h" + +#include "dri_util.h" + +#include "intel_image.h" +#include "intel_regions.h" + +#include "i915_drm.h" + +static struct intel_image_format intel_image_formats[] = { + { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1, + { { 0, 0, 0, MESA_FORMAT_ARGB8888, 4 } } }, + + { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1, + { { 0, 0, 0, MESA_FORMAT_XRGB8888, 4 }, } }, + + { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_COMPONENTS_RGBA, 1, + { { 0, 0, 0, MESA_FORMAT_RGBA8888_REV, 4 } } }, + + { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_COMPONENTS_RGB, 1, + { { 0, 0, 0, MESA_FORMAT_RGBX8888_REV, 4 }, } }, + + { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1, + { { 0, 0, 0, MESA_FORMAT_RGB565, 2 } } }, + + { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 2, 2, MESA_FORMAT_R8, 1 }, + { 2, 2, 2, MESA_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 2, 0, MESA_FORMAT_R8, 1 }, + { 2, 2, 0, MESA_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 1, 1, MESA_FORMAT_R8, 1 }, + { 2, 1, 1, MESA_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 1, 0, MESA_FORMAT_R8, 1 }, + { 2, 1, 0, MESA_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 0, 0, MESA_FORMAT_R8, 1 }, + { 2, 0, 0, MESA_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 1, 1, MESA_FORMAT_GR88, 2 } } }, + + { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2, + { { 0, 0, 0, MESA_FORMAT_R8, 1 }, + { 1, 1, 0, MESA_FORMAT_GR88, 2 } } }, + + /* For YUYV buffers, we set up two overlapping DRI images and treat + * them as planar buffers in the compositors. Plane 0 is GR88 and + * samples YU or YV pairs and places Y into the R component, while + * plane 1 is ARGB and samples YUYV clusters and places pairs and + * places U into the G component and V into A. This lets the + * texture sampler interpolate the Y components correctly when + * sampling from plane 0, and interpolate U and V correctly when + * sampling from plane 1. */ + { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2, + { { 0, 0, 0, MESA_FORMAT_GR88, 2 }, + { 0, 1, 0, MESA_FORMAT_ARGB8888, 4 } } } +}; + +int +dri_format_to_fourcc(int dri_format) +{ + switch (dri_format) { + case __DRI_IMAGE_FORMAT_RGB565: + return __DRI_IMAGE_FOURCC_RGB565; + case __DRI_IMAGE_FORMAT_XRGB8888: + return __DRI_IMAGE_FOURCC_XRGB8888; + case __DRI_IMAGE_FORMAT_ARGB8888: + return __DRI_IMAGE_FOURCC_ARGB8888; + case __DRI_IMAGE_FORMAT_ABGR8888: + return __DRI_IMAGE_FOURCC_ABGR8888; + case __DRI_IMAGE_FORMAT_XBGR8888: + return __DRI_IMAGE_FOURCC_XBGR8888; + default: + return 0; + } +} + +struct intel_image_format * +intel_image_format_lookup(int fourcc) +{ + struct intel_image_format *f = NULL; + + for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) { + if (intel_image_formats[i].fourcc == fourcc) { + f = &intel_image_formats[i]; + break; + } + } + + return f; +} + +void +intel_image_destroy(intel_image_t *image) +{ + intel_region_release(&image->region); + + if (image->format->fourcc == 0) + free(image->format); + + free(image); +} + +void +intel_image_set_gl_format(intel_image_t *image, + GLenum internal_format, GLuint gl_format) +{ + struct intel_image_format *f = image->format; + + if (f->fourcc != 0) { + _mesa_warning(NULL, "intel_image_set_gl_format: " + "image already has a format, skipping"); + return; + } + + memset(f, 0, sizeof *f); + + switch (internal_format) { + case GL_RGB: + f->components = __DRI_IMAGE_COMPONENTS_RGB; + break; + case GL_RGBA: + f->components = __DRI_IMAGE_COMPONENTS_RGBA; + break; + default: + f->components = 0; + } + + f->nplanes = 1; + f->planes[0].format = gl_format; + + image->internal_format = internal_format; +} + +intel_image_t * +intel_image_create_from_region(int fourcc, struct intel_region *region, + int *strides, int *offsets, int plane) +{ + intel_image_t *image; + struct intel_image_format *f; + int i, index; + gl_format format; + + if (fourcc != 0) + f = intel_image_format_lookup(fourcc); + else + f = calloc(1, sizeof *f); + + if (f == NULL) + return NULL; + + image = calloc(1, sizeof *image); + if (image == NULL) + return NULL; + + image->region = region; + image->format = f; + image->plane = plane; + + format = f->planes[plane].format; + image->internal_format = _mesa_get_format_base_format(format); + + for (i = 0; i < f->nplanes; i++) { + index = f->planes[i].buffer_index; + image->offsets[index] = offsets[index]; + image->strides[index] = strides[index]; + } + + return image; +} + +static uint32_t +choose_tiling(int use) +{ + uint32_t tiling; + + tiling = I915_TILING_X; + + if (use & __DRI_IMAGE_USE_LINEAR) + tiling = I915_TILING_NONE; + + return tiling; +} + +int +intel_image_validate_usage(intel_image_t *image, int use) +{ + if (use & __DRI_IMAGE_USE_CURSOR) { + if (image->region->width != 64 || image->region->height != 64) + return GL_FALSE; + } + + return GL_TRUE; +} + +intel_image_t * +intel_image_create(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, int use) +{ + intel_image_t *image; + struct intel_region *region; + struct intel_image_format *f = intel_image_format_lookup(fourcc); + uint32_t tiling = choose_tiling(use); + int stride, offset; + + if (f == NULL || f->nplanes != 1) + return NULL; + + region = intel_region_alloc(bufmgr, tiling, f->planes[0].cpp, + width, height, true); + if (!region) + return NULL; + + stride = region->pitch; + offset = region->offset; + + image = intel_image_create_from_region(fourcc, region, + &stride, &offset, 0); + if (!image) { + intel_region_release(®ion); + return NULL; + } + + if (!intel_image_validate_usage(image, use)) { + intel_image_destroy(image); + return NULL; + } + + return image; +} + +intel_image_t * +intel_image_create_from_names(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, + int *names, int num_names, + int *strides, int *offsets) +{ + intel_image_t *image; + struct intel_region *region; + struct intel_image_format *f = intel_image_format_lookup(fourcc); + + if (f == NULL || names == NULL || num_names != 1) + return NULL; + + region = + intel_region_alloc_for_handle(bufmgr, f->planes[0].cpp, width, height, + strides[0] * f->planes[0].cpp, names[0], + "image"); + if (!region) + return NULL; + + image = intel_image_create_from_region(fourcc, region, + strides, offsets, 0); + if (!image) { + intel_region_release(®ion); + return NULL; + } + + return image; +} + +intel_image_t * +intel_image_create_from_fds(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, + int *fds, int num_fds, + int *strides, int *offsets) +{ + intel_image_t *image; + struct intel_region *region; + struct intel_image_format *f = intel_image_format_lookup(fourcc); + + if (f == NULL || fds == NULL || num_fds != 1) + return NULL; + + region = intel_region_alloc_for_fd(bufmgr, f->planes[0].cpp, width, height, + strides[0], height * strides[0], fds[0], + "image"); + if (!region) + return NULL; + + image = intel_image_create_from_region(fourcc, region, + strides, offsets, 0); + if (!image) { + intel_region_release(®ion); + return NULL; + } + + return image; +} + +intel_image_t * +intel_image_dup(intel_image_t *orig_image) +{ + intel_image_t *image; + + image = calloc(1, sizeof *image); + if (image == NULL) + return NULL; + + intel_region_reference(&image->region, orig_image->region); + if (image->region == NULL) { + free(image); + return NULL; + } + + memcpy(image, orig_image, sizeof *image); + + return image; +} + +intel_image_t * +intel_image_create_from_plane(intel_image_t *parent, int plane) +{ + intel_image_t *image; + struct intel_region *region; + struct intel_image_format *f = parent->format; + int width, height, offset, stride, index, cpp; + uint32_t mask_x, mask_y; + gl_format format; + + if (plane >= f->nplanes) + return NULL; + + width = parent->region->width >> f->planes[plane].width_shift; + height = parent->region->height >> f->planes[plane].height_shift; + index = f->planes[plane].buffer_index; + offset = parent->offsets[index]; + stride = parent->strides[index]; + + format = f->planes[plane].format; + cpp = _mesa_get_format_bytes(format); + + region = intel_region_alloc_subregion(parent->region, cpp, width, height, + stride, offset, 0, 0); + if (region == NULL) + return NULL; + + image = intel_image_create_from_region(f->fourcc, region, + (int *) parent->strides, + (int *) parent->offsets, + plane); + if (image == NULL) { + intel_region_release(®ion); + return NULL; + } + + intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false); + if (offset & mask_x) + _mesa_warning(NULL, + "intel_create_sub_image: offset not on tile boundary"); + + return image; +} diff --git a/src/mesa/drivers/dri/i965/intel_image.h b/src/mesa/drivers/dri/i965/intel_image.h new file mode 100644 index 0000000..0429830 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_image.h @@ -0,0 +1,73 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef INTEL_IMAGE_H +#define INTEL_IMAGE_H + +#include "intel_regions.h" + +typedef __DRIimage intel_image_t; + +int +dri_format_to_fourcc(int dri_format); + +struct intel_image_format * +intel_image_format_lookup(int fourcc); + +void +intel_image_set_gl_format(intel_image_t *image, + GLenum internal_format, GLuint gl_format); +void +intel_image_destroy(intel_image_t *image); + +int +intel_image_validate_usage(intel_image_t *image, int use); + +intel_image_t * +intel_image_create_from_region(int fourcc, struct intel_region *region, + int *strides, int *offsets, int plane); + +intel_image_t * +intel_image_create(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, int use); + +intel_image_t * +intel_image_create_from_names(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, + int *names, int num_names, + int *strides, int *offsets); + +intel_image_t * +intel_image_create_from_fds(drm_intel_bufmgr *bufmgr, + int width, int height, int fourcc, + int *fds, int num_fds, + int *strides, int *offsets); + +intel_image_t * +intel_image_dup(intel_image_t *orig_image); + +intel_image_t * +intel_image_create_from_plane(intel_image_t *parent, int plane); + +#endif /* INTEL_IMAGE_H */ diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 9ab5ce8..396aa46 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -134,16 +134,16 @@ struct intel_image_format { int buffer_index; int width_shift; int height_shift; - uint32_t dri_format; + GLuint format; int cpp; } planes[3]; }; struct __DRIimageRec { struct intel_region *region; + struct intel_image_format *format; GLenum internal_format; - uint32_t dri_format; - GLuint format; + int plane; /* * Need to save these here between calls to @@ -151,7 +151,6 @@ struct __DRIimageRec { */ uint32_t strides[3]; uint32_t offsets[3]; - struct intel_image_format *planar_format; /* particular miptree level */ bool has_depthstencil; @@ -168,8 +167,6 @@ struct __DRIimageRec { enum __DRISampleRange sample_range; enum __DRIChromaSiting horizontal_siting; enum __DRIChromaSiting vertical_siting; - - void *data; }; #ifdef __cplusplus diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index fe412b5..0019b8c 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -96,6 +96,7 @@ DRI_CONF_END #include "intel_bufmgr.h" #include "intel_chipset.h" #include "intel_fbo.h" +#include "intel_image.h" #include "intel_mipmap_tree.h" #include "intel_screen.h" #include "intel_tex.h" @@ -216,108 +217,62 @@ static const struct __DRI2flushExtensionRec intelFlushExtension = { .flush_with_flags = intel_dri2_flush_with_flags, }; -static struct intel_image_format intel_image_formats[] = { - { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }, - - { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } }, - - { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } }, - - { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 }, - { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } }, - - { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, - - { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 }, - { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } }, - - { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, - - { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, - - { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } }, - - { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, - { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } }, - - /* For YUYV buffers, we set up two overlapping DRI images and treat - * them as planar buffers in the compositors. Plane 0 is GR88 and - * samples YU or YV pairs and places Y into the R component, while - * plane 1 is ARGB and samples YUYV clusters and places pairs and - * places U into the G component and V into A. This lets the - * texture sampler interpolate the Y components correctly when - * sampling from plane 0, and interpolate U and V correctly when - * sampling from plane 1. */ - { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2, - { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, - { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } } -}; - -static struct intel_image_format * -intel_image_format_lookup(int fourcc) +static __DRIimage * +intel_dri_image_create_from_name(__DRIscreen *screen, + int width, int height, int format, + int name, int pitch, void *loaderPrivate) { - struct intel_image_format *f = NULL; - - for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) { - if (intel_image_formats[i].fourcc == fourcc) { - f = &intel_image_formats[i]; - break; - } - } + struct intel_screen *intelScreen = screen->driverPrivate; + int fourcc = dri_format_to_fourcc(format); + int offset = 0; - return f; + return intel_image_create_from_names(intelScreen->bufmgr, width, height, + fourcc, &name, 1, &pitch, &offset); } static __DRIimage * -intel_allocate_image(int dri_format, void *loaderPrivate) +intel_dri_image_create_from_renderbuffer(__DRIcontext *context, + int renderbuffer, + void *loaderPrivate) { - __DRIimage *image; + __DRIimage *image; + struct intel_region *region = NULL; + struct brw_context *brw = context->driverPrivate; + struct gl_context *ctx = &brw->ctx; + struct gl_renderbuffer *rb; + struct intel_renderbuffer *irb; + int stride, offset; + + rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); + if (!rb) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA"); + return NULL; + } - image = calloc(1, sizeof *image); - if (image == NULL) - return NULL; + irb = intel_renderbuffer(rb); + intel_miptree_make_shareable(brw, irb->mt); + intel_region_reference(®ion, irb->mt->region); - image->dri_format = dri_format; + stride = region->pitch; + offset = 0; - image->format = driImageFormatToGLFormat(dri_format); - if (dri_format != __DRI_IMAGE_FORMAT_NONE && - image->format == MESA_FORMAT_NONE) { - free(image); - return NULL; - } + image = intel_image_create_from_region(0, region, &stride, &offset, 0); + if (image == NULL) { + intel_region_release(®ion); + return NULL; + } - image->internal_format = _mesa_get_format_base_format(image->format); - image->data = loaderPrivate; + intel_image_set_gl_format(image, rb->InternalFormat, rb->Format); + image->has_depthstencil = irb->mt->stencil_mt? true : false; - return image; + rb->NeedsFinishRenderTexture = true; + return image; } -/** - * Sets up a DRIImage structure to point to our shared image in a region - */ -static void -intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image, - struct intel_mipmap_tree *mt, GLuint level, - GLuint zoffset) +static struct intel_region * +intel_region_alloc_from_mipmap_tree(struct brw_context *brw, + struct intel_mipmap_tree *mt, GLuint level, + GLuint zoffset) { unsigned int draw_x, draw_y; uint32_t mask_x, mask_y; @@ -341,82 +296,9 @@ intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image, draw_y & ~mask_y, false); - image->region = intel_region_alloc_subregion(mt->region, - mt->region->cpp, - width, height, - mt->region->pitch, - offset, tile_x, tile_y); -} - -static void -intel_setup_image_from_dimensions(__DRIimage *image) -{ - image->has_depthstencil = false; -} - -static __DRIimage * -intel_dri_image_create_from_name(__DRIscreen *screen, - int width, int height, int format, - int name, int pitch, void *loaderPrivate) -{ - struct intel_screen *intelScreen = screen->driverPrivate; - __DRIimage *image; - int cpp; - - image = intel_allocate_image(format, loaderPrivate); - if (image == NULL) - return NULL; - - if (image->format == MESA_FORMAT_NONE) - cpp = 1; - else - cpp = _mesa_get_format_bytes(image->format); - image->region = intel_region_alloc_for_handle(intelScreen->bufmgr, - cpp, width, height, - pitch * cpp, name, "image"); - if (image->region == NULL) { - free(image); - return NULL; - } - - intel_setup_image_from_dimensions(image); - - return image; -} - -static __DRIimage * -intel_dri_image_create_from_renderbuffer(__DRIcontext *context, - int renderbuffer, - void *loaderPrivate) -{ - __DRIimage *image; - struct brw_context *brw = context->driverPrivate; - struct gl_context *ctx = &brw->ctx; - struct gl_renderbuffer *rb; - struct intel_renderbuffer *irb; - - rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); - if (!rb) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA"); - return NULL; - } - - irb = intel_renderbuffer(rb); - intel_miptree_make_shareable(brw, irb->mt); - image = calloc(1, sizeof *image); - if (image == NULL) - return NULL; - - image->internal_format = rb->InternalFormat; - image->format = rb->Format; - image->data = loaderPrivate; - intel_region_reference(&image->region, irb->mt->region); - intel_setup_image_from_dimensions(image); - image->dri_format = driGLFormatToImageFormat(image->format); - image->has_depthstencil = irb->mt->stencil_mt? true : false; - - rb->NeedsFinishRenderTexture = true; - return image; + return intel_region_alloc_subregion(mt->region, mt->region->cpp, + width, height, mt->region->pitch, + offset, tile_x, tile_y); } static __DRIimage * @@ -427,9 +309,11 @@ intel_dri_image_create_from_texture(__DRIcontext *context, int target, void *loaderPrivate) { __DRIimage *image; + struct intel_region *region = NULL; struct brw_context *brw = context->driverPrivate; struct gl_texture_object *obj; struct intel_texture_object *iobj; + int stride, offset; GLuint face = 0; obj = _mesa_lookup_texture(&brw->ctx, texture); @@ -457,24 +341,26 @@ intel_dri_image_create_from_texture(__DRIcontext *context, int target, *error = __DRI_IMAGE_ERROR_BAD_MATCH; return NULL; } - image = calloc(1, sizeof *image); - if (image == NULL) { + + region = intel_region_alloc_from_mipmap_tree(brw, iobj->mt, level, zoffset); + if (!region) { *error = __DRI_IMAGE_ERROR_BAD_ALLOC; return NULL; } - image->internal_format = obj->Image[face][level]->InternalFormat; - image->format = obj->Image[face][level]->TexFormat; - image->data = loaderPrivate; - intel_setup_image_from_mipmap_tree(brw, image, iobj->mt, level, zoffset); - image->dri_format = driGLFormatToImageFormat(image->format); - image->has_depthstencil = iobj->mt->stencil_mt? true : false; - if (image->dri_format == MESA_FORMAT_NONE) { - *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; - free(image); + stride = region->pitch; + offset = 0; + image = intel_image_create_from_region(0, region, &stride, &offset, 0); + if (!image) { + *error = __DRI_IMAGE_ERROR_BAD_ALLOC; return NULL; } + intel_image_set_gl_format(image, + obj->Image[face][level]->InternalFormat, + obj->Image[face][level]->TexFormat); + image->has_depthstencil = iobj->mt->stencil_mt? true : false; + *error = __DRI_IMAGE_ERROR_SUCCESS; return image; } @@ -482,8 +368,7 @@ intel_dri_image_create_from_texture(__DRIcontext *context, int target, static void intel_dri_image_destroy(__DRIimage *image) { - intel_region_release(&image->region); - free(image); + intel_image_destroy(image); } static __DRIimage * @@ -492,42 +377,17 @@ intel_dri_image_create(__DRIscreen *screen, unsigned int use, void *loaderPrivate) { - __DRIimage *image; struct intel_screen *intelScreen = screen->driverPrivate; - uint32_t tiling; - int cpp; - - tiling = I915_TILING_X; - if (use & __DRI_IMAGE_USE_CURSOR) { - if (width != 64 || height != 64) - return NULL; - tiling = I915_TILING_NONE; - } - - if (use & __DRI_IMAGE_USE_LINEAR) - tiling = I915_TILING_NONE; - - image = intel_allocate_image(format, loaderPrivate); - if (image == NULL) - return NULL; - - cpp = _mesa_get_format_bytes(image->format); - image->region = - intel_region_alloc(intelScreen->bufmgr, tiling, cpp, - width, height, true); - if (image->region == NULL) { - free(image); - return NULL; - } - - intel_setup_image_from_dimensions(image); + int fourcc = dri_format_to_fourcc(format); - return image; + return intel_image_create(intelScreen->bufmgr, width, height, fourcc, use); } static GLboolean intel_dri_image_query(__DRIimage *image, int attrib, int *value) { + GLuint format; + switch (attrib) { case __DRI_IMAGE_ATTRIB_STRIDE: *value = image->region->pitch; @@ -538,7 +398,8 @@ intel_dri_image_query(__DRIimage *image, int attrib, int *value) case __DRI_IMAGE_ATTRIB_NAME: return intel_region_flink(image->region, (uint32_t *) value); case __DRI_IMAGE_ATTRIB_FORMAT: - *value = image->dri_format; + format = image->format->planes[image->plane].format; + *value = driGLFormatToImageFormat(format); return true; case __DRI_IMAGE_ATTRIB_WIDTH: *value = image->region->width; @@ -547,9 +408,9 @@ intel_dri_image_query(__DRIimage *image, int attrib, int *value) *value = image->region->height; return true; case __DRI_IMAGE_ATTRIB_COMPONENTS: - if (image->planar_format == NULL) + if (image->format == NULL) return false; - *value = image->planar_format->components; + *value = image->format->components; return true; case __DRI_IMAGE_ATTRIB_FD: if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0) @@ -563,40 +424,13 @@ intel_dri_image_query(__DRIimage *image, int attrib, int *value) static __DRIimage * intel_dri_image_dup(__DRIimage *orig_image, void *loaderPrivate) { - __DRIimage *image; - - image = calloc(1, sizeof *image); - if (image == NULL) - return NULL; - - intel_region_reference(&image->region, orig_image->region); - if (image->region == NULL) { - free(image); - return NULL; - } - - image->internal_format = orig_image->internal_format; - image->planar_format = orig_image->planar_format; - image->dri_format = orig_image->dri_format; - image->format = orig_image->format; - image->has_depthstencil = orig_image->has_depthstencil; - image->data = loaderPrivate; - - memcpy(image->strides, orig_image->strides, sizeof(image->strides)); - memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets)); - - return image; + return intel_image_dup(orig_image); } static GLboolean intel_dri_image_validate_usage(__DRIimage *image, unsigned int use) { - if (use & __DRI_IMAGE_USE_CURSOR) { - if (image->region->width != 64 || image->region->height != 64) - return GL_FALSE; - } - - return GL_TRUE; + return intel_image_validate_usage(image, use); } static __DRIimage * @@ -606,33 +440,11 @@ intel_dri_image_create_from_names(__DRIscreen *screen, int *strides, int *offsets, void *loaderPrivate) { - struct intel_image_format *f = NULL; - __DRIimage *image; - int i, index; - - if (screen == NULL || names == NULL || num_names != 1) - return NULL; - - f = intel_image_format_lookup(fourcc); - if (f == NULL) - return NULL; - - image = intel_dri_image_create_from_name(screen, width, height, - __DRI_IMAGE_FORMAT_NONE, - names[0], strides[0], - loaderPrivate); - - if (image == NULL) - return NULL; - - image->planar_format = f; - for (i = 0; i < f->nplanes; i++) { - index = f->planes[i].buffer_index; - image->offsets[index] = offsets[index]; - image->strides[index] = strides[index]; - } + struct intel_screen *intelScreen = screen->driverPrivate; - return image; + return intel_image_create_from_names(intelScreen->bufmgr, width, height, + fourcc, names, num_names, + strides, offsets); } static __DRIimage * @@ -642,43 +454,9 @@ intel_dri_image_create_from_fds(__DRIscreen *screen, int *offsets, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; - struct intel_image_format *f; - __DRIimage *image; - int i, index; - - if (fds == NULL || num_fds != 1) - return NULL; - - f = intel_image_format_lookup(fourcc); - if (f == NULL) - return NULL; - - if (f->nplanes == 1) - image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate); - else - image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate); - - if (image == NULL) - return NULL; - - image->region = intel_region_alloc_for_fd(intelScreen->bufmgr, - f->planes[0].cpp, width, height, strides[0], - height * strides[0], fds[0], "image"); - if (image->region == NULL) { - free(image); - return NULL; - } - image->planar_format = f; - for (i = 0; i < f->nplanes; i++) { - index = f->planes[i].buffer_index; - image->offsets[index] = offsets[index]; - image->strides[index] = strides[index]; - } - - intel_setup_image_from_dimensions(image); - - return image; + return intel_image_create_from_fds(intelScreen->bufmgr, width, height, + fourcc, fds, num_fds, strides, offsets); } static __DRIimage * @@ -730,52 +508,7 @@ static __DRIimage * intel_dri_image_create_from_planar(__DRIimage *parent, int plane, void *loaderPrivate) { - int width, height, offset, stride, dri_format, index, cpp; - struct intel_image_format *f; - uint32_t mask_x, mask_y; - __DRIimage *image; - - if (parent == NULL || parent->planar_format == NULL) - return NULL; - - f = parent->planar_format; - - if (plane >= f->nplanes) - return NULL; - - width = parent->region->width >> f->planes[plane].width_shift; - height = parent->region->height >> f->planes[plane].height_shift; - dri_format = f->planes[plane].dri_format; - index = f->planes[plane].buffer_index; - offset = parent->offsets[index]; - stride = parent->strides[index]; - - image = intel_allocate_image(dri_format, loaderPrivate); - if (image == NULL) - return NULL; - - if (offset + height * stride > parent->region->bo->size) { - _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); - free(image); - return NULL; - } - - cpp = _mesa_get_format_bytes(image->format); - image->region = intel_region_alloc_subregion(parent->region, cpp, - width, height, stride, - offset, 0, 0); - if (image->region == NULL) { - free(image); - return NULL; - } - intel_setup_image_from_dimensions(image); - - intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false); - if (offset & mask_x) - _mesa_warning(NULL, - "intel_create_sub_image: offset not on tile boundary"); - - return image; + return intel_image_create_from_plane(parent, plane); } static struct __DRIimageExtensionRec intelImageExtension = { diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c index 9e87003..c2bafd0 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_image.c +++ b/src/mesa/drivers/dri/i965/intel_tex_image.c @@ -18,6 +18,7 @@ #include "intel_mipmap_tree.h" #include "intel_buffer_objects.h" #include "intel_batchbuffer.h" +#include "intel_image.h" #include "intel_tex.h" #include "intel_blit.h" #include "intel_fbo.h" @@ -373,9 +374,10 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target, return; } - intel_set_texture_image_region(ctx, texImage, image->region, - target, image->internal_format, - image->format, image->region->offset, + intel_set_texture_image_region(ctx, texImage, image->region, target, + image->internal_format, + image->format->planes[image->plane].format, + image->region->offset, image->region->width, image->region->height, image->region->tile_x, image->region->tile_y); -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev