gallium/radeon: create and return a fence in the flush function
authorMarek Olšák <marek.olsak@amd.com>
Sat, 12 Apr 2014 15:01:52 +0000 (17:01 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 16 Apr 2014 12:02:51 +0000 (14:02 +0200)
All flush functions get a fence parameter. cs_create_fence is removed.

Reviewed-by: Christian König <christian.koenig@amd.com>
20 files changed:
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r600/evergreen_compute.c
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeon/r600_buffer_common.c
src/gallium/drivers/radeon/r600_cs.h
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeon/radeon_uvd.c
src/gallium/drivers/radeon/radeon_vce.c
src/gallium/drivers/radeonsi/si_hw_context.c
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/winsys/radeon/drm/radeon_drm_bo.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.h
src/gallium/winsys/radeon/drm/radeon_winsys.h

index 0116d6c0683e884199c6ce592310762775e69301..7ae355189fc60354958b9553c1a4c7f3d78729c8 100644 (file)
@@ -123,11 +123,12 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300);
 }
 
-static void r300_flush_callback(void *data, unsigned flags)
+static void r300_flush_callback(void *data, unsigned flags,
+                               struct pipe_fence_handle **fence)
 {
     struct r300_context* const cs_context_copy = data;
 
-    r300_flush(&cs_context_copy->context, flags, NULL);
+    r300_flush(&cs_context_copy->context, flags, fence);
 }
 
 #define R300_INIT_ATOM(atomname, atomsize) \
index cbe2b5784489e73d9a850ab8a9f08c01c50c0cea..404c6fe11ec056446452bbed66117924ceff67f1 100644 (file)
@@ -34,7 +34,8 @@
 #include "r300_emit.h"
 
 
-static void r300_flush_and_cleanup(struct r300_context *r300, unsigned flags)
+static void r300_flush_and_cleanup(struct r300_context *r300, unsigned flags,
+                                   struct pipe_fence_handle **fence)
 {
     struct r300_atom *atom;
 
@@ -52,7 +53,7 @@ static void r300_flush_and_cleanup(struct r300_context *r300, unsigned flags)
     }
 
     r300->flush_counter++;
-    r300->rws->cs_flush(r300->cs, flags, 0);
+    r300->rws->cs_flush(r300->cs, flags, fence, 0);
     r300->dirty_hw = 0;
 
     /* New kitchen sink, baby. */
@@ -81,23 +82,19 @@ void r300_flush(struct pipe_context *pipe,
         flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
     }
 
-    if (fence) {
-        *fence = r300->rws->cs_create_fence(r300->cs);
-    }
-
     if (r300->dirty_hw) {
-        r300_flush_and_cleanup(r300, flags);
+        r300_flush_and_cleanup(r300, flags, fence);
     } else {
         if (fence) {
             /* We have to create a fence object, but the command stream is empty
              * and we cannot emit an empty CS. Let's write to some reg. */
             CS_LOCALS(r300);
             OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0);
-            r300->rws->cs_flush(r300->cs, flags, 0);
+            r300->rws->cs_flush(r300->cs, flags, fence, 0);
         } else {
             /* Even if hw is not dirty, we should at least reset the CS in case
              * the space checking failed for the first draw operation. */
-            r300->rws->cs_flush(r300->cs, flags, 0);
+            r300->rws->cs_flush(r300->cs, flags, NULL, 0);
         }
     }
 
@@ -119,7 +116,9 @@ void r300_flush(struct pipe_context *pipe,
                     r300_decompress_zmask(r300);
                 }
 
-                r300_flush_and_cleanup(r300, flags);
+                if (fence && *fence)
+                    r300->rws->fence_reference(fence, NULL);
+                r300_flush_and_cleanup(r300, flags, fence);
             }
 
             /* Revoke Hyper-Z access, so that some other process can take it. */
index aba34085dae12b105c944a09f772889c6e96ce2a..701bb5cfa709dfb08ca98613f4c920b2ae2c9010 100644 (file)
@@ -408,8 +408,8 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
        int i;
 
        /* make sure that the gfx ring is only one active */
