#if defined(XCENGINE_SUPPORT_VULKAN) #include "fixtures/VulkanTestFixture.h" #include "XCEngine/RHI/RHIDescriptorPool.h" #include "XCEngine/RHI/Vulkan/VulkanDescriptorSet.h" using namespace XCEngine::RHI; namespace { TEST_F(VulkanGraphicsFixture, DescriptorSet_MixedBindingsRetainLayoutMetadata) { DescriptorPoolDesc poolDesc = {}; poolDesc.type = DescriptorHeapType::CBV_SRV_UAV; poolDesc.descriptorCount = 4; poolDesc.shaderVisible = true; RHIDescriptorPool* pool = m_device->CreateDescriptorPool(poolDesc); ASSERT_NE(pool, nullptr); DescriptorSetLayoutBinding bindings[3] = {}; bindings[0].binding = 2; bindings[0].type = static_cast(DescriptorType::UAV); bindings[0].count = 1; bindings[1].binding = 0; bindings[1].type = static_cast(DescriptorType::CBV); bindings[1].count = 1; bindings[2].binding = 1; bindings[2].type = static_cast(DescriptorType::SRV); bindings[2].count = 1; DescriptorSetLayoutDesc layoutDesc = {}; layoutDesc.bindings = bindings; layoutDesc.bindingCount = 3; RHIDescriptorSet* set = pool->AllocateSet(layoutDesc); ASSERT_NE(set, nullptr); auto* vulkanSet = static_cast(set); ASSERT_NE(vulkanSet->GetDescriptorSet(), VK_NULL_HANDLE); ASSERT_NE(vulkanSet->GetDescriptorSetLayout(), VK_NULL_HANDLE); ASSERT_EQ(vulkanSet->GetBindingCount(), 3u); const DescriptorSetLayoutBinding* storedBindings = vulkanSet->GetBindings(); ASSERT_NE(storedBindings, nullptr); EXPECT_EQ(storedBindings[0].binding, 2u); EXPECT_EQ(storedBindings[0].type, static_cast(DescriptorType::UAV)); EXPECT_EQ(storedBindings[1].binding, 0u); EXPECT_EQ(storedBindings[1].type, static_cast(DescriptorType::CBV)); EXPECT_EQ(storedBindings[2].binding, 1u); EXPECT_EQ(storedBindings[2].type, static_cast(DescriptorType::SRV)); set->Shutdown(); delete set; pool->Shutdown(); delete pool; } TEST_F(VulkanGraphicsFixture, DescriptorSet_WriteConstantTracksDirtyStateAndBacksData) { DescriptorPoolDesc poolDesc = {}; poolDesc.type = DescriptorHeapType::CBV_SRV_UAV; poolDesc.descriptorCount = 1; poolDesc.shaderVisible = true; RHIDescriptorPool* pool = m_device->CreateDescriptorPool(poolDesc); ASSERT_NE(pool, nullptr); DescriptorSetLayoutBinding binding = {}; binding.binding = 0; binding.type = static_cast(DescriptorType::CBV); binding.count = 1; DescriptorSetLayoutDesc layoutDesc = {}; layoutDesc.bindings = &binding; layoutDesc.bindingCount = 1; RHIDescriptorSet* set = pool->AllocateSet(layoutDesc); ASSERT_NE(set, nullptr); auto* vulkanSet = static_cast(set); EXPECT_FALSE(vulkanSet->IsConstantDirty()); EXPECT_EQ(vulkanSet->GetConstantBufferData(), nullptr); EXPECT_EQ(vulkanSet->GetConstantBufferSize(), 0u); const float constants[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; vulkanSet->WriteConstant(0, constants, sizeof(constants)); EXPECT_TRUE(vulkanSet->IsConstantDirty()); ASSERT_NE(vulkanSet->GetConstantBufferData(), nullptr); ASSERT_EQ(vulkanSet->GetConstantBufferSize(), sizeof(constants)); auto* storedConstants = static_cast(vulkanSet->GetConstantBufferData()); EXPECT_FLOAT_EQ(storedConstants[0], 1.0f); EXPECT_FLOAT_EQ(storedConstants[1], 2.0f); EXPECT_FLOAT_EQ(storedConstants[2], 3.0f); EXPECT_FLOAT_EQ(storedConstants[3], 4.0f); vulkanSet->MarkConstantClean(); EXPECT_FALSE(vulkanSet->IsConstantDirty()); set->Shutdown(); delete set; pool->Shutdown(); delete pool; } } // namespace #endif