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