-       if (ctx->b.rings.dma.cs) {
-               ctx->b.rings.dma.flush(ctx, RADEON_FLUSH_ASYNC);
+       if (ctx->b.rings.dma.cs && ctx->b.rings.dma.cs->cdw) {
+               ctx->b.rings.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
        }
 
        /* Initialize all the compute-related registers.
index 1884412cb29edfb119c5b6d023d41ded2a22abc6..60260eea0c563091bf311f2f463e27f3deaa850c 100644 (file)
@@ -37,7 +37,7 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
        if (!ctx->b.ws->cs_memory_below_limit(ctx->b.rings.gfx.cs, ctx->b.vram, ctx->b.gtt)) {
                ctx->b.gtt = 0;
                ctx->b.vram = 0;
-               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC);
+               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
                return;
        }
        /* all will be accounted once relocation are emited */
@@ -93,7 +93,7 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
 
        /* Flush if there's not enough space. */
        if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
-               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC);
+               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
        }
 }
 
@@ -230,7 +230,8 @@ void r600_flush_emit(struct r600_context *rctx)
        rctx->b.flags = 0;
 }
 
-void r600_context_flush(struct r600_context *ctx, unsigned flags)
+void r600_context_flush(struct r600_context *ctx, unsigned flags,
+                       struct pipe_fence_handle **fence)
 {
        struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
 
@@ -270,7 +271,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
        }
 
        /* Flush the CS. */
-       ctx->b.ws->cs_flush(ctx->b.rings.gfx.cs, flags, ctx->screen->b.cs_count++);
+       ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
 }
 
 void r600_begin_new_cs(struct r600_context *ctx)
index 677f414226dd825f25586659ccb52a6d3c49df6e..ef8883d18a7b060d240b3d07c3246a7dcb700ece 100644 (file)
@@ -66,7 +66,8 @@ static const struct debug_named_value r600_debug_options[] = {
  * pipe_context
  */
 
-static void r600_flush(struct pipe_context *ctx, unsigned flags)
+static void r600_flush(struct pipe_context *ctx, unsigned flags,
+                      struct pipe_fence_handle **fence)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct pipe_query *render_cond = NULL;
@@ -85,7 +86,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags)
                ctx->render_condition(ctx, NULL, FALSE, 0);
        }
 
-       r600_context_flush(rctx, flags);
+       r600_context_flush(rctx, flags, fence);
        rctx->b.rings.gfx.flushing = false;
        r600_begin_new_cs(rctx);
 
@@ -105,19 +106,18 @@ static void r600_flush_from_st(struct pipe_context *ctx,
        unsigned fflags;
 
        fflags = flags & PIPE_FLUSH_END_OF_FRAME ? RADEON_FLUSH_END_OF_FRAME : 0;
-       if (fence) {
-               *fence = rctx->b.ws->cs_create_fence(rctx->b.rings.gfx.cs);
-       }
+
        /* flush gfx & dma ring, order does not matter as only one can be live */
        if (rctx->b.rings.dma.cs) {
-               rctx->b.rings.dma.flush(rctx, fflags);
+               rctx->b.rings.dma.flush(rctx, fflags, NULL);
        }
-       rctx->b.rings.gfx.flush(rctx, fflags);
+       rctx->b.rings.gfx.flush(rctx, fflags, fence);
 }
 
-static void r600_flush_gfx_ring(void *ctx, unsigned flags)
+static void r600_flush_gfx_ring(void *ctx, unsigned flags,
+                               struct pipe_fence_handle **fence)
 {
-       r600_flush((struct pipe_context*)ctx, flags);
+       r600_flush((struct pipe_context*)ctx, flags, fence);
 }
 
 static void r600_destroy_context(struct pipe_context *context)
index 0a3fa42c27cea1968aa53eb1fec021dee96ccc6e..d52de3520634ec694536049c16ea696479d0a955 100644 (file)
@@ -582,7 +582,8 @@ boolean r600_is_format_supported(struct pipe_screen *screen,
 void r600_update_db_shader_control(struct r600_context * rctx);
 
 /* r600_hw_context.c */
-void r600_context_flush(struct r600_context *ctx, unsigned flags);
+void r600_context_flush(struct r600_context *ctx, unsigned flags,
+                       struct pipe_fence_handle **fence);
 void r600_begin_new_cs(struct r600_context *ctx);
 void r600_flush_emit(struct r600_context *ctx);
 void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count_draw_in);
index 7dbb0b777ed3e17c5ca65be8ae1677c565458ba8..4245b145a93a71b6d825b05c1064f56be1ce381c 100644 (file)
@@ -1335,8 +1335,8 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
        }
 
        /* make sure that the gfx ring is only one active */
