diff options
-rw-r--r-- | src/mesa/state_tracker/st_atom.h | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_array.c | 30 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw_feedback.c | 93 |
3 files changed, 68 insertions, 62 deletions
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index 901e9b6d439..d36f0180faf 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -75,6 +75,13 @@ st_setup_current(struct st_context *st, struct pipe_vertex_element *velements, struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers); +void +st_setup_current_user(struct st_context *st, + const struct st_vertex_program *vp, + const struct st_vp_variant *vp_variant, + struct pipe_vertex_element *velements, + struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers); + /* Define ST_NEW_xxx_INDEX */ enum { #define ST_STATE(FLAG, st_update) FLAG##_INDEX, diff --git a/src/mesa/state_tracker/st_atom_array.c b/src/mesa/state_tracker/st_atom_array.c index ac9bd727dfc..1073e76c3e4 100644 --- a/src/mesa/state_tracker/st_atom_array.c +++ b/src/mesa/state_tracker/st_atom_array.c @@ -511,6 +511,36 @@ st_setup_current(struct st_context *st, } void +st_setup_current_user(struct st_context *st, + const struct st_vertex_program *vp, + const struct st_vp_variant *vp_variant, + struct pipe_vertex_element *velements, + struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers) +{ + struct gl_context *ctx = st->ctx; + const GLbitfield inputs_read = vp_variant->vert_attrib_mask; + const ubyte *input_to_index = vp->input_to_index; + + /* Process values that should have better been uniforms in the application */ + GLbitfield curmask = inputs_read & _mesa_draw_current_bits(ctx); + /* For each attribute, make an own user buffer binding. */ + while (curmask) { + const gl_vert_attrib attr = u_bit_scan(&curmask); + const struct gl_array_attributes *const attrib + = _mesa_draw_current_attrib(ctx, attr); + const unsigned bufidx = (*num_vbuffers)++; + + init_velement_lowered(vp, velements, &attrib->Format, 0, 0, + bufidx, input_to_index[attr]); + + vbuffer[bufidx].is_user_buffer = true; + vbuffer[bufidx].buffer.user = attrib->Ptr; + vbuffer[bufidx].buffer_offset = 0; + vbuffer[bufidx].stride = 0; + } +} + +void st_update_array(struct st_context *st) { /* vertex program validation must be done before this */ diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 82f2feb86e3..6ec6d5c16f4 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -127,12 +127,14 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_context *pipe = st->pipe; struct draw_context *draw = st_get_draw_context(st); const struct st_vertex_program *vp; + struct st_vp_variant *vp_variant; const struct pipe_shader_state *vs; struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; + unsigned num_vbuffers = 0; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *ib_transfer = NULL; - GLuint attr, i; + GLuint i; const void *mapped_indices = NULL; if (!draw) @@ -148,10 +150,11 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* must get these after state validation! */ vp = st->vp; - vs = &st->vp_variant->tgsi; + vp_variant = st->vp_variant; + vs = &vp_variant->tgsi; - if (!st->vp_variant->draw_shader) { - st->vp_variant->draw_shader = draw_create_vertex_shader(draw, vs); + if (!vp_variant->draw_shader) { + vp_variant->draw_shader = draw_create_vertex_shader(draw, vs); } /* @@ -164,64 +167,30 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_set_viewport_states(draw, 0, 1, &st->state.viewport[0]); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); - draw_bind_vertex_shader(draw, st->vp_variant->draw_shader); + draw_bind_vertex_shader(draw, vp_variant->draw_shader); set_feedback_vertex_format(ctx); - /* loop over TGSI shader inputs to determine vertex buffer - * and attribute info - */ - for (attr = 0; attr < vp->num_inputs; attr++) { - const GLuint mesaAttr = vp->index_to_input[attr]; - const struct gl_vertex_buffer_binding *binding; - const struct gl_array_attributes *attrib; - void *map; - - _mesa_draw_attrib_and_binding(ctx, mesaAttr, &attrib, &binding); - - if (_mesa_is_bufferobj(binding->BufferObj)) { - /* Attribute data is in a VBO. */ - struct st_buffer_object *stobj = st_buffer_object(binding->BufferObj); - assert(stobj->buffer); - - vbuffers[attr].buffer.resource = NULL; - vbuffers[attr].is_user_buffer = false; - vbuffers[attr].buffer.resource = stobj->buffer; - vbuffers[attr].buffer_offset = _mesa_draw_binding_offset(binding); - velements[attr].src_offset = - _mesa_draw_attributes_relative_offset(attrib); - - /* map the attrib buffer */ - map = pipe_buffer_map(pipe, vbuffers[attr].buffer.resource, - PIPE_TRANSFER_READ, - &vb_transfer[attr]); - draw_set_mapped_vertex_buffer(draw, attr, map, - vbuffers[attr].buffer.resource->width0); - } - else { - /* Attribute data is in a user space array. */ - vbuffers[attr].buffer.user = attrib->Ptr; - vbuffers[attr].is_user_buffer = true; - vbuffers[attr].buffer_offset = 0; - velements[attr].src_offset = 0; - - draw_set_mapped_vertex_buffer(draw, attr, - vbuffers[attr].buffer.user, ~0); + /* Must setup these after state validation! */ + /* Setup arrays */ + st_setup_arrays(st, vp, vp_variant, velements, vbuffers, &num_vbuffers); + /* Setup current values as userspace arrays */ + st_setup_current_user(st, vp, vp_variant, velements, vbuffers, &num_vbuffers); + + /* Map all buffers and tell draw about their mapping */ + for (unsigned buf = 0; buf < num_vbuffers; ++buf) { + struct pipe_vertex_buffer *vbuffer = &vbuffers[buf]; + + if (vbuffer->is_user_buffer) { + draw_set_mapped_vertex_buffer(draw, buf, vbuffer->buffer.user, ~0); + } else { + void *map = pipe_buffer_map(pipe, vbuffer->buffer.resource, + PIPE_TRANSFER_READ, &vb_transfer[buf]); + draw_set_mapped_vertex_buffer(draw, buf, map, + vbuffer->buffer.resource->width0); } - - /* common-case setup */ - vbuffers[attr].stride = binding->Stride; /* in bytes */ - velements[attr].instance_divisor = 0; - velements[attr].vertex_buffer_index = attr; - velements[attr].src_format = st_pipe_vertex_format(&attrib->Format); - assert(velements[attr].src_format); - - /* tell draw about this attribute */ -#if 0 - draw_set_vertex_buffer(draw, attr, &vbuffer[attr]); -#endif } - draw_set_vertex_buffers(draw, 0, vp->num_inputs, vbuffers); + draw_set_vertex_buffers(draw, 0, num_vbuffers, vbuffers); draw_set_vertex_elements(draw, vp->num_inputs, velements); unsigned start = 0; @@ -271,10 +240,10 @@ st_feedback_draw_vbo(struct gl_context *ctx, } out_unref_vertex: - for (attr = 0; attr < vp->num_inputs; attr++) { - if (vb_transfer[attr]) - pipe_buffer_unmap(pipe, vb_transfer[attr]); - draw_set_mapped_vertex_buffer(draw, attr, NULL, 0); + for (unsigned buf = 0; buf < num_vbuffers; ++buf) { + if (vb_transfer[buf]) + pipe_buffer_unmap(pipe, vb_transfer[buf]); + draw_set_mapped_vertex_buffer(draw, buf, NULL, 0); } - draw_set_vertex_buffers(draw, 0, vp->num_inputs, NULL); + draw_set_vertex_buffers(draw, 0, num_vbuffers, NULL); } |