#include "freedreno_log.h"
#include "freedreno_resource.h"
+#include "freedreno_state.h"
#include "freedreno_query_hw.h"
#include "common/freedreno_guardband.h"
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)) {
);
}
+ /* 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);
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
),
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;
}
{
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);
}
#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;
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 *
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);
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:
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);
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,