-       if (rctx->b.rings.dma.cs) {
-               rctx->b.rings.dma.flush(rctx, RADEON_FLUSH_ASYNC);
+       if (rctx->b.rings.dma.cs && rctx->b.rings.dma.cs->cdw) {
+               rctx->b.rings.dma.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
        }
 
        if (!r600_update_derived_state(rctx)) {
index 77e1b35862ad06c4ff44f78bdcae12d3a6a7d715..805756f6cf1d8c4d20cac865cf8d3647abce90e9 100644 (file)
@@ -37,7 +37,7 @@ boolean r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
        if (ctx->ws->cs_is_buffer_referenced(ctx->rings.gfx.cs, buf, usage)) {
                return TRUE;
        }
-       if (ctx->rings.dma.cs &&
+       if (ctx->rings.dma.cs && ctx->rings.dma.cs->cdw &&
            ctx->ws->cs_is_buffer_referenced(ctx->rings.dma.cs, buf, usage)) {
                return TRUE;
        }
@@ -64,10 +64,10 @@ void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
            ctx->ws->cs_is_buffer_referenced(ctx->rings.gfx.cs,
                                             resource->cs_buf, rusage)) {
                if (usage & PIPE_TRANSFER_DONTBLOCK) {
-                       ctx->rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC);
+                       ctx->rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
                        return NULL;
                } else {
-                       ctx->rings.gfx.flush(ctx, 0);
+                       ctx->rings.gfx.flush(ctx, 0, NULL);
                        busy = true;
                }
        }
@@ -76,10 +76,10 @@ void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
            ctx->ws->cs_is_buffer_referenced(ctx->rings.dma.cs,
                                             resource->cs_buf, rusage)) {
                if (usage & PIPE_TRANSFER_DONTBLOCK) {
-                       ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC);
+                       ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
                        return NULL;
                } else {
-                       ctx->rings.dma.flush(ctx, 0);
+                       ctx->rings.dma.flush(ctx, 0, NULL);
                        busy = true;
                }
        }
index 5588592eb025187e8b7bc0629f484c84ea4bb60d..b30b465ed41390b12edc172756919d534dadd321 100644 (file)
@@ -57,11 +57,11 @@ static INLINE unsigned r600_context_bo_reloc(struct r600_common_context *rctx,
                if (ring == &rctx->rings.gfx) {
                        if (rctx->rings.dma.cs) {
                                /* flush dma ring */
-                               rctx->rings.dma.flush(rctx, RADEON_FLUSH_ASYNC);
+                               rctx->rings.dma.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
                        }
                } else {
                        /* flush gfx ring */
-                       rctx->rings.gfx.flush(rctx, RADEON_FLUSH_ASYNC);
+                       rctx->rings.gfx.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
                }
        }
        return rctx->ws->cs_add_reloc(ring->cs, rbo->cs_buf, usage,
index 92f43deba54ecd6c5a307ac0992278e451e2f232..bc4838842c122e2b35399772dc48d9b625c6623c 100644 (file)
@@ -45,7 +45,7 @@ void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw)
        num_dw += ctx->rings.dma.cs->cdw;
        /* Flush if there's not enough space. */
        if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
-               ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC);
+               ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
        }
 }
 
@@ -53,7 +53,8 @@ static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
 {
 }
 
-static void r600_flush_dma_ring(void *ctx, unsigned flags)
+static void r600_flush_dma_ring(void *ctx, unsigned flags,
+                               struct pipe_fence_handle **fence)
 {
        struct r600_common_context *rctx = (struct r600_common_context *)ctx;
        struct radeon_winsys_cs *cs = rctx->rings.dma.cs;
@@ -63,7 +64,7 @@ static void r600_flush_dma_ring(void *ctx, unsigned flags)
        }
 
        rctx->rings.dma.flushing = true;
-       rctx->ws->cs_flush(cs, flags, 0);
+       rctx->ws->cs_flush(cs, flags, fence, 0);
        rctx->rings.dma.flushing = false;
 }
 
