agx: switch to combined clip/cull

don't swim against the tide.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29607>
This commit is contained in:
Alyssa Rosenzweig 2024-04-19 22:01:49 -04:00 committed by Marge Bot
parent 24bd46aa10
commit 8998034fa9
8 changed files with 50 additions and 26 deletions

View File

@ -508,7 +508,7 @@ cf_for_intrinsic(agx_builder *b, nir_intrinsic_instr *intr)
/* Determine the base location, taking into account a constant offset */
unsigned location = nir_intrinsic_io_semantics(intr).location;
bool compact = location == VARYING_SLOT_CLIP_DIST0 ||
location == VARYING_SLOT_CULL_DIST0;
location == VARYING_SLOT_CLIP_DIST1;
nir_src *offset = nir_get_io_offset_src(intr);
if (nir_src_is_const(*offset)) {
@ -3250,11 +3250,6 @@ agx_preprocess_nir(nir_shader *nir, const nir_shader *libagx)
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS(_, nir, agx_nir_lower_frag_sidefx);
} else if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL) {
if (nir->info.cull_distance_array_size)
NIR_PASS(_, nir, agx_nir_lower_cull_distance_vs);
}
/* Clean up deref gunk after lowering I/O */

View File

@ -236,6 +236,7 @@ bool agx_nir_lower_discard_zs_emit(nir_shader *s);
bool agx_nir_lower_sample_mask(nir_shader *s);
bool agx_nir_lower_interpolation(nir_shader *s);
bool agx_nir_lower_cull_distance_vs(struct nir_shader *s);
bool agx_nir_lower_cull_distance_fs(struct nir_shader *s,
unsigned nr_distances);

View File

@ -15,5 +15,4 @@ bool agx_nir_fuse_algebraic_late(struct nir_shader *shader);
bool agx_nir_fence_images(struct nir_shader *shader);
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);

View File

