b->cursor = nir_before_instr(&intrin->instr);
assert(index_src->is_ssa);
+
+ struct nir_io_semantics sem = nir_intrinsic_io_semantics(intrin);
+ uint32_t pitch;
+ if (sem.location == VARYING_SLOT_PRIMITIVE_INDICES)
+ pitch = num_mesh_vertices_per_primitive(b->shader->info.mesh.primitive_type);
+ else
+ pitch = map->per_primitive_pitch_dw;
+
nir_ssa_def *offset =
nir_iadd(b,
offset_src->ssa,
- nir_imul_imm(b, index_src->ssa, map->per_primitive_pitch_dw));
+ nir_imul_imm(b, index_src->ssa, pitch));
nir_instr_rewrite_src(&intrin->instr, offset_src, nir_src_for_ssa(offset));
return true;
}
return true;
}
- case nir_intrinsic_store_deref: {
- /* Replace:
- * gl_PrimitiveTriangleIndicesEXT[N] := vec3(X,Y,Z)
- * by:
- * gl_PrimitiveIndicesNV[N*3+0] := X
- * gl_PrimitiveIndicesNV[N*3+1] := Y
- * gl_PrimitiveIndicesNV[N*3+2] := Z
- */
-
- nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
- if (deref->deref_type != nir_deref_type_array)
- break;
-
- nir_deref_instr *deref2 = nir_src_as_deref(deref->parent);
- if (deref2->deref_type != nir_deref_type_var)
- break;
-
- const nir_variable *var = deref2->var;
- if (var->data.location != VARYING_SLOT_PRIMITIVE_INDICES)
- break;
-
- if (state->primitive_count == NULL)
- assert(!"primitive count must be set before indices");
-
- b->cursor = nir_before_instr(instr);
-
- if (!state->primitive_indices) {
- const struct glsl_type *type =
- glsl_array_type(glsl_uint_type(),
- glsl_get_length(var->type),
- 0);
-
- state->primitive_indices =
- nir_variable_create(b->shader,
- nir_var_shader_out,
- type,
- "gl_PrimitiveIndicesNV");
- state->primitive_indices->data.location = var->data.location;
- state->primitive_indices->data.interpolation = var->data.interpolation;
- }
-
- nir_deref_instr *primitive_indices_deref =
- nir_build_deref_var(b, state->primitive_indices);
-
- assert(intrin->src[1].is_ssa);
- uint8_t components = intrin->src[1].ssa->num_components;
-
- ASSERTED unsigned vertices_per_primitive =
- num_mesh_vertices_per_primitive(b->shader->info.mesh.primitive_type);
- assert(vertices_per_primitive == components);
- assert(nir_intrinsic_write_mask(intrin) == (1u << components) - 1);
-
- nir_src ind = deref->arr.index;
- assert(ind.is_ssa);
- nir_ssa_def *new_base = nir_imul_imm(b, ind.ssa, components);
-
- for (unsigned i = 0; i < components; ++i) {
- nir_ssa_def *new_idx = nir_iadd_imm(b, new_base, i);
-
- nir_deref_instr *reindexed_deref =
- nir_build_deref_array(b, primitive_indices_deref, new_idx);
-
- nir_store_deref(b, reindexed_deref, nir_channel(b, intrin->src[1].ssa, i), 1);
- }
-
- nir_instr_remove(instr);
-
- return true;
- }
-
default:
break;
}