r600g: Emit vertex buffers using the same method as constant buffers
authorTom Stellard <tstellar@gmail.com>
Thu, 12 Jul 2012 19:50:28 +0000 (19:50 +0000)
committerMarek Olšák <maraeo@gmail.com>
Sun, 15 Jul 2012 00:00:27 +0000 (02:00 +0200)
Signed-off-by: Marek Olšák <maraeo@gmail.com>
src/gallium/drivers/r600/evergreen_compute.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index b61ea8f..947a328 100644 (file)
@@ -90,13 +90,15 @@ static void evergreen_cs_set_vertex_buffer(
        struct pipe_resource * buffer)
 {
        struct pipe_vertex_buffer *vb = &rctx->cs_vertex_buffer[vb_index];
+       struct r600_vertexbuf_state * state = &rctx->cs_vertex_buffer_state;
        vb->stride = 1;
        vb->buffer_offset = offset;
        vb->buffer = buffer;
        vb->user_buffer = NULL;
 
        r600_inval_vertex_cache(rctx);
-       r600_atom_dirty(rctx, &rctx->cs_vertex_buffer_state);
+       state->dirty_mask |= 1 << vb_index;
+       r600_atom_dirty(rctx, &state->atom);
 }
 
 const struct u_resource_vtbl r600_global_buffer_vtbl =
@@ -367,8 +369,8 @@ static void compute_emit_cs(struct r600_context *ctx)
        r600_context_pipe_state_emit(ctx, cb_state, RADEON_CP_PACKET3_COMPUTE_MODE);
 
        /* Emit vertex buffer state */
