freedreno/a6xx: Add ARB_depth_clamp and separate clamp support.

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>
This commit is contained in:
Eric Anholt 2020-09-01 12:09:40 -07:00 committed by Marge Bot
parent 5c0d34cee4
commit 0369dd9077
6 changed files with 69 additions and 38 deletions

View 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);

View 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
),

View 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);
}

View 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);

View 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);

View 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,