a4xx: make sure to actually clamp depth as requested
authorIlia Mirkin <imirkin@alum.mit.edu>
Mon, 15 Aug 2016 03:58:18 +0000 (23:58 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 19 Aug 2016 23:40:04 +0000 (19:40 -0400)
We were previously ... not clamping. I guess this meant that everything
got clamped to 1/0, which was enough to pass the existing tests. Or
perhaps the clamping would only happen to the rasterized depth value and
not the frag shader's output depth value.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97231
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: mesa-stable@lists.freedesktop.org
src/gallium/drivers/freedreno/a4xx/a4xx.xml.h
src/gallium/drivers/freedreno/a4xx/fd4_emit.c

index a90a4ce90b1d47420615afbcd877a8be3ce38699..aeb61e75575871b466474f3d2e8d88d85722fba2 100644 (file)
@@ -1376,7 +1376,7 @@ static inline uint32_t A4XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val)
 {
        return ((val) << A4XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT) & A4XX_RB_DEPTH_CONTROL_ZFUNC__MASK;
 }
-#define A4XX_RB_DEPTH_CONTROL_BF_ENABLE                                0x00000080
+#define A4XX_RB_DEPTH_CONTROL_Z_CLAMP_ENABLE                   0x00000080
 #define A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE                  0x00010000
 #define A4XX_RB_DEPTH_CONTROL_FORCE_FRAGZ_TO_FS                        0x00020000
 #define A4XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE                    0x80000000
index e0f413f41e64f7e332d5d0430c087f81cf24adf4..fc0e4d11155037ed7e2b4845551e8b45befb8f00 100644 (file)
@@ -31,6 +31,7 @@
 #include "util/u_memory.h"
 #include "util/u_helpers.h"
 #include "util/u_format.h"
+#include "util/u_viewport.h"
 
 #include "freedreno_resource.h"
 #include "freedreno_query_hw.h"
@@ -550,12 +551,14 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                A4XX_RB_STENCILREFMASK_BF_STENCILREF(sr->ref_value[1]));
        }
 
-       if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) {
+       if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
                struct fd4_zsa_stateobj *zsa = fd4_zsa_stateobj(ctx->zsa);
                bool fragz = fp->has_kill | fp->writes_pos;
+               bool clamp = !ctx->rasterizer->depth_clip;
 
                OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
                OUT_RING(ring, zsa->rb_depth_control |
+                               COND(clamp, A4XX_RB_DEPTH_CONTROL_Z_CLAMP_ENABLE) |
                                COND(fragz, A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE) |
                                COND(fragz && fp->frag_coord, A4XX_RB_DEPTH_CONTROL_FORCE_FRAGZ_TO_FS));
 
@@ -642,6 +645,30 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(ctx->viewport.scale[2]));
        }
 
+       if (dirty & (FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
+               float zmin, zmax;
+               int depth = 24;
+               if (ctx->batch->framebuffer.zsbuf) {
+                       depth = util_format_get_component_bits(
+                                       pipe_surface_format(ctx->batch->framebuffer.zsbuf),
+                                       UTIL_FORMAT_COLORSPACE_ZS, 0);
+               }
+               util_viewport_zmin_zmax(&ctx->viewport, ctx->rasterizer->clip_halfz,
+                                                               &zmin, &zmax);
+
+               OUT_PKT0(ring, REG_A4XX_RB_VPORT_Z_CLAMP(0), 2);
+               if (depth == 32) {
+                       OUT_RING(ring, fui(zmin));
+                       OUT_RING(ring, fui(zmax));
+               } else if (depth == 16) {
+                       OUT_RING(ring, (uint32_t)(zmin * 0xffff));
+                       OUT_RING(ring, (uint32_t)(zmax * 0xffff));
+               } else {
+                       OUT_RING(ring, (uint32_t)(zmin * 0xffffff));
+                       OUT_RING(ring, (uint32_t)(zmax * 0xffffff));
+               }
+       }
+
        if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER)) {
                struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
                unsigned n = pfb->nr_cbufs;