NazaraEngine/tests/Engine/Shader/Swizzle.cpp

294 lines
4.9 KiB
C++

#include <Engine/Shader/ShaderUtils.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderLangParser.hpp>
#include <catch2/catch.hpp>
#include <cctype>
TEST_CASE("swizzle", "[Shader]")
{
SECTION("Simple swizzle")
{
WHEN("reading")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let vec = vec4<f32>(0.0, 1.0, 2.0, 3.0);
let value = vec.xyz;
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
vec4 vec = vec4(0.000000, 1.000000, 2.000000, 3.000000);
vec3 value = vec.xyz;
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let vec: vec4<f32> = vec4<f32>(0.000000, 1.000000, 2.000000, 3.000000);
let value: vec3<f32> = vec.xyz;
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpVariable
OpCompositeConstruct
OpStore
OpLoad
OpVectorShuffle
OpStore
OpReturn
OpFunctionEnd)");
}
WHEN("writing")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let vec = vec4<f32>(0.0, 0.0, 0.0, 0.0);
vec.yzw = vec3<f32>(1.0, 2.0, 3.0);
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
vec4 vec = vec4(0.000000, 0.000000, 0.000000, 0.000000);
vec.yzw = vec3(1.000000, 2.000000, 3.000000);
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let vec: vec4<f32> = vec4<f32>(0.000000, 0.000000, 0.000000, 0.000000);
vec.yzw = vec3<f32>(1.000000, 2.000000, 3.000000);
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpCompositeConstruct
OpStore
OpCompositeConstruct
OpLoad
OpVectorShuffle
OpStore
OpReturn
OpFunctionEnd)");
}
}
SECTION("Scalar swizzle")
{
GIVEN("a variable")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let value = 42.0;
let vec = value.xxx;
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
float value = 42.000000;
vec3 vec = vec3(value, value, value);
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let value: f32 = 42.000000;
let vec: vec3<f32> = value.xxx;
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpVariable
OpStore
OpLoad
OpCompositeConstruct
OpStore
OpReturn
OpFunctionEnd)");
}
GIVEN("a function value")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let vec = max(2.0, 1.0).xxx;
let vec2 = min(2.0, 1.0).xxx;
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
float cachedResult = max(2.000000, 1.000000);
vec3 vec = vec3(cachedResult, cachedResult, cachedResult);
float cachedResult_2 = min(2.000000, 1.000000);
vec3 vec2_ = vec3(cachedResult_2, cachedResult_2, cachedResult_2);
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let vec: vec3<f32> = (max(2.000000, 1.000000)).xxx;
let vec2: vec3<f32> = (min(2.000000, 1.000000)).xxx;
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpVariable
OpExtInst
OpCompositeConstruct
OpStore
OpExtInst
OpCompositeConstruct
OpStore
OpReturn
OpFunctionEnd)");
}
}
SECTION("Complex swizzle")
{
WHEN("reading")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let vec = vec4<f32>(0.0, 1.0, 2.0, 3.0);
let value = vec.xyz.yz.y.x.xxxx;
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
vec4 vec = vec4(0.000000, 1.000000, 2.000000, 3.000000);
vec4 value = vec4(vec.xyz.yz.y, vec.xyz.yz.y, vec.xyz.yz.y, vec.xyz.yz.y);
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let vec: vec4<f32> = vec4<f32>(0.000000, 1.000000, 2.000000, 3.000000);
let value: vec4<f32> = vec.xyz.yz.y.x.xxxx;
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpVariable
OpCompositeConstruct
OpStore
OpLoad
OpVectorShuffle
OpVectorShuffle
OpCompositeExtract
OpCompositeConstruct
OpStore
OpReturn
OpFunctionEnd)");
}
WHEN("writing")
{
std::string_view nzslSource = R"(
[entry(frag)]
fn main()
{
let vec = vec4<f32>(0.0, 1.0, 2.0, 3.0);
vec.wyxz.bra.ts.x = 0.0;
vec.zyxw.ar.xy.yx = vec2<f32>(1.0, 0.0);
}
)";
Nz::ShaderAst::StatementPtr shader = Nz::ShaderLang::Parse(nzslSource);
ExpectGLSL(*shader, R"(
void main()
{
vec4 vec = vec4(0.000000, 1.000000, 2.000000, 3.000000);
vec.wyxz.zxw.yx.x = 0.000000;
vec.zyxw.wx.xy.yx = vec2(1.000000, 0.000000);
}
)");
ExpectNZSL(*shader, R"(
[entry(frag)]
fn main()
{
let vec: vec4<f32> = vec4<f32>(0.000000, 1.000000, 2.000000, 3.000000);
vec.wyxz.zxw.yx.x = 0.000000;
vec.zyxw.wx.xy.yx = vec2<f32>(1.000000, 0.000000);
}
)");
ExpectSpirV(*shader, R"(
OpFunction
OpLabel
OpVariable
OpCompositeConstruct
OpStore
OpAccessChain
OpStore
OpCompositeConstruct
OpLoad
OpVectorShuffle
OpStore
OpReturn
OpFunctionEnd)");
}
}
}