diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_cmd.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_cmd.h | 20 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_context.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_draw.c | 38 | ||||
-rw-r--r-- | 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 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; }; |