From c2f444c54db82a53f63fa7a103770ee5eedc3559 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 12 Jul 2012 19:50:28 +0000 Subject: [PATCH] r600g: Emit vertex buffers using the same method as constant buffers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Marek Olšák --- src/gallium/drivers/r600/evergreen_compute.c | 8 +++-- src/gallium/drivers/r600/evergreen_state.c | 45 ++++++++++++++++++---------- src/gallium/drivers/r600/r600_buffer.c | 5 +++- src/gallium/drivers/r600/r600_hw_context.c | 2 +- src/gallium/drivers/r600/r600_pipe.h | 10 +++++-- src/gallium/drivers/r600/r600_state.c | 2 +- src/gallium/drivers/r600/r600_state_common.c | 9 ++++-- 7 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c index b61ea8f..947a328 100644 --- a/src/gallium/drivers/r600/evergreen_compute.c +++ b/src/gallium/drivers/r600/evergreen_compute.c @@ -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) { diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 923dea7..9a64f67 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -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); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 3d7d1f0..8e2deb1 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -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. */ diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index b236069..e80f39c 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -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; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ba63dcc..0581040 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -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; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index e7fd133..3d5835c 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -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); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index d952220..be3d101 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -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, -- 2.7.4