diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch deleted file mode 100644 index 72840724c5..0000000000 --- a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0001-winsys-radeon-fix-killing-the-CS-thread.patch +++ /dev/null @@ -1,44 +0,0 @@ -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/8bbcc43/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch deleted file mode 100644 index 4fe504eb16..0000000000 --- a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0002-winsys-radeon-remove-cs_queue_empty.patch +++ /dev/null @@ -1,104 +0,0 @@ -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/8bbcc43/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch deleted file mode 100644 index cb5d210027..0000000000 --- a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0003-winsys-radeon-share-winsys-between-different-fd-s.patch +++ /dev/null @@ -1,59 +0,0 @@ -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/8bbcc43/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch deleted file mode 100644 index 617e77ea87..0000000000 --- a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0005-radeon-uvd-async-flush-the-UVD-cs.patch +++ /dev/null @@ -1,31 +0,0 @@ -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 - diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0005-radeon-uvd-move-alignment-to-winsys.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0005-radeon-uvd-move-alignment-to-winsys.patch new file mode 100644 index 0000000000..18edcc5708 --- /dev/null +++ b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0005-radeon-uvd-move-alignment-to-winsys.patch @@ -0,0 +1,53 @@ +From a1e9f01ef29e803b2eb10e53c342db702a2cdccf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sun, 22 Sep 2013 10:41:27 +0200 +Subject: [PATCH 5/9] radeon/uvd: move alignment to winsys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Similar to GFX and DMA. + +Signed-off-by: Christian König +--- + src/gallium/drivers/radeon/radeon_uvd.c | 6 ------ + src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 6 ++++++ + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c +index fa81105..a8b17e6 100644 +--- a/src/gallium/drivers/radeon/radeon_uvd.c ++++ b/src/gallium/drivers/radeon/radeon_uvd.c +@@ -104,12 +104,6 @@ static unsigned alloc_stream_handle() + /* flush IB to the hardware */ + static void flush(struct ruvd_decoder *dec) + { +- uint32_t *pm4 = dec->cs->buf; +- +- // align IB +- while(dec->cs->cdw % 16) +- pm4[dec->cs->cdw++] = RUVD_PKT2(); +- + dec->ws->cs_flush(dec->cs, RADEON_FLUSH_ASYNC, 0); + } + +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +index d530011..62f7704 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +@@ -494,6 +494,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, ui + OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ + } + break; ++ case RING_UVD: ++ while (rcs->cdw & 15) ++ OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ ++ break; ++ default: ++ break; + } + + if (rcs->cdw > RADEON_MAX_CMDBUF_DWORDS) { +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0006-st-vdpau-use-a-separate-lock-per-decoder.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0006-st-vdpau-use-a-separate-lock-per-decoder.patch new file mode 100644 index 0000000000..f3aeaa461a --- /dev/null +++ b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0006-st-vdpau-use-a-separate-lock-per-decoder.patch @@ -0,0 +1,103 @@ +From 760a3a7e464d1506ffbeaf8719abaa26d6bd0c03 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sun, 22 Sep 2013 12:16:20 +0200 +Subject: [PATCH 6/9] st/vdpau: use a separate lock per decoder +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König +--- + src/gallium/state_trackers/vdpau/decode.c | 20 +++++++++++--------- + src/gallium/state_trackers/vdpau/vdpau_private.h | 1 + + 2 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c +index b144b83..9a96a33 100644 +--- a/src/gallium/state_trackers/vdpau/decode.c ++++ b/src/gallium/state_trackers/vdpau/decode.c +@@ -130,6 +130,8 @@ vlVdpDecoderCreate(VdpDevice device, + ret = VDP_STATUS_ERROR; + goto error_handle; + } ++ ++ pipe_mutex_init(vldecoder->mutex); + pipe_mutex_unlock(dev->mutex); + + return VDP_STATUS_OK; +@@ -155,9 +157,10 @@ vlVdpDecoderDestroy(VdpDecoder decoder) + if (!vldecoder) + return VDP_STATUS_INVALID_HANDLE; + +- pipe_mutex_lock(vldecoder->device->mutex); ++ pipe_mutex_lock(vldecoder->mutex); + vldecoder->decoder->destroy(vldecoder->decoder); +- pipe_mutex_unlock(vldecoder->device->mutex); ++ pipe_mutex_unlock(vldecoder->mutex); ++ pipe_mutex_destroy(vldecoder->mutex); + + vlRemoveDataHTAB(decoder); + FREE(vldecoder); +@@ -478,8 +481,6 @@ vlVdpDecoderRender(VdpDecoder decoder, + // TODO: Recreate decoder with correct chroma + return VDP_STATUS_INVALID_CHROMA_TYPE; + +- pipe_mutex_lock(vlsurf->device->mutex); +- + buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, + PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE); + buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, +@@ -490,6 +491,8 @@ vlVdpDecoderRender(VdpDecoder decoder, + dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) || + !buffer_support[vlsurf->video_buffer->interlaced]) { + ++ pipe_mutex_lock(vlsurf->device->mutex); ++ + /* destroy the old one */ + if (vlsurf->video_buffer) + vlsurf->video_buffer->destroy(vlsurf->video_buffer); +@@ -511,6 +514,7 @@ vlVdpDecoderRender(VdpDecoder decoder, + return VDP_STATUS_NO_IMPLEMENTATION; + } + vlVdpVideoSurfaceClear(vlsurf); ++ pipe_mutex_unlock(vlsurf->device->mutex); + } + + for (i = 0; i < bitstream_buffer_count; ++i) { +@@ -536,18 +540,16 @@ vlVdpDecoderRender(VdpDecoder decoder, + ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info); + break; + default: +- pipe_mutex_unlock(vlsurf->device->mutex); + return VDP_STATUS_INVALID_DECODER_PROFILE; + } + +- if (ret != VDP_STATUS_OK) { +- pipe_mutex_unlock(vlsurf->device->mutex); ++ if (ret != VDP_STATUS_OK) + return ret; +- } + ++ pipe_mutex_lock(vldecoder->mutex); + dec->begin_frame(dec, vlsurf->video_buffer, &desc.base); + dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes); + dec->end_frame(dec, vlsurf->video_buffer, &desc.base); +- pipe_mutex_unlock(vlsurf->device->mutex); ++ pipe_mutex_unlock(vldecoder->mutex); + return ret; + } +diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h +index 54545fe..0812767 100644 +--- a/src/gallium/state_trackers/vdpau/vdpau_private.h ++++ b/src/gallium/state_trackers/vdpau/vdpau_private.h +@@ -387,6 +387,7 @@ typedef struct + typedef struct + { + vlVdpDevice *device; ++ pipe_mutex mutex; + struct pipe_video_codec *decoder; + } vlVdpDecoder; + +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0007-radeon-winsys-keep-screen-pointer-in-winsys.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0007-radeon-winsys-keep-screen-pointer-in-winsys.patch new file mode 100644 index 0000000000..1283f3ea05 --- /dev/null +++ b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0007-radeon-winsys-keep-screen-pointer-in-winsys.patch @@ -0,0 +1,479 @@ +From 43fc7abc4ec27aa99fbfb0e72fa4ff6bb4663b0f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sun, 22 Sep 2013 13:18:30 +0200 +Subject: [PATCH 7/9] radeon/winsys: keep screen pointer in winsys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Only create one screen for each winsys instance. +This helps with buffer sharing and interop handling. + +Signed-off-by: Christian König +--- + src/gallium/drivers/r300/r300_screen.c | 3 +++ + src/gallium/drivers/r600/r600_pipe.c | 3 +++ + src/gallium/drivers/radeonsi/radeonsi_pipe.c | 3 +++ + src/gallium/targets/dri-r300/target.c | 13 ++++++++----- + src/gallium/targets/dri-r600/target.c | 13 ++++++++----- + src/gallium/targets/dri-radeonsi/target.c | 13 ++++++++----- + src/gallium/targets/vdpau-r300/target.c | 13 ++++++++----- + src/gallium/targets/vdpau-r600/target.c | 13 ++++++++----- + src/gallium/targets/vdpau-radeonsi/target.c | 13 ++++++++----- + src/gallium/targets/xorg-r600/target.c | 13 ++++++++----- + src/gallium/targets/xorg-radeonsi/target.c | 13 ++++++++----- + src/gallium/targets/xvmc-r300/target.c | 13 ++++++++----- + src/gallium/targets/xvmc-r600/target.c | 13 ++++++++----- + src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 4 ---- + src/gallium/winsys/radeon/drm/radeon_winsys.h | 5 +++++ + 15 files changed, 94 insertions(+), 54 deletions(-) + +diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c +index 063bc09..45a815a 100644 +--- a/src/gallium/drivers/r300/r300_screen.c ++++ b/src/gallium/drivers/r300/r300_screen.c +@@ -540,6 +540,9 @@ static void r300_destroy_screen(struct pipe_screen* pscreen) + struct r300_screen* r300screen = r300_screen(pscreen); + struct radeon_winsys *rws = radeon_winsys(pscreen); + ++ if (rws && !pipe_reference(&rws->reference, NULL)) ++ return; ++ + pipe_mutex_destroy(r300screen->cmask_mutex); + + if (rws) +diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c +index 50ff06c..4dee37b 100644 +--- a/src/gallium/drivers/r600/r600_pipe.c ++++ b/src/gallium/drivers/r600/r600_pipe.c +@@ -958,6 +958,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen) + if (rscreen == NULL) + return; + ++ if (!pipe_reference(&rscreen->b.ws->reference, NULL)) ++ return; ++ + pipe_mutex_destroy(rscreen->aux_context_lock); + rscreen->aux_context->destroy(rscreen->aux_context); + +diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c +index 138268c..8529380 100644 +--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c ++++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c +@@ -648,6 +648,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen) + if (rscreen == NULL) + return; + ++ if (!pipe_reference(&rscreen->b.ws->reference, NULL)) ++ return; ++ + if (rscreen->fences.bo) { + struct r600_fence_block *entry, *tmp; + +diff --git a/src/gallium/targets/dri-r300/target.c b/src/gallium/targets/dri-r300/target.c +index 07b0705..d363885 100644 +--- a/src/gallium/targets/dri-r300/target.c ++++ b/src/gallium/targets/dri-r300/target.c +@@ -1,25 +1,28 @@ + #include "target-helpers/inline_debug_helper.h" + #include "state_tracker/drm_driver.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r300/r300_public.h" + + static struct pipe_screen * + create_screen(int fd) + { + struct radeon_winsys *sws; +- struct pipe_screen *screen; + + sws = radeon_drm_winsys_create(fd); + if (!sws) + return NULL; + +- screen = r300_screen_create(sws); +- if (!screen) ++ if (sws->screen) ++ return sws->screen; ++ ++ sws->screen = r300_screen_create(sws); ++ if (!sws->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ sws->screen = debug_screen_wrap(sws->screen); + +- return screen; ++ return sws->screen; + } + + DRM_DRIVER_DESCRIPTOR("r300", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/dri-r600/target.c b/src/gallium/targets/dri-r600/target.c +index 9bff6f2..3fc4422 100644 +--- a/src/gallium/targets/dri-r600/target.c ++++ b/src/gallium/targets/dri-r600/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r600/r600_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = r600_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = r600_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + static const struct drm_conf_ret throttle_ret = { +diff --git a/src/gallium/targets/dri-radeonsi/target.c b/src/gallium/targets/dri-radeonsi/target.c +index 1350ba2..a294633 100644 +--- a/src/gallium/targets/dri-radeonsi/target.c ++++ b/src/gallium/targets/dri-radeonsi/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "radeonsi/radeonsi_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = radeonsi_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = radeonsi_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + static const struct drm_conf_ret throttle_ret = { +diff --git a/src/gallium/targets/vdpau-r300/target.c b/src/gallium/targets/vdpau-r300/target.c +index 2fd7c2f..042e080 100644 +--- a/src/gallium/targets/vdpau-r300/target.c ++++ b/src/gallium/targets/vdpau-r300/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r300/r300_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = r300_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = r300_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + DRM_DRIVER_DESCRIPTOR("r300", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/vdpau-r600/target.c b/src/gallium/targets/vdpau-r600/target.c +index 3b7795b..b51c6af 100644 +--- a/src/gallium/targets/vdpau-r600/target.c ++++ b/src/gallium/targets/vdpau-r600/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r600/r600_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = r600_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = r600_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/vdpau-radeonsi/target.c b/src/gallium/targets/vdpau-radeonsi/target.c +index ffb6662..4d0b9e9 100644 +--- a/src/gallium/targets/vdpau-radeonsi/target.c ++++ b/src/gallium/targets/vdpau-radeonsi/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "radeonsi/radeonsi_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = radeonsi_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = radeonsi_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + DRM_DRIVER_DESCRIPTOR("radeonsi", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/xorg-r600/target.c b/src/gallium/targets/xorg-r600/target.c +index 75785da..81b5488 100644 +--- a/src/gallium/targets/xorg-r600/target.c ++++ b/src/gallium/targets/xorg-r600/target.c +@@ -2,25 +2,28 @@ + #include "target-helpers/inline_debug_helper.h" + #include "state_tracker/drm_driver.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r600/r600_public.h" + + static struct pipe_screen * + create_screen(int fd) + { + struct radeon_winsys *sws; +- struct pipe_screen *screen; + + sws = radeon_drm_winsys_create(fd); + if (!sws) + return NULL; + +- screen = r600_screen_create(sws); +- if (!screen) ++ if (sws->screen) ++ return sws->screen; ++ ++ sws->screen = r600_screen_create(sws); ++ if (!sws->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ sws->screen = debug_screen_wrap(sws->screen); + +- return screen; ++ return sws->screen; + } + + DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/xorg-radeonsi/target.c b/src/gallium/targets/xorg-radeonsi/target.c +index c023c68..6e618ad 100644 +--- a/src/gallium/targets/xorg-radeonsi/target.c ++++ b/src/gallium/targets/xorg-radeonsi/target.c +@@ -2,25 +2,28 @@ + #include "target-helpers/inline_debug_helper.h" + #include "state_tracker/drm_driver.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "radeonsi/radeonsi_public.h" + + static struct pipe_screen * + create_screen(int fd) + { + struct radeon_winsys *sws; +- struct pipe_screen *screen; + + sws = radeon_drm_winsys_create(fd); + if (!sws) + return NULL; + +- screen = radeonsi_screen_create(sws); +- if (!screen) ++ if (sws->screen) ++ return sws->screen; ++ ++ sws->screen = radeonsi_screen_create(sws); ++ if (!sws->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ sws->screen = debug_screen_wrap(sws->screen); + +- return screen; ++ return sws->screen; + } + + DRM_DRIVER_DESCRIPTOR("radeonsi", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/xvmc-r300/target.c b/src/gallium/targets/xvmc-r300/target.c +index 2fd7c2f..042e080 100644 +--- a/src/gallium/targets/xvmc-r300/target.c ++++ b/src/gallium/targets/xvmc-r300/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r300/r300_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = r300_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = r300_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + DRM_DRIVER_DESCRIPTOR("r300", "radeon", create_screen, NULL) +diff --git a/src/gallium/targets/xvmc-r600/target.c b/src/gallium/targets/xvmc-r600/target.c +index 3b7795b..b51c6af 100644 +--- a/src/gallium/targets/xvmc-r600/target.c ++++ b/src/gallium/targets/xvmc-r600/target.c +@@ -1,24 +1,27 @@ + #include "state_tracker/drm_driver.h" + #include "target-helpers/inline_debug_helper.h" + #include "radeon/drm/radeon_drm_public.h" ++#include "radeon/drm/radeon_winsys.h" + #include "r600/r600_public.h" + + static struct pipe_screen *create_screen(int fd) + { + struct radeon_winsys *radeon; +- struct pipe_screen *screen; + + radeon = radeon_drm_winsys_create(fd); + if (!radeon) + return NULL; + +- screen = r600_screen_create(radeon); +- if (!screen) ++ if (radeon->screen) ++ return radeon->screen; ++ ++ radeon->screen = r600_screen_create(radeon); ++ if (!radeon->screen) + return NULL; + +- screen = debug_screen_wrap(screen); ++ radeon->screen = debug_screen_wrap(radeon->screen); + +- return screen; ++ return radeon->screen; + } + + DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen, NULL) +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +index 61f0913..4f43093 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +@@ -424,10 +424,6 @@ 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); +diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h +index 1367982..7ed2437 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h ++++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h +@@ -208,6 +208,11 @@ struct radeon_winsys { + struct pipe_reference reference; + + /** ++ * The screen object this winsys was created for ++ */ ++ struct pipe_screen *screen; ++ ++ /** + * Destroy this winsys. + * + * \param ws The winsys this function is called from. +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0008-radeon-uvd-try-to-place-msg-fb-buffer-into-GART.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0008-radeon-uvd-try-to-place-msg-fb-buffer-into-GART.patch new file mode 100644 index 0000000000..5da4930cea --- /dev/null +++ b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0008-radeon-uvd-try-to-place-msg-fb-buffer-into-GART.patch @@ -0,0 +1,40 @@ +From e5e2ed6a6f05200cfa8652cd9dff046d1c2c485d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Sun, 22 Sep 2013 15:59:17 +0200 +Subject: [PATCH 8/9] radeon/uvd: try to place msg/fb buffer into GART +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is only supported on NI+, but the kernel takes care of those limitations. + +Signed-off-by: Christian König +--- + src/gallium/drivers/radeon/radeon_uvd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c +index a8b17e6..382b410 100644 +--- a/src/gallium/drivers/radeon/radeon_uvd.c ++++ b/src/gallium/drivers/radeon/radeon_uvd.c +@@ -148,7 +148,7 @@ static void send_msg(struct ruvd_decoder *dec, struct ruvd_msg *msg) + + /* and send it to the hardware */ + send_cmd(dec, RUVD_CMD_MSG_BUFFER, buf->cs_handle, 0, +- RADEON_USAGE_READ, RADEON_DOMAIN_VRAM); ++ RADEON_USAGE_READ, RADEON_DOMAIN_GTT); + } + + /* create a buffer in the winsys */ +@@ -794,7 +794,7 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder, + send_cmd(dec, RUVD_CMD_DECODING_TARGET_BUFFER, dt, 0, + RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM); + send_cmd(dec, RUVD_CMD_FEEDBACK_BUFFER, msg_fb_buf->cs_handle, +- 0x1000, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM); ++ 0x1000, RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT); + set_reg(dec, RUVD_ENGINE_CNTL, 1); + + flush(dec); +-- +1.8.3.1 + diff --git a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0004-implement-NV_vdpau_interop-v3.patch b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0009-implement-NV_vdpau_interop-v4.patch similarity index 96% rename from packages/graphics/Mesa/patches/8bbcc43/Mesa-0004-implement-NV_vdpau_interop-v3.patch rename to packages/graphics/Mesa/patches/8bbcc43/Mesa-0009-implement-NV_vdpau_interop-v4.patch index 2e6611b823..44f4cb9322 100644 --- a/packages/graphics/Mesa/patches/8bbcc43/Mesa-0004-implement-NV_vdpau_interop-v3.patch +++ b/packages/graphics/Mesa/patches/8bbcc43/Mesa-0009-implement-NV_vdpau_interop-v4.patch @@ -1,7 +1,7 @@ -From a51bdb6ea7bd9ac99d035253bf217e1bd7ac2efc Mon Sep 17 00:00:00 2001 +From b9c03e373b1771055527ca2917139ed1ac171350 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 +Subject: [PATCH 9/9] implement NV_vdpau_interop v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -12,6 +12,8 @@ v2: Actually implement interop between the gallium v3: Make it also available in non legacy contexts, fix video buffer sharing. +v4: deny interop if we don't have the same screen object + Signed-off-by: Christian König --- src/gallium/include/state_tracker/vdpau_interop.h | 49 ++++ @@ -31,9 +33,9 @@ Signed-off-by: Christian König 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.c | 181 ++++++++++++++ src/mesa/state_tracker/st_vdpau.h | 42 ++++ - 19 files changed, 800 insertions(+), 9 deletions(-) + 19 files changed, 788 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 @@ -199,7 +201,7 @@ index 8e39d68..dd434aa 100644 + 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 +index 0812767..dffc7aa 100644 --- a/src/gallium/state_trackers/vdpau/vdpau_private.h +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h @@ -36,6 +36,8 @@ @@ -211,7 +213,7 @@ index 54545fe..fe3bc3e 100644 #include "util/u_debug.h" #include "util/u_rect.h" #include "os/os_thread.h" -@@ -474,6 +476,10 @@ VdpVideoMixerGetAttributeValues vlVdpVideoMixerGetAttributeValues; +@@ -475,6 +477,10 @@ VdpVideoMixerGetAttributeValues vlVdpVideoMixerGetAttributeValues; VdpVideoMixerDestroy vlVdpVideoMixerDestroy; VdpGenerateCSCMatrix vlVdpGenerateCSCMatrix; @@ -815,10 +817,10 @@ index 97dd732..2898a8d 100644 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 +index 0000000..406df0f --- /dev/null +++ b/src/mesa/state_tracker/st_vdpau.c -@@ -0,0 +1,193 @@ +@@ -0,0 +1,181 @@ +/************************************************************************** + * + * Copyright 2013 Advanced Micro Devices, Inc. @@ -860,7 +862,6 @@ index 0000000..c6ca909 +#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" @@ -903,19 +904,6 @@ index 0000000..c6ca909 + 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; + @@ -946,10 +934,6 @@ index 0000000..c6ca909 + } + + 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) { @@ -957,6 +941,12 @@ index 0000000..c6ca909 + return; + } + ++ /* do we have different screen objects ? */ ++ if (res->screen != st->pipe->screen) { ++ _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); ++ return; ++ } ++ + /* switch to surface based */ + if (!stObj->surface_based) { + _mesa_clear_texture_object(ctx, texObj);