Add a shader generation unit test
This commit is contained in:
parent
4df7d0b4e2
commit
8fb7bb78a5
|
|
@ -46,5 +46,6 @@ TOOL.Libraries = {
|
|||
"NazaraNetwork",
|
||||
"NazaraPhysics2D",
|
||||
"NazaraPhysics3D",
|
||||
"NazaraShader",
|
||||
"NazaraUtility"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Shader/GlslWriter.hpp>
|
||||
#include <Nazara/Shader/ShaderAst.hpp>
|
||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||
#include <Nazara/Shader/SpirvPrinter.hpp>
|
||||
#include <Nazara/Shader/SpirvWriter.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
#include <cctype>
|
||||
|
||||
std::string_view Trim(std::string_view str)
|
||||
{
|
||||
while (!str.empty() && std::isspace(str.front()))
|
||||
str.remove_prefix(1);
|
||||
|
||||
while (!str.empty() && std::isspace(str.back()))
|
||||
str.remove_suffix(1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void ExpectingGLSL(const Nz::ShaderAst& shader, std::string_view expectedOutput)
|
||||
{
|
||||
Nz::GlslWriter writer;
|
||||
|
||||
std::string output = writer.Generate(shader);
|
||||
std::size_t funcOffset = output.find("void main()");
|
||||
std::string_view subset = Trim(output).substr(funcOffset);
|
||||
expectedOutput = Trim(expectedOutput);
|
||||
|
||||
REQUIRE(subset == expectedOutput);
|
||||
}
|
||||
|
||||
void ExpectingSpirV(const Nz::ShaderAst& shader, std::string_view expectedOutput)
|
||||
{
|
||||
Nz::SpirvWriter writer;
|
||||
auto spirv = writer.Generate(shader);
|
||||
|
||||
Nz::SpirvPrinter printer;
|
||||
|
||||
Nz::SpirvPrinter::Settings settings;
|
||||
settings.printHeader = false;
|
||||
settings.printParameters = false;
|
||||
|
||||
std::string output = printer.Print(spirv.data(), spirv.size(), settings);
|
||||
std::size_t funcOffset = output.find("OpFunction");
|
||||
std::string_view subset = Trim(output).substr(funcOffset);
|
||||
expectedOutput = Trim(expectedOutput);
|
||||
|
||||
REQUIRE(subset == expectedOutput);
|
||||
}
|
||||
|
||||
SCENARIO("Shader generation", "[Shader]")
|
||||
{
|
||||
SECTION("Nested member loading")
|
||||
{
|
||||
Nz::ShaderAst baseShader(Nz::ShaderStageType::Vertex);
|
||||
baseShader.AddStruct("innerStruct", {
|
||||
{
|
||||
"field",
|
||||
Nz::ShaderNodes::BasicType::Float3
|
||||
}
|
||||
});
|
||||
|
||||
baseShader.AddStruct("outerStruct", {
|
||||
{
|
||||
"s",
|
||||
"innerStruct"
|
||||
}
|
||||
});
|
||||
|
||||
baseShader.AddUniform("ubo", "outerStruct");
|
||||
baseShader.AddOutput("result", Nz::ShaderNodes::BasicType::Float1);
|
||||
|
||||
SECTION("Nested AccessMember")
|
||||
{
|
||||
Nz::ShaderAst shader = baseShader;
|
||||
|
||||
auto uniform = Nz::ShaderBuilder::Uniform("ubo", "outerStruct");
|
||||
auto output = Nz::ShaderBuilder::Output("result", Nz::ShaderNodes::BasicType::Float1);
|
||||
|
||||
auto access = Nz::ShaderBuilder::Swizzle(Nz::ShaderBuilder::AccessMember(Nz::ShaderBuilder::AccessMember(Nz::ShaderBuilder::Identifier(uniform), 0, "innerStruct"), 0, Nz::ShaderNodes::BasicType::Float3), Nz::ShaderNodes::SwizzleComponent::Third);
|
||||
auto assign = Nz::ShaderBuilder::Assign(Nz::ShaderBuilder::Identifier(output), access);
|
||||
|
||||
shader.AddFunction("main", Nz::ShaderBuilder::ExprStatement(assign));
|
||||
|
||||
SECTION("Generating GLSL")
|
||||
{
|
||||
ExpectingGLSL(shader, R"(
|
||||
void main()
|
||||
{
|
||||
result = ubo.s.field.z;
|
||||
}
|
||||
)");
|
||||
}
|
||||
SECTION("Generating Spir-V")
|
||||
{
|
||||
ExpectingSpirV(shader, R"(
|
||||
OpFunction
|
||||
OpLabel
|
||||
OpAccessChain
|
||||
OpAccessChain
|
||||
OpLoad
|
||||
OpCompositeExtract
|
||||
OpStore
|
||||
OpReturn
|
||||
OpFunctionEnd)");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("AccessMember with multiples fields")
|
||||
{
|
||||
Nz::ShaderAst shader = baseShader;
|
||||
|
||||
auto uniform = Nz::ShaderBuilder::Uniform("ubo", "outerStruct");
|
||||
auto output = Nz::ShaderBuilder::Output("result", Nz::ShaderNodes::BasicType::Float1);
|
||||
|
||||
auto access = Nz::ShaderBuilder::Swizzle(Nz::ShaderBuilder::AccessMember(Nz::ShaderBuilder::Identifier(uniform), std::vector<std::size_t>{ 0, 0 }, Nz::ShaderNodes::BasicType::Float3), Nz::ShaderNodes::SwizzleComponent::Third);
|
||||
auto assign = Nz::ShaderBuilder::Assign(Nz::ShaderBuilder::Identifier(output), access);
|
||||
|
||||
shader.AddFunction("main", Nz::ShaderBuilder::ExprStatement(assign));
|
||||
|
||||
SECTION("Generating GLSL")
|
||||
{
|
||||
ExpectingGLSL(shader, R"(
|
||||
void main()
|
||||
{
|
||||
result = ubo.s.field.z;
|
||||
}
|
||||
)");
|
||||
}
|
||||
SECTION("Generating Spir-V")
|
||||
{
|
||||
ExpectingSpirV(shader, R"(
|
||||
OpFunction
|
||||
OpLabel
|
||||
OpAccessChain
|
||||
OpLoad
|
||||
OpCompositeExtract
|
||||
OpStore
|
||||
OpReturn
|
||||
OpFunctionEnd)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue