1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google LLC. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <string> 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 18fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 19fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace val { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ValidateInterfacesTest = spvtest::ValidateBase<bool>; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, EntryPointMissingInput) { 30fd4e5da5Sopenharmony_ci std::string text = R"( 31fd4e5da5Sopenharmony_ciOpCapability Shader 32fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 33fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 34fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 35fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 36fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 37fd4e5da5Sopenharmony_ci%4 = OpTypePointer Input %3 38fd4e5da5Sopenharmony_ci%5 = OpVariable %4 Input 39fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 40fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %6 41fd4e5da5Sopenharmony_ci%7 = OpLabel 42fd4e5da5Sopenharmony_ci%8 = OpLoad %3 %5 43fd4e5da5Sopenharmony_ciOpReturn 44fd4e5da5Sopenharmony_ciOpFunctionEnd 45fd4e5da5Sopenharmony_ci)"; 46fd4e5da5Sopenharmony_ci 47fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 48fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 49fd4e5da5Sopenharmony_ci EXPECT_THAT( 50fd4e5da5Sopenharmony_ci getDiagnosticString(), 51fd4e5da5Sopenharmony_ci HasSubstr( 52fd4e5da5Sopenharmony_ci "Interface variable id <5> is used by entry point 'func' id <1>, " 53fd4e5da5Sopenharmony_ci "but is not listed as an interface")); 54fd4e5da5Sopenharmony_ci} 55fd4e5da5Sopenharmony_ci 56fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, EntryPointMissingOutput) { 57fd4e5da5Sopenharmony_ci std::string text = R"( 58fd4e5da5Sopenharmony_ciOpCapability Shader 59fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 60fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 61fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 62fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 63fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 64fd4e5da5Sopenharmony_ci%4 = OpTypePointer Output %3 65fd4e5da5Sopenharmony_ci%5 = OpVariable %4 Output 66fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 67fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %6 68fd4e5da5Sopenharmony_ci%7 = OpLabel 69fd4e5da5Sopenharmony_ci%8 = OpLoad %3 %5 70fd4e5da5Sopenharmony_ciOpReturn 71fd4e5da5Sopenharmony_ciOpFunctionEnd 72fd4e5da5Sopenharmony_ci)"; 73fd4e5da5Sopenharmony_ci 74fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 75fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 76fd4e5da5Sopenharmony_ci EXPECT_THAT( 77fd4e5da5Sopenharmony_ci getDiagnosticString(), 78fd4e5da5Sopenharmony_ci HasSubstr( 79fd4e5da5Sopenharmony_ci "Interface variable id <5> is used by entry point 'func' id <1>, " 80fd4e5da5Sopenharmony_ci "but is not listed as an interface")); 81fd4e5da5Sopenharmony_ci} 82fd4e5da5Sopenharmony_ci 83fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, InterfaceMissingUseInSubfunction) { 84fd4e5da5Sopenharmony_ci std::string text = R"( 85fd4e5da5Sopenharmony_ciOpCapability Shader 86fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 87fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 88fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 89fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 90fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 91fd4e5da5Sopenharmony_ci%4 = OpTypePointer Input %3 92fd4e5da5Sopenharmony_ci%5 = OpVariable %4 Input 93fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 94fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %6 95fd4e5da5Sopenharmony_ci%7 = OpLabel 96fd4e5da5Sopenharmony_ci%8 = OpFunctionCall %2 %9 97fd4e5da5Sopenharmony_ciOpReturn 98fd4e5da5Sopenharmony_ciOpFunctionEnd 99fd4e5da5Sopenharmony_ci%9 = OpFunction %2 None %6 100fd4e5da5Sopenharmony_ci%10 = OpLabel 101fd4e5da5Sopenharmony_ci%11 = OpLoad %3 %5 102fd4e5da5Sopenharmony_ciOpReturn 103fd4e5da5Sopenharmony_ciOpFunctionEnd 104fd4e5da5Sopenharmony_ci)"; 105fd4e5da5Sopenharmony_ci 106fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 107fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 108fd4e5da5Sopenharmony_ci EXPECT_THAT( 109fd4e5da5Sopenharmony_ci getDiagnosticString(), 110fd4e5da5Sopenharmony_ci HasSubstr( 111fd4e5da5Sopenharmony_ci "Interface variable id <5> is used by entry point 'func' id <1>, " 112fd4e5da5Sopenharmony_ci "but is not listed as an interface")); 113fd4e5da5Sopenharmony_ci} 114fd4e5da5Sopenharmony_ci 115fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, TwoEntryPointsOneFunction) { 116fd4e5da5Sopenharmony_ci std::string text = R"( 117fd4e5da5Sopenharmony_ciOpCapability Shader 118fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 119fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" %2 120fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func2" 121fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 122fd4e5da5Sopenharmony_ci%3 = OpTypeVoid 123fd4e5da5Sopenharmony_ci%4 = OpTypeInt 32 0 124fd4e5da5Sopenharmony_ci%5 = OpTypePointer Input %4 125fd4e5da5Sopenharmony_ci%2 = OpVariable %5 Input 126fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %3 127fd4e5da5Sopenharmony_ci%1 = OpFunction %3 None %6 128fd4e5da5Sopenharmony_ci%7 = OpLabel 129fd4e5da5Sopenharmony_ci%8 = OpLoad %4 %2 130fd4e5da5Sopenharmony_ciOpReturn 131fd4e5da5Sopenharmony_ciOpFunctionEnd 132fd4e5da5Sopenharmony_ci)"; 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 135fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 136fd4e5da5Sopenharmony_ci EXPECT_THAT( 137fd4e5da5Sopenharmony_ci getDiagnosticString(), 138fd4e5da5Sopenharmony_ci HasSubstr( 139fd4e5da5Sopenharmony_ci "Interface variable id <2> is used by entry point 'func2' id <1>, " 140fd4e5da5Sopenharmony_ci "but is not listed as an interface")); 141fd4e5da5Sopenharmony_ci} 142fd4e5da5Sopenharmony_ci 143fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, MissingInterfaceThroughInitializer) { 144fd4e5da5Sopenharmony_ci const std::string text = R"( 145fd4e5da5Sopenharmony_ciOpCapability Shader 146fd4e5da5Sopenharmony_ciOpCapability VariablePointers 147fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 148fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 149fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 150fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 151fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 152fd4e5da5Sopenharmony_ci%4 = OpTypePointer Input %3 153fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %4 154fd4e5da5Sopenharmony_ci%6 = OpVariable %4 Input 155fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %2 156fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %7 157fd4e5da5Sopenharmony_ci%8 = OpLabel 158fd4e5da5Sopenharmony_ci%9 = OpVariable %5 Function %6 159fd4e5da5Sopenharmony_ciOpReturn 160fd4e5da5Sopenharmony_ciOpFunctionEnd 161fd4e5da5Sopenharmony_ci)"; 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 164fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 165fd4e5da5Sopenharmony_ci EXPECT_THAT( 166fd4e5da5Sopenharmony_ci getDiagnosticString(), 167fd4e5da5Sopenharmony_ci HasSubstr( 168fd4e5da5Sopenharmony_ci "Interface variable id <6> is used by entry point 'func' id <1>, " 169fd4e5da5Sopenharmony_ci "but is not listed as an interface")); 170fd4e5da5Sopenharmony_ci} 171fd4e5da5Sopenharmony_ci 172fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, NonUniqueInterfacesSPV1p3) { 173fd4e5da5Sopenharmony_ci const std::string text = R"( 174fd4e5da5Sopenharmony_ciOpCapability Shader 175fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 176fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %var %var 177fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 178fd4e5da5Sopenharmony_ci%void = OpTypeVoid 179fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 180fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 181fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 182fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer Input %struct 183fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct Input 184fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 185fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 186fd4e5da5Sopenharmony_ci%1 = OpLabel 187fd4e5da5Sopenharmony_ciOpReturn 188fd4e5da5Sopenharmony_ciOpFunctionEnd 189fd4e5da5Sopenharmony_ci)"; 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 192fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 193fd4e5da5Sopenharmony_ci} 194fd4e5da5Sopenharmony_ci 195fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, NonUniqueInterfacesSPV1p4) { 196fd4e5da5Sopenharmony_ci const std::string text = R"( 197fd4e5da5Sopenharmony_ciOpCapability Shader 198fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 199fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %var %var 200fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 201fd4e5da5Sopenharmony_ciOpName %main "main" 202fd4e5da5Sopenharmony_ciOpName %var "var" 203fd4e5da5Sopenharmony_ci%void = OpTypeVoid 204fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 205fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 206fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 207fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer Input %struct 208fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct Input 209fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 210fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 211fd4e5da5Sopenharmony_ci%1 = OpLabel 212fd4e5da5Sopenharmony_ciOpReturn 213fd4e5da5Sopenharmony_ciOpFunctionEnd 214fd4e5da5Sopenharmony_ci)"; 215fd4e5da5Sopenharmony_ci 216fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); 217fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 218fd4e5da5Sopenharmony_ci EXPECT_THAT( 219fd4e5da5Sopenharmony_ci getDiagnosticString(), 220fd4e5da5Sopenharmony_ci HasSubstr("Non-unique OpEntryPoint interface '2[%var]' is disallowed")); 221fd4e5da5Sopenharmony_ci} 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, MissingGlobalVarSPV1p3) { 224fd4e5da5Sopenharmony_ci const std::string text = R"( 225fd4e5da5Sopenharmony_ciOpCapability Shader 226fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 227fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 228fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 229fd4e5da5Sopenharmony_ci%void = OpTypeVoid 230fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 231fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 232fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 233fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer StorageBuffer %struct 234fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct StorageBuffer 235fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 236fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 237fd4e5da5Sopenharmony_ci%1 = OpLabel 238fd4e5da5Sopenharmony_ci%ld = OpLoad %struct %var 239fd4e5da5Sopenharmony_ciOpReturn 240fd4e5da5Sopenharmony_ciOpFunctionEnd 241fd4e5da5Sopenharmony_ci)"; 242fd4e5da5Sopenharmony_ci 243fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 244fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 245fd4e5da5Sopenharmony_ci} 246fd4e5da5Sopenharmony_ci 247fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, MissingGlobalVarSPV1p4) { 248fd4e5da5Sopenharmony_ci const std::string text = R"( 249fd4e5da5Sopenharmony_ciOpCapability Shader 250fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 251fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 252fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 253fd4e5da5Sopenharmony_ciOpName %var "var" 254fd4e5da5Sopenharmony_ci%void = OpTypeVoid 255fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 256fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 257fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 258fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer StorageBuffer %struct 259fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct StorageBuffer 260fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 261fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 262fd4e5da5Sopenharmony_ci%1 = OpLabel 263fd4e5da5Sopenharmony_ci%ld = OpLoad %struct %var 264fd4e5da5Sopenharmony_ciOpReturn 265fd4e5da5Sopenharmony_ciOpFunctionEnd 266fd4e5da5Sopenharmony_ci)"; 267fd4e5da5Sopenharmony_ci 268fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); 269fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 270fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 271fd4e5da5Sopenharmony_ci HasSubstr("Interface variable id <2> is used by entry point " 272fd4e5da5Sopenharmony_ci "'main' id <1>, but is not listed as an interface")); 273fd4e5da5Sopenharmony_ci} 274fd4e5da5Sopenharmony_ci 275fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, FunctionInterfaceVarSPV1p3) { 276fd4e5da5Sopenharmony_ci const std::string text = R"( 277fd4e5da5Sopenharmony_ciOpCapability Shader 278fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 279fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %var 280fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 281fd4e5da5Sopenharmony_ciOpName %var "var" 282fd4e5da5Sopenharmony_ci%void = OpTypeVoid 283fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 284fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 285fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 286fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer Function %struct 287fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 288fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 289fd4e5da5Sopenharmony_ci%1 = OpLabel 290fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct Function 291fd4e5da5Sopenharmony_ciOpReturn 292fd4e5da5Sopenharmony_ciOpFunctionEnd 293fd4e5da5Sopenharmony_ci)"; 294fd4e5da5Sopenharmony_ci 295fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 296fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 297fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 298fd4e5da5Sopenharmony_ci HasSubstr("OpEntryPoint interfaces must be OpVariables with " 299fd4e5da5Sopenharmony_ci "Storage Class of Input(1) or Output(3). Found Storage " 300fd4e5da5Sopenharmony_ci "Class 7 for Entry Point id 1.")); 301fd4e5da5Sopenharmony_ci} 302fd4e5da5Sopenharmony_ci 303fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, FunctionInterfaceVarSPV1p4) { 304fd4e5da5Sopenharmony_ci const std::string text = R"( 305fd4e5da5Sopenharmony_ciOpCapability Shader 306fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 307fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %var 308fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 309fd4e5da5Sopenharmony_ciOpName %var "var" 310fd4e5da5Sopenharmony_ci%void = OpTypeVoid 311fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 312fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 313fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 314fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer Function %struct 315fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 316fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 317fd4e5da5Sopenharmony_ci%1 = OpLabel 318fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct Function 319fd4e5da5Sopenharmony_ciOpReturn 320fd4e5da5Sopenharmony_ciOpFunctionEnd 321fd4e5da5Sopenharmony_ci)"; 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); 324fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 325fd4e5da5Sopenharmony_ci EXPECT_THAT( 326fd4e5da5Sopenharmony_ci getDiagnosticString(), 327fd4e5da5Sopenharmony_ci HasSubstr("OpEntryPoint interfaces should only list global variables")); 328fd4e5da5Sopenharmony_ci} 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, ModuleSPV1p3ValidateSPV1p4_NotAllUsedGlobals) { 331fd4e5da5Sopenharmony_ci const std::string text = R"( 332fd4e5da5Sopenharmony_ciOpCapability Shader 333fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 334fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 335fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 336fd4e5da5Sopenharmony_ciOpName %var "var" 337fd4e5da5Sopenharmony_ci%void = OpTypeVoid 338fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 339fd4e5da5Sopenharmony_ci%uint3 = OpTypeVector %uint 3 340fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint3 341fd4e5da5Sopenharmony_ci%ptr_struct = OpTypePointer StorageBuffer %struct 342fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_struct StorageBuffer 343fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 344fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_ty 345fd4e5da5Sopenharmony_ci%1 = OpLabel 346fd4e5da5Sopenharmony_ci%ld = OpLoad %struct %var 347fd4e5da5Sopenharmony_ciOpReturn 348fd4e5da5Sopenharmony_ciOpFunctionEnd 349fd4e5da5Sopenharmony_ci)"; 350fd4e5da5Sopenharmony_ci 351fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 352fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 353fd4e5da5Sopenharmony_ci} 354fd4e5da5Sopenharmony_ci 355fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, ModuleSPV1p3ValidateSPV1p4_DuplicateInterface) { 356fd4e5da5Sopenharmony_ci const std::string text = R"( 357fd4e5da5Sopenharmony_ciOpCapability Shader 358fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 359fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %gid %gid 360fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 361fd4e5da5Sopenharmony_ciOpDecorate %gid BuiltIn GlobalInvocationId 362fd4e5da5Sopenharmony_ci%void = OpTypeVoid 363fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 364fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3 365fd4e5da5Sopenharmony_ci%ptr_input_int3 = OpTypePointer Input %int3 366fd4e5da5Sopenharmony_ci%gid = OpVariable %ptr_input_int3 Input 367fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 368fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 369fd4e5da5Sopenharmony_ci%entry = OpLabel 370fd4e5da5Sopenharmony_ciOpReturn 371fd4e5da5Sopenharmony_ciOpFunctionEnd 372fd4e5da5Sopenharmony_ci)"; 373fd4e5da5Sopenharmony_ci 374fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 375fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 376fd4e5da5Sopenharmony_ci} 377fd4e5da5Sopenharmony_ci 378fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, SPV14MultipleEntryPointsSameFunction) { 379fd4e5da5Sopenharmony_ci const std::string text = R"( 380fd4e5da5Sopenharmony_ciOpCapability Shader 381fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 382fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main1" %gid 383fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main2" %gid 384fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 385fd4e5da5Sopenharmony_ciOpDecorate %gid BuiltIn GlobalInvocationId 386fd4e5da5Sopenharmony_ci%void = OpTypeVoid 387fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 388fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3 389fd4e5da5Sopenharmony_ci%ptr_input_int3 = OpTypePointer Input %int3 390fd4e5da5Sopenharmony_ci%gid = OpVariable %ptr_input_int3 Input 391fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 392fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 393fd4e5da5Sopenharmony_ci%entry = OpLabel 394fd4e5da5Sopenharmony_ciOpReturn 395fd4e5da5Sopenharmony_ciOpFunctionEnd 396fd4e5da5Sopenharmony_ci)"; 397fd4e5da5Sopenharmony_ci 398fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); 399fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 400fd4e5da5Sopenharmony_ci} 401fd4e5da5Sopenharmony_ci 402fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsDoubleAssignmentVariable) { 403fd4e5da5Sopenharmony_ci const std::string text = R"( 404fd4e5da5Sopenharmony_ciOpCapability Shader 405fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 406fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 407fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 408fd4e5da5Sopenharmony_ciOpDecorate %var Location 0 409fd4e5da5Sopenharmony_ciOpDecorate %var Location 1 410fd4e5da5Sopenharmony_ci%void = OpTypeVoid 411fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 412fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 413fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 414fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_float Input 415fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 416fd4e5da5Sopenharmony_ci%entry = OpLabel 417fd4e5da5Sopenharmony_ciOpReturn 418fd4e5da5Sopenharmony_ciOpFunctionEnd 419fd4e5da5Sopenharmony_ci)"; 420fd4e5da5Sopenharmony_ci 421fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 422fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 423fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 424fd4e5da5Sopenharmony_ci HasSubstr("Variable has conflicting location decorations")); 425fd4e5da5Sopenharmony_ci} 426fd4e5da5Sopenharmony_ci 427fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsVariableAndMemberAssigned) { 428fd4e5da5Sopenharmony_ci const std::string text = R"( 429fd4e5da5Sopenharmony_ciOpCapability Shader 430fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 431fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 432fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 433fd4e5da5Sopenharmony_ciOpDecorate %var Location 0 434fd4e5da5Sopenharmony_ciOpDecorate %struct Block 435fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 436fd4e5da5Sopenharmony_ci%void = OpTypeVoid 437fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 438fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 439fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float 440fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 441fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 442fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 443fd4e5da5Sopenharmony_ci%entry = OpLabel 444fd4e5da5Sopenharmony_ciOpReturn 445fd4e5da5Sopenharmony_ciOpFunctionEnd 446fd4e5da5Sopenharmony_ci)"; 447fd4e5da5Sopenharmony_ci 448fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 449fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 450fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 451fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-Location-04918")); 452fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 453fd4e5da5Sopenharmony_ci HasSubstr("Members cannot be assigned a location")); 454fd4e5da5Sopenharmony_ci} 455fd4e5da5Sopenharmony_ci 456fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMemberAndSubMemberAssigned) { 457fd4e5da5Sopenharmony_ci const std::string text = R"( 458fd4e5da5Sopenharmony_ciOpCapability Shader 459fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 460fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 461fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 462fd4e5da5Sopenharmony_ciOpDecorate %outer Block 463fd4e5da5Sopenharmony_ciOpMemberDecorate %outer 0 Location 0 464fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 465fd4e5da5Sopenharmony_ci%void = OpTypeVoid 466fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 467fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 468fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float 469fd4e5da5Sopenharmony_ci%outer = OpTypeStruct %struct 470fd4e5da5Sopenharmony_ci%ptr_input_outer = OpTypePointer Input %outer 471fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_outer Input 472fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 473fd4e5da5Sopenharmony_ci%entry = OpLabel 474fd4e5da5Sopenharmony_ciOpReturn 475fd4e5da5Sopenharmony_ciOpFunctionEnd 476fd4e5da5Sopenharmony_ci)"; 477fd4e5da5Sopenharmony_ci 478fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 479fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 480fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 481fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-Location-04918")); 482fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 483fd4e5da5Sopenharmony_ci HasSubstr("Members cannot be assigned a location")); 484fd4e5da5Sopenharmony_ci} 485fd4e5da5Sopenharmony_ci 486fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsDoubleAssignmentStructMember) { 487fd4e5da5Sopenharmony_ci const std::string text = R"( 488fd4e5da5Sopenharmony_ciOpCapability Shader 489fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 490fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 491fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 492fd4e5da5Sopenharmony_ciOpDecorate %struct Block 493fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 0 494fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 1 495fd4e5da5Sopenharmony_ci%void = OpTypeVoid 496fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 497fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 498fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 499fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 500fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 501fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 502fd4e5da5Sopenharmony_ci%entry = OpLabel 503fd4e5da5Sopenharmony_ciOpReturn 504fd4e5da5Sopenharmony_ciOpFunctionEnd 505fd4e5da5Sopenharmony_ci)"; 506fd4e5da5Sopenharmony_ci 507fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 508fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 509fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 510fd4e5da5Sopenharmony_ci HasSubstr("Member index 1 has conflicting location assignments")); 511fd4e5da5Sopenharmony_ci} 512fd4e5da5Sopenharmony_ci 513fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMissingAssignmentStructMember) { 514fd4e5da5Sopenharmony_ci const std::string text = R"( 515fd4e5da5Sopenharmony_ciOpCapability Shader 516fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 517fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 518fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 519fd4e5da5Sopenharmony_ciOpDecorate %struct Block 520fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 1 521fd4e5da5Sopenharmony_ci%void = OpTypeVoid 522fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 523fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 524fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 525fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 526fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 527fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 528fd4e5da5Sopenharmony_ci%entry = OpLabel 529fd4e5da5Sopenharmony_ciOpReturn 530fd4e5da5Sopenharmony_ciOpFunctionEnd 531fd4e5da5Sopenharmony_ci)"; 532fd4e5da5Sopenharmony_ci 533fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 534fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 535fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 536fd4e5da5Sopenharmony_ci HasSubstr("Member index 0 is missing a location assignment")); 537fd4e5da5Sopenharmony_ci} 538fd4e5da5Sopenharmony_ci 539fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMissingAssignmentNonBlockStruct) { 540fd4e5da5Sopenharmony_ci const std::string text = R"( 541fd4e5da5Sopenharmony_ciOpCapability Shader 542fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 543fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 544fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 545fd4e5da5Sopenharmony_ci%void = OpTypeVoid 546fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 547fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 548fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 549fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 550fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 551fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 552fd4e5da5Sopenharmony_ci%entry = OpLabel 553fd4e5da5Sopenharmony_ciOpReturn 554fd4e5da5Sopenharmony_ciOpFunctionEnd 555fd4e5da5Sopenharmony_ci)"; 556fd4e5da5Sopenharmony_ci 557fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 558fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 559fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 560fd4e5da5Sopenharmony_ci HasSubstr("Variable must be decorated with a location")); 561fd4e5da5Sopenharmony_ci} 562fd4e5da5Sopenharmony_ci 563fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictInput) { 564fd4e5da5Sopenharmony_ci const std::string text = R"( 565fd4e5da5Sopenharmony_ciOpCapability Shader 566fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 567fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 568fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 569fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 570fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 0 571fd4e5da5Sopenharmony_ci%void = OpTypeVoid 572fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 573fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 574fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 575fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 576fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 577fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_struct Input 578fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 579fd4e5da5Sopenharmony_ci%entry = OpLabel 580fd4e5da5Sopenharmony_ciOpReturn 581fd4e5da5Sopenharmony_ciOpFunctionEnd 582fd4e5da5Sopenharmony_ci)"; 583fd4e5da5Sopenharmony_ci 584fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 585fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 586fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 587fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 588fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 589fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 590fd4e5da5Sopenharmony_ci "at location 0")); 591fd4e5da5Sopenharmony_ci} 592fd4e5da5Sopenharmony_ci 593fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictOutput) { 594fd4e5da5Sopenharmony_ci const std::string text = R"( 595fd4e5da5Sopenharmony_ciOpCapability Shader 596fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 597fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 598fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 599fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 600fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 601fd4e5da5Sopenharmony_ci%void = OpTypeVoid 602fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 603fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 604fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 605fd4e5da5Sopenharmony_ci%ptr_output_struct = OpTypePointer Output %struct 606fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_output_struct Output 607fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_output_struct Output 608fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 609fd4e5da5Sopenharmony_ci%entry = OpLabel 610fd4e5da5Sopenharmony_ciOpReturn 611fd4e5da5Sopenharmony_ciOpFunctionEnd 612fd4e5da5Sopenharmony_ci)"; 613fd4e5da5Sopenharmony_ci 614fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 615fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 616fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 617fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); 618fd4e5da5Sopenharmony_ci EXPECT_THAT( 619fd4e5da5Sopenharmony_ci getDiagnosticString(), 620fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting output location assignment " 621fd4e5da5Sopenharmony_ci "at location 1")); 622fd4e5da5Sopenharmony_ci} 623fd4e5da5Sopenharmony_ci 624fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, 625fd4e5da5Sopenharmony_ci VulkanLocationsSameLocationInputAndOutputNoConflict) { 626fd4e5da5Sopenharmony_ci const std::string text = R"( 627fd4e5da5Sopenharmony_ciOpCapability Shader 628fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 629fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 630fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 631fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 632fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 633fd4e5da5Sopenharmony_ci%void = OpTypeVoid 634fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 635fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 636fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 637fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 638fd4e5da5Sopenharmony_ci%ptr_output_struct = OpTypePointer Output %struct 639fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 640fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_output_struct Output 641fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 642fd4e5da5Sopenharmony_ci%entry = OpLabel 643fd4e5da5Sopenharmony_ciOpReturn 644fd4e5da5Sopenharmony_ciOpFunctionEnd 645fd4e5da5Sopenharmony_ci)"; 646fd4e5da5Sopenharmony_ci 647fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 648fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 649fd4e5da5Sopenharmony_ci} 650fd4e5da5Sopenharmony_ci 651fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsVariableInGap) { 652fd4e5da5Sopenharmony_ci const std::string text = R"( 653fd4e5da5Sopenharmony_ciOpCapability Shader 654fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 655fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 656fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 657fd4e5da5Sopenharmony_ciOpDecorate %struct Block 658fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 659fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 2 660fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 661fd4e5da5Sopenharmony_ci%void = OpTypeVoid 662fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 663fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 664fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 665fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 666fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 667fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 668fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 669fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 670fd4e5da5Sopenharmony_ci%entry = OpLabel 671fd4e5da5Sopenharmony_ciOpReturn 672fd4e5da5Sopenharmony_ciOpFunctionEnd 673fd4e5da5Sopenharmony_ci)"; 674fd4e5da5Sopenharmony_ci 675fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 676fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 677fd4e5da5Sopenharmony_ci} 678fd4e5da5Sopenharmony_ci 679fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeFloatVectorConflict) { 680fd4e5da5Sopenharmony_ci const std::string text = R"( 681fd4e5da5Sopenharmony_ciOpCapability Shader 682fd4e5da5Sopenharmony_ciOpCapability Float64 683fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 684fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 685fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 686fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 687fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 688fd4e5da5Sopenharmony_ci%void = OpTypeVoid 689fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 690fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 691fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 692fd4e5da5Sopenharmony_ci%vector = OpTypeVector %double 3 693fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 694fd4e5da5Sopenharmony_ci%ptr_input_vector = OpTypePointer Input %vector 695fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_vector Input 696fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 697fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 698fd4e5da5Sopenharmony_ci%entry = OpLabel 699fd4e5da5Sopenharmony_ciOpReturn 700fd4e5da5Sopenharmony_ciOpFunctionEnd 701fd4e5da5Sopenharmony_ci)"; 702fd4e5da5Sopenharmony_ci 703fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 704fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 705fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 706fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 707fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 708fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 709fd4e5da5Sopenharmony_ci "at location 1")); 710fd4e5da5Sopenharmony_ci} 711fd4e5da5Sopenharmony_ci 712fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeIntVectorConflict) { 713fd4e5da5Sopenharmony_ci const std::string text = R"( 714fd4e5da5Sopenharmony_ciOpCapability Shader 715fd4e5da5Sopenharmony_ciOpCapability Int64 716fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 717fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 718fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 719fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 720fd4e5da5Sopenharmony_ciOpDecorate %var1 Flat 721fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 722fd4e5da5Sopenharmony_ciOpDecorate %var2 Flat 723fd4e5da5Sopenharmony_ci%void = OpTypeVoid 724fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 725fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 726fd4e5da5Sopenharmony_ci%long = OpTypeInt 64 0 727fd4e5da5Sopenharmony_ci%vector = OpTypeVector %long 4 728fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 729fd4e5da5Sopenharmony_ci%ptr_input_vector = OpTypePointer Input %vector 730fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_vector Input 731fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 732fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 733fd4e5da5Sopenharmony_ci%entry = OpLabel 734fd4e5da5Sopenharmony_ciOpReturn 735fd4e5da5Sopenharmony_ciOpFunctionEnd 736fd4e5da5Sopenharmony_ci)"; 737fd4e5da5Sopenharmony_ci 738fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 739fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 740fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 741fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 742fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 743fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 744fd4e5da5Sopenharmony_ci "at location 1")); 745fd4e5da5Sopenharmony_ci} 746fd4e5da5Sopenharmony_ci 747fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMatrix2x2Conflict) { 748fd4e5da5Sopenharmony_ci const std::string text = R"( 749fd4e5da5Sopenharmony_ciOpCapability Shader 750fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 751fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 752fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 753fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 754fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 755fd4e5da5Sopenharmony_ci%void = OpTypeVoid 756fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 757fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 758fd4e5da5Sopenharmony_ci%vector = OpTypeVector %float 2 759fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 2 760fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 761fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 762fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 763fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 764fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 765fd4e5da5Sopenharmony_ci%entry = OpLabel 766fd4e5da5Sopenharmony_ciOpReturn 767fd4e5da5Sopenharmony_ciOpFunctionEnd 768fd4e5da5Sopenharmony_ci)"; 769fd4e5da5Sopenharmony_ci 770fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 771fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 772fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 773fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 774fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 775fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 776fd4e5da5Sopenharmony_ci "at location 1")); 777fd4e5da5Sopenharmony_ci} 778fd4e5da5Sopenharmony_ci 779fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMatrix3x3Conflict) { 780fd4e5da5Sopenharmony_ci const std::string text = R"( 781fd4e5da5Sopenharmony_ciOpCapability Shader 782fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 783fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 784fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 785fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 786fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 2 787fd4e5da5Sopenharmony_ci%void = OpTypeVoid 788fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 789fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 790fd4e5da5Sopenharmony_ci%vector = OpTypeVector %float 3 791fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 3 792fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 793fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 794fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 795fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 796fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 797fd4e5da5Sopenharmony_ci%entry = OpLabel 798fd4e5da5Sopenharmony_ciOpReturn 799fd4e5da5Sopenharmony_ciOpFunctionEnd 800fd4e5da5Sopenharmony_ci)"; 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 803fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 804fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 805fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 806fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 807fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 808fd4e5da5Sopenharmony_ci "at location 2")); 809fd4e5da5Sopenharmony_ci} 810fd4e5da5Sopenharmony_ci 811fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMatrix4x4Conflict) { 812fd4e5da5Sopenharmony_ci const std::string text = R"( 813fd4e5da5Sopenharmony_ciOpCapability Shader 814fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 815fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 816fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 817fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 818fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 3 819fd4e5da5Sopenharmony_ci%void = OpTypeVoid 820fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 821fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 822fd4e5da5Sopenharmony_ci%vector = OpTypeVector %float 4 823fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 4 824fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 825fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 826fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 827fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 828fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 829fd4e5da5Sopenharmony_ci%entry = OpLabel 830fd4e5da5Sopenharmony_ciOpReturn 831fd4e5da5Sopenharmony_ciOpFunctionEnd 832fd4e5da5Sopenharmony_ci)"; 833fd4e5da5Sopenharmony_ci 834fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 835fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 836fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 837fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 838fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 839fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 840fd4e5da5Sopenharmony_ci "at location 3")); 841fd4e5da5Sopenharmony_ci} 842fd4e5da5Sopenharmony_ci 843fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix2x2Conflict) { 844fd4e5da5Sopenharmony_ci const std::string text = R"( 845fd4e5da5Sopenharmony_ciOpCapability Shader 846fd4e5da5Sopenharmony_ciOpCapability Float64 847fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 848fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 849fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 850fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 851fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 852fd4e5da5Sopenharmony_ci%void = OpTypeVoid 853fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 854fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 855fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 856fd4e5da5Sopenharmony_ci%vector = OpTypeVector %double 2 857fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 2 858fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 859fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 860fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 861fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 862fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 863fd4e5da5Sopenharmony_ci%entry = OpLabel 864fd4e5da5Sopenharmony_ciOpReturn 865fd4e5da5Sopenharmony_ciOpFunctionEnd 866fd4e5da5Sopenharmony_ci)"; 867fd4e5da5Sopenharmony_ci 868fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 869fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 870fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 871fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 872fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 873fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 874fd4e5da5Sopenharmony_ci "at location 1")); 875fd4e5da5Sopenharmony_ci} 876fd4e5da5Sopenharmony_ci 877fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix3x3Conflict) { 878fd4e5da5Sopenharmony_ci const std::string text = R"( 879fd4e5da5Sopenharmony_ciOpCapability Shader 880fd4e5da5Sopenharmony_ciOpCapability Float64 881fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 882fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 883fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 884fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 885fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 5 886fd4e5da5Sopenharmony_ci%void = OpTypeVoid 887fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 888fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 889fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 890fd4e5da5Sopenharmony_ci%vector = OpTypeVector %double 3 891fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 3 892fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 893fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 894fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 895fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 896fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 897fd4e5da5Sopenharmony_ci%entry = OpLabel 898fd4e5da5Sopenharmony_ciOpReturn 899fd4e5da5Sopenharmony_ciOpFunctionEnd 900fd4e5da5Sopenharmony_ci)"; 901fd4e5da5Sopenharmony_ci 902fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 903fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 904fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 905fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 906fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 907fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 908fd4e5da5Sopenharmony_ci "at location 5")); 909fd4e5da5Sopenharmony_ci} 910fd4e5da5Sopenharmony_ci 911fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix4x4Conflict) { 912fd4e5da5Sopenharmony_ci const std::string text = R"( 913fd4e5da5Sopenharmony_ciOpCapability Shader 914fd4e5da5Sopenharmony_ciOpCapability Float64 915fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 916fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 917fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 918fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 919fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 7 920fd4e5da5Sopenharmony_ci%void = OpTypeVoid 921fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 922fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 923fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 924fd4e5da5Sopenharmony_ci%vector = OpTypeVector %double 4 925fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 4 926fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 927fd4e5da5Sopenharmony_ci%ptr_input_matrix = OpTypePointer Input %matrix 928fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_matrix Input 929fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 930fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 931fd4e5da5Sopenharmony_ci%entry = OpLabel 932fd4e5da5Sopenharmony_ciOpReturn 933fd4e5da5Sopenharmony_ciOpFunctionEnd 934fd4e5da5Sopenharmony_ci)"; 935fd4e5da5Sopenharmony_ci 936fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 937fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 938fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 939fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 940fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 941fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 942fd4e5da5Sopenharmony_ci "at location 7")); 943fd4e5da5Sopenharmony_ci} 944fd4e5da5Sopenharmony_ci 945fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsArray2Conflict) { 946fd4e5da5Sopenharmony_ci const std::string text = R"( 947fd4e5da5Sopenharmony_ciOpCapability Shader 948fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 949fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 950fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 951fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 952fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 953fd4e5da5Sopenharmony_ci%void = OpTypeVoid 954fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 955fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 956fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 957fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 958fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_2 959fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %array 960fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 961fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 962fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 963fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 964fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 965fd4e5da5Sopenharmony_ci%entry = OpLabel 966fd4e5da5Sopenharmony_ciOpReturn 967fd4e5da5Sopenharmony_ciOpFunctionEnd 968fd4e5da5Sopenharmony_ci)"; 969fd4e5da5Sopenharmony_ci 970fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 971fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 972fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 973fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 974fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 975fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 976fd4e5da5Sopenharmony_ci "at location 1")); 977fd4e5da5Sopenharmony_ci} 978fd4e5da5Sopenharmony_ci 979fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsArray4Conflict) { 980fd4e5da5Sopenharmony_ci const std::string text = R"( 981fd4e5da5Sopenharmony_ciOpCapability Shader 982fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 983fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 984fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 985fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 986fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 3 987fd4e5da5Sopenharmony_ci%void = OpTypeVoid 988fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 989fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 990fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 991fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 992fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_4 993fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %array 994fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 995fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 996fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 997fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 998fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 999fd4e5da5Sopenharmony_ci%entry = OpLabel 1000fd4e5da5Sopenharmony_ciOpReturn 1001fd4e5da5Sopenharmony_ciOpFunctionEnd 1002fd4e5da5Sopenharmony_ci)"; 1003fd4e5da5Sopenharmony_ci 1004fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1005fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1006fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1007fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 1008fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1009fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 1010fd4e5da5Sopenharmony_ci "at location 3")); 1011fd4e5da5Sopenharmony_ci} 1012fd4e5da5Sopenharmony_ci 1013fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsMatrix4x4Array4Conflict) { 1014fd4e5da5Sopenharmony_ci const std::string text = R"( 1015fd4e5da5Sopenharmony_ciOpCapability Shader 1016fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1017fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 1018fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1019fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 0 1020fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 15 1021fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1022fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1023fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1024fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1025fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 1026fd4e5da5Sopenharmony_ci%vector = OpTypeVector %float 4 1027fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 4 1028fd4e5da5Sopenharmony_ci%array = OpTypeArray %matrix %int_4 1029fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %array 1030fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 1031fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1032fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 1033fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_input_float Input 1034fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1035fd4e5da5Sopenharmony_ci%entry = OpLabel 1036fd4e5da5Sopenharmony_ciOpReturn 1037fd4e5da5Sopenharmony_ciOpFunctionEnd 1038fd4e5da5Sopenharmony_ci)"; 1039fd4e5da5Sopenharmony_ci 1040fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1041fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1042fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1043fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 1044fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1045fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 1046fd4e5da5Sopenharmony_ci "at location 15")); 1047fd4e5da5Sopenharmony_ci} 1048fd4e5da5Sopenharmony_ci 1049fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsComponentDisambiguates) { 1050fd4e5da5Sopenharmony_ci const std::string text = R"( 1051fd4e5da5Sopenharmony_ciOpCapability Shader 1052fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1053fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 1054fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1055fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1056fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1057fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Component 0 1058fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 0 1059fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Component 1 1060fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1061fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1062fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1063fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 1064fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1065fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 1066fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1067fd4e5da5Sopenharmony_ci%entry = OpLabel 1068fd4e5da5Sopenharmony_ciOpReturn 1069fd4e5da5Sopenharmony_ciOpFunctionEnd 1070fd4e5da5Sopenharmony_ci)"; 1071fd4e5da5Sopenharmony_ci 1072fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1073fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1074fd4e5da5Sopenharmony_ci} 1075fd4e5da5Sopenharmony_ci 1076fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsComponentIn64BitVec3) { 1077fd4e5da5Sopenharmony_ci const std::string text = R"( 1078fd4e5da5Sopenharmony_ciOpCapability Shader 1079fd4e5da5Sopenharmony_ciOpCapability Float64 1080fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1081fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 1082fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1083fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1084fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1085fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 1 1086fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Component 1 1087fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1088fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1089fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1090fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 1091fd4e5da5Sopenharmony_ci%double3 = OpTypeVector %double 3 1092fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %double3 %float 1093fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1094fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 1095fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1096fd4e5da5Sopenharmony_ci%entry = OpLabel 1097fd4e5da5Sopenharmony_ciOpReturn 1098fd4e5da5Sopenharmony_ciOpFunctionEnd 1099fd4e5da5Sopenharmony_ci)"; 1100fd4e5da5Sopenharmony_ci 1101fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1102fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1103fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1104fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); 1105fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1106fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting input location assignment " 1107fd4e5da5Sopenharmony_ci "at location 1, component 1")); 1108fd4e5da5Sopenharmony_ci} 1109fd4e5da5Sopenharmony_ci 1110fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsComponentAfter64BitVec3) { 1111fd4e5da5Sopenharmony_ci const std::string text = R"( 1112fd4e5da5Sopenharmony_ciOpCapability Shader 1113fd4e5da5Sopenharmony_ciOpCapability Float64 1114fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1115fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 1116fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1117fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1118fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1119fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 1 1120fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Component 2 1121fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1122fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1123fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1124fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 1125fd4e5da5Sopenharmony_ci%double3 = OpTypeVector %double 3 1126fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %double3 %float 1127fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1128fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 1129fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1130fd4e5da5Sopenharmony_ci%entry = OpLabel 1131fd4e5da5Sopenharmony_ciOpReturn 1132fd4e5da5Sopenharmony_ciOpFunctionEnd 1133fd4e5da5Sopenharmony_ci)"; 1134fd4e5da5Sopenharmony_ci 1135fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1136fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1137fd4e5da5Sopenharmony_ci} 1138fd4e5da5Sopenharmony_ci 1139fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsConflictingComponentVariable) { 1140fd4e5da5Sopenharmony_ci const std::string text = R"( 1141fd4e5da5Sopenharmony_ciOpCapability Shader 1142fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1143fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 1144fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1145fd4e5da5Sopenharmony_ciOpDecorate %var Location 0 1146fd4e5da5Sopenharmony_ciOpDecorate %var Component 0 1147fd4e5da5Sopenharmony_ciOpDecorate %var Component 1 1148fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1149fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1150fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1151fd4e5da5Sopenharmony_ci%ptr_input_float = OpTypePointer Input %float 1152fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_float Input 1153fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1154fd4e5da5Sopenharmony_ci%entry = OpLabel 1155fd4e5da5Sopenharmony_ciOpReturn 1156fd4e5da5Sopenharmony_ciOpFunctionEnd 1157fd4e5da5Sopenharmony_ci)"; 1158fd4e5da5Sopenharmony_ci 1159fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1160fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1161fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1162fd4e5da5Sopenharmony_ci HasSubstr("Variable has conflicting component decorations")); 1163fd4e5da5Sopenharmony_ci} 1164fd4e5da5Sopenharmony_ci 1165fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, 1166fd4e5da5Sopenharmony_ci VulkanLocationsConflictingComponentStructMember) { 1167fd4e5da5Sopenharmony_ci const std::string text = R"( 1168fd4e5da5Sopenharmony_ciOpCapability Shader 1169fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1170fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var 1171fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1172fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1173fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1174fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Component 0 1175fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Component 1 1176fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1177fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1178fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1179fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float 1180fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1181fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input_struct Input 1182fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1183fd4e5da5Sopenharmony_ci%entry = OpLabel 1184fd4e5da5Sopenharmony_ciOpReturn 1185fd4e5da5Sopenharmony_ciOpFunctionEnd 1186fd4e5da5Sopenharmony_ci)"; 1187fd4e5da5Sopenharmony_ci 1188fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1189fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1190fd4e5da5Sopenharmony_ci EXPECT_THAT( 1191fd4e5da5Sopenharmony_ci getDiagnosticString(), 1192fd4e5da5Sopenharmony_ci HasSubstr("Member index 0 has conflicting component assignments")); 1193fd4e5da5Sopenharmony_ci} 1194fd4e5da5Sopenharmony_ci 1195fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictOutputIndex1) { 1196fd4e5da5Sopenharmony_ci const std::string text = R"( 1197fd4e5da5Sopenharmony_ciOpCapability Shader 1198fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1199fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 1200fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1201fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 1202fd4e5da5Sopenharmony_ciOpDecorate %var1 Index 1 1203fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 1204fd4e5da5Sopenharmony_ciOpDecorate %var2 Index 1 1205fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1206fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1207fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1208fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 1209fd4e5da5Sopenharmony_ci%ptr_output_struct = OpTypePointer Output %struct 1210fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_output_struct Output 1211fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_output_struct Output 1212fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1213fd4e5da5Sopenharmony_ci%entry = OpLabel 1214fd4e5da5Sopenharmony_ciOpReturn 1215fd4e5da5Sopenharmony_ciOpFunctionEnd 1216fd4e5da5Sopenharmony_ci)"; 1217fd4e5da5Sopenharmony_ci 1218fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1219fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1220fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1221fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); 1222fd4e5da5Sopenharmony_ci EXPECT_THAT( 1223fd4e5da5Sopenharmony_ci getDiagnosticString(), 1224fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting output location assignment " 1225fd4e5da5Sopenharmony_ci "at location 1")); 1226fd4e5da5Sopenharmony_ci} 1227fd4e5da5Sopenharmony_ci 1228fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, 1229fd4e5da5Sopenharmony_ci VulkanLocationsVariableNoConflictDifferentIndex) { 1230fd4e5da5Sopenharmony_ci const std::string text = R"( 1231fd4e5da5Sopenharmony_ciOpCapability Shader 1232fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1233fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 %var2 1234fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1235fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 1236fd4e5da5Sopenharmony_ciOpDecorate %var1 Index 0 1237fd4e5da5Sopenharmony_ciOpDecorate %var2 Location 1 1238fd4e5da5Sopenharmony_ciOpDecorate %var2 Index 1 1239fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1240fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1241fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1242fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 1243fd4e5da5Sopenharmony_ci%ptr_output_struct = OpTypePointer Output %struct 1244fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_output_struct Output 1245fd4e5da5Sopenharmony_ci%var2 = OpVariable %ptr_output_struct Output 1246fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1247fd4e5da5Sopenharmony_ci%entry = OpLabel 1248fd4e5da5Sopenharmony_ciOpReturn 1249fd4e5da5Sopenharmony_ciOpFunctionEnd 1250fd4e5da5Sopenharmony_ci)"; 1251fd4e5da5Sopenharmony_ci 1252fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1253fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1254fd4e5da5Sopenharmony_ci} 1255fd4e5da5Sopenharmony_ci 1256fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsIndexGLCompute) { 1257fd4e5da5Sopenharmony_ci const std::string text = R"( 1258fd4e5da5Sopenharmony_ciOpCapability Shader 1259fd4e5da5Sopenharmony_ciOpCapability Geometry 1260fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1261fd4e5da5Sopenharmony_ciOpEntryPoint Geometry %main "main" %var1 1262fd4e5da5Sopenharmony_ciOpExecutionMode %main Triangles 1263fd4e5da5Sopenharmony_ciOpExecutionMode %main OutputPoints 1264fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 1265fd4e5da5Sopenharmony_ciOpDecorate %var1 Index 1 1266fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1267fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1268fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1269fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 1270fd4e5da5Sopenharmony_ci%ptr_output_struct = OpTypePointer Output %struct 1271fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_output_struct Output 1272fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1273fd4e5da5Sopenharmony_ci%entry = OpLabel 1274fd4e5da5Sopenharmony_ciOpReturn 1275fd4e5da5Sopenharmony_ciOpFunctionEnd 1276fd4e5da5Sopenharmony_ci)"; 1277fd4e5da5Sopenharmony_ci 1278fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1279fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1280fd4e5da5Sopenharmony_ci EXPECT_THAT( 1281fd4e5da5Sopenharmony_ci getDiagnosticString(), 1282fd4e5da5Sopenharmony_ci HasSubstr("Index can only be applied to Fragment output variables")); 1283fd4e5da5Sopenharmony_ci} 1284fd4e5da5Sopenharmony_ci 1285fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsIndexInput) { 1286fd4e5da5Sopenharmony_ci const std::string text = R"( 1287fd4e5da5Sopenharmony_ciOpCapability Shader 1288fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1289fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var1 1290fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1291fd4e5da5Sopenharmony_ciOpDecorate %var1 Location 1 1292fd4e5da5Sopenharmony_ciOpDecorate %var1 Index 1 1293fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1294fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1295fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1296fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %float 1297fd4e5da5Sopenharmony_ci%ptr_input_struct = OpTypePointer Input %struct 1298fd4e5da5Sopenharmony_ci%var1 = OpVariable %ptr_input_struct Input 1299fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1300fd4e5da5Sopenharmony_ci%entry = OpLabel 1301fd4e5da5Sopenharmony_ciOpReturn 1302fd4e5da5Sopenharmony_ciOpFunctionEnd 1303fd4e5da5Sopenharmony_ci)"; 1304fd4e5da5Sopenharmony_ci 1305fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1306fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1307fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1308fd4e5da5Sopenharmony_ci HasSubstr("must be in the Output storage class")); 1309fd4e5da5Sopenharmony_ci} 1310fd4e5da5Sopenharmony_ci 1311fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsArrayWithComponent) { 1312fd4e5da5Sopenharmony_ci const std::string text = R"( 1313fd4e5da5Sopenharmony_ciOpCapability Shader 1314fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1315fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %4 "main" %11 %18 %28 %36 %40 1316fd4e5da5Sopenharmony_ciOpExecutionMode %4 OriginUpperLeft 1317fd4e5da5Sopenharmony_ciOpDecorate %11 Location 0 1318fd4e5da5Sopenharmony_ciOpDecorate %18 Component 0 1319fd4e5da5Sopenharmony_ciOpDecorate %18 Location 0 1320fd4e5da5Sopenharmony_ciOpDecorate %28 Component 1 1321fd4e5da5Sopenharmony_ciOpDecorate %28 Location 0 1322fd4e5da5Sopenharmony_ciOpDecorate %36 Location 1 1323fd4e5da5Sopenharmony_ciOpDecorate %40 Component 0 1324fd4e5da5Sopenharmony_ciOpDecorate %40 Location 1 1325fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1326fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 1327fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1328fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1329fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1330fd4e5da5Sopenharmony_ci%11 = OpVariable %_ptr_Input_v4float Input 1331fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 1332fd4e5da5Sopenharmony_ci%18 = OpVariable %_ptr_Output_float Output 1333fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1334fd4e5da5Sopenharmony_ci%v3float = OpTypeVector %float 3 1335fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 1336fd4e5da5Sopenharmony_ci%_arr_v3float_uint_2 = OpTypeArray %v3float %uint_2 1337fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v3float_uint_2 = OpTypePointer Output %_arr_v3float_uint_2 1338fd4e5da5Sopenharmony_ci%28 = OpVariable %_ptr_Output__arr_v3float_uint_2 Output 1339fd4e5da5Sopenharmony_ci%_ptr_Output_v3float = OpTypePointer Output %v3float 1340fd4e5da5Sopenharmony_ci%36 = OpVariable %_ptr_Input_v4float Input 1341fd4e5da5Sopenharmony_ci%40 = OpVariable %_ptr_Output_float Output 1342fd4e5da5Sopenharmony_ci%4 = OpFunction %void None %3 1343fd4e5da5Sopenharmony_ci%5 = OpLabel 1344fd4e5da5Sopenharmony_ciOpReturn 1345fd4e5da5Sopenharmony_ciOpFunctionEnd 1346fd4e5da5Sopenharmony_ci)"; 1347fd4e5da5Sopenharmony_ci 1348fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1349fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1350fd4e5da5Sopenharmony_ci} 1351fd4e5da5Sopenharmony_ci 1352fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsArrayWithComponentBad) { 1353fd4e5da5Sopenharmony_ci const std::string text = R"( 1354fd4e5da5Sopenharmony_ciOpCapability Shader 1355fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1356fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %4 "main" %11 %18 %28 %36 %40 1357fd4e5da5Sopenharmony_ciOpExecutionMode %4 OriginUpperLeft 1358fd4e5da5Sopenharmony_ciOpDecorate %11 Location 0 1359fd4e5da5Sopenharmony_ciOpDecorate %18 Component 0 1360fd4e5da5Sopenharmony_ciOpDecorate %18 Location 0 1361fd4e5da5Sopenharmony_ciOpDecorate %28 Component 1 1362fd4e5da5Sopenharmony_ciOpDecorate %28 Location 0 1363fd4e5da5Sopenharmony_ciOpDecorate %36 Location 1 1364fd4e5da5Sopenharmony_ciOpDecorate %40 Component 1 1365fd4e5da5Sopenharmony_ciOpDecorate %40 Location 1 1366fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1367fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 1368fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1369fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1370fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1371fd4e5da5Sopenharmony_ci%11 = OpVariable %_ptr_Input_v4float Input 1372fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 1373fd4e5da5Sopenharmony_ci%18 = OpVariable %_ptr_Output_float Output 1374fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1375fd4e5da5Sopenharmony_ci%v3float = OpTypeVector %float 3 1376fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 1377fd4e5da5Sopenharmony_ci%_arr_v3float_uint_2 = OpTypeArray %v3float %uint_2 1378fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v3float_uint_2 = OpTypePointer Output %_arr_v3float_uint_2 1379fd4e5da5Sopenharmony_ci%28 = OpVariable %_ptr_Output__arr_v3float_uint_2 Output 1380fd4e5da5Sopenharmony_ci%_ptr_Output_v3float = OpTypePointer Output %v3float 1381fd4e5da5Sopenharmony_ci%36 = OpVariable %_ptr_Input_v4float Input 1382fd4e5da5Sopenharmony_ci%40 = OpVariable %_ptr_Output_float Output 1383fd4e5da5Sopenharmony_ci%4 = OpFunction %void None %3 1384fd4e5da5Sopenharmony_ci%5 = OpLabel 1385fd4e5da5Sopenharmony_ciOpReturn 1386fd4e5da5Sopenharmony_ciOpFunctionEnd 1387fd4e5da5Sopenharmony_ci)"; 1388fd4e5da5Sopenharmony_ci 1389fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1390fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1391fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1392fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); 1393fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1394fd4e5da5Sopenharmony_ci HasSubstr("Entry-point has conflicting output location " 1395fd4e5da5Sopenharmony_ci "assignment at location 1, component 1")); 1396fd4e5da5Sopenharmony_ci} 1397fd4e5da5Sopenharmony_ci 1398fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationsLargeLocation) { 1399fd4e5da5Sopenharmony_ci const std::string text = R"( 1400fd4e5da5Sopenharmony_ci OpCapability Shader 1401fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1402fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "????????" %17 1403fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1404fd4e5da5Sopenharmony_ci OpDecorate %17 Location 4227868160 1405fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1406fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1407fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1408fd4e5da5Sopenharmony_ci %v3float = OpTypeVector %float 3 1409fd4e5da5Sopenharmony_ci%_ptr_Input_v3float = OpTypePointer Input %v3float 1410fd4e5da5Sopenharmony_ci %17 = OpVariable %_ptr_Input_v3float Input 1411fd4e5da5Sopenharmony_ci %4 = OpFunction %void None %3 1412fd4e5da5Sopenharmony_ci %5 = OpLabel 1413fd4e5da5Sopenharmony_ci OpUnreachable 1414fd4e5da5Sopenharmony_ci OpFunctionEnd 1415fd4e5da5Sopenharmony_ci)"; 1416fd4e5da5Sopenharmony_ci 1417fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1418fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1419fd4e5da5Sopenharmony_ci} 1420fd4e5da5Sopenharmony_ci 1421fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationMeshShader) { 1422fd4e5da5Sopenharmony_ci const std::string text = R"( 1423fd4e5da5Sopenharmony_ciOpCapability Shader 1424fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 1425fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 1426fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1427fd4e5da5Sopenharmony_ciOpEntryPoint MeshNV %foo "foo" %in 1428fd4e5da5Sopenharmony_ciOpExecutionMode %foo LocalSize 1 1 1 1429fd4e5da5Sopenharmony_ciOpDecorate %block Block 1430fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 PerTaskNV 1431fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0 1432fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1433fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1434fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32 1435fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_32 1436fd4e5da5Sopenharmony_ci%block = OpTypeStruct %array 1437fd4e5da5Sopenharmony_ci%ptr_input_block = OpTypePointer Input %block 1438fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_input_block Input 1439fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1440fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 1441fd4e5da5Sopenharmony_ci%entry = OpLabel 1442fd4e5da5Sopenharmony_ciOpReturn 1443fd4e5da5Sopenharmony_ciOpFunctionEnd 1444fd4e5da5Sopenharmony_ci)"; 1445fd4e5da5Sopenharmony_ci 1446fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_2); 1447fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); 1448fd4e5da5Sopenharmony_ci} 1449fd4e5da5Sopenharmony_ci 1450fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationArrayWithComponent1) { 1451fd4e5da5Sopenharmony_ci const std::string text = R"( 1452fd4e5da5Sopenharmony_ciOpCapability Shader 1453fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1454fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in 1455fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1456fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1457fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1458fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Component 0 1459fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 0 1460fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Component 1 1461fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1462fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1463fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1464fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1465fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 1466fd4e5da5Sopenharmony_ci%float_arr = OpTypeArray %float %int_2 1467fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float_arr %float_arr 1468fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %struct 1469fd4e5da5Sopenharmony_ci%in = OpVariable %ptr Input 1470fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1471fd4e5da5Sopenharmony_ci%entry = OpLabel 1472fd4e5da5Sopenharmony_ciOpReturn 1473fd4e5da5Sopenharmony_ciOpFunctionEnd 1474fd4e5da5Sopenharmony_ci)"; 1475fd4e5da5Sopenharmony_ci 1476fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1477fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1478fd4e5da5Sopenharmony_ci} 1479fd4e5da5Sopenharmony_ci 1480fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, VulkanLocationArrayWithComponent2) { 1481fd4e5da5Sopenharmony_ci const std::string text = R"( 1482fd4e5da5Sopenharmony_ciOpCapability Shader 1483fd4e5da5Sopenharmony_ciOpCapability Float64 1484fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1485fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in 1486fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1487fd4e5da5Sopenharmony_ciOpDecorate %struct Block 1488fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Location 0 1489fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Component 0 1490fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Location 0 1491fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Component 2 1492fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1493fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1494fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1495fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 1496fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1497fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 1498fd4e5da5Sopenharmony_ci%double_arr = OpTypeArray %double %int_2 1499fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %double_arr 1500fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Input %struct 1501fd4e5da5Sopenharmony_ci%in = OpVariable %ptr Input 1502fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1503fd4e5da5Sopenharmony_ci%entry = OpLabel 1504fd4e5da5Sopenharmony_ciOpReturn 1505fd4e5da5Sopenharmony_ciOpFunctionEnd 1506fd4e5da5Sopenharmony_ci)"; 1507fd4e5da5Sopenharmony_ci 1508fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1509fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1510fd4e5da5Sopenharmony_ci} 1511fd4e5da5Sopenharmony_ci 1512fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, DuplicateInterfaceVariableSuccess) { 1513fd4e5da5Sopenharmony_ci const std::string text = R"( 1514fd4e5da5Sopenharmony_ciOpCapability Shader 1515fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1516fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in %out %in 1517fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1518fd4e5da5Sopenharmony_ciOpDecorate %in Location 0 1519fd4e5da5Sopenharmony_ciOpDecorate %out Location 0 1520fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1521fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1522fd4e5da5Sopenharmony_ci%in_ptr = OpTypePointer Input %float 1523fd4e5da5Sopenharmony_ci%out_ptr = OpTypePointer Output %float 1524fd4e5da5Sopenharmony_ci%in = OpVariable %in_ptr Input 1525fd4e5da5Sopenharmony_ci%out = OpVariable %out_ptr Output 1526fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1527fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1528fd4e5da5Sopenharmony_ci%entry = OpLabel 1529fd4e5da5Sopenharmony_ciOpReturn 1530fd4e5da5Sopenharmony_ciOpFunctionEnd 1531fd4e5da5Sopenharmony_ci)"; 1532fd4e5da5Sopenharmony_ci 1533fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1534fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1535fd4e5da5Sopenharmony_ci} 1536fd4e5da5Sopenharmony_ci 1537fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, StructWithBuiltinsMissingBlock_Bad) { 1538fd4e5da5Sopenharmony_ci // See https://github.com/KhronosGroup/SPIRV-Registry/issues/134 1539fd4e5da5Sopenharmony_ci // 1540fd4e5da5Sopenharmony_ci // When a shader input or output is a struct that does not have Block, 1541fd4e5da5Sopenharmony_ci // then it must have a Location. 1542fd4e5da5Sopenharmony_ci // But BuiltIns must not have locations. 1543fd4e5da5Sopenharmony_ci const std::string text = R"( 1544fd4e5da5Sopenharmony_ciOpCapability Shader 1545fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1546fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in 1547fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1548fd4e5da5Sopenharmony_ci; %struct needs a Block decoration 1549fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 BuiltIn Position 1550fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1551fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1552fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1553fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %v4float 1554fd4e5da5Sopenharmony_ci%in_ptr = OpTypePointer Input %struct 1555fd4e5da5Sopenharmony_ci%in = OpVariable %in_ptr Input 1556fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1557fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1558fd4e5da5Sopenharmony_ci%entry = OpLabel 1559fd4e5da5Sopenharmony_ciOpReturn 1560fd4e5da5Sopenharmony_ciOpFunctionEnd 1561fd4e5da5Sopenharmony_ci)"; 1562fd4e5da5Sopenharmony_ci 1563fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); 1564fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1565fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1566fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-Location-04919")); 1567fd4e5da5Sopenharmony_ci EXPECT_THAT( 1568fd4e5da5Sopenharmony_ci getDiagnosticString(), 1569fd4e5da5Sopenharmony_ci HasSubstr( 1570fd4e5da5Sopenharmony_ci "Interface struct has no Block decoration but has BuiltIn members.")); 1571fd4e5da5Sopenharmony_ci} 1572fd4e5da5Sopenharmony_ci 1573fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, InvalidLocationTypePointer) { 1574fd4e5da5Sopenharmony_ci const std::string text = R"( 1575fd4e5da5Sopenharmony_ci OpCapability Shader 1576fd4e5da5Sopenharmony_ci OpMemoryModel Logical Simple 1577fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "Aiqn0" %2 %3 1578fd4e5da5Sopenharmony_ci OpDecorate %2 Location 0 1579fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1580fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %void 1581fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1582fd4e5da5Sopenharmony_ci%_ptr_Private_void = OpTypePointer Private %void 1583fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1584fd4e5da5Sopenharmony_ci%uint_4278132784 = OpConstant %uint 4278132784 1585fd4e5da5Sopenharmony_ci%_arr__ptr_Private_void_uint_4278132784 = OpTypeArray %_ptr_Private_void %uint_4278132784 1586fd4e5da5Sopenharmony_ci%_ptr_Output__arr__ptr_Private_void_uint_4278132784 = OpTypePointer Output %_arr__ptr_Private_void_uint_4278132784 1587fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output 1588fd4e5da5Sopenharmony_ci%_ptr_Output__ptr_Private_void = OpTypePointer Output %_ptr_Private_void 1589fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output 1590fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %5 1591fd4e5da5Sopenharmony_ci %15 = OpLabel 1592fd4e5da5Sopenharmony_ci OpReturn 1593fd4e5da5Sopenharmony_ci OpFunctionEnd 1594fd4e5da5Sopenharmony_ci)"; 1595fd4e5da5Sopenharmony_ci 1596fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_1); 1597fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 1598fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1599fd4e5da5Sopenharmony_ci HasSubstr("Invalid type to assign a location")); 1600fd4e5da5Sopenharmony_ci} 1601fd4e5da5Sopenharmony_ci 1602fd4e5da5Sopenharmony_ciTEST_F(ValidateInterfacesTest, ValidLocationTypePhysicalStorageBufferPointer) { 1603fd4e5da5Sopenharmony_ci const std::string text = R"( 1604fd4e5da5Sopenharmony_ciOpCapability Shader 1605fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 1606fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 1607fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %var 1608fd4e5da5Sopenharmony_ciOpDecorate %var Location 0 1609fd4e5da5Sopenharmony_ciOpDecorate %var RestrictPointer 1610fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1611fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1612fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %int 1613fd4e5da5Sopenharmony_ci%ptr2 = OpTypePointer Input %ptr 1614fd4e5da5Sopenharmony_ci%var = OpVariable %ptr2 Input 1615fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1616fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1617fd4e5da5Sopenharmony_ci%entry = OpLabel 1618fd4e5da5Sopenharmony_ciOpReturn 1619fd4e5da5Sopenharmony_ciOpFunctionEnd 1620fd4e5da5Sopenharmony_ci)"; 1621fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_VULKAN_1_3); 1622fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3)); 1623fd4e5da5Sopenharmony_ci} 1624fd4e5da5Sopenharmony_ci 1625fd4e5da5Sopenharmony_ci} // namespace 1626fd4e5da5Sopenharmony_ci} // namespace val 1627fd4e5da5Sopenharmony_ci} // namespace spvtools 1628