refactor(tests): reorganize tests directory to match engine structure
- Created tests/Core/Asset/ with tests for IResource, ResourceTypes, ResourceHandle, ResourceCache, ResourceDependencyGraph, ResourceGUID
- Created tests/Core/IO/ with tests for IResourceLoader, ResourcePath, ResourceFileSystem, FileArchive, ResourcePackage
- Reorganized tests/Resources/ into subdirectories: Texture/, Mesh/, Material/, Shader/, AudioClip/
- Added CMakeLists.txt for each new test subdirectory
- Fixed Material.h missing ResourceManager.h include (lost during engine refactor)
- tests/Core/CMakeLists.txt updated to include Asset/ and IO/ subdirectories
2026-03-24 15:44:13 +08:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <XCEngine/Resources/Shader/Shader.h>
|
|
|
|
|
#include <XCEngine/Core/Asset/ResourceTypes.h>
|
|
|
|
|
#include <XCEngine/Core/Containers/Array.h>
|
|
|
|
|
|
|
|
|
|
using namespace XCEngine::Resources;
|
|
|
|
|
using namespace XCEngine::Containers;
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
TEST(Shader, DefaultConstructor) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
EXPECT_EQ(shader.GetShaderType(), ShaderType::Fragment);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderLanguage(), ShaderLanguage::GLSL);
|
|
|
|
|
EXPECT_FALSE(shader.IsValid());
|
|
|
|
|
EXPECT_EQ(shader.GetMemorySize(), 0u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, GetType) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
EXPECT_EQ(shader.GetType(), ResourceType::Shader);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, SetGetShaderType) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
|
|
|
|
|
shader.SetShaderType(ShaderType::Vertex);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderType(), ShaderType::Vertex);
|
|
|
|
|
|
|
|
|
|
shader.SetShaderType(ShaderType::Fragment);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderType(), ShaderType::Fragment);
|
|
|
|
|
|
|
|
|
|
shader.SetShaderType(ShaderType::Geometry);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderType(), ShaderType::Geometry);
|
|
|
|
|
|
|
|
|
|
shader.SetShaderType(ShaderType::Compute);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderType(), ShaderType::Compute);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, SetGetShaderLanguage) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
|
|
|
|
|
shader.SetShaderLanguage(ShaderLanguage::GLSL);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderLanguage(), ShaderLanguage::GLSL);
|
|
|
|
|
|
|
|
|
|
shader.SetShaderLanguage(ShaderLanguage::HLSL);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderLanguage(), ShaderLanguage::HLSL);
|
|
|
|
|
|
|
|
|
|
shader.SetShaderLanguage(ShaderLanguage::SPIRV);
|
|
|
|
|
EXPECT_EQ(shader.GetShaderLanguage(), ShaderLanguage::SPIRV);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, SetGetSourceCode) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
const char* source = "#version 330 core\nvoid main() {}";
|
|
|
|
|
|
|
|
|
|
shader.SetSourceCode(source);
|
|
|
|
|
EXPECT_EQ(shader.GetSourceCode(), source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, SetGetCompiledBinary) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
XCEngine::Containers::Array<XCEngine::Core::uint8> binary = { 0x00, 0x01, 0x02, 0x03 };
|
|
|
|
|
|
|
|
|
|
shader.SetCompiledBinary(binary);
|
|
|
|
|
EXPECT_EQ(shader.GetCompiledBinary().Size(), 4u);
|
|
|
|
|
EXPECT_EQ(shader.GetCompiledBinary()[0], 0x00);
|
|
|
|
|
EXPECT_EQ(shader.GetCompiledBinary()[3], 0x03);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, AddGetUniforms) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
|
|
|
|
|
ShaderUniform uniform1;
|
|
|
|
|
uniform1.name = "uModelView";
|
|
|
|
|
uniform1.location = 0;
|
|
|
|
|
uniform1.size = 1;
|
|
|
|
|
uniform1.type = 4;
|
|
|
|
|
|
|
|
|
|
shader.AddUniform(uniform1);
|
|
|
|
|
|
|
|
|
|
const auto& uniforms = shader.GetUniforms();
|
|
|
|
|
EXPECT_EQ(uniforms.Size(), 1u);
|
|
|
|
|
EXPECT_EQ(uniforms[0].name, "uModelView");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, AddGetAttributes) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
|
|
|
|
|
ShaderAttribute attr1;
|
|
|
|
|
attr1.name = "aPosition";
|
|
|
|
|
attr1.location = 0;
|
|
|
|
|
attr1.size = 1;
|
|
|
|
|
attr1.type = 3;
|
|
|
|
|
|
|
|
|
|
shader.AddAttribute(attr1);
|
|
|
|
|
|
|
|
|
|
const auto& attributes = shader.GetAttributes();
|
|
|
|
|
EXPECT_EQ(attributes.Size(), 1u);
|
|
|
|
|
EXPECT_EQ(attributes[0].name, "aPosition");
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 16:10:50 +08:00
|
|
|
TEST(Shader, LegacySingleStageStateSyncsIntoDefaultPassVariant) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
shader.SetShaderType(ShaderType::Vertex);
|
|
|
|
|
shader.SetShaderLanguage(ShaderLanguage::HLSL);
|
|
|
|
|
shader.SetSourceCode("float4 MainVS() : SV_POSITION { return 0; }");
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(shader.GetPassCount(), 1u);
|
|
|
|
|
const ShaderPass* pass = shader.FindPass("Default");
|
|
|
|
|
ASSERT_NE(pass, nullptr);
|
|
|
|
|
ASSERT_EQ(pass->variants.Size(), 1u);
|
|
|
|
|
EXPECT_EQ(pass->variants[0].stage, ShaderType::Vertex);
|
|
|
|
|
EXPECT_EQ(pass->variants[0].language, ShaderLanguage::HLSL);
|
|
|
|
|
EXPECT_EQ(pass->variants[0].backend, ShaderBackend::Generic);
|
|
|
|
|
EXPECT_EQ(pass->variants[0].sourceCode, "float4 MainVS() : SV_POSITION { return 0; }");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, FindsBackendSpecificVariantAndFallsBackToGeneric) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
|
|
|
|
|
ShaderStageVariant genericFragment = {};
|
|
|
|
|
genericFragment.stage = ShaderType::Fragment;
|
|
|
|
|
genericFragment.language = ShaderLanguage::GLSL;
|
|
|
|
|
genericFragment.backend = ShaderBackend::Generic;
|
|
|
|
|
genericFragment.sourceCode = "generic fragment";
|
|
|
|
|
shader.AddPassVariant("ForwardLit", genericFragment);
|
|
|
|
|
|
|
|
|
|
ShaderStageVariant d3d12Fragment = {};
|
|
|
|
|
d3d12Fragment.stage = ShaderType::Fragment;
|
|
|
|
|
d3d12Fragment.language = ShaderLanguage::HLSL;
|
|
|
|
|
d3d12Fragment.backend = ShaderBackend::D3D12;
|
|
|
|
|
d3d12Fragment.sourceCode = "d3d12 fragment";
|
|
|
|
|
shader.AddPassVariant("ForwardLit", d3d12Fragment);
|
|
|
|
|
|
|
|
|
|
const ShaderStageVariant* d3d12Variant =
|
|
|
|
|
shader.FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::D3D12);
|
|
|
|
|
ASSERT_NE(d3d12Variant, nullptr);
|
|
|
|
|
EXPECT_EQ(d3d12Variant->sourceCode, "d3d12 fragment");
|
|
|
|
|
|
|
|
|
|
const ShaderStageVariant* openglVariant =
|
|
|
|
|
shader.FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL);
|
|
|
|
|
ASSERT_NE(openglVariant, nullptr);
|
|
|
|
|
EXPECT_EQ(openglVariant->sourceCode, "generic fragment");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, StoresPerPassTags) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
shader.SetPassTag("ForwardLit", "LightMode", "ForwardBase");
|
|
|
|
|
shader.SetPassTag("ForwardLit", "Queue", "Geometry");
|
|
|
|
|
|
|
|
|
|
const ShaderPass* pass = shader.FindPass("ForwardLit");
|
|
|
|
|
ASSERT_NE(pass, nullptr);
|
|
|
|
|
ASSERT_EQ(pass->tags.Size(), 2u);
|
|
|
|
|
EXPECT_EQ(pass->tags[0].name, "LightMode");
|
|
|
|
|
EXPECT_EQ(pass->tags[0].value, "ForwardBase");
|
|
|
|
|
EXPECT_EQ(pass->tags[1].name, "Queue");
|
|
|
|
|
EXPECT_EQ(pass->tags[1].value, "Geometry");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(Shader, ReleaseClearsPassRuntimeData) {
|
|
|
|
|
Shader shader;
|
|
|
|
|
shader.SetSourceCode("void main() {}");
|
|
|
|
|
ShaderStageVariant variant = {};
|
|
|
|
|
variant.stage = ShaderType::Fragment;
|
|
|
|
|
variant.sourceCode = "fragment";
|
|
|
|
|
shader.AddPassVariant("ForwardLit", variant);
|
|
|
|
|
|
|
|
|
|
shader.Release();
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(shader.GetPassCount(), 0u);
|
|
|
|
|
EXPECT_EQ(shader.GetSourceCode(), "");
|
|
|
|
|
EXPECT_EQ(shader.GetCompiledBinary().Size(), 0u);
|
|
|
|
|
EXPECT_FALSE(shader.IsValid());
|
|
|
|
|
}
|
|
|
|
|
|
refactor(tests): reorganize tests directory to match engine structure
- Created tests/Core/Asset/ with tests for IResource, ResourceTypes, ResourceHandle, ResourceCache, ResourceDependencyGraph, ResourceGUID
- Created tests/Core/IO/ with tests for IResourceLoader, ResourcePath, ResourceFileSystem, FileArchive, ResourcePackage
- Reorganized tests/Resources/ into subdirectories: Texture/, Mesh/, Material/, Shader/, AudioClip/
- Added CMakeLists.txt for each new test subdirectory
- Fixed Material.h missing ResourceManager.h include (lost during engine refactor)
- tests/Core/CMakeLists.txt updated to include Asset/ and IO/ subdirectories
2026-03-24 15:44:13 +08:00
|
|
|
} // namespace
|