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:
committed by
Marge Bot
parent
9aeaf99259
commit
beabd93c13
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user