Shader: Add support for for-each statements and improve arrays
This commit is contained in:
@@ -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;
|
||||
}
|
||||
)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
)");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user