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#include <vector> 18fd4e5da5Sopenharmony_ci 19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 20fd4e5da5Sopenharmony_ci#include "source/spirv_target_env.h" 21fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 22fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_cinamespace spvtools { 25fd4e5da5Sopenharmony_cinamespace val { 26fd4e5da5Sopenharmony_cinamespace { 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciusing ::testing::Combine; 29fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 30fd4e5da5Sopenharmony_ciusing ::testing::Values; 31fd4e5da5Sopenharmony_ciusing ::testing::ValuesIn; 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_ciusing ValidateMode = spvtest::ValidateBase<bool>; 34fd4e5da5Sopenharmony_ci 35fd4e5da5Sopenharmony_ciconst std::string kVoidFunction = R"(%void = OpTypeVoid 36fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 37fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 38fd4e5da5Sopenharmony_ci%entry = OpLabel 39fd4e5da5Sopenharmony_ciOpReturn 40fd4e5da5Sopenharmony_ciOpFunctionEnd 41fd4e5da5Sopenharmony_ci)"; 42fd4e5da5Sopenharmony_ci 43fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeNoMode) { 44fd4e5da5Sopenharmony_ci const std::string spirv = R"( 45fd4e5da5Sopenharmony_ciOpCapability Shader 46fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 47fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 48fd4e5da5Sopenharmony_ci)" + kVoidFunction; 49fd4e5da5Sopenharmony_ci 50fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 51fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 52fd4e5da5Sopenharmony_ci} 53fd4e5da5Sopenharmony_ci 54fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeNoModeVulkan) { 55fd4e5da5Sopenharmony_ci const std::string spirv = R"( 56fd4e5da5Sopenharmony_ciOpCapability Shader 57fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 58fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 59fd4e5da5Sopenharmony_ci)" + kVoidFunction; 60fd4e5da5Sopenharmony_ci 61fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_0; 62fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 63fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 64fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 65fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-LocalSize-06426")); 66fd4e5da5Sopenharmony_ci EXPECT_THAT( 67fd4e5da5Sopenharmony_ci getDiagnosticString(), 68fd4e5da5Sopenharmony_ci HasSubstr( 69fd4e5da5Sopenharmony_ci "In the Vulkan environment, GLCompute execution model entry " 70fd4e5da5Sopenharmony_ci "points require either the LocalSize or LocalSizeId execution mode " 71fd4e5da5Sopenharmony_ci "or an object decorated with WorkgroupSize must be specified.")); 72fd4e5da5Sopenharmony_ci} 73fd4e5da5Sopenharmony_ci 74fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeNoModeVulkanWorkgroupSize) { 75fd4e5da5Sopenharmony_ci const std::string spirv = R"( 76fd4e5da5Sopenharmony_ciOpCapability Shader 77fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 78fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 79fd4e5da5Sopenharmony_ciOpDecorate %int3_1 BuiltIn WorkgroupSize 80fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 81fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3 82fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 83fd4e5da5Sopenharmony_ci%int3_1 = OpConstantComposite %int3 %int_1 %int_1 %int_1 84fd4e5da5Sopenharmony_ci)" + kVoidFunction; 85fd4e5da5Sopenharmony_ci 86fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_0; 87fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 88fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 89fd4e5da5Sopenharmony_ci} 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeVulkanLocalSize) { 92fd4e5da5Sopenharmony_ci const std::string spirv = R"( 93fd4e5da5Sopenharmony_ciOpCapability Shader 94fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 95fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 96fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 97fd4e5da5Sopenharmony_ci)" + kVoidFunction; 98fd4e5da5Sopenharmony_ci 99fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_0; 100fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 101fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 102fd4e5da5Sopenharmony_ci} 103fd4e5da5Sopenharmony_ci 104fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeVulkanLocalSizeIdBad) { 105fd4e5da5Sopenharmony_ci const std::string spirv = R"( 106fd4e5da5Sopenharmony_ciOpCapability Shader 107fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 108fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 109fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 110fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 111fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 112fd4e5da5Sopenharmony_ci)" + kVoidFunction; 113fd4e5da5Sopenharmony_ci 114fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_1; // need SPIR-V 1.2 115fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 116fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 117fd4e5da5Sopenharmony_ci EXPECT_THAT( 118fd4e5da5Sopenharmony_ci getDiagnosticString(), 119fd4e5da5Sopenharmony_ci HasSubstr("LocalSizeId mode is not allowed by the current environment.")); 120fd4e5da5Sopenharmony_ci} 121fd4e5da5Sopenharmony_ci 122fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GLComputeVulkanLocalSizeIdGood) { 123fd4e5da5Sopenharmony_ci const std::string spirv = R"( 124fd4e5da5Sopenharmony_ciOpCapability Shader 125fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 126fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 127fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 128fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 129fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 130fd4e5da5Sopenharmony_ci)" + kVoidFunction; 131fd4e5da5Sopenharmony_ci 132fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_1; // need SPIR-V 1.2 133fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 134fd4e5da5Sopenharmony_ci spvValidatorOptionsSetAllowLocalSizeId(getValidatorOptions(), true); 135fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 136fd4e5da5Sopenharmony_ci} 137fd4e5da5Sopenharmony_ci 138fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentOriginLowerLeftVulkan) { 139fd4e5da5Sopenharmony_ci const std::string spirv = R"( 140fd4e5da5Sopenharmony_ciOpCapability Shader 141fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 142fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 143fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginLowerLeft 144fd4e5da5Sopenharmony_ci)" + kVoidFunction; 145fd4e5da5Sopenharmony_ci 146fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_0; 147fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 148fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 149fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 150fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OriginLowerLeft-04653")); 151fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 152fd4e5da5Sopenharmony_ci HasSubstr("In the Vulkan environment, the OriginLowerLeft " 153fd4e5da5Sopenharmony_ci "execution mode must not be used.")); 154fd4e5da5Sopenharmony_ci} 155fd4e5da5Sopenharmony_ci 156fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentPixelCenterIntegerVulkan) { 157fd4e5da5Sopenharmony_ci const std::string spirv = R"( 158fd4e5da5Sopenharmony_ciOpCapability Shader 159fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 160fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 161fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 162fd4e5da5Sopenharmony_ciOpExecutionMode %main PixelCenterInteger 163fd4e5da5Sopenharmony_ci)" + kVoidFunction; 164fd4e5da5Sopenharmony_ci 165fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_VULKAN_1_0; 166fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 167fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 168fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 169fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-PixelCenterInteger-04654")); 170fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 171fd4e5da5Sopenharmony_ci HasSubstr("In the Vulkan environment, the PixelCenterInteger " 172fd4e5da5Sopenharmony_ci "execution mode must not be used.")); 173fd4e5da5Sopenharmony_ci} 174fd4e5da5Sopenharmony_ci 175fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GeometryNoOutputMode) { 176fd4e5da5Sopenharmony_ci const std::string spirv = R"( 177fd4e5da5Sopenharmony_ciOpCapability Geometry 178fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 179fd4e5da5Sopenharmony_ciOpEntryPoint Geometry %main "main" 180fd4e5da5Sopenharmony_ciOpExecutionMode %main InputPoints 181fd4e5da5Sopenharmony_ci)" + kVoidFunction; 182fd4e5da5Sopenharmony_ci 183fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 184fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 185fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 186fd4e5da5Sopenharmony_ci HasSubstr("Geometry execution model entry points must specify " 187fd4e5da5Sopenharmony_ci "exactly one of OutputPoints, OutputLineStrip or " 188fd4e5da5Sopenharmony_ci "OutputTriangleStrip execution modes.")); 189fd4e5da5Sopenharmony_ci} 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, GeometryNoInputMode) { 192fd4e5da5Sopenharmony_ci const std::string spirv = R"( 193fd4e5da5Sopenharmony_ciOpCapability Geometry 194fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 195fd4e5da5Sopenharmony_ciOpEntryPoint Geometry %main "main" 196fd4e5da5Sopenharmony_ciOpExecutionMode %main OutputPoints 197fd4e5da5Sopenharmony_ci)" + kVoidFunction; 198fd4e5da5Sopenharmony_ci 199fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 200fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 201fd4e5da5Sopenharmony_ci EXPECT_THAT( 202fd4e5da5Sopenharmony_ci getDiagnosticString(), 203fd4e5da5Sopenharmony_ci HasSubstr("Geometry execution model entry points must specify exactly " 204fd4e5da5Sopenharmony_ci "one of InputPoints, InputLines, InputLinesAdjacency, " 205fd4e5da5Sopenharmony_ci "Triangles or InputTrianglesAdjacency execution modes.")); 206fd4e5da5Sopenharmony_ci} 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentNoOrigin) { 209fd4e5da5Sopenharmony_ci const std::string spirv = R"( 210fd4e5da5Sopenharmony_ciOpCapability Shader 211fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 212fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 213fd4e5da5Sopenharmony_ci)" + kVoidFunction; 214fd4e5da5Sopenharmony_ci 215fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 216fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 217fd4e5da5Sopenharmony_ci EXPECT_THAT( 218fd4e5da5Sopenharmony_ci getDiagnosticString(), 219fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points require either an " 220fd4e5da5Sopenharmony_ci "OriginUpperLeft or OriginLowerLeft execution mode.")); 221fd4e5da5Sopenharmony_ci} 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentBothOrigins) { 224fd4e5da5Sopenharmony_ci const std::string spirv = R"( 225fd4e5da5Sopenharmony_ciOpCapability Shader 226fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 227fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 228fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 229fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginLowerLeft 230fd4e5da5Sopenharmony_ci)" + kVoidFunction; 231fd4e5da5Sopenharmony_ci 232fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 233fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 234fd4e5da5Sopenharmony_ci EXPECT_THAT( 235fd4e5da5Sopenharmony_ci getDiagnosticString(), 236fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can only specify one of " 237fd4e5da5Sopenharmony_ci "OriginUpperLeft or OriginLowerLeft execution modes.")); 238fd4e5da5Sopenharmony_ci} 239fd4e5da5Sopenharmony_ci 240fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentDepthGreaterAndLess) { 241fd4e5da5Sopenharmony_ci const std::string spirv = R"( 242fd4e5da5Sopenharmony_ciOpCapability Shader 243fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 244fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 245fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 246fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthGreater 247fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthLess 248fd4e5da5Sopenharmony_ci)" + kVoidFunction; 249fd4e5da5Sopenharmony_ci 250fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 251fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 252fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 253fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at " 254fd4e5da5Sopenharmony_ci "most one of DepthGreater, DepthLess or DepthUnchanged " 255fd4e5da5Sopenharmony_ci "execution modes.")); 256fd4e5da5Sopenharmony_ci} 257fd4e5da5Sopenharmony_ci 258fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentDepthGreaterAndUnchanged) { 259fd4e5da5Sopenharmony_ci const std::string spirv = R"( 260fd4e5da5Sopenharmony_ciOpCapability Shader 261fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 262fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 263fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 264fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthGreater 265fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthUnchanged 266fd4e5da5Sopenharmony_ci)" + kVoidFunction; 267fd4e5da5Sopenharmony_ci 268fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 269fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 270fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 271fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at " 272fd4e5da5Sopenharmony_ci "most one of DepthGreater, DepthLess or DepthUnchanged " 273fd4e5da5Sopenharmony_ci "execution modes.")); 274fd4e5da5Sopenharmony_ci} 275fd4e5da5Sopenharmony_ci 276fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentDepthLessAndUnchanged) { 277fd4e5da5Sopenharmony_ci const std::string spirv = R"( 278fd4e5da5Sopenharmony_ciOpCapability Shader 279fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 280fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 281fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 282fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthLess 283fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthUnchanged 284fd4e5da5Sopenharmony_ci)" + kVoidFunction; 285fd4e5da5Sopenharmony_ci 286fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 287fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 288fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 289fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at " 290fd4e5da5Sopenharmony_ci "most one of DepthGreater, DepthLess or DepthUnchanged " 291fd4e5da5Sopenharmony_ci "execution modes.")); 292fd4e5da5Sopenharmony_ci} 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentAllDepths) { 295fd4e5da5Sopenharmony_ci const std::string spirv = R"( 296fd4e5da5Sopenharmony_ciOpCapability Shader 297fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 298fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 299fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 300fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthGreater 301fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthLess 302fd4e5da5Sopenharmony_ciOpExecutionMode %main DepthUnchanged 303fd4e5da5Sopenharmony_ci)" + kVoidFunction; 304fd4e5da5Sopenharmony_ci 305fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 306fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 307fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 308fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at " 309fd4e5da5Sopenharmony_ci "most one of DepthGreater, DepthLess or DepthUnchanged " 310fd4e5da5Sopenharmony_ci "execution modes.")); 311fd4e5da5Sopenharmony_ci} 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationControlSpacingEqualAndFractionalOdd) { 314fd4e5da5Sopenharmony_ci const std::string spirv = R"( 315fd4e5da5Sopenharmony_ciOpCapability Tessellation 316fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 317fd4e5da5Sopenharmony_ciOpEntryPoint TessellationControl %main "main" 318fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 319fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 320fd4e5da5Sopenharmony_ci)" + kVoidFunction; 321fd4e5da5Sopenharmony_ci 322fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 323fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 324fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 325fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 326fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 327fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 328fd4e5da5Sopenharmony_ci} 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationControlSpacingEqualAndSpacingFractionalEven) { 331fd4e5da5Sopenharmony_ci const std::string spirv = R"( 332fd4e5da5Sopenharmony_ciOpCapability Tessellation 333fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 334fd4e5da5Sopenharmony_ciOpEntryPoint TessellationControl %main "main" 335fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 336fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 337fd4e5da5Sopenharmony_ci)" + kVoidFunction; 338fd4e5da5Sopenharmony_ci 339fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 340fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 341fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 342fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 343fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 344fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 345fd4e5da5Sopenharmony_ci} 346fd4e5da5Sopenharmony_ci 347fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, 348fd4e5da5Sopenharmony_ci TessellationControlSpacingFractionalOddAndSpacingFractionalEven) { 349fd4e5da5Sopenharmony_ci const std::string spirv = R"( 350fd4e5da5Sopenharmony_ciOpCapability Tessellation 351fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 352fd4e5da5Sopenharmony_ciOpEntryPoint TessellationControl %main "main" 353fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 354fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 355fd4e5da5Sopenharmony_ci)" + kVoidFunction; 356fd4e5da5Sopenharmony_ci 357fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 358fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 359fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 360fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 361fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 362fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 363fd4e5da5Sopenharmony_ci} 364fd4e5da5Sopenharmony_ci 365fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationControlAllSpacing) { 366fd4e5da5Sopenharmony_ci const std::string spirv = R"( 367fd4e5da5Sopenharmony_ciOpCapability Tessellation 368fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 369fd4e5da5Sopenharmony_ciOpEntryPoint TessellationControl %main "main" 370fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 371fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 372fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 373fd4e5da5Sopenharmony_ci)" + kVoidFunction; 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 376fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 377fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 378fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 379fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 380fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 381fd4e5da5Sopenharmony_ci} 382fd4e5da5Sopenharmony_ci 383fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, 384fd4e5da5Sopenharmony_ci TessellationEvaluationSpacingEqualAndSpacingFractionalOdd) { 385fd4e5da5Sopenharmony_ci const std::string spirv = R"( 386fd4e5da5Sopenharmony_ciOpCapability Tessellation 387fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 388fd4e5da5Sopenharmony_ciOpEntryPoint TessellationEvaluation %main "main" 389fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 390fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 391fd4e5da5Sopenharmony_ci)" + kVoidFunction; 392fd4e5da5Sopenharmony_ci 393fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 394fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 395fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 396fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 397fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 398fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 399fd4e5da5Sopenharmony_ci} 400fd4e5da5Sopenharmony_ci 401fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, 402fd4e5da5Sopenharmony_ci TessellationEvaluationSpacingEqualAndSpacingFractionalEven) { 403fd4e5da5Sopenharmony_ci const std::string spirv = R"( 404fd4e5da5Sopenharmony_ciOpCapability Tessellation 405fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 406fd4e5da5Sopenharmony_ciOpEntryPoint TessellationEvaluation %main "main" 407fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 408fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 409fd4e5da5Sopenharmony_ci)" + kVoidFunction; 410fd4e5da5Sopenharmony_ci 411fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 412fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 413fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 414fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 415fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 416fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 417fd4e5da5Sopenharmony_ci} 418fd4e5da5Sopenharmony_ci 419fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, 420fd4e5da5Sopenharmony_ci TessellationEvaluationSpacingFractionalOddAndSpacingFractionalEven) { 421fd4e5da5Sopenharmony_ci const std::string spirv = R"( 422fd4e5da5Sopenharmony_ciOpCapability Tessellation 423fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 424fd4e5da5Sopenharmony_ciOpEntryPoint TessellationEvaluation %main "main" 425fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 426fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 427fd4e5da5Sopenharmony_ci)" + kVoidFunction; 428fd4e5da5Sopenharmony_ci 429fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 430fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 431fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 432fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 433fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 434fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 435fd4e5da5Sopenharmony_ci} 436fd4e5da5Sopenharmony_ci 437fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationEvaluationAllSpacing) { 438fd4e5da5Sopenharmony_ci const std::string spirv = R"( 439fd4e5da5Sopenharmony_ciOpCapability Tessellation 440fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 441fd4e5da5Sopenharmony_ciOpEntryPoint TessellationEvaluation %main "main" 442fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingEqual 443fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalOdd 444fd4e5da5Sopenharmony_ciOpExecutionMode %main SpacingFractionalEven 445fd4e5da5Sopenharmony_ci)" + kVoidFunction; 446fd4e5da5Sopenharmony_ci 447fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 448fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 449fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 450fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify " 451fd4e5da5Sopenharmony_ci "at most one of SpacingEqual, SpacingFractionalOdd or " 452fd4e5da5Sopenharmony_ci "SpacingFractionalEven execution modes.")); 453fd4e5da5Sopenharmony_ci} 454fd4e5da5Sopenharmony_ci 455fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationControlBothVertex) { 456fd4e5da5Sopenharmony_ci const std::string spirv = R"( 457fd4e5da5Sopenharmony_ciOpCapability Tessellation 458fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 459fd4e5da5Sopenharmony_ciOpEntryPoint TessellationControl %main "main" 460fd4e5da5Sopenharmony_ciOpExecutionMode %main VertexOrderCw 461fd4e5da5Sopenharmony_ciOpExecutionMode %main VertexOrderCcw 462fd4e5da5Sopenharmony_ci)" + kVoidFunction; 463fd4e5da5Sopenharmony_ci 464fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 465fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 466fd4e5da5Sopenharmony_ci EXPECT_THAT( 467fd4e5da5Sopenharmony_ci getDiagnosticString(), 468fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify at most " 469fd4e5da5Sopenharmony_ci "one of VertexOrderCw or VertexOrderCcw execution modes.")); 470fd4e5da5Sopenharmony_ci} 471fd4e5da5Sopenharmony_ci 472fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, TessellationEvaluationBothVertex) { 473fd4e5da5Sopenharmony_ci const std::string spirv = R"( 474fd4e5da5Sopenharmony_ciOpCapability Tessellation 475fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 476fd4e5da5Sopenharmony_ciOpEntryPoint TessellationEvaluation %main "main" 477fd4e5da5Sopenharmony_ciOpExecutionMode %main VertexOrderCw 478fd4e5da5Sopenharmony_ciOpExecutionMode %main VertexOrderCcw 479fd4e5da5Sopenharmony_ci)" + kVoidFunction; 480fd4e5da5Sopenharmony_ci 481fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 482fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 483fd4e5da5Sopenharmony_ci EXPECT_THAT( 484fd4e5da5Sopenharmony_ci getDiagnosticString(), 485fd4e5da5Sopenharmony_ci HasSubstr("Tessellation execution model entry points can specify at most " 486fd4e5da5Sopenharmony_ci "one of VertexOrderCw or VertexOrderCcw execution modes.")); 487fd4e5da5Sopenharmony_ci} 488fd4e5da5Sopenharmony_ci 489fd4e5da5Sopenharmony_ciusing ValidateModeGeometry = spvtest::ValidateBase<std::tuple< 490fd4e5da5Sopenharmony_ci std::tuple<std::string, std::string, std::string, std::string, std::string>, 491fd4e5da5Sopenharmony_ci std::tuple<std::string, std::string, std::string>>>; 492fd4e5da5Sopenharmony_ci 493fd4e5da5Sopenharmony_ciTEST_P(ValidateModeGeometry, ExecutionMode) { 494fd4e5da5Sopenharmony_ci std::vector<std::string> input_modes; 495fd4e5da5Sopenharmony_ci std::vector<std::string> output_modes; 496fd4e5da5Sopenharmony_ci input_modes.push_back(std::get<0>(std::get<0>(GetParam()))); 497fd4e5da5Sopenharmony_ci input_modes.push_back(std::get<1>(std::get<0>(GetParam()))); 498fd4e5da5Sopenharmony_ci input_modes.push_back(std::get<2>(std::get<0>(GetParam()))); 499fd4e5da5Sopenharmony_ci input_modes.push_back(std::get<3>(std::get<0>(GetParam()))); 500fd4e5da5Sopenharmony_ci input_modes.push_back(std::get<4>(std::get<0>(GetParam()))); 501fd4e5da5Sopenharmony_ci output_modes.push_back(std::get<0>(std::get<1>(GetParam()))); 502fd4e5da5Sopenharmony_ci output_modes.push_back(std::get<1>(std::get<1>(GetParam()))); 503fd4e5da5Sopenharmony_ci output_modes.push_back(std::get<2>(std::get<1>(GetParam()))); 504fd4e5da5Sopenharmony_ci 505fd4e5da5Sopenharmony_ci std::ostringstream sstr; 506fd4e5da5Sopenharmony_ci sstr << "OpCapability Geometry\n"; 507fd4e5da5Sopenharmony_ci sstr << "OpMemoryModel Logical GLSL450\n"; 508fd4e5da5Sopenharmony_ci sstr << "OpEntryPoint Geometry %main \"main\"\n"; 509fd4e5da5Sopenharmony_ci size_t num_input_modes = 0; 510fd4e5da5Sopenharmony_ci for (auto input : input_modes) { 511fd4e5da5Sopenharmony_ci if (!input.empty()) { 512fd4e5da5Sopenharmony_ci num_input_modes++; 513fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main " << input << "\n"; 514fd4e5da5Sopenharmony_ci } 515fd4e5da5Sopenharmony_ci } 516fd4e5da5Sopenharmony_ci size_t num_output_modes = 0; 517fd4e5da5Sopenharmony_ci for (auto output : output_modes) { 518fd4e5da5Sopenharmony_ci if (!output.empty()) { 519fd4e5da5Sopenharmony_ci num_output_modes++; 520fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main " << output << "\n"; 521fd4e5da5Sopenharmony_ci } 522fd4e5da5Sopenharmony_ci } 523fd4e5da5Sopenharmony_ci sstr << "%void = OpTypeVoid\n"; 524fd4e5da5Sopenharmony_ci sstr << "%void_fn = OpTypeFunction %void\n"; 525fd4e5da5Sopenharmony_ci sstr << "%int = OpTypeInt 32 0\n"; 526fd4e5da5Sopenharmony_ci sstr << "%int1 = OpConstant %int 1\n"; 527fd4e5da5Sopenharmony_ci sstr << "%main = OpFunction %void None %void_fn\n"; 528fd4e5da5Sopenharmony_ci sstr << "%entry = OpLabel\n"; 529fd4e5da5Sopenharmony_ci sstr << "OpReturn\n"; 530fd4e5da5Sopenharmony_ci sstr << "OpFunctionEnd\n"; 531fd4e5da5Sopenharmony_ci 532fd4e5da5Sopenharmony_ci CompileSuccessfully(sstr.str()); 533fd4e5da5Sopenharmony_ci if (num_input_modes == 1 && num_output_modes == 1) { 534fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 535fd4e5da5Sopenharmony_ci } else { 536fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 537fd4e5da5Sopenharmony_ci if (num_input_modes != 1) { 538fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 539fd4e5da5Sopenharmony_ci HasSubstr("Geometry execution model entry points must " 540fd4e5da5Sopenharmony_ci "specify exactly one of InputPoints, InputLines, " 541fd4e5da5Sopenharmony_ci "InputLinesAdjacency, Triangles or " 542fd4e5da5Sopenharmony_ci "InputTrianglesAdjacency execution modes.")); 543fd4e5da5Sopenharmony_ci } else { 544fd4e5da5Sopenharmony_ci EXPECT_THAT( 545fd4e5da5Sopenharmony_ci getDiagnosticString(), 546fd4e5da5Sopenharmony_ci HasSubstr("Geometry execution model entry points must specify " 547fd4e5da5Sopenharmony_ci "exactly one of OutputPoints, OutputLineStrip or " 548fd4e5da5Sopenharmony_ci "OutputTriangleStrip execution modes.")); 549fd4e5da5Sopenharmony_ci } 550fd4e5da5Sopenharmony_ci } 551fd4e5da5Sopenharmony_ci} 552fd4e5da5Sopenharmony_ci 553fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 554fd4e5da5Sopenharmony_ci GeometryRequiredModes, ValidateModeGeometry, 555fd4e5da5Sopenharmony_ci Combine(Combine(Values("InputPoints", ""), Values("InputLines", ""), 556fd4e5da5Sopenharmony_ci Values("InputLinesAdjacency", ""), Values("Triangles", ""), 557fd4e5da5Sopenharmony_ci Values("InputTrianglesAdjacency", "")), 558fd4e5da5Sopenharmony_ci Combine(Values("OutputPoints", ""), Values("OutputLineStrip", ""), 559fd4e5da5Sopenharmony_ci Values("OutputTriangleStrip", "")))); 560fd4e5da5Sopenharmony_ci 561fd4e5da5Sopenharmony_ciusing ValidateModeExecution = 562fd4e5da5Sopenharmony_ci spvtest::ValidateBase<std::tuple<spv_result_t, std::string, std::string, 563fd4e5da5Sopenharmony_ci std::string, spv_target_env>>; 564fd4e5da5Sopenharmony_ci 565fd4e5da5Sopenharmony_ciTEST_P(ValidateModeExecution, ExecutionMode) { 566fd4e5da5Sopenharmony_ci const spv_result_t expectation = std::get<0>(GetParam()); 567fd4e5da5Sopenharmony_ci const std::string error = std::get<1>(GetParam()); 568fd4e5da5Sopenharmony_ci const std::string model = std::get<2>(GetParam()); 569fd4e5da5Sopenharmony_ci const std::string mode = std::get<3>(GetParam()); 570fd4e5da5Sopenharmony_ci const spv_target_env env = std::get<4>(GetParam()); 571fd4e5da5Sopenharmony_ci 572fd4e5da5Sopenharmony_ci std::ostringstream sstr; 573fd4e5da5Sopenharmony_ci sstr << "OpCapability Shader\n"; 574fd4e5da5Sopenharmony_ci sstr << "OpCapability Geometry\n"; 575fd4e5da5Sopenharmony_ci sstr << "OpCapability Tessellation\n"; 576fd4e5da5Sopenharmony_ci sstr << "OpCapability TransformFeedback\n"; 577fd4e5da5Sopenharmony_ci if (!spvIsVulkanEnv(env)) { 578fd4e5da5Sopenharmony_ci sstr << "OpCapability Kernel\n"; 579fd4e5da5Sopenharmony_ci if (env == SPV_ENV_UNIVERSAL_1_3) { 580fd4e5da5Sopenharmony_ci sstr << "OpCapability SubgroupDispatch\n"; 581fd4e5da5Sopenharmony_ci } else if (env == SPV_ENV_UNIVERSAL_1_5) { 582fd4e5da5Sopenharmony_ci sstr << "OpCapability TileImageColorReadAccessEXT\n"; 583fd4e5da5Sopenharmony_ci sstr << "OpCapability TileImageDepthReadAccessEXT\n"; 584fd4e5da5Sopenharmony_ci sstr << "OpCapability TileImageStencilReadAccessEXT\n"; 585fd4e5da5Sopenharmony_ci sstr << "OpExtension \"SPV_EXT_shader_tile_image\"\n"; 586fd4e5da5Sopenharmony_ci } 587fd4e5da5Sopenharmony_ci } 588fd4e5da5Sopenharmony_ci sstr << "OpMemoryModel Logical GLSL450\n"; 589fd4e5da5Sopenharmony_ci sstr << "OpEntryPoint " << model << " %main \"main\"\n"; 590fd4e5da5Sopenharmony_ci if (mode.find("LocalSizeId") == 0 || mode.find("LocalSizeHintId") == 0 || 591fd4e5da5Sopenharmony_ci mode.find("SubgroupsPerWorkgroupId") == 0) { 592fd4e5da5Sopenharmony_ci sstr << "OpExecutionModeId %main " << mode << "\n"; 593fd4e5da5Sopenharmony_ci } else { 594fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main " << mode << "\n"; 595fd4e5da5Sopenharmony_ci } 596fd4e5da5Sopenharmony_ci if (model == "Geometry") { 597fd4e5da5Sopenharmony_ci if (!(mode.find("InputPoints") == 0 || mode.find("InputLines") == 0 || 598fd4e5da5Sopenharmony_ci mode.find("InputLinesAdjacency") == 0 || 599fd4e5da5Sopenharmony_ci mode.find("Triangles") == 0 || 600fd4e5da5Sopenharmony_ci mode.find("InputTrianglesAdjacency") == 0)) { 601fd4e5da5Sopenharmony_ci // Exactly one of the above modes is required for Geometry shaders. 602fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main InputPoints\n"; 603fd4e5da5Sopenharmony_ci } 604fd4e5da5Sopenharmony_ci if (!(mode.find("OutputPoints") == 0 || mode.find("OutputLineStrip") == 0 || 605fd4e5da5Sopenharmony_ci mode.find("OutputTriangleStrip") == 0)) { 606fd4e5da5Sopenharmony_ci // Exactly one of the above modes is required for Geometry shaders. 607fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main OutputPoints\n"; 608fd4e5da5Sopenharmony_ci } 609fd4e5da5Sopenharmony_ci } else if (model == "Fragment") { 610fd4e5da5Sopenharmony_ci if (!(mode.find("OriginUpperLeft") == 0 || 611fd4e5da5Sopenharmony_ci mode.find("OriginLowerLeft") == 0)) { 612fd4e5da5Sopenharmony_ci // Exactly one of the above modes is required for Fragment shaders. 613fd4e5da5Sopenharmony_ci sstr << "OpExecutionMode %main OriginUpperLeft\n"; 614fd4e5da5Sopenharmony_ci } 615fd4e5da5Sopenharmony_ci } 616fd4e5da5Sopenharmony_ci sstr << "%void = OpTypeVoid\n"; 617fd4e5da5Sopenharmony_ci sstr << "%void_fn = OpTypeFunction %void\n"; 618fd4e5da5Sopenharmony_ci sstr << "%int = OpTypeInt 32 0\n"; 619fd4e5da5Sopenharmony_ci sstr << "%int1 = OpConstant %int 1\n"; 620fd4e5da5Sopenharmony_ci sstr << "%main = OpFunction %void None %void_fn\n"; 621fd4e5da5Sopenharmony_ci sstr << "%entry = OpLabel\n"; 622fd4e5da5Sopenharmony_ci sstr << "OpReturn\n"; 623fd4e5da5Sopenharmony_ci sstr << "OpFunctionEnd\n"; 624fd4e5da5Sopenharmony_ci 625fd4e5da5Sopenharmony_ci CompileSuccessfully(sstr.str(), env); 626fd4e5da5Sopenharmony_ci EXPECT_THAT(expectation, ValidateInstructions(env)); 627fd4e5da5Sopenharmony_ci if (expectation != SPV_SUCCESS) { 628fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr(error)); 629fd4e5da5Sopenharmony_ci } 630fd4e5da5Sopenharmony_ci} 631fd4e5da5Sopenharmony_ci 632fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 633fd4e5da5Sopenharmony_ci ValidateModeGeometryOnlyGoodSpv10, ValidateModeExecution, 634fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), Values("Geometry"), 635fd4e5da5Sopenharmony_ci Values("Invocations 3", "InputPoints", "InputLines", 636fd4e5da5Sopenharmony_ci "InputLinesAdjacency", "InputTrianglesAdjacency", 637fd4e5da5Sopenharmony_ci "OutputPoints", "OutputLineStrip", "OutputTriangleStrip"), 638fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 639fd4e5da5Sopenharmony_ci 640fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 641fd4e5da5Sopenharmony_ci ValidateModeGeometryOnlyBadSpv10, ValidateModeExecution, 642fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 643fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with the Geometry " 644fd4e5da5Sopenharmony_ci "execution model."), 645fd4e5da5Sopenharmony_ci Values("Fragment", "TessellationEvaluation", "TessellationControl", 646fd4e5da5Sopenharmony_ci "GLCompute", "Vertex", "Kernel"), 647fd4e5da5Sopenharmony_ci Values("Invocations 3", "InputPoints", "InputLines", 648fd4e5da5Sopenharmony_ci "InputLinesAdjacency", "InputTrianglesAdjacency", 649fd4e5da5Sopenharmony_ci "OutputPoints", "OutputLineStrip", "OutputTriangleStrip"), 650fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 651fd4e5da5Sopenharmony_ci 652fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 653fd4e5da5Sopenharmony_ci ValidateModeTessellationOnlyGoodSpv10, ValidateModeExecution, 654fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), 655fd4e5da5Sopenharmony_ci Values("TessellationControl", "TessellationEvaluation"), 656fd4e5da5Sopenharmony_ci Values("SpacingEqual", "SpacingFractionalEven", 657fd4e5da5Sopenharmony_ci "SpacingFractionalOdd", "VertexOrderCw", "VertexOrderCcw", 658fd4e5da5Sopenharmony_ci "PointMode", "Quads", "Isolines"), 659fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 660fd4e5da5Sopenharmony_ci 661fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 662fd4e5da5Sopenharmony_ci ValidateModeTessellationOnlyBadSpv10, ValidateModeExecution, 663fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 664fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with a tessellation " 665fd4e5da5Sopenharmony_ci "execution model."), 666fd4e5da5Sopenharmony_ci Values("Fragment", "Geometry", "GLCompute", "Vertex", "Kernel"), 667fd4e5da5Sopenharmony_ci Values("SpacingEqual", "SpacingFractionalEven", 668fd4e5da5Sopenharmony_ci "SpacingFractionalOdd", "VertexOrderCw", "VertexOrderCcw", 669fd4e5da5Sopenharmony_ci "PointMode", "Quads", "Isolines"), 670fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 671fd4e5da5Sopenharmony_ci 672fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateModeGeometryAndTessellationGoodSpv10, 673fd4e5da5Sopenharmony_ci ValidateModeExecution, 674fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), 675fd4e5da5Sopenharmony_ci Values("TessellationControl", 676fd4e5da5Sopenharmony_ci "TessellationEvaluation", "Geometry"), 677fd4e5da5Sopenharmony_ci Values("Triangles", "OutputVertices 3"), 678fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 679fd4e5da5Sopenharmony_ci 680fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 681fd4e5da5Sopenharmony_ci ValidateModeGeometryAndTessellationBadSpv10, ValidateModeExecution, 682fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 683fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with a Geometry or " 684fd4e5da5Sopenharmony_ci "tessellation execution model."), 685fd4e5da5Sopenharmony_ci Values("Fragment", "GLCompute", "Vertex", "Kernel"), 686fd4e5da5Sopenharmony_ci Values("Triangles", "OutputVertices 3"), 687fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 688fd4e5da5Sopenharmony_ci 689fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 690fd4e5da5Sopenharmony_ci ValidateModeFragmentOnlyGoodSpv10, ValidateModeExecution, 691fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), Values("Fragment"), 692fd4e5da5Sopenharmony_ci Values("PixelCenterInteger", "OriginUpperLeft", "OriginLowerLeft", 693fd4e5da5Sopenharmony_ci "EarlyFragmentTests", "DepthReplacing", "DepthLess", 694fd4e5da5Sopenharmony_ci "DepthUnchanged"), 695fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 696fd4e5da5Sopenharmony_ci 697fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 698fd4e5da5Sopenharmony_ci ValidateModeFragmentOnlyBadSpv10, ValidateModeExecution, 699fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 700fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with the Fragment " 701fd4e5da5Sopenharmony_ci "execution model."), 702fd4e5da5Sopenharmony_ci Values("Geometry", "TessellationControl", "TessellationEvaluation", 703fd4e5da5Sopenharmony_ci "GLCompute", "Vertex", "Kernel"), 704fd4e5da5Sopenharmony_ci Values("PixelCenterInteger", "OriginUpperLeft", "OriginLowerLeft", 705fd4e5da5Sopenharmony_ci "EarlyFragmentTests", "DepthReplacing", "DepthGreater", 706fd4e5da5Sopenharmony_ci "DepthLess", "DepthUnchanged"), 707fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_0))); 708fd4e5da5Sopenharmony_ci 709fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateModeFragmentOnlyGoodSpv15, 710fd4e5da5Sopenharmony_ci ValidateModeExecution, 711fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), 712fd4e5da5Sopenharmony_ci Values("Fragment"), 713fd4e5da5Sopenharmony_ci Values("NonCoherentColorAttachmentReadEXT", 714fd4e5da5Sopenharmony_ci "NonCoherentDepthAttachmentReadEXT", 715fd4e5da5Sopenharmony_ci "NonCoherentStencilAttachmentReadEXT"), 716fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_5))); 717fd4e5da5Sopenharmony_ci 718fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 719fd4e5da5Sopenharmony_ci ValidateModeFragmentOnlyBadSpv15, ValidateModeExecution, 720fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 721fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with the Fragment " 722fd4e5da5Sopenharmony_ci "execution model."), 723fd4e5da5Sopenharmony_ci Values("Geometry", "TessellationControl", "TessellationEvaluation", 724fd4e5da5Sopenharmony_ci "GLCompute", "Vertex", "Kernel"), 725fd4e5da5Sopenharmony_ci Values("NonCoherentColorAttachmentReadEXT", 726fd4e5da5Sopenharmony_ci "NonCoherentDepthAttachmentReadEXT", 727fd4e5da5Sopenharmony_ci "NonCoherentStencilAttachmentReadEXT"), 728fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_5))); 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(ValidateModeKernelOnlyGoodSpv13, ValidateModeExecution, 731fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), 732fd4e5da5Sopenharmony_ci Values("Kernel"), 733fd4e5da5Sopenharmony_ci Values("LocalSizeHint 1 1 1", "VecTypeHint 4", 734fd4e5da5Sopenharmony_ci "ContractionOff", 735fd4e5da5Sopenharmony_ci "LocalSizeHintId %int1 %int1 %int1"), 736fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_3))); 737fd4e5da5Sopenharmony_ci 738fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 739fd4e5da5Sopenharmony_ci ValidateModeKernelOnlyBadSpv13, ValidateModeExecution, 740fd4e5da5Sopenharmony_ci Combine( 741fd4e5da5Sopenharmony_ci Values(SPV_ERROR_INVALID_DATA), 742fd4e5da5Sopenharmony_ci Values( 743fd4e5da5Sopenharmony_ci "Execution mode can only be used with the Kernel execution model."), 744fd4e5da5Sopenharmony_ci Values("Geometry", "TessellationControl", "TessellationEvaluation", 745fd4e5da5Sopenharmony_ci "GLCompute", "Vertex", "Fragment"), 746fd4e5da5Sopenharmony_ci Values("LocalSizeHint 1 1 1", "VecTypeHint 4", "ContractionOff", 747fd4e5da5Sopenharmony_ci "LocalSizeHintId %int1 %int1 %int1"), 748fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_3))); 749fd4e5da5Sopenharmony_ci 750fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 751fd4e5da5Sopenharmony_ci ValidateModeGLComputeAndKernelGoodSpv13, ValidateModeExecution, 752fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), Values("Kernel", "GLCompute"), 753fd4e5da5Sopenharmony_ci Values("LocalSize 1 1 1", "LocalSizeId %int1 %int1 %int1"), 754fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_3))); 755fd4e5da5Sopenharmony_ci 756fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 757fd4e5da5Sopenharmony_ci ValidateModeGLComputeAndKernelBadSpv13, ValidateModeExecution, 758fd4e5da5Sopenharmony_ci Combine(Values(SPV_ERROR_INVALID_DATA), 759fd4e5da5Sopenharmony_ci Values("Execution mode can only be used with a Kernel or GLCompute " 760fd4e5da5Sopenharmony_ci "execution model."), 761fd4e5da5Sopenharmony_ci Values("Geometry", "TessellationControl", "TessellationEvaluation", 762fd4e5da5Sopenharmony_ci "Fragment", "Vertex"), 763fd4e5da5Sopenharmony_ci Values("LocalSize 1 1 1", "LocalSizeId %int1 %int1 %int1"), 764fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_3))); 765fd4e5da5Sopenharmony_ci 766fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 767fd4e5da5Sopenharmony_ci ValidateModeAllGoodSpv13, ValidateModeExecution, 768fd4e5da5Sopenharmony_ci Combine(Values(SPV_SUCCESS), Values(""), 769fd4e5da5Sopenharmony_ci Values("Kernel", "GLCompute", "Geometry", "TessellationControl", 770fd4e5da5Sopenharmony_ci "TessellationEvaluation", "Fragment", "Vertex"), 771fd4e5da5Sopenharmony_ci Values("Xfb", "Initializer", "Finalizer", "SubgroupSize 1", 772fd4e5da5Sopenharmony_ci "SubgroupsPerWorkgroup 1", "SubgroupsPerWorkgroupId %int1"), 773fd4e5da5Sopenharmony_ci Values(SPV_ENV_UNIVERSAL_1_3))); 774fd4e5da5Sopenharmony_ci 775fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, MeshNVLocalSize) { 776fd4e5da5Sopenharmony_ci const std::string spirv = R"( 777fd4e5da5Sopenharmony_ciOpCapability Shader 778fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 779fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 780fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 781fd4e5da5Sopenharmony_ciOpEntryPoint MeshNV %main "main" 782fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 783fd4e5da5Sopenharmony_ci)" + kVoidFunction; 784fd4e5da5Sopenharmony_ci 785fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 786fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 787fd4e5da5Sopenharmony_ci} 788fd4e5da5Sopenharmony_ci 789fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, TaskNVLocalSize) { 790fd4e5da5Sopenharmony_ci const std::string spirv = R"( 791fd4e5da5Sopenharmony_ciOpCapability Shader 792fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 793fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 794fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 795fd4e5da5Sopenharmony_ciOpEntryPoint TaskNV %main "main" 796fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 797fd4e5da5Sopenharmony_ci)" + kVoidFunction; 798fd4e5da5Sopenharmony_ci 799fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 800fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 801fd4e5da5Sopenharmony_ci} 802fd4e5da5Sopenharmony_ci 803fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, MeshNVOutputPoints) { 804fd4e5da5Sopenharmony_ci const std::string spirv = R"( 805fd4e5da5Sopenharmony_ciOpCapability Shader 806fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 807fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 808fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 809fd4e5da5Sopenharmony_ciOpEntryPoint MeshNV %main "main" 810fd4e5da5Sopenharmony_ciOpExecutionMode %main OutputPoints 811fd4e5da5Sopenharmony_ci)" + kVoidFunction; 812fd4e5da5Sopenharmony_ci 813fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 814fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 815fd4e5da5Sopenharmony_ci} 816fd4e5da5Sopenharmony_ci 817fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, MeshNVOutputVertices) { 818fd4e5da5Sopenharmony_ci const std::string spirv = R"( 819fd4e5da5Sopenharmony_ciOpCapability Shader 820fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 821fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 822fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 823fd4e5da5Sopenharmony_ciOpEntryPoint MeshNV %main "main" 824fd4e5da5Sopenharmony_ciOpExecutionMode %main OutputVertices 42 825fd4e5da5Sopenharmony_ci)" + kVoidFunction; 826fd4e5da5Sopenharmony_ci 827fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 828fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 829fd4e5da5Sopenharmony_ci} 830fd4e5da5Sopenharmony_ci 831fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, MeshNVLocalSizeId) { 832fd4e5da5Sopenharmony_ci const std::string spirv = R"( 833fd4e5da5Sopenharmony_ciOpCapability Shader 834fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 835fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 836fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 837fd4e5da5Sopenharmony_ciOpEntryPoint MeshNV %main "main" 838fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 839fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 840fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 841fd4e5da5Sopenharmony_ci)" + kVoidFunction; 842fd4e5da5Sopenharmony_ci 843fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 844fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 845fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 846fd4e5da5Sopenharmony_ci} 847fd4e5da5Sopenharmony_ci 848fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, TaskNVLocalSizeId) { 849fd4e5da5Sopenharmony_ci const std::string spirv = R"( 850fd4e5da5Sopenharmony_ciOpCapability Shader 851fd4e5da5Sopenharmony_ciOpCapability MeshShadingNV 852fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_mesh_shader" 853fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 854fd4e5da5Sopenharmony_ciOpEntryPoint TaskNV %main "main" 855fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 856fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 857fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 858fd4e5da5Sopenharmony_ci)" + kVoidFunction; 859fd4e5da5Sopenharmony_ci 860fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 861fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 862fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 863fd4e5da5Sopenharmony_ci} 864fd4e5da5Sopenharmony_ci 865fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeSubgroupsPerWorkgroupIdBad) { 866fd4e5da5Sopenharmony_ci const std::string spirv = R"( 867fd4e5da5Sopenharmony_ciOpCapability Shader 868fd4e5da5Sopenharmony_ciOpCapability SubgroupDispatch 869fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 870fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 871fd4e5da5Sopenharmony_ciOpExecutionMode %main SubgroupsPerWorkgroupId %int_1 872fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 873fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 874fd4e5da5Sopenharmony_ci)" + kVoidFunction; 875fd4e5da5Sopenharmony_ci 876fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 877fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 878fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 879fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 880fd4e5da5Sopenharmony_ci HasSubstr("OpExecutionMode is only valid when the Mode operand " 881fd4e5da5Sopenharmony_ci "is an execution mode that takes no Extra Operands")); 882fd4e5da5Sopenharmony_ci} 883fd4e5da5Sopenharmony_ci 884fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdSubgroupsPerWorkgroupIdGood) { 885fd4e5da5Sopenharmony_ci const std::string spirv = R"( 886fd4e5da5Sopenharmony_ciOpCapability Shader 887fd4e5da5Sopenharmony_ciOpCapability SubgroupDispatch 888fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 889fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 890fd4e5da5Sopenharmony_ciOpExecutionModeId %main SubgroupsPerWorkgroupId %int_1 891fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 892fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 893fd4e5da5Sopenharmony_ci)" + kVoidFunction; 894fd4e5da5Sopenharmony_ci 895fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 896fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 897fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 898fd4e5da5Sopenharmony_ci} 899fd4e5da5Sopenharmony_ci 900fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdSubgroupsPerWorkgroupIdNonConstantBad) { 901fd4e5da5Sopenharmony_ci const std::string spirv = R"( 902fd4e5da5Sopenharmony_ciOpCapability Shader 903fd4e5da5Sopenharmony_ciOpCapability SubgroupDispatch 904fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 905fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 906fd4e5da5Sopenharmony_ciOpExecutionModeId %main SubgroupsPerWorkgroupId %int_1 907fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 908fd4e5da5Sopenharmony_ci%int_ptr = OpTypePointer Private %int 909fd4e5da5Sopenharmony_ci%int_1 = OpVariable %int_ptr Private 910fd4e5da5Sopenharmony_ci)" + kVoidFunction; 911fd4e5da5Sopenharmony_ci 912fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 913fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 914fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env)); 915fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 916fd4e5da5Sopenharmony_ci HasSubstr("For OpExecutionModeId all Extra Operand ids must be " 917fd4e5da5Sopenharmony_ci "constant instructions.")); 918fd4e5da5Sopenharmony_ci} 919fd4e5da5Sopenharmony_ci 920fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeLocalSizeHintIdBad) { 921fd4e5da5Sopenharmony_ci const std::string spirv = R"( 922fd4e5da5Sopenharmony_ciOpCapability Kernel 923fd4e5da5Sopenharmony_ciOpCapability Shader 924fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 925fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %main "main" 926fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSizeHintId %int_1 %int_1 %int_1 927fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 928fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 929fd4e5da5Sopenharmony_ci)" + kVoidFunction; 930fd4e5da5Sopenharmony_ci 931fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 932fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 933fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 934fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 935fd4e5da5Sopenharmony_ci HasSubstr("OpExecutionMode is only valid when the Mode operand " 936fd4e5da5Sopenharmony_ci "is an execution mode that takes no Extra Operands")); 937fd4e5da5Sopenharmony_ci} 938fd4e5da5Sopenharmony_ci 939fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdLocalSizeHintIdGood) { 940fd4e5da5Sopenharmony_ci const std::string spirv = R"( 941fd4e5da5Sopenharmony_ciOpCapability Kernel 942fd4e5da5Sopenharmony_ciOpCapability Shader 943fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 944fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %main "main" 945fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeHintId %int_1 %int_1 %int_1 946fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 947fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 948fd4e5da5Sopenharmony_ci)" + kVoidFunction; 949fd4e5da5Sopenharmony_ci 950fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 951fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 952fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 953fd4e5da5Sopenharmony_ci} 954fd4e5da5Sopenharmony_ci 955fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdLocalSizeHintIdNonConstantBad) { 956fd4e5da5Sopenharmony_ci const std::string spirv = R"( 957fd4e5da5Sopenharmony_ciOpCapability Kernel 958fd4e5da5Sopenharmony_ciOpCapability Shader 959fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 960fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 961fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeHintId %int_1 %int_1 %int_1 962fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 963fd4e5da5Sopenharmony_ci%int_ptr = OpTypePointer Private %int 964fd4e5da5Sopenharmony_ci%int_1 = OpVariable %int_ptr Private 965fd4e5da5Sopenharmony_ci)" + kVoidFunction; 966fd4e5da5Sopenharmony_ci 967fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 968fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 969fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env)); 970fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 971fd4e5da5Sopenharmony_ci HasSubstr("For OpExecutionModeId all Extra Operand ids must be " 972fd4e5da5Sopenharmony_ci "constant instructions.")); 973fd4e5da5Sopenharmony_ci} 974fd4e5da5Sopenharmony_ci 975fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeLocalSizeIdBad) { 976fd4e5da5Sopenharmony_ci const std::string spirv = R"( 977fd4e5da5Sopenharmony_ciOpCapability Kernel 978fd4e5da5Sopenharmony_ciOpCapability Shader 979fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 980fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %main "main" 981fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSizeId %int_1 %int_1 %int_1 982fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 983fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 984fd4e5da5Sopenharmony_ci)" + kVoidFunction; 985fd4e5da5Sopenharmony_ci 986fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 987fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 988fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); 989fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 990fd4e5da5Sopenharmony_ci HasSubstr("OpExecutionMode is only valid when the Mode operand " 991fd4e5da5Sopenharmony_ci "is an execution mode that takes no Extra Operands")); 992fd4e5da5Sopenharmony_ci} 993fd4e5da5Sopenharmony_ci 994fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdLocalSizeIdGood) { 995fd4e5da5Sopenharmony_ci const std::string spirv = R"( 996fd4e5da5Sopenharmony_ciOpCapability Kernel 997fd4e5da5Sopenharmony_ciOpCapability Shader 998fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 999fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %main "main" 1000fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 1001fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1002fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1003fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1004fd4e5da5Sopenharmony_ci 1005fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 1006fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 1007fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(env)); 1008fd4e5da5Sopenharmony_ci} 1009fd4e5da5Sopenharmony_ci 1010fd4e5da5Sopenharmony_ciTEST_F(ValidateModeExecution, ExecModeIdLocalSizeIdNonConstantBad) { 1011fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1012fd4e5da5Sopenharmony_ciOpCapability Kernel 1013fd4e5da5Sopenharmony_ciOpCapability Shader 1014fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1015fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 1016fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 1017fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1018fd4e5da5Sopenharmony_ci%int_ptr = OpTypePointer Private %int 1019fd4e5da5Sopenharmony_ci%int_1 = OpVariable %int_ptr Private 1020fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1021fd4e5da5Sopenharmony_ci 1022fd4e5da5Sopenharmony_ci spv_target_env env = SPV_ENV_UNIVERSAL_1_3; 1023fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, env); 1024fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(env)); 1025fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1026fd4e5da5Sopenharmony_ci HasSubstr("For OpExecutionModeId all Extra Operand ids must be " 1027fd4e5da5Sopenharmony_ci "constant instructions.")); 1028fd4e5da5Sopenharmony_ci} 1029fd4e5da5Sopenharmony_ci 1030fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderInterlockVertexBad) { 1031fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1032fd4e5da5Sopenharmony_ciOpCapability Shader 1033fd4e5da5Sopenharmony_ciOpCapability FragmentShaderPixelInterlockEXT 1034fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_fragment_shader_interlock" 1035fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1036fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 1037fd4e5da5Sopenharmony_ciOpExecutionMode %main PixelInterlockOrderedEXT 1038fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1039fd4e5da5Sopenharmony_ci 1040fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1041fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1042fd4e5da5Sopenharmony_ci EXPECT_THAT( 1043fd4e5da5Sopenharmony_ci getDiagnosticString(), 1044fd4e5da5Sopenharmony_ci HasSubstr( 1045fd4e5da5Sopenharmony_ci "Execution mode can only be used with the Fragment execution model")); 1046fd4e5da5Sopenharmony_ci} 1047fd4e5da5Sopenharmony_ci 1048fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderInterlockTooManyModesBad) { 1049fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1050fd4e5da5Sopenharmony_ciOpCapability Shader 1051fd4e5da5Sopenharmony_ciOpCapability FragmentShaderPixelInterlockEXT 1052fd4e5da5Sopenharmony_ciOpCapability FragmentShaderSampleInterlockEXT 1053fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_fragment_shader_interlock" 1054fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1055fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1056fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1057fd4e5da5Sopenharmony_ciOpExecutionMode %main PixelInterlockOrderedEXT 1058fd4e5da5Sopenharmony_ciOpExecutionMode %main SampleInterlockOrderedEXT 1059fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1060fd4e5da5Sopenharmony_ci 1061fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1062fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1063fd4e5da5Sopenharmony_ci EXPECT_THAT( 1064fd4e5da5Sopenharmony_ci getDiagnosticString(), 1065fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at most " 1066fd4e5da5Sopenharmony_ci "one fragment shader interlock execution mode")); 1067fd4e5da5Sopenharmony_ci} 1068fd4e5da5Sopenharmony_ci 1069fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderInterlockNoModeBad) { 1070fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1071fd4e5da5Sopenharmony_ciOpCapability Shader 1072fd4e5da5Sopenharmony_ciOpCapability FragmentShaderPixelInterlockEXT 1073fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_fragment_shader_interlock" 1074fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1075fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1076fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1077fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1078fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1079fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1080fd4e5da5Sopenharmony_ci%entryf = OpLabel 1081fd4e5da5Sopenharmony_ciOpBeginInvocationInterlockEXT 1082fd4e5da5Sopenharmony_ciOpEndInvocationInterlockEXT 1083fd4e5da5Sopenharmony_ciOpReturn 1084fd4e5da5Sopenharmony_ciOpFunctionEnd 1085fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1086fd4e5da5Sopenharmony_ci%entry = OpLabel 1087fd4e5da5Sopenharmony_ci%1 = OpFunctionCall %void %func 1088fd4e5da5Sopenharmony_ciOpReturn 1089fd4e5da5Sopenharmony_ciOpFunctionEnd 1090fd4e5da5Sopenharmony_ci)"; 1091fd4e5da5Sopenharmony_ci 1092fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1093fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1094fd4e5da5Sopenharmony_ci EXPECT_THAT( 1095fd4e5da5Sopenharmony_ci getDiagnosticString(), 1096fd4e5da5Sopenharmony_ci HasSubstr( 1097fd4e5da5Sopenharmony_ci "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT require a " 1098fd4e5da5Sopenharmony_ci "fragment shader interlock execution mode")); 1099fd4e5da5Sopenharmony_ci} 1100fd4e5da5Sopenharmony_ci 1101fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderInterlockGood) { 1102fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1103fd4e5da5Sopenharmony_ciOpCapability Shader 1104fd4e5da5Sopenharmony_ciOpCapability FragmentShaderPixelInterlockEXT 1105fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_fragment_shader_interlock" 1106fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1107fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1108fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1109fd4e5da5Sopenharmony_ciOpExecutionMode %main PixelInterlockOrderedEXT 1110fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1111fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1112fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1113fd4e5da5Sopenharmony_ci%entryf = OpLabel 1114fd4e5da5Sopenharmony_ciOpBeginInvocationInterlockEXT 1115fd4e5da5Sopenharmony_ciOpEndInvocationInterlockEXT 1116fd4e5da5Sopenharmony_ciOpReturn 1117fd4e5da5Sopenharmony_ciOpFunctionEnd 1118fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1119fd4e5da5Sopenharmony_ci%entry = OpLabel 1120fd4e5da5Sopenharmony_ci%1 = OpFunctionCall %void %func 1121fd4e5da5Sopenharmony_ciOpReturn 1122fd4e5da5Sopenharmony_ciOpFunctionEnd 1123fd4e5da5Sopenharmony_ci)"; 1124fd4e5da5Sopenharmony_ci 1125fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1126fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 1127fd4e5da5Sopenharmony_ci} 1128fd4e5da5Sopenharmony_ci 1129fd4e5da5Sopenharmony_ci 1130fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderStencilRefFrontTooManyModesBad) { 1131fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1132fd4e5da5Sopenharmony_ciOpCapability Shader 1133fd4e5da5Sopenharmony_ciOpCapability StencilExportEXT 1134fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_shader_early_and_late_fragment_tests" 1135fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_stencil_export" 1136fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1137fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1138fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1139fd4e5da5Sopenharmony_ciOpExecutionMode %main EarlyAndLateFragmentTestsAMD 1140fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefLessFrontAMD 1141fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefGreaterFrontAMD 1142fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1143fd4e5da5Sopenharmony_ci 1144fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1145fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1146fd4e5da5Sopenharmony_ci EXPECT_THAT( 1147fd4e5da5Sopenharmony_ci getDiagnosticString(), 1148fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at most " 1149fd4e5da5Sopenharmony_ci "one of StencilRefUnchangedFrontAMD, " 1150fd4e5da5Sopenharmony_ci "StencilRefLessFrontAMD or StencilRefGreaterFrontAMD " 1151fd4e5da5Sopenharmony_ci "execution modes.")); 1152fd4e5da5Sopenharmony_ci} 1153fd4e5da5Sopenharmony_ci 1154fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderStencilRefBackTooManyModesBad) { 1155fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1156fd4e5da5Sopenharmony_ciOpCapability Shader 1157fd4e5da5Sopenharmony_ciOpCapability StencilExportEXT 1158fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_shader_early_and_late_fragment_tests" 1159fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_stencil_export" 1160fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1161fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1162fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1163fd4e5da5Sopenharmony_ciOpExecutionMode %main EarlyAndLateFragmentTestsAMD 1164fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefLessBackAMD 1165fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefGreaterBackAMD 1166fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1167fd4e5da5Sopenharmony_ci 1168fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1169fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1170fd4e5da5Sopenharmony_ci EXPECT_THAT( 1171fd4e5da5Sopenharmony_ci getDiagnosticString(), 1172fd4e5da5Sopenharmony_ci HasSubstr("Fragment execution model entry points can specify at most " 1173fd4e5da5Sopenharmony_ci "one of StencilRefUnchangedBackAMD, " 1174fd4e5da5Sopenharmony_ci "StencilRefLessBackAMD or StencilRefGreaterBackAMD " 1175fd4e5da5Sopenharmony_ci "execution modes.")); 1176fd4e5da5Sopenharmony_ci} 1177fd4e5da5Sopenharmony_ci 1178fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderStencilRefFrontGood) { 1179fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1180fd4e5da5Sopenharmony_ciOpCapability Shader 1181fd4e5da5Sopenharmony_ciOpCapability StencilExportEXT 1182fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_shader_early_and_late_fragment_tests" 1183fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_stencil_export" 1184fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1185fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1186fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1187fd4e5da5Sopenharmony_ciOpExecutionMode %main EarlyAndLateFragmentTestsAMD 1188fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefLessFrontAMD 1189fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1190fd4e5da5Sopenharmony_ci 1191fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1192fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 1193fd4e5da5Sopenharmony_ci} 1194fd4e5da5Sopenharmony_ci 1195fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderStencilRefBackGood) { 1196fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1197fd4e5da5Sopenharmony_ciOpCapability Shader 1198fd4e5da5Sopenharmony_ciOpCapability StencilExportEXT 1199fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_shader_early_and_late_fragment_tests" 1200fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_stencil_export" 1201fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1202fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1203fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1204fd4e5da5Sopenharmony_ciOpExecutionMode %main EarlyAndLateFragmentTestsAMD 1205fd4e5da5Sopenharmony_ciOpExecutionMode %main StencilRefLessBackAMD 1206fd4e5da5Sopenharmony_ci)" + kVoidFunction; 1207fd4e5da5Sopenharmony_ci 1208fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1209fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 1210fd4e5da5Sopenharmony_ci} 1211fd4e5da5Sopenharmony_ci 1212fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderDemoteVertexBad) { 1213fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1214fd4e5da5Sopenharmony_ciOpCapability Shader 1215fd4e5da5Sopenharmony_ciOpCapability DemoteToHelperInvocationEXT 1216fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_demote_to_helper_invocation" 1217fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1218fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 1219fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1220fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1221fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1222fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1223fd4e5da5Sopenharmony_ci%entry = OpLabel 1224fd4e5da5Sopenharmony_ciOpDemoteToHelperInvocationEXT 1225fd4e5da5Sopenharmony_ci%1 = OpIsHelperInvocationEXT %bool 1226fd4e5da5Sopenharmony_ciOpReturn 1227fd4e5da5Sopenharmony_ciOpFunctionEnd 1228fd4e5da5Sopenharmony_ci)"; 1229fd4e5da5Sopenharmony_ci 1230fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1231fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1232fd4e5da5Sopenharmony_ci EXPECT_THAT( 1233fd4e5da5Sopenharmony_ci getDiagnosticString(), 1234fd4e5da5Sopenharmony_ci HasSubstr( 1235fd4e5da5Sopenharmony_ci "OpDemoteToHelperInvocationEXT requires Fragment execution model")); 1236fd4e5da5Sopenharmony_ci EXPECT_THAT( 1237fd4e5da5Sopenharmony_ci getDiagnosticString(), 1238fd4e5da5Sopenharmony_ci HasSubstr("OpIsHelperInvocationEXT requires Fragment execution model")); 1239fd4e5da5Sopenharmony_ci} 1240fd4e5da5Sopenharmony_ci 1241fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderDemoteGood) { 1242fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1243fd4e5da5Sopenharmony_ciOpCapability Shader 1244fd4e5da5Sopenharmony_ciOpCapability DemoteToHelperInvocationEXT 1245fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_demote_to_helper_invocation" 1246fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1247fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1248fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1249fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1250fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1251fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1252fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1253fd4e5da5Sopenharmony_ci%entry = OpLabel 1254fd4e5da5Sopenharmony_ciOpDemoteToHelperInvocationEXT 1255fd4e5da5Sopenharmony_ci%1 = OpIsHelperInvocationEXT %bool 1256fd4e5da5Sopenharmony_ciOpReturn 1257fd4e5da5Sopenharmony_ciOpFunctionEnd 1258fd4e5da5Sopenharmony_ci)"; 1259fd4e5da5Sopenharmony_ci 1260fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1261fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_SUCCESS, ValidateInstructions()); 1262fd4e5da5Sopenharmony_ci} 1263fd4e5da5Sopenharmony_ci 1264fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, FragmentShaderDemoteBadType) { 1265fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1266fd4e5da5Sopenharmony_ciOpCapability Shader 1267fd4e5da5Sopenharmony_ciOpCapability DemoteToHelperInvocationEXT 1268fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_demote_to_helper_invocation" 1269fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1270fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1271fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1272fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 1273fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1274fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1275fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1276fd4e5da5Sopenharmony_ci%entry = OpLabel 1277fd4e5da5Sopenharmony_ciOpDemoteToHelperInvocationEXT 1278fd4e5da5Sopenharmony_ci%1 = OpIsHelperInvocationEXT %u32 1279fd4e5da5Sopenharmony_ciOpReturn 1280fd4e5da5Sopenharmony_ciOpFunctionEnd 1281fd4e5da5Sopenharmony_ci)"; 1282fd4e5da5Sopenharmony_ci 1283fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1284fd4e5da5Sopenharmony_ci EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1285fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1286fd4e5da5Sopenharmony_ci HasSubstr("Expected bool scalar type as Result Type")); 1287fd4e5da5Sopenharmony_ci} 1288fd4e5da5Sopenharmony_ci 1289fd4e5da5Sopenharmony_ciTEST_F(ValidateMode, LocalSizeIdVulkan1p3DoesNotRequireOption) { 1290fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1291fd4e5da5Sopenharmony_ciOpCapability Shader 1292fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1293fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1294fd4e5da5Sopenharmony_ciOpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1 1295fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1296fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1297fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1298fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1299fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1300fd4e5da5Sopenharmony_ci%entry = OpLabel 1301fd4e5da5Sopenharmony_ciOpReturn 1302fd4e5da5Sopenharmony_ciOpFunctionEnd 1303fd4e5da5Sopenharmony_ci)"; 1304fd4e5da5Sopenharmony_ci 1305fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3); 1306fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3)); 1307fd4e5da5Sopenharmony_ci} 1308fd4e5da5Sopenharmony_ci 1309fd4e5da5Sopenharmony_ci} // namespace 1310fd4e5da5Sopenharmony_ci} // namespace val 1311fd4e5da5Sopenharmony_ci} // namespace spvtools 1312