diff options
author | Dave Airlie <[email protected]> | 2010-12-03 20:53:39 +1000 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2010-12-05 05:47:03 +0100 |
commit | c1365606c5b89872af4a0931e20f5cb78875eea6 (patch) | |
tree | 8eeb9533852e4739f77cad2fce9dcda760d8db0e /src | |
parent | 1774273bde184acb95ce0ba0bfd8a0d86d04ea8f (diff) |
r300g: try and use all of vertex constant space
Finished up by Marek Olšák.
We can set the constant space to use a different area per-call to the shader,
we can avoid flushing the PVS as often as we do by spreading out the constants
across the whole constant space.
Signed-off-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 71 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_reg.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 30 |
4 files changed, 62 insertions, 47 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index b543ad667ed..bb5906aeb93 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -258,6 +258,8 @@ struct r300_constant_buffer { uint32_t *ptr; /* Remapping table. */ unsigned *remap_table; + /* const buffer base */ + uint32_t buffer_base; }; /* Query object. @@ -606,6 +608,9 @@ struct r300_context { /* Stat counter. */ uint64_t flush_counter; + + /* const tracking for VS */ + int vs_const_base; }; /* Convenience cast wrappers. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 2b137271749..3ff5b13f975 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -924,7 +924,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) struct r300_vertex_program_code* code = &vs->code; struct r300_screen* r300screen = r300->screen; unsigned instruction_count = code->length / 4; - unsigned i; unsigned vtx_mem_size = r300screen->caps.is_r500 ? 128 : 72; unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1); @@ -935,10 +934,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) vtx_mem_size / output_count, 10); unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 5); - unsigned imm_first = vs->externals_count; - unsigned imm_end = vs->code.constants.Count; - unsigned imm_count = vs->immediates_count; - CS_LOCALS(r300); BEGIN_CS(size); @@ -947,12 +942,10 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) * R300_VAP_PVS_CONST_CNTL * R300_VAP_PVS_CODE_CNTL_1 * See the r5xx docs for instructions on how to use these. */ - OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3); - OUT_CS(R300_PVS_FIRST_INST(0) | - R300_PVS_XYZW_VALID_INST(instruction_count - 1) | - R300_PVS_LAST_INST(instruction_count - 1)); - OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1)); - OUT_CS(instruction_count - 1); + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) | + R300_PVS_XYZW_VALID_INST(instruction_count - 1) | + R300_PVS_LAST_INST(instruction_count - 1)); + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, instruction_count - 1); OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); @@ -964,19 +957,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) R300_PVS_VF_MAX_VTX_NUM(12) | (r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0)); - /* Emit immediates. */ - if (imm_count) { - OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, - (r300->screen->caps.is_r500 ? - R500_PVS_CONST_START : R300_PVS_CONST_START) + - imm_first); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4); - for (i = imm_first; i < imm_end; i++) { - const float *data = vs->code.constants.Constants[i].u.Immediate; - OUT_CS_TABLE(data, 4); - } - } - /* Emit flow control instructions. */ if (code->num_fc_ops) { @@ -1001,24 +981,43 @@ void r300_emit_vs_constants(struct r300_context* r300, unsigned count = ((struct r300_vertex_shader*)r300->vs_state.state)->externals_count; struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; + struct r300_vertex_shader *vs = (struct r300_vertex_shader*)r300->vs_state.state; unsigned i; + int imm_first = vs->externals_count; + int imm_end = vs->code.constants.Count; + int imm_count = vs->immediates_count; CS_LOCALS(r300); - if (!count) - return; - BEGIN_CS(size); - OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, - (r300->screen->caps.is_r500 ? - R500_PVS_CONST_START : R300_PVS_CONST_START)); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4); - if (buf->remap_table){ - for (i = 0; i < count; i++) { - uint32_t *data = &buf->ptr[buf->remap_table[i]*4]; + OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, + R300_PVS_CONST_BASE_OFFSET(buf->buffer_base) | + R300_PVS_MAX_CONST_ADDR(MAX2(imm_end - 1, 0))); + if (vs->externals_count) { + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, + (r300->screen->caps.is_r500 ? + R500_PVS_CONST_START : R300_PVS_CONST_START) + buf->buffer_base); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4); + if (buf->remap_table){ + for (i = 0; i < count; i++) { + uint32_t *data = &buf->ptr[buf->remap_table[i]*4]; + OUT_CS_TABLE(data, 4); + } + } else { + OUT_CS_TABLE(buf->ptr, count * 4); + } + } + + /* Emit immediates. */ + if (imm_count) { + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, + (r300->screen->caps.is_r500 ? + R500_PVS_CONST_START : R300_PVS_CONST_START) + + buf->buffer_base + imm_first); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4); + for (i = imm_first; i < imm_end; i++) { + const float *data = vs->code.constants.Constants[i].u.Immediate; OUT_CS_TABLE(data, 4); } - } else { - OUT_CS_TABLE(buf->ptr, count * 4); } END_CS; } diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 788c513be75..613186e8156 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -427,7 +427,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PVS_CONST_START 512 # define R500_PVS_CONST_START 1024 # define R300_MAX_PVS_CONST_VECS 256 -# define R500_MAX_PVS_CONST_VECS 1024 +# define R500_MAX_PVS_CONST_VECS 256 # define R300_PVS_UCP_START 1024 # define R500_PVS_UCP_START 1536 # define R300_POINT_VPORT_SCALE_OFFSET 1030 @@ -553,6 +553,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Addresses are relative to the vertex program parameters area. */ #define R300_VAP_PVS_CONST_CNTL 0x22D4 # define R300_PVS_CONST_BASE_OFFSET_SHIFT 0 +# define R300_PVS_CONST_BASE_OFFSET(x) (x) # define R300_PVS_MAX_CONST_ADDR_SHIFT 16 # define R300_PVS_MAX_CONST_ADDR(x) ((x) << 16) #define R300_VAP_PVS_CODE_CNTL_1 0x22D8 diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 56892755507..4eef9da06a4 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1765,15 +1765,13 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->vs_state.dirty = TRUE; r300->vs_state.size = vs->code.length + 9 + - (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0) + (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0); - if (vs->externals_count) { - r300->vs_constants.dirty = TRUE; - r300->vs_constants.size = vs->externals_count * 4 + 3; - } else { - r300->vs_constants.size = 0; - } + r300->vs_constants.dirty = TRUE; + r300->vs_constants.size = + 2 + + (vs->externals_count ? vs->externals_count * 4 + 3 : 0) + + (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0); ((struct r300_constant_buffer*)r300->vs_constants.state)->remap_table = vs->code.constants_remap_table; @@ -1835,10 +1833,22 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, if (shader == PIPE_SHADER_VERTEX) { if (r300->screen->caps.has_tcl) { - if (r300->vs_constants.size) { - r300->vs_constants.dirty = TRUE; + struct r300_vertex_shader *vs = + (struct r300_vertex_shader*)r300->vs_state.state; + + if (!vs) { + cbuf->buffer_base = 0; + return; } - r300->pvs_flush.dirty = TRUE; + + cbuf->buffer_base = r300->vs_const_base; + r300->vs_const_base += vs->code.constants.Count; + if (r300->vs_const_base > R500_MAX_PVS_CONST_VECS) { + r300->vs_const_base = vs->code.constants.Count; + cbuf->buffer_base = 0; + r300->pvs_flush.dirty = TRUE; + } + r300->vs_constants.dirty = TRUE; } else if (r300->draw) { draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, 0, mapped, buf->width0); |