nir_variable *vertex_flags_out;
struct exec_list old_outputs;
+ struct exec_list new_outputs;
struct exec_list emit_outputs;
+
+ /* tess ctrl shader on a650 gets the local primitive id at different bits: */
+ unsigned local_primitive_id_start;
};
static nir_ssa_def *
static nir_ssa_def *
build_local_primitive_id(nir_builder *b, struct state *state)
{
- return bitfield_extract(b, state->header, 0, 63);
+ return bitfield_extract(b, state->header, state->local_primitive_id_start, 63);
}
static nir_variable *
-get_var(struct exec_list *list, int driver_location)
+get_var(nir_shader *shader, nir_variable_mode mode, int driver_location)
{
- nir_foreach_variable (v, list) {
+ nir_foreach_variable_with_modes (v, shader, mode) {
if (v->data.driver_location == driver_location) {
return v;
}
}
static void
-build_primitive_map(nir_shader *shader, struct primitive_map *map, struct exec_list *list)
+build_primitive_map(nir_shader *shader, nir_variable_mode mode, struct primitive_map *map)
{
- nir_foreach_variable (var, list) {
+ nir_foreach_variable_with_modes (var, shader, mode) {
switch (var->data.location) {
case VARYING_SLOT_TESS_LEVEL_OUTER:
case VARYING_SLOT_TESS_LEVEL_INNER:
for (uint32_t i = 0; i < ARRAY_SIZE(map->size); i++) {
if (map->size[i] == 0)
continue;
- nir_variable *var = get_var(list, i);
+ nir_variable *var = get_var(shader, mode, i);
map->loc[i] = loc;
loc += map->size[i];
{
struct state state = { };
- build_primitive_map(shader, &state.map, &shader->outputs);
+ build_primitive_map(shader, nir_var_shader_out, &state.map);
memcpy(v->output_loc, state.map.loc, sizeof(v->output_loc));
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
}
void
-ir3_nir_lower_to_explicit_input(nir_shader *shader)
+ir3_nir_lower_to_explicit_input(nir_shader *shader, struct ir3_compiler *compiler)
{
struct state state = { };
+ /* when using stl/ldl (instead of stlw/ldlw) for linking VS and HS,
+ * HS uses a different primitive id, which starts at bit 16 in the header
+ */
+ if (shader->info.stage == MESA_SHADER_TESS_CTRL && compiler->tess_use_shared)
+ state.local_primitive_id_start = 16;
+
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
assert(impl);
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *address = nir_load_tess_param_base_ir3(b);
- nir_variable *var = get_var(&b->shader->outputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_out, nir_intrinsic_base(intr));
nir_ssa_def *offset = build_per_vertex_offset(b, state,
intr->src[0].ssa, intr->src[1].ssa, var);
nir_ssa_def *value = intr->src[0].ssa;
nir_ssa_def *address = nir_load_tess_param_base_ir3(b);
- nir_variable *var = get_var(&b->shader->outputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_out, nir_intrinsic_base(intr));
nir_ssa_def *offset = build_per_vertex_offset(b, state,
intr->src[1].ssa, intr->src[2].ssa, var);
case nir_intrinsic_load_output: {
// src[] = { offset }.
- nir_variable *var = get_var(&b->shader->outputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_out, nir_intrinsic_base(intr));
b->cursor = nir_before_instr(&intr->instr);
/* write patch output to bo */
- nir_variable *var = get_var(&b->shader->outputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_out, nir_intrinsic_base(intr));
b->cursor = nir_before_instr(&intr->instr);
nir_print_shader(shader, stderr);
}
- build_primitive_map(shader, &state.map, &shader->outputs);
+ build_primitive_map(shader, nir_var_shader_out, &state.map);
memcpy(v->output_loc, state.map.loc, sizeof(v->output_loc));
v->output_size = state.map.stride;
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *address = nir_load_tess_param_base_ir3(b);
- nir_variable *var = get_var(&b->shader->inputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_in, nir_intrinsic_base(intr));
nir_ssa_def *offset = build_per_vertex_offset(b, state,
intr->src[0].ssa, intr->src[1].ssa, var);
case nir_intrinsic_load_input: {
// src[] = { offset }.
- nir_variable *var = get_var(&b->shader->inputs, nir_intrinsic_base(intr));
+ nir_variable *var = get_var(b->shader, nir_var_shader_in, nir_intrinsic_base(intr));
debug_assert(var->data.patch);
}
/* Build map of inputs so we have the sizes. */
- build_primitive_map(shader, &state.map, &shader->inputs);
+ build_primitive_map(shader, nir_var_shader_in, &state.map);
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
assert(impl);
nir_print_shader(shader, stderr);
}
- build_primitive_map(shader, &state.map, &shader->inputs);
+ build_primitive_map(shader, nir_var_shader_in, &state.map);
/* Create an output var for vertex_flags. This will be shadowed below,
* same way regular outputs get shadowed, and this variable will become a
* we copy the emit_outputs to the real outputs, so that we get
* store_output in uniform control flow.
*/
- exec_list_move_nodes_to(&shader->outputs, &state.old_outputs);
+ exec_list_make_empty(&state.old_outputs);
+ nir_foreach_shader_out_variable_safe(var, shader) {
+ exec_node_remove(&var->node);
+ exec_list_push_tail(&state.old_outputs, &var->node);
+ }
+ exec_list_make_empty(&state.new_outputs);
exec_list_make_empty(&state.emit_outputs);
- nir_foreach_variable(var, &state.old_outputs) {
+ nir_foreach_variable_in_list(var, &state.old_outputs) {
/* Create a new output var by cloning the original output var and
* stealing the name.
*/
nir_variable *output = nir_variable_clone(var, shader);
- exec_list_push_tail(&shader->outputs, &output->node);
+ exec_list_push_tail(&state.new_outputs, &output->node);
/* Rewrite the original output to be a shadow variable. */
var->name = ralloc_asprintf(var, "%s@gs-temp", output->name);
nir_builder_instr_insert(&b, &discard_if->instr);
- foreach_two_lists(dest_node, &shader->outputs, src_node, &state.emit_outputs) {
+ foreach_two_lists(dest_node, &state.new_outputs, src_node, &state.emit_outputs) {
nir_variable *dest = exec_node_data(nir_variable, dest_node, node);
nir_variable *src = exec_node_data(nir_variable, src_node, node);
nir_copy_var(&b, dest, src);
}
}
- exec_list_append(&shader->globals, &state.old_outputs);
- exec_list_append(&shader->globals, &state.emit_outputs);
+ exec_list_append(&shader->variables, &state.old_outputs);
+ exec_list_append(&shader->variables, &state.emit_outputs);
+ exec_list_append(&shader->variables, &state.new_outputs);
nir_metadata_preserve(impl, 0);
unreachable("bad shader stage");
}
- nir_foreach_variable(in_var, &consumer->shader->nir->inputs) {
- nir_foreach_variable(out_var, &producer->shader->nir->outputs) {
+ nir_foreach_shader_in_variable(in_var, consumer->shader->nir) {
+ nir_foreach_shader_out_variable(out_var, producer->shader->nir) {
if (in_var->data.location == out_var->data.location) {
locs[in_var->data.driver_location] =
producer->output_loc[out_var->data.driver_location] * factor;