[Mesa-dev] [PATCH 4/4] i965: Refactor DRI image code
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Wed Nov 27 07:52:08 PST 2013
From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at 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
More information about the mesa-dev
mailing list