r300: fix a GPU lock up

Sending from VAP more texture coordinates than RS expects results in GPU hang.

Fixes BumpSelfShadow from DirectX8 SDK.
This commit is contained in:
Maciej Cencora 2009-06-07 21:34:44 +02:00
parent de19eb0b0d
commit 9abc72d1fc
3 changed files with 24 additions and 21 deletions

View file

@ -81,49 +81,52 @@ GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
return vic_1;
}
GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
{
GLuint ret = 0;
if (OutputsWritten & (1 << VERT_RESULT_HPOS))
if (vp_writes & (1 << VERT_RESULT_HPOS))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
if (OutputsWritten & (1 << VERT_RESULT_COL0))
if (vp_writes & (1 << VERT_RESULT_COL0) && fp_reads & FRAG_BIT_COL0)
ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT;
if (OutputsWritten & (1 << VERT_RESULT_COL1))
if (vp_writes & (1 << VERT_RESULT_COL1) && fp_reads & FRAG_BIT_COL1)
ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
if (OutputsWritten & (1 << VERT_RESULT_BFC0)
|| OutputsWritten & (1 << VERT_RESULT_BFC1))
ret |=
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT |
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT |
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
/* Two sided lighting works only if all 4 colors are written */
if (vp_writes & (1 << VERT_RESULT_BFC0) || vp_writes & (1 << VERT_RESULT_BFC1))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT |
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
if (vp_writes & (1 << VERT_RESULT_PSIZ))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
return ret;
}
GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten)
GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
{
GLuint i, ret = 0, first_free_texcoord = 0;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
if (OutputsWritten & (1 << (VERT_RESULT_TEX0 + i))) {
if (vp_writes & (1 << (VERT_RESULT_TEX0 + i)) && fp_reads & FRAG_BIT_TEX(i)) {
ret |= (4 << (3 * i));
++first_free_texcoord;
}
}
if (OutputsWritten & (1 << VERT_RESULT_FOGC)) {
if (fp_reads & FRAG_BIT_WPOS) {
ret |= (4 << (3 * first_free_texcoord));
++first_free_texcoord;
}
if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) {
if (first_free_texcoord > 8) {
fprintf(stderr, "\tout of free texcoords to write fog coord\n");
_mesa_exit(-1);
}
ret |= 1 << (3 * first_free_texcoord);
ret |= 4 << (3 * first_free_texcoord);
}
return ret;

View file

@ -225,7 +225,7 @@ extern void r300EmitCacheFlush(r300ContextPtr rmesa);
extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead);
extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead);
extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten);
extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten);
extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads);
extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads);
#endif

View file

@ -1536,7 +1536,7 @@ static void r300SetupRSUnit(GLcontext * ctx)
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count);
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_FOGC;
rs_tex_count += 1;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
} else {
@ -1662,7 +1662,7 @@ static void r500SetupRSUnit(GLcontext * ctx)
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_FOGC;
rs_tex_count += 1;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
} else {
@ -2270,8 +2270,8 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten);
rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
}
void r300UpdateShaderStates(r300ContextPtr rmesa)