mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
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:
parent
de19eb0b0d
commit
9abc72d1fc
3 changed files with 24 additions and 21 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue