}
}
+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)
{
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)
/* 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);
}
/*
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;
}
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);
}