Signed-off-by: Gwenole Beauchesne <gwenole.beauche...@intel.com> --- src/mesa/drivers/dri/i965/intel_screen.c | 77 ++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 464cebf..1e3d58f 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -286,6 +286,62 @@ intel_image_format_lookup(int fourcc) return f; } +static bool +intel_image_format_fill(struct intel_image_format *f, uint32_t fourcc) +{ + uint32_t tuple_format = 0; + int num_elements, element_size; + + if ((fourcc & 0xff) != 'T') { + struct intel_image_format * const f_tmp = + intel_image_format_lookup(fourcc); + if (!f_tmp) + return false; + + *f = *f_tmp; + return true; + } + + num_elements = ((fourcc >> 8) & 0xff) - '0'; + if (num_elements < 1 || num_elements > 4) + return false; + + element_size = ((fourcc >> 24) & 0xff) - '0'; + switch ((fourcc >> 16) & 0xff) { + case '_': /* normalized to [0..1] range */ + tuple_format = __DRI_IMAGE_FORMAT_T_UNORM; + if (element_size != 1 && element_size != 2) + return false; + break; + case 'I': /* signed integer */ + tuple_format = __DRI_IMAGE_FORMAT_T_SINT; + if (element_size != 1 && element_size != 2 && element_size != 4) + return false; + break; + case 'U': /* unsigned integer */ + tuple_format = __DRI_IMAGE_FORMAT_T_UINT; + if (element_size != 1 && element_size != 2 && element_size != 4) + return false; + break; + case 'F': /* floating-point */ + tuple_format = __DRI_IMAGE_FORMAT_T_FLOAT; + if (element_size != 2 && element_size != 4) + return false; + break; + default: + return false; + } + + f->fourcc = fourcc; + f->components = __DRI_IMAGE_COMPONENTS_X + num_elements - 1; + f->nplanes = 1; + memset(f->planes, 0, sizeof(f->planes)); + f->planes[0].dri_format = + __DRI_IMAGE_FORMAT_TUPLE_I(num_elements, tuple_format, element_size); + f->planes[0].cpp = num_elements; + return true; +} + static __DRIimage * intel_allocate_image(int dri_format, void *loaderPrivate) { @@ -644,7 +700,7 @@ intel_create_image_from_fds(__DRIscreen *screen, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; - struct intel_image_format *f; + struct intel_image_format *f, f_tmp; __DRIimage *image; int i, index; @@ -652,8 +708,11 @@ intel_create_image_from_fds(__DRIscreen *screen, return NULL; f = intel_image_format_lookup(fourcc); - if (f == NULL) - return NULL; + if (!f) { + if (!intel_image_format_fill(&f_tmp, fourcc)) + return NULL; + f = &f_tmp; + } if (f->nplanes == 1) image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate); @@ -671,7 +730,7 @@ intel_create_image_from_fds(__DRIscreen *screen, return NULL; } - image->planar_format = f; + image->planar_format = f != &f_tmp ? f : NULL; for (i = 0; i < f->nplanes; i++) { index = f->planes[i].buffer_index; image->offsets[index] = offsets[index]; @@ -696,7 +755,15 @@ intel_create_image_from_dma_bufs(__DRIscreen *screen, void *loaderPrivate) { __DRIimage *image; - struct intel_image_format *f = intel_image_format_lookup(fourcc); + struct intel_image_format f_tmp, *f = intel_image_format_lookup(fourcc); + + if (!f) { + if (!intel_image_format_fill(&f_tmp, fourcc)) { + *error = __DRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + f = &f_tmp; + } /* For now only packed formats that have native sampling are supported. */ if (!f || f->nplanes != 1) { -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev