[Mesa-dev] [PATCH 03/18] gallium/radeon: add a workaround when viewport state is used to force Z
Marek Olšák
maraeo at gmail.com
Thu Aug 17 18:31:24 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
This will be needed by u_blitter.
---
src/gallium/drivers/radeon/r600_viewport.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/radeon/r600_viewport.c b/src/gallium/drivers/radeon/r600_viewport.c
index 2de1382..f7fc536 100644
--- a/src/gallium/drivers/radeon/r600_viewport.c
+++ b/src/gallium/drivers/radeon/r600_viewport.c
@@ -316,50 +316,69 @@ static void r600_emit_viewports(struct r600_common_context *rctx)
u_bit_scan_consecutive_range(&mask, &start, &count);
radeon_set_context_reg_seq(cs, R_02843C_PA_CL_VPORT_XSCALE +
start * 4 * 6, count * 6);
for (i = start; i < start+count; i++)
r600_emit_one_viewport(rctx, &states[i]);
}
rctx->viewports.dirty_mask = 0;
}
+static void r600_get_zmin_zmax(const struct pipe_viewport_state *vp,
+ bool clip_halfz, float *zmin, float *zmax)
+{
+ /* For some reason, setting zmin == zmax breaks things.
+ * Setting zmin = 0 && zmin = 1 works around it.
+ * u_blitter sets scale = 0 && translate = Z to force a certain Z
+ * value. The clamp would have no effect anyway, but it would be nice
+ * to know what the problem is with zmin == zmax.
+ */
+ if (vp->scale[2] == 0) {
+ assert(vp->translate[2] >= 0 && vp->translate[2] <= 1);
+ *zmin = 0;
+ *zmax = 1;
+ return;
+ }
+
+ util_viewport_zmin_zmax(vp, clip_halfz, zmin, zmax);
+}
+
static void r600_emit_depth_ranges(struct r600_common_context *rctx)
{
struct radeon_winsys_cs *cs = rctx->gfx.cs;
struct pipe_viewport_state *states = rctx->viewports.states;
unsigned mask = rctx->viewports.depth_range_dirty_mask;
float zmin, zmax;
/* The simple case: Only 1 viewport is active. */
if (!rctx->vs_writes_viewport_index) {
if (!(mask & 1))
return;
- util_viewport_zmin_zmax(&states[0], rctx->clip_halfz, &zmin, &zmax);
+ r600_get_zmin_zmax(&states[0], rctx->clip_halfz, &zmin, &zmax);
radeon_set_context_reg_seq(cs, R_0282D0_PA_SC_VPORT_ZMIN_0, 2);
radeon_emit(cs, fui(zmin));
radeon_emit(cs, fui(zmax));
rctx->viewports.depth_range_dirty_mask &= ~1; /* clear one bit */
return;
}
while (mask) {
int start, count, i;
u_bit_scan_consecutive_range(&mask, &start, &count);
radeon_set_context_reg_seq(cs, R_0282D0_PA_SC_VPORT_ZMIN_0 +
start * 4 * 2, count * 2);
for (i = start; i < start+count; i++) {
- util_viewport_zmin_zmax(&states[i], rctx->clip_halfz, &zmin, &zmax);
+ r600_get_zmin_zmax(&states[i], rctx->clip_halfz, &zmin, &zmax);
radeon_emit(cs, fui(zmin));
radeon_emit(cs, fui(zmax));
}
}
rctx->viewports.depth_range_dirty_mask = 0;
}
static void r600_emit_viewport_states(struct r600_common_context *rctx,
struct r600_atom *atom)
{
--
2.7.4
More information about the mesa-dev
mailing list