Mesa (master): svga: Rebind framebuffer and tss bindings strictly when necessary.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Tue Apr 12 04:04:49 PDT 2011


Module: Mesa
Branch: master
Commit: 6b95cfb0de1bcd680679a20d6ecc32b42e5d1546
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6b95cfb0de1bcd680679a20d6ecc32b42e5d1546

Author: José Fonseca <jfonseca at vmware.com>
Date:   Thu Apr  7 16:54:37 2011 +0100

svga: Rebind framebuffer and tss bindings strictly when necessary.

The earlier change to ensure rendertargets and textures are always
rebound at every command buffer start had the downside of making
successive flushes no longer no-ops, as a command buffer with merely
the rebinding commands were being unnecessarily sent to the vGPU.

This change only re-emits the bindings when necessary, by keeping track
of the need to rebind outside of the dirty state update mechanism.

---

 src/gallium/drivers/svga/svga_context.c           |   23 +++-----------------
 src/gallium/drivers/svga/svga_context.h           |    6 ++++-
 src/gallium/drivers/svga/svga_draw.c              |   14 ++++++++++++
 src/gallium/drivers/svga/svga_pipe_clear.c        |    7 ++++++
 src/gallium/drivers/svga/svga_state_framebuffer.c |   10 ++++++--
 src/gallium/drivers/svga/svga_state_tss.c         |   11 +++++++--
 6 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 4782b4b..dbbc249 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -204,7 +204,6 @@ void svga_context_flush( struct svga_context *svga,
 {
    struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
    struct pipe_fence_handle *fence = NULL;
-   enum pipe_error ret;
 
    svga->curr.nr_fbs = 0;
 
@@ -219,25 +218,11 @@ void svga_context_flush( struct svga_context *svga,
 
    svga_screen_cache_flush(svgascreen, fence);
 
-   /* To force the reemission of rendertargets and texture bindings at
-    * the beginning of every command buffer.
-    */
-   svga->dirty |= SVGA_NEW_COMMAND_BUFFER;
-
-   /*
-    * We must reemit the surface bindings here, because svga_update_state
-    * will always flush the primitives before processing the
-    * SVGA_NEW_COMMAND_BUFFER state change.
-    *
-    * TODO: Refactor this.
+   /* To force the re-emission of rendertargets and texture sampler bindings on
+    * the next command buffer.
     */
-   ret = svga_reemit_framebuffer_bindings(svga);
-   assert(ret == PIPE_OK);
-
-   ret = svga_reemit_tss_bindings(svga);
-   assert(ret == PIPE_OK);
-
-   svga->dirty &= ~SVGA_NEW_COMMAND_BUFFER;
+   svga->rebind.rendertargets = TRUE;
+   svga->rebind.texture_samplers = TRUE;
 
    if (SVGA_DEBUG & DEBUG_SYNC) {
       if (fence)
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 7b36a36..eca529d 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -358,6 +358,11 @@ struct svga_context
    struct svga_state curr;      /* state from the state tracker */
    unsigned dirty;              /* statechanges since last update_state() */
 
+   struct {
+      unsigned rendertargets:1;
+      unsigned texture_samplers:1;
+   } rebind;
+
    struct u_upload_mgr *upload_ib;
    struct u_upload_mgr *upload_vb;
    struct svga_hwtnl *hwtnl;
@@ -402,7 +407,6 @@ struct svga_context
 #define SVGA_NEW_ZERO_STRIDE         0x2000000
 #define SVGA_NEW_TEXTURE_FLAGS       0x4000000
 #define SVGA_NEW_STENCIL_REF         0x8000000
-#define SVGA_NEW_COMMAND_BUFFER      0x10000000
 
 
 
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index 2c873a0..d8af615 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -170,6 +170,20 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
          ib_handle[i] = handle;
       }
 
+      if (svga->rebind.rendertargets) {
+         ret = svga_reemit_framebuffer_bindings(svga);
+         if (ret != PIPE_OK) {
+            return ret;
+         }
+      }
+
+      if (svga->rebind.texture_samplers) {
+         ret = svga_reemit_tss_bindings(svga);
+         if (ret != PIPE_OK) {
+            return ret;
+         }
+      }
+
       SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
                svga->curr.framebuffer.cbufs[0] ?
                svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index 41f239c..b288c3e 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -52,6 +52,13 @@ try_clear(struct svga_context *svga,
    if (ret)
       return ret;
 
+   if (svga->rebind.rendertargets) {
+      ret = svga_reemit_framebuffer_bindings(svga);
+      if (ret != PIPE_OK) {
+         return ret;
+      }
+   }
+
    if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) {
       flags |= SVGA3D_CLEAR_COLOR;
       util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index 47bdc25..cc48194 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -43,7 +43,7 @@ static int emit_framebuffer( struct svga_context *svga,
 {
    const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
    struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
-   boolean reemit = !!(dirty & SVGA_NEW_COMMAND_BUFFER);
+   boolean reemit = svga->rebind.rendertargets;
    unsigned i;
    enum pipe_error ret;
 
@@ -88,6 +88,7 @@ static int emit_framebuffer( struct svga_context *svga,
       pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
    }
 
+   svga->rebind.rendertargets = FALSE;
 
    return 0;
 }
@@ -108,6 +109,8 @@ svga_reemit_framebuffer_bindings(struct svga_context *svga)
    unsigned i;
    enum pipe_error ret;
 
+   assert(svga->rebind.rendertargets);
+
    for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, 8); ++i) {
       if (hw->cbufs[i]) {
          ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, hw->cbufs[i]);
@@ -138,6 +141,8 @@ svga_reemit_framebuffer_bindings(struct svga_context *svga)
       }
    }
 
+   svga->rebind.rendertargets = FALSE;
+
    return PIPE_OK;
 }
 
@@ -145,8 +150,7 @@ svga_reemit_framebuffer_bindings(struct svga_context *svga)
 struct svga_tracked_state svga_hw_framebuffer = 
 {
    "hw framebuffer state",
-   SVGA_NEW_FRAME_BUFFER |
-   SVGA_NEW_COMMAND_BUFFER,
+   SVGA_NEW_FRAME_BUFFER,
    emit_framebuffer
 };
 
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index c502506..8b11a2a 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -66,7 +66,7 @@ static int
 update_tss_binding(struct svga_context *svga, 
                    unsigned dirty )
 {
-   boolean reemit = !!(dirty & SVGA_NEW_COMMAND_BUFFER);
+   boolean reemit = svga->rebind.texture_samplers;
    unsigned i;
    unsigned count = MAX2( svga->curr.num_sampler_views,
                           svga->state.hw_draw.num_views );
@@ -159,6 +159,8 @@ update_tss_binding(struct svga_context *svga,
       SVGA_FIFOCommitAll( svga->swc );
    }
 
+   svga->rebind.texture_samplers = FALSE;
+
    return 0;
 
 fail:
@@ -181,6 +183,8 @@ svga_reemit_tss_bindings(struct svga_context *svga)
    enum pipe_error ret;
    struct bind_queue queue;
 
+   assert(svga->rebind.texture_samplers);
+
    queue.bind_count = 0;
 
    for (i = 0; i < svga->state.hw_draw.num_views; i++) {
@@ -220,6 +224,8 @@ svga_reemit_tss_bindings(struct svga_context *svga)
       SVGA_FIFOCommitAll(svga->swc);
    }
 
+   svga->rebind.texture_samplers = FALSE;
+
    return PIPE_OK;
 }
 
@@ -227,8 +233,7 @@ svga_reemit_tss_bindings(struct svga_context *svga)
 struct svga_tracked_state svga_hw_tss_binding = {
    "texture binding emit",
    SVGA_NEW_TEXTURE_BINDING |
-   SVGA_NEW_SAMPLER |
-   SVGA_NEW_COMMAND_BUFFER,
+   SVGA_NEW_SAMPLER,
    update_tss_binding
 };
 



More information about the mesa-commit mailing list