mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
Store location values sparsely (#3488)
Fixes http://crbug.com/1102149 * Switch from boolean vectors to unordered sets for location storage
This commit is contained in:
parent
d5766f2801
commit
717e7877ca
@ -208,8 +208,8 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) {
|
||||
// 4 * location + component.
|
||||
spv_result_t GetLocationsForVariable(
|
||||
ValidationState_t& _, const Instruction* entry_point,
|
||||
const Instruction* variable, std::vector<bool>* locations,
|
||||
std::vector<bool>* output_index1_locations) {
|
||||
const Instruction* variable, std::unordered_set<uint32_t>* locations,
|
||||
std::unordered_set<uint32_t>* output_index1_locations) {
|
||||
const bool is_fragment = entry_point->GetOperandAs<SpvExecutionModel>(0) ==
|
||||
SpvExecutionModelFragment;
|
||||
const bool is_output =
|
||||
@ -356,17 +356,13 @@ spv_result_t GetLocationsForVariable(
|
||||
auto locs = locations;
|
||||
if (has_index && index == 1) locs = output_index1_locations;
|
||||
|
||||
if (end > locs->size()) {
|
||||
locs->resize(end, false);
|
||||
}
|
||||
for (uint32_t i = start; i < end; ++i) {
|
||||
if (locs->at(i)) {
|
||||
if (!locs->insert(i).second) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
|
||||
<< "Entry-point has conflicting " << storage_class
|
||||
<< " location assignment at location " << i / 4
|
||||
<< ", component " << i % 4;
|
||||
}
|
||||
(*locs)[i] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -425,17 +421,13 @@ spv_result_t GetLocationsForVariable(
|
||||
start += component;
|
||||
end = location * 4 + component + num_components;
|
||||
}
|
||||
if (end > locations->size()) {
|
||||
locations->resize(end, false);
|
||||
}
|
||||
for (uint32_t l = start; l < end; ++l) {
|
||||
if (locations->at(l)) {
|
||||
if (!locations->insert(l).second) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
|
||||
<< "Entry-point has conflicting " << storage_class
|
||||
<< " location assignment at location " << l / 4
|
||||
<< ", component " << l % 4;
|
||||
}
|
||||
(*locations)[l] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -445,10 +437,10 @@ spv_result_t GetLocationsForVariable(
|
||||
|
||||
spv_result_t ValidateLocations(ValidationState_t& _,
|
||||
const Instruction* entry_point) {
|
||||
// Reserve space for 16 locations with 4 components each.
|
||||
std::vector<bool> input_locations(16 * 4, false);
|
||||
std::vector<bool> output_locations_index0(16 * 4, false);
|
||||
std::vector<bool> output_locations_index1(16 * 4, false);
|
||||
// Locations are stored as a combined location and component values.
|
||||
std::unordered_set<uint32_t> input_locations;
|
||||
std::unordered_set<uint32_t> output_locations_index0;
|
||||
std::unordered_set<uint32_t> output_locations_index1;
|
||||
for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
|
||||
auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
|
||||
auto interface_var = _.FindDef(interface_id);
|
||||
|
@ -1356,6 +1356,29 @@ OpFunctionEnd
|
||||
"assignment at location 1, component 1"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateInterfacesTest, VulkanLocationsLargeLocation) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "????????" %17
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpDecorate %17 Location 4227868160
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Input_v3float = OpTypePointer Input %v3float
|
||||
%17 = OpVariable %_ptr_Input_v3float Input
|
||||
%4 = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpUnreachable
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, 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