summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker/st_atom_constbuf.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-12-29 03:17:43 +0100
committerMarek Olšák <[email protected]>2011-01-06 16:16:29 +0100
commit58c5e782e351621bde2693fa945d0c90d140b855 (patch)
treed8a77d03790420d9e89325d74ff2e0dbb57a854c /src/mesa/state_tracker/st_atom_constbuf.c
parent5adcd9c9117b125cab1155c5f3af0bb51ace74b7 (diff)
st/mesa: optimize constant buffer uploads
The overhead of resource_create, transfer_inline_write, and resource_destroy to upload constant data is very visible with some apps in sysprof, and as such should be eliminated. My approach uses a user buffer to pass a pointer to a driver. This gives the driver the freedom it needs to take the fast path, which may differ for each driver. This commit addresses the same issue as Jakob's one that suballocates out of a big constant buffer, but it also eliminates the copy to the buffer.
Diffstat (limited to 'src/mesa/state_tracker/st_atom_constbuf.c')
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index f1d08a3e166..05667a74305 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -56,7 +56,6 @@ void st_upload_constants( struct st_context *st,
unsigned shader_type)
{
struct pipe_context *pipe = st->pipe;
- struct pipe_resource **cbuf = &st->state.constants[shader_type];
assert(shader_type == PIPE_SHADER_VERTEX ||
shader_type == PIPE_SHADER_FRAGMENT ||
@@ -64,6 +63,7 @@ void st_upload_constants( struct st_context *st,
/* update constants */
if (params && params->NumParameters) {
+ struct pipe_resource *cbuf;
const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
/* Update the constants which come from fixed-function state, such as
@@ -75,11 +75,12 @@ void st_upload_constants( struct st_context *st,
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization.
+ * Let's use a user buffer to avoid an unnecessary copy.
*/
- pipe_resource_reference(cbuf, NULL );
- *cbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- paramBytes );
+ cbuf = pipe_user_buffer_create(pipe->screen,
+ params->ParameterValues,
+ paramBytes,
+ PIPE_BIND_CONSTANT_BUFFER);
if (ST_DEBUG & DEBUG_CONSTANTS) {
debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
@@ -88,17 +89,15 @@ void st_upload_constants( struct st_context *st,
_mesa_print_parameter_list(params);
}
- /* load Mesa constants into the constant buffer */
- pipe_buffer_write(st->pipe, *cbuf,
- 0, paramBytes,
- params->ParameterValues);
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
+ pipe_resource_reference(&cbuf, NULL);
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, *cbuf);
+ st->state.constants[shader_type].ptr = params->ParameterValues;
+ st->state.constants[shader_type].size = paramBytes;
}
- else if (*cbuf) {
- st->constants.tracked_state[shader_type].dirty.mesa = 0x0;
-
- pipe_resource_reference(cbuf, NULL);
+ else if (st->state.constants[shader_type].ptr) {
+ st->state.constants[shader_type].ptr = NULL;
+ st->state.constants[shader_type].size = 0;
st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
}
}