From: Marek Olšák Date: Tue, 24 Apr 2012 20:53:05 +0000 (+0200) Subject: gallium: add void *user_buffer to pipe_constant_buffer X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0b7d48cbad86eaac21fce3793da41b46db8be3b4;p=mesa.git gallium: add void *user_buffer to pipe_constant_buffer This reduces CPU overhead when updating constants. --- diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 772e229ceff..bd9e8bac0ae 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -672,6 +672,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, unsigned new_num = 0; boolean diff = TRUE; + if (cb && cb->user_buffer) { + buf = i915_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } /* XXX don't support geom shaders now */ if (shader == PIPE_SHADER_GEOMETRY) @@ -707,6 +712,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, if (diff) i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; + + if (cb && cb->user_buffer) { + pipe_resource_reference(&buf, NULL); + } } diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 438fc887083..d4750705b43 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -155,6 +155,12 @@ extern unsigned llvmpipe_variant_count; struct pipe_context * llvmpipe_create_context( struct pipe_screen *screen, void *priv ); +struct pipe_resource * +llvmpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags); + static INLINE struct llvmpipe_context * llvmpipe_context( struct pipe_context *pipe ) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 7a6c1ab5bc7..ec94190649c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1173,8 +1173,17 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct pipe_resource *constants = cb ? cb->buffer : NULL; - unsigned size = constants ? constants->width0 : 0; - const void *data = constants ? llvmpipe_resource_data(constants) : NULL; + unsigned size; + const void *data; + + if (cb && cb->user_buffer) { + constants = llvmpipe_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + + size = constants ? constants->width0 : 0; + data = constants ? llvmpipe_resource_data(constants) : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index < PIPE_MAX_CONSTANT_BUFFERS); @@ -1194,6 +1203,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, } llvmpipe->dirty |= LP_NEW_CONSTANTS; + + if (cb && cb->user_buffer) { + pipe_resource_reference(&constants, NULL); + } } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index f6a1ec26bc5..958a8127b89 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -748,7 +748,7 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe, /** * Create buffer which wraps user-space data. */ -static struct pipe_resource * +struct pipe_resource * llvmpipe_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 3b4cc998877..f65c8b71fdd 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -323,6 +323,12 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_resource *buf = cb ? cb->buffer : NULL; unsigned size; + if (cb && cb->user_buffer) { + buf = nouveau_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + size = 0; if (buf) size = buf->width0 / (4 * sizeof(float)); @@ -337,6 +343,10 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, nv30->fragprog.constbuf_nr = size; nv30->dirty |= NV30_NEW_FRAGCONST; } + + if (cb && cb->user_buffer) { + pipe_resource_reference(&buf, NULL); + } } static void diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index afd6f2e929d..a17540a1492 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -749,6 +749,12 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv50_context *nv50 = nv50_context(pipe); struct pipe_resource *res = cb ? cb->buffer : NULL; + if (cb && cb->user_buffer) { + res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + pipe_resource_reference(&nv50->constbuf[shader][index], res); nv50->constbuf_dirty[shader] |= 1 << index; @@ -760,6 +766,10 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index)); nv50->dirty |= NV50_NEW_CONSTBUF; + + if (cb && cb->user_buffer) { + pipe_resource_reference(&res, NULL); + } } /* ============================================================================= diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 9b1ae550fff..40161252a3d 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -621,6 +621,12 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nvc0_context *nvc0 = nvc0_context(pipe); struct pipe_resource *res = cb ? cb->buffer : NULL; + if (cb && cb->user_buffer) { + res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + switch (shader) { case PIPE_SHADER_VERTEX: shader = 0; break; /* @@ -642,6 +648,10 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, nvc0->constbuf_dirty[shader] |= 1 << index; nvc0->dirty |= NVC0_NEW_CONSTBUF; + + if (cb->user_buffer) { + pipe_resource_reference(&res, NULL); + } } /* ============================================================================= diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 3822f2fd5d1..566bc443807 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1841,8 +1841,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, if (buf == NULL || buf->width0 == 0) return; - if (rbuf->b.b.user_ptr) - mapped = (uint32_t*)rbuf->b.b.user_ptr; + if (cb->user_buffer) + mapped = (uint32_t*)cb->user_buffer; else if (rbuf->constant_buffer) mapped = (uint32_t*)rbuf->constant_buffer; else diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 4b9338d3464..517121dc288 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1203,10 +1203,8 @@ static void evergreen_set_clip_state(struct pipe_context *ctx, rctx->states[R600_PIPE_STATE_CLIP] = rstate; r600_context_pipe_state_set(rctx, rstate); - cb.buffer = pipe_user_buffer_create(ctx->screen, - state->ucp, - 4*4*8, /* 8*4 floats */ - PIPE_BIND_CONSTANT_BUFFER); + cb.buffer = NULL; + cb.user_buffer = state->ucp; cb.buffer_offset = 0; cb.buffer_size = 4*4*8; r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 81ffaa8bfd9..3a83b613e58 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1286,10 +1286,8 @@ static void r600_set_clip_state(struct pipe_context *ctx, rctx->states[R600_PIPE_STATE_CLIP] = rstate; r600_context_pipe_state_set(rctx, rstate); - cb.buffer = pipe_user_buffer_create(ctx->screen, - state->ucp, - 4*4*8, /* 8*4 floats */ - PIPE_BIND_CONSTANT_BUFFER); + cb.buffer = NULL; + cb.user_buffer = state->ucp; cb.buffer_offset = 0; cb.buffer_size = 4*4*8; r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 9e1f016f294..ccae7d91d43 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -535,7 +535,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, struct r600_context *rctx = (struct r600_context *)ctx; struct r600_constbuf_state *state; struct pipe_constant_buffer *cb; - uint8_t *ptr; + const uint8_t *ptr; switch (shader) { case PIPE_SHADER_VERTEX: @@ -561,7 +561,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, cb = &state->cb[index]; cb->buffer_size = input->buffer_size; - ptr = input->buffer->user_ptr; + ptr = input->user_buffer; if (ptr) { /* Upload the user buffer. */ diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c index 05a201ce3bc..63c07420915 100644 --- a/src/gallium/drivers/radeonsi/r600_state_common.c +++ b/src/gallium/drivers/radeonsi/r600_state_common.c @@ -439,6 +439,12 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, return; } + if (cb->user_buffer) { + rbuffer = pipe_user_buffer_create(ctx->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + r600_inval_shader_cache(rctx); r600_upload_const_buffer(rctx, &rbuffer, &offset); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index c657bd61fcf..7634254104b 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -206,6 +206,11 @@ softpipe_reset_sampler_variants(struct softpipe_context *softpipe); struct pipe_context * softpipe_create_context( struct pipe_screen *, void *priv ); +struct pipe_resource * +softpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags); #define SP_UNREFERENCED 0 #define SP_REFERENCED_FOR_READ (1 << 0) diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c index af05d0d5d68..4056d2d4444 100644 --- a/src/gallium/drivers/softpipe/sp_state_shader.c +++ b/src/gallium/drivers/softpipe/sp_state_shader.c @@ -346,8 +346,17 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct pipe_resource *constants = cb ? cb->buffer : NULL; - unsigned size = constants ? constants->width0 : 0; - const void *data = constants ? softpipe_resource(constants)->data : NULL; + unsigned size; + const void *data; + + if (cb && cb->user_buffer) { + constants = softpipe_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + + size = constants ? constants->width0 : 0; + data = constants ? softpipe_resource(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); @@ -364,6 +373,10 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, softpipe->const_buffer_size[shader][index] = size; softpipe->dirty |= SP_NEW_CONSTANTS; + + if (cb && cb->user_buffer) { + pipe_resource_reference(&constants, NULL); + } } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index f5c6f565f21..292010638f9 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -454,7 +454,7 @@ softpipe_transfer_unmap(struct pipe_context *pipe, /** * Create buffer which wraps user-space data. */ -static struct pipe_resource * +struct pipe_resource * softpipe_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c index 5de547bc08a..46dc45b9ed0 100644 --- a/src/gallium/drivers/svga/svga_pipe_constants.c +++ b/src/gallium/drivers/svga/svga_pipe_constants.c @@ -29,6 +29,7 @@ #include "tgsi/tgsi_parse.h" #include "svga_context.h" +#include "svga_resource_buffer.h" /*********************************************************************** * Constant buffers @@ -50,6 +51,12 @@ static void svga_set_constant_buffer(struct pipe_context *pipe, struct svga_context *svga = svga_context(pipe); struct pipe_resource *buf = cb ? cb->buffer : NULL; + if (cb && cb->user_buffer) { + buf = svga_user_buffer_create(pipe->screen, cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -60,6 +67,10 @@ static void svga_set_constant_buffer(struct pipe_context *pipe, svga->dirty |= SVGA_NEW_FS_CONST_BUFFER; else svga->dirty |= SVGA_NEW_VS_CONST_BUFFER; + + if (cb && cb->user_buffer) { + pipe_resource_reference(&buf, NULL); + } } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index ceb6c6b7ef1..e969b74eff6 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -459,6 +459,7 @@ struct pipe_constant_buffer { struct pipe_resource *buffer; /**< the actual buffer */ unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */ unsigned buffer_size; /**< how much data can be read in shader */ + const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */ }; diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index eb98161dbd0..c9018b3bd77 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -56,8 +56,6 @@ void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, unsigned shader_type) { - struct pipe_context *pipe = st->pipe; - assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT || shader_type == PIPE_SHADER_GEOMETRY); @@ -80,13 +78,12 @@ void st_upload_constants( struct st_context *st, */ if (st->constbuf_uploader) { cb.buffer = NULL; + cb.user_buffer = NULL; u_upload_data(st->constbuf_uploader, 0, paramBytes, params->ParameterValues, &cb.buffer_offset, &cb.buffer); } else { - cb.buffer = pipe_user_buffer_create(pipe->screen, - params->ParameterValues, - paramBytes, - PIPE_BIND_CONSTANT_BUFFER); + cb.buffer = NULL; + cb.user_buffer = params->ParameterValues; cb.buffer_offset = 0; } cb.buffer_size = paramBytes;