Validate ShaderCallKHR memory scope (#3332)

This commit is contained in:
Jeff Bolz 2020-05-05 12:08:28 -05:00 committed by GitHub
parent 2e1d208ed9
commit d2b4862194
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 2 deletions

View File

@ -230,11 +230,33 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
if ((_.context()->target_env == SPV_ENV_VULKAN_1_1 ||
_.context()->target_env == SPV_ENV_VULKAN_1_2) &&
value != SpvScopeDevice && value != SpvScopeWorkgroup &&
value != SpvScopeSubgroup && value != SpvScopeInvocation) {
value != SpvScopeSubgroup && value != SpvScopeInvocation &&
value != SpvScopeShaderCallKHR) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< ": in Vulkan 1.1 and 1.2 environment Memory Scope is limited "
<< "to Device, Workgroup and Invocation";
<< "to Device, Workgroup, Invocation, and ShaderCall";
}
if (value == SpvScopeShaderCallKHR) {
_.function(inst->function()->id())
->RegisterExecutionModelLimitation(
[](SpvExecutionModel model, std::string* message) {
if (model != SpvExecutionModelRayGenerationKHR &&
model != SpvExecutionModelIntersectionKHR &&
model != SpvExecutionModelAnyHitKHR &&
model != SpvExecutionModelClosestHitKHR &&
model != SpvExecutionModelMissKHR &&
model != SpvExecutionModelCallableKHR) {
if (message) {
*message =
"ShaderCallKHR Memory Scope requires a ray tracing "
"execution model";
}
return false;
}
return true;
});
}
}

View File

@ -70,6 +70,7 @@ OpCapability Shader
%subgroup = OpConstant %u32 3
%invocation = OpConstant %u32 4
%queuefamily = OpConstant %u32 5
%shadercall = OpConstant %u32 6
%none = OpConstant %u32 0
%acquire = OpConstant %u32 2
@ -1586,6 +1587,79 @@ OpFunctionEnd
"CooperativeMatrixNV capability is present"));
}
TEST_F(ValidateBarriers, OpMemoryBarrierShaderCallRayGenSuccess) {
const std::string body =
"OpMemoryBarrier %shadercall %release_uniform_workgroup";
CompileSuccessfully(GenerateShaderCodeImpl(body,
// capabilities_and_extensions
R"(
OpCapability VulkanMemoryModelKHR
OpCapability RayTracingProvisionalKHR
OpExtension "SPV_KHR_vulkan_memory_model"
OpExtension "SPV_KHR_ray_tracing"
)",
// definitions
"",
// execution_model
"RayGenerationKHR",
// memory_model
"OpMemoryModel Logical VulkanKHR"),
SPV_ENV_VULKAN_1_1);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
}
TEST_F(ValidateBarriers, OpMemoryBarrierShaderCallComputeFailure) {
const std::string body =
"OpMemoryBarrier %shadercall %release_uniform_workgroup";
CompileSuccessfully(GenerateShaderCodeImpl(body,
// capabilities_and_extensions
R"(
OpCapability VulkanMemoryModelKHR
OpExtension "SPV_KHR_vulkan_memory_model"
)",
// definitions
"",
// execution_model
"GLCompute",
// memory_model
"OpMemoryModel Logical VulkanKHR"),
SPV_ENV_VULKAN_1_1);
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"ShaderCallKHR Memory Scope requires a ray tracing execution model"));
}
TEST_F(ValidateBarriers, OpControlBarrierShaderCallRayGenFailure) {
const std::string body = "OpControlBarrier %shadercall %shadercall %none";
CompileSuccessfully(GenerateShaderCodeImpl(body,
// capabilities_and_extensions
R"(
OpCapability VulkanMemoryModelKHR
OpCapability RayTracingProvisionalKHR
OpExtension "SPV_KHR_vulkan_memory_model"
OpExtension "SPV_KHR_ray_tracing"
)",
// definitions
"",
// execution_model
"RayGenerationKHR",
// memory_model
"OpMemoryModel Logical VulkanKHR"),
SPV_ENV_VULKAN_1_1);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("in Vulkan environment Execution Scope is limited to "
"Workgroup and Subgroup"));
}
} // namespace
} // namespace val
} // namespace spvtools