Mesa (master): r300: Fix corner-case of KIL on R300

Nicolai Hähnle nh at kemper.freedesktop.org
Sat Aug 1 17:01:05 UTC 2009


Module: Mesa
Branch: master
Commit: 9a1c336253579d8b58b31910325227b22b4af395
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9a1c336253579d8b58b31910325227b22b4af395

Author: Nicolai Hähnle <nhaehnle at gmail.com>
Date:   Sat Aug  1 18:58:47 2009 +0200

r300: Fix corner-case of KIL on R300

R300 hardware (but _not_ R500) hardware requires an enabled texture unit
if KIL is used in fragment programs. We now work around the CS checker
correctly when enabling such a fake texture unit.

Signed-off-by: Nicolai Hähnle <nhaehnle at gmail.com>

---

 src/mesa/drivers/dri/r300/r300_cmdbuf.c |   78 +++++++++++++++----------------
 src/mesa/drivers/dri/r300/r300_state.c  |   33 +++++++++----
 2 files changed, 60 insertions(+), 51 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index af53503..7eb11aa 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -164,47 +164,43 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
 	BATCH_LOCALS(&r300->radeon);
 	int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd);
-	int notexture = 0;
-
-	if (numtmus) {
-		int i;
-
-		for(i = 0; i < numtmus; ++i) {
-		    radeonTexObj *t = r300->hw.textures[i];
-
-		    if (!t)
-			notexture = 1;
-		}
-
-		if (r300->radeon.radeonScreen->kernel_mm && notexture) {
-			return;
-		}
-		for(i = 0; i < numtmus; ++i) {
-		    radeonTexObj *t = r300->hw.textures[i];
-		    if (t && !t->image_override) {
-                BEGIN_BATCH_NO_AUTOSTATE(4);
-                OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
-			    OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
-					    RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
-                END_BATCH();
-		    } else if (!t) {
-                /* Texture unit hasn't a texture bound nothings to do */
-		    } else { /* override cases */
-			    if (t->bo) {
-                    BEGIN_BATCH_NO_AUTOSTATE(4);
-                    OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
-				    OUT_BATCH_RELOC(t->tile_bits, t->bo, 0,
-						    RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
-                    END_BATCH();
-			    } else if (!r300->radeon.radeonScreen->kernel_mm) {
-                    BEGIN_BATCH_NO_AUTOSTATE(2);
-                    OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
-				    OUT_BATCH(t->override_offset);
-                    END_BATCH();
-			    } else {
-                    /* Texture unit hasn't a texture bound nothings to do */
-                }
-		    }
+	int i;
+
+	for(i = 0; i < numtmus; ++i) {
+		radeonTexObj *t = r300->hw.textures[i];
+		if (t && !t->image_override) {
+			BEGIN_BATCH_NO_AUTOSTATE(4);
+			OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+			OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+					RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+			END_BATCH();
+		} else if (!t) {
+			/* Texture unit hasn't a texture bound.
+			 * We assign the current color buffer as a fakery to make
+			 * KIL work. */
+			struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&r300->radeon);
+			if (rrb && rrb->bo) {
+				BEGIN_BATCH_NO_AUTOSTATE(4);
+				OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+				OUT_BATCH_RELOC(0, rrb->bo, 0,
+						RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+				END_BATCH();
+			}
+		} else { /* override cases */
+			if (t->bo) {
+				BEGIN_BATCH_NO_AUTOSTATE(4);
+				OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+				OUT_BATCH_RELOC(t->tile_bits, t->bo, 0,
+						RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+				END_BATCH();
+			} else if (!r300->radeon.radeonScreen->kernel_mm) {
+				BEGIN_BATCH_NO_AUTOSTATE(2);
+				OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+				OUT_BATCH(t->override_offset);
+				END_BATCH();
+			} else {
+				/* Texture unit hasn't a texture bound nothings to do */
+			}
 		}
 	}
 }
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 3c6e544..050e8cd 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1253,6 +1253,7 @@ static GLuint translate_lod_bias(GLfloat bias)
 	return (((GLuint)b) << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;
 }
 
+
 static void r300SetupTextures(GLcontext * ctx)
 {
 	int i, mtu;
@@ -1345,6 +1346,28 @@ static void r300SetupTextures(GLcontext * ctx)
 		}
 	}
 
+	/* R3xx and R4xx chips require that the texture unit corresponding to
+	 * KIL instructions is really enabled.
+	 *
+	 * We do some fakery here and in the state atom emit logic to enable
+	 * the texture without tripping up the CS checker in the kernel.
+	 */
+	if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
+		if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
+			last_hw_tmu++;
+
+			r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
+
+			r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0] = 0;
+			r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0] = 0;
+			r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
+			r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0] = 0;
+			r300->hw.tex.size.cmd[R300_TEX_VALUE_0] = 0; /* 1x1 texture */
+			r300->hw.tex.format.cmd[R300_TEX_VALUE_0] = 0; /* A8 format */
+			r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0] = 0;
+		}
+	}
+
 	r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
 	    cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1);
 	r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =
@@ -1362,16 +1385,6 @@ static void r300SetupTextures(GLcontext * ctx)
 	r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
 	    cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
 
-	if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
-		if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
-			// The KILL operation requires the first texture unit
-			// to be enabled.
-			r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
-			r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
-			r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
-				cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1);
-		}
-	}
 	r300->vtbl.SetupFragmentShaderTextures(ctx, tmu_mappings);
 
 	if (RADEON_DEBUG & DEBUG_STATE)




More information about the mesa-commit mailing list