Skip to content

Commit

Permalink
[opt] Add struct-packing pass and unit test.
Browse files Browse the repository at this point in the history
This pass allows to re-assign offset layout decorations
to tightly pack a struct according to its packing rules.
  • Loading branch information
LukasBanana committed Aug 29, 2024
1 parent b21dda0 commit 8381662
Show file tree
Hide file tree
Showing 9 changed files with 827 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/spirv-tools/optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,18 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass();
// the unknown capability interacts with one of the trimmed capabilities.
Optimizer::PassToken CreateTrimCapabilitiesPass();

// Creates a struct-packing pass.
// This pass re-assigns all offset layout decorators to tightly pack
// the specified struct according to its packing rules.
// This is especially useful when spirv-opt removes lots of unused fields
// in HLSL's "$Globals" struct after which this pass can reduce its memory
// footprint. Accepted packing rules are:
// std140, std140EnhancedLayout, std430,
// std430EnhancedLayout, hlslCbuffer, hlslCbufferPackOffset, scalar,
// scalarEnhancedLayout.
Optimizer::PassToken CreateStructPackingPass(const char* structToPack,
const char* packingRule);

// Creates a switch-descriptorset pass.
// This pass changes any DescriptorSet decorations with the value |ds_from| to
// use the new value |ds_to|.
Expand Down
1 change: 1 addition & 0 deletions source/opt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
strip_debug_info_pass.cpp
strip_nonsemantic_info_pass.cpp
struct_cfg_analysis.cpp
struct_packing_pass.cpp
switch_descriptorset_pass.cpp
trim_capabilities_pass.cpp
type_manager.cpp
Expand Down
27 changes: 27 additions & 0 deletions source/opt/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,25 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag,
pass_args.c_str());
return false;
}
} else if (pass_name == "struct-packing") {
if (pass_args.size() == 0) {
Error(consumer(), nullptr, {},
"--struct-packing requires a name:rule argument.");
return false;
}

auto separator_pos = pass_args.find(':');
if (separator_pos == std::string::npos || separator_pos == 0 ||
separator_pos + 1 == pass_args.size()) {
Errorf(consumer(), nullptr, {},
"Invalid argument for --struct-packing: %s", pass_args.c_str());
return false;
}

const std::string struct_name = pass_args.substr(0, separator_pos);
const std::string rule_name = pass_args.substr(separator_pos + 1);

RegisterPass(CreateStructPackingPass(struct_name.c_str(), rule_name.c_str()));
} else if (pass_name == "switch-descriptorset") {
if (pass_args.size() == 0) {
Error(consumer(), nullptr, {},
Expand Down Expand Up @@ -1152,6 +1171,14 @@ Optimizer::PassToken CreateTrimCapabilitiesPass() {
MakeUnique<opt::TrimCapabilitiesPass>());
}

Optimizer::PassToken CreateStructPackingPass(const char* structToPack,
const char* packingRule) {
return MakeUnique<Optimizer::PassToken::Impl>(
MakeUnique<opt::StructPackingPass>(
structToPack,
opt::StructPackingPass::ParsePackingRuleFromString(packingRule)));
}

Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) {
return MakeUnique<Optimizer::PassToken::Impl>(
MakeUnique<opt::SwitchDescriptorSetPass>(from, to));
Expand Down
1 change: 1 addition & 0 deletions source/opt/passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
#include "source/opt/strength_reduction_pass.h"
#include "source/opt/strip_debug_info_pass.h"
#include "source/opt/strip_nonsemantic_info_pass.h"
#include "source/opt/struct_packing_pass.h"
#include "source/opt/switch_descriptorset_pass.h"
#include "source/opt/trim_capabilities_pass.h"
#include "source/opt/unify_const_pass.h"
Expand Down
Loading

0 comments on commit 8381662

Please sign in to comment.