已关闭
[ArkWeb][安全][上游社区漏洞修复][BUG-536636648] 描述符池回收修复 #470
[ArkWeb][安全][上游社区漏洞修复][BUG-536636648] 描述符池回收修复 #470
已关闭
创建于 8 天前关闭于 8 天前
3 个文件变更+52-2
@@ -3505,6 +3505,15 @@ void DescriptorPoolHelper::cleanupPendingGarbage()
3505 }3505 }
3506}3506}
3507 3507 
3508+void DescriptorPoolHelper::forceFinishPendingGarbage()
3509+{
3510+ while (!mPendingGarbageList.empty())
3511+ {
3512+ mFinishedGarbageList.push_back(std::move(mPendingGarbageList.front()));
3513+ mPendingGarbageList.pop_front();
3514+ }
3515+}
3516+ 
3508bool DescriptorPoolHelper::recycleFromGarbage(Renderer *renderer,3517bool DescriptorPoolHelper::recycleFromGarbage(Renderer *renderer,
3509 DescriptorSetPointer *descriptorSetOut)3518 DescriptorSetPointer *descriptorSetOut)
3510{3519{
@@ -3627,7 +3636,11 @@ void DynamicDescriptorPool::destroy(VkDevice device)
3627 3636 
3628 for (DescriptorPoolPointer &pool : mDescriptorPools)3637 for (DescriptorPoolPointer &pool : mDescriptorPools)
3629 {3638 {
3630- pool->cleanupPendingGarbage();3639+ // Usually all pending garbage should have been finished when DynamicDescriptorPool is
3640+ // destroyed. But when context runs into error and submit code path early out, we could have
3641+ // unfinished garbage in the pending list. So force all pending garbage to be cleared rather
3642+ // than being left in place until the pool itself is deleted.
3643+ pool->forceFinishPendingGarbage();
3631 pool->destroyGarbage();3644 pool->destroyGarbage();
3632 ASSERT(pool.unique());3645 ASSERT(pool.unique());
3633 }3646 }
@@ -298,6 +298,7 @@ class DescriptorPoolHelper final : angle::NonCopyable
298 bool recycleFromGarbage(Renderer *renderer, DescriptorSetPointer *descriptorSetOut);298 bool recycleFromGarbage(Renderer *renderer, DescriptorSetPointer *descriptorSetOut);
299 void destroyGarbage();299 void destroyGarbage();
300 void cleanupPendingGarbage();300 void cleanupPendingGarbage();
301+ void forceFinishPendingGarbage();
301 302 
302 bool hasValidDescriptorSet() const { return mValidDescriptorSets != 0; }303 bool hasValidDescriptorSet() const { return mValidDescriptorSets != 0; }
303 bool canDestroy() const { return mValidDescriptorSets == 0 && mPendingGarbageList.empty(); }304 bool canDestroy() const { return mValidDescriptorSets == 0 && mPendingGarbageList.empty(); }
@@ -208,7 +208,43 @@ TEST_P(VulkanDescriptorSetLayoutDescTest, Basic)
208 mDescriptorSetLayoutCache.destroy(contextVk->getRenderer());208 mDescriptorSetLayoutCache.destroy(contextVk->getRenderer());
209}209}
210 210 
211+// Verify that DynamicDescriptorPool::destroy tears down cleanly even when descriptor sets that
212+// were returned to the pool are still tagged with an outstanding queue serial.
213+TEST_P(VulkanDescriptorSetLayoutDescTest, DestroyWithPendingGarbage)
214+{
215+ rx::ContextVk *contextVk = hackANGLE();
216+ 
217+ rx::vk::DescriptorSetLayoutDesc desc;
218+ addBindings({0}, &desc);
219+ 
220+ rx::vk::DescriptorSetLayoutPtr descriptorSetLayout;
221+ angle::Result result =
222+ mDescriptorSetLayoutCache.getDescriptorSetLayout(contextVk, desc, &descriptorSetLayout);
223+ ASSERT_EQ(result, angle::Result::Continue);
224+ 
225+ VkDescriptorPoolSize poolSize = {VK_DESCRIPTOR_TYPE_SAMPLER, 1};
226+ rx::vk::DynamicDescriptorPool dynamicPool;
227+ result = dynamicPool.init(contextVk, &poolSize, 1, *descriptorSetLayout);
228+ ASSERT_EQ(result, angle::Result::Continue);
229+ 
230+ rx::vk::DescriptorSetPointer descriptorSet;
231+ result = dynamicPool.allocateDescriptorSet(contextVk, *descriptorSetLayout, &descriptorSet);
232+ ASSERT_EQ(result, angle::Result::Continue);
233+ ASSERT_TRUE(descriptorSet);
234+ 
235+ // Tag the descriptor set with a queue serial that has not been reached so that it stays on the
236+ // pool's pending garbage list once released.
237+ descriptorSet->setQueueSerial(rx::QueueSerial(0, rx::Serial::Infinite()));
238+ descriptorSet.reset();
239+ 
240+ dynamicPool.destroy(contextVk->getDevice());
241+ 
242+ descriptorSetLayout.reset();
243+ mDescriptorSetLayoutCache.destroy(contextVk->getRenderer());
244+}
245+ 
211ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetTest, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER());246ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetTest, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER());
212-ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetLayoutDescTest, ES31_VULKAN());247+ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetLayoutDescTest, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER());
248+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanDescriptorSetLayoutDescTest);
213 249 
214} // namespace250} // namespace