From 48d923907b4cd658dd23bffd48e3773dcaf6722f Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Tue, 27 Nov 2018 09:39:37 -0500 Subject: [PATCH] Restrict capabilities to WebGPU spec (#2113) Restrict capabilities to WebGPU spec This covers whitelisting Matrix, Shader, Sampled1D, Image1D, DerivativeControl, and ImageQuery. These are the allowed capabilities that don't require an extension. Whitelisting VulkanMemoryModelKHR will be handled by whitelisting its extension in a seperate patch. Fixes #2101 --- source/val/validate_capability.cpp | 21 ++++++++++++++ test/val/val_capability_test.cpp | 41 ++++++++++++++++++++++++++++ test/val/val_decoration_test.cpp | 1 - test/val/val_webgpu_test.cpp | 44 ++++++++++++++++-------------- 4 files changed, 86 insertions(+), 21 deletions(-) diff --git a/source/val/validate_capability.cpp b/source/val/validate_capability.cpp index 3c5f98bc1..b464d5ddd 100644 --- a/source/val/validate_capability.cpp +++ b/source/val/validate_capability.cpp @@ -220,6 +220,19 @@ bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, return false; } +bool IsSupportGuaranteedWebGPU(uint32_t capability) { + switch (capability) { + case SpvCapabilityMatrix: + case SpvCapabilityShader: + case SpvCapabilitySampled1D: + case SpvCapabilityImage1D: + case SpvCapabilityDerivativeControl: + case SpvCapabilityImageQuery: + return true; + } + return false; +} + } // namespace // Validates that capability declarations use operands allowed in the current @@ -303,6 +316,14 @@ spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { << " Profile specification" << " (or requires extension or capability)"; } + } else if (env == SPV_ENV_WEBGPU_0) { + if (!IsSupportGuaranteedWebGPU(capability) && + !IsEnabledByExtension(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by WebGPU specification" + << " (or requires extension)"; + } } return SPV_SUCCESS; diff --git a/test/val/val_capability_test.cpp b/test/val/val_capability_test.cpp index 923d417f9..46a80305d 100644 --- a/test/val/val_capability_test.cpp +++ b/test/val/val_capability_test.cpp @@ -112,6 +112,8 @@ using ValidateCapabilityVulkan10 = spvtest::ValidateBase; using ValidateCapabilityOpenGL40 = spvtest::ValidateBase; // Always assembles using Vulkan 1.1. using ValidateCapabilityVulkan11 = spvtest::ValidateBase; +// Always assembles using WebGPU. +using ValidateCapabilityWebGPU = spvtest::ValidateBase; TEST_F(ValidateCapability, Default) { const char str[] = R"( @@ -382,6 +384,18 @@ const std::vector& AllVulkan11Capabilities() { return *r; } +const std::vector& AllWebGPUCapabilities() { + static const auto r = new std::vector{ + "", + "Shader", + "Matrix", + "Sampled1D", + "Image1D", + "ImageQuery", + "DerivativeControl"}; + return *r; +} + const std::vector& MatrixDependencies() { static const auto r = new std::vector{ "Matrix", @@ -572,6 +586,12 @@ const char kGLSL450MemoryModel[] = \ " OpCapability Shader" " OpMemoryModel Logical GLSL450 "; +const char kVulkanMemoryModel[] = \ + " OpCapability Shader" + " OpCapability VulkanMemoryModelKHR" + " OpExtension \"SPV_KHR_vulkan_memory_model\"" + " OpMemoryModel Logical VulkanKHR "; + const char kVoidFVoid[] = \ " %void = OpTypeVoid" " %void_f = OpTypeFunction %void" @@ -1529,6 +1549,16 @@ std::make_pair(std::string(kGLSL450MemoryModel) + AllSpirV10Capabilities()) )),); +INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityWebGPU, + Combine( + // All capabilities to try. + ValuesIn(AllCapabilities()), + Values( +std::make_pair(std::string(kVulkanMemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + std::string(kVoidFVoid), + AllWebGPUCapabilities()) +)),); + INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityVulkan11, Combine( // All capabilities to try. @@ -1720,6 +1750,17 @@ TEST_P(ValidateCapabilityOpenGL40, Capability) { } } +TEST_P(ValidateCapabilityWebGPU, Capability) { + const std::string capability = Capability(GetParam()); + if (Exists(capability, SPV_ENV_WEBGPU_0)) { + const std::string test_code = MakeAssembly(GetParam()); + CompileSuccessfully(test_code, SPV_ENV_WEBGPU_0); + ASSERT_EQ(ExpectedResult(GetParam()), + ValidateInstructions(SPV_ENV_WEBGPU_0)) + << test_code; + } +} + TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) { // From https://github.com/KhronosGroup/SPIRV-Tools/issues/248 // The validator was interpreting the memory semantics ID number diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp index 554c4b376..bbf7e94ab 100644 --- a/test/val/val_decoration_test.cpp +++ b/test/val/val_decoration_test.cpp @@ -151,7 +151,6 @@ TEST_F(ValidateDecorations, ValidateGroupDecorateRegistration) { TEST_F(ValidateDecorations, WebGPUOpDecorationGroupBad) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR diff --git a/test/val/val_webgpu_test.cpp b/test/val/val_webgpu_test.cpp index 31da795c9..cc3f90593 100644 --- a/test/val/val_webgpu_test.cpp +++ b/test/val/val_webgpu_test.cpp @@ -29,13 +29,19 @@ using ValidateWebGPU = spvtest::ValidateBase; TEST_F(ValidateWebGPU, OpUndefIsDisallowed) { std::string spirv = R"( - OpCapability Shader - OpCapability Linkage - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - %float = OpTypeFloat 32 - %1 = OpUndef %float + OpCapability Shader + OpCapability VulkanMemoryModelKHR + OpExtension "SPV_KHR_vulkan_memory_model" + OpMemoryModel Logical VulkanKHR + OpEntryPoint Vertex %func "shader" +%float = OpTypeFloat 32 +%1 = OpUndef %float +%void = OpTypeVoid +%void_f = OpTypeFunction %void +%func = OpFunction %void None %void_f +%label = OpLabel + OpReturn + OpFunctionEnd )"; CompileSuccessfully(spirv); @@ -51,7 +57,6 @@ TEST_F(ValidateWebGPU, OpUndefIsDisallowed) { TEST_F(ValidateWebGPU, OpNameIsDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -70,7 +75,6 @@ TEST_F(ValidateWebGPU, OpNameIsDisallowed) { TEST_F(ValidateWebGPU, OpMemberNameIsDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -91,7 +95,6 @@ TEST_F(ValidateWebGPU, OpMemberNameIsDisallowed) { TEST_F(ValidateWebGPU, OpSourceIsDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -112,7 +115,6 @@ TEST_F(ValidateWebGPU, OpSourceIsDisallowed) { TEST_F(ValidateWebGPU, OpSourceExtensionIsDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -131,7 +133,6 @@ TEST_F(ValidateWebGPU, OpSourceExtensionIsDisallowed) { TEST_F(ValidateWebGPU, OpStringIsDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -152,7 +153,6 @@ TEST_F(ValidateWebGPU, OpStringIsDisallowed) { TEST_F(ValidateWebGPU, OpNoLineDisallowed) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical VulkanKHR @@ -169,11 +169,17 @@ TEST_F(ValidateWebGPU, OpNoLineDisallowed) { TEST_F(ValidateWebGPU, LogicalAddressingVulkanKHRMemoryGood) { std::string spirv = R"( - OpCapability Shader - OpCapability Linkage - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR + OpCapability Shader + OpCapability VulkanMemoryModelKHR + OpExtension "SPV_KHR_vulkan_memory_model" + OpMemoryModel Logical VulkanKHR + OpEntryPoint Vertex %func "shader" +%void = OpTypeVoid +%void_f = OpTypeFunction %void +%func = OpFunction %void None %void_f +%label = OpLabel + OpReturn + OpFunctionEnd )"; CompileSuccessfully(spirv); @@ -184,7 +190,6 @@ TEST_F(ValidateWebGPU, LogicalAddressingVulkanKHRMemoryGood) { TEST_F(ValidateWebGPU, NonLogicalAddressingModelBad) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Physical32 VulkanKHR @@ -202,7 +207,6 @@ TEST_F(ValidateWebGPU, NonLogicalAddressingModelBad) { TEST_F(ValidateWebGPU, NonVulkanKHRMemoryModelBad) { std::string spirv = R"( OpCapability Shader - OpCapability Linkage OpMemoryModel Logical GLSL450 OpNoLine )";