[Mesa-dev] [PATCH 2/2] intel: Support new dri image interface v2
Pekka Paalanen
ppaalanen at gmail.com
Fri Aug 31 07:51:57 PDT 2012
On Fri, 31 Aug 2012 15:22:04 +0200
Jakob Bornecrantz <jakob at vmware.com> wrote:
> Follow up to the previous patch, kept seperate for easier viewing,
> will be merged with previous patch before commiting.
>
> v2: Should fix YUV pitch/stride == 0.
>
> Signed-off-by: Jakob Bornecrantz <jakob at vmware.com>
> ---
> src/mesa/drivers/dri/intel/intel_regions.h | 26 ++++++
> src/mesa/drivers/dri/intel/intel_screen.c | 135 ++++++++++++++++++++++++++--
> 2 files changed, 153 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
> index 4ff0efe..c0fdc95 100644
> --- a/src/mesa/drivers/dri/intel/intel_regions.h
> +++ b/src/mesa/drivers/dri/intel/intel_regions.h
> @@ -141,12 +141,38 @@ uint32_t
> intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
> uint32_t y);
>
> +/**
> + * Used with images created with image_from_names
> + * to help support planar images.
> + */
> +typedef struct intel_image_format {
> + int fourcc;
> + int components;
> + int nplanes;
> + struct {
> + int buffer_index;
> + int width_shift;
> + int height_shift;
> + uint32_t dri_format;
> + int cpp;
> + } planes[3];
> +} intel_image_format_t;
> +
> struct __DRIimageRec {
> struct intel_region *region;
> GLenum internal_format;
> uint32_t dri_format;
> GLuint format;
> uint32_t offset;
> +
> + /*
> + * Need to save these here between calls to
> + * image_from_names and calls to image_from_planar.
> + */
> + uint32_t strides[3];
> + uint32_t offsets[3];
> + struct intel_image_format *planar_format;
> +
> void *data;
> };
>
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index 55cebac..f20b072 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -190,6 +190,59 @@ static const struct __DRI2flushExtensionRec intelFlushExtension = {
> dri2InvalidateDrawable,
> };
>
> +intel_image_format_t 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_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 __DRIimage *
> intel_allocate_image(int dri_format, void *loaderPrivate)
> {
> @@ -249,7 +302,7 @@ intel_create_image_from_name(__DRIscreen *screen,
>
> image = intel_allocate_image(format, loaderPrivate);
> if (image->format == MESA_FORMAT_NONE)
> - cpp = 0;
> + cpp = 1;
> else
> cpp = _mesa_get_format_bytes(image->format);
> image->region = intel_region_alloc_for_handle(intelScreen,
> @@ -372,6 +425,11 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
> case __DRI_IMAGE_ATTRIB_HEIGHT:
> *value = image->region->height;
> return true;
> + case __DRI_IMAGE_ATTRIB_COMPONENTS:
> + if (image->planar_format == NULL)
> + return false;
> + *value = image->planar_format->components;
> + return true;
> default:
> return false;
> }
> @@ -393,11 +451,15 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
> }
>
> 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->offset = orig_image->offset;
> image->data = loaderPrivate;
> -
> +
> + memcpy(image->strides, orig_image->strides, sizeof(image->strides));
> + memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
> +
> return image;
> }
>
> @@ -413,16 +475,72 @@ intel_validate_usage(__DRIimage *image, unsigned int use)
> }
>
> static __DRIimage *
> -intel_create_sub_image(__DRIimage *parent,
> - int width, int height, int dri_format,
> - int offset, int pitch, void *loaderPrivate)
> +intel_create_image_from_names(__DRIscreen *screen,
> + int width, int height, int fourcc,
> + int *names, int num_names,
> + int *strides, int *offsets,
> + void *loaderPrivate)
> {
> + struct intel_image_format *f = NULL;
> __DRIimage *image;
> - int cpp;
> + int i, index;
> +
> + if (screen == NULL || names == NULL || num_names != 1)
> + return NULL;
> +
> + for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
> + if (intel_image_formats[i].fourcc == fourcc) {
> + f = &intel_image_formats[i];
> + }
> + }
> +
> + if (f == NULL)
> + return NULL;
> +
> + image = intel_create_image_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];
> + }
> +
> + return image;
> +}
> +
> +static __DRIimage *
> +intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
> +{
> + int width, height, offset, stride, dri_format, cpp, index, pitch;
> + 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);
> - cpp = _mesa_get_format_bytes(image->format);
> + cpp = _mesa_get_format_bytes(image->format); /* safe since no none format */
> + pitch = stride / cpp;
> if (offset + height * cpp * pitch > parent->region->bo->size) {
> _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
> FREE(image);
> @@ -463,7 +581,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
> intel_query_image,
> intel_dup_image,
> intel_validate_usage,
> - intel_create_sub_image
> + intel_create_image_from_names,
> + intel_from_planar
> };
>
> static const __DRIextension *intelScreenExtensions[] = {
Tested-by: Pekka Paalanen <ppaalanen at gmail.com>
Date: 2012-08-31 EEST
[17:43:58.976] weston 0.95.0
http://wayland.freedesktop.org/
Bug reports to: https://bugs.freedesktop.org/enter_bug.cgi?product=weston
Build: 0.95.0-139-g5418a90 toytoolkit: don't ignore resizes with negative width or height (2012-08-16 10:33:56 -0400)
[17:43:58.976] OS: Linux, 3.1.7, #2 SMP PREEMPT Thu Jan 5 10:42:13 EET 2012, x86_64
[17:43:58.977] Loading module '/home/pq/local/lib/weston/drm-backend.so'
[17:43:58.977] initializing drm backend
[17:43:59.326] using /dev/dri/card0
Mesa: Initializing x86-64 optimizations
[17:43:59.336] EGL version: 1.4 (DRI2)
[17:43:59.337] EGL vendor: Mesa Project
[17:43:59.337] EGL client APIs: OpenGL OpenGL_ES OpenGL_ES2
[17:43:59.337] EGL extensions: EGL_MESA_drm_image EGL_WL_bind_wayland_display
EGL_KHR_image_base EGL_KHR_gl_renderbuffer_image
EGL_KHR_surfaceless_context EGL_KHR_create_context
[17:43:59.337] GL version: OpenGL ES 2.0 Mesa 9.0-devel (git-caec6ce)
[17:43:59.337] GLSL version: OpenGL ES GLSL ES 1.0.16
[17:43:59.337] GL vendor: Intel Open Source Technology Center
[17:43:59.337] GL renderer: Mesa DRI Intel(R) Sandybridge Mobile
[17:43:59.337] GL extensions: GL_EXT_blend_minmax GL_EXT_multi_draw_arrays
GL_EXT_texture_filter_anisotropic
GL_EXT_texture_compression_dxt1 GL_EXT_texture_format_BGRA8888
GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth24
GL_OES_element_index_uint GL_OES_fbo_render_mipmap
GL_OES_mapbuffer GL_OES_rgb8_rgba8 GL_OES_standard_derivatives
GL_OES_stencil8 GL_OES_texture_3D GL_OES_texture_npot
GL_OES_EGL_image GL_OES_depth_texture
GL_OES_packed_depth_stencil GL_EXT_texture_type_2_10_10_10_REV
GL_APPLE_texture_max_level GL_EXT_read_format_bgra
GL_NV_fbo_color_attachments GL_OES_vertex_array_object
GL_EXT_texture_rg GL_EXT_unpack_subimage GL_NV_draw_buffers
GL_NV_read_buffer
[17:43:59.359] failed to get plane resources: Invalid argument
[17:43:59.359] Output LVDS1, (connector 5, crtc 3)
mode 1600x900 at 60.0, preferred, current
mode 1600x900 at 40.0
[17:43:59.421] Output VGA1, (connector 12, crtc 4)
mode 1600x1200 at 60.0, preferred, current
http://people.collabora.com/~pq/simple-yuv-for-jakob.png
Cheers!
- pq
More information about the mesa-dev
mailing list