Previously, we would create temporary variables and fill them out.
Instead, we create as many function parameters as we need and pass them
through as SSA defs.
---
src/compiler/spirv/vtn_cfg.c | 180 +++
1 file changed, 139 insertions(+), 41 deletions(-)
diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index 87149905ed1..1020b2722f4 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -42,6 +42,135 @@ vtn_load_param_pointer(struct vtn_builder *b,
return vtn_pointer_from_ssa(b, nir_load_param(&b->nb, param_idx), ptr_type);
}
+static unsigned
+vtn_type_count_function_params(struct vtn_type *type)
+{
+ switch (type->base_type) {
+ case vtn_base_type_array:
+ return type->length *
vtn_type_count_function_params(type->array_element);
+
+ case vtn_base_type_struct: {
+ unsigned count = 0;
+ for (unsigned i = 0; i < type->length; i++)
+ count += vtn_type_count_function_params(type->members[i]);
+ return count;
+ }
+
+ case vtn_base_type_sampled_image:
+ return 2;
+
+ default:
+ return 1;
+ }
+}
+
+static void
+vtn_type_add_to_function_params(struct vtn_type *type,
+nir_function *func,
+unsigned *param_idx)
+{
+ static const nir_parameter nir_deref_param = {
+ .num_components = 1,
+ .bit_size = 32,
+ };
+
+ switch (type->base_type) {
+ case vtn_base_type_array:
+ for (unsigned i = 0; i < type->length; i++)
+ vtn_type_add_to_function_params(type->array_element, func, param_idx);
+ break;
+
+ case vtn_base_type_struct:
+ for (unsigned i = 0; i < type->length; i++)
+ vtn_type_add_to_function_params(type->members[i], func, param_idx);
+ break;
+
+ case vtn_base_type_sampled_image:
+ func->params[(*param_idx)++] = nir_deref_param;
+ func->params[(*param_idx)++] = nir_deref_param;
+ break;
+
+ case vtn_base_type_image:
+ case vtn_base_type_sampler:
+ func->params[(*param_idx)++] = nir_deref_param;
+ break;
+
+ case vtn_base_type_pointer:
+ if (type->type) {
+ func->params[(*param_idx)++] = (nir_parameter) {
+.num_components = glsl_get_vector_elements(type->type),
+.bit_size = glsl_get_bit_size(type->type),
+ };
+ } else {
+ func->params[(*param_idx)++] = nir_deref_param;
+ }
+ break;
+
+ default:
+ func->params[(*param_idx)++] = (nir_parameter) {
+ .num_components = glsl_get_vector_elements(type->type),
+ .bit_size = glsl_get_bit_size(type->type),
+ };
+ }
+}
+
+static void
+vtn_ssa_value_add_to_call_params(struct vtn_builder *b,
+ struct vtn_ssa_value *value,
+ struct vtn_type *type,
+ nir_call_instr *call,
+ unsigned *param_idx)
+{
+ switch (type->base_type) {
+ case vtn_base_type_array:
+ for (unsigned i = 0; i < type->length; i++) {
+ vtn_ssa_value_add_to_call_params(b, value->elems[i],
+ type->array_element,
+ call, param_idx);
+ }
+ break;
+
+ case vtn_base_type_struct:
+ for (unsigned i = 0; i < type->length; i++) {
+ vtn_ssa_value_add_to_call_params(b, value->elems[i],
+ type->members[i],
+ call, param_idx);
+ }
+ break;
+
+ default:
+ call->params[(*param_idx)++] = nir_src_for_ssa(value->def);
+ break;
+ }
+}
+
+static void
+vtn_ssa_value_load_function_param(struct vtn_builder *b,
+ struct vtn_ssa_value *value,
+ struct vtn_type *type,
+ unsigned *param_idx)
+{
+ switch (type->base_type) {
+ case vtn_base_type_array:
+ for (unsigned i = 0; i < type->length; i++) {
+ vtn_ssa_value_load_function_param(b, value->elems[i],
+ type->array_element, param_idx);
+ }
+ break;
+
+ case vtn_base_type_struct:
+ for (unsigned i = 0; i < type->length; i++) {
+ vtn_ssa_value_load_function_param(b, value->elems[i],
+ type->members[i], param_idx);
+ }
+ break;
+
+ default:
+ value->def = nir_load_param(&b->nb, b->func_param_idx++);
+ break;
+ }
+}
+
void
vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count)
@@ -86,12 +215,8 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp
opcode,
call->params[param_idx++] =
nir_src_for_ssa(vtn_pointer_to_ssa(b, pointer));
} else {
- /* This is a regular SSA value and we need a temporary */
-