mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-21 19:20:07 +00:00
spirv-val: Separate Location check for tess patch (#5654)
This commit is contained in:
parent
dd4b663e13
commit
57a42e6c1d
@ -519,6 +519,8 @@ spv_result_t ValidateLocations(ValidationState_t& _,
|
||||
std::unordered_set<uint32_t> input_locations;
|
||||
std::unordered_set<uint32_t> output_locations_index0;
|
||||
std::unordered_set<uint32_t> output_locations_index1;
|
||||
std::unordered_set<uint32_t> patch_locations_index0;
|
||||
std::unordered_set<uint32_t> patch_locations_index1;
|
||||
std::unordered_set<uint32_t> seen;
|
||||
for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
|
||||
auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
|
||||
@ -534,6 +536,26 @@ spv_result_t ValidateLocations(ValidationState_t& _,
|
||||
continue;
|
||||
}
|
||||
|
||||
// The two Tessellation stages have a "Patch" variable that interface with
|
||||
// the Location mechanism, but are not suppose to be tied to the "normal"
|
||||
// input/output Location.
|
||||
// TODO - SPIR-V allows the Patch decoration to be applied to struct
|
||||
// members, but is not allowed in GLSL/HLSL
|
||||
bool has_patch = false;
|
||||
for (auto& dec : _.id_decorations(interface_var->id())) {
|
||||
if (dec.dec_type() == spv::Decoration::Patch) {
|
||||
has_patch = true;
|
||||
if (auto error = GetLocationsForVariable(_, entry_point, interface_var,
|
||||
&patch_locations_index0,
|
||||
&patch_locations_index1))
|
||||
return error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_patch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto locations = (storage_class == spv::StorageClass::Input)
|
||||
? &input_locations
|
||||
: &output_locations_index0;
|
||||
|
@ -623,6 +623,72 @@ OpFunctionEnd
|
||||
"at location 1"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateInterfacesTest, VulkanPatchAndNonPatchOverlap) {
|
||||
const std::string text = R"(
|
||||
OpCapability Tessellation
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint TessellationControl %main "main" %a %b
|
||||
OpExecutionMode %main OutputVertices 4
|
||||
OpDecorate %a Location 0
|
||||
OpDecorate %b Patch
|
||||
OpDecorate %b Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
|
||||
%a = OpVariable %_ptr_Output__arr_float_uint_4 Output
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%b = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, SPV_ENV_VULKAN_1_2);
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
|
||||
}
|
||||
|
||||
TEST_F(ValidateInterfacesTest, VulkanPatchOverlap) {
|
||||
const std::string text = R"(
|
||||
OpCapability Tessellation
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint TessellationControl %main "main" %a %b %c
|
||||
OpExecutionMode %main OutputVertices 4
|
||||
OpDecorate %a Location 0
|
||||
OpDecorate %b Patch
|
||||
OpDecorate %b Location 6
|
||||
OpDecorate %c Patch
|
||||
OpDecorate %c Location 6
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
|
||||
%a = OpVariable %_ptr_Output__arr_float_uint_4 Output
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%b = OpVariable %_ptr_Output_float Output
|
||||
%c = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, SPV_ENV_VULKAN_1_2);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Entry-point has conflicting output location "
|
||||
"assignment at location 6, component 0"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateInterfacesTest,
|
||||
VulkanLocationsSameLocationInputAndOutputNoConflict) {
|
||||
const std::string text = R"(
|
||||
|
Loading…
Reference in New Issue
Block a user