summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/r300_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_state.c')
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c208
1 files changed, 206 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index ec9bf25bab..1f3779cade 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1603,6 +1603,128 @@ static void r300SetupRSUnit(GLcontext * ctx)
WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
}
+static void r500SetupRSUnit(GLcontext * ctx)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ /* I'm still unsure if these are needed */
+ GLuint interp_magic[8] = {
+ 0x00,
+ R300_RS_COL_PTR(1),
+ R300_RS_COL_PTR(2),
+ R300_RS_COL_PTR(3),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ union r300_outputs_written OutputsWritten;
+ GLuint InputsRead;
+ int fp_reg, high_rr;
+ int in_texcoords, col_interp_nr;
+ int i;
+
+ if (hw_tcl_on)
+ OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+ else
+ RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);
+
+ if (ctx->FragmentProgram._Current)
+ InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+ else {
+ fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+ return; /* This should only ever happen once.. */
+ }
+
+ R300_STATECHANGE(r300, ri);
+ R300_STATECHANGE(r300, rc);
+ R300_STATECHANGE(r300, rr);
+
+ fp_reg = in_texcoords = col_interp_nr = high_rr = 0;
+
+ r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
+
+ if (InputsRead & FRAG_BIT_WPOS) {
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+ break;
+
+ if (i == ctx->Const.MaxTextureUnits) {
+ fprintf(stderr, "\tno free texcoord found...\n");
+ _mesa_exit(-1);
+ }
+
+ InputsRead |= (FRAG_BIT_TEX0 << i);
+ InputsRead &= ~FRAG_BIT_WPOS;
+ }
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | (in_texcoords << R300_RS_INTERP_SRC_SHIFT)
+ | interp_magic[i];
+
+ r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0;
+ if (InputsRead & (FRAG_BIT_TEX0 << i)) {
+ //assert(r300->state.texture.tc_count != 0);
+ r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] |= R300_RS_ROUTE_ENABLE | i /* source INTERP */
+ | (fp_reg << R300_RS_ROUTE_DEST_SHIFT);
+ high_rr = fp_reg;
+
+ /* Passing invalid data here can lock the GPU. */
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
+ InputsRead &= ~(FRAG_BIT_TEX0 << i);
+ fp_reg++;
+ } else {
+ WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i);
+ }
+ }
+ /* Need to count all coords enabled at vof */
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {
+ in_texcoords++;
+ }
+ }
+
+ if (InputsRead & FRAG_BIT_COL0) {
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {
+ r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
+ InputsRead &= ~FRAG_BIT_COL0;
+ col_interp_nr++;
+ } else {
+ WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
+ }
+ }
+
+ if (InputsRead & FRAG_BIT_COL1) {
+ if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {
+ r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 | (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT);
+ InputsRead &= ~FRAG_BIT_COL1;
+ if (high_rr < 1)
+ high_rr = 1;
+ col_interp_nr++;
+ } else {
+ WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
+ }
+ }
+
+ /* Need at least one. This might still lock as the values are undefined... */
+ if (in_texcoords == 0 && col_interp_nr == 0) {
+ r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
+ col_interp_nr++;
+ }
+
+ r300->hw.rc.cmd[1] = 0 | ((in_texcoords << 2) << R300_IT_COUNT_SHIFT)
+ | (col_interp_nr << R300_IC_COUNT_SHIFT)
+ | R300_HIRES_EN;
+
+ assert(high_rr >= 0);
+ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, high_rr + 1);
+ r300->hw.rc.cmd[2] = 0xC0 | high_rr;
+
+ if (InputsRead)
+ WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
+}
+
+
+
+
#define bump_vpu_count(ptr, new_count) do{\
drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
int _nc=(new_count)/4; \
@@ -2163,6 +2285,81 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
}
}
+static void r500SetupPixelShader(r300ContextPtr rmesa)
+{
+ GLcontext *ctx = rmesa->radeon.glCtx;
+ struct r300_fragment_program *fp = (struct r300_fragment_program *)
+ (char *)ctx->FragmentProgram._Current;
+ int i, k;
+
+ if (!fp) /* should only happenen once, just after context is created */
+ return;
+
+ /* emit the standard zero shader */
+ R300_STATECHANGE(rmesa, r500fp);
+ i = 1;
+ rmesa->hw.r500fp.cmd[i++] = 0x7807;
+ rmesa->hw.r500fp.cmd[i++] = R500_TEX_ID(0) | R500_TEX_INST_LD | R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED;
+ rmesa->hw.r500fp.cmd[i++] = R500_TEX_SRC_ADDR(0) | R500_TEX_SRC_S_SWIZ_R |
+ R500_TEX_SRC_T_SWIZ_G |
+ R500_TEX_DST_ADDR(0) |
+ R500_TEX_DST_R_SWIZ_R |
+ R500_TEX_DST_G_SWIZ_G |
+ R500_TEX_DST_B_SWIZ_B |
+ R500_TEX_DST_A_SWIZ_A;
+ rmesa->hw.r500fp.cmd[i++] = R500_DX_ADDR(0) |
+ R500_DX_S_SWIZ_R |
+ R500_DX_T_SWIZ_R |
+ R500_DX_R_SWIZ_R |
+ R500_DX_Q_SWIZ_R |
+ R500_DY_ADDR(0) |
+ R500_DY_S_SWIZ_R |
+ R500_DY_T_SWIZ_R |
+ R500_DY_R_SWIZ_R |
+ R500_DY_Q_SWIZ_R;
+ rmesa->hw.r500fp.cmd[i++] = 0x0;
+ rmesa->hw.r500fp.cmd[i++] = 0x0;
+
+ rmesa->hw.r500fp.cmd[i++] = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT |
+ R500_INST_LAST |
+ R500_INST_RGB_OMASK_R |
+ R500_INST_RGB_OMASK_G |
+ R500_INST_RGB_OMASK_B |
+ R500_INST_ALPHA_OMASK;
+
+ rmesa->hw.r500fp.cmd[i++] = R500_RGB_ADDR0(0) |
+ R500_RGB_ADDR1(0) |
+ R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) |
+ R500_RGB_ADDR2_CONST |
+ R500_RGB_SRCP_OP_1_MINUS_2RGB0;
+ rmesa->hw.r500fp.cmd[i++] = R500_ALPHA_ADDR0(0) |
+ R500_ALPHA_ADDR1(0) |
+ R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) |
+ R500_ALPHA_ADDR2_CONST |
+ R500_ALPHA_SRCP_OP_1_MINUS_2A0;
+ rmesa->hw.r500fp.cmd[i++] = R500_ALU_RGB_SEL_A_SRC0 |
+ R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G |
+ R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 |
+ R500_ALU_RGB_R_SWIZ_B_1 |
+ R500_ALU_RGB_B_SWIZ_B_1 |
+ R500_ALU_RGB_G_SWIZ_B_1;
+ rmesa->hw.r500fp.cmd[i++] = R500_ALPHA_OP_MAD |
+ R500_ALPHA_SWIZ_A_A |
+ R500_ALPHA_SWIZ_B_1;
+ rmesa->hw.r500fp.cmd[i++] = R500_ALU_RGBA_OP_MAD |
+ R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 |
+ R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0;
+
+
+}
+
void r300UpdateShaderStates(r300ContextPtr rmesa)
{
GLcontext *ctx;
@@ -2170,12 +2367,19 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
r300UpdateTextureState(ctx);
- r300SetupPixelShader(rmesa);
+ if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
+ r500SetupPixelShader(rmesa);
+ else
+ r300SetupPixelShader(rmesa);
r300SetupTextures(ctx);
if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
r300SetupVertexProgram(rmesa);
- r300SetupRSUnit(ctx);
+
+ if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
+ r500SetupRSUnit(ctx);
+ else
+ r300SetupRSUnit(ctx);
}
/**