1 // Copyright (c) 2015-2016 The Khronos Group Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Validation tests for Logical Layout 16 17 #include <sstream> 18 #include <string> 19 #include <tuple> 20 #include <utility> 21 #include <vector> 22 23 #include "gmock/gmock.h" 24 #include "source/assembly_grammar.h" 25 #include "source/spirv_target_env.h" 26 #include "test/test_fixture.h" 27 #include "test/unit_spirv.h" 28 #include "test/val/val_fixtures.h" 29 30 namespace spvtools { 31 namespace val { 32 namespace { 33 34 using spvtest::ScopedContext; 35 using testing::Combine; 36 using testing::HasSubstr; 37 using testing::Values; 38 using testing::ValuesIn; 39 40 // Parameter for validation test fixtures. The first std::string is a 41 // capability name that will begin the assembly under test, the second the 42 // remainder assembly, and the std::vector at the end determines whether the 43 // test expects success or failure. See below for details and convenience 44 // methods to access each one. 45 // 46 // The assembly to test is composed from a variable top line and a fixed 47 // remainder. The top line will be an OpCapability instruction, while the 48 // remainder will be some assembly text that succeeds or fails to assemble 49 // depending on which capability was chosen. For instance, the following will 50 // succeed: 51 // 52 // OpCapability Pipes ; implies Kernel 53 // OpLifetimeStop %1 0 ; requires Kernel 54 // 55 // and the following will fail: 56 // 57 // OpCapability Kernel 58 // %1 = OpTypeNamedBarrier ; requires NamedBarrier 59 // 60 // So how does the test parameter capture which capabilities should cause 61 // success and which shouldn't? The answer is in the last element: it's a 62 // std::vector of capabilities that make the remainder assembly succeed. So if 63 // the first-line capability exists in that std::vector, success is expected; 64 // otherwise, failure is expected in the tests. 65 // 66 // We will use testing::Combine() to vary the first line: when we combine 67 // AllCapabilities() with a single remainder assembly, we generate enough test 68 // cases to try the assembly with every possible capability that could be 69 // declared. However, Combine() only produces tuples -- it cannot produce, say, 70 // a struct. Therefore, this type must be a tuple. 71 using CapTestParameter = 72 std::tuple<std::string, std::pair<std::string, std::vector<std::string>>>; 73 74 const std::string& Capability(const CapTestParameter& p) { 75 return std::get<0>(p); 76 } 77 const std::string& Remainder(const CapTestParameter& p) { 78 return std::get<1>(p).first; 79 } 80 const std::vector<std::string>& MustSucceed(const CapTestParameter& p) { 81 return std::get<1>(p).second; 82 } 83 84 // Creates assembly to test from p. 85 std::string MakeAssembly(const CapTestParameter& p) { 86 std::ostringstream ss; 87 const std::string& capability = Capability(p); 88 if (!capability.empty()) { 89 ss << "OpCapability " << capability << "\n"; 90 } 91 ss << Remainder(p); 92 return ss.str(); 93 } 94 95 // Expected validation result for p. 96 spv_result_t ExpectedResult(const CapTestParameter& p) { 97 const auto& caps = MustSucceed(p); 98 auto found = find(begin(caps), end(caps), Capability(p)); 99 return (found == end(caps)) ? SPV_ERROR_INVALID_CAPABILITY : SPV_SUCCESS; 100 } 101 102 // Assembles using v1.0, unless the parameter's capability requires v1.1. 103 using ValidateCapability = spvtest::ValidateBase<CapTestParameter>; 104 105 // Always assembles using v1.1. 106 using ValidateCapabilityV11 = spvtest::ValidateBase<CapTestParameter>; 107 108 // Always assembles using Vulkan 1.0. 109 // TODO(dneto): Refactor all these tests to scale better across environments. 110 using ValidateCapabilityVulkan10 = spvtest::ValidateBase<CapTestParameter>; 111 // Always assembles using OpenGL 4.0. 112 using ValidateCapabilityOpenGL40 = spvtest::ValidateBase<CapTestParameter>; 113 // Always assembles using Vulkan 1.1. 114 using ValidateCapabilityVulkan11 = spvtest::ValidateBase<CapTestParameter>; 115 // Always assembles using WebGPU. 116 using ValidateCapabilityWebGPU = spvtest::ValidateBase<CapTestParameter>; 117 118 TEST_F(ValidateCapability, Default) { 119 const char str[] = R"( 120 OpCapability Kernel 121 OpCapability Linkage 122 OpCapability Matrix 123 OpMemoryModel Logical OpenCL 124 %f32 = OpTypeFloat 32 125 %vec3 = OpTypeVector %f32 3 126 %mat33 = OpTypeMatrix %vec3 3 127 )"; 128 129 CompileSuccessfully(str); 130 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 131 } 132 133 // clang-format off 134 const std::vector<std::string>& AllCapabilities() { 135 static const auto r = new std::vector<std::string>{ 136 "", 137 "Matrix", 138 "Shader", 139 "Geometry", 140 "Tessellation", 141 "Addresses", 142 "Linkage", 143 "Kernel", 144 "Vector16", 145 "Float16Buffer", 146 "Float16", 147 "Float64", 148 "Int64", 149 "Int64Atomics", 150 "ImageBasic", 151 "ImageReadWrite", 152 "ImageMipmap", 153 "Pipes", 154 "Groups", 155 "DeviceEnqueue", 156 "LiteralSampler", 157 "AtomicStorage", 158 "Int16", 159 "TessellationPointSize", 160 "GeometryPointSize", 161 "ImageGatherExtended", 162 "StorageImageMultisample", 163 "UniformBufferArrayDynamicIndexing", 164 "SampledImageArrayDynamicIndexing", 165 "StorageBufferArrayDynamicIndexing", 166 "StorageImageArrayDynamicIndexing", 167 "ClipDistance", 168 "CullDistance", 169 "ImageCubeArray", 170 "SampleRateShading", 171 "ImageRect", 172 "SampledRect", 173 "GenericPointer", 174 "Int8", 175 "InputAttachment", 176 "SparseResidency", 177 "MinLod", 178 "Sampled1D", 179 "Image1D", 180 "SampledCubeArray", 181 "SampledBuffer", 182 "ImageBuffer", 183 "ImageMSArray", 184 "StorageImageExtendedFormats", 185 "ImageQuery", 186 "DerivativeControl", 187 "InterpolationFunction", 188 "TransformFeedback", 189 "GeometryStreams", 190 "StorageImageReadWithoutFormat", 191 "StorageImageWriteWithoutFormat", 192 "MultiViewport", 193 "SubgroupDispatch", 194 "NamedBarrier", 195 "PipeStorage", 196 "GroupNonUniform", 197 "GroupNonUniformVote", 198 "GroupNonUniformArithmetic", 199 "GroupNonUniformBallot", 200 "GroupNonUniformShuffle", 201 "GroupNonUniformShuffleRelative", 202 "GroupNonUniformClustered", 203 "GroupNonUniformQuad", 204 "DrawParameters", 205 "StorageBuffer16BitAccess", 206 "StorageUniformBufferBlock16", 207 "UniformAndStorageBuffer16BitAccess", 208 "StorageUniform16", 209 "StoragePushConstant16", 210 "StorageInputOutput16", 211 "DeviceGroup", 212 "MultiView", 213 "VariablePointersStorageBuffer", 214 "VariablePointers"}; 215 return *r; 216 } 217 218 const std::vector<std::string>& AllSpirV10Capabilities() { 219 static const auto r = new std::vector<std::string>{ 220 "", 221 "Matrix", 222 "Shader", 223 "Geometry", 224 "Tessellation", 225 "Addresses", 226 "Linkage", 227 "Kernel", 228 "Vector16", 229 "Float16Buffer", 230 "Float16", 231 "Float64", 232 "Int64", 233 "Int64Atomics", 234 "ImageBasic", 235 "ImageReadWrite", 236 "ImageMipmap", 237 "Pipes", 238 "Groups", 239 "DeviceEnqueue", 240 "LiteralSampler", 241 "AtomicStorage", 242 "Int16", 243 "TessellationPointSize", 244 "GeometryPointSize", 245 "ImageGatherExtended", 246 "StorageImageMultisample", 247 "UniformBufferArrayDynamicIndexing", 248 "SampledImageArrayDynamicIndexing", 249 "StorageBufferArrayDynamicIndexing", 250 "StorageImageArrayDynamicIndexing", 251 "ClipDistance", 252 "CullDistance", 253 "ImageCubeArray", 254 "SampleRateShading", 255 "ImageRect", 256 "SampledRect", 257 "GenericPointer", 258 "Int8", 259 "InputAttachment", 260 "SparseResidency", 261 "MinLod", 262 "Sampled1D", 263 "Image1D", 264 "SampledCubeArray", 265 "SampledBuffer", 266 "ImageBuffer", 267 "ImageMSArray", 268 "StorageImageExtendedFormats", 269 "ImageQuery", 270 "DerivativeControl", 271 "InterpolationFunction", 272 "TransformFeedback", 273 "GeometryStreams", 274 "StorageImageReadWithoutFormat", 275 "StorageImageWriteWithoutFormat", 276 "MultiViewport"}; 277 return *r; 278 } 279 280 const std::vector<std::string>& AllVulkan10Capabilities() { 281 static const auto r = new std::vector<std::string>{ 282 "", 283 "Matrix", 284 "Shader", 285 "InputAttachment", 286 "Sampled1D", 287 "Image1D", 288 "SampledBuffer", 289 "ImageBuffer", 290 "ImageQuery", 291 "DerivativeControl", 292 "Geometry", 293 "Tessellation", 294 "Float16", 295 "Float64", 296 "Int64", 297 "Int64Atomics", 298 "Int16", 299 "TessellationPointSize", 300 "GeometryPointSize", 301 "ImageGatherExtended", 302 "StorageImageMultisample", 303 "UniformBufferArrayDynamicIndexing", 304 "SampledImageArrayDynamicIndexing", 305 "StorageBufferArrayDynamicIndexing", 306 "StorageImageArrayDynamicIndexing", 307 "ClipDistance", 308 "CullDistance", 309 "ImageCubeArray", 310 "SampleRateShading", 311 "Int8", 312 "SparseResidency", 313 "MinLod", 314 "SampledCubeArray", 315 "ImageMSArray", 316 "StorageImageExtendedFormats", 317 "InterpolationFunction", 318 "StorageImageReadWithoutFormat", 319 "StorageImageWriteWithoutFormat", 320 "MultiViewport", 321 "TransformFeedback", 322 "GeometryStreams"}; 323 return *r; 324 } 325 326 const std::vector<std::string>& AllVulkan11Capabilities() { 327 static const auto r = new std::vector<std::string>{ 328 "", 329 "Matrix", 330 "Shader", 331 "InputAttachment", 332 "Sampled1D", 333 "Image1D", 334 "SampledBuffer", 335 "ImageBuffer", 336 "ImageQuery", 337 "DerivativeControl", 338 "Geometry", 339 "Tessellation", 340 "Float16", 341 "Float64", 342 "Int64", 343 "Int64Atomics", 344 "Int16", 345 "TessellationPointSize", 346 "GeometryPointSize", 347 "ImageGatherExtended", 348 "StorageImageMultisample", 349 "UniformBufferArrayDynamicIndexing", 350 "SampledImageArrayDynamicIndexing", 351 "StorageBufferArrayDynamicIndexing", 352 "StorageImageArrayDynamicIndexing", 353 "ClipDistance", 354 "CullDistance", 355 "ImageCubeArray", 356 "SampleRateShading", 357 "Int8", 358 "SparseResidency", 359 "MinLod", 360 "SampledCubeArray", 361 "ImageMSArray", 362 "StorageImageExtendedFormats", 363 "InterpolationFunction", 364 "StorageImageReadWithoutFormat", 365 "StorageImageWriteWithoutFormat", 366 "MultiViewport", 367 "GroupNonUniform", 368 "GroupNonUniformVote", 369 "GroupNonUniformArithmetic", 370 "GroupNonUniformBallot", 371 "GroupNonUniformShuffle", 372 "GroupNonUniformShuffleRelative", 373 "GroupNonUniformClustered", 374 "GroupNonUniformQuad", 375 "DrawParameters", 376 "StorageBuffer16BitAccess", 377 "StorageUniformBufferBlock16", 378 "UniformAndStorageBuffer16BitAccess", 379 "StorageUniform16", 380 "StoragePushConstant16", 381 "StorageInputOutput16", 382 "DeviceGroup", 383 "MultiView", 384 "VariablePointersStorageBuffer", 385 "VariablePointers", 386 "TransformFeedback", 387 "GeometryStreams"}; 388 return *r; 389 } 390 391 const std::vector<std::string>& AllWebGPUCapabilities() { 392 static const auto r = new std::vector<std::string>{ 393 "", 394 "Shader", 395 "Matrix", 396 "Sampled1D", 397 "Image1D", 398 "ImageQuery", 399 "DerivativeControl"}; 400 return *r; 401 } 402 403 const std::vector<std::string>& MatrixDependencies() { 404 static const auto r = new std::vector<std::string>{ 405 "Matrix", 406 "Shader", 407 "Geometry", 408 "Tessellation", 409 "AtomicStorage", 410 "TessellationPointSize", 411 "GeometryPointSize", 412 "ImageGatherExtended", 413 "StorageImageMultisample", 414 "UniformBufferArrayDynamicIndexing", 415 "SampledImageArrayDynamicIndexing", 416 "StorageBufferArrayDynamicIndexing", 417 "StorageImageArrayDynamicIndexing", 418 "ClipDistance", 419 "CullDistance", 420 "ImageCubeArray", 421 "SampleRateShading", 422 "ImageRect", 423 "SampledRect", 424 "InputAttachment", 425 "SparseResidency", 426 "MinLod", 427 "SampledCubeArray", 428 "ImageMSArray", 429 "StorageImageExtendedFormats", 430 "ImageQuery", 431 "DerivativeControl", 432 "InterpolationFunction", 433 "TransformFeedback", 434 "GeometryStreams", 435 "StorageImageReadWithoutFormat", 436 "StorageImageWriteWithoutFormat", 437 "MultiViewport", 438 "DrawParameters", 439 "MultiView", 440 "VariablePointersStorageBuffer", 441 "VariablePointers"}; 442 return *r; 443 } 444 445 const std::vector<std::string>& ShaderDependencies() { 446 static const auto r = new std::vector<std::string>{ 447 "Shader", 448 "Geometry", 449 "Tessellation", 450 "AtomicStorage", 451 "TessellationPointSize", 452 "GeometryPointSize", 453 "ImageGatherExtended", 454 "StorageImageMultisample", 455 "UniformBufferArrayDynamicIndexing", 456 "SampledImageArrayDynamicIndexing", 457 "StorageBufferArrayDynamicIndexing", 458 "StorageImageArrayDynamicIndexing", 459 "ClipDistance", 460 "CullDistance", 461 "ImageCubeArray", 462 "SampleRateShading", 463 "ImageRect", 464 "SampledRect", 465 "InputAttachment", 466 "SparseResidency", 467 "MinLod", 468 "SampledCubeArray", 469 "ImageMSArray", 470 "StorageImageExtendedFormats", 471 "ImageQuery", 472 "DerivativeControl", 473 "InterpolationFunction", 474 "TransformFeedback", 475 "GeometryStreams", 476 "StorageImageReadWithoutFormat", 477 "StorageImageWriteWithoutFormat", 478 "MultiViewport", 479 "DrawParameters", 480 "MultiView", 481 "VariablePointersStorageBuffer", 482 "VariablePointers"}; 483 return *r; 484 } 485 486 const std::vector<std::string>& TessellationDependencies() { 487 static const auto r = new std::vector<std::string>{ 488 "Tessellation", 489 "TessellationPointSize"}; 490 return *r; 491 } 492 493 const std::vector<std::string>& GeometryDependencies() { 494 static const auto r = new std::vector<std::string>{ 495 "Geometry", 496 "GeometryPointSize", 497 "GeometryStreams", 498 "MultiViewport"}; 499 return *r; 500 } 501 502 const std::vector<std::string>& GeometryTessellationDependencies() { 503 static const auto r = new std::vector<std::string>{ 504 "Tessellation", 505 "TessellationPointSize", 506 "Geometry", 507 "GeometryPointSize", 508 "GeometryStreams", 509 "MultiViewport"}; 510 return *r; 511 } 512 513 // Returns the names of capabilities that directly depend on Kernel, 514 // plus itself. 515 const std::vector<std::string>& KernelDependencies() { 516 static const auto r = new std::vector<std::string>{ 517 "Kernel", 518 "Vector16", 519 "Float16Buffer", 520 "ImageBasic", 521 "ImageReadWrite", 522 "ImageMipmap", 523 "Pipes", 524 "DeviceEnqueue", 525 "LiteralSampler", 526 "SubgroupDispatch", 527 "NamedBarrier", 528 "PipeStorage"}; 529 return *r; 530 } 531 532 const std::vector<std::string>& KernelAndGroupNonUniformDependencies() { 533 static const auto r = new std::vector<std::string>{ 534 "Kernel", 535 "Vector16", 536 "Float16Buffer", 537 "ImageBasic", 538 "ImageReadWrite", 539 "ImageMipmap", 540 "Pipes", 541 "DeviceEnqueue", 542 "LiteralSampler", 543 "SubgroupDispatch", 544 "NamedBarrier", 545 "PipeStorage", 546 "GroupNonUniform", 547 "GroupNonUniformVote", 548 "GroupNonUniformArithmetic", 549 "GroupNonUniformBallot", 550 "GroupNonUniformShuffle", 551 "GroupNonUniformShuffleRelative", 552 "GroupNonUniformClustered", 553 "GroupNonUniformQuad"}; 554 return *r; 555 } 556 557 const std::vector<std::string>& AddressesDependencies() { 558 static const auto r = new std::vector<std::string>{ 559 "Addresses", 560 "GenericPointer"}; 561 return *r; 562 } 563 564 const std::vector<std::string>& Sampled1DDependencies() { 565 static const auto r = new std::vector<std::string>{ 566 "Sampled1D", 567 "Image1D"}; 568 return *r; 569 } 570 571 const std::vector<std::string>& SampledRectDependencies() { 572 static const auto r = new std::vector<std::string>{ 573 "SampledRect", 574 "ImageRect"}; 575 return *r; 576 } 577 578 const std::vector<std::string>& SampledBufferDependencies() { 579 static const auto r = new std::vector<std::string>{ 580 "SampledBuffer", 581 "ImageBuffer"}; 582 return *r; 583 } 584 585 const char kOpenCLMemoryModel[] = \ 586 " OpCapability Kernel" 587 " OpMemoryModel Logical OpenCL "; 588 589 const char kGLSL450MemoryModel[] = \ 590 " OpCapability Shader" 591 " OpMemoryModel Logical GLSL450 "; 592 593 const char kVulkanMemoryModel[] = \ 594 " OpCapability Shader" 595 " OpCapability VulkanMemoryModelKHR" 596 " OpExtension \"SPV_KHR_vulkan_memory_model\"" 597 " OpMemoryModel Logical VulkanKHR "; 598 599 const char kVoidFVoid[] = \ 600 " %void = OpTypeVoid" 601 " %void_f = OpTypeFunction %void" 602 " %func = OpFunction %void None %void_f" 603 " %label = OpLabel" 604 " OpReturn" 605 " OpFunctionEnd "; 606 607 const char kVoidFVoid2[] = \ 608 " %void_f = OpTypeFunction %voidt" 609 " %func = OpFunction %voidt None %void_f" 610 " %label = OpLabel" 611 " OpReturn" 612 " OpFunctionEnd "; 613 614 INSTANTIATE_TEST_CASE_P(ExecutionModel, ValidateCapability, 615 Combine( 616 ValuesIn(AllCapabilities()), 617 Values( 618 std::make_pair(std::string(kOpenCLMemoryModel) + 619 " OpEntryPoint Vertex %func \"shader\"" + 620 std::string(kVoidFVoid), ShaderDependencies()), 621 std::make_pair(std::string(kOpenCLMemoryModel) + 622 " OpEntryPoint TessellationControl %func \"shader\"" + 623 std::string(kVoidFVoid), TessellationDependencies()), 624 std::make_pair(std::string(kOpenCLMemoryModel) + 625 " OpEntryPoint TessellationEvaluation %func \"shader\"" + 626 std::string(kVoidFVoid), TessellationDependencies()), 627 std::make_pair(std::string(kOpenCLMemoryModel) + 628 " OpEntryPoint Geometry %func \"shader\"" + 629 " OpExecutionMode %func InputPoints" + 630 " OpExecutionMode %func OutputPoints" + 631 std::string(kVoidFVoid), GeometryDependencies()), 632 std::make_pair(std::string(kOpenCLMemoryModel) + 633 " OpEntryPoint Fragment %func \"shader\"" + 634 " OpExecutionMode %func OriginUpperLeft" + 635 std::string(kVoidFVoid), ShaderDependencies()), 636 std::make_pair(std::string(kOpenCLMemoryModel) + 637 " OpEntryPoint GLCompute %func \"shader\"" + 638 std::string(kVoidFVoid), ShaderDependencies()), 639 std::make_pair(std::string(kGLSL450MemoryModel) + 640 " OpEntryPoint Kernel %func \"shader\"" + 641 std::string(kVoidFVoid), KernelDependencies()) 642 )),); 643 644 INSTANTIATE_TEST_CASE_P(AddressingAndMemoryModel, ValidateCapability, 645 Combine( 646 ValuesIn(AllCapabilities()), 647 Values( 648 std::make_pair(" OpCapability Shader" 649 " OpMemoryModel Logical Simple" 650 " OpEntryPoint Vertex %func \"shader\"" + 651 std::string(kVoidFVoid), AllCapabilities()), 652 std::make_pair(" OpCapability Shader" 653 " OpMemoryModel Logical GLSL450" 654 " OpEntryPoint Vertex %func \"shader\"" + 655 std::string(kVoidFVoid), AllCapabilities()), 656 std::make_pair(" OpCapability Kernel" 657 " OpMemoryModel Logical OpenCL" 658 " OpEntryPoint Kernel %func \"compute\"" + 659 std::string(kVoidFVoid), AllCapabilities()), 660 std::make_pair(" OpCapability Shader" 661 " OpMemoryModel Physical32 Simple" 662 " OpEntryPoint Vertex %func \"shader\"" + 663 std::string(kVoidFVoid), AddressesDependencies()), 664 std::make_pair(" OpCapability Shader" 665 " OpMemoryModel Physical32 GLSL450" 666 " OpEntryPoint Vertex %func \"shader\"" + 667 std::string(kVoidFVoid), AddressesDependencies()), 668 std::make_pair(" OpCapability Kernel" 669 " OpMemoryModel Physical32 OpenCL" 670 " OpEntryPoint Kernel %func \"compute\"" + 671 std::string(kVoidFVoid), AddressesDependencies()), 672 std::make_pair(" OpCapability Shader" 673 " OpMemoryModel Physical64 Simple" 674 " OpEntryPoint Vertex %func \"shader\"" + 675 std::string(kVoidFVoid), AddressesDependencies()), 676 std::make_pair(" OpCapability Shader" 677 " OpMemoryModel Physical64 GLSL450" 678 " OpEntryPoint Vertex %func \"shader\"" + 679 std::string(kVoidFVoid), AddressesDependencies()), 680 std::make_pair(" OpCapability Kernel" 681 " OpMemoryModel Physical64 OpenCL" 682 " OpEntryPoint Kernel %func \"compute\"" + 683 std::string(kVoidFVoid), AddressesDependencies()) 684 )),); 685 686 INSTANTIATE_TEST_CASE_P(ExecutionMode, ValidateCapability, 687 Combine( 688 ValuesIn(AllCapabilities()), 689 Values( 690 std::make_pair(std::string(kOpenCLMemoryModel) + 691 "OpEntryPoint Geometry %func \"shader\" " 692 "OpExecutionMode %func Invocations 42" + 693 " OpExecutionMode %func InputPoints" + 694 " OpExecutionMode %func OutputPoints" + 695 std::string(kVoidFVoid), GeometryDependencies()), 696 std::make_pair(std::string(kOpenCLMemoryModel) + 697 "OpEntryPoint TessellationControl %func \"shader\" " 698 "OpExecutionMode %func SpacingEqual" + 699 std::string(kVoidFVoid), TessellationDependencies()), 700 std::make_pair(std::string(kOpenCLMemoryModel) + 701 "OpEntryPoint TessellationControl %func \"shader\" " 702 "OpExecutionMode %func SpacingFractionalEven" + 703 std::string(kVoidFVoid), TessellationDependencies()), 704 std::make_pair(std::string(kOpenCLMemoryModel) + 705 "OpEntryPoint TessellationControl %func \"shader\" " 706 "OpExecutionMode %func SpacingFractionalOdd" + 707 std::string(kVoidFVoid), TessellationDependencies()), 708 std::make_pair(std::string(kOpenCLMemoryModel) + 709 "OpEntryPoint TessellationControl %func \"shader\" " 710 "OpExecutionMode %func VertexOrderCw" + 711 std::string(kVoidFVoid), TessellationDependencies()), 712 std::make_pair(std::string(kOpenCLMemoryModel) + 713 "OpEntryPoint TessellationControl %func \"shader\" " 714 "OpExecutionMode %func VertexOrderCcw" + 715 std::string(kVoidFVoid), TessellationDependencies()), 716 std::make_pair(std::string(kOpenCLMemoryModel) + 717 "OpEntryPoint Fragment %func \"shader\" " 718 "OpExecutionMode %func PixelCenterInteger" + 719 " OpExecutionMode %func OriginUpperLeft" + 720 std::string(kVoidFVoid), ShaderDependencies()), 721 std::make_pair(std::string(kOpenCLMemoryModel) + 722 "OpEntryPoint Fragment %func \"shader\" " 723 "OpExecutionMode %func OriginUpperLeft" + 724 std::string(kVoidFVoid), ShaderDependencies()), 725 std::make_pair(std::string(kOpenCLMemoryModel) + 726 "OpEntryPoint Fragment %func \"shader\" " 727 "OpExecutionMode %func OriginLowerLeft" + 728 std::string(kVoidFVoid), ShaderDependencies()), 729 std::make_pair(std::string(kOpenCLMemoryModel) + 730 "OpEntryPoint Fragment %func \"shader\" " 731 "OpExecutionMode %func EarlyFragmentTests" + 732 " OpExecutionMode %func OriginUpperLeft" + 733 std::string(kVoidFVoid), ShaderDependencies()), 734 std::make_pair(std::string(kOpenCLMemoryModel) + 735 "OpEntryPoint TessellationControl %func \"shader\" " 736 "OpExecutionMode %func PointMode" + 737 std::string(kVoidFVoid), TessellationDependencies()), 738 std::make_pair(std::string(kOpenCLMemoryModel) + 739 "OpEntryPoint Vertex %func \"shader\" " 740 "OpExecutionMode %func Xfb" + 741 std::string(kVoidFVoid), std::vector<std::string>{"TransformFeedback"}), 742 std::make_pair(std::string(kOpenCLMemoryModel) + 743 "OpEntryPoint Fragment %func \"shader\" " 744 "OpExecutionMode %func DepthReplacing" + 745 " OpExecutionMode %func OriginUpperLeft" + 746 std::string(kVoidFVoid), ShaderDependencies()), 747 std::make_pair(std::string(kOpenCLMemoryModel) + 748 "OpEntryPoint Fragment %func \"shader\" " 749 "OpExecutionMode %func DepthGreater" + 750 " OpExecutionMode %func OriginUpperLeft" + 751 std::string(kVoidFVoid), ShaderDependencies()), 752 std::make_pair(std::string(kOpenCLMemoryModel) + 753 "OpEntryPoint Fragment %func \"shader\" " 754 "OpExecutionMode %func DepthLess" + 755 " OpExecutionMode %func OriginUpperLeft" + 756 std::string(kVoidFVoid), ShaderDependencies()), 757 std::make_pair(std::string(kOpenCLMemoryModel) + 758 "OpEntryPoint Fragment %func \"shader\" " 759 "OpExecutionMode %func DepthUnchanged" + 760 " OpExecutionMode %func OriginUpperLeft" + 761 std::string(kVoidFVoid), ShaderDependencies()), 762 std::make_pair(std::string(kOpenCLMemoryModel) + 763 "OpEntryPoint Kernel %func \"shader\" " 764 "OpExecutionMode %func LocalSize 42 42 42" + 765 std::string(kVoidFVoid), AllCapabilities()), 766 std::make_pair(std::string(kGLSL450MemoryModel) + 767 "OpEntryPoint Kernel %func \"shader\" " 768 "OpExecutionMode %func LocalSizeHint 42 42 42" + 769 std::string(kVoidFVoid), KernelDependencies()), 770 std::make_pair(std::string(kOpenCLMemoryModel) + 771 "OpEntryPoint Geometry %func \"shader\" " 772 "OpExecutionMode %func InputPoints" + 773 " OpExecutionMode %func OutputPoints" + 774 std::string(kVoidFVoid), GeometryDependencies()), 775 std::make_pair(std::string(kOpenCLMemoryModel) + 776 "OpEntryPoint Geometry %func \"shader\" " 777 "OpExecutionMode %func InputLines" + 778 " OpExecutionMode %func OutputLineStrip" + 779 std::string(kVoidFVoid), GeometryDependencies()), 780 std::make_pair(std::string(kOpenCLMemoryModel) + 781 "OpEntryPoint Geometry %func \"shader\" " 782 "OpExecutionMode %func InputLinesAdjacency" + 783 " OpExecutionMode %func OutputLineStrip" + 784 std::string(kVoidFVoid), GeometryDependencies()), 785 std::make_pair(std::string(kOpenCLMemoryModel) + 786 "OpEntryPoint Geometry %func \"shader\" " 787 "OpExecutionMode %func Triangles" + 788 " OpExecutionMode %func OutputTriangleStrip" + 789 std::string(kVoidFVoid), GeometryDependencies()), 790 std::make_pair(std::string(kOpenCLMemoryModel) + 791 "OpEntryPoint TessellationControl %func \"shader\" " 792 "OpExecutionMode %func Triangles" + 793 std::string(kVoidFVoid), TessellationDependencies()), 794 std::make_pair(std::string(kOpenCLMemoryModel) + 795 "OpEntryPoint Geometry %func \"shader\" " 796 "OpExecutionMode %func InputTrianglesAdjacency" + 797 " OpExecutionMode %func OutputTriangleStrip" + 798 std::string(kVoidFVoid), GeometryDependencies()), 799 std::make_pair(std::string(kOpenCLMemoryModel) + 800 "OpEntryPoint TessellationControl %func \"shader\" " 801 "OpExecutionMode %func Quads" + 802 std::string(kVoidFVoid), TessellationDependencies()), 803 std::make_pair(std::string(kOpenCLMemoryModel) + 804 "OpEntryPoint TessellationControl %func \"shader\" " 805 "OpExecutionMode %func Isolines" + 806 std::string(kVoidFVoid), TessellationDependencies()), 807 std::make_pair(std::string(kOpenCLMemoryModel) + 808 "OpEntryPoint Geometry %func \"shader\" " 809 "OpExecutionMode %func OutputVertices 42" + 810 " OpExecutionMode %func OutputPoints" + 811 " OpExecutionMode %func InputPoints" + 812 std::string(kVoidFVoid), GeometryDependencies()), 813 std::make_pair(std::string(kOpenCLMemoryModel) + 814 "OpEntryPoint TessellationControl %func \"shader\" " 815 "OpExecutionMode %func OutputVertices 42" + 816 std::string(kVoidFVoid), TessellationDependencies()), 817 std::make_pair(std::string(kOpenCLMemoryModel) + 818 "OpEntryPoint Geometry %func \"shader\" " 819 "OpExecutionMode %func OutputPoints" + 820 " OpExecutionMode %func InputPoints" + 821 std::string(kVoidFVoid), GeometryDependencies()), 822 std::make_pair(std::string(kOpenCLMemoryModel) + 823 "OpEntryPoint Geometry %func \"shader\" " 824 "OpExecutionMode %func OutputLineStrip" + 825 " OpExecutionMode %func InputLines" + 826 std::string(kVoidFVoid), GeometryDependencies()), 827 std::make_pair(std::string(kOpenCLMemoryModel) + 828 "OpEntryPoint Geometry %func \"shader\" " 829 "OpExecutionMode %func OutputTriangleStrip" + 830 " OpExecutionMode %func Triangles" + 831 std::string(kVoidFVoid), GeometryDependencies()), 832 std::make_pair(std::string(kGLSL450MemoryModel) + 833 "OpEntryPoint Kernel %func \"shader\" " 834 "OpExecutionMode %func VecTypeHint 2" + 835 std::string(kVoidFVoid), KernelDependencies()), 836 std::make_pair(std::string(kGLSL450MemoryModel) + 837 "OpEntryPoint Kernel %func \"shader\" " 838 "OpExecutionMode %func ContractionOff" + 839 std::string(kVoidFVoid), KernelDependencies()))),); 840 841 // clang-format on 842 843 INSTANTIATE_TEST_CASE_P( 844 ExecutionModeV11, ValidateCapabilityV11, 845 Combine(ValuesIn(AllCapabilities()), 846 Values(std::make_pair(std::string(kOpenCLMemoryModel) + 847 "OpEntryPoint Kernel %func \"shader\" " 848 "OpExecutionMode %func SubgroupSize 1" + 849 std::string(kVoidFVoid), 850 std::vector<std::string>{"SubgroupDispatch"}), 851 std::make_pair( 852 std::string(kOpenCLMemoryModel) + 853 "OpEntryPoint Kernel %func \"shader\" " 854 "OpExecutionMode %func SubgroupsPerWorkgroup 65535" + 855 std::string(kVoidFVoid), 856 std::vector<std::string>{"SubgroupDispatch"}))), ); 857 // clang-format off 858 859 INSTANTIATE_TEST_CASE_P(StorageClass, ValidateCapability, 860 Combine( 861 ValuesIn(AllCapabilities()), 862 Values( 863 std::make_pair(std::string(kGLSL450MemoryModel) + 864 " OpEntryPoint Vertex %func \"shader\"" + 865 " %intt = OpTypeInt 32 0\n" 866 " %ptrt = OpTypePointer UniformConstant %intt\n" 867 " %var = OpVariable %ptrt UniformConstant\n" + std::string(kVoidFVoid), 868 AllCapabilities()), 869 std::make_pair(std::string(kOpenCLMemoryModel) + 870 " OpEntryPoint Kernel %func \"compute\"" + 871 " %intt = OpTypeInt 32 0\n" 872 " %ptrt = OpTypePointer Input %intt" 873 " %var = OpVariable %ptrt Input\n" + std::string(kVoidFVoid), 874 AllCapabilities()), 875 std::make_pair(std::string(kOpenCLMemoryModel) + 876 " OpEntryPoint Vertex %func \"shader\"" + 877 " %intt = OpTypeInt 32 0\n" 878 " %ptrt = OpTypePointer Uniform %intt\n" 879 " %var = OpVariable %ptrt Uniform\n" + std::string(kVoidFVoid), 880 ShaderDependencies()), 881 std::make_pair(std::string(kOpenCLMemoryModel) + 882 " OpEntryPoint Vertex %func \"shader\"" + 883 " %intt = OpTypeInt 32 0\n" 884 " %ptrt = OpTypePointer Output %intt\n" 885 " %var = OpVariable %ptrt Output\n" + std::string(kVoidFVoid), 886 ShaderDependencies()), 887 std::make_pair(std::string(kGLSL450MemoryModel) + 888 " OpEntryPoint Vertex %func \"shader\"" + 889 " %intt = OpTypeInt 32 0\n" 890 " %ptrt = OpTypePointer Workgroup %intt\n" 891 " %var = OpVariable %ptrt Workgroup\n" + std::string(kVoidFVoid), 892 AllCapabilities()), 893 std::make_pair(std::string(kGLSL450MemoryModel) + 894 " OpEntryPoint Vertex %func \"shader\"" + 895 " %intt = OpTypeInt 32 0\n" 896 " %ptrt = OpTypePointer CrossWorkgroup %intt\n" 897 " %var = OpVariable %ptrt CrossWorkgroup\n" + std::string(kVoidFVoid), 898 AllCapabilities()), 899 std::make_pair(std::string(kOpenCLMemoryModel) + 900 " OpEntryPoint Kernel %func \"compute\"" + 901 " %intt = OpTypeInt 32 0\n" 902 " %ptrt = OpTypePointer Private %intt\n" 903 " %var = OpVariable %ptrt Private\n" + std::string(kVoidFVoid), 904 ShaderDependencies()), 905 std::make_pair(std::string(kOpenCLMemoryModel) + 906 " OpEntryPoint Kernel %func \"compute\"" + 907 " %intt = OpTypeInt 32 0\n" 908 " %ptrt = OpTypePointer PushConstant %intt\n" 909 " %var = OpVariable %ptrt PushConstant\n" + std::string(kVoidFVoid), 910 ShaderDependencies()), 911 std::make_pair(std::string(kGLSL450MemoryModel) + 912 " OpEntryPoint Vertex %func \"shader\"" + 913 " %intt = OpTypeInt 32 0\n" 914 " %ptrt = OpTypePointer AtomicCounter %intt\n" 915 " %var = OpVariable %ptrt AtomicCounter\n" + std::string(kVoidFVoid), 916 std::vector<std::string>{"AtomicStorage"}), 917 std::make_pair(std::string(kGLSL450MemoryModel) + 918 " OpEntryPoint Vertex %func \"shader\"" + 919 " %intt = OpTypeInt 32 0\n" 920 " %ptrt = OpTypePointer Image %intt\n" 921 " %var = OpVariable %ptrt Image\n" + std::string(kVoidFVoid), 922 AllCapabilities()) 923 )),); 924 925 INSTANTIATE_TEST_CASE_P(Dim, ValidateCapability, 926 Combine( 927 ValuesIn(AllCapabilities()), 928 Values( 929 std::make_pair(" OpCapability ImageBasic" + 930 std::string(kOpenCLMemoryModel) + 931 std::string(" OpEntryPoint Kernel %func \"compute\"") + 932 " %voidt = OpTypeVoid" 933 " %imgt = OpTypeImage %voidt 1D 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 934 Sampled1DDependencies()), 935 std::make_pair(" OpCapability ImageBasic" + 936 std::string(kOpenCLMemoryModel) + 937 std::string(" OpEntryPoint Kernel %func \"compute\"") + 938 " %voidt = OpTypeVoid" 939 " %imgt = OpTypeImage %voidt 2D 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 940 AllCapabilities()), 941 std::make_pair(" OpCapability ImageBasic" + 942 std::string(kOpenCLMemoryModel) + 943 std::string(" OpEntryPoint Kernel %func \"compute\"") + 944 " %voidt = OpTypeVoid" 945 " %imgt = OpTypeImage %voidt 3D 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 946 AllCapabilities()), 947 std::make_pair(" OpCapability ImageBasic" + 948 std::string(kOpenCLMemoryModel) + 949 std::string(" OpEntryPoint Kernel %func \"compute\"") + 950 " %voidt = OpTypeVoid" 951 " %imgt = OpTypeImage %voidt Cube 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 952 ShaderDependencies()), 953 std::make_pair(" OpCapability ImageBasic" + 954 std::string(kOpenCLMemoryModel) + 955 std::string(" OpEntryPoint Kernel %func \"compute\"") + 956 " %voidt = OpTypeVoid" 957 " %imgt = OpTypeImage %voidt Rect 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 958 SampledRectDependencies()), 959 std::make_pair(" OpCapability ImageBasic" + 960 std::string(kOpenCLMemoryModel) + 961 std::string(" OpEntryPoint Kernel %func \"compute\"") + 962 " %voidt = OpTypeVoid" 963 " %imgt = OpTypeImage %voidt Buffer 0 0 0 0 Unknown" + std::string(kVoidFVoid2), 964 SampledBufferDependencies()), 965 std::make_pair(" OpCapability ImageBasic" + 966 std::string(kOpenCLMemoryModel) + 967 std::string(" OpEntryPoint Kernel %func \"compute\"") + 968 " %voidt = OpTypeVoid" 969 " %imgt = OpTypeImage %voidt SubpassData 0 0 0 2 Unknown" + std::string(kVoidFVoid2), 970 std::vector<std::string>{"InputAttachment"}) 971 )),); 972 973 // NOTE: All Sampler Address Modes require kernel capabilities but the 974 // OpConstantSampler requires LiteralSampler which depends on Kernel 975 INSTANTIATE_TEST_CASE_P(SamplerAddressingMode, ValidateCapability, 976 Combine( 977 ValuesIn(AllCapabilities()), 978 Values( 979 std::make_pair(std::string(kGLSL450MemoryModel) + 980 " OpEntryPoint Vertex %func \"shader\"" 981 " %samplert = OpTypeSampler" 982 " %sampler = OpConstantSampler %samplert None 1 Nearest" + 983 std::string(kVoidFVoid), 984 std::vector<std::string>{"LiteralSampler"}), 985 std::make_pair(std::string(kGLSL450MemoryModel) + 986 " OpEntryPoint Vertex %func \"shader\"" 987 " %samplert = OpTypeSampler" 988 " %sampler = OpConstantSampler %samplert ClampToEdge 1 Nearest" + 989 std::string(kVoidFVoid), 990 std::vector<std::string>{"LiteralSampler"}), 991 std::make_pair(std::string(kGLSL450MemoryModel) + 992 " OpEntryPoint Vertex %func \"shader\"" 993 " %samplert = OpTypeSampler" 994 " %sampler = OpConstantSampler %samplert Clamp 1 Nearest" + 995 std::string(kVoidFVoid), 996 std::vector<std::string>{"LiteralSampler"}), 997 std::make_pair(std::string(kGLSL450MemoryModel) + 998 " OpEntryPoint Vertex %func \"shader\"" 999 " %samplert = OpTypeSampler" 1000 " %sampler = OpConstantSampler %samplert Repeat 1 Nearest" + 1001 std::string(kVoidFVoid), 1002 std::vector<std::string>{"LiteralSampler"}), 1003 std::make_pair(std::string(kGLSL450MemoryModel) + 1004 " OpEntryPoint Vertex %func \"shader\"" 1005 " %samplert = OpTypeSampler" 1006 " %sampler = OpConstantSampler %samplert RepeatMirrored 1 Nearest" + 1007 std::string(kVoidFVoid), 1008 std::vector<std::string>{"LiteralSampler"}) 1009 )),); 1010 1011 // TODO(umar): Sampler Filter Mode 1012 // TODO(umar): Image Format 1013 // TODO(umar): Image Channel Order 1014 // TODO(umar): Image Channel Data Type 1015 // TODO(umar): Image Operands 1016 // TODO(umar): FP Fast Math Mode 1017 // TODO(umar): FP Rounding Mode 1018 // TODO(umar): Linkage Type 1019 // TODO(umar): Access Qualifier 1020 // TODO(umar): Function Parameter Attribute 1021 1022 INSTANTIATE_TEST_CASE_P(Decoration, ValidateCapability, 1023 Combine( 1024 ValuesIn(AllCapabilities()), 1025 Values( 1026 std::make_pair(std::string(kOpenCLMemoryModel) + 1027 "OpEntryPoint Kernel %func \"compute\" \n" 1028 "OpDecorate %intt RelaxedPrecision\n" 1029 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1030 ShaderDependencies()), 1031 std::make_pair(std::string(kOpenCLMemoryModel) + 1032 "OpEntryPoint Kernel %func \"compute\" \n" 1033 "OpDecorate %intt Block\n" 1034 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1035 ShaderDependencies()), 1036 std::make_pair(std::string(kOpenCLMemoryModel) + 1037 "OpEntryPoint Kernel %func \"compute\" \n" 1038 "OpDecorate %intt BufferBlock\n" 1039 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1040 ShaderDependencies()), 1041 std::make_pair(std::string(kOpenCLMemoryModel) + 1042 "OpEntryPoint Kernel %func \"compute\" \n" 1043 "OpDecorate %intt RowMajor\n" 1044 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1045 MatrixDependencies()), 1046 std::make_pair(std::string(kOpenCLMemoryModel) + 1047 "OpEntryPoint Kernel %func \"compute\" \n" 1048 "OpDecorate %intt ColMajor\n" 1049 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1050 MatrixDependencies()), 1051 std::make_pair(std::string(kOpenCLMemoryModel) + 1052 "OpEntryPoint Kernel %func \"compute\" \n" 1053 "OpDecorate %intt ArrayStride 1\n" 1054 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1055 ShaderDependencies()), 1056 std::make_pair(std::string(kOpenCLMemoryModel) + 1057 "OpEntryPoint Kernel %func \"compute\" \n" 1058 "OpDecorate %intt MatrixStride 1\n" 1059 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1060 MatrixDependencies()), 1061 std::make_pair(std::string(kOpenCLMemoryModel) + 1062 "OpEntryPoint Kernel %func \"compute\" \n" 1063 "OpDecorate %intt GLSLShared\n" 1064 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1065 ShaderDependencies()), 1066 std::make_pair(std::string(kOpenCLMemoryModel) + 1067 "OpEntryPoint Kernel %func \"compute\" \n" 1068 "OpDecorate %intt GLSLPacked\n" 1069 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1070 ShaderDependencies()), 1071 std::make_pair(std::string(kGLSL450MemoryModel) + 1072 "OpEntryPoint Vertex %func \"shader\" \n" 1073 "OpDecorate %intt CPacked\n" 1074 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1075 KernelDependencies()), 1076 std::make_pair(std::string(kOpenCLMemoryModel) + 1077 "OpEntryPoint Kernel %func \"compute\" \n" 1078 "OpDecorate %intt NoPerspective\n" 1079 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1080 ShaderDependencies()), 1081 std::make_pair(std::string(kOpenCLMemoryModel) + 1082 "OpEntryPoint Kernel %func \"compute\" \n" 1083 "OpDecorate %intt Flat\n" 1084 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1085 ShaderDependencies()), 1086 std::make_pair(std::string(kOpenCLMemoryModel) + 1087 "OpEntryPoint Kernel %func \"compute\" \n" 1088 "OpDecorate %intt Patch\n" 1089 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1090 TessellationDependencies()), 1091 std::make_pair(std::string(kOpenCLMemoryModel) + 1092 "OpEntryPoint Kernel %func \"compute\" \n" 1093 "OpDecorate %intt Centroid\n" 1094 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1095 ShaderDependencies()), 1096 std::make_pair(std::string(kOpenCLMemoryModel) + 1097 "OpEntryPoint Kernel %func \"compute\" \n" 1098 "OpDecorate %intt Sample\n" 1099 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1100 std::vector<std::string>{"SampleRateShading"}), 1101 std::make_pair(std::string(kOpenCLMemoryModel) + 1102 "OpEntryPoint Kernel %func \"compute\" \n" 1103 "OpDecorate %intt Invariant\n" 1104 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1105 ShaderDependencies()), 1106 std::make_pair(std::string(kOpenCLMemoryModel) + 1107 "OpEntryPoint Kernel %func \"compute\" \n" 1108 "OpDecorate %intt Restrict\n" 1109 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1110 AllCapabilities()), 1111 std::make_pair(std::string(kOpenCLMemoryModel) + 1112 "OpEntryPoint Kernel %func \"compute\" \n" 1113 "OpDecorate %intt Aliased\n" 1114 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1115 AllCapabilities()), 1116 std::make_pair(std::string(kOpenCLMemoryModel) + 1117 "OpEntryPoint Kernel %func \"compute\" \n" 1118 "OpDecorate %intt Volatile\n" 1119 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1120 AllCapabilities()), 1121 std::make_pair(std::string(kGLSL450MemoryModel) + 1122 "OpEntryPoint Vertex %func \"shader\" \n" 1123 "OpDecorate %intt Constant\n" 1124 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1125 KernelDependencies()), 1126 std::make_pair(std::string(kOpenCLMemoryModel) + 1127 "OpEntryPoint Kernel %func \"compute\" \n" 1128 "OpDecorate %intt Coherent\n" 1129 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1130 AllCapabilities()), 1131 std::make_pair(std::string(kOpenCLMemoryModel) + 1132 "OpEntryPoint Kernel %func \"compute\" \n" 1133 "OpDecorate %intt NonWritable\n" 1134 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1135 AllCapabilities()), 1136 std::make_pair(std::string(kOpenCLMemoryModel) + 1137 "OpEntryPoint Kernel %func \"compute\" \n" 1138 "OpDecorate %intt NonReadable\n" 1139 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1140 AllCapabilities()), 1141 std::make_pair(std::string(kOpenCLMemoryModel) + 1142 // Uniform must target a non-void value. 1143 "OpEntryPoint Kernel %func \"compute\" \n" 1144 "OpDecorate %int0 Uniform\n" 1145 "%intt = OpTypeInt 32 0\n" + 1146 "%int0 = OpConstantNull %intt" 1147 + std::string(kVoidFVoid), 1148 ShaderDependencies()), 1149 std::make_pair(std::string(kGLSL450MemoryModel) + 1150 "OpEntryPoint Vertex %func \"shader\" \n" 1151 "OpDecorate %intt SaturatedConversion\n" 1152 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1153 KernelDependencies()), 1154 std::make_pair(std::string(kOpenCLMemoryModel) + 1155 "OpEntryPoint Kernel %func \"compute\" \n" 1156 "OpDecorate %intt Stream 0\n" 1157 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1158 std::vector<std::string>{"GeometryStreams"}), 1159 std::make_pair(std::string(kOpenCLMemoryModel) + 1160 "OpEntryPoint Kernel %func \"compute\" \n" 1161 "OpDecorate %intt Location 0\n" 1162 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1163 ShaderDependencies()), 1164 std::make_pair(std::string(kOpenCLMemoryModel) + 1165 "OpEntryPoint Kernel %func \"compute\" \n" 1166 "OpDecorate %intt Component 0\n" 1167 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1168 ShaderDependencies()), 1169 std::make_pair(std::string(kOpenCLMemoryModel) + 1170 "OpEntryPoint Kernel %func \"compute\" \n" 1171 "OpDecorate %intt Index 0\n" 1172 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1173 ShaderDependencies()), 1174 std::make_pair(std::string(kOpenCLMemoryModel) + 1175 "OpEntryPoint Kernel %func \"compute\" \n" 1176 "OpDecorate %intt Binding 0\n" 1177 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1178 ShaderDependencies()), 1179 std::make_pair(std::string(kOpenCLMemoryModel) + 1180 "OpEntryPoint Kernel %func \"compute\" \n" 1181 "OpDecorate %intt DescriptorSet 0\n" 1182 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1183 ShaderDependencies()), 1184 std::make_pair(std::string(kOpenCLMemoryModel) + 1185 "OpEntryPoint Kernel %func \"compute\" \n" 1186 "OpDecorate %intt Offset 0\n" 1187 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1188 ShaderDependencies()), 1189 std::make_pair(std::string(kOpenCLMemoryModel) + 1190 "OpEntryPoint Kernel %func \"compute\" \n" 1191 "OpDecorate %intt XfbBuffer 0\n" 1192 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1193 std::vector<std::string>{"TransformFeedback"}), 1194 std::make_pair(std::string(kOpenCLMemoryModel) + 1195 "OpEntryPoint Kernel %func \"compute\" \n" 1196 "OpDecorate %intt XfbStride 0\n" 1197 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1198 std::vector<std::string>{"TransformFeedback"}), 1199 std::make_pair(std::string(kGLSL450MemoryModel) + 1200 "OpEntryPoint Vertex %func \"shader\" \n" 1201 "OpDecorate %intt FuncParamAttr Zext\n" 1202 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1203 KernelDependencies()), 1204 std::make_pair(std::string(kGLSL450MemoryModel) + 1205 "OpEntryPoint Vertex %func \"shader\" \n" 1206 "OpDecorate %intt FPFastMathMode Fast\n" 1207 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1208 KernelDependencies()), 1209 std::make_pair(std::string(kOpenCLMemoryModel) + 1210 "OpEntryPoint Kernel %func \"compute\" \n" 1211 "OpDecorate %intt LinkageAttributes \"other\" Import\n" 1212 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1213 std::vector<std::string>{"Linkage"}), 1214 std::make_pair(std::string(kOpenCLMemoryModel) + 1215 "OpEntryPoint Kernel %func \"compute\" \n" 1216 "OpDecorate %intt NoContraction\n" 1217 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1218 ShaderDependencies()), 1219 std::make_pair(std::string(kOpenCLMemoryModel) + 1220 "OpEntryPoint Kernel %func \"compute\" \n" 1221 "OpDecorate %intt InputAttachmentIndex 0\n" 1222 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1223 std::vector<std::string>{"InputAttachment"}), 1224 std::make_pair(std::string(kGLSL450MemoryModel) + 1225 "OpEntryPoint Vertex %func \"shader\" \n" 1226 "OpDecorate %intt Alignment 4\n" 1227 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1228 KernelDependencies()) 1229 )),); 1230 1231 // clang-format on 1232 INSTANTIATE_TEST_CASE_P( 1233 DecorationSpecId, ValidateCapability, 1234 Combine( 1235 ValuesIn(AllSpirV10Capabilities()), 1236 Values(std::make_pair(std::string(kOpenCLMemoryModel) + 1237 "OpEntryPoint Vertex %func \"shader\" \n" + 1238 "OpDecorate %1 SpecId 1\n" 1239 "%intt = OpTypeInt 32 0\n" 1240 "%1 = OpSpecConstant %intt 0\n" + 1241 std::string(kVoidFVoid), 1242 ShaderDependencies()))), ); 1243 1244 INSTANTIATE_TEST_CASE_P( 1245 DecorationV11, ValidateCapabilityV11, 1246 Combine(ValuesIn(AllCapabilities()), 1247 Values(std::make_pair(std::string(kOpenCLMemoryModel) + 1248 "OpEntryPoint Kernel %func \"compute\" \n" 1249 "OpDecorate %p MaxByteOffset 0 " 1250 "%i32 = OpTypeInt 32 0 " 1251 "%pi32 = OpTypePointer Workgroup %i32 " 1252 "%p = OpVariable %pi32 Workgroup " + 1253 std::string(kVoidFVoid), 1254 AddressesDependencies()), 1255 // Trying to test OpDecorate here, but if this fails due to 1256 // incorrect OpMemoryModel validation, that must also be 1257 // fixed. 1258 std::make_pair( 1259 std::string("OpMemoryModel Logical OpenCL " 1260 "OpEntryPoint Kernel %func \"compute\" \n" 1261 "OpDecorate %1 SpecId 1 " 1262 "%intt = OpTypeInt 32 0 " 1263 "%1 = OpSpecConstant %intt 0") + 1264 std::string(kVoidFVoid), 1265 KernelDependencies()), 1266 std::make_pair( 1267 std::string("OpMemoryModel Logical Simple " 1268 "OpEntryPoint Vertex %func \"shader\" \n" 1269 "OpDecorate %1 SpecId 1 " 1270 "%intt = OpTypeInt 32 0 " 1271 "%1 = OpSpecConstant %intt 0") + 1272 std::string(kVoidFVoid), 1273 ShaderDependencies()))), ); 1274 // clang-format off 1275 1276 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapability, 1277 Combine( 1278 ValuesIn(AllCapabilities()), 1279 Values( 1280 std::make_pair(std::string(kOpenCLMemoryModel) + 1281 "OpEntryPoint Kernel %func \"compute\" \n" + 1282 "OpDecorate %intt BuiltIn Position\n" 1283 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1284 ShaderDependencies()), 1285 // Just mentioning PointSize, ClipDistance, or CullDistance as a BuiltIn does 1286 // not trigger the requirement for the associated capability. 1287 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 1288 std::make_pair(std::string(kOpenCLMemoryModel) + 1289 "OpEntryPoint Kernel %func \"compute\" \n" + 1290 "OpDecorate %intt BuiltIn PointSize\n" 1291 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1292 AllCapabilities()), 1293 std::make_pair(std::string(kOpenCLMemoryModel) + 1294 "OpEntryPoint Kernel %func \"compute\" \n" + 1295 "OpDecorate %intt BuiltIn ClipDistance\n" 1296 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1297 AllCapabilities()), 1298 std::make_pair(std::string(kOpenCLMemoryModel) + 1299 "OpEntryPoint Kernel %func \"compute\" \n" + 1300 "OpDecorate %intt BuiltIn CullDistance\n" 1301 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1302 AllCapabilities()), 1303 std::make_pair(std::string(kOpenCLMemoryModel) + 1304 "OpEntryPoint Kernel %func \"compute\" \n" + 1305 "OpDecorate %intt BuiltIn VertexId\n" 1306 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1307 ShaderDependencies()), 1308 std::make_pair(std::string(kOpenCLMemoryModel) + 1309 "OpEntryPoint Kernel %func \"compute\" \n" + 1310 "OpDecorate %intt BuiltIn InstanceId\n" 1311 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1312 ShaderDependencies()), 1313 std::make_pair(std::string(kOpenCLMemoryModel) + 1314 "OpEntryPoint Kernel %func \"compute\" \n" + 1315 "OpDecorate %intt BuiltIn PrimitiveId\n" 1316 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1317 GeometryTessellationDependencies()), 1318 std::make_pair(std::string(kOpenCLMemoryModel) + 1319 "OpEntryPoint Kernel %func \"compute\" \n" + 1320 "OpDecorate %intt BuiltIn InvocationId\n" 1321 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1322 GeometryTessellationDependencies()), 1323 std::make_pair(std::string(kOpenCLMemoryModel) + 1324 "OpEntryPoint Kernel %func \"compute\" \n" + 1325 "OpDecorate %intt BuiltIn Layer\n" 1326 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1327 GeometryDependencies()), 1328 std::make_pair(std::string(kOpenCLMemoryModel) + 1329 "OpEntryPoint Kernel %func \"compute\" \n" + 1330 "OpDecorate %intt BuiltIn ViewportIndex\n" 1331 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1332 std::vector<std::string>{"MultiViewport"}), 1333 std::make_pair(std::string(kOpenCLMemoryModel) + 1334 "OpEntryPoint Kernel %func \"compute\" \n" + 1335 "OpDecorate %intt BuiltIn TessLevelOuter\n" 1336 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1337 TessellationDependencies()), 1338 std::make_pair(std::string(kOpenCLMemoryModel) + 1339 "OpEntryPoint Kernel %func \"compute\" \n" + 1340 "OpDecorate %intt BuiltIn TessLevelInner\n" 1341 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1342 TessellationDependencies()), 1343 std::make_pair(std::string(kOpenCLMemoryModel) + 1344 "OpEntryPoint Kernel %func \"compute\" \n" + 1345 "OpDecorate %intt BuiltIn TessCoord\n" 1346 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1347 TessellationDependencies()), 1348 std::make_pair(std::string(kOpenCLMemoryModel) + 1349 "OpEntryPoint Kernel %func \"compute\" \n" + 1350 "OpDecorate %intt BuiltIn PatchVertices\n" 1351 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1352 TessellationDependencies()), 1353 std::make_pair(std::string(kOpenCLMemoryModel) + 1354 "OpEntryPoint Kernel %func \"compute\" \n" + 1355 "OpDecorate %intt BuiltIn FragCoord\n" 1356 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1357 ShaderDependencies()), 1358 std::make_pair(std::string(kOpenCLMemoryModel) + 1359 "OpEntryPoint Kernel %func \"compute\" \n" + 1360 "OpDecorate %intt BuiltIn PointCoord\n" 1361 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1362 ShaderDependencies()), 1363 std::make_pair(std::string(kOpenCLMemoryModel) + 1364 "OpEntryPoint Kernel %func \"compute\" \n" + 1365 "OpDecorate %intt BuiltIn FrontFacing\n" 1366 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1367 ShaderDependencies()), 1368 std::make_pair(std::string(kOpenCLMemoryModel) + 1369 "OpEntryPoint Kernel %func \"compute\" \n" + 1370 "OpDecorate %intt BuiltIn SampleId\n" 1371 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1372 std::vector<std::string>{"SampleRateShading"}), 1373 std::make_pair(std::string(kOpenCLMemoryModel) + 1374 "OpEntryPoint Kernel %func \"compute\" \n" + 1375 "OpDecorate %intt BuiltIn SamplePosition\n" 1376 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1377 std::vector<std::string>{"SampleRateShading"}), 1378 std::make_pair(std::string(kOpenCLMemoryModel) + 1379 "OpEntryPoint Kernel %func \"compute\" \n" + 1380 "OpDecorate %intt BuiltIn SampleMask\n" 1381 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1382 ShaderDependencies()), 1383 std::make_pair(std::string(kOpenCLMemoryModel) + 1384 "OpEntryPoint Kernel %func \"compute\" \n" + 1385 "OpDecorate %intt BuiltIn FragDepth\n" 1386 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1387 ShaderDependencies()), 1388 std::make_pair(std::string(kOpenCLMemoryModel) + 1389 "OpEntryPoint Kernel %func \"compute\" \n" + 1390 "OpDecorate %intt BuiltIn HelperInvocation\n" 1391 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1392 ShaderDependencies()), 1393 std::make_pair(std::string(kOpenCLMemoryModel) + 1394 "OpEntryPoint Kernel %func \"compute\" \n" + 1395 "OpDecorate %intt BuiltIn VertexIndex\n" 1396 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1397 ShaderDependencies()), 1398 std::make_pair(std::string(kOpenCLMemoryModel) + 1399 "OpEntryPoint Kernel %func \"compute\" \n" + 1400 "OpDecorate %intt BuiltIn InstanceIndex\n" 1401 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1402 ShaderDependencies()), 1403 std::make_pair(std::string(kOpenCLMemoryModel) + 1404 "OpEntryPoint Kernel %func \"compute\" \n" + 1405 "OpDecorate %intt BuiltIn NumWorkgroups\n" 1406 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1407 AllCapabilities()), 1408 std::make_pair(std::string(kOpenCLMemoryModel) + 1409 "OpEntryPoint Kernel %func \"compute\" \n" + 1410 "OpDecorate %intt BuiltIn WorkgroupSize\n" 1411 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1412 AllCapabilities()), 1413 std::make_pair(std::string(kOpenCLMemoryModel) + 1414 "OpEntryPoint Kernel %func \"compute\" \n" + 1415 "OpDecorate %intt BuiltIn WorkgroupId\n" 1416 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1417 AllCapabilities()), 1418 std::make_pair(std::string(kOpenCLMemoryModel) + 1419 "OpEntryPoint Kernel %func \"compute\" \n" + 1420 "OpDecorate %intt BuiltIn LocalInvocationId\n" 1421 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1422 AllCapabilities()), 1423 std::make_pair(std::string(kOpenCLMemoryModel) + 1424 "OpEntryPoint Kernel %func \"compute\" \n" + 1425 "OpDecorate %intt BuiltIn GlobalInvocationId\n" 1426 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1427 AllCapabilities()), 1428 std::make_pair(std::string(kOpenCLMemoryModel) + 1429 "OpEntryPoint Kernel %func \"compute\" \n" + 1430 "OpDecorate %intt BuiltIn LocalInvocationIndex\n" 1431 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1432 AllCapabilities()), 1433 std::make_pair(std::string(kGLSL450MemoryModel) + 1434 "OpEntryPoint Vertex %func \"shader\" \n" + 1435 "OpDecorate %intt BuiltIn WorkDim\n" 1436 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1437 KernelDependencies()), 1438 std::make_pair(std::string(kGLSL450MemoryModel) + 1439 "OpEntryPoint Vertex %func \"shader\" \n" + 1440 "OpDecorate %intt BuiltIn GlobalSize\n" 1441 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1442 KernelDependencies()), 1443 std::make_pair(std::string(kGLSL450MemoryModel) + 1444 "OpEntryPoint Vertex %func \"shader\" \n" + 1445 "OpDecorate %intt BuiltIn EnqueuedWorkgroupSize\n" 1446 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1447 KernelDependencies()), 1448 std::make_pair(std::string(kGLSL450MemoryModel) + 1449 "OpEntryPoint Vertex %func \"shader\" \n" + 1450 "OpDecorate %intt BuiltIn GlobalOffset\n" 1451 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1452 KernelDependencies()), 1453 std::make_pair(std::string(kGLSL450MemoryModel) + 1454 "OpEntryPoint Vertex %func \"shader\" \n" + 1455 "OpDecorate %intt BuiltIn GlobalLinearId\n" 1456 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1457 KernelDependencies()), 1458 std::make_pair(std::string(kGLSL450MemoryModel) + 1459 "OpEntryPoint Vertex %func \"shader\" \n" + 1460 "OpDecorate %intt BuiltIn SubgroupSize\n" 1461 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1462 KernelAndGroupNonUniformDependencies()), 1463 std::make_pair(std::string(kGLSL450MemoryModel) + 1464 "OpEntryPoint Vertex %func \"shader\" \n" + 1465 "OpDecorate %intt BuiltIn SubgroupMaxSize\n" 1466 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1467 KernelDependencies()), 1468 std::make_pair(std::string(kGLSL450MemoryModel) + 1469 "OpEntryPoint Vertex %func \"shader\" \n" + 1470 "OpDecorate %intt BuiltIn NumSubgroups\n" 1471 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1472 KernelAndGroupNonUniformDependencies()), 1473 std::make_pair(std::string(kGLSL450MemoryModel) + 1474 "OpEntryPoint Vertex %func \"shader\" \n" + 1475 "OpDecorate %intt BuiltIn NumEnqueuedSubgroups\n" 1476 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1477 KernelDependencies()), 1478 std::make_pair(std::string(kGLSL450MemoryModel) + 1479 "OpEntryPoint Vertex %func \"shader\" \n" + 1480 "OpDecorate %intt BuiltIn SubgroupId\n" 1481 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1482 KernelAndGroupNonUniformDependencies()), 1483 std::make_pair(std::string(kGLSL450MemoryModel) + 1484 "OpEntryPoint Vertex %func \"shader\" \n" + 1485 "OpDecorate %intt BuiltIn SubgroupLocalInvocationId\n" 1486 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1487 KernelAndGroupNonUniformDependencies()), 1488 std::make_pair(std::string(kOpenCLMemoryModel) + 1489 "OpEntryPoint Kernel %func \"compute\" \n" + 1490 "OpDecorate %intt BuiltIn VertexIndex\n" 1491 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1492 ShaderDependencies()), 1493 std::make_pair(std::string(kOpenCLMemoryModel) + 1494 "OpEntryPoint Kernel %func \"compute\" \n" + 1495 "OpDecorate %intt BuiltIn InstanceIndex\n" 1496 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1497 ShaderDependencies()) 1498 )),); 1499 1500 // Ensure that mere mention of PointSize, ClipDistance, or CullDistance as 1501 // BuiltIns does not trigger the requirement for the associated 1502 // capability. 1503 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 1504 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityVulkan10, 1505 Combine( 1506 // All capabilities to try. 1507 ValuesIn(AllSpirV10Capabilities()), 1508 Values( 1509 std::make_pair(std::string(kGLSL450MemoryModel) + 1510 "OpEntryPoint Vertex %func \"shader\" \n" 1511 "OpMemberDecorate %block 0 BuiltIn PointSize\n" 1512 "%f32 = OpTypeFloat 32\n" 1513 "%block = OpTypeStruct %f32\n" 1514 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1515 // Capabilities which should succeed. 1516 AllVulkan10Capabilities()), 1517 std::make_pair(std::string(kGLSL450MemoryModel) + 1518 "OpEntryPoint Vertex %func \"shader\" \n" 1519 "OpMemberDecorate %block 0 BuiltIn ClipDistance\n" 1520 "%f32 = OpTypeFloat 32\n" 1521 "%intt = OpTypeInt 32 0\n" 1522 "%intt_4 = OpConstant %intt 4\n" 1523 "%f32arr4 = OpTypeArray %f32 %intt_4\n" 1524 "%block = OpTypeStruct %f32arr4\n" + std::string(kVoidFVoid), 1525 AllVulkan10Capabilities()), 1526 std::make_pair(std::string(kGLSL450MemoryModel) + 1527 "OpEntryPoint Vertex %func \"shader\" \n" 1528 "OpMemberDecorate %block 0 BuiltIn CullDistance\n" 1529 "%f32 = OpTypeFloat 32\n" 1530 "%intt = OpTypeInt 32 0\n" 1531 "%intt_4 = OpConstant %intt 4\n" 1532 "%f32arr4 = OpTypeArray %f32 %intt_4\n" 1533 "%block = OpTypeStruct %f32arr4\n" + std::string(kVoidFVoid), 1534 AllVulkan10Capabilities()) 1535 )),); 1536 1537 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityOpenGL40, 1538 Combine( 1539 // OpenGL 4.0 is based on SPIR-V 1.0 1540 ValuesIn(AllSpirV10Capabilities()), 1541 Values( 1542 std::make_pair(std::string(kGLSL450MemoryModel) + 1543 "OpEntryPoint Vertex %func \"shader\" \n" + 1544 "OpDecorate %intt BuiltIn PointSize\n" 1545 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1546 AllSpirV10Capabilities()), 1547 std::make_pair(std::string(kGLSL450MemoryModel) + 1548 "OpEntryPoint Vertex %func \"shader\" \n" + 1549 "OpDecorate %intt BuiltIn ClipDistance\n" 1550 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1551 AllSpirV10Capabilities()), 1552 std::make_pair(std::string(kGLSL450MemoryModel) + 1553 "OpEntryPoint Vertex %func \"shader\" \n" + 1554 "OpDecorate %intt BuiltIn CullDistance\n" 1555 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1556 AllSpirV10Capabilities()) 1557 )),); 1558 1559 INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityWebGPU, 1560 Combine( 1561 // All capabilities to try. 1562 ValuesIn(AllCapabilities()), 1563 Values( 1564 std::make_pair(std::string(kVulkanMemoryModel) + 1565 "OpEntryPoint Vertex %func \"shader\" \n" + std::string(kVoidFVoid), 1566 AllWebGPUCapabilities()) 1567 )),); 1568 1569 INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityVulkan11, 1570 Combine( 1571 // All capabilities to try. 1572 ValuesIn(AllCapabilities()), 1573 Values( 1574 std::make_pair(std::string(kGLSL450MemoryModel) + 1575 "OpEntryPoint Vertex %func \"shader\" \n" + 1576 "OpDecorate %intt BuiltIn PointSize\n" 1577 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1578 AllVulkan11Capabilities()), 1579 std::make_pair(std::string(kGLSL450MemoryModel) + 1580 "OpEntryPoint Vertex %func \"shader\" \n" + 1581 "OpDecorate %intt BuiltIn CullDistance\n" 1582 "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid), 1583 AllVulkan11Capabilities()) 1584 )),); 1585 1586 // TODO(umar): Selection Control 1587 // TODO(umar): Loop Control 1588 // TODO(umar): Function Control 1589 // TODO(umar): Memory Semantics 1590 // TODO(umar): Memory Access 1591 // TODO(umar): Scope 1592 // TODO(umar): Group Operation 1593 // TODO(umar): Kernel Enqueue Flags 1594 // TODO(umar): Kernel Profiling Flags 1595 1596 INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateCapability, 1597 Combine( 1598 ValuesIn(AllCapabilities()), 1599 Values( 1600 std::make_pair(std::string(kOpenCLMemoryModel) + 1601 "OpEntryPoint Kernel %func \"compute\" \n" + 1602 "%f32 = OpTypeFloat 32\n" 1603 "%vec3 = OpTypeVector %f32 3\n" 1604 "%mat33 = OpTypeMatrix %vec3 3\n" + std::string(kVoidFVoid), 1605 MatrixDependencies()))),); 1606 // clang-format on 1607 1608 #if 0 1609 // TODO(atgoo (at) github.com) The following test is not valid as it generates 1610 // invalid combinations of images, instructions and image operands. 1611 // 1612 // Creates assembly containing an OpImageFetch instruction using operands for 1613 // the image-operands part. The assembly defines constants %fzero and %izero 1614 // that can be used for operands where IDs are required. The assembly is valid, 1615 // apart from not declaring any capabilities required by the operands. 1616 string ImageOperandsTemplate(const std::string& operands) { 1617 ostringstream ss; 1618 // clang-format off 1619 ss << R"( 1620 OpCapability Kernel 1621 OpCapability Linkage 1622 OpMemoryModel Logical OpenCL 1623 1624 %i32 = OpTypeInt 32 0 1625 %f32 = OpTypeFloat 32 1626 %v4i32 = OpTypeVector %i32 4 1627 %timg = OpTypeImage %i32 2D 0 0 0 0 Unknown 1628 %pimg = OpTypePointer UniformConstant %timg 1629 %tfun = OpTypeFunction %i32 1630 1631 %vimg = OpVariable %pimg UniformConstant 1632 %izero = OpConstant %i32 0 1633 %fzero = OpConstant %f32 0. 1634 1635 %main = OpFunction %i32 None %tfun 1636 %lbl = OpLabel 1637 %img = OpLoad %timg %vimg 1638 %r1 = OpImageFetch %v4i32 %img %izero )" << operands << R"( 1639 OpReturnValue %izero 1640 OpFunctionEnd 1641 )"; 1642 // clang-format on 1643 return ss.str(); 1644 } 1645 1646 INSTANTIATE_TEST_CASE_P( 1647 TwoImageOperandsMask, ValidateCapability, 1648 Combine( 1649 ValuesIn(AllCapabilities()), 1650 Values(std::make_pair(ImageOperandsTemplate("Bias|Lod %fzero %fzero"), 1651 ShaderDependencies()), 1652 std::make_pair(ImageOperandsTemplate("Lod|Offset %fzero %izero"), 1653 std::vector<std::string>{"ImageGatherExtended"}), 1654 std::make_pair(ImageOperandsTemplate("Sample|MinLod %izero %fzero"), 1655 std::vector<std::string>{"MinLod"}), 1656 std::make_pair(ImageOperandsTemplate("Lod|Sample %fzero %izero"), 1657 AllCapabilities()))), ); 1658 #endif 1659 1660 // TODO(umar): Instruction capability checks 1661 1662 spv_result_t spvCoreOperandTableNameLookup(spv_target_env env, 1663 const spv_operand_table table, 1664 const spv_operand_type_t type, 1665 const char* name, 1666 const size_t nameLength) { 1667 if (!table) return SPV_ERROR_INVALID_TABLE; 1668 if (!name) return SPV_ERROR_INVALID_POINTER; 1669 1670 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) { 1671 const auto& group = table->types[typeIndex]; 1672 if (type != group.type) continue; 1673 for (uint64_t index = 0; index < group.count; ++index) { 1674 const auto& entry = group.entries[index]; 1675 // Check for min version only. 1676 if (spvVersionForTargetEnv(env) >= entry.minVersion && 1677 nameLength == strlen(entry.name) && 1678 !strncmp(entry.name, name, nameLength)) { 1679 return SPV_SUCCESS; 1680 } 1681 } 1682 } 1683 1684 return SPV_ERROR_INVALID_LOOKUP; 1685 } 1686 1687 // True if capability exists in core spec of env. 1688 bool Exists(const std::string& capability, spv_target_env env) { 1689 ScopedContext sc(env); 1690 return SPV_SUCCESS == 1691 spvCoreOperandTableNameLookup(env, sc.context->operand_table, 1692 SPV_OPERAND_TYPE_CAPABILITY, 1693 capability.c_str(), capability.size()); 1694 } 1695 1696 TEST_P(ValidateCapability, Capability) { 1697 const std::string capability = Capability(GetParam()); 1698 spv_target_env env = SPV_ENV_UNIVERSAL_1_0; 1699 if (!capability.empty()) { 1700 if (Exists(capability, SPV_ENV_UNIVERSAL_1_0)) 1701 env = SPV_ENV_UNIVERSAL_1_0; 1702 else if (Exists(capability, SPV_ENV_UNIVERSAL_1_1)) 1703 env = SPV_ENV_UNIVERSAL_1_1; 1704 else if (Exists(capability, SPV_ENV_UNIVERSAL_1_2)) 1705 env = SPV_ENV_UNIVERSAL_1_2; 1706 else 1707 env = SPV_ENV_UNIVERSAL_1_3; 1708 } 1709 const std::string test_code = MakeAssembly(GetParam()); 1710 CompileSuccessfully(test_code, env); 1711 ASSERT_EQ(ExpectedResult(GetParam()), ValidateInstructions(env)) 1712 << "target env: " << spvTargetEnvDescription(env) << "\ntest code:\n" 1713 << test_code; 1714 } 1715 1716 TEST_P(ValidateCapabilityV11, Capability) { 1717 const std::string capability = Capability(GetParam()); 1718 if (Exists(capability, SPV_ENV_UNIVERSAL_1_1)) { 1719 const std::string test_code = MakeAssembly(GetParam()); 1720 CompileSuccessfully(test_code, SPV_ENV_UNIVERSAL_1_1); 1721 ASSERT_EQ(ExpectedResult(GetParam()), 1722 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)) 1723 << test_code; 1724 } 1725 } 1726 1727 TEST_P(ValidateCapabilityVulkan10, Capability) { 1728 const std::string capability = Capability(GetParam()); 1729 if (Exists(capability, SPV_ENV_VULKAN_1_0)) { 1730 const std::string test_code = MakeAssembly(GetParam()); 1731 CompileSuccessfully(test_code, SPV_ENV_VULKAN_1_0); 1732 ASSERT_EQ(ExpectedResult(GetParam()), 1733 ValidateInstructions(SPV_ENV_VULKAN_1_0)) 1734 << test_code; 1735 } 1736 } 1737 1738 TEST_P(ValidateCapabilityVulkan11, Capability) { 1739 const std::string capability = Capability(GetParam()); 1740 if (Exists(capability, SPV_ENV_VULKAN_1_1)) { 1741 const std::string test_code = MakeAssembly(GetParam()); 1742 CompileSuccessfully(test_code, SPV_ENV_VULKAN_1_1); 1743 ASSERT_EQ(ExpectedResult(GetParam()), 1744 ValidateInstructions(SPV_ENV_VULKAN_1_1)) 1745 << test_code; 1746 } 1747 } 1748 1749 TEST_P(ValidateCapabilityOpenGL40, Capability) { 1750 const std::string capability = Capability(GetParam()); 1751 if (Exists(capability, SPV_ENV_OPENGL_4_0)) { 1752 const std::string test_code = MakeAssembly(GetParam()); 1753 CompileSuccessfully(test_code, SPV_ENV_OPENGL_4_0); 1754 ASSERT_EQ(ExpectedResult(GetParam()), 1755 ValidateInstructions(SPV_ENV_OPENGL_4_0)) 1756 << test_code; 1757 } 1758 } 1759 1760 TEST_P(ValidateCapabilityWebGPU, Capability) { 1761 const std::string capability = Capability(GetParam()); 1762 if (Exists(capability, SPV_ENV_WEBGPU_0)) { 1763 const std::string test_code = MakeAssembly(GetParam()); 1764 CompileSuccessfully(test_code, SPV_ENV_WEBGPU_0); 1765 ASSERT_EQ(ExpectedResult(GetParam()), 1766 ValidateInstructions(SPV_ENV_WEBGPU_0)) 1767 << test_code; 1768 } 1769 } 1770 1771 TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) { 1772 // From https://github.com/KhronosGroup/SPIRV-Tools/issues/248 1773 // The validator was interpreting the memory semantics ID number 1774 // as the value to be checked rather than an ID that references 1775 // another value to be checked. 1776 // In this case a raw ID of 64 was mistaken to mean a literal 1777 // semantic value of UniformMemory, which would require the Shader 1778 // capability. 1779 const char str[] = R"( 1780 OpCapability Kernel 1781 OpCapability Linkage 1782 OpMemoryModel Logical OpenCL 1783 1784 ; %i32 has ID 1 1785 %i32 = OpTypeInt 32 0 1786 %tf = OpTypeFunction %i32 1787 %pi32 = OpTypePointer CrossWorkgroup %i32 1788 %var = OpVariable %pi32 CrossWorkgroup 1789 %c = OpConstant %i32 100 1790 %scope = OpConstant %i32 1 ; Device scope 1791 1792 ; Fake an instruction with 64 as the result id. 1793 ; !64 = OpConstantNull %i32 1794 !0x3002e !1 !64 1795 1796 %f = OpFunction %i32 None %tf 1797 %l = OpLabel 1798 %result = OpAtomicIAdd %i32 %var %scope !64 %c 1799 OpReturnValue %result 1800 OpFunctionEnd 1801 )"; 1802 1803 CompileSuccessfully(str); 1804 1805 // Since we are forcing usage of <id> 64, the "id bound" in the binary header 1806 // must be overwritten so that <id> 64 is considered within bound. 1807 // ID Bound is at index 3 of the binary. Set it to 65. 1808 OverwriteAssembledBinary(3, 65); 1809 1810 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1811 } 1812 1813 TEST_F(ValidateCapability, IntSignednessKernelGood) { 1814 const std::string spirv = R"( 1815 OpCapability Kernel 1816 OpCapability Linkage 1817 OpMemoryModel Logical OpenCL 1818 %i32 = OpTypeInt 32 0 1819 )"; 1820 CompileSuccessfully(spirv); 1821 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1822 } 1823 1824 TEST_F(ValidateCapability, IntSignednessKernelBad) { 1825 const std::string spirv = R"( 1826 OpCapability Kernel 1827 OpCapability Linkage 1828 OpMemoryModel Logical OpenCL 1829 %i32 = OpTypeInt 32 1 1830 )"; 1831 CompileSuccessfully(spirv); 1832 EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); 1833 EXPECT_THAT(getDiagnosticString(), 1834 HasSubstr("The Signedness in OpTypeInt must always be 0 when " 1835 "Kernel capability is used.")); 1836 } 1837 1838 TEST_F(ValidateCapability, IntSignednessShaderGood) { 1839 const std::string spirv = R"( 1840 OpCapability Shader 1841 OpCapability Linkage 1842 OpMemoryModel Logical GLSL450 1843 %u32 = OpTypeInt 32 0 1844 %i32 = OpTypeInt 32 1 1845 )"; 1846 CompileSuccessfully(spirv); 1847 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1848 } 1849 1850 TEST_F(ValidateCapability, NonVulkan10Capability) { 1851 const std::string spirv = R"( 1852 OpCapability Shader 1853 OpCapability Linkage 1854 OpMemoryModel Logical GLSL450 1855 %u32 = OpTypeInt 32 0 1856 %i32 = OpTypeInt 32 1 1857 )"; 1858 CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); 1859 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1860 ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1861 EXPECT_THAT(getDiagnosticString(), 1862 HasSubstr("Capability Linkage is not allowed by Vulkan 1.0")); 1863 } 1864 1865 TEST_F(ValidateCapability, Vulkan10EnabledByExtension) { 1866 const std::string spirv = R"( 1867 OpCapability Shader 1868 OpCapability DrawParameters 1869 OpExtension "SPV_KHR_shader_draw_parameters" 1870 OpMemoryModel Logical GLSL450 1871 OpEntryPoint Vertex %func "shader" 1872 OpMemberDecorate %block 0 BuiltIn PointSize 1873 %f32 = OpTypeFloat 32 1874 %block = OpTypeStruct %f32 1875 )" + std::string(kVoidFVoid); 1876 1877 CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); 1878 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1879 } 1880 1881 TEST_F(ValidateCapability, Vulkan10NotEnabledByExtension) { 1882 const std::string spirv = R"( 1883 OpCapability Shader 1884 OpCapability DrawParameters 1885 OpMemoryModel Logical GLSL450 1886 OpEntryPoint Vertex %func "shader" 1887 OpDecorate %intt BuiltIn PointSize 1888 %intt = OpTypeInt 32 0 1889 )" + std::string(kVoidFVoid); 1890 1891 CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); 1892 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1893 ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1894 EXPECT_THAT( 1895 getDiagnosticString(), 1896 HasSubstr("Capability DrawParameters is not allowed by Vulkan 1.0")); 1897 } 1898 1899 TEST_F(ValidateCapability, NonOpenCL12FullCapability) { 1900 const std::string spirv = R"( 1901 OpCapability Kernel 1902 OpCapability Addresses 1903 OpCapability Linkage 1904 OpCapability Pipes 1905 OpMemoryModel Physical64 OpenCL 1906 %u32 = OpTypeInt 32 0 1907 )"; 1908 CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2); 1909 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1910 ValidateInstructions(SPV_ENV_OPENCL_1_2)); 1911 EXPECT_THAT( 1912 getDiagnosticString(), 1913 HasSubstr("Capability Pipes is not allowed by OpenCL 1.2 Full Profile")); 1914 } 1915 1916 TEST_F(ValidateCapability, OpenCL12FullEnabledByCapability) { 1917 const std::string spirv = R"( 1918 OpCapability Kernel 1919 OpCapability Addresses 1920 OpCapability Linkage 1921 OpCapability ImageBasic 1922 OpCapability Sampled1D 1923 OpMemoryModel Physical64 OpenCL 1924 %u32 = OpTypeInt 32 0 1925 )" + std::string(kVoidFVoid); 1926 1927 CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2); 1928 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2)); 1929 } 1930 1931 TEST_F(ValidateCapability, OpenCL12FullNotEnabledByCapability) { 1932 const std::string spirv = R"( 1933 OpCapability Kernel 1934 OpCapability Addresses 1935 OpCapability Linkage 1936 OpCapability Sampled1D 1937 OpMemoryModel Physical64 OpenCL 1938 %u32 = OpTypeInt 32 0 1939 )" + std::string(kVoidFVoid); 1940 1941 CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2); 1942 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1943 ValidateInstructions(SPV_ENV_OPENCL_1_2)); 1944 EXPECT_THAT( 1945 getDiagnosticString(), 1946 HasSubstr( 1947 "Capability Sampled1D is not allowed by OpenCL 1.2 Full Profile")); 1948 } 1949 1950 TEST_F(ValidateCapability, NonOpenCL12EmbeddedCapability) { 1951 const std::string spirv = R"( 1952 OpCapability Kernel 1953 OpCapability Addresses 1954 OpCapability Linkage 1955 OpCapability Int64 1956 OpMemoryModel Physical64 OpenCL 1957 %u32 = OpTypeInt 32 0 1958 )"; 1959 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2); 1960 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1961 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2)); 1962 EXPECT_THAT( 1963 getDiagnosticString(), 1964 HasSubstr( 1965 "Capability Int64 is not allowed by OpenCL 1.2 Embedded Profile")); 1966 } 1967 1968 TEST_F(ValidateCapability, OpenCL12EmbeddedEnabledByCapability) { 1969 const std::string spirv = R"( 1970 OpCapability Kernel 1971 OpCapability Addresses 1972 OpCapability Linkage 1973 OpCapability ImageBasic 1974 OpCapability Sampled1D 1975 OpMemoryModel Physical64 OpenCL 1976 %u32 = OpTypeInt 32 0 1977 )" + std::string(kVoidFVoid); 1978 1979 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2); 1980 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2)); 1981 } 1982 1983 TEST_F(ValidateCapability, OpenCL12EmbeddedNotEnabledByCapability) { 1984 const std::string spirv = R"( 1985 OpCapability Kernel 1986 OpCapability Addresses 1987 OpCapability Linkage 1988 OpCapability Sampled1D 1989 OpMemoryModel Physical64 OpenCL 1990 %u32 = OpTypeInt 32 0 1991 )" + std::string(kVoidFVoid); 1992 1993 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2); 1994 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 1995 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2)); 1996 EXPECT_THAT(getDiagnosticString(), 1997 HasSubstr("Capability Sampled1D is not allowed by OpenCL 1.2 " 1998 "Embedded Profile")); 1999 } 2000 2001 TEST_F(ValidateCapability, OpenCL20FullCapability) { 2002 const std::string spirv = R"( 2003 OpCapability Kernel 2004 OpCapability Addresses 2005 OpCapability Linkage 2006 OpCapability Pipes 2007 OpMemoryModel Physical64 OpenCL 2008 %u32 = OpTypeInt 32 0 2009 )"; 2010 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0); 2011 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_0)); 2012 } 2013 2014 TEST_F(ValidateCapability, NonOpenCL20FullCapability) { 2015 const std::string spirv = R"( 2016 OpCapability Kernel 2017 OpCapability Addresses 2018 OpCapability Linkage 2019 OpCapability Matrix 2020 OpMemoryModel Physical64 OpenCL 2021 %u32 = OpTypeInt 32 0 2022 )"; 2023 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0); 2024 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2025 ValidateInstructions(SPV_ENV_OPENCL_2_0)); 2026 EXPECT_THAT( 2027 getDiagnosticString(), 2028 HasSubstr( 2029 "Capability Matrix is not allowed by OpenCL 2.0/2.1 Full Profile")); 2030 } 2031 2032 TEST_F(ValidateCapability, OpenCL20FullEnabledByCapability) { 2033 const std::string spirv = R"( 2034 OpCapability Kernel 2035 OpCapability Addresses 2036 OpCapability Linkage 2037 OpCapability ImageBasic 2038 OpCapability Sampled1D 2039 OpMemoryModel Physical64 OpenCL 2040 %u32 = OpTypeInt 32 0 2041 )" + std::string(kVoidFVoid); 2042 2043 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0); 2044 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_0)); 2045 } 2046 2047 TEST_F(ValidateCapability, OpenCL20FullNotEnabledByCapability) { 2048 const std::string spirv = R"( 2049 OpCapability Kernel 2050 OpCapability Addresses 2051 OpCapability Linkage 2052 OpCapability Sampled1D 2053 OpMemoryModel Physical64 OpenCL 2054 %u32 = OpTypeInt 32 0 2055 )" + std::string(kVoidFVoid); 2056 2057 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0); 2058 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2059 ValidateInstructions(SPV_ENV_OPENCL_2_0)); 2060 EXPECT_THAT(getDiagnosticString(), 2061 HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.0/2.1 " 2062 "Full Profile")); 2063 } 2064 2065 TEST_F(ValidateCapability, NonOpenCL20EmbeddedCapability) { 2066 const std::string spirv = R"( 2067 OpCapability Kernel 2068 OpCapability Addresses 2069 OpCapability Linkage 2070 OpCapability Int64 2071 OpMemoryModel Physical64 OpenCL 2072 %u32 = OpTypeInt 32 0 2073 )"; 2074 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0); 2075 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2076 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0)); 2077 EXPECT_THAT(getDiagnosticString(), 2078 HasSubstr("Capability Int64 is not allowed by OpenCL 2.0/2.1 " 2079 "Embedded Profile")); 2080 } 2081 2082 TEST_F(ValidateCapability, OpenCL20EmbeddedEnabledByCapability) { 2083 const std::string spirv = R"( 2084 OpCapability Kernel 2085 OpCapability Addresses 2086 OpCapability Linkage 2087 OpCapability ImageBasic 2088 OpCapability Sampled1D 2089 OpMemoryModel Physical64 OpenCL 2090 %u32 = OpTypeInt 32 0 2091 )" + std::string(kVoidFVoid); 2092 2093 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0); 2094 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0)); 2095 } 2096 2097 TEST_F(ValidateCapability, OpenCL20EmbeddedNotEnabledByCapability) { 2098 const std::string spirv = R"( 2099 OpCapability Kernel 2100 OpCapability Addresses 2101 OpCapability Linkage 2102 OpCapability Sampled1D 2103 OpMemoryModel Physical64 OpenCL 2104 %u32 = OpTypeInt 32 0 2105 )" + std::string(kVoidFVoid); 2106 2107 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0); 2108 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2109 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0)); 2110 EXPECT_THAT(getDiagnosticString(), 2111 HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.0/2.1 " 2112 "Embedded Profile")); 2113 } 2114 2115 TEST_F(ValidateCapability, OpenCL22FullCapability) { 2116 const std::string spirv = R"( 2117 OpCapability Kernel 2118 OpCapability Addresses 2119 OpCapability Linkage 2120 OpCapability PipeStorage 2121 OpMemoryModel Physical64 OpenCL 2122 %u32 = OpTypeInt 32 0 2123 )"; 2124 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2); 2125 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_2)); 2126 } 2127 2128 TEST_F(ValidateCapability, NonOpenCL22FullCapability) { 2129 const std::string spirv = R"( 2130 OpCapability Kernel 2131 OpCapability Addresses 2132 OpCapability Linkage 2133 OpCapability Matrix 2134 OpMemoryModel Physical64 OpenCL 2135 %u32 = OpTypeInt 32 0 2136 )"; 2137 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2); 2138 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2139 ValidateInstructions(SPV_ENV_OPENCL_2_2)); 2140 EXPECT_THAT( 2141 getDiagnosticString(), 2142 HasSubstr("Capability Matrix is not allowed by OpenCL 2.2 Full Profile")); 2143 } 2144 2145 TEST_F(ValidateCapability, OpenCL22FullEnabledByCapability) { 2146 const std::string spirv = R"( 2147 OpCapability Kernel 2148 OpCapability Addresses 2149 OpCapability Linkage 2150 OpCapability ImageBasic 2151 OpCapability Sampled1D 2152 OpMemoryModel Physical64 OpenCL 2153 %u32 = OpTypeInt 32 0 2154 )" + std::string(kVoidFVoid); 2155 2156 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2); 2157 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_2)); 2158 } 2159 2160 TEST_F(ValidateCapability, OpenCL22FullNotEnabledByCapability) { 2161 const std::string spirv = R"( 2162 OpCapability Kernel 2163 OpCapability Addresses 2164 OpCapability Linkage 2165 OpCapability Sampled1D 2166 OpMemoryModel Physical64 OpenCL 2167 %u32 = OpTypeInt 32 0 2168 )" + std::string(kVoidFVoid); 2169 2170 CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2); 2171 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2172 ValidateInstructions(SPV_ENV_OPENCL_2_2)); 2173 EXPECT_THAT( 2174 getDiagnosticString(), 2175 HasSubstr( 2176 "Capability Sampled1D is not allowed by OpenCL 2.2 Full Profile")); 2177 } 2178 2179 TEST_F(ValidateCapability, NonOpenCL22EmbeddedCapability) { 2180 const std::string spirv = R"( 2181 OpCapability Kernel 2182 OpCapability Addresses 2183 OpCapability Linkage 2184 OpCapability Int64 2185 OpMemoryModel Physical64 OpenCL 2186 %u32 = OpTypeInt 32 0 2187 )"; 2188 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2); 2189 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2190 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2)); 2191 EXPECT_THAT( 2192 getDiagnosticString(), 2193 HasSubstr( 2194 "Capability Int64 is not allowed by OpenCL 2.2 Embedded Profile")); 2195 } 2196 2197 TEST_F(ValidateCapability, OpenCL22EmbeddedEnabledByCapability) { 2198 const std::string spirv = R"( 2199 OpCapability Kernel 2200 OpCapability Addresses 2201 OpCapability Linkage 2202 OpCapability ImageBasic 2203 OpCapability Sampled1D 2204 OpMemoryModel Physical64 OpenCL 2205 %u32 = OpTypeInt 32 0 2206 )" + std::string(kVoidFVoid); 2207 2208 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2); 2209 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2)); 2210 } 2211 2212 TEST_F(ValidateCapability, OpenCL22EmbeddedNotEnabledByCapability) { 2213 const std::string spirv = R"( 2214 OpCapability Kernel 2215 OpCapability Addresses 2216 OpCapability Linkage 2217 OpCapability Sampled1D 2218 OpMemoryModel Physical64 OpenCL 2219 %u32 = OpTypeInt 32 0 2220 )" + std::string(kVoidFVoid); 2221 2222 CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2); 2223 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2224 ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2)); 2225 EXPECT_THAT(getDiagnosticString(), 2226 HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.2 " 2227 "Embedded Profile")); 2228 } 2229 2230 // Three tests to check enablement of an enum (a decoration) which is not 2231 // in core, and is directly enabled by a capability, but not directly enabled 2232 // by an extension. See https://github.com/KhronosGroup/SPIRV-Tools/issues/1596 2233 2234 TEST_F(ValidateCapability, DecorationFromExtensionMissingEnabledByCapability) { 2235 // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in 2236 // turn is enabled by SPV_NV_viewport_array2. 2237 const std::string spirv = R"( 2238 OpCapability Shader 2239 OpMemoryModel Logical Simple 2240 OpDecorate %void ViewportRelativeNV 2241 )" + std::string(kVoidFVoid); 2242 2243 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2244 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2245 ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)); 2246 EXPECT_THAT(getDiagnosticString(), 2247 HasSubstr("Operand 2 of Decorate requires one of these " 2248 "capabilities: ShaderViewportMaskNV")); 2249 } 2250 2251 TEST_F(ValidateCapability, CapabilityEnabledByMissingExtension) { 2252 // Capability ShaderViewportMaskNV is enabled by SPV_NV_viewport_array2. 2253 const std::string spirv = R"( 2254 OpCapability Shader 2255 OpCapability ShaderViewportMaskNV 2256 OpMemoryModel Logical Simple 2257 )" + std::string(kVoidFVoid); 2258 2259 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2260 EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION, 2261 ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)); 2262 EXPECT_THAT(getDiagnosticString(), 2263 HasSubstr("operand 5255 requires one of these extensions: " 2264 "SPV_NV_viewport_array2")); 2265 } 2266 2267 TEST_F(ValidateCapability, 2268 DecorationEnabledByCapabilityEnabledByPresentExtension) { 2269 // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in 2270 // turn is enabled by SPV_NV_viewport_array2. 2271 const std::string spirv = R"( 2272 OpCapability Shader 2273 OpCapability Linkage 2274 OpCapability ShaderViewportMaskNV 2275 OpExtension "SPV_NV_viewport_array2" 2276 OpMemoryModel Logical Simple 2277 OpDecorate %void ViewportRelativeNV 2278 %void = OpTypeVoid 2279 )"; 2280 2281 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2282 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)) 2283 << getDiagnosticString(); 2284 } 2285 2286 // Three tests to check enablement of an instruction which is not in core, and 2287 // is directly enabled by a capability, but not directly enabled by an 2288 // extension. See https://github.com/KhronosGroup/SPIRV-Tools/issues/1624 2289 // Instruction OpSubgroupShuffleINTEL is enabled by SubgroupShuffleINTEL, which 2290 // in turn is enabled by SPV_INTEL_subgroups. 2291 2292 TEST_F(ValidateCapability, InstructionFromExtensionMissingEnabledByCapability) { 2293 // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in 2294 // turn is enabled by SPV_NV_viewport_array2. 2295 const std::string spirv = R"( 2296 OpCapability Kernel 2297 OpCapability Addresses 2298 ; OpCapability SubgroupShuffleINTEL 2299 OpExtension "SPV_INTEL_subgroups" 2300 OpMemoryModel Physical32 OpenCL 2301 OpEntryPoint Kernel %main "main" 2302 %void = OpTypeVoid 2303 %uint = OpTypeInt 32 0 2304 %voidfn = OpTypeFunction %void 2305 %zero = OpConstant %uint 0 2306 %main = OpFunction %void None %voidfn 2307 %entry = OpLabel 2308 %foo = OpSubgroupShuffleINTEL %uint %zero %zero 2309 OpReturn 2310 OpFunctionEnd 2311 )"; 2312 2313 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2314 EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, 2315 ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)); 2316 EXPECT_THAT(getDiagnosticString(), 2317 HasSubstr("Opcode SubgroupShuffleINTEL requires one of these " 2318 "capabilities: SubgroupShuffleINTEL")); 2319 } 2320 2321 TEST_F(ValidateCapability, 2322 InstructionEnablingCapabilityEnabledByMissingExtension) { 2323 const std::string spirv = R"( 2324 OpCapability Kernel 2325 OpCapability Addresses 2326 OpCapability SubgroupShuffleINTEL 2327 ; OpExtension "SPV_INTEL_subgroups" 2328 OpMemoryModel Physical32 OpenCL 2329 OpEntryPoint Kernel %main "main" 2330 %void = OpTypeVoid 2331 %uint = OpTypeInt 32 0 2332 %voidfn = OpTypeFunction %void 2333 %zero = OpConstant %uint 0 2334 %main = OpFunction %void None %voidfn 2335 %entry = OpLabel 2336 %foo = OpSubgroupShuffleINTEL %uint %zero %zero 2337 OpReturn 2338 OpFunctionEnd 2339 )"; 2340 2341 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2342 EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION, 2343 ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)); 2344 EXPECT_THAT(getDiagnosticString(), 2345 HasSubstr("operand 5568 requires one of these extensions: " 2346 "SPV_INTEL_subgroups")); 2347 } 2348 2349 TEST_F(ValidateCapability, 2350 InstructionEnabledByCapabilityEnabledByPresentExtension) { 2351 const std::string spirv = R"( 2352 OpCapability Kernel 2353 OpCapability Addresses 2354 OpCapability SubgroupShuffleINTEL 2355 OpExtension "SPV_INTEL_subgroups" 2356 OpMemoryModel Physical32 OpenCL 2357 OpEntryPoint Kernel %main "main" 2358 %void = OpTypeVoid 2359 %uint = OpTypeInt 32 0 2360 %voidfn = OpTypeFunction %void 2361 %zero = OpConstant %uint 0 2362 %main = OpFunction %void None %voidfn 2363 %entry = OpLabel 2364 %foo = OpSubgroupShuffleINTEL %uint %zero %zero 2365 OpReturn 2366 OpFunctionEnd 2367 )"; 2368 2369 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0); 2370 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0)) 2371 << getDiagnosticString(); 2372 } 2373 2374 TEST_F(ValidateCapability, VulkanMemoryModelWithVulkanKHR) { 2375 const std::string spirv = R"( 2376 OpCapability Shader 2377 OpCapability VulkanMemoryModelKHR 2378 OpCapability Linkage 2379 OpExtension "SPV_KHR_vulkan_memory_model" 2380 OpMemoryModel Logical VulkanKHR 2381 )"; 2382 2383 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3); 2384 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)) 2385 << getDiagnosticString(); 2386 } 2387 2388 TEST_F(ValidateCapability, VulkanMemoryModelWithGLSL450) { 2389 const std::string spirv = R"( 2390 OpCapability Shader 2391 OpCapability VulkanMemoryModelKHR 2392 OpCapability Linkage 2393 OpExtension "SPV_KHR_vulkan_memory_model" 2394 OpMemoryModel Logical GLSL450 2395 )"; 2396 2397 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3); 2398 EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2399 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2400 EXPECT_THAT(getDiagnosticString(), 2401 HasSubstr("VulkanMemoryModelKHR capability must only be " 2402 "specified if the VulkanKHR memory model is used")); 2403 } 2404 2405 } // namespace 2406 } // namespace val 2407 } // namespace spvtools 2408