Support the VK_EXT_memory_budget extension.

This requires macOS 10.13 or iOS 11, for the `currentAllocatedSize`
property of `MTLDevice`. Ideally, we'd check for that method instead of
keying on the version.
This commit is contained in:
Chip Davis 2019-01-31 11:02:48 -06:00
parent e703705a9a
commit 3df6d2d00f
6 changed files with 40 additions and 4 deletions

View File

@ -243,6 +243,7 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
- `VK_KHR_swapchain`
- `VK_KHR_swapchain_mutable_format`
- `VK_KHR_variable_pointers`
- `VK_EXT_memory_budget`
- `VK_EXT_shader_viewport_index_layer`
- `VK_EXT_vertex_attribute_divisor`
- `VK_EXTX_portability_subset`

View File

@ -210,7 +210,7 @@ public:
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties);
/** Populates the specified memory properties with the memory characteristics of this device. */
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
/**
* Returns a bit mask of all memory type indices.

View File

@ -165,7 +165,7 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
break;
}
default:
next = (MVKVkAPIStructHeader*)((VkPhysicalDeviceProperties2*)next)->pNext;
next = (MVKVkAPIStructHeader*)next->pNext;
break;
}
}
@ -612,10 +612,29 @@ VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMe
return VK_SUCCESS;
}
VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties) {
VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
if (pMemoryProperties) {
pMemoryProperties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR;
pMemoryProperties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
pMemoryProperties->memoryProperties = _memoryProperties;
auto* next = (MVKVkAPIStructHeader*)pMemoryProperties->pNext;
while (next) {
switch ((uint32_t)next->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: {
auto* budgetProps = (VkPhysicalDeviceMemoryBudgetPropertiesEXT*)next;
memset(budgetProps->heapBudget, 0, sizeof(budgetProps->heapBudget));
memset(budgetProps->heapUsage, 0, sizeof(budgetProps->heapUsage));
budgetProps->heapBudget[0] = (VkDeviceSize)mvkRecommendedMaxWorkingSetSize(_mtlDevice);
if ( [_mtlDevice respondsToSelector: @selector(currentAllocatedSize)] ) {
budgetProps->heapUsage[0] = (VkDeviceSize)_mtlDevice.currentAllocatedSize;
}
next = (MVKVkAPIStructHeader*)budgetProps->pNext;
break;
}
default:
next = (MVKVkAPIStructHeader*)next->pNext;
break;
}
}
}
return VK_SUCCESS;
}

View File

@ -18,6 +18,7 @@
#include "MVKExtensions.h"
#include "MVKFoundation.h"
#include "MVKOSExtensions.h"
#include "vk_mvk_moltenvk.h"
#include <vulkan/vulkan_ios.h>
#include <vulkan/vulkan_macos.h>
@ -103,11 +104,17 @@ string MVKExtensionList::enabledNamesString(const char* separator, bool prefixFi
// Returns whether the specified properties are valid for this platform
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
#if !(MVK_IOS)
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 10.13;
}
if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
#endif
#if !(MVK_MACOS)
if (pProperties == &kVkExtProps_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE) { return false; }
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 11.0;
}
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
#endif

View File

@ -51,6 +51,7 @@ MVK_EXTENSION(KHR_surface, KHR_SURFACE)
MVK_EXTENSION(KHR_swapchain, KHR_SWAPCHAIN)
MVK_EXTENSION(KHR_swapchain_mutable_format, KHR_SWAPCHAIN_MUTABLE_FORMAT)
MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS)
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET)
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER)
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR)
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET)

View File

@ -22,7 +22,9 @@
#include "MVKFoundation.h"
#include <string>
#ifdef __OBJC__
#import <Metal/Metal.h>
#endif
typedef float MVKOSVersion;
@ -59,6 +61,7 @@ double mvkGetTimestampPeriod();
*/
double mvkGetElapsedMilliseconds(uint64_t startTimestamp = 0, uint64_t endTimestamp = 0);
#ifdef __OBJC__
/** Ensures the block is executed on the main thread. */
inline void mvkDispatchToMainAndWait(dispatch_block_t block) {
if (NSThread.isMainThread) {
@ -67,12 +70,14 @@ inline void mvkDispatchToMainAndWait(dispatch_block_t block) {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
#endif
#pragma mark -
#pragma mark Process environment
#ifdef __OBJC__
/**
* Returns the value of the environment variable at the given name,
* or an empty string if no environment variable with that name exists.
@ -130,11 +135,13 @@ inline bool mvkGetEnvVarBool(std::string varName, bool* pWasFound = nullptr) {
int64_t val = wasFound ? ev : EV; \
cfgVal = (int32_t)mvkClamp(val, (int64_t)INT32_MIN, (int64_t)INT32_MAX); \
} while(false)
#endif
#pragma mark -
#pragma mark MTLDevice
#ifdef __OBJC__
/** Returns an approximation of how much memory, in bytes, the device can use with good performance. */
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice);
@ -147,3 +154,4 @@ void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlD
* The format must support linear texture memory (must not be depth, stencil, or compressed).
*/
VkDeviceSize mvkMTLPixelFormatLinearTextureAlignment(MTLPixelFormat mtlPixelFormat, id<MTLDevice> mtlDevice);
#endif