feat: 添加CommandList常量和DSV支持,完善RenderContext
This commit is contained in:
@@ -25,6 +25,9 @@ public:
|
||||
virtual void SetIndexBuffer(IResource* buffer, uint32_t offset = 0) = 0;
|
||||
virtual void SetDescriptorHeap(IDescriptorHeap* heap) = 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 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;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class D3D12DescriptorHeap;
|
||||
|
||||
class RenderContext {
|
||||
public:
|
||||
RenderContext(D3D12Device* device);
|
||||
@@ -19,9 +21,14 @@ public:
|
||||
void EndFrame();
|
||||
|
||||
ICommandList* GetCommandList() { return m_commandList; }
|
||||
ICommandAllocator* GetCommandAllocator() { return m_commandAllocator; }
|
||||
ISwapChain* GetSwapChain() { return m_swapChain; }
|
||||
IRenderTarget* GetCurrentRenderTarget() { return m_currentRenderTarget; }
|
||||
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 SetScissor(int32_t width, int32_t height);
|
||||
@@ -37,6 +44,7 @@ private:
|
||||
ISwapChain* m_swapChain = nullptr;
|
||||
IRenderTarget* m_currentRenderTarget = nullptr;
|
||||
IDepthStencil* m_depthStencil = nullptr;
|
||||
D3D12DescriptorHeap* m_dsvHeap = nullptr;
|
||||
uint64_t m_fenceValue = 0;
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
|
||||
@@ -7,10 +7,12 @@ namespace RHI {
|
||||
|
||||
class D3D12Device;
|
||||
class D3D12SwapChain;
|
||||
class D3D12DescriptorHeap;
|
||||
|
||||
class IDepthStencil : public ITexture2D {
|
||||
public:
|
||||
virtual ~IDepthStencil() = default;
|
||||
virtual void SetDSVHeap(void* heap) = 0;
|
||||
};
|
||||
|
||||
class IRenderTarget : public ITexture2D {
|
||||
|
||||
@@ -751,6 +751,22 @@ void D3D12CommandList::SetGraphicsDescriptorTable(uint32_t rootParameterIndex, u
|
||||
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) {
|
||||
m_commandList->SetComputeRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptor });
|
||||
}
|
||||
|
||||
@@ -159,6 +159,9 @@ public:
|
||||
void SetIndexBuffer(IResource* buffer, uint32_t offset) override;
|
||||
void SetDescriptorHeap(IDescriptorHeap* heap) 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 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;
|
||||
|
||||
@@ -35,10 +35,20 @@ bool RenderContext::Initialize(uint32_t width, uint32_t height) {
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_depthStencil->SetDSVHeap(m_dsvHeap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,16 +66,20 @@ void RenderContext::Shutdown() {
|
||||
}
|
||||
|
||||
void RenderContext::BeginFrame() {
|
||||
EngineLog("BeginFrame: start");
|
||||
|
||||
m_fence->Wait(m_fenceValue);
|
||||
|
||||
m_commandAllocator->Reset();
|
||||
m_commandList->Reset(m_commandAllocator);
|
||||
|
||||
uint32_t bufferIndex = m_swapChain->GetCurrentBufferIndex();
|
||||
EngineLog("BeginFrame: bufferIndex=%u", bufferIndex);
|
||||
|
||||
D3D12CommandList* cmdList = (D3D12CommandList*)m_commandList;
|
||||
ID3D12GraphicsCommandList* d3dCmdList = cmdList->GetNative();
|
||||
|
||||
void* currentRT = m_swapChain->GetCurrentRenderTarget();
|
||||
void* currentDS = m_depthStencil->GetDSV();
|
||||
m_depthStencil->CreateDSV();
|
||||
|
||||
ID3D12Resource* buffer = (ID3D12Resource*)m_swapChain->GetBuffer(bufferIndex);
|
||||
|
||||
@@ -76,6 +90,24 @@ void RenderContext::BeginFrame() {
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
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() {
|
||||
@@ -106,10 +138,6 @@ void RenderContext::EndFrame() {
|
||||
D3D12Fence* d3d12Fence = static_cast<D3D12Fence*>(m_fence);
|
||||
queue->Signal(d3d12Fence->GetNativeFence(), m_fenceValue);
|
||||
EngineLog("EndFrame: after Signal");
|
||||
|
||||
EngineLog("EndFrame: before Wait");
|
||||
m_fence->Wait(m_fenceValue);
|
||||
EngineLog("EndFrame: after Wait");
|
||||
}
|
||||
|
||||
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]) {
|
||||
EngineLog("ClearRT: start");
|
||||
void* rtv = m_swapChain->GetCurrentRenderTarget();
|
||||
void* ds = m_depthStencil->GetDSV();
|
||||
void* targets[] = { rtv };
|
||||
m_commandList->SetRenderTargets(targets, 1, ds);
|
||||
EngineLog("ClearRT: rtv=%p", rtv);
|
||||
m_commandList->ClearRenderTargetView(rtv, color);
|
||||
EngineLog("ClearRT: done");
|
||||
|
||||
@@ -8,14 +8,25 @@ namespace RHI {
|
||||
|
||||
void D3D12DepthStencil::CreateDSV() {
|
||||
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");
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
|
||||
dsvDesc.Format = FormatToDXGIFormat(m_desc.format);
|
||||
EngineLog("CreateDSV: format=%d", dsvDesc.Format);
|
||||
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);
|
||||
EngineLog("CreateDSV: done");
|
||||
EngineLog("CreateDSV: done, handle=%llu", (UINT64)m_dsvHandle.ptr);
|
||||
}
|
||||
|
||||
void D3D12RenderTarget::CreateRTV() {
|
||||
|
||||
@@ -122,6 +122,8 @@ public:
|
||||
void* GetNativeResource() const override { return m_resource.Get(); }
|
||||
ID3D12Resource* GetNative() const { return m_resource.Get(); }
|
||||
|
||||
void SetDSVHeap(void* heap) override { m_dsvHeap = (D3D12DescriptorHeap*)heap; }
|
||||
|
||||
void CreateSRV() override {}
|
||||
void* GetSRV() override { return nullptr; }
|
||||
void CreateRTV() override {}
|
||||
@@ -134,6 +136,7 @@ private:
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> m_resource;
|
||||
TextureDesc m_desc;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE m_dsvHandle = {};
|
||||
D3D12DescriptorHeap* m_dsvHeap = nullptr;
|
||||
};
|
||||
|
||||
class D3D12RenderTarget : public IRenderTarget {
|
||||
|
||||
@@ -70,24 +70,16 @@ bool StaticMeshComponent::Initialize(ICommandList* commandList, const char* file
|
||||
void StaticMeshComponent::Render(ICommandList* commandList) {
|
||||
if (!m_vertexBuffer) return;
|
||||
|
||||
printf("StaticMesh::Render - before SetVertexBuffer\n");
|
||||
commandList->SetVertexBuffer(0, m_vertexBuffer, 0, sizeof(MeshVertex));
|
||||
printf("StaticMesh::Render - after SetVertexBuffer\n");
|
||||
|
||||
if (m_subMeshes.empty()) {
|
||||
printf("StaticMesh::Render - before DrawInstanced\n");
|
||||
commandList->DrawInstanced(m_vertexCount, 1, 0, 0);
|
||||
printf("StaticMesh::Render - after DrawInstanced\n");
|
||||
}
|
||||
else {
|
||||
for (auto& pair : m_subMeshes) {
|
||||
SubMesh* submesh = pair.second;
|
||||
printf("StaticMesh::Render - before SetIndexBuffer\n");
|
||||
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);
|
||||
printf("StaticMesh::Render - after DrawIndexedInstanced\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
run_debug_demo.bat
Normal file
25
run_debug_demo.bat
Normal 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
|
||||
17
run_demo.bat
17
run_demo.bat
@@ -1,3 +1,16 @@
|
||||
@echo off
|
||||
cd /d D:\Xuanchi\高斯泼溅\XCEngine\build\mvs\XCEngineDemo\Debug
|
||||
XCEngineDemo.exe
|
||||
cd /d D:\Xuanchi\高斯泼溅\XCEngine
|
||||
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
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user