Add support for VK_EXTX_portability_subset extension.
Add KhronosGroup/Vulkan-Portability as external dependency repo. Add ExternalRevisions/Vulkan-Portability_repo_revision. Add vk_extx_portability_subset.h header file to mvk_vulkan.h. MVKImageView allow constructor with no image or device. Add mvkVkComponentMappingsMatch() & mvkVkComponentSwizzlesMatch() functions. Cleanup some local var init warnings.
This commit is contained in:
parent
100848304d
commit
e5a890775b
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@ External/cereal
|
||||
External/glslang
|
||||
External/SPIRV-Cross
|
||||
External/Vulkan-Headers
|
||||
External/Vulkan-Portability
|
||||
External/Vulkan-Tools
|
||||
External/VulkanSamples
|
||||
|
||||
|
@ -750,7 +750,7 @@
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/../../../External/Vulkan-Headers/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include\"",
|
||||
"\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"",
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@ -777,7 +777,7 @@
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/../../../External/Vulkan-Headers/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include\"",
|
||||
"\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.moltenvk.${PRODUCT_NAME:identifier}";
|
||||
|
@ -410,8 +410,7 @@
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include/MoltenVK\"",
|
||||
"\"$(SRCROOT)/../../../External/Vulkan-Headers/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include\"",
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
@ -435,8 +434,7 @@
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include/MoltenVK\"",
|
||||
"\"$(SRCROOT)/../../../External/Vulkan-Headers/include\"",
|
||||
"\"$(SRCROOT)/../../../MoltenVK/include\"",
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.moltenvk.${PRODUCT_NAME:identifier}";
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#import "DemoViewController.h"
|
||||
|
||||
#include "mvk_vulkan.h"
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
#include "../../Vulkan-Tools/cube/cube.c"
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#import "DemoViewController.h"
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#include "mvk_vulkan.h"
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
#include "../../Vulkan-Tools/cube/cube.c"
|
||||
|
||||
|
||||
|
@ -245,8 +245,9 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
|
||||
- `VK_KHR_variable_pointers`
|
||||
- `VK_EXT_shader_viewport_index_layer`
|
||||
- `VK_EXT_vertex_attribute_divisor`
|
||||
- `VK_MVK_macos_surface` (macOS)
|
||||
- `VK_EXTX_portability_subset`
|
||||
- `VK_MVK_ios_surface` (iOS)
|
||||
- `VK_MVK_macos_surface` (macOS)
|
||||
- `VK_MVK_moltenvk`
|
||||
- `VK_AMD_gpu_shader_half_float`
|
||||
- `VK_AMD_negative_viewport_height`
|
||||
|
1
ExternalRevisions/Vulkan-Portability_repo_revision
Normal file
1
ExternalRevisions/Vulkan-Portability_repo_revision
Normal file
@ -0,0 +1 @@
|
||||
53be040f04ce55463d0e5b25fd132f45f003e903
|
@ -378,6 +378,7 @@
|
||||
A9E53DFE21064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPipelineDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
|
||||
A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommonEnvironment.h; sourceTree = "<group>"; };
|
||||
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKLogging.h; sourceTree = "<group>"; };
|
||||
A9F2559121F96814008C7785 /* vulkan-portability */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "vulkan-portability"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -539,6 +540,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A9AD67C72054DD6C00ED3C08 /* vulkan */,
|
||||
A9F2559121F96814008C7785 /* vulkan-portability */,
|
||||
);
|
||||
path = include;
|
||||
sourceTree = "<group>";
|
||||
@ -1123,7 +1125,7 @@
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
GENERATE_MASTER_OBJECT_FILE = YES;
|
||||
@ -1179,7 +1181,7 @@
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
GENERATE_MASTER_OBJECT_FILE = YES;
|
||||
|
@ -40,5 +40,6 @@
|
||||
#endif
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan-portability/vk_extx_portability_subset.h>
|
||||
|
||||
#endif
|
||||
|
@ -375,26 +375,38 @@ typedef struct {
|
||||
VkBool32 switchSystemGPU;
|
||||
|
||||
/**
|
||||
* If enabled, arbitrary ImageView component swizzles are supported, as defined
|
||||
* If enabled, arbitrary VkImageView component swizzles are supported, as defined
|
||||
* in VkImageViewCreateInfo::components when creating a VkImageView.
|
||||
*
|
||||
* If disabled, a very limited set of ImageView component swizzles are supported
|
||||
* If disabled, a very limited set of VkImageView component swizzles are supported
|
||||
* via format substitutions.
|
||||
*
|
||||
* Metal does not natively support per-texture swizzling. If this parameter is enabled
|
||||
* when a pipeline is compiled, ImageView swizzling is automatically performed in the
|
||||
* converted Metal shader code during all texture sampling and reading operations,
|
||||
* regardless of whether a swizzle has been specified for the ImageView associated
|
||||
* with the Metal texture. This may result in reduced performance.
|
||||
* both when a VkImageView is created, and when any pipeline that uses that VkImageView
|
||||
* is compiled, VkImageView swizzling is automatically performed in the converted Metal
|
||||
* shader code during all texture sampling and reading operations, regardless of whether
|
||||
* a swizzle is required for the VkImageView associated with the Metal texture.
|
||||
* This may result in reduced performance.
|
||||
*
|
||||
* The value of this parameter may be changed at any time during application runtime,
|
||||
* and the changed value will immediately effect subsequent MoltenVK behaviour.
|
||||
* Specifically, this parameter can be enabled when compiling some pipelines,
|
||||
* and disabled when compiling others. Existing pipelines are not automatically
|
||||
* re-compiled when this parameter is changed.
|
||||
* Specifically, this parameter can be enabled when creating VkImageViews that need it,
|
||||
* and compiling pipelines that use those VkImageViews, and can be disabled when creating
|
||||
* VkImageViews that don't need it, and compiling pipelines that use those VkImageViews.
|
||||
*
|
||||
* If this parameter is disabled, the following limited set of ImageView swizzles
|
||||
* are supported by MoltenVK, via automatic format substitution:
|
||||
* Existing pipelines are not automatically re-compiled when this parameter is changed.
|
||||
*
|
||||
* An error is logged and returned during VkImageView creation if that VkImageView
|
||||
* requires full image view swizzling and this feature is not enabled. An error is
|
||||
* also logged when a pipeline that was not compiled with full image view swizzling
|
||||
* is presented with a VkImageView that is expecting it.
|
||||
*
|
||||
* An error is also retuned and logged when a VkPhysicalDeviceImageFormatInfo2KHR is passed
|
||||
* in a call to vkGetPhysicalDeviceImageFormatProperties2KHR() to query for an VkImageView
|
||||
* format that will require full swizzling to be enabled, and this feature is not enabled.
|
||||
*
|
||||
* If this parameter is disabled, the following limited set of VkImageView swizzles are
|
||||
* supported by MoltenVK, via automatic format substitution:
|
||||
*
|
||||
* Texture format Swizzle
|
||||
* -------------- -------
|
||||
|
@ -287,6 +287,7 @@ protected:
|
||||
std::vector<MVKQueueFamily*>& getQueueFamilies();
|
||||
void initPipelineCacheUUID();
|
||||
MTLFeatureSet getHighestMTLFeatureSet();
|
||||
bool getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo);
|
||||
void logGPUInfo();
|
||||
|
||||
id<MTLDevice> _mtlDevice;
|
||||
|
@ -65,7 +65,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
features->features = _features;
|
||||
auto* next = (MVKVkAPIStructHeader*)features->pNext;
|
||||
while (next) {
|
||||
switch (next->sType) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
||||
auto* storageFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
|
||||
storageFeatures->storageBuffer16BitAccess = true;
|
||||
@ -104,6 +104,16 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
next = (MVKVkAPIStructHeader*)divisorFeatures->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX: {
|
||||
auto* portabilityFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesEXTX*)next;
|
||||
portabilityFeatures->triangleFans = false;
|
||||
portabilityFeatures->separateStencilMaskRef = false;
|
||||
portabilityFeatures->events = false;
|
||||
portabilityFeatures->standardImageViews = false;
|
||||
portabilityFeatures->samplerMipLodBias = false;
|
||||
next = (MVKVkAPIStructHeader*)portabilityFeatures->pNext;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
@ -120,36 +130,42 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
|
||||
if (properties) {
|
||||
properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties->properties = _properties;
|
||||
auto* next = (VkStructureType*)properties->pNext;
|
||||
while (next) {
|
||||
switch (*next) {
|
||||
auto* next = (MVKVkAPIStructHeader*)properties->pNext;
|
||||
while (next) {
|
||||
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 = (VkStructureType*)pointClipProps->pNext;
|
||||
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->maxMemoryAllocationSize = _metalFeatures.maxMTLBufferSize;
|
||||
next = (VkStructureType*)maint3Props->pNext;
|
||||
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 = (VkStructureType*)pushDescProps->pNext;
|
||||
next = (MVKVkAPIStructHeader*)pushDescProps->pNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
||||
auto* divisorProps = (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT*)next;
|
||||
divisorProps->maxVertexAttribDivisor = kMVKUndefinedLargeUInt32;
|
||||
next = (VkStructureType*)divisorProps->pNext;
|
||||
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 = (VkStructureType*)((VkPhysicalDeviceProperties2*)next)->pNext;
|
||||
next = (MVKVkAPIStructHeader*)((VkPhysicalDeviceProperties2*)next)->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -334,17 +350,56 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(const VkPhysicalDeviceImage
|
||||
if ( !pImageFormatInfo || pImageFormatInfo->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR ) {
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if ( !getFormatIsSupported(pImageFormatInfo->format) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
|
||||
|
||||
if ( !pImageFormatProperties ) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
if ( !getImageViewIsSupported(pImageFormatInfo) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
|
||||
|
||||
pImageFormatProperties->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
return getImageFormatProperties(pImageFormatInfo->format, pImageFormatInfo->type,
|
||||
pImageFormatInfo->tiling, pImageFormatInfo->usage,
|
||||
pImageFormatInfo->flags,
|
||||
&pImageFormatProperties->imageFormatProperties);
|
||||
if (pImageFormatProperties) {
|
||||
pImageFormatProperties->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
return getImageFormatProperties(pImageFormatInfo->format, pImageFormatInfo->type,
|
||||
pImageFormatInfo->tiling, pImageFormatInfo->usage,
|
||||
pImageFormatInfo->flags,
|
||||
&pImageFormatProperties->imageFormatProperties);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// If the image format info links portability image view info, test if an image view of that configuration is supported
|
||||
bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo) {
|
||||
auto* next = (VkStructureType*)pImageFormatInfo->pNext;
|
||||
while (next) {
|
||||
switch ((int32_t)*next) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_SUPPORT_EXTX: {
|
||||
auto* portImgViewInfo = (VkPhysicalDeviceImageViewSupportEXTX*)next;
|
||||
|
||||
// Create an image view and test whether it could be configured
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = (VkStructureType*)portImgViewInfo->pNext,
|
||||
.flags = portImgViewInfo->flags,
|
||||
.image = VK_NULL_HANDLE,
|
||||
.viewType = portImgViewInfo->viewType,
|
||||
.format = portImgViewInfo->format,
|
||||
.components = portImgViewInfo->components,
|
||||
.subresourceRange = {
|
||||
.aspectMask = portImgViewInfo->aspectMask,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1},
|
||||
};
|
||||
MVKImageView imgView(VK_NULL_HANDLE, &viewInfo, _mvkInstance->getMoltenVKConfiguration());
|
||||
return imgView.getConfigurationResult() == VK_SUCCESS;
|
||||
}
|
||||
default:
|
||||
next = (VkStructureType*)((VkPhysicalDeviceFeatures2*)next)->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,15 +280,19 @@ public:
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCreateInfo);
|
||||
MVKImageView(MVKDevice* device,
|
||||
const VkImageViewCreateInfo* pCreateInfo,
|
||||
const MVKConfiguration* pAltMVKConfig = nullptr);
|
||||
|
||||
~MVKImageView() override;
|
||||
|
||||
protected:
|
||||
id<MTLTexture> newMTLTexture();
|
||||
void initMTLTextureViewSupport();
|
||||
MTLPixelFormat getSwizzledMTLPixelFormat(VkFormat format, VkComponentMapping components, bool& useSwizzle);
|
||||
bool matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern);
|
||||
MTLPixelFormat getSwizzledMTLPixelFormat(VkFormat format,
|
||||
VkComponentMapping components,
|
||||
bool& useSwizzle,
|
||||
const MVKConfiguration* pMVKConfig);
|
||||
void validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo);
|
||||
|
||||
MVKImage* _image;
|
||||
|
@ -761,10 +761,13 @@ id<MTLTexture> MVKImageView::newMTLTexture() {
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCreateInfo) : MVKRefCountedDeviceObject(device) {
|
||||
|
||||
// device and _image may be nil when a temporary instance
|
||||
// is constructed to validate image view capabilities
|
||||
MVKImageView::MVKImageView(MVKDevice* device,
|
||||
const VkImageViewCreateInfo* pCreateInfo,
|
||||
const MVKConfiguration* pAltMVKConfig) : MVKRefCountedDeviceObject(device) {
|
||||
_image = (MVKImage*)pCreateInfo->image;
|
||||
_usage = _image->_usage;
|
||||
_usage = _image ? _image->_usage : 0;
|
||||
|
||||
auto* next = (VkStructureType*)pCreateInfo->pNext;
|
||||
while (next) {
|
||||
@ -787,23 +790,30 @@ MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCrea
|
||||
// Remember the subresource range, and determine the actual number of mip levels and texture slices
|
||||
_subresourceRange = pCreateInfo->subresourceRange;
|
||||
if (_subresourceRange.levelCount == VK_REMAINING_MIP_LEVELS) {
|
||||
_subresourceRange.levelCount = _image->getMipLevelCount() - _subresourceRange.baseMipLevel;
|
||||
_subresourceRange.levelCount = _image ? (_image->getMipLevelCount() - _subresourceRange.baseMipLevel) : 1;
|
||||
}
|
||||
if (_subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS) {
|
||||
_subresourceRange.layerCount = _image->getLayerCount() - _subresourceRange.baseArrayLayer;
|
||||
_subresourceRange.layerCount = _image ? (_image->getLayerCount() - _subresourceRange.baseArrayLayer) : 1;
|
||||
}
|
||||
|
||||
bool useSwizzle;
|
||||
bool useShaderSwizzle;
|
||||
bool isMultisample = _image ? _image->getSampleCount() != VK_SAMPLE_COUNT_1_BIT : false;
|
||||
_mtlTexture = nil;
|
||||
_mtlPixelFormat = getSwizzledMTLPixelFormat(pCreateInfo->format, pCreateInfo->components, useSwizzle);
|
||||
_mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType, (_image->getSampleCount() != VK_SAMPLE_COUNT_1_BIT));
|
||||
_mtlPixelFormat = getSwizzledMTLPixelFormat(pCreateInfo->format, pCreateInfo->components, useShaderSwizzle,
|
||||
(_device ? _device->_pMVKConfig : pAltMVKConfig));
|
||||
_packedSwizzle = useShaderSwizzle ? mvkPackSwizzle(pCreateInfo->components) : 0;
|
||||
_mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType, isMultisample);
|
||||
|
||||
initMTLTextureViewSupport();
|
||||
_packedSwizzle = useSwizzle ? mvkPackSwizzle(pCreateInfo->components) : 0;
|
||||
}
|
||||
|
||||
// Validate whether the image view configuration can be supported
|
||||
void MVKImageView::validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo) {
|
||||
|
||||
// No image if we are just validating view config
|
||||
MVKImage* image = (MVKImage*)pCreateInfo->image;
|
||||
if ( !image ) { return; }
|
||||
|
||||
VkImageType imgType = image->getImageType();
|
||||
VkImageViewType viewType = pCreateInfo->viewType;
|
||||
|
||||
@ -820,102 +830,117 @@ void MVKImageView::validateImageViewConfig(const VkImageViewCreateInfo* pCreateI
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a MTLPixelFormat, based on the original MTLPixelFormat, as converted from the VkFormat,
|
||||
// but possibly modified by the swizzles defined in the VkComponentMapping of the VkImageViewCreateInfo.
|
||||
// Metal does not support general per-texture swizzles, and so this function relies on a few coincidental
|
||||
// alignments of existing MTLPixelFormats of the same structure. If swizzling is not possible for a
|
||||
// particular combination of format and swizzle spec, the original MTLPixelFormat is returned.
|
||||
MTLPixelFormat MVKImageView::getSwizzledMTLPixelFormat(VkFormat format, VkComponentMapping components, bool& useSwizzle) {
|
||||
MTLPixelFormat mtlPF = getMTLPixelFormatFromVkFormat(format);
|
||||
// Returns a MTLPixelFormat, based on the MTLPixelFormat converted from the VkFormat, but possibly
|
||||
// modified by the swizzles defined in the VkComponentMapping of the VkImageViewCreateInfo.
|
||||
// Metal does not support general per-texture swizzles, so if the swizzle is not an identity swizzle, this
|
||||
// function attempts to find an alternate MTLPixelFormat that coincidentally matches the swizzled format.
|
||||
// If a replacement MTLFormat was found, it is returned and useShaderSwizzle is set to false.
|
||||
// If a replacement MTLFormat could not be found, the original MTLPixelFormat is returned, and the
|
||||
// useShaderSwizzle is set to true, indicating that shader swizzling should be used for this image view.
|
||||
// The config is used to test whether full shader swizzle support is available, and to report an error if not.
|
||||
MTLPixelFormat MVKImageView::getSwizzledMTLPixelFormat(VkFormat format,
|
||||
VkComponentMapping components,
|
||||
bool& useShaderSwizzle,
|
||||
const MVKConfiguration* pMVKConfig) {
|
||||
|
||||
useSwizzle = false;
|
||||
switch (mtlPF) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_R} ) ) {
|
||||
return MTLPixelFormatA8Unorm;
|
||||
}
|
||||
break;
|
||||
// Attempt to find a valid format transformation swizzle first.
|
||||
MTLPixelFormat mtlPF = getMTLPixelFormatFromVkFormat(format);
|
||||
useShaderSwizzle = false;
|
||||
|
||||
case MTLPixelFormatA8Unorm:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_ZERO} ) ) {
|
||||
return MTLPixelFormatR8Unorm;
|
||||
}
|
||||
break;
|
||||
#define SWIZZLE_MATCHES(R, G, B, A) mvkVkComponentMappingsMatch(components, {VK_COMPONENT_SWIZZLE_ ##R, VK_COMPONENT_SWIZZLE_ ##G, VK_COMPONENT_SWIZZLE_ ##B, VK_COMPONENT_SWIZZLE_ ##A} )
|
||||
#define VK_COMPONENT_SWIZZLE_ANY VK_COMPONENT_SWIZZLE_MAX_ENUM
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A} ) ) {
|
||||
return MTLPixelFormatBGRA8Unorm;
|
||||
}
|
||||
break;
|
||||
switch (mtlPF) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {
|
||||
return MTLPixelFormatA8Unorm;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A} ) ) {
|
||||
return MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
}
|
||||
break;
|
||||
case MTLPixelFormatA8Unorm:
|
||||
if (SWIZZLE_MATCHES(A, ANY, ANY, ZERO)) {
|
||||
return MTLPixelFormatR8Unorm;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A} ) ) {
|
||||
return MTLPixelFormatRGBA8Unorm;
|
||||
}
|
||||
break;
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
return MTLPixelFormatBGRA8Unorm;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
if (matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A} ) ) {
|
||||
return MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
}
|
||||
break;
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
return MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
if (_subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
if (!matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM} ) ) {
|
||||
useSwizzle = true;
|
||||
}
|
||||
return MTLPixelFormatX32_Stencil8;
|
||||
}
|
||||
break;
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
return MTLPixelFormatRGBA8Unorm;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
return MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (_subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
mtlPF = MTLPixelFormatX32_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return mtlPF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if MVK_MACOS
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
if (_subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
if (!matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM, VK_COMPONENT_SWIZZLE_MAX_ENUM} ) ) {
|
||||
useSwizzle = true;
|
||||
}
|
||||
return MTLPixelFormatX24_Stencil8;
|
||||
}
|
||||
break;
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (_subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
mtlPF = MTLPixelFormatX24_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return mtlPF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !matchesSwizzle(components, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A} ) ) {
|
||||
useSwizzle = true;
|
||||
}
|
||||
return mtlPF;
|
||||
}
|
||||
// No format transformation swizzles were found, so unless we have an identity swizzle, we'll need to use shader swizzling.
|
||||
if ( !SWIZZLE_MATCHES(R, G, B, A)) {
|
||||
useShaderSwizzle = true;
|
||||
|
||||
// Returns whether the swizzle components of the internal VkComponentMapping matches the
|
||||
// swizzle pattern, by comparing corresponding elements of the two structures. The pattern
|
||||
// supports wildcards, in that any element of pattern can be set to VK_COMPONENT_SWIZZLE_MAX_ENUM
|
||||
// to indicate that any value in the corresponding element of components.
|
||||
bool MVKImageView::matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern) {
|
||||
if ( !((pattern.r == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (pattern.r == components.r) ||
|
||||
((pattern.r == VK_COMPONENT_SWIZZLE_R) && (components.r == VK_COMPONENT_SWIZZLE_IDENTITY))) ) { return false; }
|
||||
if ( !((pattern.g == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (pattern.g == components.g) ||
|
||||
((pattern.g == VK_COMPONENT_SWIZZLE_G) && (components.g == VK_COMPONENT_SWIZZLE_IDENTITY))) ) { return false; }
|
||||
if ( !((pattern.b == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (pattern.b == components.b) ||
|
||||
((pattern.b == VK_COMPONENT_SWIZZLE_B) && (components.b == VK_COMPONENT_SWIZZLE_IDENTITY))) ) { return false; }
|
||||
if ( !((pattern.a == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (pattern.a == components.a) ||
|
||||
((pattern.a == VK_COMPONENT_SWIZZLE_A) && (components.a == VK_COMPONENT_SWIZZLE_IDENTITY))) ) { return false; }
|
||||
if ( !pMVKConfig->fullImageViewSwizzle ) {
|
||||
const char* vkCmd = _image ? "vkCreateImageView(VkImageViewCreateInfo" : "vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDeviceImageViewSupportEXTX";
|
||||
const char* errMsg = ("The value of %s::components) (%s, %s, %s, %s), when applied to a VkImageView, requires full component swizzling to be enabled both at the"
|
||||
" time when the VkImageView is created and at the time any pipeline that uses that VkImageView is compiled. Full component swizzling can"
|
||||
" be enabled via the MVKConfiguration::fullImageViewSwizzle config parameter or MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE environment variable.");
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, errMsg, vkCmd,
|
||||
mvkVkComponentSwizzleName(components.r), mvkVkComponentSwizzleName(components.g),
|
||||
mvkVkComponentSwizzleName(components.b), mvkVkComponentSwizzleName(components.a)));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return mtlPF;
|
||||
}
|
||||
|
||||
// Determine whether this image view should use a Metal texture view,
|
||||
// and set the _useMTLTextureView variable appropriately.
|
||||
void MVKImageView::initMTLTextureViewSupport() {
|
||||
|
||||
// If no image we're just validating image iview config
|
||||
if ( !_image ) {
|
||||
_useMTLTextureView = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_useMTLTextureView = _image->_canSupportMTLTextureView;
|
||||
|
||||
bool is3D = _image->_mtlTextureType == MTLTextureType3D;
|
||||
|
@ -53,6 +53,7 @@ MVK_EXTENSION(KHR_swapchain_mutable_format, KHR_SWAPCHAIN_MUTABLE_FORMAT)
|
||||
MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS)
|
||||
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)
|
||||
MVK_EXTENSION(MVK_ios_surface, MVK_IOS_SURFACE)
|
||||
MVK_EXTENSION(MVK_macos_surface, MVK_MACOS_SURFACE)
|
||||
MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK)
|
||||
|
@ -297,6 +297,40 @@ static inline VkComponentMapping mvkUnpackSwizzle(uint32_t packed) {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the two component swizzles, cs1 and cs2 match. Positional identity matches
|
||||
* and wildcard matches are allowed. The two values match under any of the following conditions:
|
||||
* 1) cs1 and cs2 are equal to each other.
|
||||
* 2) Either cs1 or cs2 is equal to VK_COMPONENT_SWIZZLE_IDENTITY and the other value
|
||||
* is equal to the positional value csPos, which is one of VK_COMPONENT_SWIZZLE_R,
|
||||
* VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, or VK_COMPONENT_SWIZZLE_A.
|
||||
* 3) Either cs1 or cs2 is VK_COMPONENT_SWIZZLE_MAX_ENUM, which is considered a wildcard,
|
||||
* and matches any value.
|
||||
*/
|
||||
static inline bool mvkVKComponentSwizzlesMatch(VkComponentSwizzle cs1,
|
||||
VkComponentSwizzle cs2,
|
||||
VkComponentSwizzle csPos) {
|
||||
return ((cs1 == cs2) ||
|
||||
((cs1 == VK_COMPONENT_SWIZZLE_IDENTITY) && (cs2 == csPos)) ||
|
||||
((cs2 == VK_COMPONENT_SWIZZLE_IDENTITY) && (cs1 == csPos)) ||
|
||||
(cs1 == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (cs2 == VK_COMPONENT_SWIZZLE_MAX_ENUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the two swizzle component mappings match each other, by comparing the
|
||||
* corresponding elements of the two mappings. A component value of VK_COMPONENT_SWIZZLE_IDENTITY
|
||||
* on either mapping matches the VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
|
||||
* or VK_COMPONENT_SWIZZLE_A value in the other mapping if it is the correct position.
|
||||
* A component value of VK_COMPONENT_SWIZZLE_MAX_ENUM is considered a wildcard and matches
|
||||
* any value in the corresponding component in the other mapping.
|
||||
*/
|
||||
static inline bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComponentMapping cm2) {
|
||||
return (mvkVKComponentSwizzlesMatch(cm1.r, cm2.r, VK_COMPONENT_SWIZZLE_R) &&
|
||||
mvkVKComponentSwizzlesMatch(cm1.g, cm2.g, VK_COMPONENT_SWIZZLE_G) &&
|
||||
mvkVKComponentSwizzlesMatch(cm1.b, cm2.b, VK_COMPONENT_SWIZZLE_B) &&
|
||||
mvkVKComponentSwizzlesMatch(cm1.a, cm2.a, VK_COMPONENT_SWIZZLE_A));
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Template functions
|
||||
|
@ -1480,33 +1480,31 @@ MVK_PUBLIC_SYMBOL void vkCmdExecuteCommands(
|
||||
#pragma mark VK_KHR_bind_memory2 extension
|
||||
|
||||
MVK_PUBLIC_SYMBOL VkResult vkBindBufferMemory2KHR(
|
||||
VkDevice device,
|
||||
uint32_t bindInfoCount,
|
||||
const VkBindBufferMemoryInfoKHR* pBindInfos) {
|
||||
VkResult res;
|
||||
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
||||
MVKBuffer* mvkBuff = (MVKBuffer*)pBindInfos[i].buffer;
|
||||
res = mvkBuff->bindDeviceMemory2(&pBindInfos[i]);
|
||||
if (res != VK_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
VkDevice device,
|
||||
uint32_t bindInfoCount,
|
||||
const VkBindBufferMemoryInfoKHR* pBindInfos) {
|
||||
|
||||
VkResult rslt = VK_SUCCESS;
|
||||
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
||||
MVKBuffer* mvkBuff = (MVKBuffer*)pBindInfos[i].buffer;
|
||||
VkResult r = mvkBuff->bindDeviceMemory2(&pBindInfos[i]);
|
||||
if (rslt == VK_SUCCESS) { rslt = r; }
|
||||
}
|
||||
return rslt;
|
||||
}
|
||||
|
||||
MVK_PUBLIC_SYMBOL VkResult vkBindImageMemory2KHR(
|
||||
VkDevice device,
|
||||
uint32_t bindInfoCount,
|
||||
const VkBindImageMemoryInfoKHR* pBindInfos) {
|
||||
VkResult res;
|
||||
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
||||
MVKImage* mvkImg = (MVKImage*)pBindInfos[i].image;
|
||||
res = mvkImg->bindDeviceMemory2(&pBindInfos[i]);
|
||||
if (res != VK_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
VkDevice device,
|
||||
uint32_t bindInfoCount,
|
||||
const VkBindImageMemoryInfoKHR* pBindInfos) {
|
||||
|
||||
VkResult rslt = VK_SUCCESS;
|
||||
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
||||
MVKImage* mvkImg = (MVKImage*)pBindInfos[i].image;
|
||||
VkResult r = mvkImg->bindDeviceMemory2(&pBindInfos[i]);
|
||||
if (rslt == VK_SUCCESS) { rslt = r; }
|
||||
}
|
||||
return rslt;
|
||||
}
|
||||
|
||||
|
||||
|
1
MoltenVK/include/vulkan-portability
Symbolic link
1
MoltenVK/include/vulkan-portability
Symbolic link
@ -0,0 +1 @@
|
||||
../../External/Vulkan-Portability/include/vulkan
|
1
MoltenVK/vulkan-portability
Symbolic link
1
MoltenVK/vulkan-portability
Symbolic link
@ -0,0 +1 @@
|
||||
../../External/Vulkan-Portability/include/vulkan
|
@ -144,6 +144,18 @@ else
|
||||
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
|
||||
fi
|
||||
|
||||
# ----------------- Vulkan-Portability -------------------
|
||||
|
||||
echo
|
||||
echo ========== Vulkan-Portability ==========
|
||||
echo
|
||||
|
||||
REPO_NAME=Vulkan-Portability
|
||||
REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git"
|
||||
REPO_REV=$(cat "../${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
|
||||
|
||||
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
|
||||
|
||||
|
||||
# ----------------- SPIRV-Cross -------------------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user