Skip to content

Commit 653c436

Browse files
committed
[opt] Add struct-packing pass and unit test.
This pass allows to re-assign offset layout decorations to tighly pack a struct according to its packing rules.
1 parent b21dda0 commit 653c436

File tree

9 files changed

+825
-0
lines changed

9 files changed

+825
-0
lines changed

include/spirv-tools/optimizer.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,18 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass();
956956
// the unknown capability interacts with one of the trimmed capabilities.
957957
Optimizer::PassToken CreateTrimCapabilitiesPass();
958958

959+
// Creates a struct-packing pass.
960+
// This pass re-assigns all offset layout decorators to tightly pack
961+
// the specified struct according to its packing rules.
962+
// This is especially useful when spirv-opt removes lots of unused fields
963+
// in HLSL's "$Globals" struct after which this pass can reduce its memory
964+
// footprint. Accepted packing rules are:
965+
// std140, std140EnhancedLayout, std430,
966+
// std430EnhancedLayout, hlslCbuffer, hlslCbufferPackOffset, scalar,
967+
// scalarEnhancedLayout.
968+
Optimizer::PassToken CreateStructPackingPass(const char* structToPack,
969+
const char* packingRule);
970+
959971
// Creates a switch-descriptorset pass.
960972
// This pass changes any DescriptorSet decorations with the value |ds_from| to
961973
// use the new value |ds_to|.

source/opt/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
240240
strip_debug_info_pass.cpp
241241
strip_nonsemantic_info_pass.cpp
242242
struct_cfg_analysis.cpp
243+
struct_packing_pass.cpp
243244
switch_descriptorset_pass.cpp
244245
trim_capabilities_pass.cpp
245246
type_manager.cpp

source/opt/optimizer.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,25 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag,
571571
pass_args.c_str());
572572
return false;
573573
}
574+
} else if (pass_name == "struct-packing") {
575+
if (pass_args.size() == 0) {
576+
Error(consumer(), nullptr, {},
577+
"--struct-packing requires a name:rule argument.");
578+
return false;
579+
}
580+
581+
auto separator_pos = pass_args.find(':');
582+
if (separator_pos == std::string::npos || separator_pos == 0 ||
583+
separator_pos + 1 == pass_args.size()) {
584+
Errorf(consumer(), nullptr, {},
585+
"Invalid argument for --struct-packing: %s", pass_args.c_str());
586+
return false;
587+
}
588+
589+
const std::string struct_name = pass_args.substr(0, separator_pos);
590+
const std::string rule_name = pass_args.substr(separator_pos + 1);
591+
592+
RegisterPass(CreateStructPackingPass(struct_name.c_str(), rule_name.c_str()));
574593
} else if (pass_name == "switch-descriptorset") {
575594
if (pass_args.size() == 0) {
576595
Error(consumer(), nullptr, {},
@@ -1152,6 +1171,14 @@ Optimizer::PassToken CreateTrimCapabilitiesPass() {
11521171
MakeUnique<opt::TrimCapabilitiesPass>());
11531172
}
11541173

1174+
Optimizer::PassToken CreateStructPackingPass(const char* structToPack,
1175+
const char* packingRule) {
1176+
return MakeUnique<Optimizer::PassToken::Impl>(
1177+
MakeUnique<opt::StructPackingPass>(
1178+
structToPack,
1179+
opt::StructPackingPass::ParsePackingRuleFromString(packingRule)));
1180+
}
1181+
11551182
Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) {
11561183
return MakeUnique<Optimizer::PassToken::Impl>(
11571184
MakeUnique<opt::SwitchDescriptorSetPass>(from, to));

source/opt/passes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#include "source/opt/strength_reduction_pass.h"
8484
#include "source/opt/strip_debug_info_pass.h"
8585
#include "source/opt/strip_nonsemantic_info_pass.h"
86+
#include "source/opt/struct_packing_pass.h"
8687
#include "source/opt/switch_descriptorset_pass.h"
8788
#include "source/opt/trim_capabilities_pass.h"
8889
#include "source/opt/unify_const_pass.h"

0 commit comments

Comments
 (0)