Skip to content

Commit 9d802ed

Browse files
mbaitAlexander Solovets
authored andcommitted
Fix Device::availableMemory crash on Vulkan 1.0 instances
vkGetPhysicalDeviceMemoryProperties2 and VkPhysicalDeviceMemoryBudgetPropertiesEXT were called unconditionally, but the former requires Vulkan 1.1 and the latter requires VK_EXT_memory_budget. On a 1.0 instance this triggered undefined behaviour and crashed Lavapipe during scene compilation. Gate the 1.1 path on both preconditions and fall back to vkGetPhysicalDeviceMemoryProperties with heap sizes when either is missing.
1 parent 599a8c5 commit 9d802ed

1 file changed

Lines changed: 25 additions & 10 deletions

File tree

src/vsg/vk/Device.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,30 @@ bool Device::supportsDeviceExtension(const char* extensionName) const
208208

209209
VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const
210210
{
211-
VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
212-
memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
213-
memoryBudget.pNext = nullptr;
211+
// vkGetPhysicalDeviceMemoryProperties2 requires Vulkan 1.1, and the chained
212+
// VkPhysicalDeviceMemoryBudgetPropertiesEXT additionally requires VK_EXT_memory_budget.
213+
// Fall back to the 1.0 query (no live budget tracking) when either is missing.
214+
const bool useBudget = supportsApiVersion(VK_API_VERSION_1_1) &&
215+
supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
214216

215-
VkPhysicalDeviceMemoryProperties2 dmp;
216-
dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
217-
dmp.pNext = &memoryBudget;
217+
VkPhysicalDeviceMemoryProperties memoryProperties;
218+
VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget = {};
218219

219-
vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp);
220+
if (useBudget)
221+
{
222+
memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
223+
224+
VkPhysicalDeviceMemoryProperties2 dmp = {};
225+
dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
226+
dmp.pNext = &memoryBudget;
220227

221-
auto& memoryProperties = dmp.memoryProperties;
228+
vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp);
229+
memoryProperties = dmp.memoryProperties;
230+
}
231+
else
232+
{
233+
vkGetPhysicalDeviceMemoryProperties(*(getPhysicalDevice()), &memoryProperties);
234+
}
222235

223236
VkDeviceSize availableSpace = 0;
224237
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
@@ -227,8 +240,10 @@ VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags
227240
{
228241
uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex;
229242

230-
VkDeviceSize heapBudget = static_cast<VkDeviceSize>(static_cast<double>(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit);
231-
VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex];
243+
VkDeviceSize heapBudget = useBudget ? memoryBudget.heapBudget[heapIndex] : memoryProperties.memoryHeaps[heapIndex].size;
244+
VkDeviceSize heapUsage = useBudget ? memoryBudget.heapUsage[heapIndex] : 0;
245+
246+
heapBudget = static_cast<VkDeviceSize>(static_cast<double>(heapBudget) * allocatedMemoryLimit);
232247
VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0;
233248
availableSpace += heapAvailable;
234249

0 commit comments

Comments
 (0)