Shader: Remove struct and functions that aren't required
This commit is contained in:
@@ -225,6 +225,19 @@ namespace Nz::ShaderAst
|
|||||||
if (!clone->rootNode)
|
if (!clone->rootNode)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
// Remove unused statements of imported modules
|
||||||
|
for (std::size_t moduleId = 0; moduleId < clone->importedModules.size(); ++moduleId)
|
||||||
|
{
|
||||||
|
auto& moduleData = m_context->modules[moduleId];
|
||||||
|
auto& importedModule = clone->importedModules[moduleId];
|
||||||
|
|
||||||
|
if (moduleData.dependenciesVisitor)
|
||||||
|
{
|
||||||
|
moduleData.dependenciesVisitor->Resolve();
|
||||||
|
importedModule.module = EliminateUnusedPass(*importedModule.module, moduleData.dependenciesVisitor->GetUsage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,27 @@ TEST_CASE("Modules", "[Shader]")
|
|||||||
{
|
{
|
||||||
WHEN("using a simple module")
|
WHEN("using a simple module")
|
||||||
{
|
{
|
||||||
|
// UUID are required here to have a stable output
|
||||||
std::string_view importedSource = R"(
|
std::string_view importedSource = R"(
|
||||||
[nzsl_version("1.0")]
|
[nzsl_version("1.0")]
|
||||||
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
||||||
module;
|
module;
|
||||||
|
|
||||||
|
[layout(std140)]
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
[export]
|
||||||
|
[layout(std140)]
|
||||||
|
struct Block
|
||||||
|
{
|
||||||
|
data: Data
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Unused {}
|
||||||
|
|
||||||
[export]
|
[export]
|
||||||
struct InputData
|
struct InputData
|
||||||
{
|
{
|
||||||
@@ -36,11 +52,16 @@ module;
|
|||||||
|
|
||||||
import SimpleModule;
|
import SimpleModule;
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[binding(0)] block: uniform[Block]
|
||||||
|
}
|
||||||
|
|
||||||
[entry(frag)]
|
[entry(frag)]
|
||||||
fn main(input: InputData) -> OutputData
|
fn main(input: InputData) -> OutputData
|
||||||
{
|
{
|
||||||
let output: OutputData;
|
let output: OutputData;
|
||||||
output.value = input.value;
|
output.value = block.data.value * input.value;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@@ -56,6 +77,16 @@ fn main(input: InputData) -> OutputData
|
|||||||
REQUIRE_NOTHROW(shaderModule = Nz::ShaderAst::Sanitize(*shaderModule, sanitizeOpt));
|
REQUIRE_NOTHROW(shaderModule = Nz::ShaderAst::Sanitize(*shaderModule, sanitizeOpt));
|
||||||
|
|
||||||
ExpectGLSL(*shaderModule, R"(
|
ExpectGLSL(*shaderModule, R"(
|
||||||
|
struct Data__181c45e9
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Block__181c45e9
|
||||||
|
{
|
||||||
|
Data__181c45e9 data;
|
||||||
|
};
|
||||||
|
|
||||||
struct InputData__181c45e9
|
struct InputData__181c45e9
|
||||||
{
|
{
|
||||||
float value;
|
float value;
|
||||||
@@ -66,6 +97,12 @@ struct OutputData__181c45e9
|
|||||||
float value;
|
float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform _NzBinding_block
|
||||||
|
{
|
||||||
|
Data__181c45e9 data;
|
||||||
|
} block;
|
||||||
|
|
||||||
|
|
||||||
/**************** Inputs ****************/
|
/**************** Inputs ****************/
|
||||||
in float _NzIn_value;
|
in float _NzIn_value;
|
||||||
|
|
||||||
@@ -78,7 +115,7 @@ void main()
|
|||||||
input_.value = _NzIn_value;
|
input_.value = _NzIn_value;
|
||||||
|
|
||||||
OutputData__181c45e9 output_;
|
OutputData__181c45e9 output_;
|
||||||
output_.value = input_.value;
|
output_.value = block.data.value * input_.value;
|
||||||
|
|
||||||
_NzOut_value = output_.value;
|
_NzOut_value = output_.value;
|
||||||
return;
|
return;
|
||||||
@@ -93,6 +130,18 @@ module;
|
|||||||
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
||||||
module __181c45e9
|
module __181c45e9
|
||||||
{
|
{
|
||||||
|
[layout(std140)]
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
[layout(std140)]
|
||||||
|
struct Block
|
||||||
|
{
|
||||||
|
data: Data
|
||||||
|
}
|
||||||
|
|
||||||
struct InputData
|
struct InputData
|
||||||
{
|
{
|
||||||
value: f32
|
value: f32
|
||||||
@@ -104,15 +153,22 @@ module __181c45e9
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
alias Block = __181c45e9.Block;
|
||||||
|
|
||||||
alias InputData = __181c45e9.InputData;
|
alias InputData = __181c45e9.InputData;
|
||||||
|
|
||||||
alias OutputData = __181c45e9.OutputData;
|
alias OutputData = __181c45e9.OutputData;
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[set(0), binding(0)] block: uniform[__181c45e9.Block]
|
||||||
|
}
|
||||||
|
|
||||||
[entry(frag)]
|
[entry(frag)]
|
||||||
fn main(input: InputData) -> OutputData
|
fn main(input: InputData) -> OutputData
|
||||||
{
|
{
|
||||||
let output: OutputData;
|
let output: OutputData;
|
||||||
output.value = input.value;
|
output.value = block.data.value * input.value;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
@@ -125,6 +181,221 @@ OpVariable
|
|||||||
OpAccessChain
|
OpAccessChain
|
||||||
OpLoad
|
OpLoad
|
||||||
OpAccessChain
|
OpAccessChain
|
||||||
|
OpLoad
|
||||||
|
OpFMul
|
||||||
|
OpAccessChain
|
||||||
|
OpStore
|
||||||
|
OpLoad
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd)");
|
||||||
|
}
|
||||||
|
|
||||||
|
WHEN("Using nested modules")
|
||||||
|
{
|
||||||
|
// UUID are required here to have a stable output
|
||||||
|
std::string_view dataModule = R"(
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
||||||
|
module;
|
||||||
|
|
||||||
|
fn dummy() {}
|
||||||
|
|
||||||
|
[export]
|
||||||
|
[layout(std140)]
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::string_view blockModule = R"(
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("7a548506-89e6-4944-897f-4f695a8bca01")]
|
||||||
|
module;
|
||||||
|
|
||||||
|
import Modules/Data;
|
||||||
|
|
||||||
|
[export]
|
||||||
|
[layout(std140)]
|
||||||
|
struct Block
|
||||||
|
{
|
||||||
|
data: Data
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Unused {}
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::string_view inputOutputModule = R"(
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("e66c6e98-fc37-4390-a7e1-c81508ff8e49")]
|
||||||
|
module;
|
||||||
|
|
||||||
|
[export]
|
||||||
|
struct InputData
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
[export]
|
||||||
|
struct OutputData
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::string_view shaderSource = R"(
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
module;
|
||||||
|
|
||||||
|
import Modules/Block;
|
||||||
|
import Modules/InputOutput;
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[binding(0)] block: uniform[Block]
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag)]
|
||||||
|
fn main(input: InputData) -> OutputData
|
||||||
|
{
|
||||||
|
let output: OutputData;
|
||||||
|
output.value = block.data.value * input.value;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
Nz::ShaderAst::ModulePtr shaderModule = Nz::ShaderLang::Parse(shaderSource);
|
||||||
|
|
||||||
|
auto directoryModuleResolver = std::make_shared<Nz::DirectoryModuleResolver>();
|
||||||
|
directoryModuleResolver->RegisterModuleFile("Modules/Data", dataModule.data(), dataModule.size());
|
||||||
|
directoryModuleResolver->RegisterModuleFile("Modules/Block", blockModule.data(), blockModule.size());
|
||||||
|
directoryModuleResolver->RegisterModuleFile("Modules/InputOutput", inputOutputModule.data(), inputOutputModule.size());
|
||||||
|
|
||||||
|
Nz::ShaderAst::SanitizeVisitor::Options sanitizeOpt;
|
||||||
|
sanitizeOpt.moduleResolver = directoryModuleResolver;
|
||||||
|
|
||||||
|
REQUIRE_NOTHROW(shaderModule = Nz::ShaderAst::Sanitize(*shaderModule, sanitizeOpt));
|
||||||
|
|
||||||
|
ExpectGLSL(*shaderModule, R"(
|
||||||
|
struct Data__181c45e9
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Block__e528265d
|
||||||
|
{
|
||||||
|
Data__181c45e9 data;
|
||||||
|
};
|
||||||
|
struct InputData__26cce136
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OutputData__26cce136
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
layout(std140) uniform _NzBinding_block
|
||||||
|
{
|
||||||
|
Data__181c45e9 data;
|
||||||
|
} block;
|
||||||
|
|
||||||
|
|
||||||
|
/**************** Inputs ****************/
|
||||||
|
in float _NzIn_value;
|
||||||
|
|
||||||
|
/*************** Outputs ***************/
|
||||||
|
out float _NzOut_value;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
InputData__26cce136 input_;
|
||||||
|
input_.value = _NzIn_value;
|
||||||
|
|
||||||
|
OutputData__26cce136 output_;
|
||||||
|
output_.value = block.data.value * input_.value;
|
||||||
|
|
||||||
|
_NzOut_value = output_.value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
ExpectNZSL(*shaderModule, R"(
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
module;
|
||||||
|
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")]
|
||||||
|
module __181c45e9
|
||||||
|
{
|
||||||
|
[layout(std140)]
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("7a548506-89e6-4944-897f-4f695a8bca01")]
|
||||||
|
module __e528265d
|
||||||
|
{
|
||||||
|
alias Data = __181c45e9.Data;
|
||||||
|
|
||||||
|
[layout(std140)]
|
||||||
|
struct Block
|
||||||
|
{
|
||||||
|
data: Data
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
[nzsl_version("1.0")]
|
||||||
|
[uuid("e66c6e98-fc37-4390-a7e1-c81508ff8e49")]
|
||||||
|
module __26cce136
|
||||||
|
{
|
||||||
|
struct InputData
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OutputData
|
||||||
|
{
|
||||||
|
value: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
alias Block = __e528265d.Block;
|
||||||
|
|
||||||
|
alias InputData = __26cce136.InputData;
|
||||||
|
|
||||||
|
alias OutputData = __26cce136.OutputData;
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[set(0), binding(0)] block: uniform[__e528265d.Block]
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag)]
|
||||||
|
fn main(input: InputData) -> OutputData
|
||||||
|
{
|
||||||
|
let output: OutputData;
|
||||||
|
output.value = block.data.value * input.value;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
ExpectSPIRV(*shaderModule, R"(
|
||||||
|
OpFunction
|
||||||
|
OpLabel
|
||||||
|
OpVariable
|
||||||
|
OpVariable
|
||||||
|
OpAccessChain
|
||||||
|
OpLoad
|
||||||
|
OpAccessChain
|
||||||
|
OpLoad
|
||||||
|
OpFMul
|
||||||
|
OpAccessChain
|
||||||
OpStore
|
OpStore
|
||||||
OpLoad
|
OpLoad
|
||||||
OpReturn
|
OpReturn
|
||||||
|
|||||||
Reference in New Issue
Block a user