rendering: add opengl hlsl shader translation
This commit is contained in:
@@ -19,10 +19,37 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
|
||||
namespace {
|
||||
|
||||
bool FindToolFromVulkanSdkOrPath(const wchar_t* fileName) {
|
||||
wchar_t sdkBuffer[32767] = {};
|
||||
const DWORD sdkBufferCount = static_cast<DWORD>(sizeof(sdkBuffer) / sizeof(sdkBuffer[0]));
|
||||
const DWORD sdkLength = GetEnvironmentVariableW(L"VULKAN_SDK", sdkBuffer, sdkBufferCount);
|
||||
if (sdkLength > 0 && sdkLength < sdkBufferCount) {
|
||||
const std::filesystem::path candidate = std::filesystem::path(sdkBuffer) / L"Bin" / fileName;
|
||||
if (std::filesystem::exists(candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t pathBuffer[MAX_PATH] = {};
|
||||
const DWORD pathLength = SearchPathW(nullptr, fileName, nullptr, MAX_PATH, pathBuffer, nullptr);
|
||||
return pathLength > 0 && pathLength < MAX_PATH;
|
||||
}
|
||||
|
||||
bool SupportsOpenGLHlslToolchainForTests() {
|
||||
return FindToolFromVulkanSdkOrPath(L"glslangValidator.exe") &&
|
||||
FindToolFromVulkanSdkOrPath(L"spirv-cross.exe");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(OpenGLTestFixture, Device_Initialize_UnifiedPath_CanCreateSwapChain) {
|
||||
auto* device = new OpenGLDevice();
|
||||
ASSERT_NE(device, nullptr);
|
||||
@@ -52,6 +79,100 @@ TEST_F(OpenGLTestFixture, Device_Initialize_UnifiedPath_CanCreateSwapChain) {
|
||||
delete device;
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, Device_CreateShader_HlslVertex_UsesTranspiledHlslPath) {
|
||||
ASSERT_TRUE(GetDevice()->MakeContextCurrent());
|
||||
if (!SupportsOpenGLHlslToolchainForTests()) {
|
||||
GTEST_SKIP() << "glslangValidator.exe or spirv-cross.exe was not found.";
|
||||
}
|
||||
|
||||
static const char* vertexSource = R"(
|
||||
struct VSInput {
|
||||
float4 position : POSITION;
|
||||
};
|
||||
|
||||
struct VSOutput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
VSOutput MainVS(VSInput input) {
|
||||
VSOutput output;
|
||||
output.position = input.position;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
ShaderCompileDesc shaderDesc = {};
|
||||
shaderDesc.source.assign(vertexSource, vertexSource + std::strlen(vertexSource));
|
||||
shaderDesc.sourceLanguage = ShaderLanguage::HLSL;
|
||||
shaderDesc.entryPoint = L"MainVS";
|
||||
shaderDesc.profile = L"vs_5_0";
|
||||
|
||||
RHIShader* shader = GetDevice()->CreateShader(shaderDesc);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
EXPECT_TRUE(shader->IsValid());
|
||||
EXPECT_EQ(shader->GetType(), ShaderType::Vertex);
|
||||
|
||||
shader->Shutdown();
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, Device_CreatePipelineState_HlslGraphicsShaders_UsesTranspiledHlslPath) {
|
||||
ASSERT_TRUE(GetDevice()->MakeContextCurrent());
|
||||
if (!SupportsOpenGLHlslToolchainForTests()) {
|
||||
GTEST_SKIP() << "glslangValidator.exe or spirv-cross.exe was not found.";
|
||||
}
|
||||
|
||||
static const char* hlslSource = R"(
|
||||
struct VSInput {
|
||||
float4 position : POSITION;
|
||||
};
|
||||
|
||||
struct PSInput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
PSInput MainVS(VSInput input) {
|
||||
PSInput output;
|
||||
output.position = input.position;
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 MainPS(PSInput input) : SV_TARGET {
|
||||
return float4(1.0f, 0.25f, 0.0f, 1.0f);
|
||||
}
|
||||
)";
|
||||
|
||||
GraphicsPipelineDesc pipelineDesc = {};
|
||||
pipelineDesc.topologyType = static_cast<uint32_t>(PrimitiveTopologyType::Triangle);
|
||||
pipelineDesc.renderTargetFormats[0] = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
pipelineDesc.depthStencilFormat = static_cast<uint32_t>(Format::Unknown);
|
||||
|
||||
InputElementDesc position = {};
|
||||
position.semanticName = "POSITION";
|
||||
position.semanticIndex = 0;
|
||||
position.format = static_cast<uint32_t>(Format::R32G32B32A32_Float);
|
||||
position.inputSlot = 0;
|
||||
position.alignedByteOffset = 0;
|
||||
pipelineDesc.inputLayout.elements.push_back(position);
|
||||
|
||||
pipelineDesc.vertexShader.source.assign(hlslSource, hlslSource + std::strlen(hlslSource));
|
||||
pipelineDesc.vertexShader.sourceLanguage = ShaderLanguage::HLSL;
|
||||
pipelineDesc.vertexShader.entryPoint = L"MainVS";
|
||||
pipelineDesc.vertexShader.profile = L"vs_5_0";
|
||||
|
||||
pipelineDesc.fragmentShader.source.assign(hlslSource, hlslSource + std::strlen(hlslSource));
|
||||
pipelineDesc.fragmentShader.sourceLanguage = ShaderLanguage::HLSL;
|
||||
pipelineDesc.fragmentShader.entryPoint = L"MainPS";
|
||||
pipelineDesc.fragmentShader.profile = L"ps_5_0";
|
||||
|
||||
RHIPipelineState* pipelineState = GetDevice()->CreatePipelineState(pipelineDesc);
|
||||
ASSERT_NE(pipelineState, nullptr);
|
||||
EXPECT_NE(pipelineState->GetNativeHandle(), nullptr);
|
||||
|
||||
pipelineState->Shutdown();
|
||||
delete pipelineState;
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, CommandList_SetRenderTargets_BindsColorAndDepthAttachments) {
|
||||
TextureDesc colorDesc = {};
|
||||
colorDesc.width = 128;
|
||||
|
||||
Reference in New Issue
Block a user