From 0cad7b09685a987d9765bf545576f8acec374a2b Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 3 Apr 2025 16:12:56 +0200 Subject: [PATCH] spirv: fix cooperative matrix by value function params The vtn_ssa_value for a cmat is not backed by a nir_def, but by a nir_variable, so can't be used directly when calling a function. In most cases the cmat is used by reference so code will take the value of deref for it (which is a `nir_def`). When passing a cooperative matrix to a function by value, let the caller pass the deref value, and the callee copy to a new local variable from that deref. Fixes: b98f87612bc ("spirv: Implement SPV_KHR_cooperative_matrix") Reviewed-by: Caio Oliveira Part-of: --- src/compiler/spirv/vtn_cfg.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index 2ac83aa71d5..595171261f1 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -78,7 +78,10 @@ vtn_ssa_value_add_to_call_params(struct vtn_builder *b, nir_call_instr *call, unsigned *param_idx) { - if (glsl_type_is_vector_or_scalar(value->type)) { + if (glsl_type_is_cmat(value->type)) { + nir_deref_instr *src_deref = vtn_get_deref_for_ssa_value(b, value); + call->params[(*param_idx)++] = nir_src_for_ssa(&src_deref->def); + } else if (glsl_type_is_vector_or_scalar(value->type)) { call->params[(*param_idx)++] = nir_src_for_ssa(value->def); } else { unsigned elems = glsl_get_length(value->type); @@ -150,7 +153,17 @@ vtn_ssa_value_load_function_param(struct vtn_builder *b, struct vtn_func_arg_info *info, unsigned *param_idx) { - if (glsl_type_is_vector_or_scalar(value->type)) { + if (glsl_type_is_cmat(value->type)) { + nir_variable *copy_var = + nir_local_variable_create(b->nb.impl, value->type, "cmat_param_by_value"); + + nir_def *param = nir_load_param(&b->nb, (*param_idx)++); + nir_deref_instr *copy = nir_build_deref_var(&b->nb, copy_var); + nir_cmat_copy(&b->nb, ©->def, param); + + value->is_variable = true; + value->var = copy_var; + } else if (glsl_type_is_vector_or_scalar(value->type)) { /* if the parameter is passed by value, we need to create a local copy if it's a pointer */ if (info->by_value && type && type->base_type == vtn_base_type_pointer) { struct vtn_type *pointee_type = type->pointed;