1 /*
2 * Copyright 2023 Valve Corporation
3 * SPDX-License-Identifier: MIT
4 */
5 #include "agx_state.h"
6 #include "nir.h"
7 #include "nir_builder.h"
8
9 /*
10 * gl_PointSize lowering. This runs late on a vertex shader (epilogue). By this
11 * time, I/O has been lowered, and transform feedback has been written. Point
12 * size will thus only get consumed by the rasterizer, so we can clamp/replace.
13 * We do this instead of the mesa/st lowerings for better behaviour with lowered
14 * I/O and vertex epilogues.
15 */
16
17 static bool
pass(nir_builder * b,nir_intrinsic_instr * intr,void * data)18 pass(nir_builder *b, nir_intrinsic_instr *intr, void *data)
19 {
20 bool *fixed_point_size = data;
21 b->cursor = nir_before_instr(&intr->instr);
22
23 if ((intr->intrinsic != nir_intrinsic_store_output) ||
24 (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_PSIZ))
25 return false;
26
27 if (*fixed_point_size) {
28 /* We want to override point size. Remove this store. */
29 nir_instr_remove(&intr->instr);
30 } else {
31 /* We want to use this point size. Clamp it. */
32 nir_src_rewrite(&intr->src[0],
33 nir_fmax(b, intr->src[0].ssa, nir_imm_float(b, 1.0f)));
34 }
35
36 return true;
37 }
38
39 bool
agx_nir_lower_point_size(nir_shader * nir,bool fixed_point_size)40 agx_nir_lower_point_size(nir_shader *nir, bool fixed_point_size)
41 {
42 /* Handle existing point size write */
43 bool progress = nir_shader_intrinsics_pass(
44 nir, pass, nir_metadata_block_index | nir_metadata_dominance,
45 &fixed_point_size);
46
47 /* Write the fixed-function point size if we have one */
48 if (fixed_point_size) {
49 nir_builder b =
50 nir_builder_at(nir_after_impl(nir_shader_get_entrypoint(nir)));
51
52 nir_store_output(
53 &b, nir_load_fixed_point_size_agx(&b), nir_imm_int(&b, 0),
54 .io_semantics.location = VARYING_SLOT_PSIZ,
55 .io_semantics.num_slots = 1, .write_mask = nir_component_mask(1));
56
57 nir->info.outputs_written |= VARYING_BIT_PSIZ;
58 progress = true;
59 nir_metadata_preserve(b.impl,
60 nir_metadata_dominance | nir_metadata_block_index);
61 }
62
63 return progress;
64 }
65