/* * Copyright 2025 Google LLC * SPDX-License-Identifier: MIT */ #include #include "util/memstream.h" #include "helpers.h" struct CooperativeMatrix : public spirv_test { void SetUp() { spirv_caps.CooperativeMatrixKHR = true; shader_text = NULL; } void TearDown() { free(shader_text); } // Prints the shader to a newly allocated null-terminated string, and // saves it into 'shader_text'. Returns NULL if resources were exhausted. char *to_string(nir_shader *shader) { free(shader_text); shader_text = NULL; size_t result_size = 0; struct u_memstream mem; if (u_memstream_open(&mem, &shader_text, &result_size)) { FILE * memf = u_memstream_get(&mem); nir_print_shader(shader, memf); u_memstream_close(&mem); } return shader_text; } char * shader_text; }; TEST_F(CooperativeMatrix, VariableInitializer) { // This module creates a cooperative matrix variable in Function storage // class with an initializer. spirv2nir should be able to print it, // including the initializer value. /* ; SPIR-V ; Version: 1.3 ; Generator: Khronos SPIR-V Tools Assembler; 0 ; Bound: 26 ; Schema: 0 OpCapability Shader OpCapability VulkanMemoryModel OpCapability VulkanMemoryModelDeviceScope OpCapability CooperativeMatrixKHR OpExtension "SPV_KHR_vulkan_memory_model" OpExtension "SPV_KHR_cooperative_matrix" OpMemoryModel Logical Vulkan OpEntryPoint GLCompute %main "main" OpExecutionMode %main LocalSize 64 1 1 OpMemberName %buf_block_tint_explicit_layout 0 "inner" OpName %buf_block_tint_explicit_layout "buf_block_tint_explicit_layout" OpName %main "main" OpName %m "m" OpDecorate %_arr_float_uint_64 ArrayStride 4 OpMemberDecorate %buf_block_tint_explicit_layout 0 Offset 0 OpDecorate %buf_block_tint_explicit_layout Block OpDecorate %5 DescriptorSet 0 OpDecorate %5 Binding 0 %float = OpTypeFloat 32 %uint = OpTypeInt 32 0 %uint_64 = OpConstant %uint 64 %_arr_float_uint_64 = OpTypeArray %float %uint_64 %buf_block_tint_explicit_layout = OpTypeStruct %_arr_float_uint_64 %_ptr_StorageBuffer_buf_block_tint_explicit_layout = OpTypePointer StorageBuffer %buf_block_tint_explicit_layout %5 = OpVariable %_ptr_StorageBuffer_buf_block_tint_explicit_layout StorageBuffer %void = OpTypeVoid %11 = OpTypeFunction %void %uint_3 = OpConstant %uint 3 %uint_8 = OpConstant %uint 8 %uint_2 = OpConstant %uint 2 %15 = OpTypeCooperativeMatrixKHR %float %uint_3 %uint_8 %uint_8 %uint_2 %_ptr_Function_15 = OpTypePointer Function %15 %float_1_5 = OpConstant %float 1.5 %18 = OpConstantComposite %15 %float_1_5 %_ptr_StorageBuffer__arr_float_uint_64 = OpTypePointer StorageBuffer %_arr_float_uint_64 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %main = OpFunction %void None %11 %22 = OpLabel %m = OpVariable %_ptr_Function_15 Function %18 %23 = OpLoad %15 %m None %24 = OpAccessChain %_ptr_StorageBuffer__arr_float_uint_64 %5 %uint_0 %25 = OpAccessChain %_ptr_StorageBuffer_float %24 %uint_0 OpCooperativeMatrixStoreKHR %25 %23 %uint_0 %uint_8 NonPrivatePointer OpReturn OpFunctionEnd */ static const uint32_t words[] = { 0x07230203, 0x00010300, 0x00070000, 0x0000001a, 0x00000000, 0x00020011, 0x00000001, 0x00020011, 0x000014e1, 0x00020011, 0x000014e2, 0x00020011, 0x00001786, 0x0008000a, 0x5f565053, 0x5f52484b, 0x6b6c7576, 0x6d5f6e61, 0x726f6d65, 0x6f6d5f79, 0x006c6564, 0x0008000a, 0x5f565053, 0x5f52484b, 0x706f6f63, 0x74617265, 0x5f657669, 0x7274616d, 0x00007869, 0x0003000e, 0x00000000, 0x00000003, 0x0005000f, 0x00000005, 0x00000001, 0x6e69616d, 0x00000000, 0x00060010, 0x00000001, 0x00000011, 0x00000040, 0x00000001, 0x00000001, 0x00050006, 0x00000002, 0x00000000, 0x656e6e69, 0x00000072, 0x000a0005, 0x00000002, 0x5f667562, 0x636f6c62, 0x69745f6b, 0x655f746e, 0x696c7078, 0x5f746963, 0x6f79616c, 0x00007475, 0x00040005, 0x00000001, 0x6e69616d, 0x00000000, 0x00030005, 0x00000003, 0x0000006d, 0x00040047, 0x00000004, 0x00000006, 0x00000004, 0x00050048, 0x00000002, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000002, 0x00000002, 0x00040047, 0x00000005, 0x00000022, 0x00000000, 0x00040047, 0x00000005, 0x00000021, 0x00000000, 0x00030016, 0x00000006, 0x00000020, 0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0004002b, 0x00000007, 0x00000008, 0x00000040, 0x0004001c, 0x00000004, 0x00000006, 0x00000008, 0x0003001e, 0x00000002, 0x00000004, 0x00040020, 0x00000009, 0x0000000c, 0x00000002, 0x0004003b, 0x00000009, 0x00000005, 0x0000000c, 0x00020013, 0x0000000a, 0x00030021, 0x0000000b, 0x0000000a, 0x0004002b, 0x00000007, 0x0000000c, 0x00000003, 0x0004002b, 0x00000007, 0x0000000d, 0x00000008, 0x0004002b, 0x00000007, 0x0000000e, 0x00000002, 0x00071168, 0x0000000f, 0x00000006, 0x0000000c, 0x0000000d, 0x0000000d, 0x0000000e, 0x00040020, 0x00000010, 0x00000007, 0x0000000f, 0x0004002b, 0x00000006, 0x00000011, 0x3fc00000, 0x0004002c, 0x0000000f, 0x00000012, 0x00000011, 0x00040020, 0x00000013, 0x0000000c, 0x00000004, 0x0004002b, 0x00000007, 0x00000014, 0x00000000, 0x00040020, 0x00000015, 0x0000000c, 0x00000006, 0x00050036, 0x0000000a, 0x00000001, 0x00000000, 0x0000000b, 0x000200f8, 0x00000016, 0x0005003b, 0x00000010, 0x00000003, 0x00000007, 0x00000012, 0x0005003d, 0x0000000f, 0x00000017, 0x00000003, 0x00000000, 0x00050041, 0x00000013, 0x00000018, 0x00000005, 0x00000014, 0x00050041, 0x00000015, 0x00000019, 0x00000018, 0x00000014, 0x0006116a, 0x00000019, 0x00000017, 0x00000014, 0x0000000d, 0x00000020, 0x000100fd, 0x00010038, }; get_nir(sizeof(words) / sizeof(words[0]), words); ASSERT_TRUE(shader); char *text = to_string(shader); const char* expected = "m = { coopmat(1.500000) }"; EXPECT_NE(nullptr, strstr(text, expected)) << text; }