index 2be9ea280ba3339f6f757460cf44071dd531617f..36a4fb1f6aaa08a7617da092230ebd2431ac8ebf 100644 (file)
@@ -297,7 +297,8 @@ struct r600_streamout {
 struct r600_ring {
        struct radeon_winsys_cs         *cs;
        bool                            flushing;
-       void (*flush)(void *ctx, unsigned flags);
+       void (*flush)(void *ctx, unsigned flags,
+                     struct pipe_fence_handle **fence);
 };
 
 struct r600_rings {
index 88573c1a941f5ba5033d7bd25feab666e0587dd4..137c69cd15784a9c705d477bd9e4b7311cf35390 100644 (file)
@@ -87,7 +87,7 @@ struct ruvd_decoder {
 /* flush IB to the hardware */
 static void flush(struct ruvd_decoder *dec)
 {
-       dec->ws->cs_flush(dec->cs, RADEON_FLUSH_ASYNC, 0);
+       dec->ws->cs_flush(dec->cs, RADEON_FLUSH_ASYNC, NULL, 0);
 }
 
 /* add a new set register command to the IB */
index 5778dd1b3bfd62a704acbef6e7e51bef8b95a6e3..222f32e1ba0c5247ccabf661db3c04c5728219e2 100644 (file)
@@ -50,7 +50,7 @@
  */
 static void flush(struct rvce_encoder *enc)
 {
-       enc->ws->cs_flush(enc->cs, RADEON_FLUSH_ASYNC, 0);
+       enc->ws->cs_flush(enc->cs, RADEON_FLUSH_ASYNC, NULL, 0);
 }
 
 #if 0
@@ -267,7 +267,8 @@ static void rvce_flush(struct pipe_video_codec *encoder)
 {
 }
 
-static void rvce_cs_flush(void *ctx, unsigned flags)
+static void rvce_cs_flush(void *ctx, unsigned flags,
+                         struct pipe_fence_handle **fence)
 {
        // just ignored
 }
index c952c8d31f70517bc536a6cccbf4879597dfeefc..f52778163823646c23375da454ef2746da77a6b9 100644 (file)
@@ -73,11 +73,12 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
 
        /* Flush if there's not enough space. */
        if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
-               si_flush(&ctx->b.b, NULL, RADEON_FLUSH_ASYNC);
+               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
        }
 }
 
-void si_context_flush(struct si_context *ctx, unsigned flags)
+void si_context_flush(struct si_context *ctx, unsigned flags,
+                     struct pipe_fence_handle **fence)
 {
        struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
 
@@ -123,7 +124,7 @@ void si_context_flush(struct si_context *ctx, unsigned flags)
 #endif
 
        /* Flush the CS. */
-       ctx->b.ws->cs_flush(ctx->b.rings.gfx.cs, flags, 0);
+       ctx->b.ws->cs_flush(cs, flags, fence, 0);
 
 #if SI_TRACE_CS
        if (ctx->screen->b.trace_bo) {
index bd7670d07be0058668a57723ff01d9ad316e76ad..d434064b5724ef6742a0a13fe229fa79684f10c6 100644 (file)
 /*
  * pipe_context
  */
-void si_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
-             unsigned flags)
+static void si_flush(struct pipe_context *ctx, unsigned flags,
+                    struct pipe_fence_handle **fence)
 {
        struct si_context *sctx = (struct si_context *)ctx;
        struct pipe_query *render_cond = NULL;
        boolean render_cond_cond = FALSE;
        unsigned render_cond_mode = 0;
 
-       if (fence) {
-               *fence = sctx->b.ws->cs_create_fence(sctx->b.rings.gfx.cs);
-       }
-
        /* Disable render condition. */
        if (sctx->b.current_render_cond) {
                render_cond = sctx->b.current_render_cond;
@@ -53,7 +49,7 @@ void si_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
                ctx->render_condition(ctx, NULL, FALSE, 0);
        }
 
-       si_context_flush(sctx, flags);
+       si_context_flush(sctx, flags, fence);
 
        /* Re-enable render condition. */
        if (render_cond) {
@@ -72,15 +68,16 @@ static void si_flush_from_st(struct pipe_context *ctx,
                rflags |= RADEON_FLUSH_END_OF_FRAME;
 
        if (sctx->b.rings.dma.cs) {
-               sctx->b.rings.dma.flush(sctx, rflags);
+               sctx->b.rings.dma.flush(sctx, rflags, NULL);
        }
 
-       si_flush(ctx, fence, rflags);
+       si_flush(ctx, rflags, fence);
 }
 
-static void si_flush_gfx_ring(void *ctx, unsigned flags)
+static void si_flush_gfx_ring(void *ctx, unsigned flags,
+                             struct pipe_fence_handle **fence)
 {
-       si_flush((struct pipe_context*)ctx, NULL, flags);
+       si_flush(ctx, flags, fence);
 }
 
 static void si_destroy_context(struct pipe_context *context)
index f1ef2ac94697464d226b96695db9e2535bb6e9db..8930f2becb84a743cb4964a6d64e201ab80bca4a 100644 (file)
@@ -177,14 +177,11 @@ void si_dma_copy(struct pipe_context *ctx,
                 const struct pipe_box *src_box);
 
 /* si_hw_context.c */
-void si_context_flush(struct si_context *ctx, unsigned flags);
+void si_context_flush(struct si_context *ctx, unsigned flags,
+                     struct pipe_fence_handle **fence);
 void si_begin_new_cs(struct si_context *ctx);
 void si_need_cs_space(struct si_context *ctx, unsigned num_dw, boolean count_draw_in);
 
-/* si_pipe.c */
-void si_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
-              unsigned flags);
-
 #if SI_TRACE_CS
 void si_trace_emit(struct si_context *sctx);
 #endif
index e6668930fa9dce8af3e9298dea857b3b3f1051ac..380316ebd69c2a94fc3b89a52dc8ffb740ba4211 100644 (file)
@@ -405,7 +405,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
                  *
                  * Only check whether the buffer is being used for write. */
                 if (cs && radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
-                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
+                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC, NULL);
                     return NULL;
                 }
 
@@ -415,7 +415,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
                 }
             } else {
                 if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
-                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
+                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC, NULL);
                     return NULL;
                 }
 
