Add RHI texture upload and descriptor set fixes

This commit is contained in:
2026-03-26 00:04:51 +08:00
parent 605ef56e16
commit 76c4c2ace2
15 changed files with 468 additions and 46 deletions

View File

@@ -1,10 +1,15 @@
#include "fixtures/RHITestFixture.h"
#include "XCEngine/RHI/D3D12/D3D12DescriptorSet.h"
#include "XCEngine/RHI/OpenGL/OpenGLDescriptorSet.h"
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
#include "XCEngine/RHI/RHIDescriptorPool.h"
#include "XCEngine/RHI/RHIDescriptorSet.h"
#include "XCEngine/RHI/RHISampler.h"
#include "XCEngine/RHI/RHIResourceView.h"
#include "XCEngine/RHI/RHITexture.h"
#include <glad/glad.h>
using namespace XCEngine::RHI;
TEST_P(RHITestFixture, DescriptorSet_Allocate_Basic) {
@@ -359,4 +364,132 @@ TEST_P(RHITestFixture, DescriptorSet_ConstantBufferSize) {
pool->Shutdown();
delete pool;
}
}
TEST_P(RHITestFixture, DescriptorSet_MultipleAllocations_AdvanceDescriptorOffsets) {
DescriptorPoolDesc poolDesc = {};
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
poolDesc.descriptorCount = 8;
poolDesc.shaderVisible = true;
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
ASSERT_NE(pool, nullptr);
DescriptorSetLayoutBinding bindings[2] = {};
bindings[0].binding = 0;
bindings[0].type = static_cast<uint32_t>(DescriptorType::SRV);
bindings[0].count = 1;
bindings[1].binding = 1;
bindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
bindings[1].count = 1;
DescriptorSetLayoutDesc layoutDesc = {};
layoutDesc.bindings = bindings;
layoutDesc.bindingCount = 2;
RHIDescriptorSet* firstSet = pool->AllocateSet(layoutDesc);
RHIDescriptorSet* secondSet = pool->AllocateSet(layoutDesc);
ASSERT_NE(firstSet, nullptr);
ASSERT_NE(secondSet, nullptr);
if (GetBackendType() == RHIType::D3D12) {
auto* firstD3D12Set = static_cast<D3D12DescriptorSet*>(firstSet);
auto* secondD3D12Set = static_cast<D3D12DescriptorSet*>(secondSet);
EXPECT_EQ(firstD3D12Set->GetOffset(), 0u);
EXPECT_EQ(secondD3D12Set->GetOffset(), 2u);
}
firstSet->Shutdown();
delete firstSet;
secondSet->Shutdown();
delete secondSet;
pool->Shutdown();
delete pool;
}
TEST_P(RHITestFixture, DescriptorSet_Update_UsesBindingNumberOnOpenGL) {
if (GetBackendType() != RHIType::OpenGL) {
GTEST_SKIP() << "OpenGL-specific descriptor binding verification";
}
auto* openGLDevice = static_cast<OpenGLDevice*>(GetDevice());
ASSERT_NE(openGLDevice, nullptr);
ASSERT_TRUE(openGLDevice->MakeContextCurrent());
DescriptorPoolDesc poolDesc = {};
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
poolDesc.descriptorCount = 8;
poolDesc.shaderVisible = true;
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
ASSERT_NE(pool, nullptr);
TextureDesc textureDesc = {};
textureDesc.width = 1;
textureDesc.height = 1;
textureDesc.depth = 1;
textureDesc.mipLevels = 1;
textureDesc.arraySize = 1;
textureDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
textureDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
textureDesc.sampleCount = 1;
const uint8_t pixel[4] = { 255, 255, 255, 255 };
RHITexture* texture = GetDevice()->CreateTexture(textureDesc, pixel, sizeof(pixel), 4);
ASSERT_NE(texture, nullptr);
ResourceViewDesc srvDesc = {};
srvDesc.format = textureDesc.format;
srvDesc.dimension = ResourceViewDimension::Texture2D;
RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, srvDesc);
ASSERT_NE(srv, nullptr);
DescriptorSetLayoutBinding bindings[2] = {};
bindings[0].binding = 3;
bindings[0].type = static_cast<uint32_t>(DescriptorType::SRV);
bindings[0].count = 1;
bindings[1].binding = 7;
bindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
bindings[1].count = 1;
DescriptorSetLayoutDesc layoutDesc = {};
layoutDesc.bindings = bindings;
layoutDesc.bindingCount = 2;
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
ASSERT_NE(set, nullptr);
auto* openGLSet = static_cast<OpenGLDescriptorSet*>(set);
const uint32_t untouchedUnit = openGLSet->GetBindingPoint(3);
const uint32_t updatedUnit = openGLSet->GetBindingPoint(7);
ASSERT_NE(untouchedUnit, updatedUnit);
set->Update(7, srv);
set->Bind();
GLint updatedTexture = 0;
glActiveTexture(GL_TEXTURE0 + updatedUnit);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &updatedTexture);
EXPECT_EQ(static_cast<unsigned int>(updatedTexture), static_cast<unsigned int>(reinterpret_cast<uintptr_t>(srv->GetNativeHandle())));
GLint untouchedTexture = 0;
glActiveTexture(GL_TEXTURE0 + untouchedUnit);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &untouchedTexture);
EXPECT_EQ(untouchedTexture, 0);
set->Unbind();
GLint unboundTexture = 0;
glActiveTexture(GL_TEXTURE0 + updatedUnit);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &unboundTexture);
EXPECT_EQ(unboundTexture, 0);
set->Shutdown();
delete set;
srv->Shutdown();
delete srv;
texture->Shutdown();
delete texture;
pool->Shutdown();
delete pool;
}