freedreno/a6xx: Add ARB_depth_clamp and separate clamp support.
authorEric Anholt <eric@anholt.net>
Tue, 1 Sep 2020 19:09:40 +0000 (12:09 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 1 Sep 2020 23:03:46 +0000 (23:03 +0000)
Passes piglit depth_clamp, depth-clamp-range,
amd_depth_clamp_separate_range.  This is part of enabling GL 3.2 (the
other is bumping PIPE_CAP_GLSL_FEATURE_LEVEL, which I'm hoping to do once
we have the KHR-GL* testing in place).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6544>

src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c
src/gallium/drivers/freedreno/a6xx/fd6_zsa.c
src/gallium/drivers/freedreno/a6xx/fd6_zsa.h
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_state.h

index fc1ea40e5c5b76d3b2824871336f0298b017b119..ff441126e19aae888083419943aaf2c5129dd529 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "freedreno_log.h"
 #include "freedreno_resource.h"
+#include "freedreno_state.h"
 #include "freedreno_query_hw.h"
 #include "common/freedreno_guardband.h"
 
@@ -823,13 +824,13 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
                fd6_emit_take_group(emit, state, FD6_GROUP_VBO, ENABLE_ALL);
        }
 
-       if (dirty & FD_DIRTY_ZSA) {
-               struct fd6_zsa_stateobj *zsa = fd6_zsa_stateobj(ctx->zsa);
+       if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER)) {
+               struct fd_ringbuffer *state =
+                       fd6_zsa_state(ctx,
+                                       util_format_is_pure_integer(pipe_surface_format(pfb->cbufs[0])),
+                                       fd_depth_clamp_enabled(ctx));
 
-               if (util_format_is_pure_integer(pipe_surface_format(pfb->cbufs[0])))
-                       fd6_emit_add_group(emit, zsa->stateobj_no_alpha, FD6_GROUP_ZSA, ENABLE_ALL);
-               else
-                       fd6_emit_add_group(emit, zsa->stateobj, FD6_GROUP_ZSA, ENABLE_ALL);
+               fd6_emit_add_group(emit, state, FD6_GROUP_ZSA, ENABLE_ALL);
        }
 
        if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_BLEND | FD_DIRTY_PROG)) {
@@ -919,6 +920,24 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
                        );
        }
 
+       /* The clamp ranges are only used when the rasterizer wants depth
+        * clamping.
+        */
+       if ((dirty & (FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER)) &&
+                       fd_depth_clamp_enabled(ctx)) {
+               float zmin, zmax;
+               util_viewport_zmin_zmax(&ctx->viewport, ctx->rasterizer->clip_halfz,
+                               &zmin, &zmax);
+
+               OUT_REG(ring,
+                               A6XX_GRAS_CL_Z_CLAMP_MIN(0, zmin),
+                               A6XX_GRAS_CL_Z_CLAMP_MAX(0, zmax));
+
+               OUT_REG(ring,
+                               A6XX_RB_Z_CLAMP_MIN(zmin),
+                               A6XX_RB_Z_CLAMP_MAX(zmax));
+       }
+
        if (dirty & FD_DIRTY_PROG) {
                fd6_emit_add_group(emit, prog->config_stateobj, FD6_GROUP_PROG_CONFIG, ENABLE_ALL);
                fd6_emit_add_group(emit, prog->stateobj, FD6_GROUP_PROG, ENABLE_DRAW);
index 33c96377a0abc812e0dea506541b5f3fa60a25c5..1f6bf70d904f42f6b5d8a93083363d2190dc53d8 100644 (file)
@@ -53,6 +53,9 @@ __fd6_setup_rasterizer_stateobj(struct fd_context *ctx,
 
        OUT_REG(ring,
                A6XX_GRAS_CL_CNTL(
+                       .znear_clip_disable = !cso->depth_clip_near,
+                       .zfar_clip_disable = !cso->depth_clip_far,
+                       .unk5 = !cso->depth_clip_near || !cso->depth_clip_far,
                        .vp_clip_code_ignore = 1,
                        .zero_gb_scale_z = cso->clip_halfz
                        ),
index dc7c1fbf087a44aeb5f4868b4b471c3ee4a56946..06625617118706800c995f34926fe04779b9a3ba 100644 (file)
@@ -200,37 +200,26 @@ fd6_zsa_state_create(struct pipe_context *pctx,
                        A6XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(cso->alpha.func);
        }
 
-       so->stateobj = fd_ringbuffer_new_object(ctx->pipe, 9 * 4);
-       struct fd_ringbuffer *ring = so->stateobj;
+       for (int i = 0; i < 4; i++) {
+               struct fd_ringbuffer *ring = fd_ringbuffer_new_object(ctx->pipe, 9 * 4);
 
-       OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1);
-       OUT_RING(ring, so->rb_alpha_control);
+               OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1);
+               OUT_RING(ring, (i & FD6_ZSA_NO_ALPHA) ? so->rb_alpha_control :
+                       so->rb_alpha_control & ~A6XX_RB_ALPHA_CONTROL_ALPHA_TEST);
 
-       OUT_PKT4(ring, REG_A6XX_RB_STENCIL_CONTROL, 1);
-       OUT_RING(ring, so->rb_stencil_control);
+               OUT_PKT4(ring, REG_A6XX_RB_STENCIL_CONTROL, 1);
+               OUT_RING(ring, so->rb_stencil_control);
 
-       OUT_PKT4(ring, REG_A6XX_RB_DEPTH_CNTL, 1);
-       OUT_RING(ring, so->rb_depth_cntl);
+               OUT_PKT4(ring, REG_A6XX_RB_DEPTH_CNTL, 1);
+               OUT_RING(ring, so->rb_depth_cntl |
+                               COND(i & FD6_ZSA_DEPTH_CLAMP, A6XX_RB_DEPTH_CNTL_Z_CLAMP_ENABLE));
 
-       OUT_PKT4(ring, REG_A6XX_RB_STENCILMASK, 2);
-       OUT_RING(ring, so->rb_stencilmask);
-       OUT_RING(ring, so->rb_stencilwrmask);
+               OUT_PKT4(ring, REG_A6XX_RB_STENCILMASK, 2);
+               OUT_RING(ring, so->rb_stencilmask);
+               OUT_RING(ring, so->rb_stencilwrmask);
 
-       so->stateobj_no_alpha = fd_ringbuffer_new_object(ctx->pipe, 9 * 4);
-       ring = so->stateobj_no_alpha;
-
-       OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1);
-       OUT_RING(ring, so->rb_alpha_control & ~A6XX_RB_ALPHA_CONTROL_ALPHA_TEST);
-
-       OUT_PKT4(ring, REG_A6XX_RB_STENCIL_CONTROL, 1);
-       OUT_RING(ring, so->rb_stencil_control);
-
-       OUT_PKT4(ring, REG_A6XX_RB_DEPTH_CNTL, 1);
-       OUT_RING(ring, so->rb_depth_cntl);
-
-       OUT_PKT4(ring, REG_A6XX_RB_STENCILMASK, 2);
-       OUT_RING(ring, so->rb_stencilmask);
-       OUT_RING(ring, so->rb_stencilwrmask);
+               so->stateobj[i] = ring;
+       }
 
        return so;
 }