@@ -436,7 +436,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
                  *
                  * Only check whether the buffer is being used for write. */
                 if (cs && radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
-                    cs->flush_cs(cs->flush_data, 0);
+                    cs->flush_cs(cs->flush_data, 0, NULL);
                 }
                 radeon_bo_wait((struct pb_buffer*)bo,
                                RADEON_USAGE_WRITE);
@@ -444,7 +444,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
                 /* Mapping for write. */
                 if (cs) {
                     if (radeon_bo_is_referenced_by_cs(cs, bo)) {
-                        cs->flush_cs(cs->flush_data, 0);
+                        cs->flush_cs(cs->flush_data, 0, NULL);
                     } else {
                         /* Try to avoid busy-waiting in radeon_bo_wait. */
                         if (p_atomic_read(&bo->num_active_ioctls))
@@ -751,7 +751,7 @@ static void radeon_bo_set_tiling(struct pb_buffer *_buf,
     /* Tiling determines how DRM treats the buffer data.
      * We must flush CS when changing it if the buffer is referenced. */
     if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
-        cs->flush_cs(cs->flush_data, 0);
+        cs->flush_cs(cs->flush_data, 0, NULL);
     }
 
     while (p_atomic_read(&bo->num_active_ioctls)) {
index 91db6b7f365d88dd60f3ef16a1a14e067ecfaf94..284a404c9975dbc9145c7d29bb93dc13a7a8c553 100644 (file)
 
 #define RELOC_DWORDS (sizeof(struct drm_radeon_cs_reloc) / sizeof(uint32_t))
 
+static struct pipe_fence_handle *
+radeon_cs_create_fence(struct radeon_winsys_cs *rcs);
+static void radeon_fence_reference(struct pipe_fence_handle **dst,
+                                   struct pipe_fence_handle *src);
+
 static boolean radeon_init_cs_context(struct radeon_cs_context *csc,
                                       struct radeon_drm_winsys *ws)
 {
@@ -140,7 +145,8 @@ static void radeon_destroy_cs_context(struct radeon_cs_context *csc)
 static struct radeon_winsys_cs *
 radeon_drm_cs_create(struct radeon_winsys *rws,
                      enum ring_type ring_type,
-                     void (*flush)(void *ctx, unsigned flags),
+                     void (*flush)(void *ctx, unsigned flags,
+                                  struct pipe_fence_handle **fence),
                      void *flush_ctx,
                      struct radeon_winsys_cs_handle *trace_buf)
 {
@@ -349,7 +355,7 @@ static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs)
 
         /* Flush if there are any relocs. Clean up otherwise. */
         if (cs->csc->crelocs) {
-            cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
+            cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC, NULL);
         } else {
             radeon_cs_context_cleanup(cs->csc);
 
@@ -417,7 +423,10 @@ void radeon_drm_cs_sync_flush(struct radeon_winsys_cs *rcs)
 
 DEBUG_GET_ONCE_BOOL_OPTION(noop, "RADEON_NOOP", FALSE)
 
-static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, uint32_t cs_trace_id)
+static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
+                                unsigned flags,
+                                struct pipe_fence_handle **fence,
+                                uint32_t cs_trace_id)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     struct radeon_cs_context *tmp;
@@ -457,9 +466,14 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, ui
        fprintf(stderr, "radeon: command stream overflowed\n");
     }
 
+    if (fence) {
+        radeon_fence_reference(fence, NULL);
+        *fence = radeon_cs_create_fence(rcs);
+    }
+
     radeon_drm_cs_sync_flush(rcs);
 
-    /* Flip command streams. */
+    /* Swap command streams. */
     tmp = cs->csc;
     cs->csc = cs->cst;
     cs->cst = tmp;
@@ -468,7 +482,9 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, ui
 
     /* If the CS is not empty or overflowed, emit it in a separate thread. */
     if (cs->base.cdw && cs->base.cdw <= RADEON_MAX_CMDBUF_DWORDS && !debug_get_option_noop()) {
-        unsigned i, crelocs = cs->cst->crelocs;
+        unsigned i, crelocs;
+
+        crelocs = cs->cst->crelocs;
 
         cs->cst->chunks[0].length_dw = cs->base.cdw;
 
@@ -643,7 +659,6 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws)
     ws->base.cs_flush = radeon_drm_cs_flush;
     ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced;
     ws->base.cs_sync_flush = radeon_drm_cs_sync_flush;
-    ws->base.cs_create_fence = radeon_cs_create_fence;
     ws->base.fence_wait = radeon_fence_wait;
     ws->base.fence_reference = radeon_fence_reference;
 }
