pan/compiler: Make lower_vs_outputs write needs_extended_fifo

Signed-off-by: Lorenzo Rossi <lorenzo.rossi@collabora.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40537>
This commit is contained in:
Lorenzo Rossi 2026-03-26 13:21:06 +01:00 committed by Marge Bot
parent 445a22acbd
commit 245d54397d
6 changed files with 47 additions and 43 deletions

View file

@ -6818,17 +6818,9 @@ bifrost_compile_shader_nir(nir_shader *nir,
if (info->vs.idvs && nir->info.writes_memory)
NIR_PASS(_, nir, bifrost_nir_lower_vs_atomics);
bool has_extended_fifo = false;
if (pan_arch(inputs->gpu_id) >= 9) {
const uint64_t outputs = nir->info.outputs_written;
has_extended_fifo = valhal_writes_extended_fifo(outputs, false, true);
/* Must be the same with and without no_psiz */
assert(valhal_writes_extended_fifo(outputs, true, true) ==
has_extended_fifo);
}
NIR_PASS(_, nir, pan_nir_lower_vs_outputs, inputs->gpu_id,
inputs->varying_layout, info->vs.idvs, has_extended_fifo);
inputs->varying_layout, info->vs.idvs,
&info->vs.needs_extended_fifo);
}
if (nir->info.stage == MESA_SHADER_FRAGMENT) {

View file

@ -80,30 +80,6 @@ void bifrost_compile_shader_nir(nir_shader *nir,
#define VALHAL_EX_FIFO_VARYING_BITS \
(VARYING_BIT_PSIZ | VARYING_BIT_LAYER | VARYING_BIT_PRIMITIVE_ID)
static inline bool
valhal_writes_extended_fifo(uint64_t outputs_written,
bool no_psiz, bool multiview)
{
uint64_t ex_fifo_written = outputs_written & VALHAL_EX_FIFO_VARYING_BITS;
if (ex_fifo_written == 0)
return false;
/* Multiview shaders depend on the FIFO format for indexing per-view
* output writes. We don't currently patch these offsets in the no_psiz
* variant, so we need the extended format, regardless of point size.
*/
if (multiview)
return true;
/* If we're not rendering in points mode, the no_psiz variant has point
* size write patched out for us.
*/
if (no_psiz)
ex_fifo_written &= ~VARYING_BIT_PSIZ;
return ex_fifo_written != 0;
}
#define DEFINE_OPTIONS(arch) \
static const nir_shader_compiler_options bifrost_nir_options_v##arch = { \
.lower_scmp = true, \

View file

@ -2985,7 +2985,7 @@ midgard_compile_shader_nir(nir_shader *nir,
if (nir->info.stage == MESA_SHADER_VERTEX) {
NIR_PASS(_, nir, pan_nir_lower_vs_outputs, inputs->gpu_id,
inputs->varying_layout, false /* has_idvs */,
false /* has_extended_fifo */);
NULL /* needs_extended_fifo */);
}
/* Optimisation passes */

View file

@ -193,10 +193,6 @@ pan_shader_update_info(struct pan_shader_info *info, nir_shader *s,
info->vs.writes_point_size =
s->info.outputs_written & VARYING_BIT_PSIZ;
info->vs.needs_extended_fifo = arch >= 9 &&
valhal_writes_extended_fifo(s->info.outputs_written,
true, inputs->view_mask != 0);
break;
case MESA_SHADER_FRAGMENT:
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))

View file

@ -57,7 +57,7 @@ bool pan_nir_lower_noperspective_fs(nir_shader *shader);
bool pan_nir_lower_vs_outputs(nir_shader *shader, unsigned gpu_id,
const struct pan_varying_layout *varying_layout,
bool has_idvs, bool has_extended_fifo);
bool has_idvs, bool *needs_extended_fifo);
bool pan_nir_lower_fs_inputs(nir_shader *shader, unsigned gpu_id,
const struct pan_varying_layout *varying_layout,

View file

@ -3,6 +3,7 @@
* SPDX-License-Identifier: MIT
*/
#include "bifrost_compile.h"
#include "pan_nir.h"
#include "nir_builder.h"
@ -19,8 +20,33 @@ struct lower_vs_outputs_ctx {
nir_variable *variables[PAN_MAX_VARYINGS];
uint8_t per_view_written[PAN_MAX_VARYINGS];
unsigned used_buckets;
bool uses_multiview;
};
static bool
valhal_writes_extended_fifo(uint64_t outputs_written,
bool no_psiz, bool multiview)
{
uint64_t ex_fifo_written = outputs_written & VALHAL_EX_FIFO_VARYING_BITS;
if (ex_fifo_written == 0)
return false;
/* Multiview shaders depend on the FIFO format for indexing per-view
* output writes. We don't currently patch these offsets in the no_psiz
* variant, so we need the extended format, regardless of point size.
*/
if (multiview)
return true;
/* If we're not rendering in points mode, the no_psiz variant has point
* size write patched out for us.
*/
if (no_psiz)
ex_fifo_written &= ~VARYING_BIT_PSIZ;
return ex_fifo_written != 0;
}
static void
build_attr_buf_write(struct nir_builder *b, nir_def *data, uint32_t idx,
uint32_t view_index,
@ -196,6 +222,7 @@ gather_vs_outputs(struct nir_builder *b,
ctx->per_view_written[slot_idx] |= BITFIELD_BIT(view_index);
ctx->used_buckets |= BITFIELD_BIT(va_shader_output_from_loc(sem.location));
ctx->uses_multiview |= is_per_view;
b->cursor = nir_instr_remove(&intr->instr);
nir_variable *var = get_or_create_var(b, ctx, intr);
@ -233,8 +260,7 @@ gather_vs_outputs(struct nir_builder *b,
bool
pan_nir_lower_vs_outputs(nir_shader *shader, unsigned gpu_id,
const struct pan_varying_layout *varying_layout,
bool has_idvs,
bool has_extended_fifo)
bool has_idvs, bool *needs_extended_fifo)
{
assert(shader->info.stage == MESA_SHADER_VERTEX);
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
@ -243,10 +269,11 @@ pan_nir_lower_vs_outputs(nir_shader *shader, unsigned gpu_id,
.arch = pan_arch(gpu_id),
.varying_layout = varying_layout,
.has_idvs = has_idvs,
.has_extended_fifo = has_extended_fifo,
.has_extended_fifo = false, /* computed after gather_vs_outputs */
.variables = {NULL, },
.per_view_written = {0, },
.used_buckets = 0,
.uses_multiview = false,
};
/* We use uint8 as a viewcount bitmask */
assert(PAN_MAX_MULTIVIEW_VIEW_COUNT <= 8 * sizeof(ctx.per_view_written[0]));
@ -256,6 +283,19 @@ pan_nir_lower_vs_outputs(nir_shader *shader, unsigned gpu_id,
if (!progress)
return false;
/* Should we use extended FIFO? */
if (ctx.arch >= 9) {
assert(needs_extended_fifo);
const uint64_t outputs = shader->info.outputs_written;
ctx.has_extended_fifo =
valhal_writes_extended_fifo(outputs, false, ctx.uses_multiview);
/* Export if we need ex_fifo even without psiz. The backend needs to
* know this because we can patch psiz out.
*/
*needs_extended_fifo =
valhal_writes_extended_fifo(outputs, true, ctx.uses_multiview);
}
nir_builder builder = nir_builder_at(nir_after_impl(impl));
nir_builder *b = &builder;
nir_def *shader_output = has_idvs ? nir_load_shader_output_pan(b) : NULL;