Implement IShader and ISwapChain interfaces for D3D12 backend

- D3D12Shader now implements IShader interface with GetBytecode, GetBytecodeSize, GetType, GetInputLayout
- D3D12SwapChain now implements ISwapChain interface with GetBackBuffer returning IResource*
- Added D3D12Texture back buffer storage to SwapChain
- Fixed ISwapChain const correctness (GetCurrentBackBufferIndex, GetBackBuffer)
- main.cpp: use GetD3D12Bytecode() instead of GetBytecode() for PSO creation
This commit is contained in:
2026-03-16 12:38:17 +08:00
parent f4d94bda3d
commit 554c48448b
10 changed files with 84 additions and 46 deletions

View File

@@ -5,4 +5,5 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(engine) add_subdirectory(engine)
add_subdirectory(tests/D3D12) add_subdirectory(tests)
add_subdirectory(tests/OpenGL)

View File

@@ -28,11 +28,7 @@ public:
uint32_t GetDescriptorCount() const override; uint32_t GetDescriptorCount() const override;
DescriptorType GetType() const override; DescriptorType GetType() const override;
D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle(uint32_t index) const;
D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandle(uint32_t index) const;
uint32_t GetDescriptorSize() const { return m_descriptorSize; } uint32_t GetDescriptorSize() const { return m_descriptorSize; }
D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandleForHeapStart() const; D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandleForHeapStart() const;
D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandleForHeapStart() const; D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandleForHeapStart() const;

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <d3d12.h> #include <d3d12.h>
#include <dxgi1_4.h>
#include <wrl/client.h> #include <wrl/client.h>
#include <string> #include <string>
#include "../SwapChain.h"
#include "D3D12Enum.h" #include "D3D12Enum.h"
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
@@ -11,7 +13,7 @@ using Microsoft::WRL::ComPtr;
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
class D3D12Shader { class D3D12Shader : public IShader {
public: public:
D3D12Shader(); D3D12Shader();
~D3D12Shader(); ~D3D12Shader();
@@ -20,13 +22,17 @@ public:
bool Compile(const void* sourceData, size_t sourceSize, const char* entryPoint, const char* target); bool Compile(const void* sourceData, size_t sourceSize, const char* entryPoint, const char* target);
void Shutdown(); void Shutdown();
const D3D12_SHADER_BYTECODE GetBytecode() const; const D3D12_SHADER_BYTECODE GetD3D12Bytecode() const;
ShaderType GetType() const { return m_type; } virtual const void* GetBytecode() const override;
virtual size_t GetBytecodeSize() const override;
virtual ShaderType GetType() const override;
virtual const InputLayoutDesc& GetInputLayout() const override;
private: private:
ComPtr<ID3DBlob> m_bytecode; ComPtr<ID3DBlob> m_bytecode;
ComPtr<ID3DBlob> m_error; ComPtr<ID3DBlob> m_error;
ShaderType m_type; ShaderType m_type;
InputLayoutDesc m_inputLayout;
}; };
} // namespace RHI } // namespace RHI

View File

@@ -4,15 +4,16 @@
#include <dxgi1_4.h> #include <dxgi1_4.h>
#include <wrl/client.h> #include <wrl/client.h>
#include "../Enums.h" #include "../SwapChain.h"
#include "D3D12Enum.h" #include "D3D12Enum.h"
#include "D3D12Texture.h"
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
class D3D12SwapChain { class D3D12SwapChain : public ISwapChain {
public: public:
D3D12SwapChain(); D3D12SwapChain();
~D3D12SwapChain(); ~D3D12SwapChain();
@@ -21,10 +22,13 @@ public:
bool Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height); bool Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height);
void Shutdown(); void Shutdown();
uint32_t GetCurrentBackBufferIndex() const; uint32_t GetCurrentBackBufferIndex() const override;
ID3D12Resource* GetBackBuffer(uint32_t index) const; IResource* GetBackBuffer(uint32_t index) const override;
void Present(uint32_t syncInterval, uint32_t flags); void Present(uint32_t syncInterval, uint32_t flags) override;
void Resize(uint32_t width, uint32_t height); void Resize(uint32_t width, uint32_t height) override;
void SetFullscreen(bool fullscreen) override;
bool IsFullscreen() const override;
void* GetNativeHandle() const override;
IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); } IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); }
@@ -35,6 +39,7 @@ private:
uint32_t m_width; uint32_t m_width;
uint32_t m_height; uint32_t m_height;
uint32_t m_bufferCount; uint32_t m_bufferCount;
std::vector<D3D12Texture> m_backBuffers;
}; };
} // namespace RHI } // namespace RHI

