void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; unsigned count = fs->shader->externals_count; unsigned i, j; CS_LOCALS(r300); if (count == 0) return; BEGIN_CS(size); OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4); if (buf->remap_table){ for (i = 0; i < count; i++) { float *data = (float*)&buf->ptr[buf->remap_table[i]*4]; for (j = 0; j < 4; j++) OUT_CS(pack_float24(data[j])); } } else { for (i = 0; i < count; i++) for (j = 0; j < 4; j++) OUT_CS(pack_float24(*(float*)&buf->ptr[i*4+j])); } END_CS; }
void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); struct rc_constant_list *constants = &fs->shader->code.constants; unsigned i; unsigned count = fs->shader->rc_state_count; unsigned first = fs->shader->externals_count; unsigned end = constants->Count; unsigned j; CS_LOCALS(r300); if (count == 0) return; BEGIN_CS(size); for(i = first; i < end; ++i) { if (constants->Constants[i].Type == RC_CONSTANT_STATE) { float data[4]; get_rc_constant_state(data, r300, &constants->Constants[i]); OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); for (j = 0; j < 4; j++) OUT_CS(pack_float24(data[j])); } } END_CS; }
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 = 19 + ((code->inst_end + 1) * 6) + imm_count * 7 + code->int_constant_count * 2; 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_FC_CTRL, code->us_fc_ctrl); for(i = 0; i < code->int_constant_count; i++){ OUT_CB_REG(R500_US_FC_INT_CONST_0 + (i * 4), code->int_constants[i]); } 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; unsigned int alu_length = code->alu.length; unsigned int alu_iterations = ((alu_length - 1) / 64) + 1; unsigned int tex_length = code->tex.length; unsigned int tex_iterations = tex_length > 0 ? ((tex_length - 1) / 32) + 1 : 0; unsigned int iterations = alu_iterations > tex_iterations ? alu_iterations : tex_iterations; unsigned int bank = 0; shader->cb_code_size = 15 + /* R400_US_CODE_BANK */ (r300->screen->caps.is_r400 ? 2 * (iterations + 1): 0) + /* R400_US_CODE_EXT */ (r300->screen->caps.is_r400 ? 2 : 0) + /* R300_US_ALU_{RGB,ALPHA}_{INST,ADDR}_0, R400_US_ALU_EXT_ADDR_0 */ (code->r390_mode ? (5 * alu_iterations) : 4) + /* R400_US_ALU_EXT_ADDR_[0-63] */ (code->r390_mode ? (code->alu.length) : 0) + /* R300_US_ALU_{RGB,ALPHA}_{INST,ADDR}_0 */ code->alu.length * 4 + /* R300_US_TEX_INST_0, R300_US_TEX_INST_[0-31] */ (code->tex.length > 0 ? code->tex.length + tex_iterations : 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); if (code->r390_mode) { OUT_CB_REG(R400_US_CODE_EXT, code->r400_code_offset_ext); } else if (r300->screen->caps.is_r400) { /* This register appears to affect shaders even if r390_mode is * disabled, so it needs to be set to 0 for shaders that * don't use r390_mode. */ OUT_CB_REG(R400_US_CODE_EXT, 0); } OUT_CB_REG_SEQ(R300_US_CODE_ADDR_0, 4); OUT_CB_TABLE(code->code_addr, 4); do { unsigned int bank_alu_length = (alu_length < 64 ? alu_length : 64); unsigned int bank_alu_offset = bank * 64; unsigned int bank_tex_length = (tex_length < 32 ? tex_length : 32); unsigned int bank_tex_offset = bank * 32; if (r300->screen->caps.is_r400) { OUT_CB_REG(R400_US_CODE_BANK, code->r390_mode ? (bank << R400_BANK_SHIFT) | R400_R390_MODE_ENABLE : 0);//2 } if (bank_alu_length > 0) { OUT_CB_REG_SEQ(R300_US_ALU_RGB_INST_0, bank_alu_length); for (i = 0; i < bank_alu_length; i++) OUT_CB(code->alu.inst[i + bank_alu_offset].rgb_inst); OUT_CB_REG_SEQ(R300_US_ALU_RGB_ADDR_0, bank_alu_length); for (i = 0; i < bank_alu_length; i++) OUT_CB(code->alu.inst[i + bank_alu_offset].rgb_addr); OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_INST_0, bank_alu_length); for (i = 0; i < bank_alu_length; i++) OUT_CB(code->alu.inst[i + bank_alu_offset].alpha_inst); OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, bank_alu_length); for (i = 0; i < bank_alu_length; i++) OUT_CB(code->alu.inst[i + bank_alu_offset].alpha_addr); if (code->r390_mode) { OUT_CB_REG_SEQ(R400_US_ALU_EXT_ADDR_0, bank_alu_length); for (i = 0; i < bank_alu_length; i++) OUT_CB(code->alu.inst[i + bank_alu_offset].r400_ext_addr); } } if (bank_tex_length > 0) { OUT_CB_REG_SEQ(R300_US_TEX_INST_0, bank_tex_length); OUT_CB_TABLE(code->tex.inst + bank_tex_offset, bank_tex_length); } alu_length -= bank_alu_length; tex_length -= bank_tex_length; bank++; } while(code->r390_mode && (alu_length > 0 || tex_length > 0)); /* R400_US_CODE_BANK needs to be reset to 0, otherwise some shaders * will be rendered incorrectly. */ if (r300->screen->caps.is_r400) { OUT_CB_REG(R400_US_CODE_BANK, code->r390_mode ? R400_R390_MODE_ENABLE : 0); } /* 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; }