Module: Mesa
Branch: radeon-rewrite
Commit: 9abc72d1fc0aada59a76bd602ebc36db9a729b5b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9abc72d1fc0aada59a76bd602ebc36db9a729b5b

Author: Maciej Cencora <m.cenc...@gmail.com>
Date:   Sun Jun  7 21:34:44 2009 +0200

r300: fix a GPU lock up

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  |   33 +++++++++++++++++--------------
 src/mesa/drivers/dri/r300/r300_emit.h  |    4 +-
 src/mesa/drivers/dri/r300/r300_state.c |    8 +++---
 3 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/r300_emit.c 
b/src/mesa/drivers/dri/r300/r300_emit.c
index cf31596..4017224 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h 
b/src/mesa/drivers/dri/r300/r300_emit.h
index d88914c..2fb8b82 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -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
diff --git a/src/mesa/drivers/dri/r300/r300_state.c 
b/src/mesa/drivers/dri/r300/r300_state.c
index 2fff89c..b509c13 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -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)

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to