Skip to content

Commit b01d466

Browse files
committed
Added enabling of and checks for VK_EXT_memory_budget
1 parent 599a8c5 commit b01d466

2 files changed

Lines changed: 55 additions & 19 deletions

File tree

include/vsg/vk/Device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ namespace vsg
8585
/// return true if Device was created with specified extension
8686
bool supportsDeviceExtension(const char* extensionName) const;
8787

88+
/// commonly checked extensions
89+
const bool memory_budget = false; // VK_EXT_memory_budget
90+
8891
/// return the amount of remaining memory, compatible with specified flags, available that can be allocated.
8992
VkDeviceSize availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit = 1.0) const;
9093

src/vsg/vk/Device.cpp

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ static void releaseDeviceID(uint32_t deviceID)
5353

5454
Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSettings, Names layers, Names deviceExtensions, const DeviceFeatures* deviceFeatures, AllocationCallbacks* allocator) :
5555
deviceID(getUniqueDeviceID()),
56-
enabledExtensions(deviceExtensions),
5756
_instance(physicalDevice->getInstance()),
5857
_physicalDevice(physicalDevice),
5958
_allocator(allocator)
@@ -115,6 +114,12 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting
115114
deviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
116115
#endif
117116

117+
if (_physicalDevice->supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME))
118+
{
119+
deviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
120+
const_cast<bool&>(memory_budget) = true;
121+
}
122+
118123
VkDeviceCreateInfo createInfo = {};
119124
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
120125

@@ -162,6 +167,7 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting
162167
}
163168
}
164169

170+
const_cast<Names&>(enabledExtensions) = deviceExtensions;
165171
_extensions = DeviceExtensions::create(this);
166172
}
167173

@@ -208,32 +214,59 @@ bool Device::supportsDeviceExtension(const char* extensionName) const
208214

209215
VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const
210216
{
211-
VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
212-
memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
213-
memoryBudget.pNext = nullptr;
217+
if (memory_budget)
218+
{
219+
VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
220+
memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
221+
memoryBudget.pNext = nullptr;
214222

215-
VkPhysicalDeviceMemoryProperties2 dmp;
216-
dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
217-
dmp.pNext = &memoryBudget;
223+
VkPhysicalDeviceMemoryProperties2 dmp;
224+
dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
225+
dmp.pNext = &memoryBudget;
218226

219-
vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp);
227+
vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp);
220228

221-
auto& memoryProperties = dmp.memoryProperties;
229+
auto& memoryProperties = dmp.memoryProperties;
222230

223-
VkDeviceSize availableSpace = 0;
224-
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
231+
VkDeviceSize availableSpace = 0;
232+
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
233+
{
234+
if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
235+
{
236+
uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex;
237+
238+
VkDeviceSize heapBudget = static_cast<VkDeviceSize>(static_cast<double>(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit);
239+
VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex];
240+
VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0;
241+
availableSpace += heapAvailable;
242+
243+
break;
244+
}
245+
}
246+
247+
return availableSpace;
248+
}
249+
else
225250
{
226-
if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
251+
VkPhysicalDeviceMemoryProperties memoryProperties;
252+
vkGetPhysicalDeviceMemoryProperties(*(getPhysicalDevice()), &memoryProperties);
253+
254+
VkDeviceSize availableSpace = 0;
255+
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
227256
{
228-
uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex;
257+
if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
258+
{
259+
uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex;
260+
261+
VkDeviceSize heapBudget = static_cast<VkDeviceSize>(static_cast<double>(memoryProperties.memoryHeaps[heapIndex].size) * allocatedMemoryLimit);;
229262

230-
VkDeviceSize heapBudget = static_cast<VkDeviceSize>(static_cast<double>(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit);
231-
VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex];
232-
VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0;
233-
availableSpace += heapAvailable;
263+
// unable to estimate usage, so assume whole budget is available and let calling code gracefully handle any memory allocation failures.
264+
availableSpace += heapBudget;
234265

235-
break;
266+
break;
267+
}
236268
}
269+
270+
return availableSpace;
237271
}
238-
return availableSpace;
239272
}

0 commit comments

Comments
 (0)