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:

committed by
Marge Bot

parent
2454531de4
commit
3a0a8688d3
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 =
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user