Refactor RHI ResourceView abstraction layer for unified cross-platform interface

- Create unified RHIResourceView base interface with type-specific Initialize methods
- Implement D3D12ResourceView with RTV/DSV/SRV/UAV/CBV support
- Implement OpenGL ResourceView simulation layer using FBO, texture units, and UBO
- Add OpenGLTextureUnitAllocator for managing texture unit bindings
- Add OpenGLUniformBufferManager for UBO binding points
- Add OpenGLFramebuffer for FBO management
- Remove deprecated D3D12 view classes (RenderTargetView, DepthStencilView, etc.)
- Fix ExecuteCommandLists type confusion bug by adding GetNativeHandle to RHICommandList
- Fix test bug where Close() was called before ExecuteCommandLists
- Update all integration tests to use new D3D12ResourceView class
- All tests pass: 144 unit tests + 8 integration tests
This commit is contained in:
2026-03-24 03:49:13 +08:00
parent 86b6d6b042
commit 0a3fe842b9
32 changed files with 1288 additions and 233 deletions

View File

@@ -14,6 +14,10 @@
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
#include "XCEngine/RHI/OpenGL/OpenGLCommandQueue.h"
#include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h"
#include "XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h"
#include "XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h"
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
#include "XCEngine/Debug/Logger.h"
static bool s_windowClassRegistered = false;
@@ -44,6 +48,8 @@ OpenGLDevice::OpenGLDevice()
, m_initialized(false)
, m_ownsWindow(false)
, m_shouldClose(false) {
m_textureUnitAllocator = std::make_unique<OpenGLTextureUnitAllocator>();
m_uniformBufferManager = std::make_unique<OpenGLUniformBufferManager>();
}
OpenGLDevice::~OpenGLDevice() {
@@ -229,6 +235,14 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
GLint maxAttribs = 0;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
m_capabilities.maxVertexAttribs = static_cast<uint32_t>(maxAttribs);
GLint maxTextureUnits = 0;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
m_textureUnitAllocator->Initialize(static_cast<uint32_t>(maxTextureUnits));
GLint maxUniformBlocks = 0;
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBlocks);
m_uniformBufferManager->Initialize(static_cast<uint32_t>(maxUniformBlocks));
m_initialized = true;
return true;
@@ -297,6 +311,13 @@ void OpenGLDevice::Shutdown() {
m_hwnd = nullptr;
}
if (m_uniformBufferManager) {
m_uniformBufferManager->Shutdown();
}
if (m_textureUnitAllocator) {
m_textureUnitAllocator->Shutdown();
}
m_initialized = false;
m_ownsWindow = false;
m_shouldClose = false;
@@ -441,6 +462,106 @@ RHISampler* OpenGLDevice::CreateSampler(const SamplerDesc& desc) {
return sampler;
}
RHIResourceView* OpenGLDevice::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) {
if (!texture) {
return nullptr;
}
auto* glTexture = static_cast<OpenGLTexture*>(texture);
FramebufferDesc fbDesc = {};
fbDesc.width = static_cast<int>(texture->GetWidth());
fbDesc.height = static_cast<int>(texture->GetHeight());
FramebufferAttachment colorAttachment = {};
colorAttachment.texture = glTexture->GetID();
colorAttachment.mipLevel = static_cast<int>(desc.mipLevel);
colorAttachment.type = FramebufferAttachmentType::Color;
colorAttachment.format = desc.format;
fbDesc.colorAttachments.push_back(colorAttachment);
auto* framebuffer = new OpenGLFramebuffer();
if (!framebuffer->Initialize(fbDesc)) {
delete framebuffer;
return nullptr;
}
auto* view = new OpenGLResourceView();
if (!view->InitializeAsRenderTarget(glTexture, desc, framebuffer)) {
delete framebuffer;
delete view;
return nullptr;
}
return view;
}
RHIResourceView* OpenGLDevice::CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) {
if (!texture) {
return nullptr;
}
auto* glTexture = static_cast<OpenGLTexture*>(texture);
FramebufferDesc fbDesc = {};
fbDesc.width = static_cast<int>(texture->GetWidth());
fbDesc.height = static_cast<int>(texture->GetHeight());
FramebufferAttachment depthAttachment = {};
depthAttachment.texture = glTexture->GetID();
depthAttachment.mipLevel = static_cast<int>(desc.mipLevel);
depthAttachment.type = FramebufferAttachmentType::DepthStencil;
depthAttachment.format = desc.format;
fbDesc.depthAttachment = depthAttachment;
auto* framebuffer = new OpenGLFramebuffer();
if (!framebuffer->Initialize(fbDesc)) {
delete framebuffer;
return nullptr;
}
auto* view = new OpenGLResourceView();
if (!view->InitializeAsDepthStencil(glTexture, desc, framebuffer)) {
delete framebuffer;
delete view;
return nullptr;
}
return view;
}
RHIResourceView* OpenGLDevice::CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) {
if (!texture) {
return nullptr;
}
auto* glTexture = static_cast<OpenGLTexture*>(texture);
auto* view = new OpenGLResourceView();
if (!view->InitializeAsShaderResource(glTexture, desc, m_textureUnitAllocator.get())) {
delete view;
return nullptr;
}
return view;
}
RHIResourceView* OpenGLDevice::CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) {
if (!texture) {
return nullptr;
}
auto* glTexture = static_cast<OpenGLTexture*>(texture);
auto* view = new OpenGLResourceView();
if (!view->InitializeAsUnorderedAccess(glTexture, desc, m_textureUnitAllocator.get())) {
delete view;
return nullptr;
}
return view;
}
const RHICapabilities& OpenGLDevice::GetCapabilities() const {
return m_capabilities;
}