Shader: Add support for for-each statements and improve arrays

This commit is contained in:
Jérôme Leclercq
2022-01-02 22:02:11 +01:00
parent aac6e38da2
commit 4fe44339c5
30 changed files with 712 additions and 93 deletions

View File

@@ -109,4 +109,55 @@ fn main()
)");
}
}
WHEN("using const for-each")
{
std::string_view sourceCode = R"(
const LightCount = 3;
[layout(std140)]
struct Light
{
color: vec4<f32>
}
[layout(std140)]
struct LightData
{
lights: [Light; LightCount]
}
external
{
[set(0), binding(0)] data: uniform<LightData>
}
[entry(frag)]
fn main()
{
let color = (0.0).xxxx;
const for light in data.lights
{
color += light.color;
}
}
)";
Nz::ShaderAst::StatementPtr shader;
REQUIRE_NOTHROW(shader = Nz::ShaderLang::Parse(sourceCode));
ExpectOutput(*shader, {}, R"(
[entry(frag)]
fn main()
{
let color: vec4<f32> = (0.000000).xxxx;
let light: Light = data.lights[0];
color += light.color;
let light: Light = data.lights[1];
color += light.color;
let light: Light = data.lights[2];
color += light.color;
}
)");
}
}

View File

@@ -8,7 +8,9 @@
TEST_CASE("loops", "[Shader]")
{
std::string_view nzslSource = R"(
WHEN("using a while")
{
std::string_view nzslSource = R"(
struct inputStruct
{
value: f32
@@ -32,9 +34,9 @@ fn main()
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
ExpectGLSL(*shader, R"(
void main()
{
float value = 0.000000;
@@ -48,7 +50,7 @@ void main()
}
)");
ExpectNZSL(*shader, R"(
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
@@ -63,7 +65,7 @@ fn main()
}
)");
ExpectSpirV(*shader, R"(
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
@@ -87,4 +89,93 @@ OpBranch
OpLabel
OpReturn
OpFunctionEnd)");
}
WHEN("using a for-each")
{
std::string_view nzslSource = R"(
struct inputStruct
{
value: [f32; 10]
}
external
{
[set(0), binding(0)] data: uniform<inputStruct>
}
[entry(frag)]
fn main()
{
let x = 0.0;
for v in data.value
{
x += v;
}
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
float x = 0.000000;
uint i = 0u;
while (i < (10u))
{
float v = data.value[i];
x += v;
i += 1u;
}
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let x: f32 = 0.000000;
for v in data.value
{
x += v;
}
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpVariable
OpVariable
OpStore
OpStore
OpBranch
OpLabel
OpLoad
OpULessThan
OpLoopMerge
OpBranchConditional
OpLabel
OpAccessChain
OpLoad
OpAccessChain
OpLoad
OpStore
OpLoad
OpLoad
OpFAdd
OpStore
OpLoad
OpIAdd
OpStore
OpBranch
OpLabel
OpReturn
OpFunctionEnd)");
}
}

View File

@@ -74,6 +74,55 @@ fn main()
}
}
)");
}
WHEN("reducing for-each to while")
{
std::string_view nzslSource = R"(
struct inputStruct
{
value: [f32; 10]
}
external
{
[set(0), binding(0)] data: uniform<inputStruct>
}
[entry(frag)]
fn main()
{
let x = 0.0;
for v in data.value
{
x += v;
}
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
Nz::ShaderAst::SanitizeVisitor::Options options;
options.reduceLoopsToWhile = true;
REQUIRE_NOTHROW(shader = Nz::ShaderAst::Sanitize(*shader, options));
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let x: f32 = 0.000000;
let i: u32 = 0;
while (i < (10))
{
let v: f32 = data.value[i];
x += v;
i += 1;
}
}
)");