gallium: add void *user_buffer to pipe_constant_buffer

This reduces CPU overhead when updating constants.
This commit is contained in:
Marek Olšák
2012-04-24 22:53:05 +02:00
parent 01bf5569c4
commit 0b7d48cbad
18 changed files with 111 additions and 24 deletions

View File

@@ -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);
}
}

View File

@@ -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 )

View File

@@ -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);
}
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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);
}
}
/* =============================================================================

View File

@@ -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);
}
}
/* =============================================================================

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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. */

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -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 */
};

View File

@@ -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;