From e2050e35ec302556d6bb2acea4d4a6498110dad1 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 24 Mar 2026 05:11:47 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=85=B3=E9=94=AE=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E3=80=91RHICommandList=E6=B7=BB=E5=8A=A0RHIResourceView*?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E9=87=8D=E8=BD=BD=E5=AE=9E=E7=8E=B0=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E8=B5=84=E6=BA=90=E7=BB=91=E5=AE=9A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在RHICommandList.h中添加7个RHIResourceView*方法重载: - TransitionBarrier(RHIResourceView*, ...) - SetRenderTargets(count, RHIResourceView**, RHIResourceView*) - SetVertexBuffer(slot, RHIResourceView*, ...) - SetIndexBuffer(RHIResourceView*, ...) - ClearRenderTarget(RHIResourceView*, ...) - ClearDepthStencil(RHIResourceView*, ...) - CopyResource(RHIResourceView*, RHIResourceView*) - D3D12CommandList完整实现: - 通过D3D12ResourceView::GetResource()获取底层资源 - 通过D3D12ResourceView::GetCPUHandle()获取RTV/DSV句柄 - OpenGLCommandList添加stub实现保持接口一致 - 验证: 144个单元测试全部通过, 4个D3D12集成测试全部通过 --- .../XCEngine/RHI/D3D12/D3D12CommandList.h | 7 ++ .../XCEngine/RHI/OpenGL/OpenGLCommandList.h | 7 ++ engine/include/XCEngine/RHI/RHICommandList.h | 9 +++ engine/src/RHI/D3D12/D3D12CommandList.cpp | 64 +++++++++++++++++++ engine/src/RHI/OpenGL/OpenGLCommandList.cpp | 21 ++++++ 5 files changed, 108 insertions(+) diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h index 13d20963..72b86491 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h @@ -29,6 +29,7 @@ public: ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); } void TransitionBarrier(void* resource, ResourceStates stateBefore, ResourceStates stateAfter) override; + void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override; void TransitionBarrierInternal(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter, uint32_t subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES); void UAVBarrier(void* resource = nullptr); void UAVBarrierInternal(ID3D12Resource* resource); @@ -44,14 +45,17 @@ public: void SetScissorRects(uint32_t count, const Rect* rects) override; void SetPrimitiveTopology(PrimitiveTopology topology); void SetRenderTargets(uint32_t count, void** renderTargets, void* depthStencil = nullptr) override; + void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) override; void SetRenderTargetsInternal(uint32_t count, ID3D12Resource** renderTargets, ID3D12Resource* depthStencil = nullptr); void SetRenderTargetsHandle(uint32_t count, const D3D12_CPU_DESCRIPTOR_HANDLE* renderTargetHandles, const D3D12_CPU_DESCRIPTOR_HANDLE* depthStencilHandle = nullptr); void SetVertexBuffer(uint32_t slot, void* buffer, uint64_t offset, uint32_t stride) override; + void SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) override; void SetVertexBufferInternal(uint32_t slot, ID3D12Resource* buffer, uint64_t offset, uint32_t stride); void SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) override; void SetVertexBuffersInternal(uint32_t startSlot, uint32_t count, const D3D12_VERTEX_BUFFER_VIEW* views); void SetIndexBuffer(void* buffer, uint64_t offset, Format format) override; + void SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) override; void SetIndexBufferInternal(ID3D12Resource* buffer, uint64_t offset, Format indexFormat); void SetDescriptorHeap(ID3D12DescriptorHeap* heap); @@ -79,7 +83,9 @@ public: void Clear(float r, float g, float b, float a, uint32_t buffers) override; void ClearRenderTarget(void* renderTarget, const float color[4]) override; + void ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) override; void ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) override; + void ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) override; void ClearRenderTargetView(ID3D12Resource* renderTarget, const float color[4], uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr); void ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE renderTargetHandle, const float color[4], uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr); void ClearDepthStencilView(ID3D12Resource* depthStencil, uint32_t clearFlags, float depth = 1.0f, uint8_t stencil = 0, uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr); @@ -87,6 +93,7 @@ public: void ClearUnorderedAccessView(D3D12_GPU_DESCRIPTOR_HANDLE viewHandle, D3D12_CPU_DESCRIPTOR_HANDLE resourceHandle, ID3D12Resource* unorderedAccess, const float values[4], uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr); void CopyResource(void* dst, void* src) override; + void CopyResource(RHIResourceView* dst, RHIResourceView* src) override; void CopyResourceInternal(ID3D12Resource* dst, ID3D12Resource* src); void CopyBuffer(ID3D12Resource* dst, uint64_t dstOffset, ID3D12Resource* src, uint64_t srcOffset, uint64_t size); void CopyTexture(ID3D12Resource* dst, const D3D12_TEXTURE_COPY_LOCATION& dstLocation, ID3D12Resource* src, const D3D12_TEXTURE_COPY_LOCATION& srcLocation); diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h index ad4e4a3f..08c40daf 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h @@ -53,8 +53,10 @@ public: void SetPipelineState(void* pipelineState) override; void SetVertexBuffer(uint32_t slot, void* buffer, uint64_t offset, uint32_t stride) override; + void SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) override; void SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) override; void SetIndexBuffer(void* buffer, uint64_t offset, Format format) override; + void SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) override; // OpenGL 特有版本(底层逃逸) void SetVertexBuffer(unsigned int buffer, size_t offset, size_t stride); @@ -149,6 +151,7 @@ public: void CopyImageSubData(unsigned int srcName, unsigned int srcTarget, int srcLevel, int srcX, int srcY, int srcZ, unsigned int dstName, unsigned int dstTarget, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth); void CopyResource(void* dst, void* src) override; + void CopyResource(RHIResourceView* dst, RHIResourceView* src) override; void InvalidateFramebuffer(unsigned int target, unsigned int count, const unsigned int* attachments); void InvalidateSubFramebuffer(unsigned int target, unsigned int count, const unsigned int* attachments, int x, int y, int width, int height); @@ -157,18 +160,22 @@ public: void PopDebugGroup(); void TransitionBarrier(void* resource, ResourceStates stateBefore, ResourceStates stateAfter) override; + void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override; void SetPrimitiveTopology(PrimitiveTopology topology) override; void SetViewport(const Viewport& viewport) override; void SetViewports(uint32_t count, const Viewport* viewports) override; void SetScissorRect(const Rect& rect) override; void SetScissorRects(uint32_t count, const Rect* rects) override; void SetRenderTargets(uint32_t count, void** renderTargets, void* depthStencil = nullptr) override; + void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) override; void SetDepthStencilState(const DepthStencilState& state) override; void SetStencilRef(uint8_t ref) override; void SetBlendState(const BlendState& state) override; void SetBlendFactor(const float factor[4]) override; void ClearRenderTarget(void* renderTarget, const float color[4]) override; + void ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) override; void ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) override; + void ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) override; void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) override; void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) override; diff --git a/engine/include/XCEngine/RHI/RHICommandList.h b/engine/include/XCEngine/RHI/RHICommandList.h index c3e94145..2f97b7a7 100644 --- a/engine/include/XCEngine/RHI/RHICommandList.h +++ b/engine/include/XCEngine/RHI/RHICommandList.h @@ -6,6 +6,8 @@ namespace XCEngine { namespace RHI { +class RHIResourceView; + struct DepthStencilState { bool depthEnable = true; bool depthWriteMask = true; @@ -50,6 +52,7 @@ public: virtual void Close() = 0; virtual void TransitionBarrier(void* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0; + virtual void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0; virtual void SetPipelineState(void* pso) = 0; virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0; @@ -58,6 +61,7 @@ public: virtual void SetScissorRect(const Rect& rect) = 0; virtual void SetScissorRects(uint32_t count, const Rect* rects) = 0; virtual void SetRenderTargets(uint32_t count, void** renderTargets, void* depthStencil = nullptr) = 0; + virtual void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) = 0; virtual void SetDepthStencilState(const DepthStencilState& state) = 0; virtual void SetStencilRef(uint8_t ref) = 0; @@ -65,17 +69,22 @@ public: virtual void SetBlendFactor(const float factor[4]) = 0; virtual void SetVertexBuffer(uint32_t slot, void* buffer, uint64_t offset, uint32_t stride) = 0; + virtual void SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) = 0; virtual void SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) = 0; virtual void SetIndexBuffer(void* buffer, uint64_t offset, Format format) = 0; + virtual void SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) = 0; virtual void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t startVertex = 0, uint32_t startInstance = 0) = 0; virtual void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t startIndex = 0, int32_t baseVertex = 0, uint32_t startInstance = 0) = 0; virtual void Clear(float r, float g, float b, float a, uint32_t buffers) = 0; virtual void ClearRenderTarget(void* renderTarget, const float color[4]) = 0; + virtual void ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) = 0; virtual void ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) = 0; + virtual void ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) = 0; virtual void CopyResource(void* dst, void* src) = 0; + virtual void CopyResource(RHIResourceView* dst, RHIResourceView* src) = 0; virtual void Dispatch(uint32_t x, uint32_t y, uint32_t z) = 0; diff --git a/engine/src/RHI/D3D12/D3D12CommandList.cpp b/engine/src/RHI/D3D12/D3D12CommandList.cpp index 35a9f72c..73f75562 100644 --- a/engine/src/RHI/D3D12/D3D12CommandList.cpp +++ b/engine/src/RHI/D3D12/D3D12CommandList.cpp @@ -1,4 +1,5 @@ #include "XCEngine/RHI/D3D12/D3D12CommandList.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" namespace XCEngine { namespace RHI { @@ -77,6 +78,12 @@ void D3D12CommandList::TransitionBarrier(void* resource, ResourceStates stateBef TransitionBarrierInternal(static_cast(resource), stateBefore, stateAfter); } +void D3D12CommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) { + if (!resource || !resource->IsValid()) return; + D3D12ResourceView* d3d12View = static_cast(resource); + TransitionBarrierInternal(d3d12View->GetResource(), stateBefore, stateAfter); +} + void D3D12CommandList::UAVBarrier(void* resource) { UAVBarrierInternal(static_cast(resource)); } @@ -197,6 +204,32 @@ void D3D12CommandList::SetRenderTargets(uint32_t count, void** renderTargets, vo SetRenderTargetsInternal(count, resources.data(), static_cast(depthStencil)); } +void D3D12CommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) { + std::vector rtvHandles(count); + for (uint32_t i = 0; i < count; ++i) { + if (renderTargets[i] && renderTargets[i]->IsValid()) { + D3D12ResourceView* view = static_cast(renderTargets[i]); + rtvHandles[i] = view->GetCPUHandle(); + } + } + + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {}; + if (depthStencil && depthStencil->IsValid()) { + D3D12ResourceView* view = static_cast(depthStencil); + dsvHandle = view->GetCPUHandle(); + } + + m_commandList->OMSetRenderTargets(count, count > 0 ? rtvHandles.data() : nullptr, FALSE, depthStencil ? &dsvHandle : nullptr); + + m_boundRenderTargets = rtvHandles; + if (depthStencil) { + m_boundDepthStencil = dsvHandle; + m_depthStencilBound = true; + } else { + m_depthStencilBound = false; + } +} + void D3D12CommandList::SetRenderTargetsInternal(uint32_t count, ID3D12Resource** renderTargets, ID3D12Resource* depthStencil) { std::vector rtvHandles(count); for (uint32_t i = 0; i < count; ++i) { @@ -229,6 +262,12 @@ void D3D12CommandList::SetVertexBuffer(uint32_t slot, void* buffer, uint64_t off SetVertexBufferInternal(slot, static_cast(buffer), offset, stride); } +void D3D12CommandList::SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) { + if (!buffer || !buffer->IsValid()) return; + D3D12ResourceView* view = static_cast(buffer); + SetVertexBufferInternal(slot, view->GetResource(), offset, stride); +} + void D3D12CommandList::SetVertexBufferInternal(uint32_t slot, ID3D12Resource* buffer, uint64_t offset, uint32_t stride) { D3D12_VERTEX_BUFFER_VIEW view = {}; view.BufferLocation = buffer->GetGPUVirtualAddress() + offset; @@ -256,6 +295,12 @@ void D3D12CommandList::SetIndexBuffer(void* buffer, uint64_t offset, Format form SetIndexBufferInternal(static_cast(buffer), offset, format); } +void D3D12CommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) { + if (!buffer || !buffer->IsValid()) return; + D3D12ResourceView* view = static_cast(buffer); + SetIndexBufferInternal(view->GetResource(), offset, format); +} + void D3D12CommandList::SetIndexBufferInternal(ID3D12Resource* buffer, uint64_t offset, Format indexFormat) { D3D12_INDEX_BUFFER_VIEW view = {}; view.BufferLocation = buffer->GetGPUVirtualAddress() + offset; @@ -355,10 +400,22 @@ void D3D12CommandList::ClearRenderTarget(void* renderTarget, const float color[4 ClearRenderTargetView(static_cast(renderTarget), color, 0, nullptr); } +void D3D12CommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) { + if (!renderTarget || !renderTarget->IsValid()) return; + D3D12ResourceView* view = static_cast(renderTarget); + ClearRenderTargetView(view->GetCPUHandle(), color, 0, nullptr); +} + void D3D12CommandList::ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) { ClearDepthStencilView(static_cast(depthStencil), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, depth, stencil, 0, nullptr); } +void D3D12CommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) { + if (!depthStencil || !depthStencil->IsValid()) return; + D3D12ResourceView* view = static_cast(depthStencil); + ClearDepthStencilView(view->GetCPUHandle(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, depth, stencil, 0, nullptr); +} + void D3D12CommandList::ClearDepthStencilView(ID3D12Resource* depthStencil, uint32_t clearFlags, float depth, uint8_t stencil, uint32_t rectCount, const D3D12_RECT* rects) { D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {}; m_commandList->ClearDepthStencilView(dsvHandle, static_cast(clearFlags), depth, stencil, rectCount, rects); @@ -376,6 +433,13 @@ void D3D12CommandList::CopyResource(void* dst, void* src) { CopyResourceInternal(static_cast(dst), static_cast(src)); } +void D3D12CommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src) { + if (!dst || !src || !dst->IsValid() || !src->IsValid()) return; + D3D12ResourceView* dstView = static_cast(dst); + D3D12ResourceView* srcView = static_cast(src); + CopyResourceInternal(dstView->GetResource(), srcView->GetResource()); +} + void D3D12CommandList::CopyResourceInternal(ID3D12Resource* dst, ID3D12Resource* src) { m_commandList->CopyResource(dst, src); } diff --git a/engine/src/RHI/OpenGL/OpenGLCommandList.cpp b/engine/src/RHI/OpenGL/OpenGLCommandList.cpp index c824e000..b56d3895 100644 --- a/engine/src/RHI/OpenGL/OpenGLCommandList.cpp +++ b/engine/src/RHI/OpenGL/OpenGLCommandList.cpp @@ -432,6 +432,9 @@ void OpenGLCommandList::Close() { void OpenGLCommandList::TransitionBarrier(void* resource, ResourceStates stateBefore, ResourceStates stateAfter) { } +void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) { +} + void OpenGLCommandList::SetViewport(const Viewport& viewport) { glViewport(static_cast(viewport.topLeftX), static_cast(viewport.topLeftY), static_cast(viewport.width), static_cast(viewport.height)); @@ -468,16 +471,25 @@ void OpenGLCommandList::SetScissorRects(uint32_t count, const Rect* rects) { void OpenGLCommandList::SetRenderTargets(uint32_t count, void** renderTargets, void* depthStencil) { } +void OpenGLCommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) { +} + void OpenGLCommandList::ClearRenderTarget(void* renderTarget, const float color[4]) { glClearColor(color[0], color[1], color[2], color[3]); glClear(GL_COLOR_BUFFER_BIT); } +void OpenGLCommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) { +} + void OpenGLCommandList::ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) { glClearDepth(depth); glClear(GL_DEPTH_BUFFER_BIT); } +void OpenGLCommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) { +} + void OpenGLCommandList::SetPipelineState(void* pipelineState) { if (pipelineState) { UseShader(reinterpret_cast(pipelineState)); @@ -491,6 +503,9 @@ void OpenGLCommandList::SetVertexBuffer(uint32_t slot, void* buffer, uint64_t of glEnableVertexAttribArray(slot); } +void OpenGLCommandList::SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) { +} + void OpenGLCommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) { for (uint32_t i = 0; i < count; i++) { GLuint glBuffer = static_cast(buffers[i]); @@ -508,9 +523,15 @@ void OpenGLCommandList::SetIndexBuffer(void* buffer, uint64_t offset, Format for (void)format; } +void OpenGLCommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) { +} + void OpenGLCommandList::CopyResource(void* dst, void* src) { } +void OpenGLCommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src) { +} + void OpenGLCommandList::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) { glDrawArraysInstanced(GL_TRIANGLES, static_cast(startVertex), static_cast(vertexCount), static_cast(instanceCount)); }