panfrost: Use early-ZS helpers

Remove the previous compile-time early-ZS implementation and replace it with the
decoupled early-ZS implementation. This uses more efficient settings in some
cases (depth/stencil tests always passes or do not write), and fixes the
settings used in another case (alpha-to-coverage enabled with an otherwise
early-ZS shader.)

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Closes: #6206
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17428>
This commit is contained in:
Alyssa Rosenzweig
2022-07-08 13:46:49 -04:00
committed by Marge Bot
parent 2454531de4
commit 3a0a8688d3
6 changed files with 51 additions and 59 deletions

View File

@@ -70,6 +70,9 @@ struct panfrost_zsa_state {
*/
bool zs_always_passes;
/* Are depth or stencil writes possible? */
bool writes_zs;
#if PAN_ARCH <= 7
/* Prepacked words from the RSD */
struct mali_multisample_misc_packed rsd_depth;
@@ -526,9 +529,21 @@ panfrost_prepare_fs_state(struct panfrost_context *ctx,
for (unsigned c = 0; c < rt_count; ++c)
has_blend_shader |= (blend_shaders[c] != 0);
bool has_oq = ctx->occlusion_query && ctx->active_queries;
pan_pack(rsd, RENDERER_STATE, cfg) {
if (panfrost_fs_required(fs, so, &ctx->pipe_framebuffer, zsa)) {
#if PAN_ARCH >= 6
struct pan_earlyzs_state earlyzs =
pan_earlyzs_get(fs->earlyzs,
ctx->depth_stencil->writes_zs ||
has_oq,
ctx->blend->base.alpha_to_coverage,
ctx->depth_stencil->zs_always_passes);
cfg.properties.pixel_kill_operation = earlyzs.kill;
cfg.properties.zs_update_operation = earlyzs.update;
cfg.properties.allow_forward_pixel_to_kill =
pan_allow_forward_pixel_to_kill(ctx, fs);
#else
@@ -544,7 +559,6 @@ panfrost_prepare_fs_state(struct panfrost_context *ctx,
/* Hardware quirks around early-zs forcing without a
* depth buffer. Note this breaks occlusion queries. */
bool has_oq = ctx->occlusion_query && ctx->active_queries;
bool force_ez_with_discard = !zsa->enabled && !has_oq;
cfg.properties.shader_reads_tilebuffer =
@@ -3326,9 +3340,16 @@ panfrost_emit_draw(void *out,
cfg.depth_stencil = batch->depth_stencil;
if (fs_required) {
struct pan_pixel_kill kill = pan_shader_classify_pixel_kill_coverage(&fs->info);
cfg.pixel_kill_operation = kill.pixel_kill;
cfg.zs_update_operation = kill.zs_update;
bool has_oq = ctx->occlusion_query && ctx->active_queries;
struct pan_earlyzs_state earlyzs =
pan_earlyzs_get(fs->earlyzs,
ctx->depth_stencil->writes_zs || has_oq,
ctx->blend->base.alpha_to_coverage,
ctx->depth_stencil->zs_always_passes);
cfg.pixel_kill_operation = earlyzs.kill;
cfg.zs_update_operation = earlyzs.update;
cfg.allow_forward_pixel_to_kill = pan_allow_forward_pixel_to_kill(ctx, fs);
cfg.allow_forward_pixel_to_be_killed = !fs->info.writes_global;
@@ -4449,6 +4470,7 @@ panfrost_create_depth_stencil_state(struct pipe_context *pipe,
(zsa->depth_enabled && zsa->depth_func != PIPE_FUNC_ALWAYS);
so->zs_always_passes = pipe_zs_always_passes(zsa);
so->writes_zs = util_writes_depth_stencil(zsa);
/* TODO: Bounds test should be easy */
assert(!zsa->depth_bounds_test);

View File

@@ -510,6 +510,8 @@ panfrost_new_variant_locked(
update_so_info(&shader_state->stream_output,
shader_state->info.outputs_written);
shader_state->earlyzs = pan_earlyzs_analyze(&shader_state->info);
return variant;
}

View File

@@ -33,6 +33,7 @@
#include "pan_blend_cso.h"
#include "pan_encoder.h"
#include "pan_texture.h"
#include "pan_earlyzs.h"
#include "pipe/p_compiler.h"
#include "pipe/p_config.h"
@@ -290,6 +291,8 @@ struct panfrost_shader_state {
struct pan_shader_info info;
struct pan_earlyzs_lut earlyzs;
/* Attached transform feedback program, if one exists */
struct panfrost_shader_state *xfb;

View File

@@ -259,8 +259,14 @@ pan_blitter_emit_rsd(const struct panfrost_device *dev,
cfg.stencil_back = cfg.stencil_front;
#if PAN_ARCH >= 6
/* Skipping ATEST requires forcing Z/S */
if (!zs) {
if (zs) {
/* Writing Z/S requires late updates */
cfg.properties.zs_update_operation =
MALI_PIXEL_KILL_FORCE_LATE;
cfg.properties.pixel_kill_operation =
MALI_PIXEL_KILL_FORCE_LATE;
} else {
/* Skipping ATEST requires forcing Z/S */
cfg.properties.zs_update_operation =
MALI_PIXEL_KILL_STRONG_EARLY;
cfg.properties.pixel_kill_operation =

View File

@@ -68,54 +68,6 @@ pan_register_allocation(unsigned work_reg_count)
}
#endif
#if PAN_ARCH >= 6
/* Classify a shader into the following pixel kill categories:
*
* (force early, strong early): no side effects/depth/stencil/coverage writes (force)
* (weak early, weak early): no side effects/depth/stencil/coverage writes
* (weak early, force late): no side effects/depth/stencil writes
* (force late, weak early): side effects but no depth/stencil/coverage writes
* (force late, force early): only run for side effects
* (force late, force late): depth/stencil writes
*
* Note that discard is considered a coverage write. TODO: what about
* alpha-to-coverage?
* */
struct pan_pixel_kill {
enum mali_pixel_kill pixel_kill;
enum mali_pixel_kill zs_update;
};
#define RETURN_PIXEL_KILL(kill, update) return (struct pan_pixel_kill) { \
MALI_PIXEL_KILL_## kill, MALI_PIXEL_KILL_## update \
}
static inline struct pan_pixel_kill
pan_shader_classify_pixel_kill_coverage(const struct pan_shader_info *info)
{
bool force_early = info->fs.early_fragment_tests;
bool sidefx = info->writes_global;
bool coverage = info->fs.writes_coverage || info->fs.can_discard;
bool depth = info->fs.writes_depth;
bool stencil = info->fs.writes_stencil;
if (force_early)
RETURN_PIXEL_KILL(FORCE_EARLY, STRONG_EARLY);
else if (depth || stencil || (sidefx && coverage))
RETURN_PIXEL_KILL(FORCE_LATE, FORCE_LATE);
else if (sidefx)
RETURN_PIXEL_KILL(FORCE_LATE, WEAK_EARLY);
else if (coverage)
RETURN_PIXEL_KILL(WEAK_EARLY, FORCE_LATE);
else
RETURN_PIXEL_KILL(WEAK_EARLY, WEAK_EARLY);
}
#undef RETURN_PIXEL_KILL
#endif
static inline enum mali_depth_source
pan_depth_source(const struct pan_shader_info *info)
{
@@ -229,11 +181,6 @@ pan_shader_prepare_bifrost_rsd(const struct pan_shader_info *info,
pan_make_preload(info->stage, info->preload, &rsd->preload);
if (info->stage == MESA_SHADER_FRAGMENT) {
struct pan_pixel_kill kill = pan_shader_classify_pixel_kill_coverage(info);
rsd->properties.pixel_kill_operation = kill.pixel_kill;
rsd->properties.zs_update_operation = kill.zs_update;
rsd->properties.shader_modifies_coverage =
info->fs.writes_coverage || info->fs.can_discard;

View File

@@ -32,6 +32,7 @@
#include "pan_encoder.h"
#include "pan_pool.h"
#include "pan_shader.h"
#include "pan_earlyzs.h"
#include "panvk_cs.h"
#include "panvk_private.h"
@@ -722,6 +723,17 @@ panvk_per_arch(emit_base_fs_rsd)(const struct panvk_device *dev,
!(rt_mask & ~rt_written) &&
!pipeline->ms.alpha_to_coverage &&
!pipeline->blend.reads_dest;
bool writes_zs = pipeline->zs.z_write || pipeline->zs.s_test;
bool zs_always_passes = !pipeline->zs.z_test && !pipeline->zs.s_test;
bool oq = false; /* TODO: Occlusion queries */
struct pan_earlyzs_state earlyzs =
pan_earlyzs_get(pan_earlyzs_analyze(info), writes_zs || oq,
pipeline->ms.alpha_to_coverage, zs_always_passes);
cfg.properties.pixel_kill_operation = earlyzs.kill;
cfg.properties.zs_update_operation = earlyzs.update;
} else {
cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
cfg.properties.allow_forward_pixel_to_kill = true;