Add Vulkan sphere integration support
This commit is contained in:
@@ -139,13 +139,35 @@ void RHIIntegrationFixture::SetUp() {
|
||||
mBackBufferViews.push_back(rtv);
|
||||
}
|
||||
|
||||
mDepthStencilTexture = new D3D12Texture();
|
||||
ASSERT_NE(mDepthStencilTexture, nullptr);
|
||||
ASSERT_TRUE(mDepthStencilTexture->InitializeDepthStencil(device, width, height));
|
||||
auto* depthStencilTexture = new D3D12Texture();
|
||||
ASSERT_NE(depthStencilTexture, nullptr);
|
||||
ASSERT_TRUE(depthStencilTexture->InitializeDepthStencil(device, width, height));
|
||||
mDepthStencilTexture = depthStencilTexture;
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12ResourceView::CreateDepthStencilDesc(Format::D24_UNorm_S8_UInt, D3D12_DSV_DIMENSION_TEXTURE2D);
|
||||
auto* d3d12DSV = new D3D12ResourceView();
|
||||
d3d12DSV->InitializeAsDepthStencil(device, mDepthStencilTexture->GetResource(), &dsvDesc, mDSVHeap, 0);
|
||||
mDSV = d3d12DSV;
|
||||
d3d12DSV->InitializeAsDepthStencil(device, depthStencilTexture->GetResource(), &dsvDesc, mDSVHeap, 0);
|
||||
mDepthStencilView = d3d12DSV;
|
||||
} else if (GetParam() == RHIType::Vulkan) {
|
||||
TextureDesc depthDesc = {};
|
||||
depthDesc.width = static_cast<uint32_t>(width);
|
||||
depthDesc.height = static_cast<uint32_t>(height);
|
||||
depthDesc.depth = 1;
|
||||
depthDesc.mipLevels = 1;
|
||||
depthDesc.arraySize = 1;
|
||||
depthDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||
depthDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||
depthDesc.sampleCount = 1;
|
||||
depthDesc.sampleQuality = 0;
|
||||
depthDesc.flags = 0;
|
||||
|
||||
mDepthStencilTexture = mDevice->CreateTexture(depthDesc);
|
||||
ASSERT_NE(mDepthStencilTexture, nullptr);
|
||||
|
||||
ResourceViewDesc depthViewDesc = {};
|
||||
depthViewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||
depthViewDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||
mDepthStencilView = mDevice->CreateDepthStencilView(mDepthStencilTexture, depthViewDesc);
|
||||
ASSERT_NE(mDepthStencilView, nullptr);
|
||||
}
|
||||
|
||||
mScreenshot = RHIScreenshot::Create(GetParam());
|
||||
@@ -179,7 +201,7 @@ void RHIIntegrationFixture::SetRenderTargetForClear(bool includeDepthStencil) {
|
||||
d3d12CmdList->TransitionBarrier(backBuffer->GetResource(), ResourceStates::Present, ResourceStates::RenderTarget);
|
||||
RHIResourceView* rtv = mBackBufferViews[mCurrentBackBufferIndex];
|
||||
Log("[TEST] SetRenderTargetForClear: calling SetRenderTargets, rtv=%p", (void*)rtv);
|
||||
mCommandList->SetRenderTargets(1, &rtv, includeDepthStencil ? mDSV : nullptr);
|
||||
mCommandList->SetRenderTargets(1, &rtv, includeDepthStencil ? mDepthStencilView : nullptr);
|
||||
Log("[TEST] SetRenderTargetForClear: done");
|
||||
} else {
|
||||
Log("[TEST] SetRenderTargetForClear: skipped - condition failed");
|
||||
@@ -204,7 +226,7 @@ void RHIIntegrationFixture::SetRenderTargetForClear(bool includeDepthStencil) {
|
||||
|
||||
ASSERT_NE(mBackBufferViews[backBufferIndex], nullptr);
|
||||
RHIResourceView* rtv = mBackBufferViews[backBufferIndex];
|
||||
mCommandList->SetRenderTargets(1, &rtv, nullptr);
|
||||
mCommandList->SetRenderTargets(1, &rtv, includeDepthStencil ? mDepthStencilView : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,19 +254,19 @@ void RHIIntegrationFixture::TearDown() {
|
||||
}
|
||||
mBackBufferViews.clear();
|
||||
|
||||
if (mDepthStencilView) {
|
||||
mDepthStencilView->Shutdown();
|
||||
delete mDepthStencilView;
|
||||
mDepthStencilView = nullptr;
|
||||
}
|
||||
|
||||
if (mDepthStencilTexture) {
|
||||
mDepthStencilTexture->Shutdown();
|
||||
delete mDepthStencilTexture;
|
||||
mDepthStencilTexture = nullptr;
|
||||
}
|
||||
|
||||
if (GetParam() == RHIType::D3D12) {
|
||||
if (mDSV) {
|
||||
mDSV->Shutdown();
|
||||
delete mDSV;
|
||||
mDSV = nullptr;
|
||||
}
|
||||
|
||||
if (mDepthStencilTexture) {
|
||||
mDepthStencilTexture->Shutdown();
|
||||
delete mDepthStencilTexture;
|
||||
mDepthStencilTexture = nullptr;
|
||||
}
|
||||
|
||||
if (mRTVHeap) {
|
||||
mRTVHeap->Shutdown();
|
||||
delete mRTVHeap;
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include "XCEngine/RHI/RHICommandList.h"
|
||||
#include "XCEngine/RHI/RHISwapChain.h"
|
||||
#include "XCEngine/RHI/RHIScreenshot.h"
|
||||
#include "XCEngine/RHI/RHIResourceView.h"
|
||||
#include "XCEngine/RHI/RHIEnums.h"
|
||||
#include "XCEngine/RHI/RHITexture.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
||||
#include "XCEngine/Debug/Logger.h"
|
||||
#include "XCEngine/Debug/ConsoleLogSink.h"
|
||||
@@ -68,12 +70,12 @@ private:
|
||||
HWND mWindow = nullptr;
|
||||
int mCurrentBackBufferIndex = 0;
|
||||
std::vector<RHIResourceView*> mBackBufferViews;
|
||||
RHITexture* mDepthStencilTexture = nullptr;
|
||||
RHIResourceView* mDepthStencilView = nullptr;
|
||||
|
||||
#if defined(XCENGINE_SUPPORT_D3D12)
|
||||
D3D12DescriptorHeap* mRTVHeap = nullptr;
|
||||
D3D12DescriptorHeap* mDSVHeap = nullptr;
|
||||
D3D12Texture* mDepthStencilTexture = nullptr;
|
||||
RHIResourceView* mDSV = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/opengl/package)
|
||||
|
||||
get_filename_component(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
|
||||
|
||||
find_package(Vulkan QUIET)
|
||||
|
||||
add_executable(rhi_integration_sphere
|
||||
main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../fixtures/RHIIntegrationFixture.cpp
|
||||
@@ -33,6 +35,60 @@ target_link_libraries(rhi_integration_sphere PRIVATE
|
||||
GTest::gtest
|
||||
)
|
||||
|
||||
if(Vulkan_FOUND)
|
||||
set(XCENGINE_GLSLANG_VALIDATOR_HINT "$ENV{VULKAN_SDK}")
|
||||
find_program(
|
||||
XCENGINE_GLSLANG_VALIDATOR
|
||||
NAMES glslangValidator glslangValidator.exe
|
||||
HINTS
|
||||
"${XCENGINE_GLSLANG_VALIDATOR_HINT}/Bin"
|
||||
"${Vulkan_ROOT}/Bin")
|
||||
|
||||
if(NOT XCENGINE_GLSLANG_VALIDATOR)
|
||||
file(GLOB XCENGINE_VULKAN_BIN_DIRS "D:/VulkanSDK/*/Bin")
|
||||
if(XCENGINE_VULKAN_BIN_DIRS)
|
||||
list(SORT XCENGINE_VULKAN_BIN_DIRS COMPARE NATURAL ORDER DESCENDING)
|
||||
foreach(XCENGINE_VULKAN_BIN_DIR IN LISTS XCENGINE_VULKAN_BIN_DIRS)
|
||||
find_program(
|
||||
XCENGINE_GLSLANG_VALIDATOR
|
||||
NAMES glslangValidator glslangValidator.exe
|
||||
PATHS "${XCENGINE_VULKAN_BIN_DIR}"
|
||||
NO_DEFAULT_PATH)
|
||||
if(XCENGINE_GLSLANG_VALIDATOR)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT XCENGINE_GLSLANG_VALIDATOR)
|
||||
message(FATAL_ERROR "glslangValidator not found for Vulkan sphere shaders")
|
||||
endif()
|
||||
|
||||
set(SPHERE_VULKAN_VERTEX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Res/Shader/sphere_vulkan.vert)
|
||||
set(SPHERE_VULKAN_FRAGMENT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Res/Shader/sphere_vulkan.frag)
|
||||
|
||||
add_custom_command(TARGET rhi_integration_sphere PRE_BUILD
|
||||
COMMAND ${XCENGINE_GLSLANG_VALIDATOR}
|
||||
-V
|
||||
-S
|
||||
vert
|
||||
-o
|
||||
$<TARGET_FILE_DIR:rhi_integration_sphere>/sphere_vulkan.vert.spv
|
||||
${SPHERE_VULKAN_VERTEX_SOURCE}
|
||||
COMMAND ${XCENGINE_GLSLANG_VALIDATOR}
|
||||
-V
|
||||
-S
|
||||
frag
|
||||
-o
|
||||
$<TARGET_FILE_DIR:rhi_integration_sphere>/sphere_vulkan.frag.spv
|
||||
${SPHERE_VULKAN_FRAGMENT_SOURCE}
|
||||
VERBATIM)
|
||||
|
||||
target_link_libraries(rhi_integration_sphere PRIVATE Vulkan::Vulkan)
|
||||
target_compile_definitions(rhi_integration_sphere PRIVATE XCENGINE_SUPPORT_VULKAN)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(rhi_integration_sphere PRIVATE
|
||||
UNICODE
|
||||
_UNICODE
|
||||
|
||||
11
tests/RHI/integration/sphere/Res/Shader/sphere_vulkan.frag
Normal file
11
tests/RHI/integration/sphere/Res/Shader/sphere_vulkan.frag
Normal file
@@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 2, binding = 0) uniform texture2D uTexture;
|
||||
layout(set = 3, binding = 0) uniform sampler uSampler;
|
||||
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(sampler2D(uTexture, uSampler), vTexCoord);
|
||||
}
|
||||
19
tests/RHI/integration/sphere/Res/Shader/sphere_vulkan.vert
Normal file
19
tests/RHI/integration/sphere/Res/Shader/sphere_vulkan.vert
Normal file
@@ -0,0 +1,19 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
|
||||
layout(set = 1, binding = 0, std140) uniform MatrixBuffer {
|
||||
mat4 gProjectionMatrix;
|
||||
mat4 gViewMatrix;
|
||||
mat4 gModelMatrix;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vec4 positionWS = gModelMatrix * aPosition;
|
||||
vec4 positionVS = gViewMatrix * positionWS;
|
||||
gl_Position = gProjectionMatrix * positionVS;
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -61,6 +62,27 @@ std::filesystem::path ResolveRuntimePath(const char* relativePath) {
|
||||
return GetExecutableDirectory() / relativePath;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LoadBinaryFileRelative(const char* filename) {
|
||||
const std::filesystem::path path = ResolveRuntimePath(filename);
|
||||
std::ifstream file(path, std::ios::binary | std::ios::ate);
|
||||
if (!file.is_open()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::streamsize size = file.tellg();
|
||||
if (size <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes(static_cast<size_t>(size));
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (!file.read(reinterpret_cast<char*>(bytes.data()), size)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void GenerateSphere(std::vector<Vertex>& vertices, std::vector<uint32_t>& indices, float radius, int segments) {
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
@@ -188,7 +210,16 @@ void main() {
|
||||
)";
|
||||
|
||||
const char* GetScreenshotFilename(RHIType type) {
|
||||
return type == RHIType::D3D12 ? "sphere_d3d12.ppm" : "sphere_opengl.ppm";
|
||||
switch (type) {
|
||||
case RHIType::D3D12:
|
||||
return "sphere_d3d12.ppm";
|
||||
case RHIType::OpenGL:
|
||||
return "sphere_opengl.ppm";
|
||||
case RHIType::Vulkan:
|
||||
return "sphere_vulkan.ppm";
|
||||
default:
|
||||
return "sphere_unknown.ppm";
|
||||
}
|
||||
}
|
||||
|
||||
int GetComparisonThreshold(RHIType type) {
|
||||
@@ -275,7 +306,7 @@ GraphicsPipelineDesc CreateSpherePipelineDesc(RHIType type, RHIPipelineLayout* p
|
||||
desc.fragmentShader.sourceLanguage = ShaderLanguage::HLSL;
|
||||
desc.fragmentShader.entryPoint = L"MainPS";
|
||||
desc.fragmentShader.profile = L"ps_5_0";
|
||||
} else {
|
||||
} else if (type == RHIType::OpenGL) {
|
||||
desc.vertexShader.source.assign(kSphereVertexShader, kSphereVertexShader + strlen(kSphereVertexShader));
|
||||
desc.vertexShader.sourceLanguage = ShaderLanguage::GLSL;
|
||||
desc.vertexShader.profile = L"vs_4_30";
|
||||
@@ -283,6 +314,14 @@ GraphicsPipelineDesc CreateSpherePipelineDesc(RHIType type, RHIPipelineLayout* p
|
||||
desc.fragmentShader.source.assign(kSphereFragmentShader, kSphereFragmentShader + strlen(kSphereFragmentShader));
|
||||
desc.fragmentShader.sourceLanguage = ShaderLanguage::GLSL;
|
||||
desc.fragmentShader.profile = L"fs_4_30";
|
||||
} else if (type == RHIType::Vulkan) {
|
||||
desc.vertexShader.source = LoadBinaryFileRelative("sphere_vulkan.vert.spv");
|
||||
desc.vertexShader.sourceLanguage = ShaderLanguage::SPIRV;
|
||||
desc.vertexShader.entryPoint = L"main";
|
||||
|
||||
desc.fragmentShader.source = LoadBinaryFileRelative("sphere_vulkan.frag.spv");
|
||||
desc.fragmentShader.sourceLanguage = ShaderLanguage::SPIRV;
|
||||
desc.fragmentShader.entryPoint = L"main";
|
||||
}
|
||||
|
||||
return desc;
|
||||
@@ -657,6 +696,9 @@ TEST_P(SphereTest, RenderSphere) {
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(D3D12, SphereTest, ::testing::Values(RHIType::D3D12));
|
||||
INSTANTIATE_TEST_SUITE_P(OpenGL, SphereTest, ::testing::Values(RHIType::OpenGL));
|
||||
#if defined(XCENGINE_SUPPORT_VULKAN)
|
||||
INSTANTIATE_TEST_SUITE_P(Vulkan, SphereTest, ::testing::Values(RHIType::Vulkan));
|
||||
#endif
|
||||
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
Logger::Get().Initialize();
|
||||
|
||||
Reference in New Issue
Block a user