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 <sstream> 16fd4e5da5Sopenharmony_ci#include <string> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 19fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 20fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace val { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 27fd4e5da5Sopenharmony_ciusing ::testing::Not; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciusing ValidateBarriers = spvtest::ValidateBase<bool>; 30fd4e5da5Sopenharmony_ci 31fd4e5da5Sopenharmony_cistd::string GenerateShaderCodeImpl( 32fd4e5da5Sopenharmony_ci const std::string& body, const std::string& capabilities_and_extensions, 33fd4e5da5Sopenharmony_ci const std::string& definitions, const std::string& execution_model, 34fd4e5da5Sopenharmony_ci const std::string& memory_model) { 35fd4e5da5Sopenharmony_ci std::ostringstream ss; 36fd4e5da5Sopenharmony_ci ss << R"( 37fd4e5da5Sopenharmony_ciOpCapability Shader 38fd4e5da5Sopenharmony_ci)"; 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ci ss << capabilities_and_extensions; 41fd4e5da5Sopenharmony_ci ss << memory_model << std::endl; 42fd4e5da5Sopenharmony_ci ss << "OpEntryPoint " << execution_model << " %main \"main\"\n"; 43fd4e5da5Sopenharmony_ci if (execution_model == "Fragment") { 44fd4e5da5Sopenharmony_ci ss << "OpExecutionMode %main OriginUpperLeft\n"; 45fd4e5da5Sopenharmony_ci } else if (execution_model == "Geometry") { 46fd4e5da5Sopenharmony_ci ss << "OpExecutionMode %main InputPoints\n"; 47fd4e5da5Sopenharmony_ci ss << "OpExecutionMode %main OutputPoints\n"; 48fd4e5da5Sopenharmony_ci } else if (execution_model == "GLCompute") { 49fd4e5da5Sopenharmony_ci ss << "OpExecutionMode %main LocalSize 1 1 1\n"; 50fd4e5da5Sopenharmony_ci } 51fd4e5da5Sopenharmony_ci 52fd4e5da5Sopenharmony_ci ss << R"( 53fd4e5da5Sopenharmony_ci%void = OpTypeVoid 54fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 55fd4e5da5Sopenharmony_ci%bool = OpTypeBool 56fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 57fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 58fd4e5da5Sopenharmony_ci 59fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0 60fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 61fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0 62fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1 63fd4e5da5Sopenharmony_ci%u32_4 = OpConstant %u32 4 64fd4e5da5Sopenharmony_ci)"; 65fd4e5da5Sopenharmony_ci ss << definitions; 66fd4e5da5Sopenharmony_ci ss << R"( 67fd4e5da5Sopenharmony_ci%cross_device = OpConstant %u32 0 68fd4e5da5Sopenharmony_ci%device = OpConstant %u32 1 69fd4e5da5Sopenharmony_ci%workgroup = OpConstant %u32 2 70fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 71fd4e5da5Sopenharmony_ci%invocation = OpConstant %u32 4 72fd4e5da5Sopenharmony_ci%queuefamily = OpConstant %u32 5 73fd4e5da5Sopenharmony_ci%shadercall = OpConstant %u32 6 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci%none = OpConstant %u32 0 76fd4e5da5Sopenharmony_ci%acquire = OpConstant %u32 2 77fd4e5da5Sopenharmony_ci%release = OpConstant %u32 4 78fd4e5da5Sopenharmony_ci%acquire_release = OpConstant %u32 8 79fd4e5da5Sopenharmony_ci%acquire_and_release = OpConstant %u32 6 80fd4e5da5Sopenharmony_ci%sequentially_consistent = OpConstant %u32 16 81fd4e5da5Sopenharmony_ci%acquire_release_uniform_workgroup = OpConstant %u32 328 82fd4e5da5Sopenharmony_ci%acquire_uniform_workgroup = OpConstant %u32 322 83fd4e5da5Sopenharmony_ci%release_uniform_workgroup = OpConstant %u32 324 84fd4e5da5Sopenharmony_ci%acquire_and_release_uniform = OpConstant %u32 70 85fd4e5da5Sopenharmony_ci%acquire_release_subgroup = OpConstant %u32 136 86fd4e5da5Sopenharmony_ci%acquire_release_workgroup = OpConstant %u32 264 87fd4e5da5Sopenharmony_ci%uniform = OpConstant %u32 64 88fd4e5da5Sopenharmony_ci%uniform_workgroup = OpConstant %u32 320 89fd4e5da5Sopenharmony_ci%workgroup_memory = OpConstant %u32 256 90fd4e5da5Sopenharmony_ci%image_memory = OpConstant %u32 2048 91fd4e5da5Sopenharmony_ci%uniform_image_memory = OpConstant %u32 2112 92fd4e5da5Sopenharmony_ci 93fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 94fd4e5da5Sopenharmony_ci%main_entry = OpLabel 95fd4e5da5Sopenharmony_ci)"; 96fd4e5da5Sopenharmony_ci 97fd4e5da5Sopenharmony_ci ss << body; 98fd4e5da5Sopenharmony_ci 99fd4e5da5Sopenharmony_ci ss << R"( 100fd4e5da5Sopenharmony_ciOpReturn 101fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci return ss.str(); 104fd4e5da5Sopenharmony_ci} 105fd4e5da5Sopenharmony_ci 106fd4e5da5Sopenharmony_cistd::string GenerateShaderCode( 107fd4e5da5Sopenharmony_ci const std::string& body, 108fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "", 109fd4e5da5Sopenharmony_ci const std::string& execution_model = "GLCompute") { 110fd4e5da5Sopenharmony_ci const std::string int64_capability = R"( 111fd4e5da5Sopenharmony_ciOpCapability Int64 112fd4e5da5Sopenharmony_ci)"; 113fd4e5da5Sopenharmony_ci const std::string int64_declarations = R"( 114fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0 115fd4e5da5Sopenharmony_ci%u64_0 = OpConstant %u64 0 116fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1 117fd4e5da5Sopenharmony_ci)"; 118fd4e5da5Sopenharmony_ci const std::string memory_model = "OpMemoryModel Logical GLSL450"; 119fd4e5da5Sopenharmony_ci return GenerateShaderCodeImpl( 120fd4e5da5Sopenharmony_ci body, int64_capability + capabilities_and_extensions, int64_declarations, 121fd4e5da5Sopenharmony_ci execution_model, memory_model); 122fd4e5da5Sopenharmony_ci} 123fd4e5da5Sopenharmony_ci 124fd4e5da5Sopenharmony_cistd::string GenerateVulkanVertexShaderCode( 125fd4e5da5Sopenharmony_ci const std::string& body, 126fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "", 127fd4e5da5Sopenharmony_ci const std::string& execution_model = "Vertex") { 128fd4e5da5Sopenharmony_ci const std::string memory_model = "OpMemoryModel Logical GLSL450"; 129fd4e5da5Sopenharmony_ci return GenerateShaderCodeImpl(body, capabilities_and_extensions, "", 130fd4e5da5Sopenharmony_ci execution_model, memory_model); 131fd4e5da5Sopenharmony_ci} 132fd4e5da5Sopenharmony_ci 133fd4e5da5Sopenharmony_cistd::string GenerateKernelCode( 134fd4e5da5Sopenharmony_ci const std::string& body, 135fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "") { 136fd4e5da5Sopenharmony_ci std::ostringstream ss; 137fd4e5da5Sopenharmony_ci ss << R"( 138fd4e5da5Sopenharmony_ciOpCapability Addresses 139fd4e5da5Sopenharmony_ciOpCapability Kernel 140fd4e5da5Sopenharmony_ciOpCapability Linkage 141fd4e5da5Sopenharmony_ciOpCapability Int64 142fd4e5da5Sopenharmony_ciOpCapability NamedBarrier 143fd4e5da5Sopenharmony_ci)"; 144fd4e5da5Sopenharmony_ci 145fd4e5da5Sopenharmony_ci ss << capabilities_and_extensions; 146fd4e5da5Sopenharmony_ci ss << R"( 147fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL 148fd4e5da5Sopenharmony_ci%void = OpTypeVoid 149fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 150fd4e5da5Sopenharmony_ci%bool = OpTypeBool 151fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 152fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 153fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0 154fd4e5da5Sopenharmony_ci 155fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0 156fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 157fd4e5da5Sopenharmony_ci%f32_4 = OpConstant %f32 4 158fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0 159fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1 160fd4e5da5Sopenharmony_ci%u32_4 = OpConstant %u32 4 161fd4e5da5Sopenharmony_ci%u64_0 = OpConstant %u64 0 162fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1 163fd4e5da5Sopenharmony_ci%u64_4 = OpConstant %u64 4 164fd4e5da5Sopenharmony_ci 165fd4e5da5Sopenharmony_ci%cross_device = OpConstant %u32 0 166fd4e5da5Sopenharmony_ci%device = OpConstant %u32 1 167fd4e5da5Sopenharmony_ci%workgroup = OpConstant %u32 2 168fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 169fd4e5da5Sopenharmony_ci%invocation = OpConstant %u32 4 170fd4e5da5Sopenharmony_ci 171fd4e5da5Sopenharmony_ci%none = OpConstant %u32 0 172fd4e5da5Sopenharmony_ci%acquire = OpConstant %u32 2 173fd4e5da5Sopenharmony_ci%release = OpConstant %u32 4 174fd4e5da5Sopenharmony_ci%acquire_release = OpConstant %u32 8 175fd4e5da5Sopenharmony_ci%acquire_and_release = OpConstant %u32 6 176fd4e5da5Sopenharmony_ci%sequentially_consistent = OpConstant %u32 16 177fd4e5da5Sopenharmony_ci%acquire_release_workgroup = OpConstant %u32 264 178fd4e5da5Sopenharmony_ci 179fd4e5da5Sopenharmony_ci%named_barrier = OpTypeNamedBarrier 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 182fd4e5da5Sopenharmony_ci%main_entry = OpLabel 183fd4e5da5Sopenharmony_ci)"; 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ci ss << body; 186fd4e5da5Sopenharmony_ci 187fd4e5da5Sopenharmony_ci ss << R"( 188fd4e5da5Sopenharmony_ciOpReturn 189fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ci return ss.str(); 192fd4e5da5Sopenharmony_ci} 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierGLComputeSuccess) { 195fd4e5da5Sopenharmony_ci const std::string body = R"( 196fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %none 197fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire 198fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %device %release 199fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release 200fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %sequentially_consistent 201fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release_uniform_workgroup 202fd4e5da5Sopenharmony_ci)"; 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 205fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 206fd4e5da5Sopenharmony_ci} 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierKernelSuccess) { 209fd4e5da5Sopenharmony_ci const std::string body = R"( 210fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %none 211fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire 212fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %device %release 213fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release 214fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %sequentially_consistent 215fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release_workgroup 216fd4e5da5Sopenharmony_ci)"; 217fd4e5da5Sopenharmony_ci 218fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 219fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 220fd4e5da5Sopenharmony_ci} 221fd4e5da5Sopenharmony_ci 222fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierTesselationControlSuccess) { 223fd4e5da5Sopenharmony_ci const std::string body = R"( 224fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %none 225fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire 226fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %device %release 227fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release 228fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %sequentially_consistent 229fd4e5da5Sopenharmony_ciOpControlBarrier %cross_device %cross_device %acquire_release_uniform_workgroup 230fd4e5da5Sopenharmony_ci)"; 231fd4e5da5Sopenharmony_ci 232fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n", 233fd4e5da5Sopenharmony_ci "TessellationControl")); 234fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 235fd4e5da5Sopenharmony_ci} 236fd4e5da5Sopenharmony_ci 237fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanSuccess) { 238fd4e5da5Sopenharmony_ci const std::string body = R"( 239fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %device %none 240fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire_release_uniform_workgroup 241fd4e5da5Sopenharmony_ci)"; 242fd4e5da5Sopenharmony_ci 243fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 244fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 245fd4e5da5Sopenharmony_ci} 246fd4e5da5Sopenharmony_ci 247fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv12) { 248fd4e5da5Sopenharmony_ci const std::string body = R"( 249fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %none 250fd4e5da5Sopenharmony_ci)"; 251fd4e5da5Sopenharmony_ci 252fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), 253fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_2); 254fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2)); 255fd4e5da5Sopenharmony_ci EXPECT_THAT( 256fd4e5da5Sopenharmony_ci getDiagnosticString(), 257fd4e5da5Sopenharmony_ci HasSubstr("OpControlBarrier requires one of the following " 258fd4e5da5Sopenharmony_ci "Execution Models: TessellationControl, GLCompute, Kernel, " 259fd4e5da5Sopenharmony_ci "MeshNV or TaskNV")); 260fd4e5da5Sopenharmony_ci} 261fd4e5da5Sopenharmony_ci 262fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv13) { 263fd4e5da5Sopenharmony_ci const std::string body = R"( 264fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %none 265fd4e5da5Sopenharmony_ci)"; 266fd4e5da5Sopenharmony_ci 267fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), 268fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 269fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 270fd4e5da5Sopenharmony_ci} 271fd4e5da5Sopenharmony_ci 272fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierFloatExecutionScope) { 273fd4e5da5Sopenharmony_ci const std::string body = R"( 274fd4e5da5Sopenharmony_ciOpControlBarrier %f32_1 %device %none 275fd4e5da5Sopenharmony_ci)"; 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 278fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 279fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 280fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: expected scope to be a 32-bit int")); 281fd4e5da5Sopenharmony_ci} 282fd4e5da5Sopenharmony_ci 283fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierU64ExecutionScope) { 284fd4e5da5Sopenharmony_ci const std::string body = R"( 285fd4e5da5Sopenharmony_ciOpControlBarrier %u64_1 %device %none 286fd4e5da5Sopenharmony_ci)"; 287fd4e5da5Sopenharmony_ci 288fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 289fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 290fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 291fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: expected scope to be a 32-bit int")); 292fd4e5da5Sopenharmony_ci} 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierFloatMemoryScope) { 295fd4e5da5Sopenharmony_ci const std::string body = R"( 296fd4e5da5Sopenharmony_ciOpControlBarrier %device %f32_1 %none 297fd4e5da5Sopenharmony_ci)"; 298fd4e5da5Sopenharmony_ci 299fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 300fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 301fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 302fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: expected scope to be a 32-bit int")); 303fd4e5da5Sopenharmony_ci} 304fd4e5da5Sopenharmony_ci 305fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierU64MemoryScope) { 306fd4e5da5Sopenharmony_ci const std::string body = R"( 307fd4e5da5Sopenharmony_ciOpControlBarrier %device %u64_1 %none 308fd4e5da5Sopenharmony_ci)"; 309fd4e5da5Sopenharmony_ci 310fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 311fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 312fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 313fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: expected scope to be a 32-bit int")); 314fd4e5da5Sopenharmony_ci} 315fd4e5da5Sopenharmony_ci 316fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierFloatMemorySemantics) { 317fd4e5da5Sopenharmony_ci const std::string body = R"( 318fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %f32_0 319fd4e5da5Sopenharmony_ci)"; 320fd4e5da5Sopenharmony_ci 321fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 322fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 323fd4e5da5Sopenharmony_ci EXPECT_THAT( 324fd4e5da5Sopenharmony_ci getDiagnosticString(), 325fd4e5da5Sopenharmony_ci HasSubstr( 326fd4e5da5Sopenharmony_ci "ControlBarrier: expected Memory Semantics to be a 32-bit int")); 327fd4e5da5Sopenharmony_ci} 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierU64MemorySemantics) { 330fd4e5da5Sopenharmony_ci const std::string body = R"( 331fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %u64_0 332fd4e5da5Sopenharmony_ci)"; 333fd4e5da5Sopenharmony_ci 334fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 335fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 336fd4e5da5Sopenharmony_ci EXPECT_THAT( 337fd4e5da5Sopenharmony_ci getDiagnosticString(), 338fd4e5da5Sopenharmony_ci HasSubstr( 339fd4e5da5Sopenharmony_ci "ControlBarrier: expected Memory Semantics to be a 32-bit int")); 340fd4e5da5Sopenharmony_ci} 341fd4e5da5Sopenharmony_ci 342fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanExecutionScopeDevice) { 343fd4e5da5Sopenharmony_ci const std::string body = R"( 344fd4e5da5Sopenharmony_ciOpControlBarrier %device %workgroup %none 345fd4e5da5Sopenharmony_ci)"; 346fd4e5da5Sopenharmony_ci 347fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 348fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 349fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 350fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04636")); 351fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 352fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: in Vulkan environment Execution Scope " 353fd4e5da5Sopenharmony_ci "is limited to Workgroup and Subgroup")); 354fd4e5da5Sopenharmony_ci} 355fd4e5da5Sopenharmony_ci 356fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanMemoryScopeSubgroup) { 357fd4e5da5Sopenharmony_ci const std::string body = R"( 358fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %none 359fd4e5da5Sopenharmony_ci)"; 360fd4e5da5Sopenharmony_ci 361fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 362fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 363fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 364fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-07951")); 365fd4e5da5Sopenharmony_ci EXPECT_THAT( 366fd4e5da5Sopenharmony_ci getDiagnosticString(), 367fd4e5da5Sopenharmony_ci HasSubstr( 368fd4e5da5Sopenharmony_ci "ControlBarrier: in Vulkan 1.0 environment Memory Scope is can not " 369fd4e5da5Sopenharmony_ci "be Subgroup without SubgroupBallotKHR or SubgroupVoteKHR declared")); 370fd4e5da5Sopenharmony_ci} 371fd4e5da5Sopenharmony_ci 372fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanMemoryScopeSubgroupVoteKHR) { 373fd4e5da5Sopenharmony_ci const std::string capabilities = R"( 374fd4e5da5Sopenharmony_ciOpCapability SubgroupVoteKHR 375fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_subgroup_vote" 376fd4e5da5Sopenharmony_ci)"; 377fd4e5da5Sopenharmony_ci const std::string body = R"( 378fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %none 379fd4e5da5Sopenharmony_ci)"; 380fd4e5da5Sopenharmony_ci 381fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, capabilities), 382fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 383fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 384fd4e5da5Sopenharmony_ci} 385fd4e5da5Sopenharmony_ci 386fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkan1p1MemoryScopeSubgroup) { 387fd4e5da5Sopenharmony_ci const std::string body = R"( 388fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %none 389fd4e5da5Sopenharmony_ci)"; 390fd4e5da5Sopenharmony_ci 391fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1); 392fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 393fd4e5da5Sopenharmony_ci} 394fd4e5da5Sopenharmony_ci 395fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkan1p1MemoryScopeCrossDevice) { 396fd4e5da5Sopenharmony_ci const std::string body = R"( 397fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %cross_device %none 398fd4e5da5Sopenharmony_ci)"; 399fd4e5da5Sopenharmony_ci 400fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1); 401fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 402fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 403fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04638")); 404fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 405fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: in Vulkan environment Memory Scope is " 406fd4e5da5Sopenharmony_ci "limited to Device, QueueFamily, Workgroup, " 407fd4e5da5Sopenharmony_ci "ShaderCallKHR, Subgroup, or Invocation")); 408fd4e5da5Sopenharmony_ci} 409fd4e5da5Sopenharmony_ci 410fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 411fd4e5da5Sopenharmony_ci OpControlBarrierVulkan1p1WorkgroupNonComputeMemoryFailure) { 412fd4e5da5Sopenharmony_ci const std::string body = R"( 413fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %workgroup %acquire 414fd4e5da5Sopenharmony_ci)"; 415fd4e5da5Sopenharmony_ci 416fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1); 417fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 418fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 419fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-07321")); 420fd4e5da5Sopenharmony_ci EXPECT_THAT( 421fd4e5da5Sopenharmony_ci getDiagnosticString(), 422fd4e5da5Sopenharmony_ci HasSubstr("Workgroup Memory Scope is limited to MeshNV, " 423fd4e5da5Sopenharmony_ci "TaskNV, MeshEXT, TaskEXT, TessellationControl, and GLCompute " 424fd4e5da5Sopenharmony_ci "execution model")); 425fd4e5da5Sopenharmony_ci} 426fd4e5da5Sopenharmony_ci 427fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 428fd4e5da5Sopenharmony_ci OpControlBarrierVulkan1p1WorkgroupNonComputeExecutionFailure) { 429fd4e5da5Sopenharmony_ci const std::string body = R"( 430fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %subgroup %acquire 431fd4e5da5Sopenharmony_ci)"; 432fd4e5da5Sopenharmony_ci 433fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1); 434fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 435fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 436fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04637")); 437fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 438fd4e5da5Sopenharmony_ci HasSubstr("in Vulkan environment, Workgroup execution scope is " 439fd4e5da5Sopenharmony_ci "only for TaskNV, MeshNV, TaskEXT, MeshEXT, " 440fd4e5da5Sopenharmony_ci "TessellationControl, and GLCompute execution models")); 441fd4e5da5Sopenharmony_ci} 442fd4e5da5Sopenharmony_ci 443fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupComputeSuccess) { 444fd4e5da5Sopenharmony_ci const std::string body = R"( 445fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire 446fd4e5da5Sopenharmony_ci)"; 447fd4e5da5Sopenharmony_ci 448fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1); 449fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 450fd4e5da5Sopenharmony_ci} 451fd4e5da5Sopenharmony_ci 452fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupNonComputeSuccess) { 453fd4e5da5Sopenharmony_ci const std::string body = R"( 454fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %acquire 455fd4e5da5Sopenharmony_ci)"; 456fd4e5da5Sopenharmony_ci 457fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1); 458fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 459fd4e5da5Sopenharmony_ci} 460fd4e5da5Sopenharmony_ci 461fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanInvocationSuccess) { 462fd4e5da5Sopenharmony_ci const std::string body = R"( 463fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %invocation %none 464fd4e5da5Sopenharmony_ci)"; 465fd4e5da5Sopenharmony_ci 466fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 467fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 468fd4e5da5Sopenharmony_ci} 469fd4e5da5Sopenharmony_ci 470fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierVulkanInvocationFailure) { 471fd4e5da5Sopenharmony_ci const std::string body = R"( 472fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %invocation %acquire 473fd4e5da5Sopenharmony_ci)"; 474fd4e5da5Sopenharmony_ci 475fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 476fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 477fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 478fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 479fd4e5da5Sopenharmony_ci EXPECT_THAT( 480fd4e5da5Sopenharmony_ci getDiagnosticString(), 481fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: Vulkan specification requires Memory " 482fd4e5da5Sopenharmony_ci "Semantics to be None if used with Invocation Memory Scope")); 483fd4e5da5Sopenharmony_ci} 484fd4e5da5Sopenharmony_ci 485fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierAcquireAndRelease) { 486fd4e5da5Sopenharmony_ci const std::string body = R"( 487fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %acquire_and_release_uniform 488fd4e5da5Sopenharmony_ci)"; 489fd4e5da5Sopenharmony_ci 490fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 491fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 492fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 493fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: Memory Semantics can have at most one " 494fd4e5da5Sopenharmony_ci "of the following bits set: Acquire, Release, " 495fd4e5da5Sopenharmony_ci "AcquireRelease or SequentiallyConsistent")); 496fd4e5da5Sopenharmony_ci} 497fd4e5da5Sopenharmony_ci 498fd4e5da5Sopenharmony_ci// TODO(atgoo@github.com): the corresponding check fails Vulkan CTS, 499fd4e5da5Sopenharmony_ci// reenable once fixed. 500fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, DISABLED_OpControlBarrierVulkanSubgroupStorageClass) { 501fd4e5da5Sopenharmony_ci const std::string body = R"( 502fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %device %acquire_release_subgroup 503fd4e5da5Sopenharmony_ci)"; 504fd4e5da5Sopenharmony_ci 505fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 506fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 507fd4e5da5Sopenharmony_ci EXPECT_THAT( 508fd4e5da5Sopenharmony_ci getDiagnosticString(), 509fd4e5da5Sopenharmony_ci HasSubstr( 510fd4e5da5Sopenharmony_ci "ControlBarrier: expected Memory Semantics to include a " 511fd4e5da5Sopenharmony_ci "Vulkan-supported storage class if Memory Semantics is not None")); 512fd4e5da5Sopenharmony_ci} 513fd4e5da5Sopenharmony_ci 514fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionFragment1p1) { 515fd4e5da5Sopenharmony_ci const std::string body = R"( 516fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %acquire_release_subgroup 517fd4e5da5Sopenharmony_ci)"; 518fd4e5da5Sopenharmony_ci 519fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), 520fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 521fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 522fd4e5da5Sopenharmony_ci} 523fd4e5da5Sopenharmony_ci 524fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionFragment1p1) { 525fd4e5da5Sopenharmony_ci const std::string body = R"( 526fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire_release 527fd4e5da5Sopenharmony_ci)"; 528fd4e5da5Sopenharmony_ci 529fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), 530fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 531fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 532fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 533fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpControlBarrier-04682")); 534fd4e5da5Sopenharmony_ci EXPECT_THAT( 535fd4e5da5Sopenharmony_ci getDiagnosticString(), 536fd4e5da5Sopenharmony_ci HasSubstr( 537fd4e5da5Sopenharmony_ci "OpControlBarrier execution scope must be Subgroup for Fragment, " 538fd4e5da5Sopenharmony_ci "Vertex, Geometry, TessellationEvaluation, RayGeneration, " 539fd4e5da5Sopenharmony_ci "Intersection, AnyHit, ClosestHit, and Miss execution models")); 540fd4e5da5Sopenharmony_ci} 541fd4e5da5Sopenharmony_ci 542fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionFragment1p0) { 543fd4e5da5Sopenharmony_ci const std::string body = R"( 544fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %workgroup %acquire_release 545fd4e5da5Sopenharmony_ci)"; 546fd4e5da5Sopenharmony_ci 547fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"), 548fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 549fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 550fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 551fd4e5da5Sopenharmony_ci HasSubstr("OpControlBarrier requires one of the following " 552fd4e5da5Sopenharmony_ci "Execution " 553fd4e5da5Sopenharmony_ci "Models: TessellationControl, GLCompute, Kernel, " 554fd4e5da5Sopenharmony_ci "MeshNV or TaskNV")); 555fd4e5da5Sopenharmony_ci} 556fd4e5da5Sopenharmony_ci 557fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p1) { 558fd4e5da5Sopenharmony_ci const std::string body = R"( 559fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %acquire_release_subgroup 560fd4e5da5Sopenharmony_ci)"; 561fd4e5da5Sopenharmony_ci 562fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"), 563fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 564fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 565fd4e5da5Sopenharmony_ci} 566fd4e5da5Sopenharmony_ci 567fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionVertex1p1) { 568fd4e5da5Sopenharmony_ci const std::string body = R"( 569fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire_release 570fd4e5da5Sopenharmony_ci)"; 571fd4e5da5Sopenharmony_ci 572fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"), 573fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 574fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 575fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 576fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpControlBarrier-04682")); 577fd4e5da5Sopenharmony_ci EXPECT_THAT( 578fd4e5da5Sopenharmony_ci getDiagnosticString(), 579fd4e5da5Sopenharmony_ci HasSubstr( 580fd4e5da5Sopenharmony_ci "OpControlBarrier execution scope must be Subgroup for Fragment, " 581fd4e5da5Sopenharmony_ci "Vertex, Geometry, TessellationEvaluation, RayGeneration, " 582fd4e5da5Sopenharmony_ci "Intersection, AnyHit, ClosestHit, and Miss execution models")); 583fd4e5da5Sopenharmony_ci} 584fd4e5da5Sopenharmony_ci 585fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p0) { 586fd4e5da5Sopenharmony_ci const std::string body = R"( 587fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %workgroup %acquire_release 588fd4e5da5Sopenharmony_ci)"; 589fd4e5da5Sopenharmony_ci 590fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"), 591fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 592fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 593fd4e5da5Sopenharmony_ci EXPECT_THAT( 594fd4e5da5Sopenharmony_ci getDiagnosticString(), 595fd4e5da5Sopenharmony_ci HasSubstr("OpControlBarrier requires one of the following " 596fd4e5da5Sopenharmony_ci "Execution Models: TessellationControl, GLCompute, Kernel, " 597fd4e5da5Sopenharmony_ci "MeshNV or TaskNV")); 598fd4e5da5Sopenharmony_ci} 599fd4e5da5Sopenharmony_ci 600fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p1) { 601fd4e5da5Sopenharmony_ci const std::string body = R"( 602fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %acquire_release_subgroup 603fd4e5da5Sopenharmony_ci)"; 604fd4e5da5Sopenharmony_ci 605fd4e5da5Sopenharmony_ci CompileSuccessfully( 606fd4e5da5Sopenharmony_ci GenerateShaderCode(body, "OpCapability Geometry\n", "Geometry"), 607fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 608fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 609fd4e5da5Sopenharmony_ci} 610fd4e5da5Sopenharmony_ci 611fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionGeometry1p1) { 612fd4e5da5Sopenharmony_ci const std::string body = R"( 613fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire_release 614fd4e5da5Sopenharmony_ci)"; 615fd4e5da5Sopenharmony_ci 616fd4e5da5Sopenharmony_ci CompileSuccessfully( 617fd4e5da5Sopenharmony_ci GenerateShaderCode(body, "OpCapability Geometry\n", "Geometry"), 618fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 619fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 620fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 621fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpControlBarrier-04682")); 622fd4e5da5Sopenharmony_ci EXPECT_THAT( 623fd4e5da5Sopenharmony_ci getDiagnosticString(), 624fd4e5da5Sopenharmony_ci HasSubstr( 625fd4e5da5Sopenharmony_ci "OpControlBarrier execution scope must be Subgroup for Fragment, " 626fd4e5da5Sopenharmony_ci "Vertex, Geometry, TessellationEvaluation, RayGeneration, " 627fd4e5da5Sopenharmony_ci "Intersection, AnyHit, ClosestHit, and Miss execution models")); 628fd4e5da5Sopenharmony_ci} 629fd4e5da5Sopenharmony_ci 630fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p0) { 631fd4e5da5Sopenharmony_ci const std::string body = R"( 632fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %workgroup %acquire_release 633fd4e5da5Sopenharmony_ci)"; 634fd4e5da5Sopenharmony_ci 635fd4e5da5Sopenharmony_ci CompileSuccessfully( 636fd4e5da5Sopenharmony_ci GenerateShaderCode(body, "OpCapability Geometry\n", "Geometry"), 637fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 638fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 639fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 640fd4e5da5Sopenharmony_ci HasSubstr("OpControlBarrier requires one of the following " 641fd4e5da5Sopenharmony_ci "Execution " 642fd4e5da5Sopenharmony_ci "Models: TessellationControl, GLCompute, Kernel, " 643fd4e5da5Sopenharmony_ci "MeshNV or TaskNV")); 644fd4e5da5Sopenharmony_ci} 645fd4e5da5Sopenharmony_ci 646fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 647fd4e5da5Sopenharmony_ci OpControlBarrierSubgroupExecutionTessellationEvaluation1p1) { 648fd4e5da5Sopenharmony_ci const std::string body = R"( 649fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %subgroup %acquire_release_subgroup 650fd4e5da5Sopenharmony_ci)"; 651fd4e5da5Sopenharmony_ci 652fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n", 653fd4e5da5Sopenharmony_ci "TessellationEvaluation"), 654fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 655fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 656fd4e5da5Sopenharmony_ci} 657fd4e5da5Sopenharmony_ci 658fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 659fd4e5da5Sopenharmony_ci OpControlBarrierWorkgroupExecutionTessellationEvaluation1p1) { 660fd4e5da5Sopenharmony_ci const std::string body = R"( 661fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %acquire_release 662fd4e5da5Sopenharmony_ci)"; 663fd4e5da5Sopenharmony_ci 664fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n", 665fd4e5da5Sopenharmony_ci "TessellationEvaluation"), 666fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 667fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 668fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 669fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpControlBarrier-04682")); 670fd4e5da5Sopenharmony_ci EXPECT_THAT( 671fd4e5da5Sopenharmony_ci getDiagnosticString(), 672fd4e5da5Sopenharmony_ci HasSubstr( 673fd4e5da5Sopenharmony_ci "OpControlBarrier execution scope must be Subgroup for Fragment, " 674fd4e5da5Sopenharmony_ci "Vertex, Geometry, TessellationEvaluation, RayGeneration, " 675fd4e5da5Sopenharmony_ci "Intersection, AnyHit, ClosestHit, and Miss execution models")); 676fd4e5da5Sopenharmony_ci} 677fd4e5da5Sopenharmony_ci 678fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 679fd4e5da5Sopenharmony_ci OpControlBarrierSubgroupExecutionTessellationEvaluation1p0) { 680fd4e5da5Sopenharmony_ci const std::string body = R"( 681fd4e5da5Sopenharmony_ciOpControlBarrier %subgroup %workgroup %acquire_release 682fd4e5da5Sopenharmony_ci)"; 683fd4e5da5Sopenharmony_ci 684fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n", 685fd4e5da5Sopenharmony_ci "TessellationEvaluation"), 686fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 687fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 688fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 689fd4e5da5Sopenharmony_ci HasSubstr("OpControlBarrier requires one of the following " 690fd4e5da5Sopenharmony_ci "Execution " 691fd4e5da5Sopenharmony_ci "Models: TessellationControl, GLCompute, Kernel, " 692fd4e5da5Sopenharmony_ci "MeshNV or TaskNV")); 693fd4e5da5Sopenharmony_ci} 694fd4e5da5Sopenharmony_ci 695fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierSuccess) { 696fd4e5da5Sopenharmony_ci const std::string body = R"( 697fd4e5da5Sopenharmony_ciOpMemoryBarrier %cross_device %acquire_release_uniform_workgroup 698fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %uniform 699fd4e5da5Sopenharmony_ci)"; 700fd4e5da5Sopenharmony_ci 701fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 702fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 703fd4e5da5Sopenharmony_ci} 704fd4e5da5Sopenharmony_ci 705fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierKernelSuccess) { 706fd4e5da5Sopenharmony_ci const std::string body = R"( 707fd4e5da5Sopenharmony_ciOpMemoryBarrier %cross_device %acquire_release_workgroup 708fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %none 709fd4e5da5Sopenharmony_ci)"; 710fd4e5da5Sopenharmony_ci 711fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 712fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 713fd4e5da5Sopenharmony_ci} 714fd4e5da5Sopenharmony_ci 715fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkanSuccess) { 716fd4e5da5Sopenharmony_ci const std::string body = R"( 717fd4e5da5Sopenharmony_ciOpMemoryBarrier %workgroup %acquire_release_uniform_workgroup 718fd4e5da5Sopenharmony_ci)"; 719fd4e5da5Sopenharmony_ci 720fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 721fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 722fd4e5da5Sopenharmony_ci} 723fd4e5da5Sopenharmony_ci 724fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierFloatMemoryScope) { 725fd4e5da5Sopenharmony_ci const std::string body = R"( 726fd4e5da5Sopenharmony_ciOpMemoryBarrier %f32_1 %acquire_release_uniform_workgroup 727fd4e5da5Sopenharmony_ci)"; 728fd4e5da5Sopenharmony_ci 729fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 730fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 731fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 732fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected scope to be a 32-bit int")); 733fd4e5da5Sopenharmony_ci} 734fd4e5da5Sopenharmony_ci 735fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierU64MemoryScope) { 736fd4e5da5Sopenharmony_ci const std::string body = R"( 737fd4e5da5Sopenharmony_ciOpMemoryBarrier %u64_1 %acquire_release_uniform_workgroup 738fd4e5da5Sopenharmony_ci)"; 739fd4e5da5Sopenharmony_ci 740fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 741fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 742fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 743fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected scope to be a 32-bit int")); 744fd4e5da5Sopenharmony_ci} 745fd4e5da5Sopenharmony_ci 746fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierFloatMemorySemantics) { 747fd4e5da5Sopenharmony_ci const std::string body = R"( 748fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %f32_0 749fd4e5da5Sopenharmony_ci)"; 750fd4e5da5Sopenharmony_ci 751fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 752fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 753fd4e5da5Sopenharmony_ci EXPECT_THAT( 754fd4e5da5Sopenharmony_ci getDiagnosticString(), 755fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to be a 32-bit int")); 756fd4e5da5Sopenharmony_ci} 757fd4e5da5Sopenharmony_ci 758fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierU64MemorySemantics) { 759fd4e5da5Sopenharmony_ci const std::string body = R"( 760fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %u64_0 761fd4e5da5Sopenharmony_ci)"; 762fd4e5da5Sopenharmony_ci 763fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 764fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 765fd4e5da5Sopenharmony_ci EXPECT_THAT( 766fd4e5da5Sopenharmony_ci getDiagnosticString(), 767fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to be a 32-bit int")); 768fd4e5da5Sopenharmony_ci} 769fd4e5da5Sopenharmony_ci 770fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkanMemoryScopeSubgroup) { 771fd4e5da5Sopenharmony_ci const std::string body = R"( 772fd4e5da5Sopenharmony_ciOpMemoryBarrier %subgroup %acquire_release_uniform_workgroup 773fd4e5da5Sopenharmony_ci)"; 774fd4e5da5Sopenharmony_ci 775fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 776fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 777fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 778fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-07951")); 779fd4e5da5Sopenharmony_ci EXPECT_THAT( 780fd4e5da5Sopenharmony_ci getDiagnosticString(), 781fd4e5da5Sopenharmony_ci HasSubstr( 782fd4e5da5Sopenharmony_ci "MemoryBarrier: in Vulkan 1.0 environment Memory Scope is can not be " 783fd4e5da5Sopenharmony_ci "Subgroup without SubgroupBallotKHR or SubgroupVoteKHR declared")); 784fd4e5da5Sopenharmony_ci} 785fd4e5da5Sopenharmony_ci 786fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkan1p1MemoryScopeSubgroup) { 787fd4e5da5Sopenharmony_ci const std::string body = R"( 788fd4e5da5Sopenharmony_ciOpMemoryBarrier %subgroup %acquire_release_uniform_workgroup 789fd4e5da5Sopenharmony_ci)"; 790fd4e5da5Sopenharmony_ci 791fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1); 792fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 793fd4e5da5Sopenharmony_ci} 794fd4e5da5Sopenharmony_ci 795fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierAcquireAndRelease) { 796fd4e5da5Sopenharmony_ci const std::string body = R"( 797fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %acquire_and_release_uniform 798fd4e5da5Sopenharmony_ci)"; 799fd4e5da5Sopenharmony_ci 800fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 801fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 802fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 803fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: Memory Semantics can have at most one " 804fd4e5da5Sopenharmony_ci "of the following bits set: Acquire, Release, " 805fd4e5da5Sopenharmony_ci "AcquireRelease or SequentiallyConsistent")); 806fd4e5da5Sopenharmony_ci} 807fd4e5da5Sopenharmony_ci 808fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkanMemorySemanticsNone) { 809fd4e5da5Sopenharmony_ci const std::string body = R"( 810fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %none 811fd4e5da5Sopenharmony_ci)"; 812fd4e5da5Sopenharmony_ci 813fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 814fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 815fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 816fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpMemoryBarrier-04732")); 817fd4e5da5Sopenharmony_ci EXPECT_THAT( 818fd4e5da5Sopenharmony_ci getDiagnosticString(), 819fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: Vulkan specification requires Memory Semantics " 820fd4e5da5Sopenharmony_ci "to have one of the following bits set: Acquire, Release, " 821fd4e5da5Sopenharmony_ci "AcquireRelease or SequentiallyConsistent")); 822fd4e5da5Sopenharmony_ci} 823fd4e5da5Sopenharmony_ci 824fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkanMemorySemanticsAcquire) { 825fd4e5da5Sopenharmony_ci const std::string body = R"( 826fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %acquire 827fd4e5da5Sopenharmony_ci)"; 828fd4e5da5Sopenharmony_ci 829fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 830fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 831fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 832fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpMemoryBarrier-04733")); 833fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 834fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to include a " 835fd4e5da5Sopenharmony_ci "Vulkan-supported storage class")); 836fd4e5da5Sopenharmony_ci} 837fd4e5da5Sopenharmony_ci 838fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierVulkanSubgroupStorageClass) { 839fd4e5da5Sopenharmony_ci const std::string body = R"( 840fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %acquire_release_subgroup 841fd4e5da5Sopenharmony_ci)"; 842fd4e5da5Sopenharmony_ci 843fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 844fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 845fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 846fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpMemoryBarrier-04733")); 847fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 848fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to include a " 849fd4e5da5Sopenharmony_ci "Vulkan-supported storage class")); 850fd4e5da5Sopenharmony_ci} 851fd4e5da5Sopenharmony_ci 852fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpNamedBarrierInitializeSuccess) { 853fd4e5da5Sopenharmony_ci const std::string body = R"( 854fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u32_4 855fd4e5da5Sopenharmony_ci)"; 856fd4e5da5Sopenharmony_ci 857fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 858fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 859fd4e5da5Sopenharmony_ci} 860fd4e5da5Sopenharmony_ci 861fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpNamedBarrierInitializeWrongResultType) { 862fd4e5da5Sopenharmony_ci const std::string body = R"( 863fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %u32 %u32_4 864fd4e5da5Sopenharmony_ci)"; 865fd4e5da5Sopenharmony_ci 866fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 867fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 868fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 869fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 870fd4e5da5Sopenharmony_ci HasSubstr("NamedBarrierInitialize: expected Result Type to be " 871fd4e5da5Sopenharmony_ci "OpTypeNamedBarrier")); 872fd4e5da5Sopenharmony_ci} 873fd4e5da5Sopenharmony_ci 874fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpNamedBarrierInitializeFloatSubgroupCount) { 875fd4e5da5Sopenharmony_ci const std::string body = R"( 876fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %f32_4 877fd4e5da5Sopenharmony_ci)"; 878fd4e5da5Sopenharmony_ci 879fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 880fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 881fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 882fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 883fd4e5da5Sopenharmony_ci HasSubstr("NamedBarrierInitialize: expected Subgroup Count to be " 884fd4e5da5Sopenharmony_ci "a 32-bit int")); 885fd4e5da5Sopenharmony_ci} 886fd4e5da5Sopenharmony_ci 887fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpNamedBarrierInitializeU64SubgroupCount) { 888fd4e5da5Sopenharmony_ci const std::string body = R"( 889fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u64_4 890fd4e5da5Sopenharmony_ci)"; 891fd4e5da5Sopenharmony_ci 892fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 893fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 894fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 895fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 896fd4e5da5Sopenharmony_ci HasSubstr("NamedBarrierInitialize: expected Subgroup Count to be " 897fd4e5da5Sopenharmony_ci "a 32-bit int")); 898fd4e5da5Sopenharmony_ci} 899fd4e5da5Sopenharmony_ci 900fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryNamedBarrierSuccess) { 901fd4e5da5Sopenharmony_ci const std::string body = R"( 902fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u32_4 903fd4e5da5Sopenharmony_ciOpMemoryNamedBarrier %barrier %workgroup %acquire_release_workgroup 904fd4e5da5Sopenharmony_ci)"; 905fd4e5da5Sopenharmony_ci 906fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 907fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 908fd4e5da5Sopenharmony_ci} 909fd4e5da5Sopenharmony_ci 910fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryNamedBarrierNotNamedBarrier) { 911fd4e5da5Sopenharmony_ci const std::string body = R"( 912fd4e5da5Sopenharmony_ciOpMemoryNamedBarrier %u32_1 %workgroup %acquire_release_workgroup 913fd4e5da5Sopenharmony_ci)"; 914fd4e5da5Sopenharmony_ci 915fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 916fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 917fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 918fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 919fd4e5da5Sopenharmony_ci HasSubstr("MemoryNamedBarrier: expected Named Barrier to be of " 920fd4e5da5Sopenharmony_ci "type OpTypeNamedBarrier")); 921fd4e5da5Sopenharmony_ci} 922fd4e5da5Sopenharmony_ci 923fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryNamedBarrierFloatMemoryScope) { 924fd4e5da5Sopenharmony_ci const std::string body = R"( 925fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u32_4 926fd4e5da5Sopenharmony_ciOpMemoryNamedBarrier %barrier %f32_1 %acquire_release_workgroup 927fd4e5da5Sopenharmony_ci)"; 928fd4e5da5Sopenharmony_ci 929fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 930fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 931fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 932fd4e5da5Sopenharmony_ci EXPECT_THAT( 933fd4e5da5Sopenharmony_ci getDiagnosticString(), 934fd4e5da5Sopenharmony_ci HasSubstr("MemoryNamedBarrier: expected scope to be a 32-bit int")); 935fd4e5da5Sopenharmony_ci} 936fd4e5da5Sopenharmony_ci 937fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryNamedBarrierFloatMemorySemantics) { 938fd4e5da5Sopenharmony_ci const std::string body = R"( 939fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u32_4 940fd4e5da5Sopenharmony_ciOpMemoryNamedBarrier %barrier %workgroup %f32_0 941fd4e5da5Sopenharmony_ci)"; 942fd4e5da5Sopenharmony_ci 943fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 944fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 945fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 946fd4e5da5Sopenharmony_ci EXPECT_THAT( 947fd4e5da5Sopenharmony_ci getDiagnosticString(), 948fd4e5da5Sopenharmony_ci HasSubstr( 949fd4e5da5Sopenharmony_ci "MemoryNamedBarrier: expected Memory Semantics to be a 32-bit int")); 950fd4e5da5Sopenharmony_ci} 951fd4e5da5Sopenharmony_ci 952fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryNamedBarrierAcquireAndRelease) { 953fd4e5da5Sopenharmony_ci const std::string body = R"( 954fd4e5da5Sopenharmony_ci%barrier = OpNamedBarrierInitialize %named_barrier %u32_4 955fd4e5da5Sopenharmony_ciOpMemoryNamedBarrier %barrier %workgroup %acquire_and_release 956fd4e5da5Sopenharmony_ci)"; 957fd4e5da5Sopenharmony_ci 958fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 959fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, 960fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 961fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 962fd4e5da5Sopenharmony_ci HasSubstr("MemoryNamedBarrier: Memory Semantics can have at most " 963fd4e5da5Sopenharmony_ci "one of the following bits set: Acquire, Release, " 964fd4e5da5Sopenharmony_ci "AcquireRelease or SequentiallyConsistent")); 965fd4e5da5Sopenharmony_ci} 966fd4e5da5Sopenharmony_ci 967fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, TypeAsMemoryScope) { 968fd4e5da5Sopenharmony_ci const std::string body = R"( 969fd4e5da5Sopenharmony_ciOpMemoryBarrier %u32 %u32_0 970fd4e5da5Sopenharmony_ci)"; 971fd4e5da5Sopenharmony_ci 972fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_1); 973fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); 974fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand '5[%uint]' cannot be a " 975fd4e5da5Sopenharmony_ci "type")); 976fd4e5da5Sopenharmony_ci} 977fd4e5da5Sopenharmony_ci 978fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 979fd4e5da5Sopenharmony_ci OpControlBarrierVulkanMemoryModelBanSequentiallyConsistent) { 980fd4e5da5Sopenharmony_ci const std::string text = R"( 981fd4e5da5Sopenharmony_ciOpCapability Shader 982fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 983fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 984fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 985fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 986fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 987fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 988fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 989fd4e5da5Sopenharmony_ci%4 = OpConstant %3 16 990fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 991fd4e5da5Sopenharmony_ci%6 = OpConstant %3 5 992fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 993fd4e5da5Sopenharmony_ci%7 = OpLabel 994fd4e5da5Sopenharmony_ciOpControlBarrier %6 %6 %4 995fd4e5da5Sopenharmony_ciOpReturn 996fd4e5da5Sopenharmony_ciOpFunctionEnd 997fd4e5da5Sopenharmony_ci)"; 998fd4e5da5Sopenharmony_ci 999fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1000fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1001fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1002fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1003fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1004fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1005fd4e5da5Sopenharmony_ci} 1006fd4e5da5Sopenharmony_ci 1007fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, 1008fd4e5da5Sopenharmony_ci OpMemoryBarrierVulkanMemoryModelBanSequentiallyConsistent) { 1009fd4e5da5Sopenharmony_ci const std::string text = R"( 1010fd4e5da5Sopenharmony_ciOpCapability Shader 1011fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1012fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1013fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1014fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 1015fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 1016fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1017fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 1018fd4e5da5Sopenharmony_ci%4 = OpConstant %3 16 1019fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 1020fd4e5da5Sopenharmony_ci%6 = OpConstant %3 5 1021fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 1022fd4e5da5Sopenharmony_ci%7 = OpLabel 1023fd4e5da5Sopenharmony_ciOpMemoryBarrier %6 %4 1024fd4e5da5Sopenharmony_ciOpReturn 1025fd4e5da5Sopenharmony_ciOpFunctionEnd 1026fd4e5da5Sopenharmony_ci)"; 1027fd4e5da5Sopenharmony_ci 1028fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1029fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1030fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1031fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1032fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1033fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1034fd4e5da5Sopenharmony_ci} 1035fd4e5da5Sopenharmony_ci 1036fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OutputMemoryKHRRequireVulkanMemoryModelKHR) { 1037fd4e5da5Sopenharmony_ci const std::string text = R"( 1038fd4e5da5Sopenharmony_ciOpCapability Shader 1039fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1040fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 1041fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 1042fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1043fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 1044fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 4104 1045fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 1046fd4e5da5Sopenharmony_ci%device = OpConstant %3 1 1047fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 1048fd4e5da5Sopenharmony_ci%7 = OpLabel 1049fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1050fd4e5da5Sopenharmony_ciOpReturn 1051fd4e5da5Sopenharmony_ciOpFunctionEnd 1052fd4e5da5Sopenharmony_ci)"; 1053fd4e5da5Sopenharmony_ci 1054fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1055fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1056fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1057fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: Memory Semantics OutputMemoryKHR " 1058fd4e5da5Sopenharmony_ci "requires capability VulkanMemoryModelKHR")); 1059fd4e5da5Sopenharmony_ci} 1060fd4e5da5Sopenharmony_ci 1061fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeAvailableKHRRequireVulkanMemoryModelKHR) { 1062fd4e5da5Sopenharmony_ci const std::string text = R"( 1063fd4e5da5Sopenharmony_ciOpCapability Shader 1064fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1065fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 1066fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 1067fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1068fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 1069fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 8264 1070fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 1071fd4e5da5Sopenharmony_ci%device = OpConstant %3 1 1072fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 1073fd4e5da5Sopenharmony_ci%7 = OpLabel 1074fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1075fd4e5da5Sopenharmony_ciOpReturn 1076fd4e5da5Sopenharmony_ciOpFunctionEnd 1077fd4e5da5Sopenharmony_ci)"; 1078fd4e5da5Sopenharmony_ci 1079fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1080fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1081fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1082fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: Memory Semantics MakeAvailableKHR " 1083fd4e5da5Sopenharmony_ci "requires capability VulkanMemoryModelKHR")); 1084fd4e5da5Sopenharmony_ci} 1085fd4e5da5Sopenharmony_ci 1086fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeVisibleKHRRequireVulkanMemoryModelKHR) { 1087fd4e5da5Sopenharmony_ci const std::string text = R"( 1088fd4e5da5Sopenharmony_ciOpCapability Shader 1089fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1090fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 1091fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 1092fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1093fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 1094fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 16456 1095fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 1096fd4e5da5Sopenharmony_ci%device = OpConstant %3 1 1097fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 1098fd4e5da5Sopenharmony_ci%7 = OpLabel 1099fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1100fd4e5da5Sopenharmony_ciOpReturn 1101fd4e5da5Sopenharmony_ciOpFunctionEnd 1102fd4e5da5Sopenharmony_ci)"; 1103fd4e5da5Sopenharmony_ci 1104fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1105fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1106fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1107fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: Memory Semantics MakeVisibleKHR " 1108fd4e5da5Sopenharmony_ci "requires capability VulkanMemoryModelKHR")); 1109fd4e5da5Sopenharmony_ci} 1110fd4e5da5Sopenharmony_ci 1111fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeAvailableKHRRequiresReleaseSemantics) { 1112fd4e5da5Sopenharmony_ci const std::string text = R"( 1113fd4e5da5Sopenharmony_ciOpCapability Shader 1114fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1115fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1116fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1117fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1118fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1119fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1120fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1121fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1122fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 8448 1123fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1124fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1125fd4e5da5Sopenharmony_ci%1 = OpLabel 1126fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %semantics 1127fd4e5da5Sopenharmony_ciOpReturn 1128fd4e5da5Sopenharmony_ciOpFunctionEnd 1129fd4e5da5Sopenharmony_ci)"; 1130fd4e5da5Sopenharmony_ci 1131fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1132fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1133fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1134fd4e5da5Sopenharmony_ci EXPECT_THAT( 1135fd4e5da5Sopenharmony_ci getDiagnosticString(), 1136fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: MakeAvailableKHR Memory Semantics also " 1137fd4e5da5Sopenharmony_ci "requires either Release or AcquireRelease Memory Semantics")); 1138fd4e5da5Sopenharmony_ci} 1139fd4e5da5Sopenharmony_ci 1140fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeVisibleKHRRequiresAcquireSemantics) { 1141fd4e5da5Sopenharmony_ci const std::string text = R"( 1142fd4e5da5Sopenharmony_ciOpCapability Shader 1143fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1144fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1145fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1146fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1147fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1148fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1149fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1150fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1151fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 16640 1152fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1153fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1154fd4e5da5Sopenharmony_ci%1 = OpLabel 1155fd4e5da5Sopenharmony_ciOpControlBarrier %workgroup %workgroup %semantics 1156fd4e5da5Sopenharmony_ciOpReturn 1157fd4e5da5Sopenharmony_ciOpFunctionEnd 1158fd4e5da5Sopenharmony_ci)"; 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1161fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1162fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1163fd4e5da5Sopenharmony_ci EXPECT_THAT( 1164fd4e5da5Sopenharmony_ci getDiagnosticString(), 1165fd4e5da5Sopenharmony_ci HasSubstr("ControlBarrier: MakeVisibleKHR Memory Semantics also requires " 1166fd4e5da5Sopenharmony_ci "either Acquire or AcquireRelease Memory Semantics")); 1167fd4e5da5Sopenharmony_ci} 1168fd4e5da5Sopenharmony_ci 1169fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeAvailableKHRRequiresStorageSemantics) { 1170fd4e5da5Sopenharmony_ci const std::string text = R"( 1171fd4e5da5Sopenharmony_ciOpCapability Shader 1172fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1173fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1174fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1175fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1176fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1177fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1178fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1179fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1180fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 8196 1181fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1182fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1183fd4e5da5Sopenharmony_ci%1 = OpLabel 1184fd4e5da5Sopenharmony_ciOpMemoryBarrier %workgroup %semantics 1185fd4e5da5Sopenharmony_ciOpReturn 1186fd4e5da5Sopenharmony_ciOpFunctionEnd 1187fd4e5da5Sopenharmony_ci)"; 1188fd4e5da5Sopenharmony_ci 1189fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1190fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1191fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1192fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1193fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to include a " 1194fd4e5da5Sopenharmony_ci "storage class")); 1195fd4e5da5Sopenharmony_ci} 1196fd4e5da5Sopenharmony_ci 1197fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, MakeVisibleKHRRequiresStorageSemantics) { 1198fd4e5da5Sopenharmony_ci const std::string text = R"( 1199fd4e5da5Sopenharmony_ciOpCapability Shader 1200fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1201fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1202fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1203fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1204fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1205fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1206fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1207fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1208fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 16386 1209fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1210fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1211fd4e5da5Sopenharmony_ci%1 = OpLabel 1212fd4e5da5Sopenharmony_ciOpMemoryBarrier %workgroup %semantics 1213fd4e5da5Sopenharmony_ciOpReturn 1214fd4e5da5Sopenharmony_ciOpFunctionEnd 1215fd4e5da5Sopenharmony_ci)"; 1216fd4e5da5Sopenharmony_ci 1217fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1218fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1219fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1220fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1221fd4e5da5Sopenharmony_ci HasSubstr("MemoryBarrier: expected Memory Semantics to include a " 1222fd4e5da5Sopenharmony_ci "storage class")); 1223fd4e5da5Sopenharmony_ci} 1224fd4e5da5Sopenharmony_ci 1225fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, SemanticsSpecConstantShader) { 1226fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1227fd4e5da5Sopenharmony_ciOpCapability Shader 1228fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1229fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1230fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1231fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1232fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1233fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 1234fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 1235fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 1236fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 1237fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1238fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 1239fd4e5da5Sopenharmony_ci%entry = OpLabel 1240fd4e5da5Sopenharmony_ciOpMemoryBarrier %workgroup %spec_const 1241fd4e5da5Sopenharmony_ciOpReturn 1242fd4e5da5Sopenharmony_ciOpFunctionEnd 1243fd4e5da5Sopenharmony_ci)"; 1244fd4e5da5Sopenharmony_ci 1245fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1246fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1247fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1248fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics ids must be OpConstant when Shader " 1249fd4e5da5Sopenharmony_ci "capability is present")); 1250fd4e5da5Sopenharmony_ci} 1251fd4e5da5Sopenharmony_ci 1252fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, SemanticsSpecConstantKernel) { 1253fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1254fd4e5da5Sopenharmony_ciOpCapability Kernel 1255fd4e5da5Sopenharmony_ciOpCapability Linkage 1256fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1257fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1258fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1259fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 1260fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 1261fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 1262fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 1263fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 1264fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 1265fd4e5da5Sopenharmony_ci%entry = OpLabel 1266fd4e5da5Sopenharmony_ciOpMemoryBarrier %workgroup %spec_const 1267fd4e5da5Sopenharmony_ciOpReturn 1268fd4e5da5Sopenharmony_ciOpFunctionEnd 1269fd4e5da5Sopenharmony_ci)"; 1270fd4e5da5Sopenharmony_ci 1271fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1272fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1273fd4e5da5Sopenharmony_ci} 1274fd4e5da5Sopenharmony_ci 1275fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, ScopeSpecConstantShader) { 1276fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1277fd4e5da5Sopenharmony_ciOpCapability Shader 1278fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1279fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1280fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1281fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1283fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 1284fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 1285fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 1286fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 1287fd4e5da5Sopenharmony_ci%relaxed = OpConstant %int 0 1288fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 1289fd4e5da5Sopenharmony_ci%entry = OpLabel 1290fd4e5da5Sopenharmony_ciOpMemoryBarrier %spec_const %relaxed 1291fd4e5da5Sopenharmony_ciOpReturn 1292fd4e5da5Sopenharmony_ciOpFunctionEnd 1293fd4e5da5Sopenharmony_ci)"; 1294fd4e5da5Sopenharmony_ci 1295fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1296fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1297fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1298fd4e5da5Sopenharmony_ci HasSubstr("Scope ids must be OpConstant when Shader " 1299fd4e5da5Sopenharmony_ci "capability is present")); 1300fd4e5da5Sopenharmony_ci} 1301fd4e5da5Sopenharmony_ci 1302fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, ScopeSpecConstantKernel) { 1303fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1304fd4e5da5Sopenharmony_ciOpCapability Kernel 1305fd4e5da5Sopenharmony_ciOpCapability Linkage 1306fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1307fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1308fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1309fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 1310fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 1311fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 1312fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 1313fd4e5da5Sopenharmony_ci%relaxed = OpConstant %int 0 1314fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 1315fd4e5da5Sopenharmony_ci%entry = OpLabel 1316fd4e5da5Sopenharmony_ciOpMemoryBarrier %spec_const %relaxed 1317fd4e5da5Sopenharmony_ciOpReturn 1318fd4e5da5Sopenharmony_ciOpFunctionEnd 1319fd4e5da5Sopenharmony_ci)"; 1320fd4e5da5Sopenharmony_ci 1321fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1322fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1323fd4e5da5Sopenharmony_ci} 1324fd4e5da5Sopenharmony_ci 1325fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, VulkanMemoryModelDeviceScopeBad) { 1326fd4e5da5Sopenharmony_ci const std::string text = R"( 1327fd4e5da5Sopenharmony_ciOpCapability Shader 1328fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1329fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1330fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1331fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1332fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1333fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1334fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1335fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1336fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 0 1337fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1338fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1339fd4e5da5Sopenharmony_ci%1 = OpLabel 1340fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %semantics 1341fd4e5da5Sopenharmony_ciOpReturn 1342fd4e5da5Sopenharmony_ciOpFunctionEnd 1343fd4e5da5Sopenharmony_ci)"; 1344fd4e5da5Sopenharmony_ci 1345fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1346fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1347fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1348fd4e5da5Sopenharmony_ci EXPECT_THAT( 1349fd4e5da5Sopenharmony_ci getDiagnosticString(), 1350fd4e5da5Sopenharmony_ci HasSubstr("Use of device scope with VulkanKHR memory model requires the " 1351fd4e5da5Sopenharmony_ci "VulkanMemoryModelDeviceScopeKHR capability")); 1352fd4e5da5Sopenharmony_ci} 1353fd4e5da5Sopenharmony_ci 1354fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, VulkanMemoryModelDeviceScopeGood) { 1355fd4e5da5Sopenharmony_ci const std::string text = R"( 1356fd4e5da5Sopenharmony_ciOpCapability Shader 1357fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1358fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 1359fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1360fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1361fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1362fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1363fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1364fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1365fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1366fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 0 1367fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1368fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1369fd4e5da5Sopenharmony_ci%1 = OpLabel 1370fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %semantics 1371fd4e5da5Sopenharmony_ciOpReturn 1372fd4e5da5Sopenharmony_ciOpFunctionEnd 1373fd4e5da5Sopenharmony_ci)"; 1374fd4e5da5Sopenharmony_ci 1375fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 1376fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1377fd4e5da5Sopenharmony_ci} 1378fd4e5da5Sopenharmony_ci 1379fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, VolatileMemoryBarrier) { 1380fd4e5da5Sopenharmony_ci const std::string text = R"( 1381fd4e5da5Sopenharmony_ciOpCapability Shader 1382fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1383fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 1384fd4e5da5Sopenharmony_ciOpCapability Linkage 1385fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1386fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1387fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1388fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1389fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1390fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 32768 1391fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1392fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1393fd4e5da5Sopenharmony_ci%1 = OpLabel 1394fd4e5da5Sopenharmony_ciOpMemoryBarrier %device %semantics 1395fd4e5da5Sopenharmony_ciOpReturn 1396fd4e5da5Sopenharmony_ciOpFunctionEnd 1397fd4e5da5Sopenharmony_ci)"; 1398fd4e5da5Sopenharmony_ci 1399fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1400fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1401fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1402fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics Volatile can only be used with " 1403fd4e5da5Sopenharmony_ci "atomic instructions")); 1404fd4e5da5Sopenharmony_ci} 1405fd4e5da5Sopenharmony_ci 1406fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, VolatileControlBarrier) { 1407fd4e5da5Sopenharmony_ci const std::string text = R"( 1408fd4e5da5Sopenharmony_ciOpCapability Shader 1409fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1410fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 1411fd4e5da5Sopenharmony_ciOpCapability Linkage 1412fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1413fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1414fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1415fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1416fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1417fd4e5da5Sopenharmony_ci%semantics = OpConstant %int 32768 1418fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1419fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1420fd4e5da5Sopenharmony_ci%1 = OpLabel 1421fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1422fd4e5da5Sopenharmony_ciOpReturn 1423fd4e5da5Sopenharmony_ciOpFunctionEnd 1424fd4e5da5Sopenharmony_ci)"; 1425fd4e5da5Sopenharmony_ci 1426fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1427fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1428fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1429fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics Volatile can only be used with " 1430fd4e5da5Sopenharmony_ci "atomic instructions")); 1431fd4e5da5Sopenharmony_ci} 1432fd4e5da5Sopenharmony_ci 1433fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, CooperativeMatrixSpecConstantVolatile) { 1434fd4e5da5Sopenharmony_ci const std::string text = R"( 1435fd4e5da5Sopenharmony_ciOpCapability Shader 1436fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1437fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 1438fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 1439fd4e5da5Sopenharmony_ciOpCapability Linkage 1440fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1441fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 1442fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1443fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1444fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1445fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1446fd4e5da5Sopenharmony_ci%semantics = OpSpecConstant %int 32768 1447fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1448fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1449fd4e5da5Sopenharmony_ci%1 = OpLabel 1450fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1451fd4e5da5Sopenharmony_ciOpReturn 1452fd4e5da5Sopenharmony_ciOpFunctionEnd 1453fd4e5da5Sopenharmony_ci)"; 1454fd4e5da5Sopenharmony_ci 1455fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1456fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1457fd4e5da5Sopenharmony_ci} 1458fd4e5da5Sopenharmony_ci 1459fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, CooperativeMatrixNonConstantSemantics) { 1460fd4e5da5Sopenharmony_ci const std::string text = R"( 1461fd4e5da5Sopenharmony_ciOpCapability Shader 1462fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1463fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 1464fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 1465fd4e5da5Sopenharmony_ciOpCapability Linkage 1466fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1467fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 1468fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 1469fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1470fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1471fd4e5da5Sopenharmony_ci%device = OpConstant %int 1 1472fd4e5da5Sopenharmony_ci%semantics = OpUndef %int 1473fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1474fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1475fd4e5da5Sopenharmony_ci%1 = OpLabel 1476fd4e5da5Sopenharmony_ciOpControlBarrier %device %device %semantics 1477fd4e5da5Sopenharmony_ciOpReturn 1478fd4e5da5Sopenharmony_ciOpFunctionEnd 1479fd4e5da5Sopenharmony_ci)"; 1480fd4e5da5Sopenharmony_ci 1481fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 1482fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1483fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1484fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics must be a constant instruction when " 1485fd4e5da5Sopenharmony_ci "CooperativeMatrixNV capability is present")); 1486fd4e5da5Sopenharmony_ci} 1487fd4e5da5Sopenharmony_ci 1488fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierShaderCallRayGenSuccess) { 1489fd4e5da5Sopenharmony_ci const std::string body = 1490fd4e5da5Sopenharmony_ci "OpMemoryBarrier %shadercall %release_uniform_workgroup"; 1491fd4e5da5Sopenharmony_ci 1492fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCodeImpl(body, 1493fd4e5da5Sopenharmony_ci // capabilities_and_extensions 1494fd4e5da5Sopenharmony_ci R"( 1495fd4e5da5Sopenharmony_ci OpCapability VulkanMemoryModelKHR 1496fd4e5da5Sopenharmony_ci OpCapability RayTracingKHR 1497fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_vulkan_memory_model" 1498fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_ray_tracing" 1499fd4e5da5Sopenharmony_ci )", 1500fd4e5da5Sopenharmony_ci // definitions 1501fd4e5da5Sopenharmony_ci "", 1502fd4e5da5Sopenharmony_ci // execution_model 1503fd4e5da5Sopenharmony_ci "RayGenerationKHR", 1504fd4e5da5Sopenharmony_ci // memory_model 1505fd4e5da5Sopenharmony_ci "OpMemoryModel Logical VulkanKHR"), 1506fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 1507fd4e5da5Sopenharmony_ci 1508fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 1509fd4e5da5Sopenharmony_ci} 1510fd4e5da5Sopenharmony_ci 1511fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpMemoryBarrierShaderCallComputeFailure) { 1512fd4e5da5Sopenharmony_ci const std::string body = 1513fd4e5da5Sopenharmony_ci "OpMemoryBarrier %shadercall %release_uniform_workgroup"; 1514fd4e5da5Sopenharmony_ci 1515fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCodeImpl(body, 1516fd4e5da5Sopenharmony_ci // capabilities_and_extensions 1517fd4e5da5Sopenharmony_ci R"( 1518fd4e5da5Sopenharmony_ci OpCapability VulkanMemoryModelKHR 1519fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_vulkan_memory_model" 1520fd4e5da5Sopenharmony_ci )", 1521fd4e5da5Sopenharmony_ci // definitions 1522fd4e5da5Sopenharmony_ci "", 1523fd4e5da5Sopenharmony_ci // execution_model 1524fd4e5da5Sopenharmony_ci "GLCompute", 1525fd4e5da5Sopenharmony_ci // memory_model 1526fd4e5da5Sopenharmony_ci "OpMemoryModel Logical VulkanKHR"), 1527fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 1528fd4e5da5Sopenharmony_ci 1529fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 1530fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1531fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04640")); 1532fd4e5da5Sopenharmony_ci EXPECT_THAT( 1533fd4e5da5Sopenharmony_ci getDiagnosticString(), 1534fd4e5da5Sopenharmony_ci HasSubstr( 1535fd4e5da5Sopenharmony_ci "ShaderCallKHR Memory Scope requires a ray tracing execution model")); 1536fd4e5da5Sopenharmony_ci} 1537fd4e5da5Sopenharmony_ci 1538fd4e5da5Sopenharmony_ciTEST_F(ValidateBarriers, OpControlBarrierShaderCallRayGenFailure) { 1539fd4e5da5Sopenharmony_ci const std::string body = "OpControlBarrier %shadercall %shadercall %none"; 1540fd4e5da5Sopenharmony_ci 1541fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCodeImpl(body, 1542fd4e5da5Sopenharmony_ci // capabilities_and_extensions 1543fd4e5da5Sopenharmony_ci R"( 1544fd4e5da5Sopenharmony_ci OpCapability VulkanMemoryModelKHR 1545fd4e5da5Sopenharmony_ci OpCapability RayTracingKHR 1546fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_vulkan_memory_model" 1547fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_ray_tracing" 1548fd4e5da5Sopenharmony_ci )", 1549fd4e5da5Sopenharmony_ci // definitions 1550fd4e5da5Sopenharmony_ci "", 1551fd4e5da5Sopenharmony_ci // execution_model 1552fd4e5da5Sopenharmony_ci "RayGenerationKHR", 1553fd4e5da5Sopenharmony_ci // memory_model 1554fd4e5da5Sopenharmony_ci "OpMemoryModel Logical VulkanKHR"), 1555fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 1556fd4e5da5Sopenharmony_ci 1557fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 1558fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1559fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04636")); 1560fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1561fd4e5da5Sopenharmony_ci HasSubstr("in Vulkan environment Execution Scope is limited to " 1562fd4e5da5Sopenharmony_ci "Workgroup and Subgroup")); 1563fd4e5da5Sopenharmony_ci} 1564fd4e5da5Sopenharmony_ci 1565fd4e5da5Sopenharmony_ci} // namespace 1566fd4e5da5Sopenharmony_ci} // namespace val 1567fd4e5da5Sopenharmony_ci} // namespace spvtools 1568