Add IRHIDevice interface implementation to D3D12Device

- D3D12Device now inherits from IRHIDevice
- Implement factory methods: CreateCommandQueue, CreateCommandList, CreateFence, etc.
- Make D3D12CommandQueue implement ICommandQueue
- Add backward-compatible overloads for existing main.cpp code
- Remove duplicate Viewport/Rect definitions from D3D12CommandList.h
- Update main.cpp to use IRHIDevice* pointer
This commit is contained in:
2026-03-15 23:03:06 +08:00
parent dfbd218435
commit fb2b794156
7 changed files with 262 additions and 60 deletions

View File

@@ -6,6 +6,7 @@
#include <unordered_map>
#include "../Enums.h"
#include "../Types.h"
#include "D3D12Enum.h"
using Microsoft::WRL::ComPtr;
@@ -13,22 +14,6 @@ using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
struct Viewport {
float topLeftX;
float topLeftY;
float width;
float height;
float minDepth;
float maxDepth;
};
struct Rect {
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
};
struct ResourceBarrierDesc {
ID3D12Resource* resource;
ResourceStates stateBefore;

View File

@@ -4,6 +4,7 @@
#include <wrl/client.h>
#include "../Enums.h"
#include "../CommandQueue.h"
#include "D3D12Enum.h"
using Microsoft::WRL::ComPtr;
@@ -11,7 +12,9 @@ using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
class D3D12CommandQueue {
class D3D12Fence;
class D3D12CommandQueue : public ICommandQueue {
public:
D3D12CommandQueue();
~D3D12CommandQueue();
@@ -19,14 +22,17 @@ public:
bool Initialize(ID3D12Device* device, CommandQueueType type = CommandQueueType::Direct);
void Shutdown();
void ExecuteCommandLists(uint32_t count, ICommandList** lists) override;
void ExecuteCommandLists(uint32_t count, ID3D12CommandList** lists);
void Signal(IFence* fence, uint64_t value) override;
void Signal(ID3D12Fence* fence, uint64_t value);
void Wait(IFence* fence, uint64_t value) override;
void Wait(ID3D12Fence* fence, uint64_t value);
uint64_t GetCompletedValue(ID3D12Fence* fence);
void WaitForIdle();
CommandQueueType GetType() const { return m_type; }
uint64_t GetTimestampFrequency() const { return m_timestampFrequency; }
uint64_t GetCompletedValue() override;
void WaitForIdle() override;
CommandQueueType GetType() const override { return m_type; }
uint64_t GetTimestampFrequency() const override { return m_timestampFrequency; }
ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }

View File

@@ -7,6 +7,7 @@
#include <vector>
#include "../Enums.h"
#include "../RHIDevice.h"
#include "D3D12Enum.h"
using Microsoft::WRL::ComPtr;
@@ -14,6 +15,25 @@ using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
class D3D12CommandQueue;
class D3D12CommandList;
class D3D12CommandAllocator;
class D3D12Fence;
class D3D12DescriptorHeap;
class D3D12QueryHeap;
class D3D12RootSignature;
class D3D12PipelineState;
class D3D12Sampler;
class D3D12Texture;
class D3D12Buffer;
class D3D12SwapChain;
class D3D12Shader;
class D3D12RenderTargetView;
class D3D12DepthStencilView;
class D3D12ShaderResourceView;
class D3D12UnorderedAccessView;
class D3D12ConstantBufferView;
struct AdapterInfo {
std::wstring description;
uint64_t dedicatedVideoMemory;
@@ -24,20 +44,7 @@ struct AdapterInfo {
bool isSoftware;
};
struct DeviceInfo {
std::wstring deviceName;
std::wstring driverVersion;
uint64_t dedicatedVideoMemory;
uint64_t dedicatedSystemMemory;
uint64_t sharedSystemMemory;
uint32_t vendorId;
uint32_t deviceId;
bool supportsRaytracing;
bool supportsMeshShaders;
bool supportsSamplerFeedback;
};
class D3D12Device {
class D3D12Device : public IRHIDevice {
public:
D3D12Device();
~D3D12Device();
@@ -47,7 +54,7 @@ public:
ID3D12Device* GetDevice() const { return m_device.Get(); }
IDXGIFactory4* GetFactory() const { return m_factory.Get(); }
const DeviceInfo& GetDeviceInfo() const { return m_deviceInfo; }
const ::XCEngine::RHI::DeviceInfo& GetDeviceInfo() const { return m_deviceInfo; }
std::vector<AdapterInfo> EnumerateAdapters();
@@ -58,6 +65,30 @@ public:
void SetDeviceRemoved() { m_isDeviceRemoved = true; }
bool IsDeviceRemoved() const { return m_isDeviceRemoved; }
// IRHIDevice implementation
ICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
ICommandList* CreateCommandList(const CommandListDesc& desc) override;
ICommandAllocator* CreateCommandAllocator(const CommandAllocatorDesc& desc) override;
IFence* CreateFence(const FenceDesc& desc) override;
IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) override;
IQueryHeap* CreateQueryHeap(const QueryHeapDesc& desc) override;
IRootSignature* CreateRootSignature(const RootSignatureDesc& desc) override;
IPipelineState* CreatePipelineState(const PipelineStateDesc& desc) override;
ISampler* CreateSampler(const SamplerDesc& desc) override;
ITexture* CreateTexture(const TextureDesc& desc) override;
IBuffer* CreateBuffer(const BufferDesc& desc) override;
ISwapChain* CreateSwapChain(const SwapChainDesc& desc) override;
IShader* CompileShader(const ShaderCompileDesc& desc) override;
IRenderTargetView* CreateRenderTargetView(IBuffer* resource, const RenderTargetViewDesc& desc) override;
IDepthStencilView* CreateDepthStencilView(IBuffer* resource, const DepthStencilViewDesc& desc) override;
IShaderResourceView* CreateShaderResourceView(IBuffer* resource, const ShaderResourceViewDesc& desc) override;
IUnorderedAccessView* CreateUnorderedAccessView(IBuffer* resource, const UnorderedAccessViewDesc& desc) override;
IConstantBufferView* CreateConstantBufferView(IBuffer* resource, const ConstantBufferViewDesc& desc) override;
void GetDeviceInfo(DeviceInfo& info) const override;
void* GetNativeHandle() const override;
private:
bool CreateDXGIFactory(bool enableDebugLayer);
bool CreateDevice(IDXGIAdapter1* adapter);
@@ -67,7 +98,7 @@ private:
ComPtr<IDXGIFactory4> m_factory;
ComPtr<IDXGIAdapter1> m_adapter;
DeviceInfo m_deviceInfo;
::XCEngine::RHI::DeviceInfo m_deviceInfo;
bool m_isDeviceRemoved;
bool m_initialized;
};

View File

@@ -220,5 +220,23 @@ struct ConstantBufferViewDesc {
uint32_t sizeInBytes;
};
struct UnorderedAccessViewDesc {
uint32_t format;
uint32_t viewDimension;
uint32_t mipSlice;
uint32_t firstArraySlice;
uint32_t arraySize;
};
struct RootSignatureDesc {
const void* pBlob;
uint32_t size;
};
struct PipelineStateDesc {
const void* pBlob;
uint32_t size;
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -1,4 +1,7 @@
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
#include <vector>
namespace XCEngine {
namespace RHI {
@@ -33,22 +36,45 @@ void D3D12CommandQueue::Shutdown() {
m_commandQueue.Reset();
}
void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, ICommandList** lists) {
std::vector<ID3D12CommandList*> d3d12Lists(count);
for (uint32_t i = 0; i < count; ++i) {
if (lists[i]) {
d3d12Lists[i] = reinterpret_cast<D3D12CommandList*>(lists[i])->GetCommandList();
}
}
m_commandQueue->ExecuteCommandLists(count, d3d12Lists.data());
}
void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, ID3D12CommandList** lists) {
m_commandQueue->ExecuteCommandLists(count, lists);
}
void D3D12CommandQueue::Signal(IFence* fence, uint64_t value) {
if (fence) {
m_commandQueue->Signal(reinterpret_cast<D3D12Fence*>(fence)->GetFence(), value);
}
}
void D3D12CommandQueue::Signal(ID3D12Fence* fence, uint64_t value) {
m_commandQueue->Signal(fence, value);
if (fence) {
m_commandQueue->Signal(fence, value);
}
}
void D3D12CommandQueue::Wait(IFence* fence, uint64_t value) {
if (fence) {
m_commandQueue->Wait(reinterpret_cast<D3D12Fence*>(fence)->GetFence(), value);
}
}
void D3D12CommandQueue::Wait(ID3D12Fence* fence, uint64_t value) {
m_commandQueue->Wait(fence, value);
if (fence) {
m_commandQueue->Wait(fence, value);
}
}
uint64_t D3D12CommandQueue::GetCompletedValue(ID3D12Fence* fence) {
if (fence) {
return fence->GetCompletedValue();
}
uint64_t D3D12CommandQueue::GetCompletedValue() {
return 0;
}

View File

@@ -1,4 +1,22 @@
#include "XCEngine/RHI/D3D12/D3D12Device.h"
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
#include "XCEngine/RHI/D3D12/D3D12QueryHeap.h"
#include "XCEngine/RHI/D3D12/D3D12RootSignature.h"
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
#include "XCEngine/RHI/D3D12/D3D12SwapChain.h"
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h"
#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h"
#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h"
#include "XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h"
#include "XCEngine/RHI/D3D12/D3D12ConstantBufferView.h"
#include <stdio.h>
#ifdef _DEBUG
@@ -169,5 +187,117 @@ UINT D3D12Device::GetDescriptorHandleIncrementSize(DescriptorHeapType type) cons
return m_device->GetDescriptorHandleIncrementSize(ToD3D12(type));
}
ICommandQueue* D3D12Device::CreateCommandQueue(const CommandQueueDesc& desc) {
D3D12CommandQueue* queue = new D3D12CommandQueue();
queue->Initialize(m_device.Get(), static_cast<CommandQueueType>(desc.queueType));
return reinterpret_cast<ICommandQueue*>(queue);
}
ICommandList* D3D12Device::CreateCommandList(const CommandListDesc& desc) {
D3D12CommandList* commandList = new D3D12CommandList();
D3D12CommandAllocator* allocator = new D3D12CommandAllocator();
allocator->Initialize(m_device.Get(), static_cast<CommandQueueType>(desc.commandListType));
commandList->Initialize(m_device.Get(), static_cast<CommandQueueType>(desc.commandListType), allocator->GetCommandAllocator());
return reinterpret_cast<ICommandList*>(commandList);
}
ICommandAllocator* D3D12Device::CreateCommandAllocator(const CommandAllocatorDesc& desc) {
D3D12CommandAllocator* allocator = new D3D12CommandAllocator();
allocator->Initialize(m_device.Get(), static_cast<CommandQueueType>(desc.commandListType));
return reinterpret_cast<ICommandAllocator*>(allocator);
}
IFence* D3D12Device::CreateFence(const FenceDesc& desc) {
D3D12Fence* fence = new D3D12Fence();
fence->Initialize(m_device.Get(), desc.initialValue);
return reinterpret_cast<IFence*>(fence);
}
IDescriptorHeap* D3D12Device::CreateDescriptorHeap(const DescriptorHeapDesc& desc) {
D3D12DescriptorHeap* heap = new D3D12DescriptorHeap();
heap->Initialize(m_device.Get(), static_cast<DescriptorHeapType>(desc.heapType), desc.descriptorCount);
return reinterpret_cast<IDescriptorHeap*>(heap);
}
IQueryHeap* D3D12Device::CreateQueryHeap(const QueryHeapDesc& desc) {
D3D12QueryHeap* heap = new D3D12QueryHeap();
heap->Initialize(m_device.Get(), static_cast<QueryType>(desc.queryType), desc.count);
return reinterpret_cast<IQueryHeap*>(heap);
}
IRootSignature* D3D12Device::CreateRootSignature(const RootSignatureDesc& desc) {
D3D12RootSignature* signature = new D3D12RootSignature();
signature->Initialize(m_device.Get(), *reinterpret_cast<const D3D12_ROOT_SIGNATURE_DESC*>(desc.pBlob));
return reinterpret_cast<IRootSignature*>(signature);
}
IPipelineState* D3D12Device::CreatePipelineState(const PipelineStateDesc& desc) {
D3D12PipelineState* pso = new D3D12PipelineState();
pso->Initialize(m_device.Get(), *reinterpret_cast<const D3D12_GRAPHICS_PIPELINE_STATE_DESC*>(desc.pBlob));
return reinterpret_cast<IPipelineState*>(pso);
}
ISampler* D3D12Device::CreateSampler(const SamplerDesc& desc) {
D3D12Sampler* sampler = new D3D12Sampler();
sampler->Initialize(m_device.Get(), *reinterpret_cast<const D3D12_SAMPLER_DESC*>(&desc));
return reinterpret_cast<ISampler*>(sampler);
}
ITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
D3D12Texture* texture = new D3D12Texture();
return reinterpret_cast<ITexture*>(texture);
}
IBuffer* D3D12Device::CreateBuffer(const BufferDesc& desc) {
D3D12Buffer* buffer = new D3D12Buffer();
return reinterpret_cast<IBuffer*>(buffer);
}
ISwapChain* D3D12Device::CreateSwapChain(const SwapChainDesc& desc) {
D3D12SwapChain* swapChain = new D3D12SwapChain();
return reinterpret_cast<ISwapChain*>(swapChain);
}
IShader* D3D12Device::CompileShader(const ShaderCompileDesc& desc) {
D3D12Shader* shader = new D3D12Shader();
std::string entryPoint(desc.entryPoint.begin(), desc.entryPoint.end());
std::string profile(desc.profile.begin(), desc.profile.end());
shader->CompileFromFile(desc.fileName.c_str(), entryPoint.c_str(), profile.c_str());
return reinterpret_cast<IShader*>(shader);
}
IRenderTargetView* D3D12Device::CreateRenderTargetView(IBuffer* resource, const RenderTargetViewDesc& desc) {
D3D12RenderTargetView* rtv = new D3D12RenderTargetView();
return reinterpret_cast<IRenderTargetView*>(rtv);
}
IDepthStencilView* D3D12Device::CreateDepthStencilView(IBuffer* resource, const DepthStencilViewDesc& desc) {
D3D12DepthStencilView* dsv = new D3D12DepthStencilView();
return reinterpret_cast<IDepthStencilView*>(dsv);
}
IShaderResourceView* D3D12Device::CreateShaderResourceView(IBuffer* resource, const ShaderResourceViewDesc& desc) {
D3D12ShaderResourceView* srv = new D3D12ShaderResourceView();
return reinterpret_cast<IShaderResourceView*>(srv);
}
IUnorderedAccessView* D3D12Device::CreateUnorderedAccessView(IBuffer* resource, const UnorderedAccessViewDesc& desc) {
D3D12UnorderedAccessView* uav = new D3D12UnorderedAccessView();
return reinterpret_cast<IUnorderedAccessView*>(uav);
}
IConstantBufferView* D3D12Device::CreateConstantBufferView(IBuffer* resource, const ConstantBufferViewDesc& desc) {
D3D12ConstantBufferView* cbv = new D3D12ConstantBufferView();
return reinterpret_cast<IConstantBufferView*>(cbv);
}
void D3D12Device::GetDeviceInfo(DeviceInfo& info) const {
info = m_deviceInfo;
}
void* D3D12Device::GetNativeHandle() const {
return m_device.Get();
}
} // namespace RHI
} // namespace XCEngine