@@ -240,7 +229,7 @@ fd6_depth_stencil_alpha_state_delete(struct pipe_context *pctx, void *hwcso)
 {
        struct fd6_zsa_stateobj *so = hwcso;
 
-       fd_ringbuffer_del(so->stateobj);
-       fd_ringbuffer_del(so->stateobj_no_alpha);
+       for (int i = 0; i < ARRAY_SIZE(so->stateobj); i++)
+               fd_ringbuffer_del(so->stateobj[i]);
        FREE(hwcso);
 }
index 2d39797116bb5aa080c71c95de465d99369cb582..b1c087e82cb68a3b620d3f6688438efd344b726d 100644 (file)
@@ -36,6 +36,9 @@
 
 #include "fd6_context.h"
 
+#define FD6_ZSA_NO_ALPHA    (1 << 0)
+#define FD6_ZSA_DEPTH_CLAMP (1 << 1)
+
 struct fd6_zsa_stateobj {
        struct pipe_depth_stencil_alpha_state base;
 
@@ -49,8 +52,7 @@ struct fd6_zsa_stateobj {
        bool invalidate_lrz;
        bool alpha_test;
 
-       struct fd_ringbuffer *stateobj;
-       struct fd_ringbuffer *stateobj_no_alpha;
+       struct fd_ringbuffer *stateobj[4];
 };
 
 static inline struct fd6_zsa_stateobj *
@@ -59,6 +61,17 @@ fd6_zsa_stateobj(struct pipe_depth_stencil_alpha_state *zsa)
        return (struct fd6_zsa_stateobj *)zsa;
 }
 
+static inline struct fd_ringbuffer *
+fd6_zsa_state(struct fd_context *ctx, bool no_alpha, bool depth_clamp)
+{
+       int variant = 0;
+       if (no_alpha)
+               variant |= FD6_ZSA_NO_ALPHA;
+       if (depth_clamp)
+               variant |= FD6_ZSA_DEPTH_CLAMP;
+       return fd6_zsa_stateobj(ctx->zsa)->stateobj[variant];
+}
+
 void * fd6_zsa_state_create(struct pipe_context *pctx,
                const struct pipe_depth_stencil_alpha_state *cso);
 
index f2b8eee9531526f7ca37fe51413eaaeefd1320ec..bea23999026a20601487abc71ff144f0a1d0f56d 100644 (file)
@@ -232,7 +232,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_PCI_BUS:
        case PIPE_CAP_PCI_DEVICE:
        case PIPE_CAP_PCI_FUNCTION:
-       case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
                return 0;
 
        case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
@@ -262,7 +261,10 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return is_a6xx(screen);
 
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
-               return is_a3xx(screen) || is_a4xx(screen);
+               return is_a3xx(screen) || is_a4xx(screen) || is_a6xx(screen);
+
+       case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+               return is_a6xx(screen);
 
        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
                return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
index 0d8d3368ad48cf6a25934df43eeb562a15928c01..ac65c44921db88b8990625be483c71cb92f7b534 100644 (file)
@@ -55,6 +55,11 @@ static inline bool fd_blend_enabled(struct fd_context *ctx, unsigned n)
        return ctx->blend && ctx->blend->rt[n].blend_enable;
 }
 
+static inline bool fd_depth_clamp_enabled(struct fd_context *ctx)
+{
+       return !(ctx->rasterizer->depth_clip_near && ctx->rasterizer->depth_clip_far);
+}
+
 void fd_set_shader_images(struct pipe_context *pctx,
                enum pipe_shader_type shader,
                unsigned start, unsigned count,