View File

@@ -11,8 +11,8 @@ class ISwapChain {
public: public:
virtual ~ISwapChain() = default; virtual ~ISwapChain() = default;
virtual uint32_t GetCurrentBackBufferIndex() = 0; virtual uint32_t GetCurrentBackBufferIndex() const = 0;
virtual IResource* GetBackBuffer(uint32_t index) = 0; virtual IResource* GetBackBuffer(uint32_t index) const = 0;
virtual void Present(uint32_t syncInterval, uint32_t flags) = 0; virtual void Present(uint32_t syncInterval, uint32_t flags) = 0;
virtual void Resize(uint32_t width, uint32_t height) = 0; virtual void Resize(uint32_t width, uint32_t height) = 0;
virtual void SetFullscreen(bool fullscreen) = 0; virtual void SetFullscreen(bool fullscreen) = 0;

View File

@@ -38,18 +38,6 @@ void D3D12DescriptorHeap::Shutdown() {
m_descriptorHeap.Reset(); m_descriptorHeap.Reset();
} }
D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index) const {
D3D12_CPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetCPUDescriptorHandleForHeapStart();
handle.ptr += index * m_descriptorSize;
return handle;
}
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandle(uint32_t index) const {
D3D12_GPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
handle.ptr += index * m_descriptorSize;
return handle;
}
D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart() const { D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart() const {
return m_descriptorHeap->GetCPUDescriptorHandleForHeapStart(); return m_descriptorHeap->GetCPUDescriptorHandleForHeapStart();
} }
@@ -59,15 +47,19 @@ D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapSt
} }
CPUDescriptorHandle D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index) { CPUDescriptorHandle D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index) {
CPUDescriptorHandle handle; D3D12_CPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetCPUDescriptorHandleForHeapStart();
handle.ptr = GetCPUDescriptorHandle(index).ptr; handle.ptr += index * m_descriptorSize;
return handle; CPUDescriptorHandle result;
result.ptr = handle.ptr;
return result;
} }
GPUDescriptorHandle D3D12DescriptorHeap::GetGPUDescriptorHandle(uint32_t index) { GPUDescriptorHandle D3D12DescriptorHeap::GetGPUDescriptorHandle(uint32_t index) {
GPUDescriptorHandle handle; D3D12_GPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
handle.ptr = GetGPUDescriptorHandle(index).ptr; handle.ptr += index * m_descriptorSize;
return handle; GPUDescriptorHandle result;
result.ptr = handle.ptr;
return result;
} }
DescriptorType D3D12DescriptorHeap::GetType() const { DescriptorType D3D12DescriptorHeap::GetType() const {

View File

@@ -57,7 +57,7 @@ void D3D12Shader::Shutdown() {
m_error.Reset(); m_error.Reset();
} }
const D3D12_SHADER_BYTECODE D3D12Shader::GetBytecode() const { const D3D12_SHADER_BYTECODE D3D12Shader::GetD3D12Bytecode() const {
D3D12_SHADER_BYTECODE bytecode = {}; D3D12_SHADER_BYTECODE bytecode = {};
if (m_bytecode) { if (m_bytecode) {
bytecode.pShaderBytecode = m_bytecode->GetBufferPointer(); bytecode.pShaderBytecode = m_bytecode->GetBufferPointer();
@@ -66,5 +66,27 @@ const D3D12_SHADER_BYTECODE D3D12Shader::GetBytecode() const {
return bytecode; return bytecode;
} }
const void* D3D12Shader::GetBytecode() const {
if (m_bytecode) {
return m_bytecode->GetBufferPointer();
}
return nullptr;
}
size_t D3D12Shader::GetBytecodeSize() const {
if (m_bytecode) {
return m_bytecode->GetBufferSize();
}
return 0;
}
const InputLayoutDesc& D3D12Shader::GetInputLayout() const {
return m_inputLayout;
}
ShaderType D3D12Shader::GetType() const {
return m_type;
}
} // namespace RHI } // namespace RHI
} // namespace XCEngine } // namespace XCEngine

View File

@@ -56,6 +56,13 @@ bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint3
m_width = width; m_width = width;
m_height = height; m_height = height;
m_backBuffers.resize(m_bufferCount);
for (uint32_t i = 0; i < m_bufferCount; ++i) {
ID3D12Resource* resource = nullptr;
m_swapChain->GetBuffer(i, IID_PPV_ARGS(&resource));
m_backBuffers[i].InitializeFromExisting(resource);
}
return true; return true;
} }
@@ -67,10 +74,11 @@ uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const {
return m_swapChain->GetCurrentBackBufferIndex(); return m_swapChain->GetCurrentBackBufferIndex();
} }
ID3D12Resource* D3D12SwapChain::GetBackBuffer(uint32_t index) const { IResource* D3D12SwapChain::GetBackBuffer(uint32_t index) const {
ID3D12Resource* resource = nullptr; if (index < m_backBuffers.size()) {
m_swapChain->GetBuffer(index, IID_PPV_ARGS(&resource)); return const_cast<D3D12Texture*>(&m_backBuffers[index]);
return resource; }
return nullptr;
} }
void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) { void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) {
@@ -83,5 +91,19 @@ void D3D12SwapChain::Resize(uint32_t width, uint32_t height) {
m_height = height; m_height = height;
} }
void D3D12SwapChain::SetFullscreen(bool fullscreen) {
m_swapChain->SetFullscreenState(fullscreen, nullptr);
}
bool D3D12SwapChain::IsFullscreen() const {
BOOL fullscreen = FALSE;
m_swapChain->GetFullscreenState(&fullscreen, nullptr);
return fullscreen != FALSE;
}
void* D3D12SwapChain::GetNativeHandle() const {
return reinterpret_cast<void*>(m_swapChain.Get());
}
} // namespace RHI } // namespace RHI
} // namespace XCEngine } // namespace XCEngine

