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

Author: Brian Paul <bri...@vmware.com>
Date:   Wed Aug 31 18:28:00 2016 -0600

svga: try to emit fewer buffer rebind commands

If a consecutive sequence of drawing commands references the same
vertex/index buffers, there should be no need to rebind the surfaces
for the second and subsequent drawing commands.

Apps that use multiple display lists benefit from this since the vertex
data for several display lists is often stored in one buffer.

In the case of the legacy E&S Glaze demo, this reduces the size of our
command buffers from 91KB to 44KB.  One WSI Fusion trace shows a 33%
reduction in command buffer sizes.

Tested with full piglit run.

Reviewed-by: Charmaine Lee <charmai...@vmware.com>

---

 src/gallium/drivers/svga/svga_cmd.c     |  2 ++
 src/gallium/drivers/svga/svga_cmd.h     | 20 +++++++++++++++++
 src/gallium/drivers/svga/svga_context.c |  2 ++
 src/gallium/drivers/svga/svga_draw.c    | 38 ++++++++++++++++++++++++++++-----
 src/gallium/drivers/svga/svga_winsys.h  |  3 +++
 5 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_cmd.c 
b/src/gallium/drivers/svga/svga_cmd.c
index e45b3e7..ecf2e9d 100644
--- a/src/gallium/drivers/svga/svga_cmd.c
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -119,6 +119,8 @@ SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
    header->id = cmd;
    header->size = cmdSize;
 
+   swc->last_command = cmd;
+
    return &header[1];
 }
 
diff --git a/src/gallium/drivers/svga/svga_cmd.h 
b/src/gallium/drivers/svga/svga_cmd.h
index 06e1b4a..47a33ec 100644
--- a/src/gallium/drivers/svga/svga_cmd.h
+++ b/src/gallium/drivers/svga/svga_cmd.h
@@ -35,6 +35,7 @@
 
 
 #include "svga_types.h"
+#include "svga_winsys.h"
 #include "svga_reg.h"
 #include "svga3d_reg.h"
 
@@ -60,6 +61,25 @@ SVGA3D_FIFOReserve(struct svga_winsys_context *swc, uint32 
cmd, uint32 cmdSize,
 void
 SVGA_FIFOCommitAll(struct svga_winsys_context *swc);
 
+/**
+ * Return the last command id put in the command buffer.
+ */
+static inline SVGAFifo3dCmdId
+SVGA3D_GetLastCommand(const struct svga_winsys_context *swc)
+{
+   return swc->last_command;
+}
+
+/**
+ * Reset/clear the last command put in the command buffer.
+ * To be called when buffer is flushed.
+ */
+static inline void
+SVGA3D_ResetLastCommand(struct svga_winsys_context *swc)
+{
+   swc->last_command = 0;
+}
+
 
 /*
  * Context Management
diff --git a/src/gallium/drivers/svga/svga_context.c 
b/src/gallium/drivers/svga/svga_context.c
index f498e83..1ed0f3d 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -338,6 +338,8 @@ void svga_context_flush( struct svga_context *svga,
 
    svga_screen_cache_flush(svgascreen, fence);
 
+   SVGA3D_ResetLastCommand(svga->swc);
+
    /* To force the re-emission of rendertargets and texture sampler bindings on
     * the next command buffer.
     */
diff --git a/src/gallium/drivers/svga/svga_draw.c 
b/src/gallium/drivers/svga/svga_draw.c
index f8d3ae5..988267b 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -427,6 +427,32 @@ validate_constant_buffers(struct svga_context *svga)
 }
 
 
+/**
+ * Was the last command put into the command buffer a drawing command?
+ * We use this to determine if we can skip emitting buffer re-bind
+ * commands when we have a sequence of drawing commands that use the
+ * same vertex/index buffers with no intervening commands.
+ *
+ * The first drawing command will bind the vertex/index buffers.  If
+ * the immediately following command is also a drawing command using the
+ * same buffers, we shouldn't have to rebind them.
+ */
+static bool
+last_command_was_draw(const struct svga_context *svga)
+{
+   switch (SVGA3D_GetLastCommand(svga->swc)) {
+   case SVGA_3D_CMD_DX_DRAW:
+   case SVGA_3D_CMD_DX_DRAW_INDEXED:
+   case SVGA_3D_CMD_DX_DRAW_INSTANCED:
+   case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
+   case SVGA_3D_CMD_DX_DRAW_AUTO:
+      return true;
+   default:
+      return false;
+   }
+}
+
+
 static enum pipe_error
 draw_vgpu10(struct svga_hwtnl *hwtnl,
             const SVGA3dPrimitiveRange *range,
@@ -583,7 +609,7 @@ draw_vgpu10(struct svga_hwtnl *hwtnl,
           * command, we still need to reference the vertex buffers surfaces.
           */
          for (i = 0; i < vbuf_count; i++) {
-            if (vbuffer_handles[i]) {
+            if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
                ret = svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
                                                 NULL, SVGA_RELOC_READ);
                if (ret != PIPE_OK)
@@ -626,10 +652,12 @@ draw_vgpu10(struct svga_hwtnl *hwtnl,
          /* Even though we can avoid emitting the redundant SetIndexBuffer
           * command, we still need to reference the index buffer surface.
           */
-         ret = svga->swc->resource_rebind(svga->swc, ib_handle,
-                                          NULL, SVGA_RELOC_READ);
-         if (ret != PIPE_OK)
-            return ret;
+         if (!last_command_was_draw(svga)) {
+            ret = svga->swc->resource_rebind(svga->swc, ib_handle,
+                                             NULL, SVGA_RELOC_READ);
+            if (ret != PIPE_OK)
+               return ret;
+         }
       }
 
       if (instance_count > 1) {
diff --git a/src/gallium/drivers/svga/svga_winsys.h 
b/src/gallium/drivers/svga/svga_winsys.h
index a7b25ab..901a73e 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -424,6 +424,9 @@ struct svga_winsys_context
 
    /** To report perf/conformance/etc issues to the state tracker */
    struct pipe_debug_callback *debug_callback;
+
+   /** The more recent command issued to command buffer */
+   SVGAFifo3dCmdId last_command;
 };
 
 

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to