@ -9,6 +9,7 @@
#include "agx_compile.h"
#include "agx_nir.h"
#include "glsl_types.h"
#include "nir_builder_opcodes.h"
#include "shader_enums.h"
/*
@ -42,20 +43,32 @@ lower_write(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
return false;
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
if (sem.location != VARYING_SLOT_CULL_DIST0)
if (sem.location != VARYING_SLOT_CLIP_DIST0 &&
sem.location != VARYING_SLOT_CLIP_DIST1)
return false;
nir_instr *clone = nir_instr_clone(b->shader, &intr->instr);
nir_intrinsic_instr *lowered = nir_instr_as_intrinsic(clone);
signed loc = sem.location + nir_src_as_uint(intr->src[1]);
unsigned total_component =
(loc - VARYING_SLOT_CLIP_DIST0) * 4 + nir_intrinsic_component(intr);
b->cursor = nir_after_instr(&intr->instr);
unsigned base = b->shader->info.clip_distance_array_size;
if (total_component < base)
return false;
unsigned component = total_component - base;
if (component >= b->shader->info.cull_distance_array_size)
return false;
assert(nir_src_num_components(intr->src[0]) == 1 && "must be scalarized");
b->cursor = nir_before_instr(&intr->instr);
nir_def *offs = nir_imm_int(b, component / 4);
nir_def *v = nir_b2f32(b, nir_fge_imm(b, intr->src[0].ssa, 0.0));
nir_builder_instr_insert(b, clone);
nir_src_rewrite(&lowered->src[0], v);
sem.location = VARYING_SLOT_CULL_PRIMITIVE;
nir_intrinsic_set_io_semantics(lowered, sem);
nir_store_output(b, v, offs, .component = component % 4,
.src_type = nir_type_float32,
.io_semantics.location = VARYING_SLOT_CULL_PRIMITIVE,
.io_semantics.num_slots = 2);
return true;
}
@ -65,8 +78,6 @@ agx_nir_lower_cull_distance_vs(nir_shader *s)
assert(s->info.stage == MESA_SHADER_VERTEX ||
s->info.stage == MESA_SHADER_TESS_EVAL);
assert(s->info.outputs_written & VARYING_BIT_CULL_DIST0);
nir_shader_intrinsics_pass(
s, lower_write, nir_metadata_block_index | nir_metadata_dominance, NULL);

View File

@ -565,8 +565,9 @@ agx_nir_create_gs_rast_shader(const nir_shader *gs, const nir_shader *libagx)
/* We set NIR_COMPACT_ARRAYS so clip/cull distance needs to come all in
* DIST0. Undo the offset if we need to.
*/
assert(slot != VARYING_SLOT_CULL_DIST1);
unsigned offset = 0;
if (slot == VARYING_SLOT_CULL_DIST1 || slot == VARYING_SLOT_CLIP_DIST1)
if (slot == VARYING_SLOT_CLIP_DIST1)
offset = 1;
nir_store_output(b, value, nir_imm_int(b, offset),

View File

@ -80,14 +80,24 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
assert(ctx->viewport == NULL && "only written once");
ctx->viewport = value;
ctx->after_layer_viewport = nir_after_instr(index->parent_instr);
} else if (sem.location == VARYING_SLOT_CLIP_DIST0) {
unsigned clip_base = ctx->layout->group_offs[UVS_CLIP_DIST];
nir_def *index = nir_iadd_imm(b, nir_imul_imm(b, nir_u2u16(b, offset), 4),
clip_base + component);
} else if (sem.location == VARYING_SLOT_CLIP_DIST0 ||
sem.location == VARYING_SLOT_CLIP_DIST1) {
nir_store_uvs_agx(b, value, index);
unsigned clip_base = ctx->layout->group_offs[UVS_CLIP_DIST];
unsigned c = 4 * (sem.location - VARYING_SLOT_CLIP_DIST0) + component;
if (c < b->shader->info.clip_distance_array_size) {
nir_def *index = nir_iadd_imm(
b, nir_imul_imm(b, nir_u2u16(b, offset), 4), clip_base + c);
nir_store_uvs_agx(b, value, index);
}
}
/* Combined clip/cull used */
assert(sem.location != VARYING_SLOT_CULL_DIST0);
assert(sem.location != VARYING_SLOT_CULL_DIST1);
return true;
}

View File

@ -1543,7 +1543,6 @@ agx_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
case PIPE_CAP_FS_FINE_DERIVATIVE:
case PIPE_CAP_CULL_DISTANCE_NOCOMBINE:
case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
case PIPE_CAP_DOUBLES:
return 1;

View File

@ -58,6 +58,7 @@
#include "agx_device.h"
#include "agx_disk_cache.h"
#include "agx_linker.h"
#include "agx_nir.h"
#include "agx_nir_lower_gs.h"
#include "agx_nir_lower_vbo.h"
#include "agx_tilebuffer.h"
@ -1643,9 +1644,12 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx,
if (key->hw) {
NIR_PASS(_, nir, agx_nir_lower_point_size, true);
NIR_PASS(_, nir, nir_shader_intrinsics_pass, agx_nir_lower_clip_m1_1,
nir_metadata_block_index | nir_metadata_dominance, NULL);
NIR_PASS(_, nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL,
NULL);
NIR_PASS(_, nir, agx_nir_lower_cull_distance_vs);
NIR_PASS(_, nir, agx_nir_lower_uvs, &uvs);
} else {
NIR_PASS(_, nir, agx_nir_lower_vs_before_gs, dev->libagx, &outputs);
@ -1732,6 +1736,10 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx,
NIR_PASS(_, gs_copy, nir_shader_intrinsics_pass, agx_nir_lower_clip_m1_1,
nir_metadata_block_index | nir_metadata_dominance, NULL);
NIR_PASS(_, gs_copy, nir_lower_io_to_scalar, nir_var_shader_out, NULL,
NULL);
NIR_PASS(_, gs_copy, agx_nir_lower_cull_distance_vs);
struct agx_unlinked_uvs_layout uvs = {0};
NIR_PASS(_, gs_copy, agx_nir_lower_uvs, &uvs);