Skip to content

Commit

Permalink
Add nzsla tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SirLynix committed Oct 14, 2024
1 parent 533ba25 commit 3bec332
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 89 deletions.
Binary file added bin/resources/modules/Archive/InstanceData.nzslb
Binary file not shown.
Binary file added bin/resources/modules/Archive/LightData.nzslb
Binary file not shown.
Binary file added bin/resources/modules/Archive/SkeletalData.nzslb
Binary file not shown.
Binary file added bin/resources/modules/Archive/SkinningData.nzslb
Binary file not shown.
Binary file added bin/resources/modules/Archive/ViewerData.nzslb
Binary file not shown.
4 changes: 2 additions & 2 deletions include/NZSL/Archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace nzsl

enum class ArchiveEntryFlag
{
CompressedLZ4HC,
CompressedLZ4HC = 0,

Max = CompressedLZ4HC
};
Expand All @@ -37,7 +37,7 @@ namespace nzsl

enum class ArchiveEntryKind
{
BinaryShaderModule
BinaryShaderModule = 0
};

class NZSL_API Archive
Expand Down
14 changes: 11 additions & 3 deletions src/NZSL/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ namespace nzsl
std::string moduleName;
std::uint32_t offset;
std::uint32_t size;
ArchiveEntryKind kind;
ArchiveEntryFlags flags;
};

Expand All @@ -140,12 +141,17 @@ namespace nzsl
{
auto& data = entries.emplace_back();
deserializer.Deserialize(data.moduleName);
deserializer.Deserialize(data.offset);
deserializer.Deserialize(data.size);

std::uint32_t kind;
deserializer.Deserialize(kind);
data.kind = static_cast<ArchiveEntryKind>(kind);

std::uint32_t flags;
deserializer.Deserialize(flags);
data.flags = ArchiveEntryFlags(Nz::SafeCast<ArchiveEntryFlags::BitField>(flags));

deserializer.Deserialize(data.offset);
deserializer.Deserialize(data.size);
}

Archive archive;
Expand All @@ -155,6 +161,7 @@ namespace nzsl

Archive::ModuleData module;
module.name = std::move(entry.moduleName);
module.kind = entry.kind;
module.flags = entry.flags;

module.data.resize(entry.size);
Expand All @@ -178,9 +185,10 @@ namespace nzsl
for (const auto& module : modules)
{
serializer.Serialize(module.name);
serializer.Serialize(std::uint32_t(module.kind));
serializer.Serialize(std::uint32_t(module.flags));
moduleOffsets.push_back(serializer.Serialize(std::uint32_t(0))); // reserve space
serializer.Serialize(Nz::SafeCast<std::uint32_t>(module.data.size()));
serializer.Serialize(std::uint32_t(module.flags));
}

auto offsetIt = moduleOffsets.begin();
Expand Down
22 changes: 17 additions & 5 deletions src/ShaderArchiver/Archiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
namespace nzsla
{
Archiver::Archiver(cxxopts::ParseResult& options) :
m_options(options)
m_options(options),
m_isArchiving(false),
m_isShowing(false),
m_isVerbose(false),
m_outputToStdout(false)
{
}

Expand Down Expand Up @@ -49,8 +53,9 @@ namespace nzsla
{
m_outputPath = Nz::Utf8Path(outputPath);

if (!std::filesystem::is_directory(m_outputPath) && !std::filesystem::create_directories(m_outputPath))
throw std::runtime_error(fmt::format("failed to create {} directory", Nz::PathToString(m_outputPath)));
std::filesystem::path parentPath = m_outputPath.parent_path();
if (!std::filesystem::is_directory(parentPath) && !std::filesystem::create_directories(parentPath))
throw std::runtime_error(fmt::format("failed to create {} directory", Nz::PathToString(parentPath)));
}
}
}
Expand Down Expand Up @@ -78,7 +83,7 @@ namespace nzsla
("version", "Print version");

options.add_options("archive")
("a,archive", "Archives the input shaders to an archive.");
("a,archive", "Archives the input shaders to an archive.")
("header", "Generates an includable header file.");

options.add_options("compression")
Expand Down Expand Up @@ -162,6 +167,7 @@ namespace nzsla

