diff --git a/packages/graphics/Mesa/patches/1569b3e/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch b/packages/graphics/Mesa/patches/1569b3e/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch new file mode 100644 index 0000000000..72840724c5 --- /dev/null +++ b/packages/graphics/Mesa/patches/1569b3e/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch @@ -0,0 +1,44 @@ +From 42a34d19fd3891cdbe0d41482288ebba5dfddc64 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sat, 21 Sep 2013 13:21:47 +0200 +Subject: [PATCH 1/5] winsys/radeon: fix killing the CS thread +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Kill the thread only after we checked that it's not used any more, not before. + +Signed-off-by: Christian König +--- + src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +index 69c42a0..0a3b932 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +@@ -421,6 +421,10 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) + { + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + ++ if (!pipe_reference(&ws->base.reference, NULL)) { ++ return; ++ } ++ + if (ws->thread) { + ws->kill_thread = 1; + pipe_semaphore_signal(&ws->cs_queued); +@@ -429,10 +433,6 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) + pipe_semaphore_destroy(&ws->cs_queued); + pipe_condvar_destroy(ws->cs_queue_empty); + +- if (!pipe_reference(&ws->base.reference, NULL)) { +- return; +- } +- + pipe_mutex_destroy(ws->hyperz_owner_mutex); + pipe_mutex_destroy(ws->cmask_owner_mutex); + pipe_mutex_destroy(ws->cs_stack_lock); +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/1569b3e/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch b/packages/graphics/Mesa/patches/1569b3e/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch new file mode 100644 index 0000000000..4fe504eb16 --- /dev/null +++ b/packages/graphics/Mesa/patches/1569b3e/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch @@ -0,0 +1,104 @@ +From 295eb75d53547fa7dcc6b188e423debbba1888ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sat, 21 Sep 2013 15:24:55 +0200 +Subject: [PATCH 2/5] winsys/radeon: remove cs_queue_empty +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Waiting for an empty queue is nonsense and can lead to deadlocks if we have +multiple waiters or another thread that continuously sends down new commands. + +Just post the cs to the queue and immediately wait for it to finish. + +This is a candidate for the stable branch. + +Signed-off-by: Christian König +--- + src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 11 +++-------- + src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 6 ------ + src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 5 ----- + 3 files changed, 3 insertions(+), 19 deletions(-) + +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +index 38a9209..d530011 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +@@ -560,17 +560,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, ui + break; + } + +- if (cs->ws->thread && (flags & RADEON_FLUSH_ASYNC)) { ++ if (cs->ws->thread) { + cs->flush_started = 1; + radeon_drm_ws_queue_cs(cs->ws, cs); ++ if (!(flags & RADEON_FLUSH_ASYNC)) ++ radeon_drm_cs_sync_flush(rcs); + } else { +- pipe_mutex_lock(cs->ws->cs_stack_lock); +- if (cs->ws->thread) { +- while (p_atomic_read(&cs->ws->ncs)) { +- pipe_condvar_wait(cs->ws->cs_queue_empty, cs->ws->cs_stack_lock); +- } +- } +- pipe_mutex_unlock(cs->ws->cs_stack_lock); + radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst); + } + } else { +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +index 0a3b932..27bf348 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +@@ -431,7 +431,6 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) + pipe_thread_wait(ws->thread); + } + pipe_semaphore_destroy(&ws->cs_queued); +- pipe_condvar_destroy(ws->cs_queue_empty); + + pipe_mutex_destroy(ws->hyperz_owner_mutex); + pipe_mutex_destroy(ws->cmask_owner_mutex); +@@ -567,9 +566,6 @@ next: + } + ws->cs_stack[p_atomic_read(&ws->ncs) - 1] = NULL; + empty_stack = p_atomic_dec_zero(&ws->ncs); +- if (empty_stack) { +- pipe_condvar_signal(ws->cs_queue_empty); +- } + pipe_mutex_unlock(ws->cs_stack_lock); + + pipe_semaphore_signal(&cs->flush_completed); +@@ -585,7 +581,6 @@ next: + ws->cs_stack[i] = NULL; + } + p_atomic_set(&ws->ncs, 0); +- pipe_condvar_signal(ws->cs_queue_empty); + pipe_mutex_unlock(ws->cs_stack_lock); + return NULL; + } +@@ -651,7 +646,6 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd) + + p_atomic_set(&ws->ncs, 0); + pipe_semaphore_init(&ws->cs_queued, 0); +- pipe_condvar_init(ws->cs_queue_empty); + if (ws->num_cpus > 1 && debug_get_option_thread()) + ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws); + +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h +index 682479e..ed90194 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h +@@ -67,11 +67,6 @@ struct radeon_drm_winsys { + /* rings submission thread */ + pipe_mutex cs_stack_lock; + pipe_semaphore cs_queued; +- /* we cannot use semaphore for empty queue because maintaining an even +- * number of call to semaphore_wait and semaphore_signal is, to say the +- * least, tricky +- */ +- pipe_condvar cs_queue_empty; + pipe_thread thread; + int kill_thread; + int ncs; +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/1569b3e/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch b/packages/graphics/Mesa/patches/1569b3e/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch new file mode 100644 index 0000000000..cb5d210027 --- /dev/null +++ b/packages/graphics/Mesa/patches/1569b3e/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch @@ -0,0 +1,59 @@ +From ab56fbbdb774eeffb232a6995fe350dd6d44ff55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sat, 21 Sep 2013 12:25:13 +0200 +Subject: [PATCH 3/5] winsys/radeon: share winsys between different fd's +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Share the winsys between different fd's if they point to the same device. + +Signed-off-by: Christian König +--- + src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +index 27bf348..61f0913 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +@@ -41,6 +41,9 @@ + + #include + #include ++#include ++#include ++#include + + /* + * this are copy from radeon_drm, once an updated libdrm is released +@@ -519,12 +522,24 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws, + + static unsigned hash_fd(void *key) + { +- return pointer_to_intptr(key); ++ int fd = pointer_to_intptr(key); ++ struct stat stat; ++ fstat(fd, &stat); ++ ++ return stat.st_dev ^ stat.st_ino ^ stat.st_rdev; + } + + static int compare_fd(void *key1, void *key2) + { +- return pointer_to_intptr(key1) != pointer_to_intptr(key2); ++ int fd1 = pointer_to_intptr(key1); ++ int fd2 = pointer_to_intptr(key2); ++ struct stat stat1, stat2; ++ fstat(fd1, &stat1); ++ fstat(fd2, &stat2); ++ ++ return stat1.st_dev != stat2.st_dev || ++ stat1.st_ino != stat2.st_ino || ++ stat1.st_rdev != stat2.st_rdev; + } + + void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs) +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/1569b3e/Mesa-0004-implement-NV_vdpau_interop-v3.patch b/packages/graphics/Mesa/patches/1569b3e/Mesa-0004-implement-NV_vdpau_interop-v3.patch new file mode 100644 index 0000000000..2e6611b823 --- /dev/null +++ b/packages/graphics/Mesa/patches/1569b3e/Mesa-0004-implement-NV_vdpau_interop-v3.patch @@ -0,0 +1,1065 @@ +From a51bdb6ea7bd9ac99d035253bf217e1bd7ac2efc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Wed, 15 May 2013 15:10:11 +0200 +Subject: [PATCH 4/5] implement NV_vdpau_interop v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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 +--- + 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 ++ * ++ */ ++ ++#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 ++ ++#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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ + + + ++ ++ + +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 ++ * ++ */ ++ ++#include ++#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 ++ * ++ */ ++ ++#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 ++ * ++ */ ++ ++#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 ++ * ++ */ ++ ++#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.3.1 + diff --git a/packages/graphics/Mesa/patches/1569b3e/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch b/packages/graphics/Mesa/patches/1569b3e/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch new file mode 100644 index 0000000000..617e77ea87 --- /dev/null +++ b/packages/graphics/Mesa/patches/1569b3e/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch @@ -0,0 +1,31 @@ +From 1ee590c6f238b638d663af889201d584239b7f73 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sat, 21 Sep 2013 15:34:38 +0200 +Subject: [PATCH 5/5] radeon/uvd: async flush the UVD cs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +No need to block for the CS thread here. + +Signed-off-by: Christian König +--- + src/gallium/drivers/radeon/radeon_uvd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c +index 518978e..fa81105 100644 +--- a/src/gallium/drivers/radeon/radeon_uvd.c ++++ b/src/gallium/drivers/radeon/radeon_uvd.c +@@ -110,7 +110,7 @@ static void flush(struct ruvd_decoder *dec) + while(dec->cs->cdw % 16) + pm4[dec->cs->cdw++] = RUVD_PKT2(); + +- dec->ws->cs_flush(dec->cs, 0, 0); ++ dec->ws->cs_flush(dec->cs, RADEON_FLUSH_ASYNC, 0); + } + + /* add a new set register command to the IB */ +-- +1.8.3.1 +