mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 14:18:07 +02:00
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 <maraeo@gmail.com>
This commit is contained in:
parent
1774273bde
commit
c1365606c5
4 changed files with 62 additions and 47 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue