On Fri, 31 Aug 2012 15:22:04 +0200 Jakob Bornecrantz <ja...@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 <ja...@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 <ppaala...@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@60.0, preferred, current mode 1600x900@40.0 [17:43:59.421] Output VGA1, (connector 12, crtc 4) mode 1600x1200@60.0, preferred, current http://people.collabora.com/~pq/simple-yuv-for-jakob.png Cheers! - pq _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev