r300: fix a GPU lock up
authorMaciej Cencora <m.cencora@gmail.com>
Sun, 7 Jun 2009 19:34:44 +0000 (21:34 +0200)
committerMaciej Cencora <m.cencora@gmail.com>
Thu, 11 Jun 2009 21:24:25 +0000 (23:24 +0200)
Sending from VAP more texture coordinates than RS expects results in GPU hang.

Fixes BumpSelfShadow from DirectX8 SDK.

src/mesa/drivers/dri/r300/r300_emit.c
src/mesa/drivers/dri/r300/r300_emit.h
src/mesa/drivers/dri/r300/r300_state.c

index cf31596d9b8c5918718df7c1d7a52c1c675d7fd3..4017224b10a20042fb799c16fab89cd9f56981dd 100644 (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;
index d88914ce9595fd2d3264c2e52eebb451e97ee2fa..2fb8b82d3a1f41befeea688d15c3517a7710b4c7 100644 (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
index 2fff89c473c39f4e1783560223e4ab135f106449..b509c13b43267b2cb462e79be47c28af151fcc6d 100644 (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)