From 3da6487115216c47ce1be56b45be654ddb879d6f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 13 Jun 2010 06:11:54 +0200 Subject: r300g: turn fragment shader into a CB --- src/gallium/drivers/r300/r300_emit.c | 126 +--------------------------------- src/gallium/drivers/r300/r300_emit.h | 6 +- src/gallium/drivers/r300/r300_fs.c | 116 +++++++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_fs.h | 3 + src/gallium/drivers/r300/r300_state.c | 4 +- 5 files changed, 126 insertions(+), 129 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f501c1fc89..658880aebc 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -127,7 +127,7 @@ static const float * get_rc_constant_state( /* Convert a normal single-precision float into the 7.16 format * used by the R300 fragment shader. */ -static uint32_t pack_float24(float f) +uint32_t pack_float24(float f) { union { float fl; @@ -158,77 +158,12 @@ static uint32_t pack_float24(float f) return float24; } -unsigned r300_get_fs_atom_size(struct r300_context *r300) -{ - struct r300_fragment_shader *fs = r300_fs(r300); - unsigned imm_count = fs->shader->immediates_count; - struct r300_fragment_program_code *code = &fs->shader->code.code.r300; - - return 19 + - code->alu.length * 4 + - (code->tex.length ? (1 + code->tex.length) : 0) + - (imm_count ? imm_count * 5 : 0); -} - void r300_emit_fs(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); - struct rX00_fragment_program_code* generic_code = &fs->shader->code; - struct r300_fragment_program_code * code = &generic_code->code.r300; - unsigned i; - unsigned imm_count = fs->shader->immediates_count; - unsigned imm_first = fs->shader->externals_count; - unsigned imm_end = generic_code->constants.Count; - struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); - BEGIN_CS(size); - OUT_CS_REG(R300_US_CONFIG, code->config); - OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); - OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset); - - OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4); - OUT_CS_TABLE(code->code_addr, 4); - - OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length); - for (i = 0; i < code->alu.length; i++) - OUT_CS(code->alu.inst[i].rgb_inst); - - OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length); - for (i = 0; i < code->alu.length; i++) - OUT_CS(code->alu.inst[i].rgb_addr); - - OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length); - for (i = 0; i < code->alu.length; i++) - OUT_CS(code->alu.inst[i].alpha_inst); - - OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); - for (i = 0; i < code->alu.length; i++) - OUT_CS(code->alu.inst[i].alpha_addr); - - if (code->tex.length) { - OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length); - OUT_CS_TABLE(code->tex.inst, code->tex.length); - } - - /* Emit immediates. */ - if (imm_count) { - for(i = imm_first; i < imm_end; ++i) { - if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { - const float *data = constants[i].u.Immediate; - - OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); - OUT_CS(pack_float24(data[0])); - OUT_CS(pack_float24(data[1])); - OUT_CS(pack_float24(data[2])); - OUT_CS(pack_float24(data[3])); - } - } - } - - OUT_CS_REG(R300_FG_DEPTH_SRC, fs->shader->fg_depth_src); - OUT_CS_REG(R300_US_W_FMT, fs->shader->us_out_w); - END_CS; + WRITE_CS_TABLE(fs->shader->cb_code, fs->shader->cb_code_size); } void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) @@ -285,67 +220,12 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo END_CS; } -unsigned r500_get_fs_atom_size(struct r300_context *r300) -{ - struct r300_fragment_shader *fs = r300_fs(r300); - unsigned imm_count = fs->shader->immediates_count; - struct r500_fragment_program_code *code = &fs->shader->code.code.r500; - - return 17 + - ((code->inst_end + 1) * 6) + - (imm_count ? imm_count * 7 : 0); -} - void r500_emit_fs(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); - struct rX00_fragment_program_code* generic_code = &fs->shader->code; - struct r500_fragment_program_code * code = &generic_code->code.r500; - unsigned i; - unsigned imm_count = fs->shader->immediates_count; - unsigned imm_first = fs->shader->externals_count; - unsigned imm_end = generic_code->constants.Count; - struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); - BEGIN_CS(size); - OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); - OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); - OUT_CS_REG(R500_US_CODE_RANGE, - R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); - OUT_CS_REG(R500_US_CODE_OFFSET, 0); - OUT_CS_REG(R500_US_CODE_ADDR, - R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end)); - - OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR); - OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6); - for (i = 0; i <= code->inst_end; i++) { - OUT_CS(code->inst[i].inst0); - OUT_CS(code->inst[i].inst1); - OUT_CS(code->inst[i].inst2); - OUT_CS(code->inst[i].inst3); - OUT_CS(code->inst[i].inst4); - OUT_CS(code->inst[i].inst5); - } - - /* Emit immediates. */ - if (imm_count) { - for(i = imm_first; i < imm_end; ++i) { - if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { - const float *data = constants[i].u.Immediate; - - OUT_CS_REG(R500_GA_US_VECTOR_INDEX, - R500_GA_US_VECTOR_INDEX_TYPE_CONST | - (i & R500_GA_US_VECTOR_INDEX_MASK)); - OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, 4); - OUT_CS_TABLE(data, 4); - } - } - } - - OUT_CS_REG(R300_FG_DEPTH_SRC, fs->shader->fg_depth_src); - OUT_CS_REG(R300_US_W_FMT, fs->shader->us_out_w); - END_CS; + WRITE_CS_TABLE(fs->shader->cb_code, fs->shader->cb_code_size); } void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 9066088342..36a29894d0 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -29,6 +29,8 @@ struct rX00_fragment_program_code; struct r300_vertex_program_code; +uint32_t pack_float24(float f); + void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed); void r300_emit_blend_state(struct r300_context* r300, @@ -43,16 +45,12 @@ void r300_emit_clip_state(struct r300_context* r300, void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state); -unsigned r300_get_fs_atom_size(struct r300_context *r300); - void r300_emit_fs(struct r300_context* r300, unsigned size, void *state); void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state); void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state); -unsigned r500_get_fs_atom_size(struct r300_context *r300); - void r500_emit_fs(struct r300_context* r300, unsigned size, void *state); void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index a434808046..e585394304 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -28,7 +28,9 @@ #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_ureg.h" +#include "r300_cb.h" #include "r300_context.h" +#include "r300_emit.h" #include "r300_screen.h" #include "r300_fs.h" #include "r300_reg.h" @@ -229,6 +231,117 @@ static void r300_dummy_fragment_shader( ureg_destroy(ureg); } +static void r300_emit_fs_code_to_buffer( + struct r300_context *r300, + struct r300_fragment_shader_code *shader) +{ + struct rX00_fragment_program_code *generic_code = &shader->code; + unsigned imm_count = shader->immediates_count; + unsigned imm_first = shader->externals_count; + unsigned imm_end = generic_code->constants.Count; + struct rc_constant *constants = generic_code->constants.Constants; + unsigned i; + CB_LOCALS; + + if (r300->screen->caps.is_r500) { + struct r500_fragment_program_code *code = &generic_code->code.r500; + + shader->cb_code_size = 17 + + ((code->inst_end + 1) * 6) + + imm_count * 7; + + NEW_CB(shader->cb_code, shader->cb_code_size); + OUT_CB_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); + OUT_CB_REG(R500_US_PIXSIZE, code->max_temp_idx); + OUT_CB_REG(R500_US_CODE_RANGE, + R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); + OUT_CB_REG(R500_US_CODE_OFFSET, 0); + OUT_CB_REG(R500_US_CODE_ADDR, + R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end)); + + OUT_CB_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR); + OUT_CB_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6); + for (i = 0; i <= code->inst_end; i++) { + OUT_CB(code->inst[i].inst0); + OUT_CB(code->inst[i].inst1); + OUT_CB(code->inst[i].inst2); + OUT_CB(code->inst[i].inst3); + OUT_CB(code->inst[i].inst4); + OUT_CB(code->inst[i].inst5); + } + + /* Emit immediates. */ + if (imm_count) { + for(i = imm_first; i < imm_end; ++i) { + if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { + const float *data = constants[i].u.Immediate; + + OUT_CB_REG(R500_GA_US_VECTOR_INDEX, + R500_GA_US_VECTOR_INDEX_TYPE_CONST | + (i & R500_GA_US_VECTOR_INDEX_MASK)); + OUT_CB_ONE_REG(R500_GA_US_VECTOR_DATA, 4); + OUT_CB_TABLE(data, 4); + } + } + } + } else { /* r300 */ + struct r300_fragment_program_code *code = &generic_code->code.r300; + + shader->cb_code_size = 19 + + code->alu.length * 4 + + (code->tex.length ? (1 + code->tex.length) : 0) + + imm_count * 5; + + NEW_CB(shader->cb_code, shader->cb_code_size); + OUT_CB_REG(R300_US_CONFIG, code->config); + OUT_CB_REG(R300_US_PIXSIZE, code->pixsize); + OUT_CB_REG(R300_US_CODE_OFFSET, code->code_offset); + + OUT_CB_REG_SEQ(R300_US_CODE_ADDR_0, 4); + OUT_CB_TABLE(code->code_addr, 4); + + OUT_CB_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CB(code->alu.inst[i].rgb_inst); + + OUT_CB_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CB(code->alu.inst[i].rgb_addr); + + OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CB(code->alu.inst[i].alpha_inst); + + OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) + OUT_CB(code->alu.inst[i].alpha_addr); + + if (code->tex.length) { + OUT_CB_REG_SEQ(R300_US_TEX_INST_0, code->tex.length); + OUT_CB_TABLE(code->tex.inst, code->tex.length); + } + + /* Emit immediates. */ + if (imm_count) { + for(i = imm_first; i < imm_end; ++i) { + if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { + const float *data = constants[i].u.Immediate; + + OUT_CB_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); + OUT_CB(pack_float24(data[0])); + OUT_CB(pack_float24(data[1])); + OUT_CB(pack_float24(data[2])); + OUT_CB(pack_float24(data[3])); + } + } + } + } + + OUT_CB_REG(R300_FG_DEPTH_SRC, shader->fg_depth_src); + OUT_CB_REG(R300_US_W_FMT, shader->us_out_w); + END_CB; +} + static void r300_translate_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader, @@ -338,6 +451,9 @@ static void r300_translate_fragment_shader( /* And, finally... */ rc_destroy(&compiler.Base); + + /* Build the command buffer. */ + r300_emit_fs_code_to_buffer(r300, shader); } boolean r300_pick_fragment_shader(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index 1cc4355359..51bfa88c5e 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -50,6 +50,9 @@ struct r300_fragment_shader_code { struct r300_fragment_program_external_state compare_state; struct rX00_fragment_program_code code; + unsigned cb_code_size; + uint32_t *cb_code; + struct r300_fragment_shader_code* next; }; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 8176bf4f98..4892a1d7a3 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -759,13 +759,12 @@ void r300_mark_fs_code_dirty(struct r300_context *r300) r300->fs.dirty = TRUE; r300->fs_rc_constant_state.dirty = TRUE; r300->fs_constants.dirty = TRUE; + r300->fs.size = fs->shader->cb_code_size; if (r300->screen->caps.is_r500) { - r300->fs.size = r500_get_fs_atom_size(r300); r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 7; r300->fs_constants.size = fs->shader->externals_count * 4 + 3; } else { - r300->fs.size = r300_get_fs_atom_size(r300); r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 5; r300->fs_constants.size = fs->shader->externals_count * 4 + 1; } @@ -799,6 +798,7 @@ static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) tmp = ptr; ptr = ptr->next; rc_constants_destroy(&tmp->code.constants); + FREE(tmp->cb_code); FREE(tmp); } FREE((void*)fs->state.tokens); -- cgit v1.2.3