feat: 添加CommandList常量和DSV支持,完善RenderContext

This commit is contained in:
2026-03-15 00:08:03 +08:00
parent ab29013c01
commit 15f42a1af5
12 changed files with 125 additions and 23 deletions

View File

@@ -25,6 +25,9 @@ public:
virtual void SetIndexBuffer(IResource* buffer, uint32_t offset = 0) = 0; virtual void SetIndexBuffer(IResource* buffer, uint32_t offset = 0) = 0;
virtual void SetDescriptorHeap(IDescriptorHeap* heap) = 0; virtual void SetDescriptorHeap(IDescriptorHeap* heap) = 0;
virtual void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0; virtual void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0;
virtual void SetGraphicsRootConstantBufferView(uint32_t slot, IResource* buffer) = 0;
virtual void SetGraphicsRootConstantBufferViewCBV(uint32_t slot, void* nativeResource) = 0;
virtual void SetGraphicsRoot32BitConstants(uint32_t rootParameterIndex, uint32_t num32BitValues, const void* data, uint32_t destOffsetIn32BitValues) = 0;
virtual void SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0; virtual void SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0;
virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) = 0; virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) = 0;
virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) = 0; virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) = 0;

View File

@@ -7,6 +7,8 @@
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
class D3D12DescriptorHeap;
class RenderContext { class RenderContext {
public: public:
RenderContext(D3D12Device* device); RenderContext(D3D12Device* device);
@@ -19,9 +21,14 @@ public:
void EndFrame(); void EndFrame();
ICommandList* GetCommandList() { return m_commandList; } ICommandList* GetCommandList() { return m_commandList; }
ICommandAllocator* GetCommandAllocator() { return m_commandAllocator; }
ISwapChain* GetSwapChain() { return m_swapChain; } ISwapChain* GetSwapChain() { return m_swapChain; }
IRenderTarget* GetCurrentRenderTarget() { return m_currentRenderTarget; } IRenderTarget* GetCurrentRenderTarget() { return m_currentRenderTarget; }
IDepthStencil* GetDepthStencil() { return m_depthStencil; } IDepthStencil* GetDepthStencil() { return m_depthStencil; }
IFence* GetFence() { return m_fence; }
uint64_t GetFenceValue() { return m_fenceValue; }
void IncrementFenceValue() { m_fenceValue++; }
void WaitForCompletionOfCommandList() { m_fence->Wait(m_fenceValue); }
void SetViewport(float width, float height); void SetViewport(float width, float height);
void SetScissor(int32_t width, int32_t height); void SetScissor(int32_t width, int32_t height);
@@ -37,6 +44,7 @@ private:
ISwapChain* m_swapChain = nullptr; ISwapChain* m_swapChain = nullptr;
IRenderTarget* m_currentRenderTarget = nullptr; IRenderTarget* m_currentRenderTarget = nullptr;
IDepthStencil* m_depthStencil = nullptr; IDepthStencil* m_depthStencil = nullptr;
D3D12DescriptorHeap* m_dsvHeap = nullptr;
uint64_t m_fenceValue = 0; uint64_t m_fenceValue = 0;
uint32_t m_width = 0; uint32_t m_width = 0;
uint32_t m_height = 0; uint32_t m_height = 0;

View File

@@ -7,10 +7,12 @@ namespace RHI {
class D3D12Device; class D3D12Device;
class D3D12SwapChain; class D3D12SwapChain;
class D3D12DescriptorHeap;
class IDepthStencil : public ITexture2D { class IDepthStencil : public ITexture2D {
public: public:
virtual ~IDepthStencil() = default; virtual ~IDepthStencil() = default;
virtual void SetDSVHeap(void* heap) = 0;
}; };
class IRenderTarget : public ITexture2D { class IRenderTarget : public ITexture2D {

View File

@@ -751,6 +751,22 @@ void D3D12CommandList::SetGraphicsDescriptorTable(uint32_t rootParameterIndex, u
m_commandList->SetGraphicsRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptor }); m_commandList->SetGraphicsRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptor });
} }
void D3D12CommandList::SetGraphicsRootConstantBufferView(uint32_t slot, IResource* buffer) {
if (buffer) {
D3D12Resource* d3dBuffer = static_cast<D3D12Resource*>(buffer);
m_commandList->SetGraphicsRootConstantBufferView(slot, d3dBuffer->GetNative()->GetGPUVirtualAddress());
}
}
void D3D12CommandList::SetGraphicsRootConstantBufferViewCBV(uint32_t slot, void* nativeResource) {
ID3D12Resource* resource = static_cast<ID3D12Resource*>(nativeResource);
m_commandList->SetGraphicsRootConstantBufferView(slot, resource->GetGPUVirtualAddress());
}
void D3D12CommandList::SetGraphicsRoot32BitConstants(uint32_t rootParameterIndex, uint32_t num32BitValues, const void* data, uint32_t destOffsetIn32BitValues) {
m_commandList->SetGraphicsRoot32BitConstants(rootParameterIndex, num32BitValues, data, destOffsetIn32BitValues);
}
void D3D12CommandList::SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) { void D3D12CommandList::SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) {
m_commandList->SetComputeRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptor }); m_commandList->SetComputeRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptor });
} }

