summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-04-24 22:53:05 +0200
committerMarek Olšák <[email protected]>2012-04-30 01:18:48 +0200
commit0b7d48cbad86eaac21fce3793da41b46db8be3b4 (patch)
tree437f5cfeb3a77278d29e384b47dfaef9b96faa75
parent01bf5569c44389c1127bbb9e873c8a234ac92ff7 (diff)
gallium: add void *user_buffer to pipe_constant_buffer
This reduces CPU overhead when updating constants.
-rw-r--r--src/gallium/drivers/i915/i915_state.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c10
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c10
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c10
-rw-r--r--src/gallium/drivers/r300/r300_state.c4
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c6
-rw-r--r--src/gallium/drivers/r600/r600_state.c6
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c4
-rw-r--r--src/gallium/drivers/radeonsi/r600_state_common.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_state_shader.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_constants.c11
-rw-r--r--src/gallium/include/pipe/p_state.h1
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c9
18 files changed, 111 insertions, 24 deletions
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;