View File

@@ -27,12 +27,6 @@ FetchContent_MakeAvailable(googletest)
enable_testing() enable_testing()
# ============================================================
# Engine Library
# ============================================================
add_subdirectory(../engine engine)
# ============================================================ # ============================================================
# Test Subdirectories # Test Subdirectories
# ============================================================ # ============================================================

View File

@@ -577,7 +577,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
gVertexShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainVS", "vs_5_1"); gVertexShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainVS", "vs_5_1");
gGeometryShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainGS", "gs_5_1"); gGeometryShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainGS", "gs_5_1");
gPixelShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainPS", "ps_5_1"); gPixelShader.CompileFromFile(L"Res/Shader/gs.hlsl", "MainPS", "ps_5_1");
ID3D12PipelineState* pso = CreatePSO(rootSignature, gVertexShader.GetBytecode(), gPixelShader.GetBytecode(), gGeometryShader.GetBytecode()); ID3D12PipelineState* pso = CreatePSO(rootSignature, gVertexShader.GetD3D12Bytecode(), gPixelShader.GetD3D12Bytecode(), gGeometryShader.GetD3D12Bytecode());
gConstantBuffer.Initialize(gD3D12Device.GetDevice(), 65536, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD); gConstantBuffer.Initialize(gD3D12Device.GetDevice(), 65536, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
DirectX::XMMATRIX projectionMatrix = DirectX::XMMatrixPerspectiveFovLH( DirectX::XMMATRIX projectionMatrix = DirectX::XMMatrixPerspectiveFovLH(