mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-29 22:41:03 +00:00
Validate VK_KHR_zero_initialize_workgroup_memory (#4124)
* Allow OpConstantNull for Workgroup variable initializer in Vulkan environment * tests
This commit is contained in:
parent
d71ac38b8e
commit
cc81f53d3d
@ -584,16 +584,26 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
||||
storage_class != SpvStorageClassPrivate &&
|
||||
storage_class != SpvStorageClassFunction) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< _.VkErrorID(4651) << "OpVariable, <id> '"
|
||||
<< _.getIdName(inst->id())
|
||||
<< "', has a disallowed initializer & storage class "
|
||||
<< "combination.\n"
|
||||
<< "From " << spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec:\n"
|
||||
<< "Variable declarations that include initializers must have "
|
||||
<< "one of the following storage classes: Output, Private, or "
|
||||
<< "Function";
|
||||
if (storage_class == SpvStorageClassWorkgroup) {
|
||||
auto init_id = inst->GetOperandAs<uint32_t>(3);
|
||||
auto init = _.FindDef(init_id);
|
||||
if (init->opcode() != SpvOpConstantNull) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Variable initializers in Workgroup storage class are "
|
||||
"limited to OpConstantNull";
|
||||
}
|
||||
} else {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< _.VkErrorID(4651) << "OpVariable, <id> '"
|
||||
<< _.getIdName(inst->id())
|
||||
<< "', has a disallowed initializer & storage class "
|
||||
<< "combination.\n"
|
||||
<< "From " << spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec:\n"
|
||||
<< "Variable declarations that include initializers must have "
|
||||
<< "one of the following storage classes: Output, Private, "
|
||||
<< "Function or Workgroup";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,8 @@ OpFunctionEnd
|
||||
HasSubstr("OpVariable, <id> '5[%5]', has a disallowed initializer & "
|
||||
"storage class combination.\nFrom Vulkan spec:\nVariable "
|
||||
"declarations that include initializers must have one of the "
|
||||
"following storage classes: Output, Private, or Function\n %5 "
|
||||
"following storage classes: Output, Private, Function or "
|
||||
"Workgroup\n %5 "
|
||||
"= OpVariable %_ptr_Input_float Input %float_1\n"));
|
||||
}
|
||||
|
||||
@ -4080,6 +4081,55 @@ OpFunctionEnd
|
||||
"Cannot use a pointer in the PhysicalStorageBuffer storage class"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassBad) {
|
||||
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 Workgroup %float
|
||||
%init_val = OpConstant %float 1.0
|
||||
%1 = OpVariable %float_ptr Workgroup %init_val
|
||||
%void = OpTypeVoid
|
||||
%functy = OpTypeFunction %void
|
||||
%func = OpFunction %void None %functy
|
||||
%2 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Variable initializers in Workgroup storage class are "
|
||||
"limited to OpConstantNull"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassGood) {
|
||||
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 Workgroup %float
|
||||
%init_val = OpConstantNull %float
|
||||
%1 = OpVariable %float_ptr Workgroup %init_val
|
||||
%void = OpTypeVoid
|
||||
%functy = OpTypeFunction %void
|
||||
%func = OpFunction %void None %functy
|
||||
%2 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user