@@ -53,7 +53,6 @@ static void releaseDeviceID(uint32_t deviceID)
5353
5454Device::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,11 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting
115114 deviceExtensions.push_back (VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME );
116115#endif
117116
117+ if (supportsApiVersion (VK_API_VERSION_1_1 ) && _physicalDevice->supportsDeviceExtension (VK_EXT_MEMORY_BUDGET_EXTENSION_NAME ))
118+ {
119+ deviceExtensions.push_back (VK_EXT_MEMORY_BUDGET_EXTENSION_NAME );
120+ }
121+
118122 VkDeviceCreateInfo createInfo = {};
119123 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO ;
120124
@@ -162,6 +166,7 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting
162166 }
163167 }
164168
169+ const_cast <Names&>(enabledExtensions) = deviceExtensions;
165170 _extensions = DeviceExtensions::create (this );
166171}
167172
@@ -208,32 +213,59 @@ bool Device::supportsDeviceExtension(const char* extensionName) const
208213
209214VkDeviceSize Device::availableMemory (VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const
210215{
211- VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
212- memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT ;
213- memoryBudget.pNext = nullptr ;
216+ if (_extensions->memory_budget )
217+ {
218+ VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
219+ memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT ;
220+ memoryBudget.pNext = nullptr ;
214221
215- VkPhysicalDeviceMemoryProperties2 dmp;
216- dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 ;
217- dmp.pNext = &memoryBudget;
222+ VkPhysicalDeviceMemoryProperties2 dmp;
223+ dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 ;
224+ dmp.pNext = &memoryBudget;
218225
219- vkGetPhysicalDeviceMemoryProperties2 (*(getPhysicalDevice ()), &dmp);
226+ vkGetPhysicalDeviceMemoryProperties2 (*(getPhysicalDevice ()), &dmp);
220227
221- auto & memoryProperties = dmp.memoryProperties ;
228+ auto & memoryProperties = dmp.memoryProperties ;
222229
223- VkDeviceSize availableSpace = 0 ;
224- for (uint32_t i = 0 ; i < memoryProperties.memoryTypeCount ; ++i)
230+ VkDeviceSize availableSpace = 0 ;
231+ for (uint32_t i = 0 ; i < memoryProperties.memoryTypeCount ; ++i)
232+ {
233+ if ((memoryProperties.memoryTypes [i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
234+ {
235+ uint32_t heapIndex = memoryProperties.memoryTypes [i].heapIndex ;
236+
237+ VkDeviceSize heapBudget = static_cast <VkDeviceSize>(static_cast <double >(memoryBudget.heapBudget [heapIndex]) * allocatedMemoryLimit);
238+ VkDeviceSize heapUsage = memoryBudget.heapUsage [heapIndex];
239+ VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0 ;
240+ availableSpace += heapAvailable;
241+
242+ break ;
243+ }
244+ }
245+
246+ return availableSpace;
247+ }
248+ else
225249 {
226- if ((memoryProperties.memoryTypes [i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
250+ VkPhysicalDeviceMemoryProperties memoryProperties;
251+ vkGetPhysicalDeviceMemoryProperties (*(getPhysicalDevice ()), &memoryProperties);
252+
253+ VkDeviceSize availableSpace = 0 ;
254+ for (uint32_t i = 0 ; i < memoryProperties.memoryTypeCount ; ++i)
227255 {
228- uint32_t heapIndex = memoryProperties.memoryTypes [i].heapIndex ;
256+ if ((memoryProperties.memoryTypes [i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported
257+ {
258+ uint32_t heapIndex = memoryProperties.memoryTypes [i].heapIndex ;
259+
260+ VkDeviceSize heapBudget = static_cast <VkDeviceSize>(static_cast <double >(memoryProperties.memoryHeaps [heapIndex].size ) * allocatedMemoryLimit);;
229261
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;
262+ // unable to estimate usage, so assume whole budget is available and let calling code gracefully handle any memory allocation failures.
263+ availableSpace += heapBudget;
234264
235- break ;
265+ break ;
266+ }
236267 }
268+
269+ return availableSpace;
237270 }
238- return availableSpace;
239271}
0 commit comments