Ensure that required storage classes have initializer for WebGPU (#2285)

Fixes #2279
This commit is contained in:
Ryan Harrison 2019-01-15 10:24:58 -05:00 committed by GitHub
parent 9d8534e329
commit cb27ffdcd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 0 deletions

View File

@ -529,6 +529,20 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
}
}
// WebGPU: All variables with storage class Output, Private, or Function MUST
// have an initializer.
if (spvIsWebGPUEnv(_.context()->target_env) && inst->operands().size() <= 3 &&
(storage_class == SpvStorageClassOutput ||
storage_class == SpvStorageClassPrivate ||
storage_class == SpvStorageClassFunction)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpVariable, <id> '" << _.getIdName(inst->id())
<< "', must have an initializer.\n"
<< "From WebGPU execution environment spec:\n"
<< "All variables in the following storage classes must have an "
<< "initializer: Output, Private, or Function";
}
if (storage_class == SpvStorageClassPhysicalStorageBufferEXT) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "PhysicalStorageBufferEXT must not be used with OpVariable.";

View File

@ -457,6 +457,93 @@ OpFunctionEnd
" %5 = OpVariable %_ptr_Uniform_float Uniform %float_1\n"));
}
TEST_F(ValidateMemory, WebGPUOutputStorageClassWithoutInitializerBad) {
std::string spirv = R"(
OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
%float = OpTypeFloat 32
%float_ptr = OpTypePointer Output %float
%1 = OpVariable %float_ptr Output
%void = OpTypeVoid
%functy = OpTypeFunction %void
%func = OpFunction %void None %functy
%2 = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("OpVariable, <id> '4[%4]', must have an initializer.\n"
"From WebGPU execution environment spec:\n"
"All variables in the following storage classes must have an "
"initializer: Output, Private, or Function\n"
" %4 = OpVariable %_ptr_Output_float Output\n"));
}
TEST_F(ValidateMemory, WebGPUFunctionStorageClassWithoutInitializerBad) {
std::string spirv = R"(
OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
%float = OpTypeFloat 32
%float_ptr = OpTypePointer Function %float
%void = OpTypeVoid
%functy = OpTypeFunction %void
%func = OpFunction %void None %functy
%1 = OpLabel
%2 = OpVariable %float_ptr Function
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("OpVariable, <id> '7[%7]', must have an initializer.\n"
"From WebGPU execution environment spec:\n"
"All variables in the following storage classes must have an "
"initializer: Output, Private, or Function\n"
" %7 = OpVariable %_ptr_Function_float Function\n"));
}
TEST_F(ValidateMemory, WebGPUPrivateStorageClassWithoutInitializerBad) {
std::string spirv = R"(
OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpEntryPoint Fragment %func "func"
OpExecutionMode %func OriginUpperLeft
%float = OpTypeFloat 32
%float_ptr = OpTypePointer Private %float
%1 = OpVariable %float_ptr Private
%void = OpTypeVoid
%functy = OpTypeFunction %void
%func = OpFunction %void None %functy
%2 = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("OpVariable, <id> '4[%4]', must have an initializer.\n"
"From WebGPU execution environment spec:\n"
"All variables in the following storage classes must have an "
"initializer: Output, Private, or Function\n"
" %4 = OpVariable %_ptr_Private_float Private\n"));
}
TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
std::string spirv = R"(
OpCapability Shader