• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Valve Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "ac_nir.h"
8 #include "ac_nir_helpers.h"
9 
10 #include "nir_builder.h"
11 
12 static void
gather_outputs(nir_builder * b,nir_function_impl * impl,ac_nir_prerast_out * out)13 gather_outputs(nir_builder *b, nir_function_impl *impl, ac_nir_prerast_out *out)
14 {
15    /* Assume:
16     * - the shader used nir_lower_io_to_temporaries
17     * - 64-bit outputs are lowered
18     * - no indirect indexing is present
19     */
20    nir_foreach_block (block, impl) {
21       nir_foreach_instr_safe (instr, block) {
22          if (instr->type != nir_instr_type_intrinsic)
23             continue;
24 
25          nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
26          if (intrin->intrinsic != nir_intrinsic_store_output)
27             continue;
28 
29          ac_nir_gather_prerast_store_output_info(b, intrin, out);
30          nir_instr_remove(instr);
31       }
32    }
33 }
34 
35 void
ac_nir_lower_legacy_vs(nir_shader * nir,enum amd_gfx_level gfx_level,uint32_t clip_cull_mask,const uint8_t * param_offsets,bool has_param_exports,bool export_primitive_id,bool disable_streamout,bool kill_pointsize,bool kill_layer,bool force_vrs)36 ac_nir_lower_legacy_vs(nir_shader *nir,
37                        enum amd_gfx_level gfx_level,
38                        uint32_t clip_cull_mask,
39                        const uint8_t *param_offsets,
40                        bool has_param_exports,
41                        bool export_primitive_id,
42                        bool disable_streamout,
43                        bool kill_pointsize,
44                        bool kill_layer,
45                        bool force_vrs)
46 {
47    nir_function_impl *impl = nir_shader_get_entrypoint(nir);
48    nir_metadata preserved = nir_metadata_control_flow;
49 
50    nir_builder b = nir_builder_at(nir_after_impl(impl));
51 
52    ac_nir_prerast_out out = {0};
53    gather_outputs(&b, impl, &out);
54    b.cursor = nir_after_impl(impl);
55 
56    if (export_primitive_id) {
57       /* When the primitive ID is read by FS, we must ensure that it's exported by the previous
58        * vertex stage because it's implicit for VS or TES (but required by the Vulkan spec for GS
59        * or MS).
60        */
61       out.outputs[VARYING_SLOT_PRIMITIVE_ID][0] = nir_load_primitive_id(&b);
62       out.infos[VARYING_SLOT_PRIMITIVE_ID].as_varying_mask = 0x1;
63 
64       /* Update outputs_written to reflect that the pass added a new output. */
65       nir->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID);
66    }
67 
68    if (!disable_streamout && nir->xfb_info) {
69       ac_nir_emit_legacy_streamout(&b, 0, ac_nir_get_sorted_xfb_info(nir), &out);
70       preserved = nir_metadata_none;
71    }
72 
73    uint64_t export_outputs = nir->info.outputs_written | VARYING_BIT_POS;
74    if (kill_pointsize)
75       export_outputs &= ~VARYING_BIT_PSIZ;
76    if (kill_layer)
77       export_outputs &= ~VARYING_BIT_LAYER;
78 
79    ac_nir_export_position(&b, gfx_level, clip_cull_mask, !has_param_exports,
80                           force_vrs, true, export_outputs, &out, NULL);
81 
82    if (has_param_exports) {
83       ac_nir_export_parameters(&b, param_offsets,
84                                nir->info.outputs_written,
85                                nir->info.outputs_written_16bit,
86                                &out);
87    }
88 
89    nir_metadata_preserve(impl, preserved);
90 }
91