summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-03-01 01:14:12 +0100
committerChristian König <[email protected]>2011-03-01 21:42:16 +0100
commit4c4ab5668cd6df573db7b065f0493fb80ac70ab8 (patch)
tree40a32e030042e5f2166767c2db74229f51f5c774 /src/mesa
parent583eb139480fb1265b5106a09dcec8ce42d1124d (diff)
st/mesa: probably handle instanced drawing
Remove the previous workaround for instanced drawing and implement it correctly.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_draw.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index c99eafbadf3..d6e67b7fb85 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -307,7 +307,8 @@ setup_interleaved_attribs(struct gl_context *ctx,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer *vbuffer,
struct pipe_vertex_element velements[],
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -336,9 +337,11 @@ setup_interleaved_attribs(struct gl_context *ctx,
pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
vbuffer->buffer_offset = pointer_to_offset(low_addr);
} else {
+ uint divisor = arrays[mesaAttr]->InstanceDivisor;
+ uint length = (divisor ? num_instances / divisor : max_index) + 1;
vbuffer->buffer =
pipe_user_buffer_create(pipe->screen, (void*)low_addr,
- stride * (max_index + 1),
+ stride * length,
PIPE_BIND_VERTEX_BUFFER);
vbuffer->buffer_offset = 0;
@@ -377,7 +380,8 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer vbuffer[],
struct pipe_vertex_element velements[],
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -403,16 +407,18 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
else {
/* wrap user data */
if (arrays[mesaAttr]->Ptr) {
- vbuffer[attr].buffer =
+ uint divisor = arrays[mesaAttr]->InstanceDivisor;
+ uint length = (divisor ? num_instances / divisor : max_index) + 1;
+ vbuffer[attr].buffer =
pipe_user_buffer_create(pipe->screen,
(void *) arrays[mesaAttr]->Ptr,
- stride * (max_index + 1),
+ stride * length,
PIPE_BIND_VERTEX_BUFFER);
}
else {
/* no array, use ctx->Current.Attrib[] value */
uint bytes = sizeof(ctx->Current.Attrib[0]);
- vbuffer[attr].buffer =
+ vbuffer[attr].buffer =
pipe_user_buffer_create(pipe->screen,
(void *) ctx->Current.Attrib[mesaAttr],
bytes,
@@ -550,7 +556,8 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
static void
st_validate_varrays(struct gl_context *ctx,
const struct gl_client_array **arrays,
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
const struct st_vertex_program *vp;
@@ -578,7 +585,7 @@ st_validate_varrays(struct gl_context *ctx,
*/
if (is_interleaved_arrays(vp, vpv, arrays)) {
setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
- max_index);
+ max_index, num_instances);
num_vbuffers = 1;
num_velements = vpv->num_inputs;
@@ -587,7 +594,7 @@ st_validate_varrays(struct gl_context *ctx,
}
else {
setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
- vbuffer, velements, max_index);
+ vbuffer, velements, max_index, num_instances);
num_vbuffers = vpv->num_inputs;
num_velements = vpv->num_inputs;
}
@@ -624,7 +631,7 @@ st_draw_vbo(struct gl_context *ctx,
struct pipe_context *pipe = st->pipe;
struct pipe_index_buffer ibuffer;
struct pipe_draw_info info;
- unsigned i;
+ unsigned i, num_instances = 1;
GLboolean new_array = GL_TRUE;
/* Fix this (Bug 34378):
GLboolean new_array =
@@ -638,6 +645,10 @@ st_draw_vbo(struct gl_context *ctx,
if (!index_bounds_valid)
if (!vbo_all_varyings_in_vbos(arrays))
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
+ for (i = 0; i < nr_prims; i++) {
+ num_instances = MAX2(num_instances, prims[i].num_instances);
+ }
} else {
/* Get min/max index for non-indexed drawing. */
min_index = ~0;
@@ -646,7 +657,7 @@ st_draw_vbo(struct gl_context *ctx,
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);
- max_index = MAX2(max_index, prims[i].num_instances);
+ num_instances = MAX2(num_instances, prims[i].num_instances);
}
}
@@ -667,7 +678,7 @@ st_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (new_array) {
- st_validate_varrays(ctx, arrays, max_index);
+ st_validate_varrays(ctx, arrays, max_index, num_instances);
}
#if 0