[Mesa-dev] [PATCH 2/2] implement NV_vdpau_interop v3
Marek Olšák
maraeo at gmail.com
Sat Sep 21 07:56:41 PDT 2013
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
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at 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.koenig at 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.koenig at 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.koenig at 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.koenig at 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.koenig at 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.koenig at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list