diff options
author | Jakob Bornecrantz <[email protected]> | 2012-08-31 19:48:26 +0200 |
---|---|---|
committer | Jakob Bornecrantz <[email protected]> | 2012-08-31 19:51:02 +0200 |
commit | 6a7dea93fa70d670a5954e47a47075a2703209d4 (patch) | |
tree | c304ff1541078fa21e2c313435f8a64b58bf57c2 /src/gallium | |
parent | 022f6d88616bf5ea3903c5056d6147e9cf356aa9 (diff) |
dri: Rework planar image interface
As discussed with Kristian on #wayland. Pushes the decision of components into
the dri driver giving it greater freedom to allow t to implement YUV samplers
in hardware, and which mode to use.
This interface will also allow drivers like SVGA to implement YUV surfaces
without the need to sub-allocate and instead send 3 seperate buffers for each
channel, currently not implemented.
I have tested these changes on Gallium Svga. Scott tested them on both intel
and Gallium Radeon. Kristan and Pekka tested them on intel.
v2: Fix typo in dri2_from_planar.
v3: Merge in intel changes.
Tested-by: Scott Moreau <[email protected]>
Tested-by: Pekka Paalanen <[email protected]>
Tested-by: Kristian Høgsberg <[email protected]>
Reviewed-by: Kristian Høgsberg <[email protected]>
Signed-off-by: Jakob Bornecrantz <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/state_trackers/dri/common/dri_screen.h | 1 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/drm/dri2.c | 82 |
2 files changed, 82 insertions, 1 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h index 2818e9c2683..ff48b022157 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.h +++ b/src/gallium/state_trackers/dri/common/dri_screen.h @@ -86,6 +86,7 @@ struct __DRIimageRec { unsigned level; unsigned layer; uint32_t dri_format; + uint32_t dri_components; void *loader_private; }; diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index d7f4dd666b5..2f83dabf165 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -574,6 +574,7 @@ dri2_create_image(__DRIscreen *_screen, img->level = 0; img->layer = 0; img->dri_format = format; + img->dri_components = 0; img->loader_private = loaderPrivate; return img; @@ -612,6 +613,11 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) case __DRI_IMAGE_ATTRIB_HEIGHT: *value = image->texture->height0; return GL_TRUE; + case __DRI_IMAGE_ATTRIB_COMPONENTS: + if (image->dri_components == 0) + return GL_FALSE; + *value = image->dri_components; + return GL_TRUE; default: return GL_FALSE; } @@ -630,6 +636,8 @@ dri2_dup_image(__DRIimage *image, void *loaderPrivate) pipe_resource_reference(&img->texture, image->texture); img->level = image->level; img->layer = image->layer; + /* This should be 0 for sub images, but dup is also used for base images. */ + img->dri_components = image->dri_components; img->loader_private = loaderPrivate; return img; @@ -649,6 +657,76 @@ dri2_validate_usage(__DRIimage *image, unsigned int use) return GL_FALSE; } +static __DRIimage * +dri2_from_names(__DRIscreen *screen, int width, int height, int format, + int *names, int num_names, int *strides, int *offsets, + void *loaderPrivate) +{ + __DRIimage *img; + int stride, dri_components; + + if (num_names != 1) + return NULL; + if (offsets[0] != 0) + return NULL; + + switch(format) { + case __DRI_IMAGE_FOURCC_RGB565: + format = __DRI_IMAGE_FORMAT_RGB565; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + case __DRI_IMAGE_FOURCC_ARGB8888: + format = __DRI_IMAGE_FORMAT_ARGB8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGBA; + break; + case __DRI_IMAGE_FOURCC_XRGB8888: + format = __DRI_IMAGE_FORMAT_XRGB8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + case __DRI_IMAGE_FOURCC_ABGR8888: + format = __DRI_IMAGE_FORMAT_ABGR8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGBA; + break; + case __DRI_IMAGE_FOURCC_XBGR8888: + format = __DRI_IMAGE_FORMAT_XBGR8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + default: + return NULL; + } + + /* Strides are in bytes not pixels. */ + stride = strides[0] /4; + + img = dri2_create_image_from_name(screen, width, height, format, + names[0], stride, loaderPrivate); + if (img == NULL) + return NULL; + + img->dri_components = dri_components; + return img; +} + +static __DRIimage * +dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate) +{ + __DRIimage *img; + + if (plane != 0) + return NULL; + + if (image->dri_components == 0) + return NULL; + + img = dri2_dup_image(image, loaderPrivate); + if (img == NULL) + return NULL; + + /* set this to 0 for sub images. */ + img->dri_components = 0; + return img; +} + static void dri2_destroy_image(__DRIimage *img) { @@ -657,7 +735,7 @@ dri2_destroy_image(__DRIimage *img) } static struct __DRIimageExtensionRec dri2ImageExtension = { - { __DRI_IMAGE, 4 }, + { __DRI_IMAGE, 5 }, dri2_create_image_from_name, dri2_create_image_from_renderbuffer, dri2_destroy_image, @@ -665,6 +743,8 @@ static struct __DRIimageExtensionRec dri2ImageExtension = { dri2_query_image, dri2_dup_image, dri2_validate_usage, + dri2_from_names, + dri2_from_planar, }; /* |