void Archiver::DoShow()
{
bool first = true;
for (const std::filesystem::path& filePath : m_inputFiles)
{
if (filePath.extension() != Nz::Utf8Path(".nzsla"))
Expand All @@ -171,7 +177,13 @@ namespace nzsla
nzsl::Deserializer deserializer(fileContent.data(), fileContent.size());

nzsl::Archive archive = nzsl::DeserializeArchive(deserializer);
fmt::print("archive info for {}\n", Nz::PathToString(filePath));

if (!first)
fmt::print("---\n");

first = false;

fmt::print("archive info for {}\n\n", Nz::PathToString(filePath));

const auto& modules = archive.GetModules();
fmt::print("{} module(s) are stored in this archive:\n", modules.size());
Expand Down
104 changes: 104 additions & 0 deletions tests/src/Tests/NzslaTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include <Tests/ToolUtils.hpp>
#include <NazaraUtils/Algorithm.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#include <NazaraUtils/PathUtils.hpp>
#include <NZSL/Config.hpp>
#include <NZSL/FilesystemModuleResolver.hpp>
#include <catch2/catch_test_macros.hpp>
#include <fmt/format.h>
#include <filesystem>

TEST_CASE("Standalone archiver", "[NZSLA]")
{
WHEN("Printing help")
{
ExecuteCommand("./nzsla -h", R"(Tool for managing NZSL shader archives)");
}

WHEN("Printing version")
{
ExecuteCommand("./nzsla --version", fmt::format(R"(nzsla version \d\.\d\.\d using nzsl {}\.{}\.{})", NZSL_VERSION_MAJOR, NZSL_VERSION_MINOR, NZSL_VERSION_PATCH));
}

WHEN("Compiling shader modules")
{
REQUIRE(std::filesystem::is_directory("../resources/modules/Archive"));

auto Cleanup = []
{
std::filesystem::remove_all("test_files");
};

Cleanup();

Nz::CallOnExit cleanupOnExit(std::move(Cleanup));

// Archive each modules
ExecuteCommand("./nzsla --archive -o test_files/test_archive.nzsla ../resources/modules/Archive/InstanceData.nzslb ../resources/modules/Archive/LightData.nzslb ../resources/modules/Archive/SkeletalData.nzslb ../resources/modules/Archive/SkinningData.nzslb ../resources/modules/Archive/ViewerData.nzslb");
ExecuteCommand("./nzsla test_files/test_archive.nzsla", {}, R"(archive info for test_files/test_archive.nzsla
5 module(s) are stored in this archive:
module name: Engine.InstanceData
- kind: BinaryShaderModule
- flags:
- size: 375
module name: Engine.LightData
- kind: BinaryShaderModule
- flags:
- size: 3410
module name: Engine.SkeletalData
- kind: BinaryShaderModule
- flags:
- size: 436
module name: Engine.SkinningData
- kind: BinaryShaderModule
- flags:
- size: 816
module name: Engine.ViewerData
- kind: BinaryShaderModule
- flags:
- size: 1198)");

// Archive and compress
ExecuteCommand("./nzsla --archive --compress -o test_files/test_archive.nzsla ../resources/modules/Archive/InstanceData.nzslb ../resources/modules/Archive/LightData.nzslb ../resources/modules/Archive/SkeletalData.nzslb ../resources/modules/Archive/SkinningData.nzslb ../resources/modules/Archive/ViewerData.nzslb");
ExecuteCommand("./nzsla test_files/test_archive.nzsla", {}, R"(archive info for test_files/test_archive.nzsla
5 module(s) are stored in this archive:
module name: Engine.InstanceData
- kind: BinaryShaderModule
- flags: CompressedLZ4HC
- size: 211
module name: Engine.LightData
- kind: BinaryShaderModule
- flags: CompressedLZ4HC
- size: 1064
module name: Engine.SkeletalData
- kind: BinaryShaderModule
- flags: CompressedLZ4HC
- size: 267
module name: Engine.SkinningData
- kind: BinaryShaderModule
- flags: CompressedLZ4HC
- size: 333
module name: Engine.ViewerData
- kind: BinaryShaderModule
- flags: CompressedLZ4HC
- size: 459)");

// Register each module
nzsl::FilesystemModuleResolver moduleResolver;
moduleResolver.RegisterFile(Nz::Utf8Path("test_files/test_archive.nzsla"));

CHECK(moduleResolver.Resolve("Engine.InstanceData"));
CHECK(moduleResolver.Resolve("Engine.LightData"));
CHECK(moduleResolver.Resolve("Engine.SkeletalData"));
CHECK(moduleResolver.Resolve("Engine.SkinningData"));
CHECK(moduleResolver.Resolve("Engine.ViewerData"));
CHECK_FALSE(moduleResolver.Resolve("NonExistent"));

// Test header generation
ExecuteCommand("./nzsla --archive --compress --header -o test_files/test_archive.nzsla.h ../resources/modules/Archive/InstanceData.nzslb ../resources/modules/Archive/LightData.nzslb ../resources/modules/Archive/SkeletalData.nzslb ../resources/modules/Archive/SkinningData.nzslb ../resources/modules/Archive/ViewerData.nzslb");

CheckHeaderMatch(Nz::Utf8Path("test_files/test_archive.nzsla"));
}
}
79 changes: 1 addition & 78 deletions tests/src/Tests/NzslcTests.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <Tests/ToolUtils.hpp>
#include <NazaraUtils/Algorithm.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#include <NZSL/Config.hpp>
Expand All @@ -11,84 +12,6 @@
#include <iostream>
#include <string_view>

void CheckHeaderMatch(const std::filesystem::path& originalFilepath)
{
std::ifstream originalFile(originalFilepath, std::ios::in | std::ios::binary);
REQUIRE(originalFile);

originalFile.seekg(0, std::ios::end);

std::streamsize length = originalFile.tellg();
REQUIRE(length > 0);
if (length == 0)
return; //< ignore empty files

originalFile.seekg(0, std::ios::beg);

std::vector<char> originalContent(Nz::SafeCast<std::size_t>(length));
REQUIRE(originalFile.read(&originalContent[0], length));

std::filesystem::path headerFilepath = originalFilepath;
headerFilepath.concat(".h");

std::ifstream headerFile(headerFilepath, std::ios::in);
REQUIRE(headerFile);

std::vector<char> content;

for (std::size_t i = 0; i < originalContent.size(); ++i)
{
std::uint8_t referenceValue = static_cast<std::uint8_t>(originalContent[i]);

unsigned int value;
headerFile >> value;

if (value != referenceValue)
REQUIRE(value == referenceValue);

char sep;
headerFile >> sep;

if (sep != ',')
REQUIRE(sep == ',');
}

CHECK(headerFile.eof());
}

void ExecuteCommand(const std::string& command, const std::string& pattern = {})
{
std::string output;
auto ReadStdout = [&](const char* str, std::size_t size)
{
output.append(str, size);
};

std::string errOutput;
auto ReadStderr = [&](const char* str, std::size_t size)
{
errOutput.append(str, size);
};

TinyProcessLib::Process compiler(command, {}, ReadStdout, ReadStderr);
int exitCode = compiler.get_exit_status();
if (exitCode != 0)
{
INFO("Command-line: " << command << "\nstdout: " << output << "\nstderr: " << errOutput);
REQUIRE(exitCode == 0);
}

if (!pattern.empty())
{
INFO("Full output: " << output);
// matcher doesn't like multilines, keep only the first one
if (std::size_t i = output.find_first_of("\r\n"); i != output.npos)
output.resize(i);

CHECK_THAT(output, Catch::Matchers::Matches(pattern));
}
}

TEST_CASE("Standalone compiler", "[NZSLC]")
{
WHEN("Printing help")
Expand Down
8 changes: 7 additions & 1 deletion tests/src/Tests/ShaderUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <glslang/Public/ShaderLang.h>
#include <spirv-tools/libspirv.hpp>

namespace
namespace NAZARA_ANONYMOUS_NAMESPACE
{
// Use OpenGL default minimal values (from https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glGet.xhtml, https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGet.xhtml and https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/)
const TBuiltInResource s_minResources = {
Expand Down Expand Up @@ -218,6 +218,8 @@ namespace

void ExpectGLSL(nzsl::ShaderStageType stageType, const nzsl::Ast::Module& shaderModule, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options, const nzsl::GlslWriter::Environment& env, bool testShaderCompilation)
{
NAZARA_USE_ANONYMOUS_NAMESPACE

std::string expectedSource = SanitizeSource(expectedOutput);

std::string_view stageName;
Expand Down Expand Up @@ -319,6 +321,8 @@ void ExpectGLSL(const nzsl::Ast::Module& shaderModule, std::string_view expected

void ExpectNZSL(const nzsl::Ast::Module& shaderModule, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options)
{
NAZARA_USE_ANONYMOUS_NAMESPACE

std::string source = SanitizeSource(expectedOutput);

SECTION("Generating NZSL")
Expand Down Expand Up @@ -349,6 +353,8 @@ void ExpectNZSL(const nzsl::Ast::Module& shaderModule, std::string_view expected

void ExpectSPIRV(const nzsl::Ast::Module& shaderModule, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options, const nzsl::SpirvWriter::Environment& env, bool outputParameter)
{
NAZARA_USE_ANONYMOUS_NAMESPACE

std::string source = SanitizeSource(expectedOutput);

SECTION("Generating SPIR-V")
Expand Down
Loading

0 comments on commit 3bec332

Please sign in to comment.