Mesa (master): freedreno/a6xx: Fix 3dmark misrendering with unwritten MRTs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 25 23:47:03 UTC 2021


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Sun Jan 24 12:35:18 2021 -0800

freedreno/a6xx: Fix 3dmark misrendering with unwritten MRTs

Fixes an issue with 3dmark caused by a shader that only writes mrt0 in a
renderpass that has two color buffers bound, resulting in mrt1 getting
random/undefined values.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8685>

---

 src/gallium/drivers/freedreno/a6xx/fd6_emit.c    | 2 ++
 src/gallium/drivers/freedreno/a6xx/fd6_program.c | 8 ++++++++
 src/gallium/drivers/freedreno/a6xx/fd6_program.h | 7 +++++++
 3 files changed, 17 insertions(+)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
index bea8b0619b3..6903b982bb8 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
@@ -1003,6 +1003,8 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
 		if (blend->use_dual_src_blend)
 			mrt_components |= 0xf << 4;
 
+		mrt_components &= prog->mrt_components;
+
 		OUT_REG(ring, A6XX_SP_FS_RENDER_COMPONENTS(.dword = mrt_components));
 		OUT_REG(ring, A6XX_RB_RENDER_COMPONENTS(.dword = mrt_components));
 
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
index c734dc156f5..8a3129f058c 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
@@ -786,6 +786,14 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_context *ctx,
 	for (i = 0; i < 8; i++) {
 		OUT_RING(ring, A6XX_SP_FS_OUTPUT_REG_REGID(color_regid[i]) |
 				COND(color_regid[i] & HALF_REG_ID, A6XX_SP_FS_OUTPUT_REG_HALF_PRECISION));
+		if (VALIDREG(color_regid[i])) {
+			state->mrt_components |= 0xf << (i * 4);
+		}
+	}
+
+	/* dual source blending has an extra fs output in the 2nd slot */
+	if (fs_has_dual_src_color) {
+		state->mrt_components |= 0xf << 4;
 	}
 
 	OUT_PKT4(ring, REG_A6XX_VPC_VS_PACK, 1);
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.h b/src/gallium/drivers/freedreno/a6xx/fd6_program.h
index 3790c62348d..efeed71c12f 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_program.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.h
@@ -49,6 +49,13 @@ struct fd6_program_state {
 	struct fd_ringbuffer *binning_stateobj;
 	struct fd_ringbuffer *streamout_stateobj;
 	struct fd_ringbuffer *stateobj;
+
+	/**
+	 * Output components from frag shader.  It is possible to have
+	 * a fragment shader that only writes a subset of the bound
+	 * render targets.
+	 */
+	uint32_t mrt_components;
 };
 
 static inline struct fd6_program_state *



More information about the mesa-commit mailing list