summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/svga/svga_cmd.c2
-rw-r--r--src/gallium/drivers/svga/svga_cmd.h20
-rw-r--r--src/gallium/drivers/svga/svga_context.c2
-rw-r--r--src/gallium/drivers/svga/svga_draw.c38
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h3
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 e45b3e72aeb..ecf2e9d2ca0 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 06e1b4a3253..47a33ec3932 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 f498e839aa2..1ed0f3d1b78 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 f8d3ae543ef..988267b8df1 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 a7b25ab7b44..901a73eba0a 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;
};