summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorChristian König <[email protected]>2013-05-15 15:10:11 +0200
committerChristian König <[email protected]>2013-10-26 12:13:36 +0200
commit80964226e9b8a05c39157f9305c06c0b2861e080 (patch)
treec4f1c11f0f3e82e0b8167b8cba21de6694f2f9d9 /src/mesa
parent3d3a0b9b67982a96a4c4d87f78c21204f3a48776 (diff)
implement NV_vdpau_interop v7
v2: Actually implement interop between the gallium state tracker and the VDPAU backend. v3: Make it also available in non legacy contexts, fix video buffer sharing. v4: deny interop if we don't have the same screen object v5: rebased on upstream changes v6: implemented VDPAUGetSurfaceivNV, improved error handling, unregister all surfaces in VDPAUFiniNV v7: squash merge with Mareks changes Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile.sources4
-rw-r--r--src/mesa/main/dd.h14
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/mtypes.h10
-rw-r--r--src/mesa/main/vdpau.c424
-rw-r--r--src/mesa/main/vdpau.h72
-rw-r--r--src/mesa/state_tracker/st_context.c3
-rw-r--r--src/mesa/state_tracker/st_extensions.c1
-rw-r--r--src/mesa/state_tracker/st_vdpau.c181
-rw-r--r--src/mesa/state_tracker/st_vdpau.h42
10 files changed, 751 insertions, 1 deletions
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index ff242b4ab9f..a84f8a78857 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -108,6 +108,7 @@ MAIN_FILES = \
$(SRCDIR)main/uniforms.c \
$(SRCDIR)main/uniform_query.cpp \
$(SRCDIR)main/varray.c \
+ $(SRCDIR)main/vdpau.c \
$(SRCDIR)main/version.c \
$(SRCDIR)main/viewport.c \
$(SRCDIR)main/vtxfmt.c \
@@ -248,7 +249,8 @@ STATETRACKER_FILES = \
$(SRCDIR)state_tracker/st_manager.c \
$(SRCDIR)state_tracker/st_mesa_to_tgsi.c \
$(SRCDIR)state_tracker/st_program.c \
- $(SRCDIR)state_tracker/st_texture.c
+ $(SRCDIR)state_tracker/st_texture.c \
+ $(SRCDIR)state_tracker/st_vdpau.c
PROGRAM_FILES = \
$(SRCDIR)program/arbprogparse.c \
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 29469ce3314..50119219906 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -868,6 +868,20 @@ struct dd_function_table {
struct gl_framebuffer *fb,
GLuint index,
GLfloat *outValue);
+
+ /**
+ * \name NV_vdpau_interop interface
+ */
+ void (*VDPAUMapSurface)(struct gl_context *ctx, GLenum target,
+ GLenum access, GLboolean output,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ const GLvoid *vdpSurface, GLuint index);
+ void (*VDPAUUnmapSurface)(struct gl_context *ctx, GLenum target,
+ GLenum access, GLboolean output,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ const GLvoid *vdpSurface, GLuint index);
};
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index e8e0a20d8b2..00d65ccb04d 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -335,6 +335,7 @@ static const struct extension extension_table[] = {
{ "GL_NV_texture_barrier", o(NV_texture_barrier), GL, 2009 },
{ "GL_NV_texture_env_combine4", o(NV_texture_env_combine4), GLL, 1999 },
{ "GL_NV_texture_rectangle", o(NV_texture_rectangle), GLL, 2000 },
+ { "GL_NV_vdpau_interop", o(NV_vdpau_interop), GL, 2010 },
{ "GL_S3_s3tc", o(ANGLE_texture_compression_dxt), GL, 1999 },
{ "GL_SGIS_generate_mipmap", o(dummy_true), GLL, 1997 },
{ "GL_SGIS_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 1997 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 97ed1bd6a14..824e33906fd 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3302,6 +3302,7 @@ struct gl_extensions
GLboolean NV_texture_barrier;
GLboolean NV_texture_env_combine4;
GLboolean NV_texture_rectangle;
+ GLboolean NV_vdpau_interop;
GLboolean TDFX_texture_compression_FXT1;
GLboolean OES_EGL_image;
GLboolean OES_draw_texture;
@@ -3832,6 +3833,15 @@ struct gl_context
struct st_context *st;
void *aelt_context;
/*@}*/
+
+ /**
+ * \name NV_vdpau_interop
+ */
+ /*@{*/
+ const void *vdpDevice;
+ const void *vdpGetProcAddress;
+ struct set *vdpSurfaces;
+ /*@}*/
};
diff --git a/src/mesa/main/vdpau.c b/src/mesa/main/vdpau.c
new file mode 100644
index 00000000000..414afe20e09
--- /dev/null
+++ b/src/mesa/main/vdpau.c
@@ -0,0 +1,424 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Christian König <[email protected]>
+ *
+ */
+
+#include <stdbool.h>
+#include "context.h"
+#include "glformats.h"
+#include "hash_table.h"
+#include "set.h"
+#include "texobj.h"
+#include "teximage.h"
+#include "vdpau.h"
+
+#define MAX_TEXTURES 4
+
+struct vdp_surface
+{
+ GLenum target;
+ struct gl_texture_object *textures[MAX_TEXTURES];
+ GLenum access, state;
+ GLboolean output;
+ const GLvoid *vdpSurface;
+};
+
+void GLAPIENTRY
+_mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!vdpDevice) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "vdpDevice");
+ return;
+ }
+
+ if (!getProcAddress) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "getProcAddress");
+ return;
+ }
+
+ if (ctx->vdpDevice || ctx->vdpGetProcAddress || ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUInitNV");
+ return;
+ }
+
+ ctx->vdpDevice = vdpDevice;
+ ctx->vdpGetProcAddress = getProcAddress;
+ ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_key_pointer_equal);
+}
+
+static void
+unregister_surface(struct set_entry *entry)
+{
+ struct vdp_surface *surf = (struct vdp_surface *)entry->key;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (surf->state == GL_SURFACE_MAPPED_NV) {
+ GLintptr surfaces[] = { (GLintptr)surf };
+ _mesa_VDPAUUnmapSurfacesNV(1, surfaces);
+ }
+
+ _mesa_set_remove(ctx->vdpSurfaces, entry);
+ FREE(surf);
+}
+
+void GLAPIENTRY
+_mesa_VDPAUFiniNV()
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUFiniNV");
+ return;
+ }
+
+ _mesa_set_destroy(ctx->vdpSurfaces, unregister_surface);
+
+ ctx->vdpDevice = 0;
+ ctx->vdpGetProcAddress = 0;
+ ctx->vdpSurfaces = NULL;
+}
+
+static GLintptr
+register_surface(struct gl_context *ctx, GLboolean isOutput,
+ const GLvoid *vdpSurface, GLenum target,
+ GLsizei numTextureNames, const GLuint *textureNames)
+{
+ struct vdp_surface *surf;
+ int i;
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV");
+ return (GLintptr)NULL;
+ }
+
+ if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
+ return (GLintptr)NULL;
+ }
+
+ if (target == GL_TEXTURE_RECTANGLE && !ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
+ return (GLintptr)NULL;
+ }
+
+ surf = CALLOC_STRUCT( vdp_surface );
+ surf->vdpSurface = vdpSurface;
+ surf->target = target;
+ surf->access = GL_READ_WRITE;
+ surf->state = GL_SURFACE_REGISTERED_NV;
+ surf->output = isOutput;
+ for (i = 0; i < numTextureNames; ++i) {
+ struct gl_texture_object *tex;
+ tex = _mesa_lookup_texture(ctx, textureNames[i]);
+
+ _mesa_lock_texture(ctx, tex);
+
+ if (tex->Immutable) {
+ _mesa_unlock_texture(ctx, tex);
+ FREE(surf);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "VDPAURegisterSurfaceNV(texture is immutable)");
+ return (GLintptr)NULL;
+ }
+
+ if (tex->Target == 0)
+ tex->Target = target;
+ else if (tex->Target != target) {
+ _mesa_unlock_texture(ctx, tex);
+ FREE(surf);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "VDPAURegisterSurfaceNV(target mismatch)");
+ return (GLintptr)NULL;
+ }
+
+ /* This will disallow respecifying the storage. */
+ tex->Immutable = GL_TRUE;
+ _mesa_unlock_texture(ctx, tex);
+
+ _mesa_reference_texobj(&surf->textures[i], tex);
+ }
+
+ _mesa_set_add(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf);
+
+ return (GLintptr)surf;
+}
+
+GLintptr GLAPIENTRY
+_mesa_VDPAURegisterVideoSurfaceNV(const GLvoid *vdpSurface, GLenum target,
+ GLsizei numTextureNames,
+ const GLuint *textureNames)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (numTextureNames != 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAURegisterVideoSurfaceNV");
+ return (GLintptr)NULL;
+ }
+
+ return register_surface(ctx, false, vdpSurface, target,
+ numTextureNames, textureNames);
+}
+
+GLintptr GLAPIENTRY
+_mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target,
+ GLsizei numTextureNames,
+ const GLuint *textureNames)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (numTextureNames != 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAURegisterVideoSurfaceNV");
+ return (GLintptr)NULL;
+ }
+
+ return register_surface(ctx, true, vdpSurface, target,
+ numTextureNames, textureNames);
+}
+
+void GLAPIENTRY
+_mesa_VDPAUIsSurfaceNV(GLintptr surface)
+{
+ struct vdp_surface *surf = (struct vdp_surface *)surface;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUIsSurfaceNV");
+ return;
+ }
+
+ if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUIsSurfaceNV");
+ return;
+ }
+}
+
+void GLAPIENTRY
+_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface)
+{
+ struct vdp_surface *surf = (struct vdp_surface *)surface;
+ struct set_entry *entry;
+ int i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnregisterSurfaceNV");
+ return;
+ }
+
+ /* according to the spec it's ok when this is zero */
+ if (surface == 0)
+ return;
+
+ entry = _mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf);
+ if (!entry) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUUnregisterSurfaceNV");
+ return;
+ }
+
+ for (i = 0; i < MAX_TEXTURES; i++) {
+ if (surf->textures[i]) {
+ surf->textures[i]->Immutable = GL_FALSE;
+ _mesa_reference_texobj(&surf->textures[i], NULL);
+ }
+ }
+
+ _mesa_set_remove(ctx->vdpSurfaces, entry);
+ FREE(surf);
+}
+
+void GLAPIENTRY
+_mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize,
+ GLsizei *length, GLint *values)
+{
+ struct vdp_surface *surf = (struct vdp_surface *)surface;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUGetSurfaceivNV");
+ return;
+ }
+
+ if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV");
+ return;
+ }
+
+ if (pname != GL_SURFACE_STATE_NV) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "VDPAUGetSurfaceivNV");
+ return;
+ }
+
+ if (bufSize < 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV");
+ return;
+ }
+
+ values[0] = surf->state;
+
+ if (length != NULL)
+ *length = 1;
+}
+
+void GLAPIENTRY
+_mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access)
+{
+ struct vdp_surface *surf = (struct vdp_surface *)surface;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ if (access != GL_READ_ONLY && access != GL_WRITE_ONLY &&
+ access != GL_READ_WRITE) {
+
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ if (surf->state == GL_SURFACE_MAPPED_NV) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ surf->access = access;
+}
+
+void GLAPIENTRY
+_mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ int i, j;
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
+ return;
+ }
+
+ for (i = 0; i < numSurfaces; ++i) {
+ struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
+
+ if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ if (surf->state == GL_SURFACE_MAPPED_NV) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
+ return;
+ }
+ }
+
+ for (i = 0; i < numSurfaces; ++i) {
+ struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
+ unsigned numTextureNames = surf->output ? 1 : 4;
+
+ for (j = 0; j < numTextureNames; ++j) {
+ struct gl_texture_object *tex = surf->textures[j];
+ struct gl_texture_image *image;
+
+ _mesa_lock_texture(ctx, tex);
+ image = _mesa_get_tex_image(ctx, tex, surf->target, 0);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "VDPAUMapSurfacesNV");
+ _mesa_unlock_texture(ctx, tex);
+ return;
+ }
+
+ ctx->Driver.FreeTextureImageBuffer(ctx, image);
+
+ ctx->Driver.VDPAUMapSurface(ctx, surf->target, surf->access,
+ surf->output, tex, image,
+ surf->vdpSurface, j);
+
+ _mesa_unlock_texture(ctx, tex);
+ }
+ surf->state = GL_SURFACE_MAPPED_NV;
+ }
+}
+
+void GLAPIENTRY
+_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ int i, j;
+
+ if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
+ return;
+ }
+
+ for (i = 0; i < numSurfaces; ++i) {
+ struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
+
+ if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
+ return;
+ }
+
+ if (surf->state != GL_SURFACE_MAPPED_NV) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
+ return;
+ }
+ }
+
+ for (i = 0; i < numSurfaces; ++i) {
+ struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
+ unsigned numTextureNames = surf->output ? 1 : 4;
+
+ for (j = 0; j < numTextureNames; ++j) {
+ struct gl_texture_object *tex = surf->textures[j];
+ struct gl_texture_image *image;
+
+ _mesa_lock_texture(ctx, tex);
+
+ image = _mesa_select_tex_image(ctx, tex, surf->target, 0);
+
+ ctx->Driver.VDPAUUnmapSurface(ctx, surf->target, surf->access,
+ surf->output, tex, image,
+ surf->vdpSurface, j);
+
+ if (image)
+ ctx->Driver.FreeTextureImageBuffer(ctx, image);
+
+ _mesa_unlock_texture(ctx, tex);
+ }
+ surf->state = GL_SURFACE_REGISTERED_NV;
+ }
+}
diff --git a/src/mesa/main/vdpau.h b/src/mesa/main/vdpau.h
new file mode 100644
index 00000000000..f32d6dacb83
--- /dev/null
+++ b/src/mesa/main/vdpau.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Christian König <[email protected]>
+ *
+ */
+
+#ifndef VDPAU_H
+#define VDPAU_H
+
+extern void GLAPIENTRY
+_mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+
+extern void GLAPIENTRY
+_mesa_VDPAUFiniNV(void);
+
+extern GLintptr GLAPIENTRY
+_mesa_VDPAURegisterVideoSurfaceNV(const GLvoid *vdpSurface, GLenum target,
+ GLsizei numTextureNames,
+ const GLuint *textureNames);
+
+extern GLintptr GLAPIENTRY
+_mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target,
+ GLsizei numTextureNames,
+ const GLuint *textureNames);
+
+extern void GLAPIENTRY
+_mesa_VDPAUIsSurfaceNV(GLintptr surface);
+
+extern void GLAPIENTRY
+_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface);
+
+extern void GLAPIENTRY
+_mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize,
+ GLsizei *length, GLint *values);
+
+extern void GLAPIENTRY
+_mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access);
+
+extern void GLAPIENTRY
+_mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces);
+
+extern void GLAPIENTRY
+_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces);
+
+#endif /* VDPAU_H */
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 4e0d98cc3b0..2cc3567e0c7 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -65,6 +65,7 @@
#include "st_extensions.h"
#include "st_gen_mipmap.h"
#include "st_program.h"
+#include "st_vdpau.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
@@ -360,5 +361,7 @@ void st_init_driver_functions(struct dd_function_table *functions)
st_init_xformfb_functions(functions);
st_init_syncobj_functions(functions);
+ st_init_vdpau_functions(functions);
+
functions->UpdateState = st_invalidate_state;
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 6635d624e65..97c5d55e1b1 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -564,6 +564,7 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.NV_fog_distance = GL_TRUE;
ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+ ctx->Extensions.NV_vdpau_interop = GL_TRUE;
ctx->Extensions.OES_EGL_image = GL_TRUE;
ctx->Extensions.OES_EGL_image_external = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c
new file mode 100644
index 00000000000..9b165ee3903
--- /dev/null
+++ b/src/mesa/state_tracker/st_vdpau.c
@@ -0,0 +1,181 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Christian König <[email protected]>
+ *
+ */
+
+#include "main/texobj.h"
+#include "main/teximage.h"
+#include "main/errors.h"
+#include "program/prog_instruction.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_video_codec.h"
+
+#include "state_tracker/vdpau_interop.h"
+
+#include "util/u_inlines.h"
+
+#include "st_vdpau.h"
+#include "st_context.h"
+#include "st_texture.h"
+#include "st_format.h"
+
+static void
+st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
+ GLboolean output, struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ const GLvoid *vdpSurface, GLuint index)
+{
+ int (*getProcAddr)(uint32_t device, uint32_t id, void **ptr);
+ uint32_t device = (uintptr_t)ctx->vdpDevice;
+
+ struct st_context *st = st_context(ctx);
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+
+ struct pipe_resource *res;
+ struct pipe_sampler_view *sv, templ;
+ gl_format texFormat;
+
+ getProcAddr = ctx->vdpGetProcAddress;
+ if (output) {
+ VdpOutputSurfaceGallium *f;
+
+ if (getProcAddr(device, VDP_FUNC_ID_OUTPUT_SURFACE_GALLIUM, (void**)&f)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ res = f((uintptr_t)vdpSurface);
+
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ } else {
+ VdpVideoSurfaceGallium *f;
+
+ struct pipe_video_buffer *buffer;
+ struct pipe_sampler_view **samplers;
+
+ if (getProcAddr(device, VDP_FUNC_ID_VIDEO_SURFACE_GALLIUM, (void**)&f)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ buffer = f((uintptr_t)vdpSurface);
+ if (!buffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ samplers = buffer->get_sampler_view_planes(buffer);
+ if (!samplers) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ sv = samplers[index >> 1];
+ if (!sv) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ res = sv->texture;
+ }
+
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ /* do we have different screen objects ? */
+ if (res->screen != st->pipe->screen) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
+ return;
+ }
+
+ /* switch to surface based */
+ if (!stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_TRUE;
+ }
+
+ texFormat = st_pipe_format_to_mesa_format(res->format);
+
+ _mesa_init_teximage_fields(ctx, texImage,
+ res->width0, res->height0, 1, 0, GL_RGBA,
+ texFormat);
+
+ pipe_resource_reference(&stObj->pt, res);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ pipe_resource_reference(&stImage->pt, res);
+
+ u_sampler_view_default_template(&templ, res, res->format);
+ templ.u.tex.first_layer = index & 1;
+ templ.u.tex.last_layer = index & 1;
+ templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0);
+ templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1);
+ templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2);
+ templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3);
+ stObj->sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ);
+
+ stObj->width0 = res->width0;
+ stObj->height0 = res->height0;
+ stObj->depth0 = 1;
+ stObj->surface_format = res->format;
+
+ _mesa_dirty_texobj(ctx, texObj);
+}
+
+static void
+st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access,
+ GLboolean output, struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ const GLvoid *vdpSurface, GLuint index)
+{
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+
+ pipe_resource_reference(&stObj->pt, NULL);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ pipe_resource_reference(&stImage->pt, NULL);
+
+ _mesa_dirty_texobj(ctx, texObj);
+}
+
+void
+st_init_vdpau_functions(struct dd_function_table *functions)
+{
+ functions->VDPAUMapSurface = st_vdpau_map_surface;
+ functions->VDPAUUnmapSurface = st_vdpau_unmap_surface;
+}
diff --git a/src/mesa/state_tracker/st_vdpau.h b/src/mesa/state_tracker/st_vdpau.h
new file mode 100644
index 00000000000..59c744305cf
--- /dev/null
+++ b/src/mesa/state_tracker/st_vdpau.h
@@ -0,0 +1,42 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Christian König <[email protected]>
+ *
+ */
+
+#ifndef ST_VDPAU_H
+#define ST_VDPAU_H
+
+struct dd_function_table;
+
+extern void
+st_init_vdpau_functions(struct dd_function_table *functions);
+
+#endif /* ST_VDPAU_H */