asahi,agx: use hw clip distance

rather than lowering in the fragment shader. this is what we're "supposed" to
do, what apple does, and it saves a byte of the fs key

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27616>
This commit is contained in:
Alyssa Rosenzweig
2024-01-27 15:45:56 -04:00
committed by Marge Bot
parent 9aeaf99259
commit beabd93c13
7 changed files with 75 additions and 14 deletions
+17 -3
View File
@@ -449,14 +449,18 @@ agx_emit_store_vary(agx_builder *b, nir_intrinsic_instr *instr)
unsigned imm_index = b->shader->out->varyings.vs.slots[sem.location];
if (sem.location == VARYING_SLOT_LAYER) {
if (sem.location == VARYING_SLOT_LAYER ||
sem.location == VARYING_SLOT_CLIP_DIST0) {
/* Separate slots used for the sysval vs the varying. The default slot
* above is for the varying. Change for the sysval.
*/
assert(sem.no_sysval_output || sem.no_varying);
if (sem.no_varying)
imm_index = b->shader->out->varyings.vs.layer_viewport_slot;
if (sem.no_varying) {
imm_index = sem.location == VARYING_SLOT_LAYER
? b->shader->out->varyings.vs.layer_viewport_slot
: b->shader->out->varyings.vs.clip_dist_slot;
}
}
assert(imm_index < ~0);
@@ -2589,6 +2593,12 @@ agx_remap_varyings_vs(nir_shader *nir, struct agx_varyings_vs *varyings,
base += 1;
}
if (nir->info.outputs_written & VARYING_BIT_CLIP_DIST0) {
varyings->clip_dist_slot = base;
varyings->nr_clip_dists = nir->info.clip_distance_array_size;
base += varyings->nr_clip_dists;
}
/* All varyings linked now */
varyings->nr_index = base;
}
@@ -3071,6 +3081,10 @@ agx_compile_shader_nir(nir_shader *nir, struct agx_shader_key *key,
if (nir->info.stage == MESA_SHADER_FRAGMENT)
out->tag_write_disable = !nir->info.writes_memory;
if (nir->info.stage == MESA_SHADER_VERTEX &&
(nir->info.outputs_written & VARYING_BIT_CLIP_DIST0))
NIR_PASS(_, nir, agx_nir_lower_clip_distance);
bool needs_libagx = nir->info.stage == MESA_SHADER_GEOMETRY;
/* Late tilebuffer lowering creates multisampled image stores */
+6
View File
@@ -46,6 +46,12 @@ struct agx_varyings_vs {
* is written. What's at slots[VARYING_SLOT_LAYER] is the varying output.
*/
unsigned layer_viewport_slot;
/* Base slot for the clip distance sysval outputs, or ~0 if none is written.
* What's at slots[VARYING_SLOT_CLIP_DIST0] is the varying output.
*/
unsigned clip_dist_slot;
unsigned nr_clip_dists;
};
/* Conservative bound, * 4 due to offsets (TODO: maybe worth eliminating
+1
View File
@@ -16,6 +16,7 @@ bool agx_nir_fuse_algebraic_late(struct nir_shader *shader);
bool agx_nir_fence_images(struct nir_shader *shader);
bool agx_nir_lower_multisampled_image_store(struct nir_shader *s);
bool agx_nir_lower_layer(struct nir_shader *s);
bool agx_nir_lower_clip_distance(struct nir_shader *s);
bool agx_nir_lower_cull_distance_vs(struct nir_shader *s);
bool agx_nir_lower_subgroups(struct nir_shader *s);
@@ -0,0 +1,42 @@
/*
* Copyright 2023 Valve Corporation
* SPDX-License-Identifier: MIT
*/
#include "compiler/nir/nir.h"
#include "compiler/nir/nir_builder.h"
#include "agx_nir.h"
static bool
lower(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
{
if (intr->intrinsic != nir_intrinsic_store_output)
return false;
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
if (sem.location != VARYING_SLOT_CLIP_DIST0)
return false;
nir_instr *clone = nir_instr_clone(b->shader, &intr->instr);
nir_intrinsic_instr *lowered = nir_instr_as_intrinsic(clone);
b->cursor = nir_after_instr(&intr->instr);
nir_builder_instr_insert(b, clone);
nir_io_semantics new_sem = sem;
new_sem.no_varying = true;
nir_intrinsic_set_io_semantics(lowered, new_sem);
sem.no_sysval_output = true;
nir_intrinsic_set_io_semantics(intr, sem);
return true;
}
bool
agx_nir_lower_clip_distance(nir_shader *s)
{
assert(s->info.outputs_written & VARYING_BIT_CLIP_DIST0);
return nir_shader_intrinsics_pass(
s, lower, nir_metadata_block_index | nir_metadata_dominance, NULL);
}
+1
View File
@@ -9,6 +9,7 @@ libasahi_agx_files = files(
'agx_insert_waits.c',
'agx_nir_fence_images.c',
'agx_nir_lower_address.c',
'agx_nir_lower_clip_distance.c',
'agx_nir_lower_cull_distance.c',
'agx_nir_lower_frag_sidefx.c',
'agx_nir_lower_sample_mask.c',