diff --git a/tests/Engine/Shader/Serializations.cpp b/tests/Engine/Shader/Serializations.cpp new file mode 100644 index 000000000..7f01064fb --- /dev/null +++ b/tests/Engine/Shader/Serializations.cpp @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void ParseSerializeUnserialize(std::string_view sourceCode, bool sanitize) +{ + Nz::ShaderAst::StatementPtr shader; + REQUIRE_NOTHROW(shader = Nz::ShaderLang::Parse(sourceCode)); + + if (sanitize) + REQUIRE_NOTHROW(shader = Nz::ShaderAst::Sanitize(*shader)); + + Nz::ByteArray serializedShader; + REQUIRE_NOTHROW(serializedShader = Nz::ShaderAst::SerializeShader(shader)); + + Nz::ByteStream byteStream(&serializedShader); + Nz::ShaderAst::StatementPtr unserializedShader; + REQUIRE_NOTHROW(unserializedShader = Nz::ShaderAst::UnserializeShader(byteStream)); + + CHECK(Nz::ShaderAst::Compare(*shader, *unserializedShader)); +} + +void ParseSerializeUnserialize(std::string_view sourceCode) +{ + ParseSerializeUnserialize(sourceCode, false); + ParseSerializeUnserialize(sourceCode, true); +} + +TEST_CASE("serialization", "[Shader]") +{ + WHEN("serializing and unserializing a simple shader") + { + ParseSerializeUnserialize(R"( +struct Data +{ + value: f32 +} + +struct Output +{ + [location(0)] value: f32 +} + +external +{ + [set(0), binding(0)] data: uniform[Data] +} + +[entry(frag)] +fn main() -> Output +{ + let output: Output; + output.value = data.value; + + return output; +} +)"); + } + + WHEN("serializing and unserializing branches") + { + ParseSerializeUnserialize(R"( +struct inputStruct +{ + value: f32 +} + +external +{ + [set(0), binding(0)] data: uniform[inputStruct] +} + +[entry(frag)] +fn main() +{ + let value: f32; + if (data.value > 3.0) + value = 3.0; + else if (data.value > 2.0) + value = 2.0; + else if (data.value > 1.0) + value = 1.0; + else + value = 0.0; +} +)"); + } + + WHEN("serializing and unserializing consts") + { + ParseSerializeUnserialize(R"( +option UseInt: bool = false; + +[cond(UseInt)] +struct inputStruct +{ + value: i32 +} + +[cond(!UseInt)] +struct inputStruct +{ + value: f32 +} + +external +{ + [set(0), binding(0)] data: uniform[inputStruct] +} + +[entry(frag)] +fn main() +{ + let value: f32; + + const if (UseInt) + { + value = f32(data.value); + } + else + { + value = data.value; + } +} +)"); + } + + WHEN("serializing and unserializing loops") + { + ParseSerializeUnserialize(R"( +struct inputStruct +{ + value: array[f32, 10] +} + +external +{ + [set(0), binding(0)] data: uniform[inputStruct] +} + +[entry(frag)] +fn main() +{ + let value = 0.0; + let i = 0; + while (i < 10) + { + value += 0.1; + i += 1; + } + + let x = 0; + for v in 0 -> 10 + { + x += v; + } + + let x = 0.0; + for v in data.value + { + x += v; + } +} +)"); + } + + WHEN("serializing and unserializing swizzles") + { + ParseSerializeUnserialize(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); +} +)"); + } +}