1) The Errors section of the spec isn't implemented properly. 2) Passing GL_TEXTURE_RECTANGLE to the new functions should generate an error if ctx->Extensions.NV_texture_rectangle is false.
3) There should also probably be some checking for GL_ARB_texture_non_power_of_two, but the spec doesn't say what we should do (probably return GL_INVALID_OPERATION). 4) VDPAUGetSurfaceivNV isn't implemented properly. 5) The unregistering in VDPAUFiniNV should be implemented too. 6) Registered and mapped VDPAU textures are not allowed to be re-specified by TexImage, TexSubImage, TexImage*Multisample, CopyTexImage, CopyTexSubImage, TexStorage, TexStorage*Multisample, and similar functions. This should be properly handled in those functions and GL errors should be returned. 7) The extension spec says that all VDPAU textures should be y-inverted. Is that actually the case here? 8) Do we actually have enough tests, so that we can say this feature works? Marek On Sat, Sep 21, 2013 at 12:32 PM, Christian König <deathsim...@vodafone.de> wrote: > From: Christian König <christian.koe...@amd.com> > > 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. > > Signed-off-by: Christian König <christian.koe...@amd.com> > --- > src/gallium/include/state_tracker/vdpau_interop.h | 49 ++++ > src/gallium/state_trackers/vdpau/ftab.c | 31 ++- > src/gallium/state_trackers/vdpau/output.c | 11 + > src/gallium/state_trackers/vdpau/surface.c | 21 ++ > src/gallium/state_trackers/vdpau/vdpau_private.h | 6 + > src/mapi/glapi/gen/Makefile.am | 1 + > src/mapi/glapi/gen/NV_vdpau_interop.xml | 69 ++++++ > src/mapi/glapi/gen/gl_API.xml | 2 + > src/mapi/glapi/gen/gl_genexec.py | 1 + > src/mesa/Makefile.sources | 4 +- > src/mesa/main/dd.h | 14 ++ > src/mesa/main/extensions.c | 1 + > src/mesa/main/mtypes.h | 9 + > src/mesa/main/vdpau.c | 279 > ++++++++++++++++++++++ > src/mesa/main/vdpau.h | 72 ++++++ > src/mesa/state_tracker/st_context.c | 3 + > src/mesa/state_tracker/st_extensions.c | 1 + > src/mesa/state_tracker/st_vdpau.c | 193 +++++++++++++++ > src/mesa/state_tracker/st_vdpau.h | 42 ++++ > 19 files changed, 800 insertions(+), 9 deletions(-) > create mode 100644 src/gallium/include/state_tracker/vdpau_interop.h > create mode 100644 src/mapi/glapi/gen/NV_vdpau_interop.xml > create mode 100644 src/mesa/main/vdpau.c > create mode 100644 src/mesa/main/vdpau.h > create mode 100644 src/mesa/state_tracker/st_vdpau.c > create mode 100644 src/mesa/state_tracker/st_vdpau.h > > diff --git a/src/gallium/include/state_tracker/vdpau_interop.h > b/src/gallium/include/state_tracker/vdpau_interop.h > new file mode 100644 > index 0000000..3ca7c9d > --- /dev/null > +++ b/src/gallium/include/state_tracker/vdpau_interop.h > @@ -0,0 +1,49 @@ > +/************************************************************************** > + * > + * 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 <christian.koe...@amd.com> > + * > + */ > + > +#ifndef _VDPAU_INTEROP_H_ > +#define _VDPAU_INTEROP_H_ > + > +/* driver specific functions for NV_vdpau_interop */ > + > +#define VDP_FUNC_ID_BASE_DRIVER 0x2000 > +#define VDP_FUNC_ID_VIDEO_SURFACE_GALLIUM (VDP_FUNC_ID_BASE_DRIVER + 0) > +#define VDP_FUNC_ID_OUTPUT_SURFACE_GALLIUM (VDP_FUNC_ID_BASE_DRIVER + 1) > + > +struct pipe_resource; > +struct pipe_video_buffer; > + > +typedef struct pipe_video_buffer *VdpVideoSurfaceGallium(uint32_t surface); > +typedef struct pipe_resource *VdpOutputSurfaceGallium(uint32_t surface); > + > +#endif /* _VDPAU_INTEROP_H_ */ > diff --git a/src/gallium/state_trackers/vdpau/ftab.c > b/src/gallium/state_trackers/vdpau/ftab.c > index 81d16ec..2c84554 100644 > --- a/src/gallium/state_trackers/vdpau/ftab.c > +++ b/src/gallium/state_trackers/vdpau/ftab.c > @@ -26,6 +26,9 @@ > **************************************************************************/ > > #include <assert.h> > + > +#include "util/u_memory.h" > + > #include "vdpau_private.h" > > static void* ftab[67] = > @@ -104,19 +107,31 @@ static void* ftab_winsys[1] = > &vlVdpPresentationQueueTargetCreateX11 /* > VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11 */ > }; > > +static void* ftab_driver[2] = > +{ > + &vlVdpVideoSurfaceGallium, /* VDP_FUNC_ID_SURFACE_GALLIUM */ > + &vlVdpOutputSurfaceGallium /* VDP_FUNC_ID_OUTPUT_SURFACE_GALLIUM */ > +}; > + > boolean vlGetFuncFTAB(VdpFuncId function_id, void **func) > { > assert(func); > + *func = NULL; > + > if (function_id < VDP_FUNC_ID_BASE_WINSYS) { > - if (function_id > 66) > - return FALSE; > - *func = ftab[function_id]; > - } > - else { > + if (function_id < Elements(ftab)) > + *func = ftab[function_id]; > + > + } else if (function_id < VDP_FUNC_ID_BASE_DRIVER) { > function_id -= VDP_FUNC_ID_BASE_WINSYS; > - if (function_id > 0) > - return FALSE; > - *func = ftab_winsys[function_id]; > + if (function_id < Elements(ftab_winsys)) > + *func = ftab_winsys[function_id]; > + > + } else { > + function_id -= VDP_FUNC_ID_BASE_DRIVER; > + if (function_id < Elements(ftab_driver)) > + *func = ftab_driver[function_id]; > } > + > return *func != NULL; > } > diff --git a/src/gallium/state_trackers/vdpau/output.c > b/src/gallium/state_trackers/vdpau/output.c > index 7266cdb..35da715 100644 > --- a/src/gallium/state_trackers/vdpau/output.c > +++ b/src/gallium/state_trackers/vdpau/output.c > @@ -724,3 +724,14 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface > destination_surface, > > return VDP_STATUS_OK; > } > + > +struct pipe_resource *vlVdpOutputSurfaceGallium(VdpOutputSurface surface) > +{ > + vlVdpOutputSurface *vlsurface; > + > + vlsurface = vlGetDataHTAB(surface); > + if (!vlsurface || !vlsurface->surface) > + return NULL; > + > + return vlsurface->surface->texture; > +} > diff --git a/src/gallium/state_trackers/vdpau/surface.c > b/src/gallium/state_trackers/vdpau/surface.c > index 8e39d68..dd434aa 100644 > --- a/src/gallium/state_trackers/vdpau/surface.c > +++ b/src/gallium/state_trackers/vdpau/surface.c > @@ -359,3 +359,24 @@ vlVdpVideoSurfaceClear(vlVdpSurface *vlsurf) > } > pipe->flush(pipe, NULL, 0); > } > + > +/** > + * Interop to mesa state tracker > + */ > +struct pipe_video_buffer *vlVdpVideoSurfaceGallium(VdpVideoSurface surface) > +{ > + vlVdpSurface *p_surf = vlGetDataHTAB(surface); > + if (!p_surf) > + return NULL; > + > + pipe_mutex_lock(p_surf->device->mutex); > + if (p_surf->video_buffer == NULL) { > + struct pipe_context *pipe = p_surf->device->context; > + > + /* try to create a video buffer if we don't already have one */ > + p_surf->video_buffer = pipe->create_video_buffer(pipe, > &p_surf->templat); > + } > + pipe_mutex_unlock(p_surf->device->mutex); > + > + return p_surf->video_buffer; > +} > diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h > b/src/gallium/state_trackers/vdpau/vdpau_private.h > index 54545fe..fe3bc3e 100644 > --- a/src/gallium/state_trackers/vdpau/vdpau_private.h > +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h > @@ -36,6 +36,8 @@ > #include "pipe/p_compiler.h" > #include "pipe/p_video_codec.h" > > +#include "state_tracker/vdpau_interop.h" > + > #include "util/u_debug.h" > #include "util/u_rect.h" > #include "os/os_thread.h" > @@ -474,6 +476,10 @@ VdpVideoMixerGetAttributeValues > vlVdpVideoMixerGetAttributeValues; > VdpVideoMixerDestroy vlVdpVideoMixerDestroy; > VdpGenerateCSCMatrix vlVdpGenerateCSCMatrix; > > +/* interop to mesa state tracker */ > +VdpVideoSurfaceGallium vlVdpVideoSurfaceGallium; > +VdpOutputSurfaceGallium vlVdpOutputSurfaceGallium; > + > #define VDPAU_OUT 0 > #define VDPAU_ERR 1 > #define VDPAU_WARN 2 > diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am > index d4fbd35..bd82e54 100644 > --- a/src/mapi/glapi/gen/Makefile.am > +++ b/src/mapi/glapi/gen/Makefile.am > @@ -131,6 +131,7 @@ API_XML = \ > NV_conditional_render.xml \ > NV_primitive_restart.xml \ > NV_texture_barrier.xml \ > + NV_vdpau_interop.xml \ > OES_EGL_image.xml \ > GL3x.xml > > diff --git a/src/mapi/glapi/gen/NV_vdpau_interop.xml > b/src/mapi/glapi/gen/NV_vdpau_interop.xml > new file mode 100644 > index 0000000..cf5f0ed > --- /dev/null > +++ b/src/mapi/glapi/gen/NV_vdpau_interop.xml > @@ -0,0 +1,69 @@ > +<?xml version="1.0"?> > +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> > + > +<OpenGLAPI> > + > +<category name="GL_NV_vdpau_interop" number="396"> > + > + <function name="VDPAUInitNV" offset="assign"> > + <param name="vdpDevice" type="const GLvoid *"/> > + <param name="getProcAddress" type="const GLvoid *"/> > + </function> > + > + <function name="VDPAUFiniNV" offset="assign"/> > + > + <function name="VDPAURegisterVideoSurfaceNV" offset="assign"> > + <return type="GLintptr"/> > + <param name="vdpSurface" type="const GLvoid *"/> > + <param name="target" type="GLenum"/> > + <param name="numTextureNames" type="GLsizei"/> > + <param name="textureNames" type="const GLuint *"/> > + </function> > + > + <function name="VDPAURegisterOutputSurfaceNV" offset="assign"> > + <return type="GLintptr"/> > + <param name="vdpSurface" type="const GLvoid *"/> > + <param name="target" type="GLenum"/> > + <param name="numTextureNames" type="GLsizei"/> > + <param name="textureNames" type="const GLuint *"/> > + </function> > + > + <function name="VDPAUIsSurfaceNV" offset="assign"> > + <param name="surface" type="GLintptr"/> > + </function> > + > + <function name="VDPAUUnregisterSurfaceNV" offset="assign"> > + <param name="surface" type="GLintptr"/> > + </function> > + > + <function name="VDPAUGetSurfaceivNV" offset="assign"> > + <param name="surface" type="GLintptr"/> > + <param name="pname" type="GLenum"/> > + <param name="bufSize" type="GLsizei"/> > + <param name="length" type="GLsizei *"/> > + <param name="values" type="GLint *"/> > + </function> > + > + <function name="VDPAUSurfaceAccessNV" offset="assign"> > + <param name="surface" type="GLintptr"/> > + <param name="access" type="GLenum"/> > + </function> > + > + <function name="VDPAUMapSurfacesNV" offset="assign"> > + <param name="numSurfaces" type="GLsizei"/> > + <param name="surfaces" type="const GLintptr *"/> > + </function> > + > + <function name="VDPAUUnmapSurfacesNV" offset="assign"> > + <param name="numSurfaces" type="GLsizei"/> > + <param name="surfaces" type="const GLintptr *"/> > + </function> > + > + <enum name="SURFACE_STATE_NV" value="0x86EB"/> > + <enum name="SURFACE_REGISTERED_NV" value="0x86FD"/> > + <enum name="SURFACE_MAPPED_NV" value="0x8700"/> > + <enum name="WRITE_DISCARD_NV" value="0x88BE"/> > + > +</category> > + > +</OpenGLAPI> > diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml > index 71aa9a7..5700caa 100644 > --- a/src/mapi/glapi/gen/gl_API.xml > +++ b/src/mapi/glapi/gen/gl_API.xml > @@ -13148,4 +13148,6 @@ > > <xi:include href="EXT_transform_feedback.xml" > xmlns:xi="http://www.w3.org/2001/XInclude"/> > > +<xi:include href="NV_vdpau_interop.xml" > xmlns:xi="http://www.w3.org/2001/XInclude"/> > + > </OpenGLAPI> > diff --git a/src/mapi/glapi/gen/gl_genexec.py > b/src/mapi/glapi/gen/gl_genexec.py > index be82f90..d76c7ae 100644 > --- a/src/mapi/glapi/gen/gl_genexec.py > +++ b/src/mapi/glapi/gen/gl_genexec.py > @@ -110,6 +110,7 @@ header = """/** > #include "main/syncobj.h" > #include "main/formatquery.h" > #include "main/dispatch.h" > +#include "main/vdpau.h" > #include "vbo/vbo.h" > > > diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources > index 122ea8e..85b4fe1 100644 > --- a/src/mesa/Makefile.sources > +++ b/src/mesa/Makefile.sources > @@ -107,6 +107,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 \ > @@ -247,7 +248,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 c1d9b2c..a3ee0b7 100644 > --- a/src/mesa/main/dd.h > +++ b/src/mesa/main/dd.h > @@ -843,6 +843,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 34615e3..a735e93 100644 > --- a/src/mesa/main/extensions.c > +++ b/src/mesa/main/extensions.c > @@ -332,6 +332,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 c88c1c6..40346e4 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -3196,6 +3196,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; > @@ -3726,6 +3727,14 @@ struct gl_context > struct st_context *st; > void *aelt_context; > /*@}*/ > + > + /** > + * \name NV_vdpau_interop > + */ > + /*@{*/ > + const void *vdpDevice; > + const void *vdpGetProcAddress; > + /*@}*/ > }; > > > diff --git a/src/mesa/main/vdpau.c b/src/mesa/main/vdpau.c > new file mode 100644 > index 0000000..68f087b > --- /dev/null > +++ b/src/mesa/main/vdpau.c > @@ -0,0 +1,279 @@ > +/************************************************************************** > + * > + * 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 <christian.koe...@amd.com> > + * > + */ > + > +#include <stdbool.h> > +#include "context.h" > +#include "glformats.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; > + 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) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUInitNV"); > + return; > + } > + > + ctx->vdpDevice = vdpDevice; > + ctx->vdpGetProcAddress = getProcAddress; > +} > + > +void GLAPIENTRY > +_mesa_VDPAUFiniNV() > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + if (!ctx->vdpDevice || !ctx->vdpGetProcAddress) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUFiniNV"); > + return; > + } > + > + /* TODO: unregister all surfaces */ > + > + ctx->vdpDevice = 0; > + ctx->vdpGetProcAddress = 0; > +} > + > +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) { > + _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; > + } > + > + surf = MALLOC_STRUCT( vdp_surface ); > + surf->vdpSurface = vdpSurface; > + surf->target = target; > + surf->access = GL_READ_WRITE; > + surf->output = isOutput; > + for (i = 0; i < numTextureNames; ++i) { > + struct gl_texture_object *tex; > + tex = _mesa_lookup_texture(ctx, textureNames[i]); > + > + if (tex->Target == 0) > + tex->Target = target; > + else if (tex->Target != target) { > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "VDPAURegisterSurfaceNV(target mismatch)"); > + return (GLintptr)NULL; > + } > + > + surf->textures[i] = tex; > + } > + > + 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) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + if (!ctx->vdpDevice || !ctx->vdpGetProcAddress) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUIsSurfaceNV"); > + return; > + } > +} > + > +void GLAPIENTRY > +_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface) > +{ > + FREE((struct vdp_surface *)surface); > +} > + > +void GLAPIENTRY > +_mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize, > + GLsizei *length, GLint *values) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + if (!ctx->vdpDevice || !ctx->vdpGetProcAddress) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUGetSurfaceivNV"); > + return; > + } > +} > + > +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) { > + _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) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV"); > + 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); > + } > + } > +} > + > +void GLAPIENTRY > +_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) > +{ > + GET_CURRENT_CONTEXT(ctx); > + int i, j; > + > + if (!ctx->vdpDevice || !ctx->vdpGetProcAddress) { > + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV"); > + 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); > + } > + } > +} > diff --git a/src/mesa/main/vdpau.h b/src/mesa/main/vdpau.h > new file mode 100644 > index 0000000..f32d6da > --- /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 <christian.koe...@amd.com> > + * > + */ > + > +#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 80393cf..1194437 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" > @@ -356,5 +357,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 97dd732..2898a8d 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 0000000..c6ca909 > --- /dev/null > +++ b/src/mesa/state_tracker/st_vdpau.c > @@ -0,0 +1,193 @@ > +/************************************************************************** > + * > + * 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 <christian.koe...@amd.com> > + * > + */ > + > +#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/drm_driver.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; > + } > + > + /* do we have different screen objects ? */ > + if (res->screen != st->pipe->screen) { > + struct winsys_handle handle; > + > + /* export the resource from the other context */ > + memset(&handle, 0, sizeof(handle)); > + handle.type = DRM_API_HANDLE_TYPE_SHARED; > + res->screen->resource_get_handle(res->screen, res, &handle); > + > + /* and import it into this one */ > + res = st->pipe->screen->resource_from_handle(st->pipe->screen, res, > &handle); > + } > + > + } 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; > + > + /* In theory we also need to reimport the buffer into the new screen, > + but that currently isn't specified. Just using the resource > + as it is does indeed seem to work.*/ > + } > + > + if (!res) { > + _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, GL_TRUE); > +} > + > +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, GL_TRUE); > +} > + > +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 0000000..59c7443 > --- /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 <christian.koe...@amd.com> > + * > + */ > + > +#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 */ > -- > 1.8.1.2 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev