#include "fixtures/RHITestFixture.h" #include "XCEngine/RHI/RHIShader.h" #include using namespace XCEngine::RHI; TEST_P(RHITestFixture, Shader_Compile_EmptyDesc_ReturnsNullptr) { ShaderCompileDesc desc = {}; RHIShader* shader = GetDevice()->CreateShader(desc); EXPECT_EQ(shader, nullptr); } TEST_P(RHITestFixture, Shader_Compile_ValidVertexShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* vs = "#version 430\nin vec4 aPosition;\nvoid main() { gl_Position = aPosition; }"; desc.source.assign(vs, vs + strlen(vs)); desc.profile = L"vs"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { EXPECT_TRUE(shader->IsValid()); EXPECT_EQ(shader->GetType(), ShaderType::Vertex); EXPECT_NE(shader->GetNativeHandle(), nullptr); shader->Shutdown(); delete shader; } } TEST_P(RHITestFixture, Shader_Compile_ValidFragmentShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainPS"; desc.profile = L"ps_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* fs = "#version 430\nout vec4 c;\nvoid main() { c = vec4(1,0,0,1); }"; desc.source.assign(fs, fs + strlen(fs)); desc.profile = L"ps"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { EXPECT_TRUE(shader->IsValid()); EXPECT_EQ(shader->GetType(), ShaderType::Fragment); EXPECT_NE(shader->GetNativeHandle(), nullptr); shader->Shutdown(); delete shader; } } TEST_P(RHITestFixture, Shader_GetType_VertexShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* vs = "#version 430\nin vec4 aPosition;\nvoid main() { gl_Position = aPosition; }"; desc.source.assign(vs, vs + strlen(vs)); desc.profile = L"vs"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { EXPECT_EQ(shader->GetType(), ShaderType::Vertex); shader->Shutdown(); delete shader; } } TEST_P(RHITestFixture, Shader_GetType_FragmentShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainPS"; desc.profile = L"ps_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* fs = "#version 430\nout vec4 c;\nvoid main() { c = vec4(1,0,0,1); }"; desc.source.assign(fs, fs + strlen(fs)); desc.profile = L"ps"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { EXPECT_EQ(shader->GetType(), ShaderType::Fragment); shader->Shutdown(); delete shader; } } TEST_P(RHITestFixture, Shader_GetNativeHandle_ValidShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* vs = "#version 430\nin vec4 aPosition;\nvoid main() { gl_Position = aPosition; }"; desc.source.assign(vs, vs + strlen(vs)); desc.profile = L"vs"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { void* handle = shader->GetNativeHandle(); EXPECT_NE(handle, nullptr); shader->Shutdown(); delete shader; } } TEST_P(RHITestFixture, Shader_Shutdown_Invalidates) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.sourceLanguage = ShaderLanguage::GLSL; static const char* vs = "#version 430\nin vec4 aPosition;\nvoid main() { gl_Position = aPosition; }"; desc.source.assign(vs, vs + strlen(vs)); desc.profile = L"vs"; } RHIShader* shader = GetDevice()->CreateShader(desc); if (shader != nullptr) { EXPECT_TRUE(shader->IsValid()); shader->Shutdown(); EXPECT_FALSE(shader->IsValid()); delete shader; } } TEST_P(RHITestFixture, Shader_Compile_FromFile_ReturnsValidShader) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.fileName = L"tests/RHI/OpenGL/integration/triangle/Res/Shader/triangle.vert"; desc.entryPoint = L"main"; desc.profile = L"vs_4_30"; } RHIShader* shader = GetDevice()->CreateShader(desc); ASSERT_NE(shader, nullptr); EXPECT_TRUE(shader->IsValid()); EXPECT_EQ(shader->GetType(), ShaderType::Vertex); shader->Shutdown(); delete shader; } TEST_P(RHITestFixture, Shader_Compile_MissingFile_ReturnsNullptr) { ShaderCompileDesc desc = {}; if (GetBackendType() == RHIType::D3D12) { desc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/does_not_exist.hlsl"; desc.entryPoint = L"MainVS"; desc.profile = L"vs_5_0"; } else { desc.fileName = L"tests/RHI/OpenGL/integration/triangle/Res/Shader/does_not_exist.vert"; desc.entryPoint = L"main"; desc.profile = L"vs_4_30"; } RHIShader* shader = GetDevice()->CreateShader(desc); EXPECT_EQ(shader, nullptr); }