View File

@@ -159,6 +159,9 @@ public:
void SetIndexBuffer(IResource* buffer, uint32_t offset) override; void SetIndexBuffer(IResource* buffer, uint32_t offset) override;
void SetDescriptorHeap(IDescriptorHeap* heap) override; void SetDescriptorHeap(IDescriptorHeap* heap) override;
void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) override; void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) override;
void SetGraphicsRootConstantBufferView(uint32_t slot, IResource* buffer) override;
void SetGraphicsRootConstantBufferViewCBV(uint32_t slot, void* nativeResource) override;
void SetGraphicsRoot32BitConstants(uint32_t rootParameterIndex, uint32_t num32BitValues, const void* data, uint32_t destOffsetIn32BitValues) override;
void SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) override; void SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) override;
void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) override; void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) override;
void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) override; void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) override;

View File

@@ -35,10 +35,20 @@ bool RenderContext::Initialize(uint32_t width, uint32_t height) {
return false; return false;
} }
DescriptorHeapDesc dsvHeapDesc = {};
dsvHeapDesc.type = DescriptorHeapType::DSV;
dsvHeapDesc.count = 1;
dsvHeapDesc.shaderVisible = false;
if (!m_device->CreateDescriptorHeap((IDescriptorHeap**)&m_dsvHeap, dsvHeapDesc)) {
return false;
}
if (!CreateDepthStencil(m_device, width, height, Format::D24_UNorm_S8_UInt, &m_depthStencil)) { if (!CreateDepthStencil(m_device, width, height, Format::D24_UNorm_S8_UInt, &m_depthStencil)) {
return false; return false;
} }
m_depthStencil->SetDSVHeap(m_dsvHeap);
return true; return true;
} }
@@ -56,16 +66,20 @@ void RenderContext::Shutdown() {
} }
void RenderContext::BeginFrame() { void RenderContext::BeginFrame() {
EngineLog("BeginFrame: start");
m_fence->Wait(m_fenceValue);
m_commandAllocator->Reset(); m_commandAllocator->Reset();
m_commandList->Reset(m_commandAllocator); m_commandList->Reset(m_commandAllocator);
uint32_t bufferIndex = m_swapChain->GetCurrentBufferIndex(); uint32_t bufferIndex = m_swapChain->GetCurrentBufferIndex();
EngineLog("BeginFrame: bufferIndex=%u", bufferIndex);
D3D12CommandList* cmdList = (D3D12CommandList*)m_commandList; D3D12CommandList* cmdList = (D3D12CommandList*)m_commandList;
ID3D12GraphicsCommandList* d3dCmdList = cmdList->GetNative(); ID3D12GraphicsCommandList* d3dCmdList = cmdList->GetNative();
void* currentRT = m_swapChain->GetCurrentRenderTarget(); m_depthStencil->CreateDSV();
void* currentDS = m_depthStencil->GetDSV();
ID3D12Resource* buffer = (ID3D12Resource*)m_swapChain->GetBuffer(bufferIndex); ID3D12Resource* buffer = (ID3D12Resource*)m_swapChain->GetBuffer(bufferIndex);
@@ -76,6 +90,24 @@ void RenderContext::BeginFrame() {
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
d3dCmdList->ResourceBarrier(1, &barrier); d3dCmdList->ResourceBarrier(1, &barrier);
EngineLog("BeginFrame: after ResourceBarrier");
void* currentRT = m_swapChain->GetCurrentRenderTarget();
void* currentDS = m_depthStencil->GetDSV();
EngineLog("BeginFrame: RTV=%llu, DSV=%llu", (UINT64)currentRT, (UINT64)currentDS);
void* targets[] = { currentRT };
m_commandList->SetRenderTargets(targets, 1, currentDS);
EngineLog("BeginFrame: after SetRenderTargets");
float clearColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
m_commandList->ClearRenderTargetView(currentRT, clearColor);
EngineLog("BeginFrame: after ClearRenderTargetView");
m_commandList->ClearDepthStencilView(currentDS, 1.0f, 0);
EngineLog("BeginFrame: after ClearDepthStencilView");
EngineLog("BeginFrame: done");
} }
void RenderContext::EndFrame() { void RenderContext::EndFrame() {
@@ -106,10 +138,6 @@ void RenderContext::EndFrame() {
D3D12Fence* d3d12Fence = static_cast<D3D12Fence*>(m_fence); D3D12Fence* d3d12Fence = static_cast<D3D12Fence*>(m_fence);
queue->Signal(d3d12Fence->GetNativeFence(), m_fenceValue); queue->Signal(d3d12Fence->GetNativeFence(), m_fenceValue);
EngineLog("EndFrame: after Signal"); EngineLog("EndFrame: after Signal");
EngineLog("EndFrame: before Wait");
m_fence->Wait(m_fenceValue);
EngineLog("EndFrame: after Wait");
} }
void RenderContext::SetViewport(float width, float height) { void RenderContext::SetViewport(float width, float height) {
@@ -139,6 +167,9 @@ void RenderContext::SetScissor(int32_t width, int32_t height) {
void RenderContext::ClearRenderTarget(const float color[4]) { void RenderContext::ClearRenderTarget(const float color[4]) {
EngineLog("ClearRT: start"); EngineLog("ClearRT: start");
void* rtv = m_swapChain->GetCurrentRenderTarget(); void* rtv = m_swapChain->GetCurrentRenderTarget();
void* ds = m_depthStencil->GetDSV();
void* targets[] = { rtv };
m_commandList->SetRenderTargets(targets, 1, ds);
EngineLog("ClearRT: rtv=%p", rtv); EngineLog("ClearRT: rtv=%p", rtv);
m_commandList->ClearRenderTargetView(rtv, color); m_commandList->ClearRenderTargetView(rtv, color);
EngineLog("ClearRT: done"); EngineLog("ClearRT: done");

View File

@@ -8,14 +8,25 @@ namespace RHI {
void D3D12DepthStencil::CreateDSV() { void D3D12DepthStencil::CreateDSV() {
EngineLog("CreateDSV: start, m_device=%p, m_resource=%p", m_device, m_resource.Get()); EngineLog("CreateDSV: start, m_device=%p, m_resource=%p", m_device, m_resource.Get());
if (m_dsvHandle.ptr != 0) return; if (m_dsvHandle.ptr != 0) {
EngineLog("CreateDSV: already created");
return;
}
if (!m_dsvHeap) {
EngineLog("CreateDSV: ERROR - no DSV heap!");
return;
}
EngineLog("CreateDSV: calling CreateDepthStencilView"); EngineLog("CreateDSV: calling CreateDepthStencilView");
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = FormatToDXGIFormat(m_desc.format); dsvDesc.Format = FormatToDXGIFormat(m_desc.format);
EngineLog("CreateDSV: format=%d", dsvDesc.Format); EngineLog("CreateDSV: format=%d", dsvDesc.Format);
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
D3D12_CPU_DESCRIPTOR_HANDLE heapStart = m_dsvHeap->GetNativeHeap()->GetCPUDescriptorHandleForHeapStart();
m_dsvHandle = heapStart;
m_device->GetD3D12Device()->CreateDepthStencilView(m_resource.Get(), &dsvDesc, m_dsvHandle); m_device->GetD3D12Device()->CreateDepthStencilView(m_resource.Get(), &dsvDesc, m_dsvHandle);
EngineLog("CreateDSV: done"); EngineLog("CreateDSV: done, handle=%llu", (UINT64)m_dsvHandle.ptr);
} }
void D3D12RenderTarget::CreateRTV() { void D3D12RenderTarget::CreateRTV() {

View File

@@ -122,6 +122,8 @@ public:
void* GetNativeResource() const override { return m_resource.Get(); } void* GetNativeResource() const override { return m_resource.Get(); }
ID3D12Resource* GetNative() const { return m_resource.Get(); } ID3D12Resource* GetNative() const { return m_resource.Get(); }
void SetDSVHeap(void* heap) override { m_dsvHeap = (D3D12DescriptorHeap*)heap; }
void CreateSRV() override {} void CreateSRV() override {}
void* GetSRV() override { return nullptr; } void* GetSRV() override { return nullptr; }
void CreateRTV() override {} void CreateRTV() override {}
@@ -134,6 +136,7 @@ private:
Microsoft::WRL::ComPtr<ID3D12Resource> m_resource; Microsoft::WRL::ComPtr<ID3D12Resource> m_resource;
TextureDesc m_desc; TextureDesc m_desc;
D3D12_CPU_DESCRIPTOR_HANDLE m_dsvHandle = {}; D3D12_CPU_DESCRIPTOR_HANDLE m_dsvHandle = {};
D3D12DescriptorHeap* m_dsvHeap = nullptr;
}; };
class D3D12RenderTarget : public IRenderTarget { class D3D12RenderTarget : public IRenderTarget {

View File

@@ -70,24 +70,16 @@ bool StaticMeshComponent::Initialize(ICommandList* commandList, const char* file
void StaticMeshComponent::Render(ICommandList* commandList) { void StaticMeshComponent::Render(ICommandList* commandList) {
if (!m_vertexBuffer) return; if (!m_vertexBuffer) return;
printf("StaticMesh::Render - before SetVertexBuffer\n");
commandList->SetVertexBuffer(0, m_vertexBuffer, 0, sizeof(MeshVertex)); commandList->SetVertexBuffer(0, m_vertexBuffer, 0, sizeof(MeshVertex));
printf("StaticMesh::Render - after SetVertexBuffer\n");
if (m_subMeshes.empty()) { if (m_subMeshes.empty()) {
printf("StaticMesh::Render - before DrawInstanced\n");
commandList->DrawInstanced(m_vertexCount, 1, 0, 0); commandList->DrawInstanced(m_vertexCount, 1, 0, 0);
printf("StaticMesh::Render - after DrawInstanced\n");
} }
else { else {
for (auto& pair : m_subMeshes) { for (auto& pair : m_subMeshes) {
SubMesh* submesh = pair.second; SubMesh* submesh = pair.second;
printf("StaticMesh::Render - before SetIndexBuffer\n");
commandList->SetIndexBuffer(submesh->indexBuffer, 0); commandList->SetIndexBuffer(submesh->indexBuffer, 0);
printf("StaticMesh::Render - after SetIndexBuffer\n");
printf("StaticMesh::Render - before DrawIndexedInstanced\n");
commandList->DrawIndexedInstanced(submesh->indexCount, 1, 0, 0, 0); commandList->DrawIndexedInstanced(submesh->indexCount, 1, 0, 0, 0);
printf("StaticMesh::Render - after DrawIndexedInstanced\n");
} }
} }
} }

25
run_debug_demo.bat Normal file
View File

@@ -0,0 +1,25 @@
@echo off
cd /d D:\Xuanchi\高斯泼溅\XCEngine
echo Starting XCEngineDemo...
echo Current directory: %CD%
echo.
echo Running Debug version...
build\mvs\XCEngineDemo\Debug\XCEngineDemo.exe
echo.
echo Program exited with code: %ERRORLEVEL%
echo.
echo Checking log files...
if exist D:\xcengine_debug.log (
echo === D:\xcengine_debug.log (first 100 lines) ===
type D:\xcengine_debug.log | more +1
) else (
echo D:\xcengine_debug.log not found
)
echo.
if exist D:\XCEngineDemo_main.log (
echo === D:\XCEngineDemo_main.log ===
type D:\XCEngineDemo_main.log
) else (
echo D:\XCEngineDemo_main.log not found
)
pause

View File

@@ -1,3 +1,16 @@
@echo off @echo off
cd /d D:\Xuanchi\高斯泼溅\XCEngine\build\mvs\XCEngineDemo\Debug cd /d D:\Xuanchi\高斯泼溅\XCEngine
XCEngineDemo.exe echo Starting XCEngineDemo...
echo Current directory: %CD%
echo.
build\mvs\XCEngineDemo\Debug\XCEngineDemo.exe
echo.
echo Program exited with code: %ERRORLEVEL%
echo.
if exist XCEngineDemo.log (
echo === Log file contents ===
type XCEngineDemo.log
) else (
echo No log file found
)
pause

View File

@@ -1,5 +0,0 @@
$proc = Start-Process -FilePath 'D:\Xuanchi\高斯泼溅\XCEngine\build\mvs\XCEngineDemo\Debug\XCEngineDemo.exe' -PassThru
Start-Sleep -Seconds 5
if (!$proc.HasExited) {
Stop-Process -Id $proc.Id -Force
}