/* Reasons to disable early-Z from a shader perspective */
bool late_z = fs->info.fs.can_discard || fs->info.writes_global ||
fs->info.fs.writes_depth || fs->info.fs.writes_stencil ||
- (zsa->alpha_func != MALI_FUNC_ALWAYS);
-
- /* If either depth or stencil is enabled, discard matters */
- bool zs_enabled =
- (zsa->base.depth_enabled && zsa->base.depth_func != PIPE_FUNC_ALWAYS) ||
- zsa->base.stencil[0].enabled;
+ ((enum mali_func) zsa->base.alpha_func != MALI_FUNC_ALWAYS);
bool has_blend_shader = false;
* reads tilebuffer? flag to compensate */
state->properties.midgard.shader_reads_tilebuffer =
fs->info.fs.outputs_read ||
- (!zs_enabled && fs->info.fs.can_discard);
+ (!zsa->enabled && fs->info.fs.can_discard);
state->properties.midgard.shader_contains_discard =
- zs_enabled && fs->info.fs.can_discard;
+ zsa->enabled && fs->info.fs.can_discard;
}
if (dev->quirks & MIDGARD_SFBD && ctx->pipe_framebuffer.nr_cbufs > 0) {
state->multisample_misc.evaluate_per_sample =
msaa && (ctx->min_samples > 1 || fs->info.fs.sample_shading);
- state->multisample_misc.depth_function = zsa->base.depth_enabled ?
- (enum mali_func) zsa->base.depth_func : MALI_FUNC_ALWAYS;
-
- state->multisample_misc.depth_write_mask = zsa->base.depth_writemask;
state->multisample_misc.fixed_function_near_discard = rast->depth_clip_near;
state->multisample_misc.fixed_function_far_discard = rast->depth_clip_far;
state->multisample_misc.shader_depth_range_fixed = true;
- state->stencil_mask_misc.stencil_mask_front = zsa->stencil_mask_front;
- state->stencil_mask_misc.stencil_mask_back = zsa->stencil_mask_back;
- state->stencil_mask_misc.stencil_enable = zsa->base.stencil[0].enabled;
state->stencil_mask_misc.alpha_to_coverage = alpha_to_coverage;
- state->stencil_mask_misc.alpha_test_compare_function = zsa->alpha_func;
state->stencil_mask_misc.depth_range_1 = rast->offset_tri;
state->stencil_mask_misc.depth_range_2 = rast->offset_tri;
state->stencil_mask_misc.single_sampled_lines = !rast->multisample;
state->depth_factor = rast->offset_scale;
bool back_enab = zsa->base.stencil[1].enabled;
- state->stencil_front = zsa->stencil_front;
- state->stencil_back = zsa->stencil_back;
state->stencil_front.reference_value = ctx->stencil_ref.ref_value[0];
state->stencil_back.reference_value = ctx->stencil_ref.ref_value[back_enab ? 1 : 0];
mali_ptr *blend_shaders)
{
struct panfrost_device *dev = pan_device(ctx->base.screen);
+ const struct panfrost_zsa_state *zsa = ctx->depth_stencil;
struct panfrost_shader_state *fs =
panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
if (panfrost_fs_required(fs, ctx->blend, &ctx->pipe_framebuffer))
pan_merge(rsd, fs->partial_rsd, RENDERER_STATE);
+ /* Word 8, 9 Misc state */
+ rsd.opaque[8] |= zsa->rsd_depth.opaque[0];
+ rsd.opaque[9] |= zsa->rsd_stencil.opaque[0];
+
+ /* Word 10, 11 Stencil Front and Back */
+ rsd.opaque[10] |= zsa->stencil_front.opaque[0];
+ rsd.opaque[11] |= zsa->stencil_back.opaque[0];
+
memcpy(fragmeta, &rsd, sizeof(rsd));
}
}
static inline void
-pan_pipe_to_stencil(const struct pipe_stencil_state *in, struct MALI_STENCIL *out)
-{
- pan_prepare(out, STENCIL);
- out->mask = in->valuemask;
- out->compare_function = (enum mali_func) in->func;
- out->stencil_fail = pan_pipe_to_stencil_op(in->fail_op);
- out->depth_fail = pan_pipe_to_stencil_op(in->zfail_op);
- out->depth_pass = pan_pipe_to_stencil_op(in->zpass_op);
+pan_pipe_to_stencil(const struct pipe_stencil_state *in,
+ struct mali_stencil_packed *out)
+{
+ pan_pack(out, STENCIL, s) {
+ s.mask = in->valuemask;
+ s.compare_function = (enum mali_func) in->func;
+ s.stencil_fail = pan_pipe_to_stencil_op(in->fail_op);
+ s.depth_fail = pan_pipe_to_stencil_op(in->zfail_op);
+ s.depth_pass = pan_pipe_to_stencil_op(in->zpass_op);
+ }
}
static void *
panfrost_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *zsa)
{
+ struct panfrost_device *dev = pan_device(pipe->screen);
struct panfrost_zsa_state *so = CALLOC_STRUCT(panfrost_zsa_state);
so->base = *zsa;
+ /* Normalize (there's no separate enable) */
+ if (!zsa->alpha_enabled)
+ so->base.alpha_func = MALI_FUNC_ALWAYS;
+
+ /* Prepack relevant parts of the Renderer State Descriptor. They will
+ * be ORed in at draw-time */
+ pan_pack(&so->rsd_depth, MULTISAMPLE_MISC, cfg) {
+ cfg.depth_function = zsa->depth_enabled ?
+ (enum mali_func) zsa->depth_func : MALI_FUNC_ALWAYS;
+
+ cfg.depth_write_mask = zsa->depth_writemask;
+ }
+
+ pan_pack(&so->rsd_stencil, STENCIL_MASK_MISC, cfg) {
+ cfg.stencil_enable = zsa->stencil[0].enabled;
+
+ cfg.stencil_mask_front = zsa->stencil[0].writemask;
+ cfg.stencil_mask_back = zsa->stencil[1].enabled ?
+ zsa->stencil[1].writemask : zsa->stencil[0].writemask;
+
+ if (dev->arch < 6) {
+ cfg.alpha_test_compare_function =
+ (enum mali_func) so->base.alpha_func;
+ }
+ }
+
+ /* Stencil tests have their own words in the RSD */
pan_pipe_to_stencil(&zsa->stencil[0], &so->stencil_front);
- so->stencil_mask_front = zsa->stencil[0].writemask;
- if (zsa->stencil[1].enabled) {
+ if (zsa->stencil[1].enabled)
pan_pipe_to_stencil(&zsa->stencil[1], &so->stencil_back);
- so->stencil_mask_back = zsa->stencil[1].writemask;
- } else {
+ else
so->stencil_back = so->stencil_front;
- so->stencil_mask_back = so->stencil_mask_front;
- }
- so->alpha_func = zsa->alpha_enabled ?
- (enum mali_func) zsa->alpha_func : MALI_FUNC_ALWAYS;
+ so->enabled = zsa->stencil[0].enabled ||
+ (zsa->depth_enabled && zsa->depth_func != PIPE_FUNC_ALWAYS);
/* TODO: Bounds test should be easy */
assert(!zsa->depth_bounds_test);
struct panfrost_zsa_state {
struct pipe_depth_stencil_alpha_state base;
- enum mali_func alpha_func;
- /* Precomputed stencil state */
- struct MALI_STENCIL stencil_front;
- struct MALI_STENCIL stencil_back;
- u8 stencil_mask_front;
- u8 stencil_mask_back;
+ /* Is any depth, stencil, or alpha testing enabled? */
+ bool enabled;
+
+ /* Prepacked words from the RSD */
+ struct mali_multisample_misc_packed rsd_depth;
+ struct mali_stencil_mask_misc_packed rsd_stencil;
+ struct mali_stencil_packed stencil_front, stencil_back;
};
struct panfrost_sampler_state {