diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/svga/svga_context.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_context.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_state_constants.c | 26 |
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 */ |