summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/svga/svga_context.c13
-rw-r--r--src/gallium/drivers/svga/svga_context.h7
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c26
3 files changed, 40 insertions, 6 deletions
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 78fb558f408..f498e839aa2 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -248,6 +248,8 @@ struct pipe_context *svga_context_create(struct pipe_screen *screen,
svga->state.hw_draw.num_vbuffers = 0;
memset(svga->state.hw_draw.vbuffers, 0,
sizeof(svga->state.hw_draw.vbuffers));
+ svga->state.hw_draw.const0_buffer = NULL;
+ svga->state.hw_draw.const0_handle = NULL;
/* Create a no-operation blend state which we will bind whenever the
* requested blend state is impossible (e.g. due to having an integer
@@ -307,6 +309,17 @@ void svga_context_flush( struct svga_context *svga,
svga->curr.nr_fbs = 0;
+ /* Unmap the 0th/default constant buffer. The u_upload_unmap() function
+ * will call pipe_context::transfer_flush_region() to indicate the
+ * region of the buffer which was modified (and needs to be uploaded).
+ */
+ if (svga->state.hw_draw.const0_handle) {
+ assert(svga->state.hw_draw.const0_buffer);
+ u_upload_unmap(svga->const0_upload);
+ pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
+ svga->state.hw_draw.const0_handle = NULL;
+ }
+
/* Ensure that texture dma uploads are processed
* before submitting commands.
*/
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index a635ef1fc95..db80061f425 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -355,6 +355,13 @@ struct svga_hw_draw_state
/** Bitmask of enabled constant buffers */
unsigned enabled_constbufs[PIPE_SHADER_TYPES];
+ /**
+ * These are used to reduce the number of times we call u_upload_unmap()
+ * while updating the zero-th/default VGPU10 constant buffer.
+ */
+ struct pipe_resource *const0_buffer;
+ struct svga_winsys_surface *const0_handle;
+
/** VGPU10 HW state (used to prevent emitting redundant state) */
SVGA3dDepthStencilStateId depth_stencil_id;
unsigned stencil_ref;
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index dc80edf0982..8d6b46a1cae 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -646,15 +646,29 @@ emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
assert(extra_offset + extra_size <= new_buf_size);
memcpy((char *) dst_map + extra_offset, extras, extra_size);
}
- u_upload_unmap(svga->const0_upload);
- /* Issue the SetSingleConstantBuffer command */
- dst_handle = svga_buffer_handle(svga, dst_buffer);
- if (!dst_handle) {
- pipe_resource_reference(&dst_buffer, NULL);
- return PIPE_ERROR_OUT_OF_MEMORY;
+ /* Get winsys handle for the constant buffer */
+ if (svga->state.hw_draw.const0_buffer == dst_buffer &&
+ svga->state.hw_draw.const0_handle) {
+ /* re-reference already mapped buffer */
+ dst_handle = svga->state.hw_draw.const0_handle;
+ }
+ else {
+ /* we must unmap the buffer before getting the winsys handle */
+ u_upload_unmap(svga->const0_upload);
+
+ dst_handle = svga_buffer_handle(svga, dst_buffer);
+ if (!dst_handle) {
+ pipe_resource_reference(&dst_buffer, NULL);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* save the buffer / handle for next time */
+ pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
+ svga->state.hw_draw.const0_handle = dst_handle;
}
+ /* Issue the SetSingleConstantBuffer command */
assert(new_buf_size % 16 == 0);
ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
0, /* index */