util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state);
util_blitter_save_fragment_shader(r300->blitter, r300->fs);
util_blitter_save_vertex_shader(r300->blitter, r300->vs);
+ util_blitter_save_vertex_elements(r300->blitter, r300->vs);
}
/* Clear currently bound buffers. */
uint32_t vap_prog_stream_cntl_ext[8];
};
+struct r300_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[];
+};
+
extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
int vertex_buffer_count;
/* Vertex elements for Gallium. */
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- int vertex_element_count;
+ struct r300_velems_state *velems;
struct pipe_stencil_ref stencil_ref;
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
- unsigned size1, size2, aos_count = r300->vertex_element_count;
+ unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
- unsigned vertex_element_count = r300->vertex_element_count;
+ unsigned vertex_element_count = r300->velems->count;
unsigned i, v, vbi, dw, elem_offset;
/* Size of the vertex, in dwords. */
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
offset[i] = velem->src_offset / 4;
size[i] = util_format_get_blocksize(velem->src_format) / 4;
vertex_size += size[i];
/* Emit vertices. */
for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
vbi = velem->vertex_buffer_index;
elem_offset = offset[i] + stride[vbi] * (v + start);
/* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) {
- vbi = r300->vertex_element[i].vertex_buffer_index;
+ vbi = r300->velems->velem[i].vertex_buffer_index;
if (map[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
static boolean r300_setup_vertex_buffers(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
struct pipe_buffer *pbuf;
validate:
- for (int i = 0; i < r300->vertex_element_count; i++) {
+ for (int i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
if (!r300->winsys->add_buffer(r300->winsys, pbuf,
static boolean r300_validate_aos(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
/* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->vertex_element_count; i++) {
+ for (i = 0; i < r300->velems->count; i++) {
if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
return FALSE;
return TRUE;
}
-static void r300_set_vertex_elements(struct pipe_context* pipe,
- unsigned count,
- const struct pipe_vertex_element* elements)
+static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
+ unsigned count,
+ const struct pipe_vertex_element* attribs)
{
- struct r300_context* r300 = r300_context(pipe);
+ /*XXX could precalculate state here instead of later */
+ struct r300_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct r300_velems_state *) MALLOC(sizeof(struct r300_velems_state) + count * sizeof(*attribs));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_velems_state *r300_velems = (struct r300_velems_state *) velems;
- memcpy(r300->vertex_element,
- elements,
- sizeof(struct pipe_vertex_element) * count);
- r300->vertex_element_count = count;
+ r300->velems = r300_velems;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_vertex_elements(r300->draw, count, elements);
+ draw_set_vertex_elements(r300->draw, r300_velems->count, r300_velems->velem);
}
if (!r300_validate_aos(r300)) {
}
}
+static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
+
static void* r300_create_vs_state(struct pipe_context* pipe,
const struct pipe_shader_state* shader)
{
r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
- r300->context.set_vertex_elements = r300_set_vertex_elements;
+
+ r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
+ r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
+ r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;
r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state;
DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
" in psc\n",
r300->vs->info.num_inputs,
- r300->vertex_element_count);
+ r300->velems->count);
- for (i = 0; i < r300->vertex_element_count; i++) {
- format = r300->vertex_element[i].src_format;
+ for (i = 0; i < r300->velems->count; i++) {
+ format = r300->velems->velem[i].src_format;
type = r300_translate_vertex_data_type(format) |
(stream_tab[i] << R300_DST_VEC_LOC_SHIFT);