RHI: Add explicit RenderPass abstraction (BeginRenderPass/EndRenderPass)
New abstractions: - RHIFramebuffer: Framebuffer interface with Initialize/Bind/GetHandle - RHIRenderPass: RenderPass interface with AttachmentDesc for load/store actions - D3D12Framebuffer/D3D12RenderPass: D3D12 implementation - OpenGLFramebuffer/OpenGLRenderPass: OpenGL implementation (adapted from existing) RHICommandList changes: - Added BeginRenderPass(RHIRenderPass*, RHIFramebuffer*, Rect, clearValues...) - Added EndRenderPass() Implementation notes: - D3D12: Uses OMSetRenderTargets + ClearRenderTargetView (fallback from native RenderPass API) - OpenGL: Uses glBindFramebuffer + glClearBufferfv for LoadOp handling - Old SetRenderTargets/ClearRenderTarget retained for backward compatibility All 845 tests pass.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12RenderPass.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
@@ -245,6 +247,52 @@ void D3D12CommandList::AliasBarrierInternal(ID3D12Resource* beforeResource, ID3D
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
void D3D12CommandList::BeginRenderPass(RHIRenderPass* renderPass, RHIFramebuffer* framebuffer,
|
||||
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) {
|
||||
(void)renderArea;
|
||||
if (!framebuffer || !renderPass) return;
|
||||
|
||||
D3D12Framebuffer* d3d12Framebuffer = static_cast<D3D12Framebuffer*>(framebuffer);
|
||||
|
||||
uint32_t rtCount = d3d12Framebuffer->GetRenderTargetCount();
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE* rtHandles = d3d12Framebuffer->GetRenderTargetHandles();
|
||||
bool hasDS = d3d12Framebuffer->HasDepthStencil();
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsHandle = d3d12Framebuffer->GetDepthStencilHandle();
|
||||
|
||||
D3D12RenderPass* d3d12RenderPass = static_cast<D3D12RenderPass*>(renderPass);
|
||||
const AttachmentDesc* attachments = d3d12RenderPass->GetColorAttachments();
|
||||
|
||||
for (uint32_t i = 0; i < rtCount; ++i) {
|
||||
if (attachments[i].loadOp == LoadAction::Clear && clearValueCount > i) {
|
||||
m_commandList->ClearRenderTargetView(rtHandles[i], &clearValues[i].color.r, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDS) {
|
||||
const AttachmentDesc* dsAttachment = d3d12RenderPass->GetDepthStencilAttachment();
|
||||
if (dsAttachment) {
|
||||
uint32_t clearFlags = 0;
|
||||
if (dsAttachment->loadOp == LoadAction::Clear) clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
|
||||
if (dsAttachment->stencilLoadOp == LoadAction::Clear) clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
||||
if (clearFlags && clearValueCount > rtCount) {
|
||||
m_commandList->ClearDepthStencilView(dsHandle, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), clearValues[rtCount].depth, clearValues[rtCount].stencil, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_commandList->OMSetRenderTargets(rtCount, rtHandles, FALSE, hasDS ? &dsHandle : nullptr);
|
||||
|
||||
m_boundRenderTargets.clear();
|
||||
for (uint32_t i = 0; i < rtCount; ++i) {
|
||||
m_boundRenderTargets.push_back(rtHandles[i]);
|
||||
}
|
||||
m_boundDepthStencil = dsHandle;
|
||||
m_depthStencilBound = hasDS;
|
||||
}
|
||||
|
||||
void D3D12CommandList::EndRenderPass() {
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
||||
m_commandList->SetPipelineState(pso);
|
||||
m_currentPipelineState = pso;
|
||||
|
||||
Reference in New Issue
Block a user