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:
@@ -19,6 +19,8 @@ class RHIPipelineState;
|
|||||||
class D3D12ResourceView;
|
class D3D12ResourceView;
|
||||||
class D3D12Shader;
|
class D3D12Shader;
|
||||||
class D3D12PipelineLayout;
|
class D3D12PipelineLayout;
|
||||||
|
class D3D12RenderPass;
|
||||||
|
class D3D12Framebuffer;
|
||||||
|
|
||||||
class D3D12CommandList : public RHICommandList {
|
class D3D12CommandList : public RHICommandList {
|
||||||
public:
|
public:
|
||||||
@@ -56,6 +58,10 @@ public:
|
|||||||
void AliasBarrier(ID3D12Resource* beforeResource = nullptr, ID3D12Resource* afterResource = nullptr);
|
void AliasBarrier(ID3D12Resource* beforeResource = nullptr, ID3D12Resource* afterResource = nullptr);
|
||||||
void AliasBarrierInternal(ID3D12Resource* beforeResource, ID3D12Resource* afterResource);
|
void AliasBarrierInternal(ID3D12Resource* beforeResource, ID3D12Resource* afterResource);
|
||||||
|
|
||||||
|
void BeginRenderPass(class RHIRenderPass* renderPass, class RHIFramebuffer* framebuffer,
|
||||||
|
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) override;
|
||||||
|
void EndRenderPass() override;
|
||||||
|
|
||||||
void SetPipelineState(RHIPipelineState* pso) override;
|
void SetPipelineState(RHIPipelineState* pso) override;
|
||||||
void SetPipelineState(ID3D12PipelineState* pso);
|
void SetPipelineState(ID3D12PipelineState* pso);
|
||||||
void SetPipelineStateInternal(ID3D12PipelineState* pso);
|
void SetPipelineStateInternal(ID3D12PipelineState* pso);
|
||||||
|
|||||||
52
engine/include/XCEngine/RHI/D3D12/D3D12Framebuffer.h
Normal file
52
engine/include/XCEngine/RHI/D3D12/D3D12Framebuffer.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <wrl/client.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../RHIFramebuffer.h"
|
||||||
|
#include "../RHIRenderPass.h"
|
||||||
|
|
||||||
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class D3D12ResourceView;
|
||||||
|
class D3D12DescriptorHeap;
|
||||||
|
class D3D12RenderPass;
|
||||||
|
|
||||||
|
class D3D12Framebuffer : public RHIFramebuffer {
|
||||||
|
public:
|
||||||
|
D3D12Framebuffer();
|
||||||
|
~D3D12Framebuffer() override;
|
||||||
|
|
||||||
|
void Shutdown() override;
|
||||||
|
|
||||||
|
bool Initialize(D3D12RenderPass* renderPass, uint32_t width, uint32_t height,
|
||||||
|
uint32_t colorAttachmentCount, RHIResourceView** colorAttachments,
|
||||||
|
RHIResourceView* depthStencilAttachment);
|
||||||
|
|
||||||
|
void* GetNativeHandle() override { return nullptr; }
|
||||||
|
uint32_t GetWidth() const override { return m_width; }
|
||||||
|
uint32_t GetHeight() const override { return m_height; }
|
||||||
|
bool IsValid() const override { return m_renderPass != nullptr; }
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetHandle(uint32_t index) const;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE GetDepthStencilHandle() const { return m_depthStencilHandle; }
|
||||||
|
bool HasDepthStencil() const { return m_depthStencilHandle.ptr != 0; }
|
||||||
|
uint32_t GetRenderTargetCount() const { return static_cast<uint32_t>(m_renderTargetHandles.size()); }
|
||||||
|
const D3D12_CPU_DESCRIPTOR_HANDLE* GetRenderTargetHandles() const { return m_renderTargetHandles.data(); }
|
||||||
|
|
||||||
|
D3D12RenderPass* GetRenderPass() const { return m_renderPass; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_width = 0;
|
||||||
|
uint32_t m_height = 0;
|
||||||
|
D3D12RenderPass* m_renderPass = nullptr;
|
||||||
|
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> m_renderTargetHandles;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE m_depthStencilHandle = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
44
engine/include/XCEngine/RHI/D3D12/D3D12RenderPass.h
Normal file
44
engine/include/XCEngine/RHI/D3D12/D3D12RenderPass.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <wrl/client.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../RHIRenderPass.h"
|
||||||
|
|
||||||
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class D3D12Framebuffer;
|
||||||
|
|
||||||
|
class D3D12RenderPass : public RHIRenderPass {
|
||||||
|
public:
|
||||||
|
D3D12RenderPass();
|
||||||
|
~D3D12RenderPass() override;
|
||||||
|
|
||||||
|
void Shutdown() override;
|
||||||
|
|
||||||
|
bool Initialize(uint32_t colorAttachmentCount, const AttachmentDesc* colorAttachments,
|
||||||
|
const AttachmentDesc* depthStencilAttachment) override;
|
||||||
|
|
||||||
|
uint32_t GetColorAttachmentCount() const override { return m_colorAttachmentCount; }
|
||||||
|
const AttachmentDesc* GetColorAttachments() const override { return m_colorAttachments.data(); }
|
||||||
|
const AttachmentDesc* GetDepthStencilAttachment() const override { return m_hasDepthStencil ? &m_depthStencilAttachment : nullptr; }
|
||||||
|
void* GetNativeHandle() override { return nullptr; }
|
||||||
|
|
||||||
|
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE GetBeginningAccessType(uint32_t index) const;
|
||||||
|
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE GetEndingAccessType(uint32_t index) const;
|
||||||
|
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE GetDepthBeginningAccessType() const;
|
||||||
|
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE GetDepthEndingAccessType() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_colorAttachmentCount = 0;
|
||||||
|
std::vector<AttachmentDesc> m_colorAttachments;
|
||||||
|
AttachmentDesc m_depthStencilAttachment;
|
||||||
|
bool m_hasDepthStencil = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -172,6 +172,9 @@ public:
|
|||||||
void PopDebugGroup();
|
void PopDebugGroup();
|
||||||
|
|
||||||
void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override;
|
void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override;
|
||||||
|
void BeginRenderPass(class RHIRenderPass* renderPass, class RHIFramebuffer* framebuffer,
|
||||||
|
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) override;
|
||||||
|
void EndRenderPass() override;
|
||||||
void SetPrimitiveTopology(PrimitiveTopology topology) override;
|
void SetPrimitiveTopology(PrimitiveTopology topology) override;
|
||||||
void SetViewport(const Viewport& viewport) override;
|
void SetViewport(const Viewport& viewport) override;
|
||||||
void SetViewports(uint32_t count, const Viewport* viewports) override;
|
void SetViewports(uint32_t count, const Viewport* viewports) override;
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../RHIFramebuffer.h"
|
||||||
|
#include "../RHIResourceView.h"
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
@@ -30,13 +33,21 @@ struct FramebufferDesc {
|
|||||||
FramebufferAttachment stencilAttachment;
|
FramebufferAttachment stencilAttachment;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenGLFramebuffer {
|
class OpenGLFramebuffer : public RHIFramebuffer {
|
||||||
public:
|
public:
|
||||||
OpenGLFramebuffer();
|
OpenGLFramebuffer();
|
||||||
~OpenGLFramebuffer();
|
~OpenGLFramebuffer() override;
|
||||||
|
|
||||||
bool Initialize(const FramebufferDesc& desc);
|
bool Initialize(const FramebufferDesc& desc);
|
||||||
void Shutdown();
|
void Shutdown() override;
|
||||||
|
|
||||||
|
bool Initialize(class RHIRenderPass* renderPass, uint32_t width, uint32_t height,
|
||||||
|
uint32_t colorAttachmentCount, RHIResourceView** colorAttachments,
|
||||||
|
RHIResourceView* depthStencilAttachment) override;
|
||||||
|
void* GetNativeHandle() override { return reinterpret_cast<void*>(m_framebuffer); }
|
||||||
|
uint32_t GetWidth() const override { return static_cast<uint32_t>(m_width); }
|
||||||
|
uint32_t GetHeight() const override { return static_cast<uint32_t>(m_height); }
|
||||||
|
bool IsValid() const override { return m_framebuffer != 0; }
|
||||||
|
|
||||||
void Bind();
|
void Bind();
|
||||||
void Unbind();
|
void Unbind();
|
||||||
@@ -47,9 +58,6 @@ public:
|
|||||||
void ClearDepthStencil(float depth, uint8_t stencil);
|
void ClearDepthStencil(float depth, uint8_t stencil);
|
||||||
|
|
||||||
unsigned int GetFramebuffer() const { return m_framebuffer; }
|
unsigned int GetFramebuffer() const { return m_framebuffer; }
|
||||||
int GetWidth() const { return m_width; }
|
|
||||||
int GetHeight() const { return m_height; }
|
|
||||||
bool IsValid() const { return m_framebuffer != 0; }
|
|
||||||
|
|
||||||
static void BindFramebuffer(unsigned int framebuffer);
|
static void BindFramebuffer(unsigned int framebuffer);
|
||||||
static void UnbindFramebuffer();
|
static void UnbindFramebuffer();
|
||||||
|
|||||||
35
engine/include/XCEngine/RHI/OpenGL/OpenGLRenderPass.h
Normal file
35
engine/include/XCEngine/RHI/OpenGL/OpenGLRenderPass.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../RHIRenderPass.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class OpenGLFramebuffer;
|
||||||
|
|
||||||
|
class OpenGLRenderPass : public RHIRenderPass {
|
||||||
|
public:
|
||||||
|
OpenGLRenderPass();
|
||||||
|
~OpenGLRenderPass() override;
|
||||||
|
|
||||||
|
void Shutdown() override;
|
||||||
|
|
||||||
|
bool Initialize(uint32_t colorAttachmentCount, const AttachmentDesc* colorAttachments,
|
||||||
|
const AttachmentDesc* depthStencilAttachment) override;
|
||||||
|
|
||||||
|
uint32_t GetColorAttachmentCount() const override { return m_colorAttachmentCount; }
|
||||||
|
const AttachmentDesc* GetColorAttachments() const override { return m_colorAttachments.data(); }
|
||||||
|
const AttachmentDesc* GetDepthStencilAttachment() const override { return m_hasDepthStencil ? &m_depthStencilAttachment : nullptr; }
|
||||||
|
void* GetNativeHandle() override { return nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_colorAttachmentCount = 0;
|
||||||
|
std::vector<AttachmentDesc> m_colorAttachments;
|
||||||
|
AttachmentDesc m_depthStencilAttachment;
|
||||||
|
bool m_hasDepthStencil = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -56,6 +56,10 @@ public:
|
|||||||
|
|
||||||
virtual void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0;
|
virtual void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0;
|
||||||
|
|
||||||
|
virtual void BeginRenderPass(class RHIRenderPass* renderPass, class RHIFramebuffer* framebuffer,
|
||||||
|
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) = 0;
|
||||||
|
virtual void EndRenderPass() = 0;
|
||||||
|
|
||||||
virtual void SetShader(RHIShader* shader) = 0;
|
virtual void SetShader(RHIShader* shader) = 0;
|
||||||
|
|
||||||
virtual void SetUniformInt(const char* name, int value) = 0;
|
virtual void SetUniformInt(const char* name, int value) = 0;
|
||||||
|
|||||||
28
engine/include/XCEngine/RHI/RHIFramebuffer.h
Normal file
28
engine/include/XCEngine/RHI/RHIFramebuffer.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RHITypes.h"
|
||||||
|
#include "RHIEnums.h"
|
||||||
|
#include "RHIResourceView.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class RHIFramebuffer {
|
||||||
|
public:
|
||||||
|
virtual ~RHIFramebuffer() = default;
|
||||||
|
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
virtual bool Initialize(class RHIRenderPass* renderPass, uint32_t width, uint32_t height,
|
||||||
|
uint32_t colorAttachmentCount, RHIResourceView** colorAttachments,
|
||||||
|
RHIResourceView* depthStencilAttachment) = 0;
|
||||||
|
|
||||||
|
virtual void* GetNativeHandle() = 0;
|
||||||
|
virtual uint32_t GetWidth() const = 0;
|
||||||
|
virtual uint32_t GetHeight() const = 0;
|
||||||
|
virtual bool IsValid() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
35
engine/include/XCEngine/RHI/RHIRenderPass.h
Normal file
35
engine/include/XCEngine/RHI/RHIRenderPass.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RHITypes.h"
|
||||||
|
#include "RHIEnums.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
struct AttachmentDesc {
|
||||||
|
Format format = Format::Unknown;
|
||||||
|
LoadAction loadOp = LoadAction::Undefined;
|
||||||
|
StoreAction storeOp = StoreAction::Store;
|
||||||
|
LoadAction stencilLoadOp = LoadAction::Undefined;
|
||||||
|
StoreAction stencilStoreOp = StoreAction::Undefined;
|
||||||
|
ClearValue clearValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RHIRenderPass {
|
||||||
|
public:
|
||||||
|
virtual ~RHIRenderPass() = default;
|
||||||
|
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
virtual bool Initialize(uint32_t colorAttachmentCount, const AttachmentDesc* colorAttachments,
|
||||||
|
const AttachmentDesc* depthStencilAttachment) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t GetColorAttachmentCount() const = 0;
|
||||||
|
virtual const AttachmentDesc* GetColorAttachments() const = 0;
|
||||||
|
virtual const AttachmentDesc* GetDepthStencilAttachment() const = 0;
|
||||||
|
virtual void* GetNativeHandle() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12RenderPass.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
@@ -245,6 +247,52 @@ void D3D12CommandList::AliasBarrierInternal(ID3D12Resource* beforeResource, ID3D
|
|||||||
m_commandList->ResourceBarrier(1, &barrier);
|
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) {
|
void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
||||||
m_commandList->SetPipelineState(pso);
|
m_commandList->SetPipelineState(pso);
|
||||||
m_currentPipelineState = pso;
|
m_currentPipelineState = pso;
|
||||||
|
|||||||
56
engine/src/RHI/D3D12/D3D12Framebuffer.cpp
Normal file
56
engine/src/RHI/D3D12/D3D12Framebuffer.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12RenderPass.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
D3D12Framebuffer::D3D12Framebuffer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12Framebuffer::~D3D12Framebuffer() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12Framebuffer::Shutdown() {
|
||||||
|
m_renderTargetHandles.clear();
|
||||||
|
m_depthStencilHandle = {};
|
||||||
|
m_renderPass = nullptr;
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool D3D12Framebuffer::Initialize(D3D12RenderPass* renderPass, uint32_t width, uint32_t height,
|
||||||
|
uint32_t colorAttachmentCount, RHIResourceView** colorAttachments,
|
||||||
|
RHIResourceView* depthStencilAttachment) {
|
||||||
|
m_renderPass = renderPass;
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
|
||||||
|
m_renderTargetHandles.resize(colorAttachmentCount);
|
||||||
|
for (uint32_t i = 0; i < colorAttachmentCount; ++i) {
|
||||||
|
if (colorAttachments[i]) {
|
||||||
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(colorAttachments[i]);
|
||||||
|
m_renderTargetHandles[i] = view->GetCPUHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilAttachment) {
|
||||||
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(depthStencilAttachment);
|
||||||
|
m_depthStencilHandle = view->GetCPUHandle();
|
||||||
|
} else {
|
||||||
|
m_depthStencilHandle = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE D3D12Framebuffer::GetRenderTargetHandle(uint32_t index) const {
|
||||||
|
if (index >= m_renderTargetHandles.size()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return m_renderTargetHandles[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
103
engine/src/RHI/D3D12/D3D12RenderPass.cpp
Normal file
103
engine/src/RHI/D3D12/D3D12RenderPass.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include "XCEngine/RHI/D3D12/D3D12RenderPass.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
D3D12RenderPass::D3D12RenderPass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12RenderPass::~D3D12RenderPass() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12RenderPass::Shutdown() {
|
||||||
|
m_colorAttachments.clear();
|
||||||
|
m_colorAttachmentCount = 0;
|
||||||
|
m_hasDepthStencil = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool D3D12RenderPass::Initialize(uint32_t colorAttachmentCount, const AttachmentDesc* colorAttachments,
|
||||||
|
const AttachmentDesc* depthStencilAttachment) {
|
||||||
|
m_colorAttachmentCount = colorAttachmentCount;
|
||||||
|
m_colorAttachments.resize(colorAttachmentCount);
|
||||||
|
for (uint32_t i = 0; i < colorAttachmentCount; ++i) {
|
||||||
|
m_colorAttachments[i] = colorAttachments[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilAttachment != nullptr) {
|
||||||
|
m_hasDepthStencil = true;
|
||||||
|
m_depthStencilAttachment = *depthStencilAttachment;
|
||||||
|
} else {
|
||||||
|
m_hasDepthStencil = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE D3D12RenderPass::GetBeginningAccessType(uint32_t index) const {
|
||||||
|
if (index >= m_colorAttachmentCount) {
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
switch (m_colorAttachments[index].loadOp) {
|
||||||
|
case LoadAction::Clear:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR;
|
||||||
|
case LoadAction::Load:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE;
|
||||||
|
case LoadAction::Undefined:
|
||||||
|
default:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE D3D12RenderPass::GetEndingAccessType(uint32_t index) const {
|
||||||
|
if (index >= m_colorAttachmentCount) {
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
switch (m_colorAttachments[index].storeOp) {
|
||||||
|
case StoreAction::Store:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE;
|
||||||
|
case StoreAction::Discard:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD;
|
||||||
|
case StoreAction::Resolve:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE;
|
||||||
|
case StoreAction::StoreAndResolve:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_STORE_AND_RESOLVE;
|
||||||
|
case StoreAction::Undefined:
|
||||||
|
default:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE D3D12RenderPass::GetDepthBeginningAccessType() const {
|
||||||
|
if (!m_hasDepthStencil) {
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
switch (m_depthStencilAttachment.loadOp) {
|
||||||
|
case LoadAction::Clear:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR;
|
||||||
|
case LoadAction::Load:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE;
|
||||||
|
case LoadAction::Undefined:
|
||||||
|
default:
|
||||||
|
return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE::D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE D3D12RenderPass::GetDepthEndingAccessType() const {
|
||||||
|
if (!m_hasDepthStencil) {
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
switch (m_depthStencilAttachment.storeOp) {
|
||||||
|
case StoreAction::Store:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE;
|
||||||
|
case StoreAction::Discard:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD;
|
||||||
|
case StoreAction::Undefined:
|
||||||
|
default:
|
||||||
|
return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE::D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLRenderPass.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -508,6 +510,45 @@ void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceSta
|
|||||||
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::BeginRenderPass(RHIRenderPass* renderPass, RHIFramebuffer* framebuffer,
|
||||||
|
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) {
|
||||||
|
(void)renderArea;
|
||||||
|
(void)clearValueCount;
|
||||||
|
(void)clearValues;
|
||||||
|
|
||||||
|
if (!framebuffer) return;
|
||||||
|
|
||||||
|
OpenGLFramebuffer* glFramebuffer = static_cast<OpenGLFramebuffer*>(framebuffer);
|
||||||
|
glFramebuffer->Bind();
|
||||||
|
|
||||||
|
OpenGLRenderPass* glRenderPass = static_cast<OpenGLRenderPass*>(renderPass);
|
||||||
|
if (glRenderPass) {
|
||||||
|
const AttachmentDesc* colorAttachments = glRenderPass->GetColorAttachments();
|
||||||
|
uint32_t colorCount = glRenderPass->GetColorAttachmentCount();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < colorCount && i < clearValueCount; ++i) {
|
||||||
|
if (colorAttachments[i].loadOp == LoadAction::Clear) {
|
||||||
|
glClearBufferfv(GL_COLOR, i, &clearValues[i].color.r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttachmentDesc* dsAttachment = glRenderPass->GetDepthStencilAttachment();
|
||||||
|
if (dsAttachment && clearValueCount > colorCount) {
|
||||||
|
if (dsAttachment->loadOp == LoadAction::Clear) {
|
||||||
|
glClearBufferfv(GL_DEPTH, 0, &clearValues[colorCount].depth);
|
||||||
|
}
|
||||||
|
if (dsAttachment->stencilLoadOp == LoadAction::Clear) {
|
||||||
|
float stencilValue = static_cast<float>(clearValues[colorCount].stencil);
|
||||||
|
glClearBufferfv(GL_STENCIL, 0, &stencilValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::EndRenderPass() {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetViewport(const Viewport& viewport) {
|
void OpenGLCommandList::SetViewport(const Viewport& viewport) {
|
||||||
glViewport(static_cast<int>(viewport.topLeftX), static_cast<int>(viewport.topLeftY),
|
glViewport(static_cast<int>(viewport.topLeftX), static_cast<int>(viewport.topLeftY),
|
||||||
static_cast<int>(viewport.width), static_cast<int>(viewport.height));
|
static_cast<int>(viewport.width), static_cast<int>(viewport.height));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -97,6 +98,57 @@ void OpenGLFramebuffer::Shutdown() {
|
|||||||
m_samples = 1;
|
m_samples = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLFramebuffer::Initialize(class RHIRenderPass* renderPass, uint32_t width, uint32_t height,
|
||||||
|
uint32_t colorAttachmentCount, RHIResourceView** colorAttachments,
|
||||||
|
RHIResourceView* depthStencilAttachment) {
|
||||||
|
(void)renderPass;
|
||||||
|
m_width = static_cast<int>(width);
|
||||||
|
m_height = static_cast<int>(height);
|
||||||
|
m_samples = 1;
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &m_framebuffer);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||||
|
|
||||||
|
GLenum drawBuffers[16] = { GL_NONE };
|
||||||
|
int drawBufferCount = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < colorAttachmentCount && i < 16; ++i) {
|
||||||
|
if (colorAttachments[i]) {
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(colorAttachments[i]);
|
||||||
|
GLenum glAttachment = GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(i);
|
||||||
|
unsigned int texture = view->GetTexture();
|
||||||
|
if (texture) {
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, texture, 0);
|
||||||
|
}
|
||||||
|
drawBuffers[drawBufferCount++] = glAttachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilAttachment) {
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(depthStencilAttachment);
|
||||||
|
unsigned int texture = view->GetTexture();
|
||||||
|
if (texture) {
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawBufferCount > 0) {
|
||||||
|
glDrawBuffers(drawBufferCount, drawBuffers);
|
||||||
|
} else {
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLFramebuffer::Bind() {
|
void OpenGLFramebuffer::Bind() {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
38
engine/src/RHI/OpenGL/OpenGLRenderPass.cpp
Normal file
38
engine/src/RHI/OpenGL/OpenGLRenderPass.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLRenderPass.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
OpenGLRenderPass::OpenGLRenderPass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLRenderPass::~OpenGLRenderPass() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderPass::Shutdown() {
|
||||||
|
m_colorAttachments.clear();
|
||||||
|
m_colorAttachmentCount = 0;
|
||||||
|
m_hasDepthStencil = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGLRenderPass::Initialize(uint32_t colorAttachmentCount, const AttachmentDesc* colorAttachments,
|
||||||
|
const AttachmentDesc* depthStencilAttachment) {
|
||||||
|
m_colorAttachmentCount = colorAttachmentCount;
|
||||||
|
m_colorAttachments.resize(colorAttachmentCount);
|
||||||
|
for (uint32_t i = 0; i < colorAttachmentCount; ++i) {
|
||||||
|
m_colorAttachments[i] = colorAttachments[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilAttachment != nullptr) {
|
||||||
|
m_hasDepthStencil = true;
|
||||||
|
m_depthStencilAttachment = *depthStencilAttachment;
|
||||||
|
} else {
|
||||||
|
m_hasDepthStencil = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
Reference in New Issue
Block a user