2 * Copyright © 2019 Google, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include "ir3_compiler.h"
26 #include "compiler/nir/nir_builder.h"
29 struct primitive_map
{
37 nir_variable
*vertex_count_var
;
38 nir_variable
*emitted_vertex_var
;
39 nir_variable
*vertex_flags_var
;
40 nir_variable
*vertex_flags_out
;
42 nir_variable
*output_vars
[32];
46 bitfield_extract(nir_builder
*b
, nir_ssa_def
*v
, uint32_t start
, uint32_t mask
)
48 return nir_iand(b
, nir_ushr(b
, v
, nir_imm_int(b
, start
)),
49 nir_imm_int(b
, mask
));
53 build_invocation_id(nir_builder
*b
, struct state
*state
)
55 return bitfield_extract(b
, state
->header
, 11, 31);
59 build_vertex_id(nir_builder
*b
, struct state
*state
)
61 return bitfield_extract(b
, state
->header
, 6, 31);
65 build_local_primitive_id(nir_builder
*b
, struct state
*state
)
67 return bitfield_extract(b
, state
->header
, 0, 63);
71 get_var(struct exec_list
*list
, int driver_location
)
73 nir_foreach_variable(v
, list
) {
74 if (v
->data
.driver_location
== driver_location
) {
83 build_local_offset(nir_builder
*b
, struct state
*state
,
84 nir_ssa_def
*vertex
, uint32_t base
, nir_ssa_def
*offset
)
86 nir_ssa_def
*primitive_stride
= nir_load_vs_primitive_stride_ir3(b
);
87 nir_ssa_def
*primitive_offset
=
88 nir_imul(b
, build_local_primitive_id(b
, state
), primitive_stride
);
89 nir_ssa_def
*attr_offset
;
90 nir_ssa_def
*vertex_stride
;
92 if (b
->shader
->info
.stage
== MESA_SHADER_VERTEX
) {
93 vertex_stride
= nir_imm_int(b
, state
->map
.stride
* 4);
94 attr_offset
= nir_imm_int(b
, state
->map
.loc
[base
] * 4);
95 } else if (b
->shader
->info
.stage
== MESA_SHADER_GEOMETRY
) {
96 vertex_stride
= nir_load_vs_vertex_stride_ir3(b
);
97 attr_offset
= nir_load_primitive_location_ir3(b
, base
);
99 unreachable("bad shader stage");
102 nir_ssa_def
*vertex_offset
= nir_imul(b
, vertex
, vertex_stride
);
104 return nir_iadd(b
, nir_iadd(b
, primitive_offset
, vertex_offset
),
105 nir_iadd(b
, attr_offset
, offset
));
108 static nir_intrinsic_instr
*
109 replace_intrinsic(nir_builder
*b
, nir_intrinsic_instr
*intr
,
110 nir_intrinsic_op op
, nir_ssa_def
*src0
, nir_ssa_def
*src1
, nir_ssa_def
*src2
)
112 nir_intrinsic_instr
*new_intr
=
113 nir_intrinsic_instr_create(b
->shader
, op
);
115 new_intr
->src
[0] = nir_src_for_ssa(src0
);
117 new_intr
->src
[1] = nir_src_for_ssa(src1
);
119 new_intr
->src
[2] = nir_src_for_ssa(src2
);
121 new_intr
->num_components
= intr
->num_components
;
123 if (nir_intrinsic_infos
[op
].has_dest
)
124 nir_ssa_dest_init(&new_intr
->instr
, &new_intr
->dest
,
125 intr
->num_components
, 32, NULL
);
127 nir_builder_instr_insert(b
, &new_intr
->instr
);
129 if (nir_intrinsic_infos
[op
].has_dest
)
130 nir_ssa_def_rewrite_uses(&intr
->dest
.ssa
, nir_src_for_ssa(&new_intr
->dest
.ssa
));
132 nir_instr_remove(&intr
->instr
);
138 build_primitive_map(nir_shader
*shader
, struct primitive_map
*map
, struct exec_list
*list
)
140 nir_foreach_variable(var
, list
) {
141 switch (var
->data
.location
) {
142 case VARYING_SLOT_TESS_LEVEL_OUTER
:
143 case VARYING_SLOT_TESS_LEVEL_INNER
:
147 unsigned size
= glsl_count_attribute_slots(var
->type
, false) * 4;
149 assert(var
->data
.driver_location
< ARRAY_SIZE(map
->size
));
150 map
->size
[var
->data
.driver_location
] =
151 MAX2(map
->size
[var
->data
.driver_location
], size
);
155 for (uint32_t i
= 0; i
< ARRAY_SIZE(map
->size
); i
++) {
156 if (map
->size
[i
] == 0)
158 nir_variable
*var
= get_var(list
, i
);
165 map
->size
[i
] = map
->size
[i
] / glsl_get_length(var
->type
);
172 lower_vs_block(nir_block
*block
, nir_builder
*b
, struct state
*state
)
174 nir_foreach_instr_safe(instr
, block
) {
175 if (instr
->type
!= nir_instr_type_intrinsic
)
178 nir_intrinsic_instr
*intr
= nir_instr_as_intrinsic(instr
);
180 switch (intr
->intrinsic
) {
181 case nir_intrinsic_store_output
: {
182 // src[] = { value, offset }.
184 b
->cursor
= nir_before_instr(&intr
->instr
);
186 nir_ssa_def
*vertex_id
= build_vertex_id(b
, state
);
187 nir_ssa_def
*offset
= build_local_offset(b
, state
, vertex_id
, nir_intrinsic_base(intr
),
189 nir_intrinsic_instr
*store
=
190 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_shared_ir3
);
192 nir_intrinsic_set_write_mask(store
, MASK(intr
->num_components
));
193 store
->src
[0] = nir_src_for_ssa(intr
->src
[0].ssa
);
194 store
->src
[1] = nir_src_for_ssa(offset
);
196 store
->num_components
= intr
->num_components
;
198 nir_builder_instr_insert(b
, &store
->instr
);
209 local_thread_id(nir_builder
*b
)
211 return bitfield_extract(b
, nir_load_gs_header_ir3(b
), 16, 1023);
215 ir3_nir_lower_vs_to_explicit_io(nir_shader
*shader
, struct ir3_shader
*s
)
217 struct state state
= { };
219 build_primitive_map(shader
, &state
.map
, &shader
->outputs
);
220 memcpy(s
->output_loc
, state
.map
.loc
, sizeof(s
->output_loc
));
222 nir_function_impl
*impl
= nir_shader_get_entrypoint(shader
);
226 nir_builder_init(&b
, impl
);
227 b
.cursor
= nir_before_cf_list(&impl
->body
);
229 state
.header
= nir_load_gs_header_ir3(&b
);
231 nir_foreach_block_safe(block
, impl
)
232 lower_vs_block(block
, &b
, &state
);
234 nir_metadata_preserve(impl
, nir_metadata_block_index
|
235 nir_metadata_dominance
);
237 s
->output_size
= state
.map
.stride
;
241 lower_gs_block(nir_block
*block
, nir_builder
*b
, struct state
*state
)
243 nir_intrinsic_instr
*outputs
[32] = {};
245 nir_foreach_instr_safe(instr
, block
) {
246 if (instr
->type
!= nir_instr_type_intrinsic
)
249 nir_intrinsic_instr
*intr
= nir_instr_as_intrinsic(instr
);
251 switch (intr
->intrinsic
) {
252 case nir_intrinsic_store_output
: {
253 // src[] = { value, offset }.
255 uint32_t loc
= nir_intrinsic_base(intr
);
260 case nir_intrinsic_end_primitive
: {
261 b
->cursor
= nir_before_instr(&intr
->instr
);
262 nir_store_var(b
, state
->vertex_flags_var
, nir_imm_int(b
, 4), 0x1);
263 nir_instr_remove(&intr
->instr
);
267 case nir_intrinsic_emit_vertex
: {
269 /* Load the vertex count */
270 b
->cursor
= nir_before_instr(&intr
->instr
);
271 nir_ssa_def
*count
= nir_load_var(b
, state
->vertex_count_var
);
273 nir_push_if(b
, nir_ieq(b
, count
, local_thread_id(b
)));
275 for (uint32_t i
= 0; i
< ARRAY_SIZE(outputs
); i
++) {
277 nir_store_var(b
, state
->output_vars
[i
],
278 outputs
[i
]->src
[0].ssa
,
279 (1 << outputs
[i
]->num_components
) - 1);
281 nir_instr_remove(&outputs
[i
]->instr
);
286 nir_instr_remove(&intr
->instr
);
288 nir_store_var(b
, state
->emitted_vertex_var
,
289 nir_iadd(b
, nir_load_var(b
, state
->emitted_vertex_var
), nir_imm_int(b
, 1)), 0x1);
291 nir_store_var(b
, state
->vertex_flags_out
,
292 nir_load_var(b
, state
->vertex_flags_var
), 0x1);
296 /* Increment the vertex count by 1 */
297 nir_store_var(b
, state
->vertex_count_var
,
298 nir_iadd(b
, count
, nir_imm_int(b
, 1)), 0x1); /* .x */
299 nir_store_var(b
, state
->vertex_flags_var
, nir_imm_int(b
, 0), 0x1);
304 case nir_intrinsic_load_per_vertex_input
: {
305 // src[] = { vertex, offset }.
307 b
->cursor
= nir_before_instr(&intr
->instr
);
309 nir_ssa_def
*offset
= build_local_offset(b
, state
,
310 intr
->src
[0].ssa
, // this is typically gl_InvocationID
311 nir_intrinsic_base(intr
),
314 replace_intrinsic(b
, intr
, nir_intrinsic_load_shared_ir3
, offset
, NULL
, NULL
);
318 case nir_intrinsic_load_invocation_id
: {
319 b
->cursor
= nir_before_instr(&intr
->instr
);
321 nir_ssa_def
*iid
= build_invocation_id(b
, state
);
322 nir_ssa_def_rewrite_uses(&intr
->dest
.ssa
, nir_src_for_ssa(iid
));
323 nir_instr_remove(&intr
->instr
);
334 emit_store_outputs(nir_builder
*b
, struct state
*state
)
336 /* This also stores the internally added vertex_flags output. */
338 for (uint32_t i
= 0; i
< ARRAY_SIZE(state
->output_vars
); i
++) {
339 if (!state
->output_vars
[i
])
342 nir_intrinsic_instr
*store
=
343 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_output
);
345 nir_intrinsic_set_base(store
, i
);
346 store
->src
[0] = nir_src_for_ssa(nir_load_var(b
, state
->output_vars
[i
]));
347 store
->src
[1] = nir_src_for_ssa(nir_imm_int(b
, 0));
348 store
->num_components
= store
->src
[0].ssa
->num_components
;
350 nir_builder_instr_insert(b
, &store
->instr
);
355 clean_up_split_vars(nir_shader
*shader
, struct exec_list
*list
)
357 uint32_t components
[32] = {};
359 nir_foreach_variable(var
, list
) {
361 ((1 << glsl_get_components(glsl_without_array(var
->type
))) - 1) << var
->data
.location_frac
;
362 components
[var
->data
.driver_location
] |= mask
;
365 nir_foreach_variable_safe(var
, list
) {
367 ((1 << glsl_get_components(glsl_without_array(var
->type
))) - 1) << var
->data
.location_frac
;
369 (components
[var
->data
.driver_location
] | mask
) != mask
;
371 exec_node_remove(&var
->node
);
376 ir3_nir_lower_gs(nir_shader
*shader
, struct ir3_shader
*s
)
378 struct state state
= { };
380 if (shader_debug_enabled(shader
->info
.stage
)) {
381 fprintf(stderr
, "NIR (before gs lowering):\n");
382 nir_print_shader(shader
, stderr
);
385 clean_up_split_vars(shader
, &shader
->inputs
);
386 clean_up_split_vars(shader
, &shader
->outputs
);
388 build_primitive_map(shader
, &state
.map
, &shader
->inputs
);
391 nir_foreach_variable(var
, &shader
->outputs
) {
392 uint32_t end
= var
->data
.driver_location
+ glsl_count_attribute_slots(var
->type
, false);
393 loc
= MAX2(loc
, end
);
396 state
.vertex_flags_out
= nir_variable_create(shader
, nir_var_shader_out
,
397 glsl_uint_type(), "vertex_flags");
398 state
.vertex_flags_out
->data
.driver_location
= loc
;
399 state
.vertex_flags_out
->data
.location
= VARYING_SLOT_GS_VERTEX_FLAGS_IR3
;
401 nir_function_impl
*impl
= nir_shader_get_entrypoint(shader
);
405 nir_builder_init(&b
, impl
);
406 b
.cursor
= nir_before_cf_list(&impl
->body
);
408 state
.header
= nir_load_gs_header_ir3(&b
);
410 nir_foreach_variable(var
, &shader
->outputs
) {
411 state
.output_vars
[var
->data
.driver_location
] =
412 nir_local_variable_create(impl
, var
->type
,
413 ralloc_asprintf(var
, "%s:gs-temp", var
->name
));
416 state
.vertex_count_var
=
417 nir_local_variable_create(impl
, glsl_uint_type(), "vertex_count");
418 state
.emitted_vertex_var
=
419 nir_local_variable_create(impl
, glsl_uint_type(), "emitted_vertex");
420 state
.vertex_flags_var
=
421 nir_local_variable_create(impl
, glsl_uint_type(), "vertex_flags");
422 state
.vertex_flags_out
= state
.output_vars
[state
.vertex_flags_out
->data
.driver_location
];
424 /* initialize to 0 */
425 b
.cursor
= nir_before_cf_list(&impl
->body
);
426 nir_store_var(&b
, state
.vertex_count_var
, nir_imm_int(&b
, 0), 0x1);
427 nir_store_var(&b
, state
.emitted_vertex_var
, nir_imm_int(&b
, 0), 0x1);
428 nir_store_var(&b
, state
.vertex_flags_var
, nir_imm_int(&b
, 4), 0x1);
430 nir_foreach_block_safe(block
, impl
)
431 lower_gs_block(block
, &b
, &state
);
433 set_foreach(impl
->end_block
->predecessors
, block_entry
) {
434 struct nir_block
*block
= (void *)block_entry
->key
;
435 b
.cursor
= nir_after_block_before_jump(block
);
437 nir_intrinsic_instr
*discard_if
=
438 nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_discard_if
);
440 nir_ssa_def
*cond
= nir_ieq(&b
, nir_load_var(&b
, state
.emitted_vertex_var
), nir_imm_int(&b
, 0));
442 discard_if
->src
[0] = nir_src_for_ssa(cond
);
444 nir_builder_instr_insert(&b
, &discard_if
->instr
);
446 emit_store_outputs(&b
, &state
);
449 nir_metadata_preserve(impl
, 0);
451 if (shader_debug_enabled(shader
->info
.stage
)) {
452 fprintf(stderr
, "NIR (after gs lowering):\n");
453 nir_print_shader(shader
, stderr
);