• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "compiler/nir/nir_builder.h"
7 #include "libagx/geometry.h"
8 #include "libagx/libagx.h"
9 #include "agx_nir_lower_gs.h"
10 #include "nir.h"
11 
12 /*
13  * This file implements basic input assembly in software. It runs on software
14  * vertex shaders, as part of geometry/tessellation lowering. It does not apply
15  * the topology, which happens in the geometry shader.
16  */
17 nir_def *
agx_nir_load_vertex_id(nir_builder * b,nir_def * id,unsigned index_size_B)18 agx_nir_load_vertex_id(nir_builder *b, nir_def *id, unsigned index_size_B)
19 {
20    /* If drawing with an index buffer, pull the vertex ID. Otherwise, the
21     * vertex ID is just the index as-is.
22     */
23    if (index_size_B) {
24       nir_def *ia = nir_load_input_assembly_buffer_agx(b);
25       id = libagx_load_index_buffer(b, ia, id, nir_imm_int(b, index_size_B));
26    }
27 
28    /* Add the "start", either an index bias or a base vertex. This must happen
29     * after indexing for proper index bias behaviour.
30     */
31    return nir_iadd(b, id, nir_load_first_vertex(b));
32 }
33 
34 static bool
lower(nir_builder * b,nir_intrinsic_instr * intr,void * data)35 lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
36 {
37    unsigned *index_size_B = data;
38    b->cursor = nir_before_instr(&intr->instr);
39 
40    if (intr->intrinsic == nir_intrinsic_load_vertex_id) {
41       nir_def *id = nir_channel(b, nir_load_global_invocation_id(b, 32), 0);
42       nir_def_replace(&intr->def, agx_nir_load_vertex_id(b, id, *index_size_B));
43       return true;
44    } else if (intr->intrinsic == nir_intrinsic_load_instance_id) {
45       nir_def_replace(&intr->def,
46                       nir_channel(b, nir_load_global_invocation_id(b, 32), 1));
47       return true;
48    }
49 
50    return false;
51 }
52 
53 bool
agx_nir_lower_sw_vs(nir_shader * s,unsigned index_size_B)54 agx_nir_lower_sw_vs(nir_shader *s, unsigned index_size_B)
55 {
56    return nir_shader_intrinsics_pass(s, lower, nir_metadata_control_flow,
57                                      &index_size_B);
58 }
59