Browse Source

Vk: fix DescriptorPool::allocate() w/o VK_KHR_maintenance1.

Heh, somehow every time I run the full battery of tests I discover
another failure.

NVidia, with Vulkan version forced to 1.0 and when VK_KHR_maintenance1
isn't enabled, returns VK_ERROR_OUT_OF_DEVICE_MEMORY. So whitelist that
error as well and treat it as allocation failure and not a fatal error.
pull/651/head
Vladimír Vondruš 2 years ago
parent
commit
fd4d522cae
  1. 32
      src/Magnum/Vk/DescriptorPool.cpp

32
src/Magnum/Vk/DescriptorPool.cpp

@ -141,24 +141,23 @@ Containers::Pair<Result, DescriptorSet> DescriptorPool::allocateInternal(const V
info.descriptorPool = _handle; info.descriptorPool = _handle;
info.descriptorSetCount = 1; info.descriptorSetCount = 1;
info.pSetLayouts = &layout; info.pSetLayouts = &layout;
/* VK_ERROR_OUT_OF_POOL_MEMORY is only available since VK_KHR_maintenance1 /* VK_ERROR_OUT_OF_POOL_MEMORY is only available since VK_KHR_maintenance1.
and it's not really clear what was supposed to happen before that. At It's not really clear what was supposed to happen before that. At the
the very least, running the allocateFail() test using very least, running the allocateFail() test using
./VkDescriptorPoolVkTest --magnum-vulkan-version 1.0 --magnum-enable-layers VK_LAYER_KHRONOS_validation ./VkDescriptorPoolVkTest --magnum-vulkan-version 1.0 --magnum-disable-extensions VK_KHR_maintenance1 --magnum-enable-layers VK_LAYER_KHRONOS_validation
without VK_KHR_maintenance1 enabled, the validation layer complains that the validation layer complains that I'm allocating from a pool that
I'm allocating from a pool that doesn't have enough free items, which doesn't have enough free items, which implies it used to be a user error
implies it used to be a user error and thus the driver is free to do and thus the driver is free to do *anything*, including random crashes,
*anything*, including random crashes, as noted on as noted on https://community.khronos.org/t/descriptor-pool-able-to-allocate-even-though-pool-should-be-empty/7330/6
https://community.khronos.org/t/descriptor-pool-able-to-allocate-even-though-pool-should-be-empty/7330/6
From practical testing, even the oldest Vulkan driver I have (ARM Mali From practical testing, even the oldest Vulkan driver I have (ARM Mali
on Huawei P9, Vulkan 1.0.66) seems to return VK_ERROR_OUT_OF_POOL_MEMORY on Huawei P9, Vulkan 1.0.66) seems to return VK_ERROR_OUT_OF_POOL_MEMORY
no matter whether the extension is enabled or not. So I'll assume all no matter whether the extension is enabled or not. On the other hand,
contemporary drivers in early 2021 do this, there's nothing I can do NVidia returns VK_ERROR_OUT_OF_DEVICE_MEMORY in this case. So I'm
otherwise. */ testing for both. */
const Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).AllocateDescriptorSets(*_device, &info, &set._handle), Result::ErrorOutOfPoolMemory, Result::ErrorFragmentedPool); const Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).AllocateDescriptorSets(*_device, &info, &set._handle), Result::ErrorOutOfDeviceMemory, Result::ErrorOutOfPoolMemory, Result::ErrorFragmentedPool);
return {result, Utility::move(set)}; return {result, Utility::move(set)};
} }
@ -192,9 +191,10 @@ Containers::Pair<Result, DescriptorSet> DescriptorPool::allocateInternal(const V
info.descriptorPool = _handle; info.descriptorPool = _handle;
info.descriptorSetCount = 1; info.descriptorSetCount = 1;
info.pSetLayouts = &layout; info.pSetLayouts = &layout;
/* See the not about VK_ERROR_OUT_OF_POOL_MEMORY and VK_KHR_maintenance1 /* See the note about VK_ERROR_OUT_OF_{DEVICE,POOL}_MEMORY and
in the other allocateInternal() implementation above. */ VK_KHR_maintenance1 in the other allocateInternal() implementation
const Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).AllocateDescriptorSets(*_device, &info, &set._handle), Result::ErrorOutOfPoolMemory, Result::ErrorFragmentedPool); above. */
const Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).AllocateDescriptorSets(*_device, &info, &set._handle), Result::ErrorOutOfDeviceMemory, Result::ErrorOutOfPoolMemory, Result::ErrorFragmentedPool);
return {result, Utility::move(set)}; return {result, Utility::move(set)};
} }

Loading…
Cancel
Save