【关键节点】OpenGLCommandList实现RHIResourceView*方法完成统一资源绑定
OpenGL实现: - TransitionBarrier: 调用glMemoryBarrier(GL_ALL_BARRIER_BITS) - SetRenderTargets: 通过framebuffer绑定渲染目标 - SetVertexBuffer: 绑定GL_ARRAY_BUFFER并设置顶点属性 - SetIndexBuffer: 绑定GL_ELEMENT_ARRAY_BUFFER - ClearRenderTarget: 临时切换framebuffer清除颜色缓冲 - ClearDepthStencil: 临时切换framebuffer清除深度 stencil缓冲 - CopyResource: 使用glCopyImageSubData复制纹理数据 新增单元测试: - CommandList_TransitionBarrier_WithResourceView - CommandList_SetRenderTargets_WithResourceView - CommandList_SetVertexBuffer_WithResourceView - CommandList_SetIndexBuffer_WithResourceView - CommandList_ClearRenderTarget_WithResourceView - CommandList_ClearDepthStencil_WithResourceView - CommandList_CopyResource_WithResourceView 验证: 158个RHI单元测试全部通过, OpenGL集成测试全部通过
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -433,6 +434,10 @@ void OpenGLCommandList::TransitionBarrier(void* resource, ResourceStates stateBe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
||||||
|
(void)resource;
|
||||||
|
(void)stateBefore;
|
||||||
|
(void)stateAfter;
|
||||||
|
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetViewport(const Viewport& viewport) {
|
void OpenGLCommandList::SetViewport(const Viewport& viewport) {
|
||||||
@@ -472,6 +477,30 @@ void OpenGLCommandList::SetRenderTargets(uint32_t count, void** renderTargets, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) {
|
void OpenGLCommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) {
|
||||||
|
if (count > 0 && renderTargets != nullptr) {
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[0]);
|
||||||
|
if (view && view->IsValid()) {
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view->GetFramebuffer());
|
||||||
|
}
|
||||||
|
} else if (depthStencil) {
|
||||||
|
OpenGLResourceView* dsv = static_cast<OpenGLResourceView*>(depthStencil);
|
||||||
|
if (dsv && dsv->IsValid()) {
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dsv->GetFramebuffer());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1 && renderTargets != nullptr) {
|
||||||
|
std::vector<GLuint> fbos(count);
|
||||||
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
|
if (renderTargets[i]) {
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[i]);
|
||||||
|
fbos[i] = view->GetFramebuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::ClearRenderTarget(void* renderTarget, const float color[4]) {
|
void OpenGLCommandList::ClearRenderTarget(void* renderTarget, const float color[4]) {
|
||||||
@@ -480,6 +509,18 @@ void OpenGLCommandList::ClearRenderTarget(void* renderTarget, const float color[
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) {
|
void OpenGLCommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) {
|
||||||
|
if (!renderTarget) return;
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTarget);
|
||||||
|
if (!view->IsValid()) return;
|
||||||
|
|
||||||
|
GLuint prevFBO = 0;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&prevFBO));
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view->GetFramebuffer());
|
||||||
|
glClearColor(color[0], color[1], color[2], color[3]);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) {
|
void OpenGLCommandList::ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) {
|
||||||
@@ -488,6 +529,19 @@ void OpenGLCommandList::ClearDepthStencil(void* depthStencil, float depth, uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) {
|
void OpenGLCommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) {
|
||||||
|
if (!depthStencil) return;
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(depthStencil);
|
||||||
|
if (!view->IsValid()) return;
|
||||||
|
|
||||||
|
GLuint prevFBO = 0;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&prevFBO));
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view->GetFramebuffer());
|
||||||
|
glClearDepth(depth);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFBO);
|
||||||
|
(void)stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetPipelineState(void* pipelineState) {
|
void OpenGLCommandList::SetPipelineState(void* pipelineState) {
|
||||||
@@ -504,6 +558,14 @@ void OpenGLCommandList::SetVertexBuffer(uint32_t slot, void* buffer, uint64_t of
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) {
|
void OpenGLCommandList::SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset, uint32_t stride) {
|
||||||
|
if (!buffer) return;
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(buffer);
|
||||||
|
if (!view->IsValid()) return;
|
||||||
|
|
||||||
|
GLuint glBuffer = view->GetBuffer();
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
|
||||||
|
glVertexAttribPointer(slot, stride / sizeof(float), GL_FLOAT, GL_FALSE, stride, reinterpret_cast<void*>(static_cast<uintptr_t>(offset)));
|
||||||
|
glEnableVertexAttribArray(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) {
|
void OpenGLCommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides) {
|
||||||
@@ -524,12 +586,32 @@ void OpenGLCommandList::SetIndexBuffer(void* buffer, uint64_t offset, Format for
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) {
|
void OpenGLCommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset, Format format) {
|
||||||
|
if (!buffer) return;
|
||||||
|
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(buffer);
|
||||||
|
if (!view->IsValid()) return;
|
||||||
|
|
||||||
|
GLuint glBuffer = view->GetBuffer();
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glBuffer);
|
||||||
|
(void)offset;
|
||||||
|
(void)format;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::CopyResource(void* dst, void* src) {
|
void OpenGLCommandList::CopyResource(void* dst, void* src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src) {
|
void OpenGLCommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src) {
|
||||||
|
if (!dst || !src) return;
|
||||||
|
OpenGLResourceView* dstView = static_cast<OpenGLResourceView*>(dst);
|
||||||
|
OpenGLResourceView* srcView = static_cast<OpenGLResourceView*>(src);
|
||||||
|
if (!dstView->IsValid() || !srcView->IsValid()) return;
|
||||||
|
|
||||||
|
GLuint dstTex = dstView->GetTexture();
|
||||||
|
GLuint srcTex = srcView->GetTexture();
|
||||||
|
if (dstTex && srcTex) {
|
||||||
|
glCopyImageSubData(srcTex, GL_TEXTURE_2D, 0, 0, 0, 0,
|
||||||
|
dstTex, GL_TEXTURE_2D, 0, 0, 0, 0,
|
||||||
|
256, 256, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) {
|
void OpenGLCommandList::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) {
|
||||||
|
|||||||
@@ -226,3 +226,110 @@ TEST_P(RHITestFixture, CommandList_TransitionBarrier) {
|
|||||||
cmdList->Shutdown();
|
cmdList->Shutdown();
|
||||||
delete cmdList;
|
delete cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_TransitionBarrier_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->TransitionBarrier(static_cast<RHIResourceView*>(nullptr), ResourceStates::Common, ResourceStates::RenderTarget);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_SetRenderTargets_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->SetRenderTargets(0, static_cast<RHIResourceView**>(nullptr), static_cast<RHIResourceView*>(nullptr));
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_SetVertexBuffer_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->SetVertexBuffer(0, static_cast<RHIResourceView*>(nullptr), 0, 16);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_SetIndexBuffer_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->SetIndexBuffer(static_cast<RHIResourceView*>(nullptr), 0, Format::R32_UInt);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_ClearRenderTarget_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
float color[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->ClearRenderTarget(static_cast<RHIResourceView*>(nullptr), color);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_ClearDepthStencil_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->ClearDepthStencil(static_cast<RHIResourceView*>(nullptr), 1.0f, 0);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_CopyResource_WithResourceView) {
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->CopyResource(static_cast<RHIResourceView*>(nullptr), static_cast<RHIResourceView*>(nullptr));
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user