This reduces CPU overhead when updating constants.
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)
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);
+ }
}
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 )
{
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);
}
llvmpipe->dirty |= LP_NEW_CONSTANTS;
+
+ if (cb && cb->user_buffer) {
+ pipe_resource_reference(&constants, NULL);
+ }
}
/**
* 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,
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));
nv30->fragprog.constbuf_nr = size;
nv30->dirty |= NV30_NEW_FRAGCONST;
}
+
+ if (cb && cb->user_buffer) {
+ pipe_resource_reference(&buf, NULL);
+ }
}
static void
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;
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);
+ }
}
/* =============================================================================
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;
/*
nvc0->constbuf_dirty[shader] |= 1 << index;
nvc0->dirty |= NVC0_NEW_CONSTBUF;
+
+ if (cb->user_buffer) {
+ pipe_resource_reference(&res, NULL);
+ }
}
/* =============================================================================
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
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);
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);
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:
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. */
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);
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)
{
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);
softpipe->const_buffer_size[shader][index] = size;
softpipe->dirty |= SP_NEW_CONSTANTS;
+
+ if (cb && cb->user_buffer) {
+ pipe_resource_reference(&constants, NULL);
+ }
}
/**
* 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,
#include "tgsi/tgsi_parse.h"
#include "svga_context.h"
+#include "svga_resource_buffer.h"
/***********************************************************************
* Constant buffers
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);
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);
+ }
}
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 */
};
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);
*/
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;