Merge branch 'master' of https://github.com/KhronosGroup/MoltenVK
This commit is contained in:
commit
de29ba9318
@ -253,11 +253,13 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
|
||||
- `VK_EXT_debug_report`
|
||||
- `VK_EXT_debug_utils`
|
||||
- `VK_EXT_host_query_reset`
|
||||
- `VK_EXT_memory_budget`
|
||||
- `VK_EXT_memory_budget` *(requires Metal 2.0)*
|
||||
- `VK_EXT_metal_surface`
|
||||
- `VK_EXT_shader_stencil_export` *(requires Mac GPU family 2 or iOS GPU family 5)*
|
||||
- `VK_EXT_shader_viewport_index_layer`
|
||||
- `VK_EXT_swapchain_colorspace` *(macOS)*
|
||||
- `VK_EXT_vertex_attribute_divisor`
|
||||
- `VK_EXT_texel_buffer_alignment` *(requires Metal 2.0)*
|
||||
- `VK_EXTX_portability_subset`
|
||||
- `VK_MVK_ios_surface` *(iOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
||||
- `VK_MVK_macos_surface` *(macOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
||||
|
@ -1 +1 @@
|
||||
097a1045098213919fd56442f52c716fc78eeb27
|
||||
737f4c1cd96283747967c2024a0108b742214455
|
||||
|
@ -223,6 +223,7 @@ MVKBufferView::MVKBufferView(MVKDevice* device, const VkBufferViewCreateInfo* pC
|
||||
// We can just use a simple 1D texel array.
|
||||
_textureSize.width = uint32_t(blockCount * fmtBlockSize.width);
|
||||
_textureSize.height = 1;
|
||||
_mtlBytesPerRow = byteCount;
|
||||
}
|
||||
|
||||
if ( !_device->_pMetalFeatures->texelBuffers ) {
|
||||
|
@ -336,6 +336,7 @@ protected:
|
||||
VkPhysicalDeviceFeatures _features;
|
||||
MVKPhysicalDeviceMetalFeatures _metalFeatures;
|
||||
VkPhysicalDeviceProperties _properties;
|
||||
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT _texelBuffAlignProperties;
|
||||
VkPhysicalDeviceMemoryProperties _memoryProperties;
|
||||
std::vector<MVKQueueFamily*> _queueFamilies;
|
||||
uint32_t _allMemoryTypes;
|
||||
|
@ -69,8 +69,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
if (features) {
|
||||
features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
features->features = _features;
|
||||
auto* next = (VkBaseOutStructure*)features->pNext;
|
||||
while (next) {
|
||||
for (auto* next = (VkBaseOutStructure*)features->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
||||
auto* storageFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
|
||||
@ -109,6 +108,11 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
hostQueryResetFeatures->hostQueryReset = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
|
||||
auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
|
||||
texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)];
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
|
||||
auto* divisorFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
|
||||
divisorFeatures->vertexAttributeInstanceRateDivisor = true;
|
||||
@ -127,7 +131,6 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next = next->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,42 +143,44 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
|
||||
if (properties) {
|
||||
properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties->properties = _properties;
|
||||
auto* next = (MVKVkAPIStructHeader*)properties->pNext;
|
||||
while (next) {
|
||||
for (auto* next = (VkBaseOutStructure*)properties->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
|
||||
auto* pointClipProps = (VkPhysicalDevicePointClippingProperties*)next;
|
||||
pointClipProps->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
|
||||
next = (MVKVkAPIStructHeader*)pointClipProps->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
|
||||
auto* maint3Props = (VkPhysicalDeviceMaintenance3Properties*)next;
|
||||
maint3Props->maxPerSetDescriptors = (_metalFeatures.maxPerStageBufferCount + _metalFeatures.maxPerStageTextureCount + _metalFeatures.maxPerStageSamplerCount) * 2;
|
||||
maint3Props->maxPerSetDescriptors = (_metalFeatures.maxPerStageBufferCount + _metalFeatures.maxPerStageTextureCount + _metalFeatures.maxPerStageSamplerCount) * 4;
|
||||
maint3Props->maxMemoryAllocationSize = _metalFeatures.maxMTLBufferSize;
|
||||
next = (MVKVkAPIStructHeader*)maint3Props->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
|
||||
auto* pushDescProps = (VkPhysicalDevicePushDescriptorPropertiesKHR*)next;
|
||||
pushDescProps->maxPushDescriptors = _properties.limits.maxPerStageResources;
|
||||
next = (MVKVkAPIStructHeader*)pushDescProps->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {
|
||||
auto* texelBuffAlignProps = (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT*)next;
|
||||
// Save the 'next' pointer; we'll unintentionally overwrite it
|
||||
// on the next line. Put it back when we're done.
|
||||
void* savedNext = texelBuffAlignProps->pNext;
|
||||
*texelBuffAlignProps = _texelBuffAlignProperties;
|
||||
texelBuffAlignProps->pNext = savedNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
||||
auto* divisorProps = (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT*)next;
|
||||
divisorProps->maxVertexAttribDivisor = kMVKUndefinedLargeUInt32;
|
||||
next = (MVKVkAPIStructHeader*)divisorProps->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_EXTX: {
|
||||
auto* portabilityProps = (VkPhysicalDevicePortabilitySubsetPropertiesEXTX*)next;
|
||||
portabilityProps->minVertexInputBindingStrideAlignment = 4;
|
||||
next = (MVKVkAPIStructHeader*)portabilityProps->pNext;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -466,22 +471,42 @@ VkResult MVKPhysicalDevice::getSurfaceFormats(MVKSurface* surface,
|
||||
MTLPixelFormatRGBA16Float,
|
||||
};
|
||||
|
||||
MVKVectorInline<VkColorSpaceKHR, 16> colorSpaces;
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR);
|
||||
#if MVK_MACOS
|
||||
if (getInstance()->_enabledExtensions.vk_EXT_swapchain_colorspace.enabled) {
|
||||
// 10.11 supports some but not all of the color spaces specified by VK_EXT_swapchain_colorspace.
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT);
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT);
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_BT709_NONLINEAR_EXT);
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT);
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_PASS_THROUGH_EXT);
|
||||
if (mvkOSVersion() >= 10.12) {
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT);
|
||||
colorSpaces.push_back(VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint mtlFmtsCnt = sizeof(mtlFormats) / sizeof(MTLPixelFormat);
|
||||
const uint vkFmtsCnt = mtlFmtsCnt * (uint)colorSpaces.size();
|
||||
|
||||
// If properties aren't actually being requested yet, simply update the returned count
|
||||
if ( !pSurfaceFormats ) {
|
||||
*pCount = mtlFmtsCnt;
|
||||
*pCount = vkFmtsCnt;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// Determine how many results we'll return, and return that number
|
||||
VkResult result = (*pCount >= mtlFmtsCnt) ? VK_SUCCESS : VK_INCOMPLETE;
|
||||
*pCount = min(*pCount, mtlFmtsCnt);
|
||||
VkResult result = (*pCount >= vkFmtsCnt) ? VK_SUCCESS : VK_INCOMPLETE;
|
||||
*pCount = min(*pCount, vkFmtsCnt);
|
||||
|
||||
// Now populate the supplied array
|
||||
for (uint fmtIdx = 0; fmtIdx < *pCount; fmtIdx++) {
|
||||
pSurfaceFormats[fmtIdx].format = mvkVkFormatFromMTLPixelFormat(mtlFormats[fmtIdx]);
|
||||
pSurfaceFormats[fmtIdx].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
for (uint csIdx = 0, idx = 0; idx < *pCount && csIdx < colorSpaces.size(); csIdx++) {
|
||||
for (uint fmtIdx = 0; idx < *pCount && fmtIdx < mtlFmtsCnt; fmtIdx++, idx++) {
|
||||
pSurfaceFormats[idx].format = mvkVkFormatFromMTLPixelFormat(mtlFormats[fmtIdx]);
|
||||
pSurfaceFormats[idx].colorSpace = colorSpaces[csIdx];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1093,14 +1118,86 @@ void MVKPhysicalDevice::initProperties() {
|
||||
_properties.limits.bufferImageGranularity = _metalFeatures.mtlBufferAlignment;
|
||||
_properties.limits.nonCoherentAtomSize = _metalFeatures.mtlBufferAlignment;
|
||||
|
||||
if ([_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)]) {
|
||||
// Figure out the greatest alignment required by all supported formats, and
|
||||
// whether or not they only require alignment to a single texel. We'll use this
|
||||
// information to fill out the VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT
|
||||
// struct.
|
||||
uint32_t maxStorage = 0, maxUniform = 0;
|
||||
bool singleTexelStorage = true, singleTexelUniform = true;
|
||||
mvkEnumerateSupportedFormats({0, 0, VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT}, true, [&](VkFormat vk) {
|
||||
NSUInteger alignment;
|
||||
if ([_mtlDevice respondsToSelector: @selector(minimumTextureBufferAlignmentForPixelFormat:)]) {
|
||||
alignment = [_mtlDevice minimumTextureBufferAlignmentForPixelFormat: mvkMTLPixelFormatFromVkFormat(vk)];
|
||||
} else {
|
||||
alignment = [_mtlDevice minimumLinearTextureAlignmentForPixelFormat: mvkMTLPixelFormatFromVkFormat(vk)];
|
||||
}
|
||||
VkFormatProperties props = mvkVkFormatProperties(vk, getFormatIsSupported(vk));
|
||||
// For uncompressed formats, this is the size of a single texel.
|
||||
// Note that no implementations of Metal support compressed formats
|
||||
// in a linear texture (including texture buffers). It's likely that even
|
||||
// if they did, this would be the absolute minimum alignment.
|
||||
uint32_t texelSize = mvkVkFormatBytesPerBlock(vk);
|
||||
// From the spec:
|
||||
// "If the size of a single texel is a multiple of three bytes, then
|
||||
// the size of a single component of the format is used instead."
|
||||
if (texelSize % 3 == 0) {
|
||||
switch (mvkFormatTypeFromVkFormat(vk)) {
|
||||
case kMVKFormatColorInt8:
|
||||
case kMVKFormatColorUInt8:
|
||||
texelSize = 1;
|
||||
break;
|
||||
case kMVKFormatColorHalf:
|
||||
case kMVKFormatColorInt16:
|
||||
case kMVKFormatColorUInt16:
|
||||
texelSize = 2;
|
||||
break;
|
||||
case kMVKFormatColorFloat:
|
||||
case kMVKFormatColorInt32:
|
||||
case kMVKFormatColorUInt32:
|
||||
default:
|
||||
texelSize = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
|
||||
maxStorage = max(maxStorage, uint32_t(alignment));
|
||||
if (alignment % texelSize != 0) { singleTexelStorage = false; }
|
||||
}
|
||||
if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) {
|
||||
maxUniform = max(maxUniform, uint32_t(alignment));
|
||||
if (alignment % texelSize != 0) { singleTexelUniform = false; }
|
||||
}
|
||||
return true;
|
||||
});
|
||||
_texelBuffAlignProperties.storageTexelBufferOffsetAlignmentBytes = maxStorage;
|
||||
_texelBuffAlignProperties.storageTexelBufferOffsetSingleTexelAlignment = singleTexelStorage;
|
||||
_texelBuffAlignProperties.uniformTexelBufferOffsetAlignmentBytes = maxUniform;
|
||||
_texelBuffAlignProperties.uniformTexelBufferOffsetSingleTexelAlignment = singleTexelUniform;
|
||||
_properties.limits.minTexelBufferOffsetAlignment = max(maxStorage, maxUniform);
|
||||
} else {
|
||||
#if MVK_IOS
|
||||
if ([_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1]) {
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 16;
|
||||
} else {
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 64;
|
||||
}
|
||||
#endif
|
||||
#if MVK_MACOS
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 256;
|
||||
#endif
|
||||
_texelBuffAlignProperties.storageTexelBufferOffsetAlignmentBytes = _properties.limits.minTexelBufferOffsetAlignment;
|
||||
_texelBuffAlignProperties.storageTexelBufferOffsetSingleTexelAlignment = VK_FALSE;
|
||||
_texelBuffAlignProperties.uniformTexelBufferOffsetAlignmentBytes = _properties.limits.minTexelBufferOffsetAlignment;
|
||||
_texelBuffAlignProperties.uniformTexelBufferOffsetSingleTexelAlignment = VK_FALSE;
|
||||
}
|
||||
|
||||
#if MVK_IOS
|
||||
_properties.limits.maxFragmentInputComponents = 60;
|
||||
|
||||
if ([_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1]) {
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 16;
|
||||
_properties.limits.optimalBufferCopyOffsetAlignment = 16;
|
||||
} else {
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 64;
|
||||
_properties.limits.optimalBufferCopyOffsetAlignment = 64;
|
||||
}
|
||||
|
||||
@ -1117,7 +1214,6 @@ void MVKPhysicalDevice::initProperties() {
|
||||
#endif
|
||||
#if MVK_MACOS
|
||||
_properties.limits.maxFragmentInputComponents = 128;
|
||||
_properties.limits.minTexelBufferOffsetAlignment = 256;
|
||||
_properties.limits.optimalBufferCopyOffsetAlignment = 256;
|
||||
|
||||
if ([_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2]) {
|
||||
|
@ -226,12 +226,40 @@ void MVKSwapchain::initCAMetalLayer(const VkSwapchainCreateInfoKHR* pCreateInfo,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_STORAGE_BIT));
|
||||
#if MVK_MACOS
|
||||
switch (pCreateInfo->imageColorSpace) {
|
||||
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
break;
|
||||
case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
|
||||
break;
|
||||
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB);
|
||||
break;
|
||||
case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceDCIP3);
|
||||
break;
|
||||
case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceITUR_709);
|
||||
break;
|
||||
case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceAdobeRGB1998);
|
||||
break;
|
||||
case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
|
||||
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
|
||||
break;
|
||||
case VK_COLOR_SPACE_PASS_THROUGH_EXT:
|
||||
default:
|
||||
// Nothing - the default is not to do color matching.
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
_mtlLayerOrigDrawSize = _mtlLayer.updatedDrawableSizeMVK;
|
||||
|
||||
// TODO: set additional CAMetalLayer properties before extracting drawables:
|
||||
// - presentsWithTransaction
|
||||
// - drawsAsynchronously
|
||||
// - colorspace (macOS only) Vulkan only supports sRGB colorspace for now.
|
||||
// - wantsExtendedDynamicRangeContent (macOS only)
|
||||
|
||||
if ( [_mtlLayer.delegate isKindOfClass: [PLATFORM_VIEW_CLASS class]] ) {
|
||||
|
@ -61,6 +61,8 @@ MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET)
|
||||
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE)
|
||||
MVK_EXTENSION(EXT_shader_stencil_export, EXT_SHADER_STENCIL_EXPORT)
|
||||
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER)
|
||||
MVK_EXTENSION(EXT_swapchain_colorspace, EXT_SWAPCHAIN_COLOR_SPACE)
|
||||
MVK_EXTENSION(EXT_texel_buffer_alignment, EXT_TEXEL_BUFFER_ALIGNMENT)
|
||||
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR)
|
||||
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET)
|
||||
MVK_EXTENSION(MVK_ios_surface, MVK_IOS_SURFACE)
|
||||
@ -68,6 +70,7 @@ MVK_EXTENSION(MVK_macos_surface, MVK_MACOS_SURFACE)
|
||||
MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK)
|
||||
MVK_EXTENSION(AMD_gpu_shader_half_float, AMD_GPU_SHADER_HALF_FLOAT)
|
||||
MVK_EXTENSION(AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT)
|
||||
MVK_EXTENSION(AMD_shader_image_load_store_lod, AMD_SHADER_IMAGE_LOAD_STORE_LOD)
|
||||
MVK_EXTENSION(IMG_format_pvrtc, IMG_FORMAT_PVRTC)
|
||||
MVK_EXTENSION_LAST(NV_glsl_shader, NV_GLSL_SHADER)
|
||||
|
||||
|
@ -46,17 +46,21 @@ static VkExtensionProperties kVkExtProps_ ##EXT = mvkMakeExtProps(VK_ ##EXT ##_E
|
||||
|
||||
// Returns whether the specified properties are valid for this platform
|
||||
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
|
||||
#if !(MVK_IOS)
|
||||
#if MVK_MACOS
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
|
||||
return mvkOSVersion() >= 10.13;
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) {
|
||||
return mvkOSVersion() >= 10.14;
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) {
|
||||
return mvkOSVersion() >= 10.13;
|
||||
}
|
||||
if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_IMAGE_LOAD_STORE_LOD) { return false; }
|
||||
if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
|
||||
#endif
|
||||
#if !(MVK_MACOS)
|
||||
#if MVK_IOS
|
||||
if (pProperties == &kVkExtProps_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
|
||||
return mvkOSVersion() >= 11.0;
|
||||
@ -64,6 +68,10 @@ static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) {
|
||||
return mvkOSVersion() >= 12.0;
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_SWAPCHAIN_COLOR_SPACE) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) {
|
||||
return mvkOSVersion() >= 11.0;
|
||||
}
|
||||
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
|
||||
#endif
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "mvk_datatypes.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
class MVKBaseObject;
|
||||
|
||||
/*
|
||||
@ -75,4 +77,13 @@ MTLWinding mvkMTLWindingFromSpvExecutionModeInObj(uint32_t spvMode, MVKBaseObjec
|
||||
MTLTessellationPartitionMode mvkMTLTessellationPartitionModeFromSpvExecutionModeInObj(uint32_t spvMode, MVKBaseObject* mvkObj);
|
||||
#define mvkMTLTessellationPartitionModeFromSpvExecutionMode(spvMode) mvkMTLTessellationPartitionModeFromSpvExecutionModeInObj(spvMode, this)
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Image properties
|
||||
|
||||
#pragma mark Texture formats
|
||||
|
||||
/** Enumerates all formats that support the given features, calling a specified function for each one. */
|
||||
void mvkEnumerateSupportedFormats(VkFormatProperties properties, bool any, std::function<bool(VkFormat)> func);
|
||||
|
||||
#endif
|
||||
|
@ -665,6 +665,25 @@ MVK_PUBLIC_SYMBOL const char* mvkMTLPixelFormatName(MTLPixelFormat mtlFormat) {
|
||||
return formatDescForMTLPixelFormat(mtlFormat).mtlName;
|
||||
}
|
||||
|
||||
void mvkEnumerateSupportedFormats(VkFormatProperties properties, bool any, std::function<bool(VkFormat)> func) {
|
||||
static const auto areFeaturesSupported = [any](uint32_t a, uint32_t b) {
|
||||
if (any)
|
||||
return mvkIsAnyFlagEnabled(a, b);
|
||||
else
|
||||
return mvkAreAllFlagsEnabled(a, b);
|
||||
};
|
||||
for (auto& formatDesc : _formatDescriptions) {
|
||||
if (formatDesc.isSupported() &&
|
||||
areFeaturesSupported(formatDesc.properties.linearTilingFeatures, properties.linearTilingFeatures) &&
|
||||
areFeaturesSupported(formatDesc.properties.optimalTilingFeatures, properties.optimalTilingFeatures) &&
|
||||
areFeaturesSupported(formatDesc.properties.bufferFeatures, properties.bufferFeatures)) {
|
||||
if (!func(formatDesc.vk)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef mvkMTLVertexFormatFromVkFormat
|
||||
MVK_PUBLIC_SYMBOL MTLVertexFormat mvkMTLVertexFormatFromVkFormat(VkFormat vkFormat) {
|
||||
return mvkMTLVertexFormatFromVkFormatInObj(vkFormat, nullptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user