index 460e9fadc10e843ad05c1bf6f10e10f836c032f7..59819a56e0a50e3b496bacedcb5fb8a15e0b56ec 100644 (file)
@@ -73,7 +73,7 @@ struct radeon_drm_cs {
     struct radeon_drm_winsys *ws;
 
     /* Flush CS. */
-    void (*flush_cs)(void *ctx, unsigned flags);
+    void (*flush_cs)(void *ctx, unsigned flags, struct pipe_fence_handle **fence);
     void *flush_data;
 
     pipe_semaphore flush_completed;
index 469c79beccc3f6039b1882dc61ceb06f047f40ac..fe0617b682b060984d7c804ee5bd2298cd0adad7 100644 (file)
@@ -424,7 +424,8 @@ struct radeon_winsys {
      */
     struct radeon_winsys_cs *(*cs_create)(struct radeon_winsys *ws,
                                           enum ring_type ring_type,
-                                          void (*flush)(void *ctx, unsigned flags),
+                                          void (*flush)(void *ctx, unsigned flags,
+                                                       struct pipe_fence_handle **fence),
                                           void *flush_ctx,
                                           struct radeon_winsys_cs_handle *trace_buf);
 
@@ -488,9 +489,14 @@ struct radeon_winsys {
      *
      * \param cs          A command stream to flush.
      * \param flags,      RADEON_FLUSH_ASYNC or 0.
-     * \param cs_trace_id A unique identifiant for the cs
+     * \param fence       Pointer to a fence. If non-NULL, a fence is inserted
+     *                    after the CS and is returned through this parameter.
+     * \param cs_trace_id A unique identifier of the cs, used for tracing.
      */
-    void (*cs_flush)(struct radeon_winsys_cs *cs, unsigned flags, uint32_t cs_trace_id);
+    void (*cs_flush)(struct radeon_winsys_cs *cs,
+                     unsigned flags,
+                     struct pipe_fence_handle **fence,
+                     uint32_t cs_trace_id);
 
     /**
      * Return TRUE if a buffer is referenced by a command stream.
@@ -519,13 +525,6 @@ struct radeon_winsys {
       */
     void (*cs_sync_flush)(struct radeon_winsys_cs *cs);
 
-    /**
-     * Return a fence associated with the CS. The fence will be signalled
-     * once the CS is flushed and all commands in the CS are completed
-     * by the GPU.
-     */
-    struct pipe_fence_handle *(*cs_create_fence)(struct radeon_winsys_cs *cs);
-
     /**
      * Wait for the fence and return true if the fence has been signalled.
      * The timeout of 0 will only return the status.