aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-05-11 16:38:13 +0200
committerMarek Olšák <[email protected]>2012-05-11 16:38:13 +0200
commitbb4c5d72d7c7cb1d9e7016e2c07c36875f30011a (patch)
tree153444ff535900f82ae63b5af8ccd09fb2f063af /src
parent96956dc5076fc03b9290368ca90e3f3b870ee613 (diff)
parent8dd3e341b337ca2d22bcc0e7548a78a6c36ca77d (diff)
Merge branch 'gallium-userbuf'
Conflicts: src/gallium/docs/source/screen.rst src/gallium/drivers/nv50/nv50_state.c src/gallium/include/pipe/p_defines.h src/mesa/state_tracker/st_draw.c
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c28
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c5
-rw-r--r--src/gallium/auxiliary/postprocess/pp_mlaa.c4
-rw-r--r--src/gallium/auxiliary/util/u_draw.c4
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c26
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h3
-rw-r--r--src/gallium/auxiliary/util/u_index_modify.c83
-rw-r--r--src/gallium/auxiliary/util/u_index_modify.h16
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h15
-rw-r--r--src/gallium/auxiliary/util/u_transfer.c8
-rw-r--r--src/gallium/auxiliary/util/u_transfer.h5
-rw-r--r--src/gallium/auxiliary/util/u_vbuf.c34
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c2
-rw-r--r--src/gallium/docs/source/screen.rst9
-rw-r--r--src/gallium/drivers/galahad/glhd_context.c27
-rw-r--r--src/gallium/drivers/i915/i915_context.c9
-rw-r--r--src/gallium/drivers/i915/i915_resource_buffer.c1
-rw-r--r--src/gallium/drivers/i915/i915_screen.c5
-rw-r--r--src/gallium/drivers/i915/i915_state.c17
-rw-r--r--src/gallium/drivers/identity/id_context.c27
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c3
-rw-r--r--src/gallium/drivers/noop/noop_pipe.c1
-rw-r--r--src/gallium/drivers/noop/noop_state.c3
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_draw.c15
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c7
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c15
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c16
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c15
-rw-r--r--src/gallium/drivers/r300/r300_context.h3
-rw-r--r--src/gallium/drivers/r300/r300_render.c55
-rw-r--r--src/gallium/drivers/r300/r300_render_translate.c25
-rw-r--r--src/gallium/drivers/r300/r300_screen.c5
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c6
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h2
-rw-r--r--src/gallium/drivers/r300/r300_state.c8
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c17
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c5
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c5
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h11
-rw-r--r--src/gallium/drivers/r600/r600_state.c17
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c26
-rw-r--r--src/gallium/drivers/r600/r600_translate.c2
-rw-r--r--src/gallium/drivers/radeonsi/evergreen_state.c1
-rw-r--r--src/gallium/drivers/radeonsi/r600_buffer.c51
-rw-r--r--src/gallium/drivers/radeonsi/r600_resource.h4
-rw-r--r--src/gallium/drivers/radeonsi/r600_state_common.c15
-rw-r--r--src/gallium/drivers/radeonsi/r600_translate.c3
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.c5
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.h2
-rw-r--r--src/gallium/drivers/rbug/rbug_context.c29
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_state_shader.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c3
-rw-r--r--src/gallium/drivers/svga/svga_pipe_constants.c15
-rw-r--r--src/gallium/drivers/svga/svga_resource.c1
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c1
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h6
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c18
-rw-r--r--src/gallium/drivers/svga/svga_screen.c5
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c20
-rw-r--r--src/gallium/drivers/trace/tr_context.c46
-rw-r--r--src/gallium/include/pipe/p_context.h12
-rw-r--r--src/gallium/include/pipe/p_defines.h5
-rw-r--r--src/gallium/include/pipe/p_state.h17
-rw-r--r--src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h6
-rw-r--r--src/gallium/state_trackers/vega/polygon.c29
-rw-r--r--src/gallium/state_trackers/vega/renderer.c27
-rw-r--r--src/gallium/state_trackers/xa/xa_renderer.c61
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c69
-rw-r--r--src/gallium/tests/graw/fs-test.c4
-rw-r--r--src/gallium/tests/graw/gs-test.c4
-rw-r--r--src/gallium/tests/graw/vs-test.c2
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c27
-rw-r--r--src/mesa/state_tracker/st_context.c53
-rw-r--r--src/mesa/state_tracker/st_context.h16
-rw-r--r--src/mesa/state_tracker/st_draw.c240
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c32
91 files changed, 710 insertions, 817 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 1cd5f8de184..7f2dc431ae5 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -233,6 +233,25 @@ static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type
}
}
+static void cso_init_vbuf(struct cso_context *cso)
+{
+ struct u_vbuf_caps caps;
+
+ u_vbuf_get_caps(cso->pipe->screen, &caps);
+
+ /* Install u_vbuf if there is anything unsupported. */
+ if (!caps.buffer_offset_unaligned ||
+ !caps.buffer_stride_unaligned ||
+ !caps.velem_src_offset_unaligned ||
+ !caps.format_fixed32 ||
+ !caps.format_float16 ||
+ !caps.format_float64 ||
+ !caps.format_norm32 ||
+ !caps.format_scaled32 ||
+ !caps.user_vertex_buffers) {
+ cso->vbuf = u_vbuf_create(cso->pipe, &caps);
+ }
+}
struct cso_context *cso_create_context( struct pipe_context *pipe )
{
@@ -251,6 +270,8 @@ struct cso_context *cso_create_context( struct pipe_context *pipe )
ctx->pipe = pipe;
+ cso_init_vbuf(ctx);
+
/* Enable for testing: */
if (0) cso_set_maximum_cache_size( ctx->cache, 4 );
@@ -270,11 +291,6 @@ out:
return NULL;
}
-void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf)
-{
- ctx->vbuf = vbuf;
-}
-
/**
* Prior to context destruction, this function unbinds all state objects.
*/
@@ -343,6 +359,8 @@ void cso_release_all( struct cso_context *ctx )
void cso_destroy_context( struct cso_context *ctx )
{
if (ctx) {
+ if (ctx->vbuf)
+ u_vbuf_destroy(ctx->vbuf);
FREE( ctx );
}
}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 79279343c39..4de08a8364c 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -43,8 +43,6 @@ struct u_vbuf;
struct cso_context *cso_create_context( struct pipe_context *pipe );
-void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf);
-
void cso_release_all( struct cso_context *ctx );
void cso_destroy_context( struct cso_context *cso );
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 620d6dc8de3..7bf9d5e5d7a 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -236,12 +236,13 @@ static LLVMTypeRef
create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name)
{
LLVMTargetDataRef target = gallivm->target;
- LLVMTypeRef elem_types[3];
+ LLVMTypeRef elem_types[4];
LLVMTypeRef vb_type;
elem_types[0] =
elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
- elem_types[2] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
+ elem_types[2] =
+ elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
#if HAVE_LLVM >= 0x0300
vb_type = LLVMStructCreateNamed(gallivm->context, struct_name);
diff --git a/src/gallium/auxiliary/postprocess/pp_mlaa.c b/src/gallium/auxiliary/postprocess/pp_mlaa.c
index 51bc02edacc..b61cbaafb5e 100644
--- a/src/gallium/auxiliary/postprocess/pp_mlaa.c
+++ b/src/gallium/auxiliary/postprocess/pp_mlaa.c
@@ -99,8 +99,8 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in,
dimensions[1] = p->framebuffer.height;
}
- p->pipe->set_constant_buffer(p->pipe, PIPE_SHADER_VERTEX, 0, constbuf);
- p->pipe->set_constant_buffer(p->pipe, PIPE_SHADER_FRAGMENT, 0, constbuf);
+ pipe_set_constant_buffer(p->pipe, PIPE_SHADER_VERTEX, 0, constbuf);
+ pipe_set_constant_buffer(p->pipe, PIPE_SHADER_FRAGMENT, 0, constbuf);
mstencil.stencil[0].enabled = 1;
mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0;
diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c
index d16575b7340..1f3eb887959 100644
--- a/src/gallium/auxiliary/util/u_draw.c
+++ b/src/gallium/auxiliary/util/u_draw.c
@@ -62,6 +62,10 @@ util_draw_max_index(
const struct util_format_description *format_desc;
unsigned format_size;
+ if (!buffer->buffer) {
+ continue;
+ }
+
assert(buffer->buffer->height0 == 1);
assert(buffer->buffer->depth0 == 1);
buffer_size = buffer->buffer->width0;
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 590fa0c36bb..469c874988d 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -69,6 +69,27 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
}
+/**
+ * Draw a simple vertex buffer / primitive.
+ * Limited to float[4] vertex attribs, tightly packed.
+ */
+void
+util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer,
+ uint prim_type, uint num_verts, uint num_attribs)
+{
+ struct pipe_vertex_buffer vbuffer = {0};
+
+ assert(num_attribs <= PIPE_MAX_ATTRIBS);
+
+ vbuffer.user_buffer = buffer;
+ vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
+
+ /* note: vertex elements already set by caller */
+
+ cso_set_vertex_buffers(cso, 1, &vbuffer);
+ cso_draw_arrays(cso, prim_type, 0, num_verts);
+}
+
/**
* Draw screen-aligned textured quad.
@@ -118,10 +139,11 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
v[28] = 0.0;
v[29] = 1.0;
- vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuf = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STAGING, vertexBytes);
if (!vbuf)
goto out;
+ pipe_buffer_write(pipe, vbuf, 0, vertexBytes, v);
util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index f1167786f0e..2834a4a8115 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -47,6 +47,9 @@ util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
struct pipe_resource *vbuf, uint offset,
uint num_attribs, uint num_verts, uint prim_type);
+void
+util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer,
+ uint prim_type, uint num_verts, uint num_attribs);
extern void
util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
diff --git a/src/gallium/auxiliary/util/u_index_modify.c b/src/gallium/auxiliary/util/u_index_modify.c
index d0a28b5fdfa..5e3fd463eb4 100644
--- a/src/gallium/auxiliary/util/u_index_modify.c
+++ b/src/gallium/auxiliary/util/u_index_modify.c
@@ -27,21 +27,25 @@
/* Ubyte indices. */
void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start,
unsigned count,
void *out)
{
- struct pipe_transfer *src_transfer;
- unsigned char *in_map;
+ struct pipe_transfer *src_transfer = NULL;
+ const unsigned char *in_map;
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &src_transfer);
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &src_transfer);
+ }
in_map += start;
for (i = 0; i < count; i++) {
@@ -50,11 +54,13 @@ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
out_map++;
}
- pipe_buffer_unmap(context, src_transfer);
+ if (src_transfer)
+ pipe_buffer_unmap(context, src_transfer);
}
void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start,
unsigned count)
@@ -70,31 +76,36 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
&dst_transfer);
- util_shorten_ubyte_elts_to_userptr(context, *elts, index_bias,
+ util_shorten_ubyte_elts_to_userptr(context, ib, index_bias,
start, count, out_map);
pipe_buffer_unmap(context, dst_transfer);
- *elts = new_elts;
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
}
/* Ushort indices. */
void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start, unsigned count,
void *out)
{
struct pipe_transfer *in_transfer = NULL;
- unsigned short *in_map;
+ const unsigned short *in_map;
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
+ }
in_map += start;
for (i = 0; i < count; i++) {
@@ -103,11 +114,13 @@ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
out_map++;
}
- pipe_buffer_unmap(context, in_transfer);
+ if (in_transfer)
+ pipe_buffer_unmap(context, in_transfer);
}
void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start, unsigned count)
{
@@ -122,31 +135,36 @@ void util_rebuild_ushort_elts(struct pipe_context *context,
out_map = pipe_buffer_map(context, new_elts,
PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_ushort_elts_to_userptr(context, *elts, index_bias,
+ util_rebuild_ushort_elts_to_userptr(context, ib, index_bias,
start, count, out_map);
pipe_buffer_unmap(context, out_transfer);
- *elts = new_elts;
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
}
/* Uint indices. */
void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start, unsigned count,
void *out)
{
struct pipe_transfer *in_transfer = NULL;
- unsigned int *in_map;
+ const unsigned int *in_map;
unsigned int *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
+ }
in_map += start;
for (i = 0; i < count; i++) {
@@ -155,11 +173,13 @@ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
out_map++;
}
- pipe_buffer_unmap(context, in_transfer);
+ if (in_transfer)
+ pipe_buffer_unmap(context, in_transfer);
}
void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start, unsigned count)
{
@@ -174,9 +194,10 @@ void util_rebuild_uint_elts(struct pipe_context *context,
out_map = pipe_buffer_map(context, new_elts,
PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_uint_elts_to_userptr(context, *elts, index_bias,
+ util_rebuild_uint_elts_to_userptr(context, ib, index_bias,
start, count, out_map);
pipe_buffer_unmap(context, out_transfer);
- *elts = new_elts;
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
}
diff --git a/src/gallium/auxiliary/util/u_index_modify.h b/src/gallium/auxiliary/util/u_index_modify.h
index 1e9de3dfac8..6afce50b984 100644
--- a/src/gallium/auxiliary/util/u_index_modify.h
+++ b/src/gallium/auxiliary/util/u_index_modify.h
@@ -25,16 +25,18 @@
struct pipe_context;
struct pipe_resource;
+struct pipe_index_buffer;
void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start,
unsigned count,
void *out);
void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start,
unsigned count);
@@ -42,26 +44,28 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start, unsigned count,
void *out);
void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start, unsigned count);
void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
+ struct pipe_index_buffer *ib,
int index_bias,
unsigned start, unsigned count,
void *out);
void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
int index_bias,
unsigned start, unsigned count);
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 49b4531dbac..651f7c2d727 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -437,6 +437,21 @@ pipe_transfer_destroy( struct pipe_context *context,
context->transfer_destroy(context, transfer);
}
+static INLINE void
+pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
+ struct pipe_resource *buf)
+{
+ if (buf) {
+ struct pipe_constant_buffer cb;
+ cb.buffer = buf;
+ cb.buffer_offset = 0;
+ cb.buffer_size = buf->width0;
+ pipe->set_constant_buffer(pipe, shader, index, &cb);
+ } else {
+ pipe->set_constant_buffer(pipe, shader, index, NULL);
+ }
+}
+
static INLINE boolean util_get_offset(
const struct pipe_rasterizer_state *templ,
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index 673a984fcb2..0b2679ffdb4 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -125,11 +125,3 @@ void u_default_transfer_destroy(struct pipe_context *pipe,
{
FREE(transfer);
}
-
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size)
-{
- resource->width0 = MAX2(resource->width0, offset + size);
-}
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 5b5ddeb4aba..f4fdf9a4840 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -124,9 +124,4 @@ void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
unsigned stride,
unsigned layer_stride);
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size);
-
#endif
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 401c8a4a850..4141ba536fd 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -277,8 +277,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
uint8_t *map;
- if (vb->buffer->user_ptr) {
- map = vb->buffer->user_ptr + offset;
+ if (vb->user_buffer) {
+ map = (uint8_t*)vb->user_buffer + offset;
} else {
unsigned size = vb->stride ? num_vertices * vb->stride
: sizeof(double)*4;
@@ -307,10 +307,10 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned offset = ib->offset + start_index * ib->index_size;
uint8_t *map;
- assert(ib->buffer && ib->index_size);
+ assert((ib->buffer || ib->user_buffer) && ib->index_size);
- if (ib->buffer->user_ptr) {
- map = ib->buffer->user_ptr + offset;
+ if (ib->user_buffer) {
+ map = (uint8_t*)ib->user_buffer + offset;
} else {
map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset,
num_indices * ib->index_size,
@@ -713,15 +713,17 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
pipe_resource_reference(&orig_vb->buffer, vb->buffer);
+ orig_vb->user_buffer = vb->user_buffer;
real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
real_vb->stride = orig_vb->stride = vb->stride;
+ real_vb->user_buffer = NULL;
if (vb->stride) {
mgr->nonzero_stride_vb_mask |= 1 << i;
}
- if (!vb->buffer) {
+ if (!vb->buffer && !vb->user_buffer) {
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
@@ -733,13 +735,14 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
continue;
}
- if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) {
+ if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
mgr->user_vb_mask |= 1 << i;
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
pipe_resource_reference(&real_vb->buffer, vb->buffer);
+ real_vb->user_buffer = vb->user_buffer;
}
for (i = count; i < mgr->nr_vertex_buffers; i++) {
@@ -759,11 +762,10 @@ void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
{
struct pipe_context *pipe = mgr->pipe;
- if (ib && ib->buffer) {
+ if (ib) {
assert(ib->offset % ib->index_size == 0);
pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer);
- mgr->index_buffer.offset = ib->offset;
- mgr->index_buffer.index_size = ib->index_size;
+ memcpy(&mgr->index_buffer, ib, sizeof(*ib));
} else {
pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
}
@@ -798,9 +800,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
continue;
}
- assert(vb->buffer);
-
- if (!vb->buffer->user_ptr) {
+ if (!vb->user_buffer) {
continue;
}
@@ -837,7 +837,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
for (i = 0; i < nr_vbufs; i++) {
unsigned start, end = end_offset[i];
struct pipe_vertex_buffer *real_vb;
- uint8_t *ptr;
+ const uint8_t *ptr;
if (!end) {
continue;
@@ -847,7 +847,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
assert(start < end);
real_vb = &mgr->real_vertex_buffer[i];
- ptr = mgr->vertex_buffer[i].buffer->user_ptr;
+ ptr = mgr->vertex_buffer[i].user_buffer;
u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer);
@@ -888,8 +888,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
unsigned i;
unsigned restart_index = info->restart_index;
- if (ib->buffer->user_ptr) {
- indices = ib->buffer->user_ptr +
+ if (ib->user_buffer) {
+ indices = (uint8_t*)ib->user_buffer +
ib->offset + info->start * ib->index_size;
} else {
indices = pipe_buffer_map_range(pipe, ib->buffer,
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index cc213b748a5..0cb1a9f38ad 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -1015,7 +1015,7 @@ vl_compositor_render(struct vl_compositor_state *s,
c->pipe->bind_vs_state(c->pipe, c->vs);
c->pipe->set_vertex_buffers(c->pipe, 1, &c->vertex_buf);
c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);
- c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->csc_matrix);
+ pipe_set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->csc_matrix);
c->pipe->bind_rasterizer_state(c->pipe, c->rast);
draw_layers(c, s, dirty_area);
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index d912dc6d81d..ff63ce83bea 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -112,6 +112,15 @@ The integer capabilities:
aligned to 4. If false, there are no restrictions on src_offset.
* ``PIPE_CAP_COMPUTE``: Whether the implementation supports the
compute entry points defined in pipe_context and pipe_screen.
+* ``PIPE_CAP_USER_INDEX_BUFFERS``: Whether user index buffers are supported.
+ If not, the state tracker must upload all indices which are not in hw
+ resources.
+* ``PIPE_CAP_USER_CONSTANT_BUFFERS``: Whether user constant buffers are
+ supported. If not, the state tracker must upload constants which are not in hw
+ resources.
+* ``PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT``: Describes the required
+ alignment of pipe_constant_buffer::buffer_offset.
+
.. _pipe_capf:
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index 0bb18884c8d..4dae61ca64a 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -458,12 +458,11 @@ static void
galahad_set_constant_buffer(struct pipe_context *_pipe,
uint shader,
uint index,
- struct pipe_resource *_resource)
+ struct pipe_constant_buffer *_cb)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->pipe;
- struct pipe_resource *unwrapped_resource;
- struct pipe_resource *resource = NULL;
+ struct pipe_constant_buffer cb;
if (shader >= PIPE_SHADER_TYPES) {
glhd_error("Unknown shader type %u", shader);
@@ -479,15 +478,15 @@ galahad_set_constant_buffer(struct pipe_context *_pipe,
}
/* XXX hmm? unwrap the input state */
- if (_resource) {
- unwrapped_resource = galahad_resource_unwrap(_resource);
- resource = unwrapped_resource;
+ if (_cb) {
+ cb = *_cb;
+ cb.buffer = galahad_resource_unwrap(_cb->buffer);
}
pipe->set_constant_buffer(pipe,
shader,
index,
- resource);
+ _cb ? &cb : NULL);
}
static void
@@ -949,19 +948,6 @@ galahad_context_transfer_inline_write(struct pipe_context *_context,
}
-static void galahad_redefine_user_buffer(struct pipe_context *_context,
- struct pipe_resource *_resource,
- unsigned offset, unsigned size)
-{
- struct galahad_context *glhd_context = galahad_context(_context);
- struct galahad_resource *glhd_resource = galahad_resource(_resource);
- struct pipe_context *context = glhd_context->pipe;
- struct pipe_resource *resource = glhd_resource->resource;
-
- context->redefine_user_buffer(context, resource, offset, size);
-}
-
-
struct pipe_context *
galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
{
@@ -1034,7 +1020,6 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
glhd_pipe->base.transfer_unmap = galahad_context_transfer_unmap;
glhd_pipe->base.transfer_flush_region = galahad_context_transfer_flush_region;
glhd_pipe->base.transfer_inline_write = galahad_context_transfer_inline_write;
- glhd_pipe->base.redefine_user_buffer = galahad_redefine_user_buffer;
glhd_pipe->pipe = pipe;
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 052a059c268..f3c7b30527c 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -53,7 +53,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
- void *mapped_indices = NULL;
+ const void *mapped_indices = NULL;
/*
@@ -67,8 +67,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
/*
* Map index buffer, if present
*/
- if (info->indexed && i915->index_buffer.buffer)
- mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+ if (info->indexed) {
+ mapped_indices = i915->index_buffer.user_buffer;
+ if (!mapped_indices)
+ mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+ }
draw_set_mapped_index_buffer(draw, mapped_indices);
if (i915->constants[PIPE_SHADER_VERTEX])
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index 6718948fe5c..77c03450b3a 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -183,7 +183,6 @@ i915_user_buffer_create(struct pipe_screen *screen,
buf->b.b.height0 = 1;
buf->b.b.depth0 = 1;
buf->b.b.array_size = 1;
- buf->b.b.user_ptr = ptr;
buf->data = ptr;
buf->free_on_destroy = FALSE;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 1546ee80230..00468602c09 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -181,6 +181,8 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_TGSI_INSTANCEID:
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
/* Unsupported features (boolean caps). */
@@ -206,6 +208,9 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
+
/* Features we can lie about (boolean caps). */
case PIPE_CAP_OCCLUSION_QUERY:
return is->debug.lie ? 1 : 0;
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 4c284d9fcbb..bd9e8bac0ae 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -665,12 +665,18 @@ static void i915_delete_vs_state(struct pipe_context *pipe, void *shader)
static void i915_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_resource *buf)
+ struct pipe_constant_buffer *cb)
{
struct i915_context *i915 = i915_context(pipe);
+ struct pipe_resource *buf = cb ? cb->buffer : NULL;
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)
@@ -706,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);
+ }
}
@@ -982,7 +992,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
/* map new */
for (i = 0; i < count; i++) {
- void *buf = i915_buffer(buffers[i].buffer)->data;
+ const void *buf = buffers[i].user_buffer;
+ if (!buf)
+ buf = i915_buffer(buffers[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
@@ -1092,7 +1104,6 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
i915->base.set_index_buffer = i915_set_index_buffer;
- i915->base.redefine_user_buffer = u_default_redefine_user_buffer;
}
void
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index af3f8239ccd..2d47296f230 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -411,23 +411,22 @@ static void
identity_set_constant_buffer(struct pipe_context *_pipe,
uint shader,
uint index,
- struct pipe_resource *_resource)
+ struct pipe_constant_buffer *_cb)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_resource *unwrapped_resource;
- struct pipe_resource *resource = NULL;
+ struct pipe_constant_buffer cb;
/* XXX hmm? unwrap the input state */
- if (_resource) {
- unwrapped_resource = identity_resource_unwrap(_resource);
- resource = unwrapped_resource;
+ if (_cb) {
+ cb = *_cb;
+ cb.buffer = identity_resource_unwrap(_cb->buffer);
}
pipe->set_constant_buffer(pipe,
shader,
index,
- resource);
+ _cb ? &cb : NULL);
}
static void
@@ -836,19 +835,6 @@ identity_context_transfer_inline_write(struct pipe_context *_context,
}
-static void identity_redefine_user_buffer(struct pipe_context *_context,
- struct pipe_resource *_resource,
- unsigned offset, unsigned size)
-{
- struct identity_context *id_context = identity_context(_context);
- struct identity_resource *id_resource = identity_resource(_resource);
- struct pipe_context *context = id_context->pipe;
- struct pipe_resource *resource = id_resource->resource;
-
- context->redefine_user_buffer(context, resource, offset, size);
-}
-
-
struct pipe_context *
identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
{
@@ -921,7 +907,6 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.transfer_unmap = identity_context_transfer_unmap;
id_pipe->base.transfer_flush_region = identity_context_transfer_flush_region;
id_pipe->base.transfer_inline_write = identity_context_transfer_inline_write;
- id_pipe->base.redefine_user_buffer = identity_redefine_user_buffer;
id_pipe->pipe = pipe;
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_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 239a596bce0..225b80e3dfb 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -54,7 +54,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct draw_context *draw = lp->draw;
- void *mapped_indices = NULL;
+ const void *mapped_indices = NULL;
unsigned i;
if (!llvmpipe_check_render_cond(lp))
@@ -67,13 +67,18 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
* Map vertex buffers
*/
for (i = 0; i < lp->num_vertex_buffers; i++) {
- void *buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
+ const void *buf = lp->vertex_buffer[i].user_buffer;
+ if (!buf)
+ buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
- if (info->indexed && lp->index_buffer.buffer)
- mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+ if (info->indexed) {
+ mapped_indices = lp->index_buffer.user_buffer;
+ if (!mapped_indices)
+ mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+ }
draw_set_mapped_index_buffer(draw, mapped_indices);
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 3e0808d61da..40037a544bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -160,7 +160,11 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
default:
return 0;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 582c6db15d5..2d2391e908c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -1166,11 +1166,21 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
static void
llvmpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_resource *constants)
+ struct pipe_constant_buffer *cb)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
- unsigned size = constants ? constants->width0 : 0;
- const void *data = constants ? llvmpipe_resource_data(constants) : NULL;
+ struct pipe_resource *constants = cb ? cb->buffer : 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);
@@ -1190,6 +1200,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_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index be86f66de91..a62cfd55334 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -115,6 +115,4 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer;
-
- llvmpipe->pipe.redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index f6a1ec26bc5..198874b4fce 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,
@@ -770,7 +770,6 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen,
buffer->base.height0 = 1;
buffer->base.depth0 = 1;
buffer->base.array_size = 1;
- buffer->base.user_ptr = ptr;
buffer->userBuffer = TRUE;
buffer->data = ptr;
diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c
index e63263a0e0c..e47f944b59b 100644
--- a/src/gallium/drivers/noop/noop_pipe.c
+++ b/src/gallium/drivers/noop/noop_pipe.c
@@ -156,7 +156,6 @@ static struct pipe_resource *noop_user_buffer_create(struct pipe_screen *screen,
templ.height0 = 1;
templ.depth0 = 1;
templ.flags = 0;
- templ.user_ptr = ptr;
return noop_resource_create(screen, &templ);
}
diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c
index 9d8dbfc4e25..dbfe35b668c 100644
--- a/src/gallium/drivers/noop/noop_state.c
+++ b/src/gallium/drivers/noop/noop_state.c
@@ -175,7 +175,7 @@ static void noop_set_framebuffer_state(struct pipe_context *ctx,
static void noop_set_constant_buffer(struct pipe_context *ctx,
uint shader, uint index,
- struct pipe_resource *buffer)
+ struct pipe_constant_buffer *cb)
{
}
@@ -320,7 +320,6 @@ void noop_init_state_functions(struct pipe_context *ctx)
ctx->sampler_view_destroy = noop_sampler_view_destroy;
ctx->surface_destroy = noop_surface_destroy;
ctx->draw_vbo = noop_draw_vbo;
- ctx->redefine_user_buffer = u_default_redefine_user_buffer;
ctx->create_stream_output_target = noop_create_stream_output_target;
ctx->stream_output_target_destroy = noop_stream_output_target_destroy;
ctx->set_stream_output_targets = noop_set_stream_output_targets;
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index f6629901c15..936e2bf246a 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -398,7 +398,6 @@ nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr,
buffer->base.width0 = bytes;
buffer->base.height0 = 1;
buffer->base.depth0 = 1;
- buffer->base.user_ptr = ptr;
buffer->data = ptr;
buffer->status = NOUVEAU_BUFFER_STATUS_USER_MEMORY;
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
index 61e324606f2..29e63953838 100644
--- a/src/gallium/drivers/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nv30/nv30_draw.c
@@ -366,7 +366,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct nv30_context *nv30 = nv30_context(pipe);
struct draw_context *draw = nv30->draw;
- struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *transferi = NULL;
int i;
@@ -403,14 +403,18 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
}
for (i = 0; i < nv30->num_vtxbufs; i++) {
- void *map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
+ const void *map = nv30->vtxbuf[i].user_buffer;
+ if (!map)
+ map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_READ, &transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, map);
}
if (info->indexed) {
- void *map = pipe_buffer_map(pipe, nv30->idxbuf.buffer,
+ const void *map = nv30->idxbuf.user_buffer;
+ if (!map)
+ pipe_buffer_map(pipe, nv30->idxbuf.buffer,
PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_READ, &transferi);
draw_set_index_buffer(draw, &nv30->idxbuf);
@@ -422,10 +426,11 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
draw_vbo(draw, info);
draw_flush(draw);
- if (info->indexed)
+ if (info->indexed && transferi)
pipe_buffer_unmap(pipe, transferi);
for (i = 0; i < nv30->num_vtxbufs; i++)
- pipe_buffer_unmap(pipe, transfer[i]);
+ if (transfer[i])
+ pipe_buffer_unmap(pipe, transfer[i]);
nv30->draw_dirty = 0;
nv30_state_release(nv30);
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index d355f749a09..c3e50a58316 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -78,8 +78,13 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
- case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_VERTEX_BUFFERS:
+ return 0;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
/* nv4x capabilities */
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_NPOT_TEXTURES:
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index 64a8f33d466..f65c8b71fdd 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -317,11 +317,18 @@ nv30_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
static void
nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_resource *buf)
+ struct pipe_constant_buffer *cb)
{
struct nv30_context *nv30 = nv30_context(pipe);
+ 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));
@@ -336,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
@@ -442,6 +453,4 @@ nv30_state_init(struct pipe_context *pipe)
pipe->set_vertex_buffers = nv30_set_vertex_buffers;
pipe->set_index_buffer = nv30_set_index_buffer;
-
- pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index b341ade695e..c96e028b2a2 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -151,9 +151,13 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
- return 0; /* state trackers will know better */
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ return 0; /* state trackers will know better */
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 256;
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 5e32b2717fd..7f840e2b42e 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -747,9 +747,16 @@ nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
static void
nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_resource *res)
+ struct pipe_constant_buffer *cb)
{
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);
@@ -762,6 +769,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);
+ }
}
/* =============================================================================
@@ -1055,7 +1066,4 @@ nv50_init_state_functions(struct nv50_context *nv50)
pipe->create_stream_output_target = nv50_so_target_create;
pipe->stream_output_target_destroy = nv50_so_target_destroy;
pipe->set_stream_output_targets = nv50_set_stream_output_targets;
-
- pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
-
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 457d56e7d9e..5d6befd45b7 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -139,9 +139,13 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
- return 0; /* state trackers will know better */
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ return 0; /* state trackers will know better */
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 256;
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index a2be53a433d..40161252a3d 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -616,9 +616,16 @@ nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso)
static void
nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_resource *res)
+ struct pipe_constant_buffer *cb)
{
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;
@@ -641,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);
+ }
}
/* =============================================================================
@@ -946,7 +957,5 @@ nvc0_init_state_functions(struct nvc0_context *nvc0)
pipe->create_stream_output_target = nvc0_so_target_create;
pipe->stream_output_target_destroy = nvc0_so_target_destroy;
pipe->set_stream_output_targets = nvc0_set_transform_feedback_targets;
-
- pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index ca57a5c7857..b58f514c358 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -692,7 +692,8 @@ void r300_stop_query(struct r300_context *r300);
/* r300_render_translate.c */
void r300_translate_index_buffer(struct r300_context *r300,
- struct pipe_resource **index_buffer,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_index_buffer,
unsigned *index_size, unsigned index_offset,
unsigned *start, unsigned count);
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 99302dc8b0a..56f480d3358 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -508,9 +508,9 @@ static void r300_emit_draw_elements(struct r300_context *r300,
static void r300_draw_elements_immediate(struct r300_context *r300,
const struct pipe_draw_info *info)
{
- uint8_t *ptr1;
- uint16_t *ptr2;
- uint32_t *ptr4;
+ const uint8_t *ptr1;
+ const uint16_t *ptr2;
+ const uint32_t *ptr4;
unsigned index_size = r300->index_buffer.index_size;
unsigned i, count_dwords = index_size == 4 ? info->count :
(info->count + 1) / 2;
@@ -529,7 +529,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
switch (index_size) {
case 1:
- ptr1 = r300->index_buffer.buffer->user_ptr;
+ ptr1 = (uint8_t*)r300->index_buffer.user_buffer;
ptr1 += info->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -553,7 +553,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
break;
case 2:
- ptr2 = (uint16_t*)r300->index_buffer.buffer->user_ptr;
+ ptr2 = (uint16_t*)r300->index_buffer.user_buffer;
ptr2 += info->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -572,7 +572,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
break;
case 4:
- ptr4 = (uint32_t*)r300->index_buffer.buffer->user_ptr;
+ ptr4 = (uint32_t*)r300->index_buffer.user_buffer;
ptr4 += info->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -606,15 +606,15 @@ static void r300_draw_elements(struct r300_context *r300,
uint16_t indices3[3];
if (info->index_bias && !r300->screen->caps.is_r500) {
- r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset);
+ r300_split_index_bias(r300, info->index_bias, &buffer_offset,
+ &index_offset);
}
- r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
- &start, count);
+ r300_translate_index_buffer(r300, &r300->index_buffer, &indexBuffer,
+ &indexSize, index_offset, &start, count);
/* Fallback for misaligned ushort indices. */
- if (indexSize == 2 && (start & 1) &&
- !indexBuffer->user_ptr) {
+ if (indexSize == 2 && (start & 1) && indexBuffer) {
/* If we got here, then orgIndexBuffer == indexBuffer. */
uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->cs_buf,
r300->cs,
@@ -632,10 +632,10 @@ static void r300_draw_elements(struct r300_context *r300,
}
r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->cs_buf);
} else {
- if (indexBuffer->user_ptr)
+ if (r300->index_buffer.user_buffer)
r300_upload_index_buffer(r300, &indexBuffer, indexSize,
&start, count,
- indexBuffer->user_ptr);
+ r300->index_buffer.user_buffer);
}
/* 19 dwords for emit_draw_elements. Give up if the function fails. */
@@ -795,7 +795,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct pipe_draw_info info = *dinfo;
- info.indexed = info.indexed && r300->index_buffer.buffer;
+ info.indexed = info.indexed;
if (r300->skip_rendering ||
!u_trim_pipe_prim(info.mode, &info.count)) {
@@ -824,7 +824,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
if (info.instance_count <= 1) {
if (info.count <= 8 &&
- r300->index_buffer.buffer->user_ptr) {
+ r300->index_buffer.user_buffer) {
r300_draw_elements_immediate(r300, &info);
} else {
r300_draw_elements(r300, &info, -1);
@@ -858,8 +858,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer = NULL;
int i;
- void *indices = NULL;
- boolean indexed = info->indexed && r300->index_buffer.buffer;
+ const void *indices = NULL;
+ boolean indexed = info->indexed;
if (r300->skip_rendering) {
return;
@@ -873,7 +873,10 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
indexed ? 256 : 6);
for (i = 0; i < r300->nr_vertex_buffers; i++) {
- if (r300->vertex_buffer[i].buffer) {
+ if (r300->vertex_buffer[i].user_buffer) {
+ draw_set_mapped_vertex_buffer(r300->draw, i,
+ r300->vertex_buffer[i].user_buffer);
+ } else if (r300->vertex_buffer[i].buffer) {
void *buf = pipe_buffer_map(pipe,
r300->vertex_buffer[i].buffer,
PIPE_TRANSFER_READ |
@@ -884,9 +887,13 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
}
if (indexed) {
- indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
+ if (r300->index_buffer.user_buffer) {
+ indices = r300->index_buffer.user_buffer;
+ } else {
+ indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
+ }
}
draw_set_mapped_index_buffer(r300->draw, indices);
@@ -899,13 +906,15 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
for (i = 0; i < r300->nr_vertex_buffers; i++) {
if (r300->vertex_buffer[i].buffer) {
- pipe_buffer_unmap(pipe, vb_transfer[i]);
+ if (vb_transfer[i])
+ pipe_buffer_unmap(pipe, vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
}
}
if (indexed) {
- pipe_buffer_unmap(pipe, ib_transfer);
+ if (ib_transfer)
+ pipe_buffer_unmap(pipe, ib_transfer);
draw_set_mapped_index_buffer(r300->draw, NULL);
}
}
diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c
index 022e8a7fc70..caeeec05909 100644
--- a/src/gallium/drivers/r300/r300_render_translate.c
+++ b/src/gallium/drivers/r300/r300_render_translate.c
@@ -26,55 +26,52 @@
void r300_translate_index_buffer(struct r300_context *r300,
- struct pipe_resource **index_buffer,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buffer,
unsigned *index_size, unsigned index_offset,
unsigned *start, unsigned count)
{
- struct pipe_resource *out_buffer = NULL;
unsigned out_offset;
void *ptr;
switch (*index_size) {
case 1:
+ *out_buffer = NULL;
u_upload_alloc(r300->uploader, 0, count * 2,
- &out_offset, &out_buffer, &ptr);
+ &out_offset, out_buffer, &ptr);
util_shorten_ubyte_elts_to_userptr(
- &r300->context, *index_buffer, index_offset,
+ &r300->context, ib, index_offset,
*start, count, ptr);
- *index_buffer = NULL;
- pipe_resource_reference(index_buffer, out_buffer);
*index_size = 2;
*start = out_offset / 2;
break;
case 2:
if (index_offset) {
+ *out_buffer = NULL;
u_upload_alloc(r300->uploader, 0, count * 2,
- &out_offset, &out_buffer, &ptr);
+ &out_offset, out_buffer, &ptr);
- util_rebuild_ushort_elts_to_userptr(&r300->context, *index_buffer,
+ util_rebuild_ushort_elts_to_userptr(&r300->context, ib,
index_offset, *start,
count, ptr);
- *index_buffer = NULL;
- pipe_resource_reference(index_buffer, out_buffer);
*start = out_offset / 2;
}
break;
case 4:
if (index_offset) {
+ *out_buffer = NULL;
u_upload_alloc(r300->uploader, 0, count * 4,
- &out_offset, &out_buffer, &ptr);
+ &out_offset, out_buffer, &ptr);
- util_rebuild_uint_elts_to_userptr(&r300->context, *index_buffer,
+ util_rebuild_uint_elts_to_userptr(&r300->context, ib,
index_offset, *start,
count, ptr);
- *index_buffer = NULL;
- pipe_resource_reference(index_buffer, out_buffer);
*start = out_offset / 4;
}
break;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 0803a0808b5..f84f3e5c58e 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -106,8 +106,13 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
+
case PIPE_CAP_GLSL_FEATURE_LEVEL:
return 120;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index d05c9149287..7927310a578 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -35,7 +35,7 @@
void r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size, unsigned *start,
- unsigned count, uint8_t *ptr)
+ unsigned count, const uint8_t *ptr)
{
unsigned index_offset;
@@ -108,8 +108,6 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
uint8_t *map;
enum pipe_transfer_usage usage;
- if (rbuf->b.b.user_ptr)
- return rbuf->b.b.user_ptr + transfer->box.x;
if (rbuf->constant_buffer)
return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
@@ -159,7 +157,6 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
rbuf->b.vtbl = &r300_buffer_vtbl;
pipe_reference_init(&rbuf->b.b.reference, 1);
rbuf->b.b.screen = screen;
- rbuf->b.b.user_ptr = NULL;
rbuf->domain = RADEON_DOMAIN_GTT;
rbuf->buf = NULL;
rbuf->constant_buffer = NULL;
@@ -205,7 +202,6 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
rbuf->b.b.depth0 = 1;
rbuf->b.b.array_size = 1;
rbuf->b.b.flags = 0;
- rbuf->b.b.user_ptr = ptr;
rbuf->b.vtbl = &r300_buffer_vtbl;
rbuf->domain = RADEON_DOMAIN_GTT;
rbuf->buf = NULL;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index 360ec509cc5..482b6e424ed 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -39,7 +39,7 @@
void r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size, unsigned *start,
- unsigned count, uint8_t *ptr);
+ unsigned count, const uint8_t *ptr);
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
const struct pipe_resource *templ);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 337008be47e..566bc443807 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1819,9 +1819,10 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
static void r300_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_resource *buf)
+ struct pipe_constant_buffer *cb)
{
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_resource *buf = cb ? cb->buffer : NULL;
struct r300_constant_buffer *cbuf;
struct r300_resource *rbuf = r300_resource(buf);
uint32_t *mapped;
@@ -1840,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
@@ -1933,7 +1934,6 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
r300->context.set_index_buffer = r300_set_index_buffer;
- r300->context.redefine_user_buffer = u_default_redefine_user_buffer;
r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 82313ea6031..81aedb5c0ac 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1177,7 +1177,7 @@ static void evergreen_set_clip_state(struct pipe_context *ctx,
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
- struct pipe_resource *cbuf;
+ struct pipe_constant_buffer cb;
if (rstate == NULL)
return;
@@ -1203,12 +1203,12 @@ static void evergreen_set_clip_state(struct pipe_context *ctx,
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
r600_context_pipe_state_set(rctx, rstate);
- cbuf = pipe_user_buffer_create(ctx->screen,
- state->ucp,
- 4*4*8, /* 8*4 floats */
- PIPE_BIND_CONSTANT_BUFFER);
- r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, cbuf);
- pipe_resource_reference(&cbuf, NULL);
+ 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);
+ pipe_resource_reference(&cb.buffer, NULL);
}
static void evergreen_set_polygon_stipple(struct pipe_context *ctx,
@@ -1767,7 +1767,7 @@ static void evergreen_emit_constant_buffer(struct r600_context *rctx,
uint32_t dirty_mask = state->dirty_mask;
while (dirty_mask) {
- struct r600_constant_buffer *cb;
+ struct pipe_constant_buffer *cb;
struct r600_resource *rbuffer;
uint64_t va;
unsigned buffer_index = ffs(dirty_mask) - 1;
@@ -1871,7 +1871,6 @@ void evergreen_init_state_functions(struct r600_context *rctx)
rctx->context.set_vertex_sampler_views = evergreen_set_vs_sampler_view;
rctx->context.set_viewport_state = evergreen_set_viewport_state;
rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
- rctx->context.redefine_user_buffer = u_default_redefine_user_buffer;
rctx->context.texture_barrier = r600_texture_barrier;
rctx->context.create_stream_output_target = r600_create_so_target;
rctx->context.stream_output_target_destroy = r600_so_target_destroy;
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index a3d63a68b5a..0ca6ff114b4 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -126,9 +126,6 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
}
}
- if (rbuffer->b.b.user_ptr)
- return rbuffer->b.b.user_ptr + transfer->box.x;
-
data = rctx->ws->buffer_map(rbuffer->cs_buf, rctx->cs, transfer->usage);
if (!data)
return NULL;
@@ -216,7 +213,6 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
rbuffer->b.b = *templ;
pipe_reference_init(&rbuffer->b.b.reference, 1);
rbuffer->b.b.screen = screen;
- rbuffer->b.b.user_ptr = NULL;
rbuffer->b.vtbl = &r600_buffer_vtbl;
if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, templ->bind, templ->usage)) {
@@ -247,7 +243,6 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
rbuffer->b.b.depth0 = 1;
rbuffer->b.b.array_size = 1;
rbuffer->b.b.flags = 0;
- rbuffer->b.b.user_ptr = ptr;
rbuffer->buf = NULL;
return &rbuffer->b.b;
}
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 0b67a0143a0..11f0fde177e 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -403,8 +403,13 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 256;
+
case PIPE_CAP_GLSL_FEATURE_LEVEL:
return rscreen->glsl_feature_level;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 3a5f5509b62..db455f021ad 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -228,17 +228,10 @@ struct r600_stencil_ref
ubyte writemask[2];
};
-struct r600_constant_buffer
-{
- struct pipe_resource *buffer;
- unsigned buffer_offset;
- unsigned buffer_size;
-};
-
struct r600_constbuf_state
{
struct r600_atom atom;
- struct r600_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
+ struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
uint32_t enabled_mask;
uint32_t dirty_mask;
};
@@ -498,7 +491,7 @@ void r600_delete_ps_shader(struct pipe_context *ctx, void *state);
void r600_delete_vs_shader(struct pipe_context *ctx, void *state);
void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state);
void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
- struct pipe_resource *buffer);
+ struct pipe_constant_buffer *cb);
struct pipe_stream_output_target *
r600_create_so_target(struct pipe_context *ctx,
struct pipe_resource *buffer,
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 2ad57b27f10..acf59f80bf4 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1260,7 +1260,7 @@ static void r600_set_clip_state(struct pipe_context *ctx,
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
- struct pipe_resource * cbuf;
+ struct pipe_constant_buffer cb;
if (rstate == NULL)
return;
@@ -1286,12 +1286,12 @@ static void r600_set_clip_state(struct pipe_context *ctx,
rctx->states[R600_PIPE_STATE_CLIP] = rstate;
r600_context_pipe_state_set(rctx, rstate);
- cbuf = pipe_user_buffer_create(ctx->screen,
- state->ucp,
- 4*4*8, /* 8*4 floats */
- PIPE_BIND_CONSTANT_BUFFER);
- r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, cbuf);
- pipe_resource_reference(&cbuf, NULL);
+ 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);
+ pipe_resource_reference(&cb.buffer, NULL);
}
static void r600_set_polygon_stipple(struct pipe_context *ctx,
@@ -1738,7 +1738,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
uint32_t dirty_mask = state->dirty_mask;
while (dirty_mask) {
- struct r600_constant_buffer *cb;
+ struct pipe_constant_buffer *cb;
struct r600_resource *rbuffer;
unsigned offset;
unsigned buffer_index = ffs(dirty_mask) - 1;
@@ -1835,7 +1835,6 @@ void r600_init_state_functions(struct r600_context *rctx)
rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_views;
rctx->context.set_viewport_state = r600_set_viewport_state;
rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
- rctx->context.redefine_user_buffer = u_default_redefine_user_buffer;
rctx->context.texture_barrier = r600_texture_barrier;
rctx->context.create_stream_output_target = r600_create_so_target;
rctx->context.stream_output_target_destroy = r600_so_target_destroy;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index a817831fd82..d47383558d9 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -532,12 +532,12 @@ void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf
}
void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
- struct pipe_resource *buffer)
+ struct pipe_constant_buffer *input)
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_constbuf_state *state;
- struct r600_constant_buffer *cb;
- uint8_t *ptr;
+ struct pipe_constant_buffer *cb;
+ const uint8_t *ptr;
switch (shader) {
case PIPE_SHADER_VERTEX:
@@ -553,7 +553,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
/* Note that the state tracker can unbind constant buffers by
* passing NULL here.
*/
- if (unlikely(!buffer)) {
+ if (unlikely(!input)) {
state->enabled_mask &= ~(1 << index);
state->dirty_mask &= ~(1 << index);
pipe_resource_reference(&state->cb[index].buffer, NULL);
@@ -561,15 +561,15 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
}
cb = &state->cb[index];
- cb->buffer_size = buffer->width0;
+ cb->buffer_size = input->buffer_size;
- ptr = buffer->user_ptr;
+ ptr = input->user_buffer;
if (ptr) {
/* Upload the user buffer. */
if (R600_BIG_ENDIAN) {
uint32_t *tmpPtr;
- unsigned i, size = buffer->width0;
+ unsigned i, size = input->buffer_size;
if (!(tmpPtr = malloc(size))) {
R600_ERR("Failed to allocate BE swap buffer.\n");
@@ -583,12 +583,12 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
u_upload_data(rctx->uploader, 0, size, tmpPtr, &cb->buffer_offset, &cb->buffer);
free(tmpPtr);
} else {
- u_upload_data(rctx->uploader, 0, buffer->width0, ptr, &cb->buffer_offset, &cb->buffer);
+ u_upload_data(rctx->uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer);
}
} else {
/* Setup the hw buffer. */
- cb->buffer_offset = 0;
- pipe_resource_reference(&cb->buffer, buffer);
+ cb->buffer_offset = input->buffer_offset;
+ pipe_resource_reference(&cb->buffer, input->buffer);
}
state->enabled_mask |= 1 << index;
@@ -753,7 +753,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
uint8_t *ptr;
if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
- (info.indexed && !rctx->index_buffer.buffer) ||
!r600_conv_pipe_prim(info.mode, &prim)) {
assert(0);
return;
@@ -769,14 +768,15 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
if (info.indexed) {
/* Initialize the index buffer struct. */
pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
+ ib.user_buffer = rctx->index_buffer.user_buffer;
ib.index_size = rctx->index_buffer.index_size;
ib.offset = rctx->index_buffer.offset + info.start * ib.index_size;
/* Translate or upload, if needed. */
r600_translate_index_buffer(rctx, &ib, info.count);
- ptr = ib.buffer->user_ptr;
- if (ptr) {
+ ptr = (uint8_t*)ib.user_buffer;
+ if (!ib.buffer && ptr) {
u_upload_data(rctx->uploader, 0, info.count * ib.index_size,
ptr, &ib.offset, &ib.buffer);
}
diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c
index af3b8cad3aa..c054c865e02 100644
--- a/src/gallium/drivers/r600/r600_translate.c
+++ b/src/gallium/drivers/r600/r600_translate.c
@@ -42,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600,
&out_offset, &out_buffer, &ptr);
util_shorten_ubyte_elts_to_userptr(
- &r600->context, ib->buffer, 0, ib->offset, count, ptr);
+ &r600->context, ib, 0, ib->offset, count, ptr);
pipe_resource_reference(&ib->buffer, NULL);
ib->buffer = out_buffer;
diff --git a/src/gallium/drivers/radeonsi/evergreen_state.c b/src/gallium/drivers/radeonsi/evergreen_state.c
index 6d345b0679f..b094248fee1 100644
--- a/src/gallium/drivers/radeonsi/evergreen_state.c
+++ b/src/gallium/drivers/radeonsi/evergreen_state.c
@@ -1807,7 +1807,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
rctx->context.set_vertex_sampler_views = evergreen_set_vs_sampler_view;
rctx->context.set_viewport_state = evergreen_set_viewport_state;
rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
- rctx->context.redefine_user_buffer = u_default_redefine_user_buffer;
rctx->context.texture_barrier = r600_texture_barrier;
rctx->context.create_stream_output_target = r600_create_so_target;
rctx->context.stream_output_target_destroy = r600_so_target_destroy;
diff --git a/src/gallium/drivers/radeonsi/r600_buffer.c b/src/gallium/drivers/radeonsi/r600_buffer.c
index 912c4ebcdc9..c6b707187a8 100644
--- a/src/gallium/drivers/radeonsi/r600_buffer.c
+++ b/src/gallium/drivers/radeonsi/r600_buffer.c
@@ -76,9 +76,6 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
struct r600_context *rctx = (struct r600_context*)pipe;
uint8_t *data;
- if (rbuffer->b.b.user_ptr)
- return (uint8_t*)rbuffer->b.b.user_ptr + transfer->box.x;
-
data = rctx->ws->buffer_map(rbuffer->cs_buf, rctx->cs, transfer->usage);
if (!data)
return NULL;
@@ -173,7 +170,6 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
pipe_reference_init(&rbuffer->b.b.reference, 1);
rbuffer->b.b.screen = screen;
rbuffer->b.vtbl = &r600_buffer_vtbl;
- rbuffer->b.b.user_ptr = NULL;
if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, templ->bind, templ->usage)) {
util_slab_free(&rscreen->pool_buffers, rbuffer);
@@ -203,7 +199,6 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
rbuffer->b.b.depth0 = 1;
rbuffer->b.b.array_size = 1;
rbuffer->b.b.flags = 0;
- rbuffer->b.b.user_ptr = ptr;
rbuffer->buf = NULL;
return &rbuffer->b.b;
}
@@ -211,43 +206,35 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
void r600_upload_index_buffer(struct r600_context *rctx,
struct pipe_index_buffer *ib, unsigned count)
{
- struct r600_resource *rbuffer = r600_resource(ib->buffer);
-
u_upload_data(rctx->uploader, 0, count * ib->index_size,
- rbuffer->b.b.user_ptr, &ib->offset, &ib->buffer);
+ ib->user_buffer, &ib->offset, &ib->buffer);
}
void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer,
- uint32_t *const_offset)
+ const uint8_t *ptr, unsigned size,
+ uint32_t *const_offset)
{
- if ((*rbuffer)->b.b.user_ptr) {
- uint8_t *ptr = (*rbuffer)->b.b.user_ptr;
- unsigned size = (*rbuffer)->b.b.width0;
-
- *rbuffer = NULL;
+ *rbuffer = NULL;
- if (R600_BIG_ENDIAN) {
- uint32_t *tmpPtr;
- unsigned i;
+ if (R600_BIG_ENDIAN) {
+ uint32_t *tmpPtr;
+ unsigned i;
- if (!(tmpPtr = malloc(size))) {
- R600_ERR("Failed to allocate BE swap buffer.\n");
- return;
- }
+ if (!(tmpPtr = malloc(size))) {
+ R600_ERR("Failed to allocate BE swap buffer.\n");
+ return;
+ }
- for (i = 0; i < size / 4; ++i) {
- tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]);
- }
+ for (i = 0; i < size / 4; ++i) {
+ tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]);
+ }
- u_upload_data(rctx->uploader, 0, size, tmpPtr, const_offset,
- (struct pipe_resource**)rbuffer);
+ u_upload_data(rctx->uploader, 0, size, tmpPtr, const_offset,
+ (struct pipe_resource**)rbuffer);
- free(tmpPtr);
- } else {
- u_upload_data(rctx->uploader, 0, size, ptr, const_offset,
- (struct pipe_resource**)rbuffer);
- }
+ free(tmpPtr);
} else {
- *const_offset = 0;
+ u_upload_data(rctx->uploader, 0, size, ptr, const_offset,
+ (struct pipe_resource**)rbuffer);
}
}
diff --git a/src/gallium/drivers/radeonsi/r600_resource.h b/src/gallium/drivers/radeonsi/r600_resource.h
index e81a2ed4675..6926d764cbe 100644
--- a/src/gallium/drivers/radeonsi/r600_resource.h
+++ b/src/gallium/drivers/radeonsi/r600_resource.h
@@ -99,6 +99,8 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx,
struct r600_context;
-void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer, uint32_t *offset);
+void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer,
+ const uint8_t *ptr, unsigned size,
+ uint32_t *const_offset);
#endif
diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c
index 416c89048e6..06eb96b9ee8 100644
--- a/src/gallium/drivers/radeonsi/r600_state_common.c
+++ b/src/gallium/drivers/radeonsi/r600_state_common.c
@@ -424,10 +424,10 @@ static void r600_update_alpha_ref(struct r600_context *rctx)
}
void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
- struct pipe_resource *buffer)
+ struct pipe_constant_buffer *cb)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_resource *rbuffer = r600_resource(buffer);
+ struct r600_resource *rbuffer = cb ? r600_resource(cb->buffer) : NULL;
struct r600_pipe_state *rstate;
uint64_t va_offset;
uint32_t offset;
@@ -435,13 +435,16 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
/* Note that the state tracker can unbind constant buffers by
* passing NULL here.
*/
- if (buffer == NULL) {
+ if (cb == NULL) {
return;
}
r600_inval_shader_cache(rctx);
- r600_upload_const_buffer(rctx, &rbuffer, &offset);
+ if (cb->user_buffer)
+ r600_upload_const_buffer(rctx, &rbuffer, cb->user_buffer, cb->buffer_size, &offset);
+ else
+ offset = 0;
va_offset = r600_resource_va(ctx->screen, (void*)rbuffer);
va_offset += offset;
//va_offset >>= 8;
@@ -474,7 +477,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
r600_context_pipe_state_set(rctx, rstate);
- if (buffer != &rbuffer->b.b)
+ if (cb->buffer != &rbuffer->b.b)
pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
}
@@ -734,7 +737,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
/* Translate or upload, if needed. */
r600_translate_index_buffer(rctx, &ib, info.count);
- if (ib.buffer->user_ptr) {
+ if (ib.user_buffer) {
r600_upload_index_buffer(rctx, &ib, info.count);
}
diff --git a/src/gallium/drivers/radeonsi/r600_translate.c b/src/gallium/drivers/radeonsi/r600_translate.c
index 985f1f6f8dc..8633d770d10 100644
--- a/src/gallium/drivers/radeonsi/r600_translate.c
+++ b/src/gallium/drivers/radeonsi/r600_translate.c
@@ -24,7 +24,6 @@
*/
#include "util/u_index_modify.h"
-#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
#include "radeonsi_pipe.h"
@@ -43,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600,
&out_offset, &out_buffer, &ptr);
util_shorten_ubyte_elts_to_userptr(
- &r600->context, ib->buffer, 0, ib->offset, count, ptr);
+ &r600->context, ib, 0, ib->offset, count, ptr);
pipe_resource_reference(&ib->buffer, NULL);
ib->buffer = out_buffer;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index f97db3ac39a..aec5af277c5 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -345,8 +345,13 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 256;
+
case PIPE_CAP_GLSL_FEATURE_LEVEL:
return debug_get_bool_option("R600_GLSL130", FALSE) ? 130 : 120;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index 3077f068017..bba4cf23691 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -443,7 +443,7 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state);
void r600_delete_ps_shader(struct pipe_context *ctx, void *state);
void r600_delete_vs_shader(struct pipe_context *ctx, void *state);
void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
- struct pipe_resource *buffer);
+ struct pipe_constant_buffer *cb);
struct pipe_stream_output_target *
r600_create_so_target(struct pipe_context *ctx,
struct pipe_resource *buffer,
diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
index 46518cd6977..65f0d71031b 100644
--- a/src/gallium/drivers/rbug/rbug_context.c
+++ b/src/gallium/drivers/rbug/rbug_context.c
@@ -614,24 +614,23 @@ static void
rbug_set_constant_buffer(struct pipe_context *_pipe,
uint shader,
uint index,
- struct pipe_resource *_resource)
+ struct pipe_constant_buffer *_cb)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
- struct pipe_resource *unwrapped_resource;
- struct pipe_resource *resource = NULL;
+ struct pipe_constant_buffer cb;
/* XXX hmm? unwrap the input state */
- if (_resource) {
- unwrapped_resource = rbug_resource_unwrap(_resource);
- resource = unwrapped_resource;
+ if (_cb) {
+ cb = *_cb;
+ cb.buffer = rbug_resource_unwrap(_cb->buffer);
}
pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_constant_buffer(pipe,
shader,
index,
- resource);
+ _cb ? &cb : NULL);
pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -1140,21 +1139,6 @@ rbug_context_transfer_inline_write(struct pipe_context *_context,
}
-static void rbug_redefine_user_buffer(struct pipe_context *_context,
- struct pipe_resource *_resource,
- unsigned offset, unsigned size)
-{
- struct rbug_context *rb_pipe = rbug_context(_context);
- struct rbug_resource *rb_resource = rbug_resource(_resource);
- struct pipe_context *context = rb_pipe->pipe;
- struct pipe_resource *resource = rb_resource->resource;
-
- pipe_mutex_lock(rb_pipe->call_mutex);
- context->redefine_user_buffer(context, resource, offset, size);
- pipe_mutex_unlock(rb_pipe->call_mutex);
-}
-
-
struct pipe_context *
rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
{
@@ -1238,7 +1222,6 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap;
rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region;
rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write;
- rb_pipe->base.redefine_user_buffer = rbug_redefine_user_buffer;
rb_pipe->pipe = pipe;
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_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 27004071f02..7a2274565d5 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -61,7 +61,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
{
struct softpipe_context *sp = softpipe_context(pipe);
struct draw_context *draw = sp->draw;
- void *mapped_indices = NULL;
+ const void *mapped_indices = NULL;
unsigned i;
if (!softpipe_check_render_cond(sp))
@@ -77,13 +77,18 @@ softpipe_draw_vbo(struct pipe_context *pipe,
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
+ const void *buf = sp->vertex_buffer[i].user_buffer;
+ if (!buf)
+ buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
- if (info->indexed && sp->index_buffer.buffer)
- mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+ if (info->indexed) {
+ mapped_indices = sp->index_buffer.user_buffer;
+ if (!mapped_indices)
+ mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+ }
draw_set_mapped_index_buffer(draw, mapped_indices);
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 28fda94060d..cdc78676655 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -139,7 +139,11 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
default:
return 0;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c
index 6acb57b3fe6..910d4ba11a5 100644
--- a/src/gallium/drivers/softpipe/sp_state_shader.c
+++ b/src/gallium/drivers/softpipe/sp_state_shader.c
@@ -342,11 +342,22 @@ softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
static void
softpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_resource *constants)
+ struct pipe_constant_buffer *cb)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- unsigned size = constants ? constants->width0 : 0;
- const void *data = constants ? softpipe_resource(constants)->data : NULL;
+ struct pipe_resource *constants = cb ? cb->buffer : NULL;
+ unsigned size;
+ const void *data;
+
+ if (cb && cb->user_buffer) {
+ constants = softpipe_user_buffer_create(pipe->screen,
+ (void *) 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);
@@ -363,6 +374,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_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index aa0b333c7a9..1dbd79807d0 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -120,5 +120,4 @@ softpipe_init_vertex_funcs(struct pipe_context *pipe)
pipe->set_vertex_buffers = softpipe_set_vertex_buffers;
pipe->set_index_buffer = softpipe_set_index_buffer;
- pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index f5c6f565f21..ee8d4230dd9 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,
@@ -476,7 +476,6 @@ softpipe_user_buffer_create(struct pipe_screen *screen,
spr->base.height0 = 1;
spr->base.depth0 = 1;
spr->base.array_size = 1;
- spr->base.user_ptr = ptr;
spr->userBuffer = TRUE;
spr->data = ptr;
diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c
index 2fa2142d07d..cfa823b345d 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
@@ -45,9 +46,17 @@ struct svga_constbuf
static void svga_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_resource *buf)
+ struct pipe_constant_buffer *cb)
{
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,
+ (void *) cb->user_buffer,
+ cb->buffer_size,
+ PIPE_BIND_CONSTANT_BUFFER);
+ }
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
@@ -59,6 +68,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/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c
index bb6236dce67..b86469af12d 100644
--- a/src/gallium/drivers/svga/svga_resource.c
+++ b/src/gallium/drivers/svga/svga_resource.c
@@ -64,7 +64,6 @@ svga_init_resource_functions(struct svga_context *svga)
svga->pipe.transfer_unmap = u_transfer_unmap_vtbl;
svga->pipe.transfer_destroy = u_transfer_destroy_vtbl;
svga->pipe.transfer_inline_write = u_transfer_inline_write_vtbl;
- svga->pipe.redefine_user_buffer = svga_redefine_user_buffer;
}
void
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index ff53b827855..fa713ee88ad 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -394,7 +394,6 @@ svga_user_buffer_create(struct pipe_screen *screen,
sbuf->b.b.height0 = 1;
sbuf->b.b.depth0 = 1;
sbuf->b.b.array_size = 1;
- sbuf->b.b.user_ptr = ptr;
sbuf->swbuf = ptr;
sbuf->user = TRUE;
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index ca8c8d1f5ea..da85f1a002e 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -243,10 +243,4 @@ svga_winsys_buffer_create(struct svga_context *svga,
unsigned usage,
unsigned size);
-void
-svga_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size);
-
#endif /* SVGA_BUFFER_H */
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index e5273009d41..94a324d6dba 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -644,21 +644,3 @@ svga_context_flush_buffers(struct svga_context *svga)
next = curr->next;
}
}
-
-
-void
-svga_redefine_user_buffer(struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size)
-{
- struct svga_buffer *sbuf = svga_buffer(resource);
-
- assert(sbuf->user);
- assert(!sbuf->dma.pending);
- assert(!sbuf->handle);
- assert(!sbuf->hwbuf);
-
- /* use the default action of simply resizing the user buffer's size */
- u_default_redefine_user_buffer(pipe, resource, offset, size);
-}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 5a8434a04dc..64ec658b80e 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -161,7 +161,12 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_SWIZZLE:
return 1;
case PIPE_CAP_USER_VERTEX_BUFFERS:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ return 0;
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 16;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
{
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 377026411f2..bb6870f6572 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -66,12 +66,14 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
* Map vertex buffers
*/
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
- map = pipe_buffer_map(&svga->pipe,
- svga->curr.vb[i].buffer,
- PIPE_TRANSFER_READ,
- &vb_transfer[i]);
-
- draw_set_mapped_vertex_buffer(draw, i, map);
+ if (svga->curr.vb[i].buffer) {
+ map = pipe_buffer_map(&svga->pipe,
+ svga->curr.vb[i].buffer,
+ PIPE_TRANSFER_READ,
+ &vb_transfer[i]);
+
+ draw_set_mapped_vertex_buffer(draw, i, map);
+ }
}
/* TODO move this to update_swtnl_draw */
@@ -109,8 +111,10 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
* unmap vertex/index buffers
*/
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
- pipe_buffer_unmap(&svga->pipe, vb_transfer[i]);
- draw_set_mapped_vertex_buffer(draw, i, NULL);
+ if (svga->curr.vb[i].buffer) {
+ pipe_buffer_unmap(&svga->pipe, vb_transfer[i]);
+ draw_set_mapped_vertex_buffer(draw, i, NULL);
+ }
}
if (ib_transfer) {
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 51a8b259a04..11a2b163370 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -721,13 +721,15 @@ trace_context_set_sample_mask(struct pipe_context *_pipe,
static INLINE void
trace_context_set_constant_buffer(struct pipe_context *_pipe,
uint shader, uint index,
- struct pipe_resource *buffer)
+ struct pipe_constant_buffer *constant_buffer)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_constant_buffer cb;
- if (buffer) {
- buffer = trace_resource_unwrap(tr_ctx, buffer);
+ if (constant_buffer) {
+ cb = *constant_buffer;
+ cb.buffer = trace_resource_unwrap(tr_ctx, constant_buffer->buffer);
}
trace_dump_call_begin("pipe_context", "set_constant_buffer");
@@ -735,9 +737,18 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe,
trace_dump_arg(ptr, pipe);
trace_dump_arg(uint, shader);
trace_dump_arg(uint, index);
- trace_dump_arg(ptr, buffer);
+ if (constant_buffer) {
+ trace_dump_struct_begin("pipe_constant_buffer");
+ trace_dump_member(ptr, constant_buffer, buffer);
+ trace_dump_member(uint, constant_buffer, buffer_offset);
+ trace_dump_member(uint, constant_buffer, buffer_size);
+ trace_dump_struct_end();
+ } else {
+ trace_dump_arg(ptr, constant_buffer);
+ }
- pipe->set_constant_buffer(pipe, shader, index, buffer);
+ pipe->set_constant_buffer(pipe, shader, index,
+ constant_buffer ? &cb : NULL);
trace_dump_call_end();
}
@@ -1469,30 +1480,6 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
}
-static void trace_redefine_user_buffer(struct pipe_context *_context,
- struct pipe_resource *_resource,
- unsigned offset, unsigned size)
-{
- struct trace_context *tr_context = trace_context(_context);
- struct trace_resource *tr_res = trace_resource(_resource);
- struct pipe_context *context = tr_context->pipe;
- struct pipe_resource *resource = tr_res->resource;
-
- assert(resource->screen == context->screen);
-
- trace_dump_call_begin("pipe_context", "redefine_user_buffer");
-
- trace_dump_arg(ptr, context);
- trace_dump_arg(ptr, resource);
- trace_dump_arg(uint, offset);
- trace_dump_arg(uint, size);
-
- trace_dump_call_end();
-
- context->redefine_user_buffer(context, resource, offset, size);
-}
-
-
static void trace_render_condition(struct pipe_context *_context,
struct pipe_query *query,
uint mode)
@@ -1615,7 +1602,6 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.transfer_unmap = trace_context_transfer_unmap;
tr_ctx->base.transfer_flush_region = trace_context_transfer_flush_region;
tr_ctx->base.transfer_inline_write = trace_context_transfer_inline_write;
- tr_ctx->base.redefine_user_buffer = trace_redefine_user_buffer;
tr_ctx->pipe = pipe;
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 0951e70f481..f59e3881232 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -41,6 +41,7 @@ struct pipe_blend_color;
struct pipe_blend_state;
struct pipe_box;
struct pipe_clip_state;
+struct pipe_constant_buffer;
struct pipe_depth_stencil_alpha_state;
struct pipe_draw_info;
struct pipe_fence_handle;
@@ -199,7 +200,7 @@ struct pipe_context {
void (*set_constant_buffer)( struct pipe_context *,
uint shader, uint index,
- struct pipe_resource *buf );
+ struct pipe_constant_buffer *buf );
void (*set_framebuffer_state)( struct pipe_context *,
const struct pipe_framebuffer_state * );
@@ -414,15 +415,6 @@ struct pipe_context {
unsigned stride,
unsigned layer_stride);
-
- /* Notify a driver that a content of a user buffer has been changed.
- * The changed range is [offset, offset+size-1].
- * The new width0 of the buffer is offset+size. */
- void (*redefine_user_buffer)(struct pipe_context *,
- struct pipe_resource *,
- unsigned offset,
- unsigned size);
-
/**
* Flush any pending framebuffer writes and invalidate texture caches.
*/
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index edcca23746b..1e05cc4caee 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -481,7 +481,10 @@ enum pipe_cap {
PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY = 65,
PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY = 66,
PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY = 67,
- PIPE_CAP_COMPUTE = 68
+ PIPE_CAP_COMPUTE = 68,
+ PIPE_CAP_USER_INDEX_BUFFERS = 69,
+ PIPE_CAP_USER_CONSTANT_BUFFERS = 70,
+ PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 71
};
/**
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 02cd1fdfafb..51a956d9532 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -417,9 +417,6 @@ struct pipe_resource
unsigned bind; /**< bitmask of PIPE_BIND_x */
unsigned flags; /**< bitmask of PIPE_RESOURCE_FLAG_x */
-
- /* XXX this is only temporary and will be removed once it's not needed */
- uint8_t *user_ptr; /**< user buffer pointer */
};
@@ -449,6 +446,19 @@ struct pipe_vertex_buffer
unsigned stride; /**< stride to same attrib in next vertex, in bytes */
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
struct pipe_resource *buffer; /**< the actual buffer */
+ const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */
+};
+
+
+/**
+ * A constant buffer. A subrange of an existing buffer can be set
+ * as a constant buffer.
+ */
+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 */
};
@@ -507,6 +517,7 @@ struct pipe_index_buffer
unsigned index_size; /**< size of an index, in bytes */
unsigned offset; /**< offset to start of data in buffer, in bytes */
struct pipe_resource *buffer; /**< the actual buffer */
+ const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */
};
diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
index d5c366ffd4f..a7b761c707f 100644
--- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
+++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
@@ -344,7 +344,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl<threadsafe>
{
constant_buffers[s][start + i] = constbufs[i];
if(s < caps.stages && start + i < caps.constant_buffers[s])
- pipe->set_constant_buffer(pipe, s, start + i, constbufs[i] ? constbufs[i]->resource : NULL);
+ pipe_set_constant_buffer(pipe, s, start + i, constbufs[i] ? constbufs[i]->resource : NULL);
}
}
}
@@ -1715,7 +1715,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl<threadsafe>
{
unsigned num = std::min(caps.constant_buffers[s], (unsigned)D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
for(unsigned i = 0; i < num; ++i)
- pipe->set_constant_buffer(pipe, s, i, constant_buffers[s][i].p ? constant_buffers[s][i].p->resource : 0);
+ pipe_set_constant_buffer(pipe, s, i, constant_buffers[s][i].p ? constant_buffers[s][i].p->resource : 0);
}
update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_VS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_VS));
@@ -1961,7 +1961,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl<threadsafe>
if(constant_buffers[s][i] == buffer)
{
constant_buffers[s][i] = (ID3D10Buffer*)NULL;
- pipe->set_constant_buffer(pipe, s, i, NULL);
+ pipe_set_constant_buffer(pipe, s, i, NULL);
}
}
}
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index bcc5cb272ca..3faec749e12 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -57,7 +57,7 @@ struct polygon
VGint num_verts;
VGboolean dirty;
- struct pipe_resource *vbuf;
+ void *user_vbuf;
struct pipe_screen *screen;
};
@@ -89,7 +89,7 @@ struct polygon * polygon_create(int size)
poly->size = size;
poly->num_verts = 0;
poly->dirty = VG_TRUE;
- poly->vbuf = NULL;
+ poly->user_vbuf = NULL;
return poly;
}
@@ -101,16 +101,13 @@ struct polygon * polygon_create_from_data(float *data, int size)
memcpy(poly->data, data, sizeof(float) * COMPONENTS * size);
poly->num_verts = size;
poly->dirty = VG_TRUE;
- poly->vbuf = NULL;
+ poly->user_vbuf = NULL;
return poly;
}
void polygon_destroy(struct polygon *poly)
{
- if (poly->vbuf)
- pipe_resource_reference(&poly->vbuf, NULL);
-
free(poly->data);
free(poly);
}
@@ -247,25 +244,15 @@ VGboolean polygon_is_closed(struct polygon *p)
static void polygon_prepare_buffer(struct vg_context *ctx,
struct polygon *poly)
{
- int vert_size;
struct pipe_context *pipe;
- vert_size = poly->num_verts * COMPONENTS * sizeof(float);
-
/*polygon_print(poly);*/
pipe = ctx->pipe;
- if (poly->vbuf == NULL || poly->dirty) {
- if (poly->vbuf) {
- pipe_resource_reference(&poly->vbuf,
- NULL);
- }
+ if (poly->user_vbuf == NULL || poly->dirty) {
poly->screen = pipe->screen;
- poly->vbuf= pipe_user_buffer_create(poly->screen,
- poly->data,
- vert_size,
- PIPE_BIND_VERTEX_BUFFER);
+ poly->user_vbuf = poly->data;
poly->dirty = VG_FALSE;
}
}
@@ -300,9 +287,8 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
/* tell renderer about the vertex buffer */
memset(&vbuffer, 0, sizeof(vbuffer));
- vbuffer.buffer = poly->vbuf;
+ vbuffer.user_buffer = poly->user_vbuf;
vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
renderer_polygon_stencil_begin(ctx->renderer,
&velement, ctx->state.vg.fill_rule, VG_FALSE);
@@ -343,7 +329,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
/* tell renderer about the vertex buffer */
memset(&vbuffer, 0, sizeof(vbuffer));
vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
/* prepare the stencil buffer */
renderer_polygon_stencil_begin(ctx->renderer,
@@ -352,7 +337,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
struct polygon *poly = (((struct polygon**)polys->data)[i]);
polygon_prepare_buffer(ctx, poly);
- vbuffer.buffer = poly->vbuf;
+ vbuffer.user_buffer = poly->user_vbuf;
renderer_polygon_stencil(ctx->renderer, &vbuffer,
PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index add1eec0038..23ec14ab84c 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -179,7 +179,7 @@ static void renderer_set_mvp(struct renderer *renderer,
pipe_buffer_write(renderer->pipe, cbuf,
0, sizeof(consts), consts);
}
- renderer->pipe->set_constant_buffer(renderer->pipe,
+ pipe_set_constant_buffer(renderer->pipe,
PIPE_SHADER_VERTEX, 0, cbuf);
memcpy(cur, mvp, sizeof(*mvp));
@@ -478,7 +478,7 @@ static void renderer_set_custom_fs(struct renderer *renderer,
const_buffer_len);
pipe_buffer_write(renderer->pipe, cbuf, 0,
const_buffer_len, const_buffer);
- renderer->pipe->set_constant_buffer(renderer->pipe,
+ pipe_set_constant_buffer(renderer->pipe,
PIPE_SHADER_FRAGMENT, 0, cbuf);
renderer->fs_cbuf = cbuf;
@@ -566,20 +566,9 @@ static void renderer_quad_texcoord(struct renderer *r,
*/
static void renderer_quad_draw(struct renderer *r)
{
- struct pipe_resource *buf;
-
- buf = pipe_user_buffer_create(r->pipe->screen,
- r->vertices,
- sizeof(r->vertices),
- PIPE_BIND_VERTEX_BUFFER);
- if (buf) {
- util_draw_vertex_buffer(r->pipe, r->cso, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- Elements(r->vertices), /* verts */
- Elements(r->vertices[0])); /* attribs/vert */
-
- pipe_resource_reference(&buf, NULL);
- }
+ util_draw_user_vertex_buffer(r->cso, r->vertices, PIPE_PRIM_TRIANGLE_FAN,
+ Elements(r->vertices), /* verts */
+ Elements(r->vertices[0])); /* attribs/vert */
}
/**
@@ -1054,7 +1043,7 @@ void renderer_polygon_stencil(struct renderer *renderer,
cso_set_vertex_buffers(renderer->cso, 1, vbuf);
if (!renderer->u.polygon_stencil.manual_two_sides) {
- util_draw_arrays(renderer->pipe, mode, start, count);
+ cso_draw_arrays(renderer->cso, mode, start, count);
}
else {
struct pipe_rasterizer_state raster;
@@ -1069,7 +1058,7 @@ void renderer_polygon_stencil(struct renderer *renderer,
cso_set_rasterizer(renderer->cso, &raster);
cso_set_depth_stencil_alpha(renderer->cso, &dsa);
- util_draw_arrays(renderer->pipe, mode, start, count);
+ cso_draw_arrays(renderer->cso, mode, start, count);
/* back */
raster.cull_face = PIPE_FACE_FRONT;
@@ -1077,7 +1066,7 @@ void renderer_polygon_stencil(struct renderer *renderer,
cso_set_rasterizer(renderer->cso, &raster);
cso_set_depth_stencil_alpha(renderer->cso, &dsa);
- util_draw_arrays(renderer->pipe, mode, start, count);
+ cso_draw_arrays(renderer->cso, mode, start, count);
}
}
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index 7052f396c3a..217887ec1ae 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -71,40 +71,19 @@ map_point(float *mat, float x, float y, float *out_x, float *out_y)
}
}
-static INLINE struct pipe_resource *
-renderer_buffer_create(struct xa_context *r)
-{
- struct pipe_resource *buf = pipe_user_buffer_create(r->pipe->screen,
- r->buffer,
- sizeof(float) *
- r->buffer_size,
- PIPE_BIND_VERTEX_BUFFER);
-
- r->buffer_size = 0;
-
- return buf;
-}
-
static INLINE void
renderer_draw(struct xa_context *r)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
int num_verts = r->buffer_size / (r->attrs_per_vertex * NUM_COMPONENTS);
if (!r->buffer_size)
return;
- buf = renderer_buffer_create(r);
-
- if (buf) {
- cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
-
- util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, num_verts, /* verts */
- r->attrs_per_vertex); /* attribs/vert */
-
- pipe_resource_reference(&buf, NULL);
- }
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+ util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
+ num_verts, /* verts */
+ r->attrs_per_vertex); /* attribs/vert */
+ r->buffer_size = 0;
}
static INLINE void
@@ -304,7 +283,7 @@ add_vertex_data2(struct xa_context *r,
src_s0, src_t1, mask_s0, mask_t1);
}
-static struct pipe_resource *
+static void
setup_vertex_data_yuv(struct xa_context *r,
float srcX,
float srcY,
@@ -337,8 +316,6 @@ setup_vertex_data_yuv(struct xa_context *r,
add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1);
/* 4th vertex */
add_vertex_1tex(r, dstX, dstY + dstH, s0, t1);
-
- return renderer_buffer_create(r);
}
/* Set up framebuffer, viewport and vertex shader constant buffer
@@ -408,7 +385,7 @@ renderer_set_constants(struct xa_context *r,
if (*cbuf) {
pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params);
}
- r->pipe->set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
+ pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
}
void
@@ -530,23 +507,17 @@ renderer_draw_yuv(struct xa_context *r,
int dst_x,
int dst_y, int dst_w, int dst_h, struct xa_surface *srf[])
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
+ const int num_attribs = 2; /*pos + tex coord */
- buf = setup_vertex_data_yuv(r,
- src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w,
- dst_h, srf);
+ setup_vertex_data_yuv(r,
+ src_x, src_y, src_w, src_h,
+ dst_x, dst_y, dst_w, dst_h, srf);
- if (buf) {
- const int num_attribs = 2; /*pos + tex coord */
-
- cso_set_vertex_elements(r->cso, num_attribs, r->velems);
-
- util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, 4, /* verts */
- num_attribs); /* attribs/vert */
-
- pipe_resource_reference(&buf, NULL);
- }
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+ util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
+ 4, /* verts */
+ num_attribs); /* attribs/vert */
+ r->buffer_size = 0;
}
void
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 22e61cf7081..6a78abebcb1 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -55,7 +55,7 @@
#include "util/u_rect.h"
#ifdef HAVE_LIBKMS
-#include "libkms.h"
+#include "libkms/libkms.h"
#endif
struct crtc_private
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 0ade319cdc3..eb9d7f075ef 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -59,7 +59,7 @@
#include "xorg_winsys.h"
#ifdef HAVE_LIBKMS
-#include "libkms.h"
+#include "libkms/libkms.h"
#endif
/*
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index eba72d81908..ca25b0912f1 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -42,44 +42,19 @@ static INLINE void map_point(float *mat, float x, float y,
}
}
-static INLINE struct pipe_resource *
-renderer_buffer_create(struct xorg_renderer *r)
-{
- struct pipe_resource *buf =
- pipe_user_buffer_create(r->pipe->screen,
- r->buffer,
- sizeof(float)*
- r->buffer_size,
-/* XXX was: PIPE_BUFFER_USAGE_PIXEL/PIPE_BUFFER_USAGE_GPU_WRITE even though this is a vertex buffer??? */
- PIPE_BIND_VERTEX_BUFFER);
- r->buffer_size = 0;
-
- return buf;
-}
-
static INLINE void
renderer_draw(struct xorg_renderer *r)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
int num_verts = r->buffer_size/(r->attrs_per_vertex * NUM_COMPONENTS);
if (!r->buffer_size)
return;
- buf = renderer_buffer_create(r);
-
-
- if (buf) {
- cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+ util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
+ num_verts, r->attrs_per_vertex);
- util_draw_vertex_buffer(pipe, r->cso, buf, 0,
- PIPE_PRIM_QUADS,
- num_verts, /* verts */
- r->attrs_per_vertex); /* attribs/vert */
-
- pipe_resource_reference(&buf, NULL);
- }
+ r->buffer_size = 0;
}
static INLINE void
@@ -287,7 +262,7 @@ add_vertex_data2(struct xorg_renderer *r,
src_s0, src_t1, mask_s0, mask_t1);
}
-static struct pipe_resource *
+static void
setup_vertex_data_yuv(struct xorg_renderer *r,
float srcX, float srcY, float srcW, float srcH,
float dstX, float dstY, float dstW, float dstH,
@@ -317,8 +292,6 @@ setup_vertex_data_yuv(struct xorg_renderer *r,
/* 4th vertex */
add_vertex_1tex(r, dstX, dstY + dstH,
s0, t1);
-
- return renderer_buffer_create(r);
}
@@ -437,7 +410,7 @@ void renderer_set_constants(struct xorg_renderer *r,
pipe_buffer_write(r->pipe, *cbuf,
0, param_bytes, params);
}
- r->pipe->set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
+ pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
}
@@ -592,34 +565,26 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
add_vertex_1tex(r, x0, y1, s0, t1);
}
-
-
-
void renderer_draw_yuv(struct xorg_renderer *r,
float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_resource **textures)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf = 0;
-
- buf = setup_vertex_data_yuv(r,
- src_x, src_y, src_w, src_h,
- dst_x, dst_y, dst_w, dst_h,
- textures);
+ const int num_attribs = 2; /*pos + tex coord*/
- if (buf) {
- const int num_attribs = 2; /*pos + tex coord*/
+ setup_vertex_data_yuv(r,
+ src_x, src_y, src_w, src_h,
+ dst_x, dst_y, dst_w, dst_h,
+ textures);
- cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
- util_draw_vertex_buffer(pipe, r->cso, buf, 0,
- PIPE_PRIM_QUADS,
- 4, /* verts */
- num_attribs); /* attribs/vert */
+ util_draw_user_vertex_buffer(r->cso, r->buffer,
+ PIPE_PRIM_QUADS,
+ 4, /* verts */
+ num_attribs); /* attribs/vert */
- pipe_resource_reference(&buf, NULL);
- }
+ r->buffer_size = 0;
}
void renderer_begin_solid(struct xorg_renderer *r)
diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c
index f8b2a0a77a0..b42a86cfc8e 100644
--- a/src/gallium/tests/graw/fs-test.c
+++ b/src/gallium/tests/graw/fs-test.c
@@ -148,7 +148,7 @@ static void init_fs_constbuf( void )
sizeof constants1);
- ctx->set_constant_buffer(ctx,
+ pipe_set_constant_buffer(ctx,
PIPE_SHADER_FRAGMENT, 0,
constbuf1);
}
@@ -165,7 +165,7 @@ static void init_fs_constbuf( void )
sizeof constants2);
- ctx->set_constant_buffer(ctx,
+ pipe_set_constant_buffer(ctx,
PIPE_SHADER_FRAGMENT, 1,
constbuf2);
}
diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c
index ef2440291fc..a471abd9a3d 100644
--- a/src/gallium/tests/graw/gs-test.c
+++ b/src/gallium/tests/graw/gs-test.c
@@ -181,7 +181,7 @@ static void init_fs_constbuf( void )
sizeof constants1);
- ctx->set_constant_buffer(ctx,
+ pipe_set_constant_buffer(ctx,
PIPE_SHADER_GEOMETRY, 0,
constbuf1);
}
@@ -198,7 +198,7 @@ static void init_fs_constbuf( void )
sizeof constants2);
- ctx->set_constant_buffer(ctx,
+ pipe_set_constant_buffer(ctx,
PIPE_SHADER_GEOMETRY, 1,
constbuf2);
}
diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c
index 83d86fbf5b2..23b7ada98ad 100644
--- a/src/gallium/tests/graw/vs-test.c
+++ b/src/gallium/tests/graw/vs-test.c
@@ -110,7 +110,7 @@ static void init_fs_constbuf( void )
sizeof constants);
- ctx->set_constant_buffer(ctx,
+ pipe_set_constant_buffer(ctx,
PIPE_SHADER_FRAGMENT, 0,
constbuf);
}
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 05667a74305..fd9228583d2 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -38,6 +38,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
+#include "util/u_upload_mgr.h"
#include "st_debug.h"
#include "st_context.h"
@@ -55,15 +56,13 @@ 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);
/* update constants */
if (params && params->NumParameters) {
- struct pipe_resource *cbuf;
+ struct pipe_constant_buffer cb;
const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
/* Update the constants which come from fixed-function state, such as
@@ -77,20 +76,28 @@ void st_upload_constants( struct st_context *st,
* avoid gratuitous rendering synchronization.
* Let's use a user buffer to avoid an unnecessary copy.
*/
- cbuf = pipe_user_buffer_create(pipe->screen,
- params->ParameterValues,
- paramBytes,
- PIPE_BIND_CONSTANT_BUFFER);
+ 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);
+ u_upload_unmap(st->constbuf_uploader);
+ } else {
+ cb.buffer = NULL;
+ cb.user_buffer = params->ParameterValues;
+ cb.buffer_offset = 0;
+ }
+ cb.buffer_size = paramBytes;
if (ST_DEBUG & DEBUG_CONSTANTS) {
- debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
+ debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
__FUNCTION__, shader_type, params->NumParameters,
params->StateFlags);
_mesa_print_parameter_list(params);
}
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
- pipe_resource_reference(&cbuf, NULL);
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
st->state.constants[shader_type].ptr = params->ParameterValues;
st->state.constants[shader_type].size = paramBytes;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index ce7dbb3f39a..b4497652539 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -65,7 +65,6 @@
#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
-#include "util/u_vbuf.h"
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
@@ -112,32 +111,12 @@ st_get_msaa(void)
}
-static void st_init_vbuf(struct st_context *st)
-{
- struct u_vbuf_caps caps;
-
- u_vbuf_get_caps(st->pipe->screen, &caps);
-
- /* Create u_vbuf if there is anything unsupported. */
- if (!caps.buffer_offset_unaligned ||
- !caps.buffer_stride_unaligned ||
- !caps.velem_src_offset_unaligned ||
- !caps.format_fixed32 ||
- !caps.format_float16 ||
- !caps.format_float64 ||
- !caps.format_norm32 ||
- !caps.format_scaled32 ||
- !caps.user_vertex_buffers) {
- /* XXX user vertex buffers are always uploaded regardless of the CAP. */
- st->vbuf = u_vbuf_create(st->pipe, &caps);
- cso_install_vbuf(st->cso_context, st->vbuf);
- }
-}
static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
{
+ struct pipe_screen *screen = pipe->screen;
uint i;
struct st_context *st = ST_CALLOC_STRUCT( st_context );
@@ -156,9 +135,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->dirty.st = ~0;
st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
+ st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4,
+ PIPE_BIND_INDEX_BUFFER);
+ }
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) {
+ unsigned alignment =
+ screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT);
+
+ st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment,
+ PIPE_BIND_CONSTANT_BUFFER);
+ }
+
st->cso_context = cso_create_context(pipe);
- st_init_vbuf(st);
st_init_atoms( st );
st_init_bitmap(st);
st_init_clear(st);
@@ -254,11 +246,6 @@ static void st_destroy_context_priv( struct st_context *st )
st_destroy_drawpix(st);
st_destroy_drawtex(st);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
-
for (i = 0; i < Elements(st->state.sampler_views); i++) {
pipe_sampler_view_reference(&st->state.sampler_views[i], NULL);
}
@@ -269,6 +256,12 @@ static void st_destroy_context_priv( struct st_context *st )
}
u_upload_destroy(st->uploader);
+ if (st->indexbuf_uploader) {
+ u_upload_destroy(st->indexbuf_uploader);
+ }
+ if (st->constbuf_uploader) {
+ u_upload_destroy(st->constbuf_uploader);
+ }
free( st );
}
@@ -276,7 +269,6 @@ static void st_destroy_context_priv( struct st_context *st )
void st_destroy_context( struct st_context *st )
{
struct pipe_context *pipe = st->pipe;
- struct u_vbuf *vbuf = st->vbuf;
struct cso_context *cso = st->cso_context;
struct gl_context *ctx = st->ctx;
GLuint i;
@@ -312,9 +304,6 @@ void st_destroy_context( struct st_context *st )
st_destroy_context_priv(st);
st = NULL;
- if (vbuf)
- u_vbuf_destroy(vbuf);
-
cso_destroy_context(cso);
pipe->destroy( pipe );
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 4786ed22fe9..00a405b69f9 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -41,7 +41,6 @@ struct gen_mipmap_state;
struct st_context;
struct st_fragment_program;
struct u_upload_mgr;
-struct u_vbuf;
#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */
@@ -74,8 +73,7 @@ struct st_context
struct pipe_context *pipe;
- struct u_upload_mgr *uploader;
- struct u_vbuf *vbuf;
+ struct u_upload_mgr *uploader, *indexbuf_uploader, *constbuf_uploader;
struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
@@ -191,18 +189,6 @@ struct st_context
int force_msaa;
void *winsys_drawable_handle;
- /* User vertex buffers. */
- struct {
- struct pipe_resource *buffer;
-
- /** Element size */
- GLuint element_size;
-
- /** Attribute stride */
- GLsizei stride;
- } user_attrib[PIPE_MAX_ATTRIBS];
- unsigned num_user_attribs;
-
/* Active render condition. */
struct pipe_query *render_condition;
unsigned condition_mode;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 42dc3757615..a8c20f45acd 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -61,6 +61,7 @@
#include "util/u_format.h"
#include "util/u_prim.h"
#include "util/u_draw_quad.h"
+#include "util/u_upload_mgr.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_context.h"
@@ -402,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer *vbuffer,
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
const GLubyte *low_addr = NULL;
GLboolean usingVBO; /* all arrays in a VBO? */
struct gl_buffer_object *bufobj;
- GLuint user_buffer_size = 0;
- GLuint vertex_size = 0; /* bytes per vertex, in bytes */
GLsizei stride;
/* Find the lowest address of the arrays we're drawing,
@@ -464,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx,
array->Normalized,
array->Integer);
assert(velements[attr].src_format);
-
- if (!usingVBO) {
- /* how many bytes referenced by this attribute array? */
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
- uint bytes = src_offset + stride * last_index + element_size;
-
- user_buffer_size = MAX2(user_buffer_size, bytes);
-
- /* update vertex size */
- vertex_size = MAX2(vertex_size, src_offset + element_size);
- }
}
/*
@@ -484,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx,
if (vpv->num_inputs == 0) {
/* just defensive coding here */
vbuffer->buffer = NULL;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = 0;
vbuffer->stride = 0;
- st->num_user_attribs = 0;
}
else if (usingVBO) {
/* all interleaved arrays in a VBO */
@@ -497,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer->buffer = NULL;
- pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer = stobj->buffer;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = pointer_to_offset(low_addr);
vbuffer->stride = stride;
- st->num_user_attribs = 0;
}
else {
/* all interleaved arrays in user memory */
- vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
- (void*) low_addr,
- user_buffer_size,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer->buffer = NULL;
+ vbuffer->user_buffer = low_addr;
vbuffer->buffer_offset = 0;
vbuffer->stride = stride;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
- st->user_attrib[0].element_size = vertex_size;
- st->user_attrib[0].stride = stride;
- st->num_user_attribs = 1;
}
return GL_TRUE;
@@ -536,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer vbuffer[],
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
struct gl_buffer_object *bufobj = array->BufferObj;
- GLuint element_size = array->_ElementSize;
GLsizei stride = array->StrideB;
- assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+ assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type));
if (_mesa_is_bufferobj(bufobj)) {
/* Attribute data is in a VBO.
@@ -565,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer[attr].buffer = NULL;
- pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer);
+ vbuffer[attr].buffer = stobj->buffer;
+ vbuffer[attr].user_buffer = NULL;
vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr);
}
else {
/* wrap user data */
- uint bytes;
void *ptr;
if (array->Ptr) {
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
-
- bytes = stride * last_index + element_size;
-
ptr = (void *) array->Ptr;
}
else {
/* no array, use ctx->Current.Attrib[] value */
- bytes = element_size = sizeof(ctx->Current.Attrib[0]);
ptr = (void *) ctx->Current.Attrib[mesaAttr];
stride = 0;
}
assert(ptr);
- assert(bytes);
-
- vbuffer[attr].buffer =
- pipe_user_buffer_create(pipe->screen, ptr, bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer[attr].buffer = NULL;
+ vbuffer[attr].user_buffer = ptr;
vbuffer[attr].buffer_offset = 0;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer);
- st->user_attrib[attr].element_size = element_size;
- st->user_attrib[attr].stride = stride;
- st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1);
-
- if (!vbuffer[attr].buffer) {
- /* probably ran out of memory */
- return GL_FALSE;
- }
}
/* common-case setup */
@@ -629,34 +577,31 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
static void
-setup_index_buffer(struct gl_context *ctx,
+setup_index_buffer(struct st_context *st,
const struct _mesa_index_buffer *ib,
struct pipe_index_buffer *ibuffer)
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
+ struct gl_buffer_object *bufobj = ib->obj;
- memset(ibuffer, 0, sizeof(*ibuffer));
- if (ib) {
- struct gl_buffer_object *bufobj = ib->obj;
-
- ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
+ ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
- /* get/create the index buffer object */
- if (_mesa_is_bufferobj(bufobj)) {
- /* elements/indexes are in a real VBO */
- struct st_buffer_object *stobj = st_buffer_object(bufobj);
- pipe_resource_reference(&ibuffer->buffer, stobj->buffer);
- ibuffer->offset = pointer_to_offset(ib->ptr);
- }
- else {
- /* element/indicies are in user space memory */
- ibuffer->buffer =
- pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
- ib->count * ibuffer->index_size,
- PIPE_BIND_INDEX_BUFFER);
- }
+ /* get/create the index buffer object */
+ if (_mesa_is_bufferobj(bufobj)) {
+ /* indices are in a real VBO */
+ ibuffer->buffer = st_buffer_object(bufobj)->buffer;
+ ibuffer->offset = pointer_to_offset(ib->ptr);
}
+ else if (st->indexbuf_uploader) {
+ u_upload_data(st->indexbuf_uploader, 0, ib->count * ibuffer->index_size,
+ ib->ptr, &ibuffer->offset, &ibuffer->buffer);
+ u_upload_unmap(st->indexbuf_uploader);
+ }
+ else {
+ /* indices are in user space memory */
+ ibuffer->user_buffer = ib->ptr;
+ }
+
+ cso_set_index_buffer(st->cso_context, ibuffer);
}
@@ -811,10 +756,10 @@ handle_fallback_primitive_restart(struct cso_context *cso,
unsigned num_sub_prims;
assert(info.indexed);
- assert(ibuffer->buffer);
+ assert(ibuffer->buffer || ibuffer->user_buffer);
assert(ib);
- if (!ibuffer->buffer || !ib)
+ if (!ibuffer->buffer || !ibuffer->user_buffer || !ib)
return;
info.primitive_restart = FALSE;
@@ -894,9 +839,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
*/
static GLboolean
st_validate_varrays(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- unsigned max_index,
- unsigned num_instances)
+ const struct gl_client_array **arrays)
{
struct st_context *st = st_context(ctx);
const struct st_vertex_program *vp;
@@ -904,8 +847,6 @@ st_validate_varrays(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
unsigned num_vbuffers, num_velements;
- GLuint attr;
- unsigned i;
/* must get these after state validation! */
vp = st->vp;
@@ -913,18 +854,12 @@ st_validate_varrays(struct gl_context *ctx,
memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
- st->num_user_attribs = 0;
-
/*
* Setup the vbuffer[] and velements[] arrays.
*/
if (is_interleaved_arrays(vp, vpv, arrays)) {
- if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
- max_index, num_instances)) {
+ if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer,
+ velements)) {
return GL_FALSE;
}
@@ -935,8 +870,7 @@ st_validate_varrays(struct gl_context *ctx,
}
else {
if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
- vbuffer, velements, max_index,
- num_instances)) {
+ vbuffer, velements)) {
return GL_FALSE;
}
@@ -947,14 +881,6 @@ st_validate_varrays(struct gl_context *ctx,
cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer);
cso_set_vertex_elements(st->cso_context, num_velements, velements);
- /* unreference buffers (frees wrapped user-space buffer objects)
- * This is OK, because the pipe driver should reference buffers by itself
- * in set_vertex_buffers. */
- for (attr = 0; attr < num_vbuffers; attr++) {
- pipe_resource_reference(&vbuffer[attr].buffer, NULL);
- assert(!vbuffer[attr].buffer);
- }
-
return GL_TRUE;
}
@@ -976,11 +902,10 @@ st_draw_vbo(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_index_buffer ibuffer;
+ struct pipe_index_buffer ibuffer = {0};
struct pipe_draw_info info;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
- unsigned i, num_instances = 1;
- unsigned max_index_plus_base;
+ unsigned i;
GLboolean new_array;
/* Mesa core state should have been validated already */
@@ -994,43 +919,6 @@ st_draw_vbo(struct gl_context *ctx,
(st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) ||
(st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
- if (ib) {
- int max_base_vertex = 0;
-
- /* Gallium probably doesn't want this in some cases. */
- if (!index_bounds_valid)
- if (!all_varyings_in_vbos(arrays))
- vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
- nr_prims);
-
- for (i = 0; i < nr_prims; i++) {
- num_instances = MAX2(num_instances, prims[i].num_instances);
- max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex);
- }
-
- /* Compute the sum of max_index and max_base_vertex. That's the value
- * we need to use when creating buffers.
- */
- if (max_index == ~0)
- max_index_plus_base = max_index;
- else
- max_index_plus_base = max_index + max_base_vertex;
- }
- else {
- /* Get min/max index for non-indexed drawing. */
- min_index = ~0;
- max_index = 0;
-
- for (i = 0; i < nr_prims; i++) {
- min_index = MIN2(min_index, prims[i].start);
- max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
- num_instances = MAX2(num_instances, prims[i].num_instances);
- }
-
- /* The base vertex offset only applies to indexed drawing */
- max_index_plus_base = max_index;
- }
-
/* Validate state. */
if (st->dirty.st) {
GLboolean vertDataEdgeFlags;
@@ -1045,8 +933,7 @@ st_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (new_array) {
- if (!st_validate_varrays(ctx, arrays, max_index_plus_base,
- num_instances)) {
+ if (!st_validate_varrays(ctx, arrays)) {
/* probably out of memory, no-op the draw call */
return;
}
@@ -1061,31 +948,16 @@ st_draw_vbo(struct gl_context *ctx,
#endif
}
- /* Notify the driver that the content of user buffers may have been
- * changed. */
- assert(max_index >= min_index);
- if (!new_array && st->num_user_attribs) {
- for (i = 0; i < st->num_user_attribs; i++) {
- if (st->user_attrib[i].buffer) {
- unsigned element_size = st->user_attrib[i].element_size;
- unsigned stride = st->user_attrib[i].stride;
- unsigned min_offset = min_index * stride;
- unsigned max_offset = max_index_plus_base * stride + element_size;
-
- assert(max_offset > min_offset);
-
- pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer,
- min_offset,
- max_offset - min_offset);
- }
- }
- }
-
- setup_index_buffer(ctx, ib, &ibuffer);
- cso_set_index_buffer(st->cso_context, &ibuffer);
-
util_draw_init_info(&info);
if (ib) {
+ /* Get index bounds for user buffers. */
+ if (!index_bounds_valid)
+ if (!all_varyings_in_vbos(arrays))
+ vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
+ nr_prims);
+
+ setup_index_buffer(st, ib, &ibuffer);
+
info.indexed = TRUE;
if (min_index != ~0 && max_index != ~0) {
info.min_index = min_index;
@@ -1098,10 +970,12 @@ st_draw_vbo(struct gl_context *ctx,
info.primitive_restart = ctx->Array.PrimitiveRestart;
info.restart_index = ctx->Array.RestartIndex;
}
-
- /* Set info.count_from_stream_output. */
- if (tfb_vertcount) {
- st_transform_feedback_draw_init(tfb_vertcount, &info);
+ else {
+ /* Transform feedback drawing is always non-indexed. */
+ /* Set info.count_from_stream_output. */
+ if (tfb_vertcount) {
+ st_transform_feedback_draw_init(tfb_vertcount, &info);
+ }
}
/* do actual drawing */
@@ -1134,7 +1008,9 @@ st_draw_vbo(struct gl_context *ctx,
cso_draw_vbo(st->cso_context, &info);
}
- pipe_resource_reference(&ibuffer.buffer, NULL);
+ if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
+ pipe_resource_reference(&ibuffer.buffer, NULL);
+ }
}
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 257618aa992..4209fb214f8 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -107,7 +107,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer ibuffer;
- struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *ib_transfer = NULL;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
GLuint attr, i;
@@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx,
assert(stobj->buffer);
vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = NULL;
pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer);
vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
+
+ /* map the attrib buffer */
+ map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
+ PIPE_TRANSFER_READ,
+ &vb_transfer[attr]);
+ draw_set_mapped_vertex_buffer(draw, attr, map);
}
else {
- /* attribute data is in user-space memory, not a VBO */
- uint bytes = (arrays[mesaAttr]->Size
- * _mesa_sizeof_type(arrays[mesaAttr]->Type)
- * (max_index + 1));
-
- /* wrap user data */
- vbuffers[attr].buffer
- = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr,
- bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr;
vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0;
+
+ draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer);
}
/* common-case setup */
@@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx,
#if 0
draw_set_vertex_buffer(draw, attr, &vbuffer[attr]);
#endif
-
- /* map the attrib buffer */
- map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
- PIPE_TRANSFER_READ,
- &vb_transfer[attr]);
- draw_set_mapped_vertex_buffer(draw, attr, map);
}
draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
@@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
out_unref_vertex:
for (attr = 0; attr < vp->num_inputs; attr++) {
- pipe_buffer_unmap(pipe, vb_transfer[attr]);
+ if (vb_transfer[attr])
+ pipe_buffer_unmap(pipe, vb_transfer[attr]);
draw_set_mapped_vertex_buffer(draw, attr, NULL);
pipe_resource_reference(&vbuffers[attr].buffer, NULL);
}