-       ctx->cs_vertex_buffer_state.num_dw = 12 * ctx->nr_cs_vertex_buffers;
-       r600_emit_atom(ctx, &ctx->cs_vertex_buffer_state);
+       ctx->cs_vertex_buffer_state.atom.num_dw = 12 * ctx->nr_cs_vertex_buffers;
+       r600_emit_atom(ctx, &ctx->cs_vertex_buffer_state.atom);
 
        for (i = 0; i < get_compute_resource_num(); i++) {
                if (ctx->cs_shader->resources[i].enabled) {
index 923dea7..9a64f67 100644 (file)
@@ -1765,32 +1765,39 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_
        r600_write_context_reg(cs, R_02800C_DB_RENDER_OVERRIDE, db_render_override);
 }
 
-static void evergreen_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom,
-       struct pipe_vertex_buffer *vb, unsigned vb_count, unsigned resource_offset,
-       unsigned pkt_flags)
+static void evergreen_emit_vertex_buffers(struct r600_context *rctx,
+                                         struct r600_vertexbuf_state *state,
+                                         struct pipe_vertex_buffer *vertex_buffers,
+                                         unsigned vb_count,
+                                         unsigned resource_offset,
+                                         unsigned pkt_flags)
 {
        struct radeon_winsys_cs *cs = rctx->cs;
-       unsigned i;
-       uint64_t va;
+       uint32_t dirty_mask = state->dirty_mask;
 
-       for (i = 0; i < vb_count; i++) {
-               struct r600_resource *rbuffer = (struct r600_resource*)vb[i].buffer;
+       while (dirty_mask) {
+               struct pipe_vertex_buffer *vb;
+               struct r600_resource *rbuffer;
+               uint64_t va;
+               unsigned buffer_index = ffs(dirty_mask) - 1;
 
+               vb = &vertex_buffers[buffer_index];
+               rbuffer = (struct r600_resource*)vb->buffer;
                if (!rbuffer) {
-                       continue;
+                       goto next;
                }
 
                va = r600_resource_va(&rctx->screen->screen, &rbuffer->b.b);
-               va += vb[i].buffer_offset;
+               va += vb->buffer_offset;
 
                /* fetch resources start at index 992 */
                r600_write_value(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags);
-               r600_write_value(cs, (resource_offset + i) * 8);
+               r600_write_value(cs, (resource_offset + buffer_index) * 8);
                r600_write_value(cs, va); /* RESOURCEi_WORD0 */
-               r600_write_value(cs, rbuffer->buf->size - vb[i].buffer_offset - 1); /* RESOURCEi_WORD1 */
+               r600_write_value(cs, rbuffer->buf->size - vb->buffer_offset - 1); /* RESOURCEi_WORD1 */
                r600_write_value(cs, /* RESOURCEi_WORD2 */
                                 S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
-                                S_030008_STRIDE(vb[i].stride) |
+                                S_030008_STRIDE(vb->stride) |
                                 S_030008_BASE_ADDRESS_HI(va >> 32UL));
                r600_write_value(cs, /* RESOURCEi_WORD3 */
                                 S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
@@ -1804,18 +1811,24 @@ static void evergreen_emit_vertex_buffers(struct r600_context *rctx, struct r600
 
                r600_write_value(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags);
                r600_write_value(cs, r600_context_bo_reloc(rctx, rbuffer, RADEON_USAGE_READ));
+
+next:
+               dirty_mask &= ~(1 << buffer_index);
        }
+       state->dirty_mask = 0;
 }
 
 static void evergreen_fs_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom * atom)
 {
-       evergreen_emit_vertex_buffers(rctx, atom, rctx->vertex_buffer,
+       evergreen_emit_vertex_buffers(rctx, &rctx->vertex_buffer_state,
+                                       rctx->vertex_buffer,
                                        rctx->nr_vertex_buffers, 992, 0);
 }
 
 static void evergreen_cs_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom * atom)
 {
-       evergreen_emit_vertex_buffers(rctx, atom, rctx->cs_vertex_buffer,
+       evergreen_emit_vertex_buffers(rctx, &rctx->cs_vertex_buffer_state,
+                                       rctx->cs_vertex_buffer,
                                        rctx->nr_cs_vertex_buffers, 816,
                                        RADEON_CP_PACKET3_COMPUTE_MODE);
 }
@@ -1895,8 +1908,8 @@ void evergreen_init_state_functions(struct r600_context *rctx)
        r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
        r600_init_atom(&rctx->db_misc_state.atom, evergreen_emit_db_misc_state, 6, 0);
        r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
-       r600_init_atom(&rctx->vertex_buffer_state, evergreen_fs_emit_vertex_buffers, 0, 0);
-       r600_init_atom(&rctx->cs_vertex_buffer_state, evergreen_cs_emit_vertex_buffers, 0, 0);
+       r600_init_atom(&rctx->vertex_buffer_state.atom, evergreen_fs_emit_vertex_buffers, 0, 0);
+       r600_init_atom(&rctx->cs_vertex_buffer_state.atom, evergreen_cs_emit_vertex_buffers, 0, 0);
        r600_init_atom(&rctx->vs_constbuf_state.atom, evergreen_emit_vs_constant_buffers, 0, 0);
        r600_init_atom(&rctx->ps_constbuf_state.atom, evergreen_emit_ps_constant_buffers, 0, 0);
 
index 3d7d1f0..8e2deb1 100644 (file)
@@ -107,8 +107,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
                        /* Vertex buffers. */
                        for (i = 0; i < rctx->nr_vertex_buffers; i++) {
                                if (rctx->vertex_buffer[i].buffer == &rbuffer->b.b) {
+                                       struct r600_vertexbuf_state * state =
+                                               &rctx->vertex_buffer_state;
+                                       state->dirty_mask |= 1 << i;
                                        r600_inval_vertex_cache(rctx);
-                                       r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
+                                       r600_atom_dirty(rctx, &state->atom);
                                }
                        }
                        /* Streamout buffers. */
index b236069..e80f39c 100644 (file)
@@ -1282,7 +1282,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
        /* Re-emit states. */
        r600_atom_dirty(ctx, &ctx->cb_misc_state.atom);
        r600_atom_dirty(ctx, &ctx->db_misc_state.atom);
-       r600_atom_dirty(ctx, &ctx->vertex_buffer_state);
+       r600_atom_dirty(ctx, &ctx->vertex_buffer_state.atom);
 
        ctx->vs_constbuf_state.dirty_mask = ctx->vs_constbuf_state.enabled_mask;
        ctx->ps_constbuf_state.dirty_mask = ctx->ps_constbuf_state.enabled_mask;
index ba63dcc..0581040 100644 (file)
@@ -276,6 +276,12 @@ struct r600_constbuf_state
        uint32_t                        dirty_mask;
 };
 
+struct r600_vertexbuf_state
+{
+       struct r600_atom                atom;
+       uint32_t                        dirty_mask;
+};
+
 struct r600_context {
        struct pipe_context             context;
        struct blitter_context          *blitter;
@@ -337,9 +343,9 @@ struct r600_context {
        struct r600_cb_misc_state       cb_misc_state;
        struct r600_db_misc_state       db_misc_state;
        /** Vertex buffers for fetch shaders */
-       struct r600_atom                vertex_buffer_state;
+       struct r600_vertexbuf_state     vertex_buffer_state;
        /** Vertex buffers for compute shaders */
-       struct r600_atom                cs_vertex_buffer_state;
+       struct r600_vertexbuf_state     cs_vertex_buffer_state;
        struct r600_constbuf_state      vs_constbuf_state;
        struct r600_constbuf_state      ps_constbuf_state;
 
index e7fd133..3d5835c 100644 (file)
@@ -1847,7 +1847,7 @@ void r600_init_state_functions(struct r600_context *rctx)
        r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
        r600_init_atom(&rctx->db_misc_state.atom, r600_emit_db_misc_state, 4, 0);
        r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
-       r600_init_atom(&rctx->vertex_buffer_state, r600_emit_vertex_buffers, 0, 0);
+       r600_init_atom(&rctx->vertex_buffer_state.atom, r600_emit_vertex_buffers, 0, 0);
        r600_init_atom(&rctx->vs_constbuf_state.atom, r600_emit_vs_constant_buffers, 0, 0);
        r600_init_atom(&rctx->ps_constbuf_state.atom, r600_emit_ps_constant_buffers, 0, 0);
 
index d952220..be3d101 100644 (file)
@@ -407,13 +407,18 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
                             const struct pipe_vertex_buffer *buffers)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
+       struct r600_vertexbuf_state * state = &rctx->vertex_buffer_state;
+       unsigned i;
 
        util_copy_vertex_buffers(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, count);
 
        r600_inval_vertex_cache(rctx);
-       rctx->vertex_buffer_state.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
+       state->atom.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
                                           rctx->nr_vertex_buffers;
-       r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
+       for (i = 0 ; i < rctx->nr_vertex_buffers; i++) {
+               state->dirty_mask |= 1 << i;
+       }
+       r600_atom_dirty(rctx, &state->atom);
 }
 
 void *r600_create_vertex_elements(struct pipe_context *ctx,