gallium: add void *user_buffer to pipe_constant_buffer
This reduces CPU overhead when updating constants.
This commit is contained in:
@@ -672,6 +672,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
unsigned new_num = 0;
|
unsigned new_num = 0;
|
||||||
boolean diff = TRUE;
|
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 */
|
/* XXX don't support geom shaders now */
|
||||||
if (shader == PIPE_SHADER_GEOMETRY)
|
if (shader == PIPE_SHADER_GEOMETRY)
|
||||||
@@ -707,6 +712,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
|
|
||||||
if (diff)
|
if (diff)
|
||||||
i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS;
|
i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS;
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&buf, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -155,6 +155,12 @@ extern unsigned llvmpipe_variant_count;
|
|||||||
struct pipe_context *
|
struct pipe_context *
|
||||||
llvmpipe_create_context( struct pipe_screen *screen, void *priv );
|
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 *
|
static INLINE struct llvmpipe_context *
|
||||||
llvmpipe_context( struct pipe_context *pipe )
|
llvmpipe_context( struct pipe_context *pipe )
|
||||||
|
@@ -1173,8 +1173,17 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
{
|
{
|
||||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||||
struct pipe_resource *constants = cb ? cb->buffer : NULL;
|
struct pipe_resource *constants = cb ? cb->buffer : NULL;
|
||||||
unsigned size = constants ? constants->width0 : 0;
|
unsigned size;
|
||||||
const void *data = constants ? llvmpipe_resource_data(constants) : NULL;
|
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(shader < PIPE_SHADER_TYPES);
|
||||||
assert(index < PIPE_MAX_CONSTANT_BUFFERS);
|
assert(index < PIPE_MAX_CONSTANT_BUFFERS);
|
||||||
@@ -1194,6 +1203,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
llvmpipe->dirty |= LP_NEW_CONSTANTS;
|
llvmpipe->dirty |= LP_NEW_CONSTANTS;
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&constants, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -748,7 +748,7 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe,
|
|||||||
/**
|
/**
|
||||||
* Create buffer which wraps user-space data.
|
* Create buffer which wraps user-space data.
|
||||||
*/
|
*/
|
||||||
static struct pipe_resource *
|
struct pipe_resource *
|
||||||
llvmpipe_user_buffer_create(struct pipe_screen *screen,
|
llvmpipe_user_buffer_create(struct pipe_screen *screen,
|
||||||
void *ptr,
|
void *ptr,
|
||||||
unsigned bytes,
|
unsigned bytes,
|
||||||
|
@@ -323,6 +323,12 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||||||
struct pipe_resource *buf = cb ? cb->buffer : NULL;
|
struct pipe_resource *buf = cb ? cb->buffer : NULL;
|
||||||
unsigned size;
|
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;
|
size = 0;
|
||||||
if (buf)
|
if (buf)
|
||||||
size = buf->width0 / (4 * sizeof(float));
|
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->fragprog.constbuf_nr = size;
|
||||||
nv30->dirty |= NV30_NEW_FRAGCONST;
|
nv30->dirty |= NV30_NEW_FRAGCONST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&buf, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -749,6 +749,12 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||||||
struct nv50_context *nv50 = nv50_context(pipe);
|
struct nv50_context *nv50 = nv50_context(pipe);
|
||||||
struct pipe_resource *res = cb ? cb->buffer : NULL;
|
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);
|
pipe_resource_reference(&nv50->constbuf[shader][index], res);
|
||||||
|
|
||||||
nv50->constbuf_dirty[shader] |= 1 << index;
|
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));
|
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
|
||||||
|
|
||||||
nv50->dirty |= NV50_NEW_CONSTBUF;
|
nv50->dirty |= NV50_NEW_CONSTBUF;
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&res, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
|
@@ -621,6 +621,12 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||||
struct pipe_resource *res = cb ? cb->buffer : NULL;
|
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) {
|
switch (shader) {
|
||||||
case PIPE_SHADER_VERTEX: shader = 0; break;
|
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->constbuf_dirty[shader] |= 1 << index;
|
||||||
|
|
||||||
nvc0->dirty |= NVC0_NEW_CONSTBUF;
|
nvc0->dirty |= NVC0_NEW_CONSTBUF;
|
||||||
|
|
||||||
|
if (cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&res, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
|
@@ -1841,8 +1841,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
if (buf == NULL || buf->width0 == 0)
|
if (buf == NULL || buf->width0 == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rbuf->b.b.user_ptr)
|
if (cb->user_buffer)
|
||||||
mapped = (uint32_t*)rbuf->b.b.user_ptr;
|
mapped = (uint32_t*)cb->user_buffer;
|
||||||
else if (rbuf->constant_buffer)
|
else if (rbuf->constant_buffer)
|
||||||
mapped = (uint32_t*)rbuf->constant_buffer;
|
mapped = (uint32_t*)rbuf->constant_buffer;
|
||||||
else
|
else
|
||||||
|
@@ -1203,10 +1203,8 @@ static void evergreen_set_clip_state(struct pipe_context *ctx,
|
|||||||
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
|
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
|
||||||
r600_context_pipe_state_set(rctx, rstate);
|
r600_context_pipe_state_set(rctx, rstate);
|
||||||
|
|
||||||
cb.buffer = pipe_user_buffer_create(ctx->screen,
|
cb.buffer = NULL;
|
||||||
state->ucp,
|
cb.user_buffer = state->ucp;
|
||||||
4*4*8, /* 8*4 floats */
|
|
||||||
PIPE_BIND_CONSTANT_BUFFER);
|
|
||||||
cb.buffer_offset = 0;
|
cb.buffer_offset = 0;
|
||||||
cb.buffer_size = 4*4*8;
|
cb.buffer_size = 4*4*8;
|
||||||
r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
|
r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
|
||||||
|
@@ -1286,10 +1286,8 @@ static void r600_set_clip_state(struct pipe_context *ctx,
|
|||||||
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
|
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
|
||||||
r600_context_pipe_state_set(rctx, rstate);
|
r600_context_pipe_state_set(rctx, rstate);
|
||||||
|
|
||||||
cb.buffer = pipe_user_buffer_create(ctx->screen,
|
cb.buffer = NULL;
|
||||||
state->ucp,
|
cb.user_buffer = state->ucp;
|
||||||
4*4*8, /* 8*4 floats */
|
|
||||||
PIPE_BIND_CONSTANT_BUFFER);
|
|
||||||
cb.buffer_offset = 0;
|
cb.buffer_offset = 0;
|
||||||
cb.buffer_size = 4*4*8;
|
cb.buffer_size = 4*4*8;
|
||||||
r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
|
r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
|
||||||
|
@@ -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_context *rctx = (struct r600_context *)ctx;
|
||||||
struct r600_constbuf_state *state;
|
struct r600_constbuf_state *state;
|
||||||
struct pipe_constant_buffer *cb;
|
struct pipe_constant_buffer *cb;
|
||||||
uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
switch (shader) {
|
switch (shader) {
|
||||||
case PIPE_SHADER_VERTEX:
|
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 = &state->cb[index];
|
||||||
cb->buffer_size = input->buffer_size;
|
cb->buffer_size = input->buffer_size;
|
||||||
|
|
||||||
ptr = input->buffer->user_ptr;
|
ptr = input->user_buffer;
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
/* Upload the user buffer. */
|
/* Upload the user buffer. */
|
||||||
|
@@ -439,6 +439,12 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
|
|||||||
return;
|
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_inval_shader_cache(rctx);
|
||||||
|
|
||||||
r600_upload_const_buffer(rctx, &rbuffer, &offset);
|
r600_upload_const_buffer(rctx, &rbuffer, &offset);
|
||||||
|
@@ -206,6 +206,11 @@ softpipe_reset_sampler_variants(struct softpipe_context *softpipe);
|
|||||||
struct pipe_context *
|
struct pipe_context *
|
||||||
softpipe_create_context( struct pipe_screen *, void *priv );
|
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_UNREFERENCED 0
|
||||||
#define SP_REFERENCED_FOR_READ (1 << 0)
|
#define SP_REFERENCED_FOR_READ (1 << 0)
|
||||||
|
@@ -346,8 +346,17 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
{
|
{
|
||||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||||
struct pipe_resource *constants = cb ? cb->buffer : NULL;
|
struct pipe_resource *constants = cb ? cb->buffer : NULL;
|
||||||
unsigned size = constants ? constants->width0 : 0;
|
unsigned size;
|
||||||
const void *data = constants ? softpipe_resource(constants)->data : NULL;
|
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);
|
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->const_buffer_size[shader][index] = size;
|
||||||
|
|
||||||
softpipe->dirty |= SP_NEW_CONSTANTS;
|
softpipe->dirty |= SP_NEW_CONSTANTS;
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&constants, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -454,7 +454,7 @@ softpipe_transfer_unmap(struct pipe_context *pipe,
|
|||||||
/**
|
/**
|
||||||
* Create buffer which wraps user-space data.
|
* Create buffer which wraps user-space data.
|
||||||
*/
|
*/
|
||||||
static struct pipe_resource *
|
struct pipe_resource *
|
||||||
softpipe_user_buffer_create(struct pipe_screen *screen,
|
softpipe_user_buffer_create(struct pipe_screen *screen,
|
||||||
void *ptr,
|
void *ptr,
|
||||||
unsigned bytes,
|
unsigned bytes,
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "tgsi/tgsi_parse.h"
|
#include "tgsi/tgsi_parse.h"
|
||||||
|
|
||||||
#include "svga_context.h"
|
#include "svga_context.h"
|
||||||
|
#include "svga_resource_buffer.h"
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Constant buffers
|
* Constant buffers
|
||||||
@@ -50,6 +51,12 @@ static void svga_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
struct svga_context *svga = svga_context(pipe);
|
struct svga_context *svga = svga_context(pipe);
|
||||||
struct pipe_resource *buf = cb ? cb->buffer : NULL;
|
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(shader < PIPE_SHADER_TYPES);
|
||||||
assert(index == 0);
|
assert(index == 0);
|
||||||
|
|
||||||
@@ -60,6 +67,10 @@ static void svga_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
|
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
|
||||||
else
|
else
|
||||||
svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
|
svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
|
||||||
|
|
||||||
|
if (cb && cb->user_buffer) {
|
||||||
|
pipe_resource_reference(&buf, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -459,6 +459,7 @@ struct pipe_constant_buffer {
|
|||||||
struct pipe_resource *buffer; /**< the actual buffer */
|
struct pipe_resource *buffer; /**< the actual buffer */
|
||||||
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
|
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
|
||||||
unsigned buffer_size; /**< how much data can be read in shader */
|
unsigned buffer_size; /**< how much data can be read in shader */
|
||||||
|
const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -56,8 +56,6 @@ void st_upload_constants( struct st_context *st,
|
|||||||
struct gl_program_parameter_list *params,
|
struct gl_program_parameter_list *params,
|
||||||
unsigned shader_type)
|
unsigned shader_type)
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = st->pipe;
|
|
||||||
|
|
||||||
assert(shader_type == PIPE_SHADER_VERTEX ||
|
assert(shader_type == PIPE_SHADER_VERTEX ||
|
||||||
shader_type == PIPE_SHADER_FRAGMENT ||
|
shader_type == PIPE_SHADER_FRAGMENT ||
|
||||||
shader_type == PIPE_SHADER_GEOMETRY);
|
shader_type == PIPE_SHADER_GEOMETRY);
|
||||||
@@ -80,13 +78,12 @@ void st_upload_constants( struct st_context *st,
|
|||||||
*/
|
*/
|
||||||
if (st->constbuf_uploader) {
|
if (st->constbuf_uploader) {
|
||||||
cb.buffer = NULL;
|
cb.buffer = NULL;
|
||||||
|
cb.user_buffer = NULL;
|
||||||
u_upload_data(st->constbuf_uploader, 0, paramBytes,
|
u_upload_data(st->constbuf_uploader, 0, paramBytes,
|
||||||
params->ParameterValues, &cb.buffer_offset, &cb.buffer);
|
params->ParameterValues, &cb.buffer_offset, &cb.buffer);
|
||||||
} else {
|
} else {
|
||||||
cb.buffer = pipe_user_buffer_create(pipe->screen,
|
cb.buffer = NULL;
|
||||||
params->ParameterValues,
|
cb.user_buffer = params->ParameterValues;
|
||||||
paramBytes,
|
|
||||||
PIPE_BIND_CONSTANT_BUFFER);
|
|
||||||
cb.buffer_offset = 0;
|
cb.buffer_offset = 0;
|
||||||
}
|
}
|
||||||
cb.buffer_size = paramBytes;
|
cb.buffer_size = paramBytes;
|
||||||
|
Reference in New Issue
Block a user