summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-09-14 14:33:10 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-09-14 14:33:10 +0200
commitef33894a6061f130a6a28bdde2af5661da146632 (patch)
tree82009e9a06a72f3a41886e5373b5682ac577f8b1
parentd00d24ddc44fb511fc49c765659ac96d0f165a19 (diff)
egl: make VA/EGL buffer support driver specific.21.VA_pixel_buffer-r221.VA_pixel_buffer
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--include/GL/internal/dri_interface.h30
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c120
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h5
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c135
4 files changed, 167 insertions, 123 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 1e0f1d07b3..1a6cf0a568 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -912,7 +912,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 5
+#define __DRI_IMAGE_VERSION 6
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1061,6 +1061,34 @@ struct __DRIimageExtensionRec {
*/
__DRIimage *(*fromPlanar)(__DRIimage *image, int plane,
void *loaderPrivate);
+
+ /**
+ * Create an image out of a VA/EGL buffer. This entry-point lets us create
+ * individual __DRIimages for different planes in a planar buffer, similar
+ * to fromPlanar(), but with a VA/EGL buffer as source.
+ *
+ * Buffer structure, if non-zero, specifies the desired sampling from the
+ * client application. e.g. if a YUV surface was provided but
+ * @buffer_structure is VA_EGL_BUFFER_STRUCTURE_RGBA, this means the user
+ * would like to get RGBA samples from the YUV surface, i.e. color space
+ * conversion is to be performed by the underlying hardware without shader
+ * code. If the hardware does not support this capability, the function
+ * shall return NULL, thus indicating to client application that a planar
+ * format should be tried instead and suitable shader code provided.
+ *
+ * Picture structure represents the full frame (default, if zero), the top
+ * or the bottom field for interlaced surfaces. Note that for those two
+ * modes, this basically actually means whether to render every other line
+ * or not. If not proper hardware function supports that capability, or
+ * that using double stride and half height doesn't work, then this
+ * entry-point shall return NULL.
+ *
+ * \since 6
+ */
+ __DRIimage *(*createImageFromVABuffer)(__DRIscreen *screen, void *buffer,
+ int buffer_structure, int plane,
+ int picture_structure,
+ void *loaderPrivate);
};
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index de4506cbbb..47d5e9b5cf 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1146,97 +1146,15 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
#endif
#ifdef HAVE_VA_EGL_INTEROP
-static const struct va_dri_image_descriptor {
- uint32_t format;
- uint32_t dri_fourcc;
- int nplanes;
-} va_dri_image_descriptors[] = {
- { VA_EGL_PIXEL_FORMAT_ARGB8888, __DRI_IMAGE_FOURCC_ARGB8888, 1 },
- { VA_EGL_PIXEL_FORMAT_XRGB8888, __DRI_IMAGE_FOURCC_XRGB8888, 1 },
- { VA_EGL_PIXEL_FORMAT_ABGR8888, __DRI_IMAGE_FOURCC_ABGR8888, 1 },
- { VA_EGL_PIXEL_FORMAT_NV12, __DRI_IMAGE_FOURCC_NV12, 2 },
- { VA_EGL_PIXEL_FORMAT_YUV410P, __DRI_IMAGE_FOURCC_YUV410, 3 },
- { VA_EGL_PIXEL_FORMAT_YUV411P, __DRI_IMAGE_FOURCC_YUV411, 3 },
- { VA_EGL_PIXEL_FORMAT_YUV420P, __DRI_IMAGE_FOURCC_YUV420, 3 },
- { VA_EGL_PIXEL_FORMAT_YUV422P, __DRI_IMAGE_FOURCC_YUV422, 3 },
- { VA_EGL_PIXEL_FORMAT_YUV444P, __DRI_IMAGE_FOURCC_YUV444, 3 },
-};
-
-struct va_dri_image {
- __DRIimage *image;
- void (*destroy_func)(__DRIimage *image);
- const struct va_dri_image_descriptor *desc;
-};
-
-static void
-dri2_va_destroy_image(struct va_dri_image *img)
-{
- if (img)
- return;
- if (img->destroy_func)
- img->destroy_func(img->image);
- free(img);
-}
-
-static struct va_dri_image *
-dri2_va_create_image(_EGLDisplay *disp, struct va_egl_client_buffer *buffer)
-{
- struct dri2_egl_display * const dri2_dpy = dri2_egl_display(disp);
- struct va_dri_image *img;
- int i, handle, pitches[3], offsets[3];
-
- for (i = 0; i < ARRAY_SIZE(va_dri_image_descriptors); i++) {
- if (va_dri_image_descriptors[i].format == buffer->format)
- break;
- }
- if (i == ARRAY_SIZE(va_dri_image_descriptors)) {
- _eglLog(_EGL_DEBUG, "DRI2-VA: failed to validate pixel format %d",
- buffer->format);
- return NULL;
- }
-
- img = malloc(sizeof(*img));
- if (!img)
- return NULL;
- img->destroy_func = dri2_dpy->image->destroyImage;
- img->desc = &va_dri_image_descriptors[i];
-
- handle = buffer->handle;
- for (i = 0; i < buffer->num_planes; i++) {
- pitches[i] = buffer->pitches[i];
- offsets[i] = buffer->offsets[i];
- }
- for (; i < ARRAY_SIZE(pitches); i++) {
- pitches[i] = 0;
- offsets[i] = 0;
- }
- img->image = dri2_dpy->image->createImageFromNames(
- dri2_dpy->dri_screen, buffer->width, buffer->height,
- img->desc->dri_fourcc, &handle, 1, pitches, offsets,
- NULL);
- if (img->image)
- return img;
-
- free(img);
- return NULL;
-}
-
static _EGLImage *
dri2_create_image_va_pixel_buffer(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer _buffer,
+ EGLClientBuffer buffer,
const EGLint *attr_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct va_egl_client_buffer *buffer = _buffer;
- struct va_dri_image *img;
__DRIimage *dri_image;
_EGLImageAttribs attrs;
- EGLint plane, structure, err;
-
- if (!buffer || buffer->version != VA_EGL_CLIENT_BUFFER_VERSION) {
- _eglError(EGL_BAD_PARAMETER, "DRI2-VA: unsupported EGLClientBuffer");
- return NULL;
- }
+ EGLint plane, err;
err = _eglParseImageAttribList(&attrs, disp, attr_list);
if (err != EGL_SUCCESS) {
@@ -1251,37 +1169,9 @@ dri2_create_image_va_pixel_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- structure = attrs.VABufferStructureINTEL;
- if (structure && structure != buffer->structure) {
- _eglError(EGL_BAD_PARAMETER,
- "DRI2-VA: buffer structure coercition is not supported yet");
- return NULL;
- }
-
- structure = attrs.VAPictureStructureINTEL;
- if (structure != VA_EGL_PICTURE_STRUCTURE_FRAME) {
- _eglError(EGL_BAD_PARAMETER,
- "DRI2-VA: interlaced picture structure is not supported yet");
- return NULL;
- }
-
- img = buffer->private_data;
- if (!img) {
- img = dri2_va_create_image(disp, buffer);
- if (!img) {
- _eglError(EGL_BAD_ALLOC, "DRI2-VA: could not reference VA buffer");
- return NULL;
- }
- buffer->private_data = img;
- buffer->destroy_private_data = (void (*)(void *))dri2_va_destroy_image;
- }
-
- if (plane >= img->desc->nplanes) {
- _eglError(EGL_BAD_PARAMETER, "DRI2-VA: invalid plane index");
- return NULL;
- }
-
- dri_image = dri2_dpy->image->fromPlanar(img->image, plane, NULL);
+ dri_image = dri2_dpy->image->createImageFromVABuffer(dri2_dpy->dri_screen,
+ buffer, attrs.VABufferStructureINTEL, plane,
+ attrs.VAPictureStructureINTEL, NULL);
if (!dri_image) {
_eglError(EGL_BAD_ALLOC, "DRI2-VA: could not create sub-buffer");
return NULL;
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 6ad78bddbd..81c1354b79 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -44,11 +44,6 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
-#ifdef HAVE_VA_EGL_INTEROP
-# include <va/va_egl.h>
-# include <va/va_backend_egl.h>
-#endif
-
#ifdef HAVE_DRM_PLATFORM
#include <gbm_driint.h>
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e3a442c2a2..835f9158e9 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -36,6 +36,11 @@
#include "main/version.h"
#include "swrast/s_renderbuffer.h"
+#ifdef HAVE_VA_EGL_INTEROP
+# include <va/va_egl.h>
+# include <va/va_backend_egl.h>
+#endif
+
#include "utils.h"
#include "xmlpool.h"
@@ -572,8 +577,133 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
return image;
}
+#ifdef HAVE_VA_EGL_INTEROP
+static const struct va_dri_image_descriptor {
+ uint32_t format;
+ uint32_t dri_fourcc;
+ int nplanes;
+} va_dri_image_descriptors[] = {
+ { VA_EGL_PIXEL_FORMAT_ARGB8888, __DRI_IMAGE_FOURCC_ARGB8888, 1 },
+ { VA_EGL_PIXEL_FORMAT_XRGB8888, __DRI_IMAGE_FOURCC_XRGB8888, 1 },
+ { VA_EGL_PIXEL_FORMAT_ABGR8888, __DRI_IMAGE_FOURCC_ABGR8888, 1 },
+ { VA_EGL_PIXEL_FORMAT_NV12, __DRI_IMAGE_FOURCC_NV12, 2 },
+ { VA_EGL_PIXEL_FORMAT_YUV410P, __DRI_IMAGE_FOURCC_YUV410, 3 },
+ { VA_EGL_PIXEL_FORMAT_YUV411P, __DRI_IMAGE_FOURCC_YUV411, 3 },
+ { VA_EGL_PIXEL_FORMAT_YUV420P, __DRI_IMAGE_FOURCC_YUV420, 3 },
+ { VA_EGL_PIXEL_FORMAT_YUV422P, __DRI_IMAGE_FOURCC_YUV422, 3 },
+ { VA_EGL_PIXEL_FORMAT_YUV444P, __DRI_IMAGE_FOURCC_YUV444, 3 },
+};
+
+struct va_dri_image {
+ __DRIimage *image;
+ const struct va_dri_image_descriptor *desc;
+};
+
+static void
+intel_destroy_va_image(struct va_dri_image *img)
+{
+ if (!img)
+ return;
+ if (img->image)
+ intel_destroy_image(img->image);
+ free(img);
+}
+
+static struct va_dri_image *
+intel_create_va_image(__DRIscreen *screen, struct va_egl_client_buffer *buffer)
+{
+ struct va_dri_image *img = NULL;
+ int i, handle, pitches[3], offsets[3];
+
+ for (i = 0; i < ARRAY_SIZE(va_dri_image_descriptors); i++) {
+ if (va_dri_image_descriptors[i].format == buffer->format)
+ break;
+ }
+ if (i == ARRAY_SIZE(va_dri_image_descriptors)) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "DRI2-VA: failed to validate pixel format %d",
+ buffer->format);
+ goto error;
+ }
+
+ img = malloc(sizeof(*img));
+ if (!img) {
+ _mesa_error(NULL, GL_OUT_OF_MEMORY, "DRI2-VA: failed to create VA image");
+ goto error;
+ }
+ img->desc = &va_dri_image_descriptors[i];
+
+ handle = buffer->handle;
+ for (i = 0; i < buffer->num_planes; i++) {
+ pitches[i] = buffer->pitches[i];
+ offsets[i] = buffer->offsets[i];
+ }
+ for (; i < ARRAY_SIZE(pitches); i++) {
+ pitches[i] = 0;
+ offsets[i] = 0;
+ }
+ img->image = intel_create_image_from_names(
+ screen, buffer->width, buffer->height,
+ img->desc->dri_fourcc, &handle, 1, pitches, offsets,
+ NULL);
+ if (!img->image)
+ goto error;
+
+ buffer->private_data = img;
+ buffer->destroy_private_data = (void (*)(void *))intel_destroy_va_image;
+ return img;
+
+error:
+ free(img);
+ return NULL;
+}
+#endif
+
+static __DRIimage *
+intel_create_image_from_va_buffer(__DRIscreen *screen, void *_buffer,
+ int buffer_structure, int plane,
+ int picture_structure, void *loaderPrivate)
+{
+#ifdef HAVE_VA_EGL_INTEROP
+ struct va_egl_client_buffer * const buffer = _buffer;
+ struct va_dri_image *img;
+
+ if (!buffer || buffer->version != VA_EGL_CLIENT_BUFFER_VERSION) {
+ _mesa_error(NULL, GL_INVALID_VALUE,
+ "DRI2-VA: unsupported EGLClientBuffer");
+ return NULL;
+ }
+
+ if (buffer_structure && buffer_structure != buffer->structure) {
+ _mesa_error(NULL, GL_INVALID_VALUE,
+ "DRI2-VA: buffer structure coercition is not supported yet");
+ return NULL;
+ }
+
+ if (picture_structure != VA_EGL_PICTURE_STRUCTURE_FRAME) {
+ _mesa_error(NULL, GL_INVALID_VALUE,
+ "DRI2-VA: interlaced picture structure is not supported yet");
+ return NULL;
+ }
+
+ img = buffer->private_data;
+ if (!img) {
+ img = intel_create_va_image(screen, buffer);
+ if (!img)
+ return NULL;
+ }
+
+ if (plane >= img->desc->nplanes) {
+ _mesa_error(NULL, GL_INVALID_VALUE, "DRI2-VA: invalid plane index");
+ return NULL;
+ }
+ return intel_from_planar(img->image, plane, loaderPrivate);
+#endif
+ return NULL;
+}
+
static struct __DRIimageExtensionRec intelImageExtension = {
- { __DRI_IMAGE, 5 },
+ { __DRI_IMAGE, 6 },
intel_create_image_from_name,
intel_create_image_from_renderbuffer,
intel_destroy_image,
@@ -582,7 +712,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
intel_dup_image,
intel_validate_usage,
intel_create_image_from_names,
- intel_from_planar
+ intel_from_planar,
+ intel_create_image_from_va_buffer
};
static const __DRIextension *intelScreenExtensions[] = {