Merge pull request #237 from billhollings/master
Vulkan extension enhancements.
diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
index c41a0dd..2f87edd 100644
--- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
+++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
@@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
+ A909F65F213B190700FCD6BE /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; };
+ A909F660213B190700FCD6BE /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; };
+ A909F661213B190700FCD6BE /* MVKExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A909F65E213B190700FCD6BE /* MVKExtensions.cpp */; };
+ A909F662213B190700FCD6BE /* MVKExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A909F65E213B190700FCD6BE /* MVKExtensions.cpp */; };
A90C8DEA1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */; };
A90C8DEB1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */; };
A90C8DEC1F45354D009CB32C /* MVKCommandEncodingPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A90C8DE91F45354D009CB32C /* MVKCommandEncodingPool.mm */; };
@@ -147,8 +151,8 @@
A98149521FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */; };
A98149531FB6A3F7005F00B4 /* MVKFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149441FB6A3F7005F00B4 /* MVKFoundation.h */; };
A98149541FB6A3F7005F00B4 /* MVKFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149441FB6A3F7005F00B4 /* MVKFoundation.h */; };
- A98149551FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */; };
- A98149561FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */; };
+ A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */; };
+ A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */; };
A98149571FB6A3F7005F00B4 /* MVKObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */; };
A98149581FB6A3F7005F00B4 /* MVKObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */; };
A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
@@ -256,6 +260,8 @@
/* Begin PBXFileReference section */
A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdDispatch.h; sourceTree = "<group>"; };
A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDispatch.mm; sourceTree = "<group>"; };
+ A909F65A213B190600FCD6BE /* MVKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKExtensions.h; sourceTree = "<group>"; };
+ A909F65E213B190700FCD6BE /* MVKExtensions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKExtensions.cpp; sourceTree = "<group>"; };
A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommandEncodingPool.h; sourceTree = "<group>"; };
A90C8DE91F45354D009CB32C /* MVKCommandEncodingPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCommandEncodingPool.mm; sourceTree = "<group>"; };
A93E832E2121C5D3001FEBD4 /* MVKGPUCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKGPUCapture.h; sourceTree = "<group>"; };
@@ -325,7 +331,7 @@
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKBaseObject.h; sourceTree = "<group>"; };
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKEnvironment.h; sourceTree = "<group>"; };
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKFoundation.h; sourceTree = "<group>"; };
- A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKFoundation.mm; sourceTree = "<group>"; };
+ A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKFoundation.cpp; sourceTree = "<group>"; };
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKObjectPool.h; sourceTree = "<group>"; };
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKWatermark.h; sourceTree = "<group>"; };
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKWatermark.mm; sourceTree = "<group>"; };
@@ -365,7 +371,7 @@
A94FB7651C7DFB4800632CA3 /* API */,
A94FB76B1C7DFB4800632CA3 /* Commands */,
A94FB77E1C7DFB4800632CA3 /* GPUObjects */,
- A94FB79F1C7DFB4800632CA3 /* Loader */,
+ A94FB79F1C7DFB4800632CA3 /* Layers */,
A9E53DCC2100B197002781DD /* OS */,
A98149401FB6A3F7005F00B4 /* Utility */,
A94FB7A81C7DFB4800632CA3 /* Vulkan */,
@@ -457,13 +463,15 @@
path = GPUObjects;
sourceTree = "<group>";
};
- A94FB79F1C7DFB4800632CA3 /* Loader */ = {
+ A94FB79F1C7DFB4800632CA3 /* Layers */ = {
isa = PBXGroup;
children = (
+ A909F65A213B190600FCD6BE /* MVKExtensions.h */,
+ A909F65E213B190700FCD6BE /* MVKExtensions.cpp */,
A94FB7A01C7DFB4800632CA3 /* MVKLayers.h */,
A94FB7A11C7DFB4800632CA3 /* MVKLayers.mm */,
);
- path = Loader;
+ path = Layers;
sourceTree = "<group>";
};
A94FB7A81C7DFB4800632CA3 /* Vulkan */ = {
@@ -483,7 +491,7 @@
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
- A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */,
+ A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */,
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */,
@@ -576,6 +584,7 @@
buildActionMask = 2147483647;
files = (
A94FB7B41C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
+ A909F65F213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B01C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A98149511FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
A948BB7F1E51642700DE59F2 /* mvk_vulkan.h in Headers */,
@@ -635,6 +644,7 @@
buildActionMask = 2147483647;
files = (
A94FB7B51C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
+ A909F660213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B11C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A98149521FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
A948BB801E51642700DE59F2 /* mvk_vulkan.h in Headers */,
@@ -866,7 +876,8 @@
A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
A94FB82A1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
- A98149551FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */,
+ A909F661213B190700FCD6BE /* MVKExtensions.cpp in Sources */,
+ A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A94FB7FA1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,
@@ -917,7 +928,8 @@
A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
A94FB7DF1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
A94FB82B1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
- A98149561FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */,
+ A909F662213B190700FCD6BE /* MVKExtensions.cpp in Sources */,
+ A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF62100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A94FB7FB1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,
diff --git a/MoltenVK/MoltenVK/API/mvk_datatypes.h b/MoltenVK/MoltenVK/API/mvk_datatypes.h
index c02676b..e95f1c6 100644
--- a/MoltenVK/MoltenVK/API/mvk_datatypes.h
+++ b/MoltenVK/MoltenVK/API/mvk_datatypes.h
@@ -31,7 +31,7 @@
extern "C" {
#endif // __cplusplus
-#include <vulkan/vulkan.h>
+#include <MoltenVK/mvk_vulkan.h>
#import <Metal/Metal.h>
#import <CoreGraphics/CoreGraphics.h>
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index 427a3b9..14067b3 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -26,7 +26,7 @@
extern "C" {
#endif // __cplusplus
-#include <vulkan/vulkan.h>
+#include <MoltenVK/mvk_vulkan.h>
#ifdef __OBJC__
#import <Metal/Metal.h>
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index b28c2cd..b54fc06 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -62,6 +62,9 @@
if (_srcImage->getMTLPixelFormat() != _dstImage->getMTLPixelFormat()) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdCopyImage(): The source and destination images must have the same format."));
}
+ if ((_srcImage->getMTLTextureType() == MTLTextureType3D) || (_dstImage->getMTLTextureType() == MTLTextureType3D)) {
+ setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdCopyImage(): Metal does not support copying to or from slices of a 3D texture."));
+ }
}
// Adds a Metal copy region structure for each layer in the specified copy region.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
index d85e29c..f47f4ff 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
@@ -801,7 +801,11 @@
const VkDescriptorSetLayout* pSetLayouts,
VkDescriptorSet* pDescriptorSets) {
if (_allocatedSetCount + count > _maxSets) {
- return mvkNotifyErrorWithText(VK_ERROR_OUT_OF_POOL_MEMORY_KHR, "The maximum number of descriptor sets that can be allocated by this descriptor pool is %d.", _maxSets);
+ if (_device->_enabledExtensions.vk_KHR_maintenance1.enabled) {
+ return VK_ERROR_OUT_OF_POOL_MEMORY; // Failure is an acceptable test...don't log as error.
+ } else {
+ return mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "The maximum number of descriptor sets that can be allocated by this descriptor pool is %d.", _maxSets);
+ }
}
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index 4eb86f4..bf19fc8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -288,7 +288,7 @@
public:
/** Returns a pointer to the Vulkan instance. */
- inline MVKInstance* getInstance() { return _physicalDevice->getInstance(); }
+ inline MVKInstance* getInstance() { return _physicalDevice->_mvkInstance; }
/** Returns the physical device underlying this logical device. */
inline MVKPhysicalDevice* getPhysicalDevice() { return _physicalDevice; }
@@ -504,7 +504,7 @@
#pragma mark Properties directly accessible
- /** The MoltenVK configuration settings. */
+ /** Pointer to the MoltenVK configuration settings. */
const MVKConfiguration* _pMVKConfig;
/** Pointer to the feature set of the underlying physical device. */
@@ -519,6 +519,9 @@
/** Pointer to the memory properties of the underlying physical device. */
const VkPhysicalDeviceMemoryProperties* _pMemoryProperties;
+ /** The list of Vulkan extensions, indicating whether each has been enabled by the app for this device. */
+ const MVKExtensionList _enabledExtensions;
+
/** Performance statistics. */
MVKPerformanceStatistics _performanceStatistics;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index ee5889c..905a95f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -1018,39 +1018,39 @@
break;
}
- string fsMsg = "GPU device:";
- fsMsg += "\n\t\tmodel: %s";
- fsMsg += "\n\t\ttype: %s";
- fsMsg += "\n\t\tvendorID: %#06x";
- fsMsg += "\n\t\tdeviceID: %#06x";
- fsMsg += "\n\t\tpipelineCacheUUID: %s";
- fsMsg += "\n\tsupports the following Metal Feature Sets:";
+ string logMsg = "GPU device:";
+ logMsg += "\n\t\tmodel: %s";
+ logMsg += "\n\t\ttype: %s";
+ logMsg += "\n\t\tvendorID: %#06x";
+ logMsg += "\n\t\tdeviceID: %#06x";
+ logMsg += "\n\t\tpipelineCacheUUID: %s";
+ logMsg += "\n\tsupports the following Metal Feature Sets:";
#if MVK_IOS
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) { fsMsg += "\n\tviOS GPU Family 4 v1"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) { logMsg += "\n\t\tiOS GPU Family 4 v1"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v3] ) { fsMsg += "\n\t\tiOS GPU Family 3 v3"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) { fsMsg += "\n\t\tiOS GPU Family 3 v2"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1] ) { fsMsg += "\n\t\tiOS GPU Family 3 v1"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v3] ) { logMsg += "\n\t\tiOS GPU Family 3 v3"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) { logMsg += "\n\t\tiOS GPU Family 3 v2"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1] ) { logMsg += "\n\t\tiOS GPU Family 3 v1"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) { fsMsg += "\n\t\tiOS GPU Family 2 v4"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v3] ) { fsMsg += "\n\t\tiOS GPU Family 2 v3"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v2] ) { fsMsg += "\n\t\tiOS GPU Family 2 v2"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) { fsMsg += "\n\t\tiOS GPU Family 2 v1"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) { logMsg += "\n\t\tiOS GPU Family 2 v4"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v3] ) { logMsg += "\n\t\tiOS GPU Family 2 v3"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v2] ) { logMsg += "\n\t\tiOS GPU Family 2 v2"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) { logMsg += "\n\t\tiOS GPU Family 2 v1"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v4] ) { fsMsg += "\n\t\tiOS GPU Family 1 v4"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v3] ) { fsMsg += "\n\t\tiOS GPU Family 1 v3"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v2] ) { fsMsg += "\n\t\tiOS GPU Family 1 v2"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v1] ) { fsMsg += "\n\t\tiOS GPU Family 1 v1"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v4] ) { logMsg += "\n\t\tiOS GPU Family 1 v4"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v3] ) { logMsg += "\n\t\tiOS GPU Family 1 v3"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v2] ) { logMsg += "\n\t\tiOS GPU Family 1 v2"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v1] ) { logMsg += "\n\t\tiOS GPU Family 1 v1"; }
#endif
#if MVK_MACOS
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v3"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v2"; }
- if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v1] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v1"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) { logMsg += "\n\t\tmacOS GPU Family 1 v3"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2] ) { logMsg += "\n\t\tmacOS GPU Family 1 v2"; }
+ if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v1] ) { logMsg += "\n\t\tmacOS GPU Family 1 v1"; }
#endif
- MVKLogInfo(fsMsg.c_str(), _properties.deviceName, devTypeStr.c_str(), _properties.vendorID, _properties.deviceID,
+ MVKLogInfo(logMsg.c_str(), _properties.deviceName, devTypeStr.c_str(), _properties.vendorID, _properties.deviceID,
[[[NSUUID alloc] initWithUUIDBytes: _properties.pipelineCacheUUID] autorelease].UUIDString.UTF8String);
}
@@ -1523,7 +1523,7 @@
initPerformanceTracking();
_physicalDevice = physicalDevice;
- _pMVKConfig = &_physicalDevice->getInstance()->_mvkConfig;
+ _pMVKConfig = _physicalDevice->_mvkInstance->getMoltenVKConfiguration();
_pFeatures = &_physicalDevice->_features;
_pMetalFeatures = &_physicalDevice->_metalFeatures;
_pProperties = &_physicalDevice->_properties;
@@ -1532,11 +1532,13 @@
_globalVisibilityResultMTLBuffer = nil;
_globalVisibilityQueryCount = 0;
- // Verify the requested extension names. Should be same as those requested from instance.
- setConfigurationResult(_physicalDevice->_mvkInstance->verifyExtensions(pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames));
+ _commandResourceFactory = new MVKCommandResourceFactory(this);
- _commandResourceFactory = new MVKCommandResourceFactory(this);
+ // Verify the requested extension names. Should be same as those requested from instance.
+ MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions;
+ setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames,
+ getInstance()->getDriverLayer()->getSupportedExtensions()));
// Create the queues
uint32_t qrCnt = pCreateInfo->queueCreateInfoCount;
@@ -1551,7 +1553,9 @@
}
}
- MVKLogInfo("Created VkDevice to run on GPU %s", _pProperties->deviceName);
+ string logMsg = "Created VkDevice to run on GPU %s with the following Vulkan extensions enabled:";
+ logMsg += _enabledExtensions.enabledNamesString("\n\t\t", true);
+ MVKLogInfo(logMsg.c_str(), _pProperties->deviceName);
}
void MVKDevice::initPerformanceTracking() {
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index 087b5f2..48e0e53 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -281,6 +281,7 @@
bool matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern);
const char* getSwizzleName(VkComponentSwizzle swizzle);
void setSwizzleFormatError(VkFormat format, VkComponentMapping components);
+ void validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo);
MVKImage* _image;
VkImageSubresourceRange _subresourceRange;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 6d27cfd..6b84a1b 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -614,6 +614,8 @@
MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
+ validateImageViewConfig(pCreateInfo);
+
_image = (MVKImage*)pCreateInfo->image;
// Remember the subresource range, and determine the actual number of mip levels and texture slices
@@ -631,6 +633,17 @@
initMTLTextureViewSupport();
}
+// Validate whether the image view configuration can be supported
+void MVKImageView::validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo) {
+ VkImageType imgType = ((MVKImage*)pCreateInfo->image)->getImageType();
+ VkImageViewType viewType = pCreateInfo->viewType;
+
+ // VK_KHR_maintenance1 supports taking 2D image views of 3D slices. No dice in Metal.
+ if ((viewType == VK_IMAGE_VIEW_TYPE_2D || viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && (imgType == VK_IMAGE_TYPE_3D)) {
+ setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImageView(): Metal does not support creating a 2D view on a 3D image."));
+ }
+}
+
// 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
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
index e0222db..9c6fdc2 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
@@ -18,6 +18,7 @@
#pragma once
+#include "MVKLayers.h"
#include "MVKSurface.h"
#include "MVKBaseObject.h"
#include "vk_mvk_moltenvk.h"
@@ -53,17 +54,8 @@
*/
VkResult getPhysicalDevices(uint32_t* pCount, VkPhysicalDevice* pPhysicalDevices);
- /**
- * Verifies that the list of layers are available,
- * and returns VK_SUCCESS or VK_ERROR_LAYER_NOT_PRESENT.
- */
- VkResult verifyLayers(uint32_t count, const char* const* names);
-
- /**
- * Verifies that the list of extensions are available,
- * and returns VK_SUCCESS or VK_ERROR_EXTENSION_NOT_PRESENT.
- */
- VkResult verifyExtensions(uint32_t count, const char* const* names);
+ /** Returns the driver layer. */
+ MVKLayer* getDriverLayer() { return MVKLayerManager::globalManager()->getDriverLayer(); }
/** Creates and returns a new object. */
MVKSurface* createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
@@ -73,8 +65,14 @@
void destroySurface(MVKSurface* mvkSrfc,
const VkAllocationCallbacks* pAllocator);
- /** The MoltenVK configuration settings. */
- MVKConfiguration _mvkConfig;
+ /** Returns the MoltenVK configuration settings. */
+ const MVKConfiguration* getMoltenVKConfiguration() { return &_mvkConfig; }
+
+ /** Returns the MoltenVK configuration settings. */
+ void setMoltenVKConfiguration(MVKConfiguration* mvkConfig) { _mvkConfig = *mvkConfig; }
+
+ /** The list of Vulkan extensions, indicating whether each has been enabled by the app. */
+ const MVKExtensionList _enabledExtensions;
#pragma mark Object Creation
@@ -102,7 +100,9 @@
void initProcAddrs();
void initConfig();
void logVersions();
+ VkResult verifyLayers(uint32_t count, const char* const* names);
+ MVKConfiguration _mvkConfig;
VkApplicationInfo _appInfo;
std::vector<MVKPhysicalDevice*> _physicalDevices;
std::unordered_map<std::string, PFN_vkVoidFunction> _procAddrMap;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
index 61df8ed..c9761c0 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
@@ -18,7 +18,6 @@
#include "MVKInstance.h"
-#include "MVKLayers.h"
#include "MVKDevice.h"
#include "MVKFoundation.h"
#include "MVKEnvironment.h"
@@ -53,27 +52,6 @@
return result;
}
-VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
- VkResult result = VK_SUCCESS;
- for (uint32_t i = 0; i < count; i++) {
- if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
- result = mvkNotifyErrorWithText(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
- }
- }
- return result;
-}
-
-VkResult MVKInstance::verifyExtensions(uint32_t count, const char* const* names) {
- VkResult result = VK_SUCCESS;
- MVKLayer* driverLayer = MVKLayerManager::globalManager()->getDriverLayer();
- for (uint32_t i = 0; i < count; i++) {
- if (!driverLayer->hasExtensionNamed(names[i])) {
- result = mvkNotifyErrorWithText(VK_ERROR_EXTENSION_NOT_PRESENT, "Vulkan extension %s is not supported.", names[i]);
- }
- }
- return result;
-}
-
MVKSurface* MVKInstance::createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKSurface(this, pCreateInfo, pAllocator);
@@ -87,6 +65,74 @@
#pragma mark Object Creation
+// Returns an autoreleased array containing the MTLDevices available on this system,
+// sorted according to power, with higher power GPU's at the front of the array.
+// This ensures that a lazy app that simply grabs the first GPU will get a high-power one by default.
+// If the MVK_FORCE_LOW_POWER_GPU is defined, the returned array will only include low-power devices.
+static NSArray<id<MTLDevice>>* getAvailableMTLDevices() {
+#if MVK_MACOS
+ NSArray* mtlDevs = [MTLCopyAllDevices() autorelease];
+
+#ifdef MVK_FORCE_LOW_POWER_GPU
+ NSMutableArray* lpDevs = [[NSMutableArray new] autorelease];
+ for (id<MTLDevice> md in mtlDevs) {
+ if (md.isLowPower) { [lpDevs addObject: md]; }
+ }
+ return lpDevs;
+#else
+ return [mtlDevs sortedArrayUsingComparator: ^(id<MTLDevice> md1, id<MTLDevice> md2) {
+ BOOL md1IsLP = md1.isLowPower;
+ BOOL md2IsLP = md2.isLowPower;
+
+ if (md1IsLP == md2IsLP) {
+ // If one device is headless and the other one is not, select the
+ // one that is not headless first.
+ BOOL md1IsHeadless = md1.isHeadless;
+ BOOL md2IsHeadless = md2.isHeadless;
+ if (md1IsHeadless == md2IsHeadless ) {
+ return NSOrderedSame;
+ }
+ return md2IsHeadless ? NSOrderedAscending : NSOrderedDescending;
+ }
+
+ return md2IsLP ? NSOrderedAscending : NSOrderedDescending;
+ }];
+#endif // MVK_MACOS
+
+#endif
+#if MVK_IOS
+ return [NSArray arrayWithObject: MTLCreateSystemDefaultDevice()];
+#endif
+}
+
+MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) {
+
+ _appInfo.apiVersion = MVK_VULKAN_API_VERSION; // Default
+ mvkSetOrClear(&_appInfo, pCreateInfo->pApplicationInfo);
+
+ initProcAddrs(); // Init function pointers
+ initConfig();
+
+ setConfigurationResult(verifyLayers(pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames));
+ MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions;
+ setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames,
+ getDriverLayer()->getSupportedExtensions()));
+ logVersions(); // Log the MoltenVK and Vulkan versions
+
+ if (MVK_VULKAN_API_VERSION_CONFORM(MVK_VULKAN_API_VERSION) <
+ MVK_VULKAN_API_VERSION_CONFORM(_appInfo.apiVersion)) {
+ setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, "Request for driver version %x is not compatible with provided version %x.", _appInfo.apiVersion, MVK_VULKAN_API_VERSION));
+ }
+
+ // Populate the array of physical GPU devices
+ NSArray<id<MTLDevice>>* mtlDevices = getAvailableMTLDevices();
+ _physicalDevices.reserve(mtlDevices.count);
+ for (id<MTLDevice> mtlDev in mtlDevices) {
+ _physicalDevices.push_back(new MVKPhysicalDevice(this, mtlDev));
+ }
+}
+
#define ADD_PROC_ADDR(entrypoint) _procAddrMap[""#entrypoint] = (PFN_vkVoidFunction)&entrypoint;
/** Initializes the function pointer map. */
@@ -276,7 +322,6 @@
ADD_PROC_ADDR(vkSetMoltenVKDeviceConfigurationMVK);
#pragma clang diagnostic pop
-
}
void MVKInstance::logVersions() {
@@ -284,74 +329,14 @@
char mvkVer[buffLen];
char vkVer[buffLen];
vkGetVersionStringsMVK(mvkVer, buffLen, vkVer, buffLen);
- MVKLogInfo("MoltenVK version %s. Vulkan version %s.", mvkVer, vkVer);
-}
-/**
- * Returns an autoreleased array containing the MTLDevices available on this system,
- * sorted according to power, with higher power GPU's at the front of the array.
- * This ensures that a lazy app that simply grabs the first GPU will get a high-power one by default.
- * If the MVK_FORCE_LOW_POWER_GPU is defined, the returned array will only include low-power devices.
- */
-static NSArray<id<MTLDevice>>* getAvailableMTLDevices() {
-#if MVK_MACOS
- NSArray* mtlDevs = [MTLCopyAllDevices() autorelease];
-
-#ifdef MVK_FORCE_LOW_POWER_GPU
- NSMutableArray* lpDevs = [[NSMutableArray new] autorelease];
- for (id<MTLDevice> md in mtlDevs) {
- if (md.isLowPower) { [lpDevs addObject: md]; }
- }
- return lpDevs;
-#else
- return [mtlDevs sortedArrayUsingComparator: ^(id<MTLDevice> md1, id<MTLDevice> md2) {
- BOOL md1IsLP = md1.isLowPower;
- BOOL md2IsLP = md2.isLowPower;
-
- if (md1IsLP == md2IsLP) {
- // If one device is headless and the other one is not, select the
- // one that is not headless first.
- BOOL md1IsHeadless = md1.isHeadless;
- BOOL md2IsHeadless = md2.isHeadless;
- if (md1IsHeadless == md2IsHeadless ) {
- return NSOrderedSame;
- }
- return md2IsHeadless ? NSOrderedAscending : NSOrderedDescending;
- }
-
- return md2IsLP ? NSOrderedAscending : NSOrderedDescending;
- }];
-#endif // MVK_MACOS
-
-#endif
-#if MVK_IOS
- return [NSArray arrayWithObject: MTLCreateSystemDefaultDevice()];
-#endif
-}
-
-MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) {
-
- _appInfo.apiVersion = MVK_VULKAN_API_VERSION; // Default
- mvkSetOrClear(&_appInfo, pCreateInfo->pApplicationInfo);
-
- logVersions(); // Log the MoltenVK and Vulkan versions
- initProcAddrs(); // Init function pointers
- initConfig();
-
- // Populate the array of physical GPU devices
- NSArray<id<MTLDevice>>* mtlDevices = getAvailableMTLDevices();
- _physicalDevices.reserve(mtlDevices.count);
- for (id<MTLDevice> mtlDev in mtlDevices) {
- _physicalDevices.push_back(new MVKPhysicalDevice(this, mtlDev));
- }
-
- if (MVK_VULKAN_API_VERSION_CONFORM(MVK_VULKAN_API_VERSION) <
- MVK_VULKAN_API_VERSION_CONFORM(_appInfo.apiVersion)) {
- setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, "Request for driver version %x is not compatible with provided version %x.", _appInfo.apiVersion, MVK_VULKAN_API_VERSION));
- }
-
- setConfigurationResult(verifyLayers(pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames));
- setConfigurationResult(verifyExtensions(pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames));
+ const char* indent = "\n\t\t";
+ string logMsg = "MoltenVK version %s. Vulkan version %s.";
+ logMsg += "\n\tThe following Vulkan extensions are supported:";
+ logMsg += getDriverLayer()->getSupportedExtensions()->enabledNamesString(indent, true);
+ logMsg += "\n\tCreated VkInstance with the following Vulkan extensions enabled:";
+ logMsg += _enabledExtensions.enabledNamesString(indent, true);
+ MVKLogInfo(logMsg.c_str(), mvkVer, vkVer);
}
// Init config.
@@ -368,6 +353,16 @@
_mvkConfig.metalCompileTimeout = MVK_CONFIG_METAL_COMPILE_TIMEOUT;
}
+VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
+ VkResult result = VK_SUCCESS;
+ for (uint32_t i = 0; i < count; i++) {
+ if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
+ result = mvkNotifyErrorWithText(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
+ }
+ }
+ return result;
+}
+
MVKInstance::~MVKInstance() {
mvkDestroyContainerContents(_physicalDevices);
}
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.cpp b/MoltenVK/MoltenVK/Layers/MVKExtensions.cpp
new file mode 100644
index 0000000..f66b76a
--- /dev/null
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.cpp
@@ -0,0 +1,149 @@
+/*
+ * MVKExtensions.cpp
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MVKExtensions.h"
+#include "MVKFoundation.h"
+#include "vk_mvk_moltenvk.h"
+#include <vulkan/vulkan_ios.h>
+#include <vulkan/vulkan_macos.h>
+
+using namespace std;
+
+
+// Returns a VkExtensionProperties struct populated with a name and version
+static VkExtensionProperties mvkMakeExtProps(const char* extensionName, uint32_t specVersion) {
+ VkExtensionProperties extProps;
+ memset(extProps.extensionName, 0, sizeof(extProps.extensionName));
+ if (extensionName) { strcpy(extProps.extensionName, extensionName); }
+ extProps.specVersion = specVersion;
+ return extProps;
+}
+
+// Declares and populates a static VkExtensionProperties variable for the extention EXT,
+// which should include the unique portion of the extension name, as uppercase.
+// For example, for the extension VK_KHR_surface, use KHR_SURFACE.
+#define MVK_MAKE_VK_EXT_PROPS(EXT) \
+static VkExtensionProperties kVkExtProps_ ##EXT = mvkMakeExtProps(VK_ ##EXT ##_EXTENSION_NAME, VK_ ##EXT ##_SPEC_VERSION)
+
+// Extension properties
+MVK_MAKE_VK_EXT_PROPS(MVK_MOLTENVK);
+MVK_MAKE_VK_EXT_PROPS(MVK_MACOS_SURFACE);
+MVK_MAKE_VK_EXT_PROPS(MVK_IOS_SURFACE);
+MVK_MAKE_VK_EXT_PROPS(KHR_SURFACE);
+MVK_MAKE_VK_EXT_PROPS(KHR_SWAPCHAIN);
+MVK_MAKE_VK_EXT_PROPS(KHR_MAINTENANCE1);
+MVK_MAKE_VK_EXT_PROPS(IMG_FORMAT_PVRTC);
+MVK_MAKE_VK_EXT_PROPS(AMD_NEGATIVE_VIEWPORT_HEIGHT);
+MVK_MAKE_VK_EXT_PROPS(KHR_SHADER_DRAW_PARAMETERS);
+MVK_MAKE_VK_EXT_PROPS(KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2);
+MVK_MAKE_VK_EXT_PROPS(KHR_PUSH_DESCRIPTOR);
+
+// Calls the constructor for a MVKExtension member variable, using the member name and the
+// portion of the extension name, as uppercase, used in the MVK_MAKE_VK_EXT_PROPS() macro above.
+// For example, for the memeber variable vk_KHR_surface, use MVKExt_CONSTRUCT(vk_KHR_surface, KHR_SURFACE).
+#define MVKExt_CONSTRUCT(var, EXT) var(&kVkExtProps_ ##EXT, enableForPlatform)
+
+MVKExtensionList::MVKExtensionList(bool enableForPlatform) :
+ MVKExt_CONSTRUCT(vk_MVK_moltenvk, MVK_MOLTENVK),
+ MVKExt_CONSTRUCT(vk_MVK_macos_surface, MVK_MACOS_SURFACE),
+ MVKExt_CONSTRUCT(vk_MVK_ios_surface, MVK_IOS_SURFACE),
+ MVKExt_CONSTRUCT(vk_KHR_surface, KHR_SURFACE),
+ MVKExt_CONSTRUCT(vk_KHR_swapchain, KHR_SWAPCHAIN),
+ MVKExt_CONSTRUCT(vk_KHR_maintenance1, KHR_MAINTENANCE1),
+ MVKExt_CONSTRUCT(vk_IMG_format_pvrtc, IMG_FORMAT_PVRTC),
+ MVKExt_CONSTRUCT(vk_AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT),
+ MVKExt_CONSTRUCT(vk_KHR_shader_draw_parameters, KHR_SHADER_DRAW_PARAMETERS),
+ MVKExt_CONSTRUCT(vk_KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2),
+ MVKExt_CONSTRUCT(vk_KHR_push_descriptor, KHR_PUSH_DESCRIPTOR)
+{}
+
+bool MVKExtensionList::isEnabled(const char* extnName) const {
+ uint32_t extnCnt = getCount();
+ const MVKExtension* extnAry = &extensionArray;
+ for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
+ const MVKExtension& extn = extnAry[extnIdx];
+ if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
+ return extn.enabled;
+ }
+ }
+ return false;
+}
+
+void MVKExtensionList::enable(const char* extnName) {
+ uint32_t extnCnt = getCount();
+ MVKExtension* extnAry = &extensionArray;
+ for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
+ MVKExtension& extn = extnAry[extnIdx];
+ if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
+ extn.enabled = true;
+ return;
+ }
+ }
+}
+
+VkResult MVKExtensionList::enable(uint32_t count, const char* const* names, MVKExtensionList* parent) {
+ VkResult result = VK_SUCCESS;
+ for (uint32_t i = 0; i < count; i++) {
+ auto extnName = names[i];
+ if (parent && !parent->isEnabled(extnName)) {
+ result = mvkNotifyErrorWithText(VK_ERROR_EXTENSION_NOT_PRESENT, "Vulkan extension %s is not supported.", extnName);
+ } else {
+ enable(extnName);
+ }
+ }
+ return result;
+}
+
+string MVKExtensionList::enabledNamesString(const char* separator, bool prefixFirstWithSeparator) const {
+ string logMsg;
+ bool isFirst = true;
+ uint32_t extnCnt = getCount();
+ const MVKExtension* extnAry = &extensionArray;
+ for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
+ const MVKExtension& extn = extnAry[extnIdx];
+ if (extn.enabled) {
+ if ( !isFirst || prefixFirstWithSeparator ) { logMsg += separator; }
+ logMsg += extn.pProperties->extensionName;
+ logMsg += " v";
+ logMsg += to_string(extn.pProperties->specVersion);
+ isFirst = false;
+ }
+ }
+ return logMsg;
+}
+
+// Returns whether the specified properties are valid for this platform
+static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
+#if !(MVK_IOS)
+ if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
+ if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
+#endif
+#if !(MVK_MACOS)
+ if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
+#endif
+
+ if (pProperties == &kVkExtProps_AMD_NEGATIVE_VIEWPORT_HEIGHT) { return false; }
+
+ return true;
+}
+
+// Disable by default unless asked to enable for platform and the extension is valid for this platform
+MVKExtension::MVKExtension(VkExtensionProperties* pProperties, bool enableForPlatform) {
+ this->pProperties = pProperties;
+ this->enabled = enableForPlatform && mvkIsSupportedOnPlatform(pProperties);
+}
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.h b/MoltenVK/MoltenVK/Layers/MVKExtensions.h
new file mode 100644
index 0000000..1b2a2e2
--- /dev/null
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.h
@@ -0,0 +1,82 @@
+/*
+ * MVKExtensions.h
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "mvk_vulkan.h"
+#include <string>
+
+/** Describes a Vulkan extension and whether or not it is enabled or supported. */
+struct MVKExtension {
+ bool enabled = false;
+ VkExtensionProperties* pProperties;
+
+ MVKExtension(VkExtensionProperties* pProperties, bool enableForPlatform = false);
+};
+
+/**
+ * A fixed list of the Vulkan extensions known to MoltenVK, with
+ * an indication of whether each extension is supported/enabled.
+ *
+ * To add support for a Vulkan extension, add a variable to this list.
+ */
+struct MVKExtensionList {
+ union {
+ struct {
+ MVKExtension vk_MVK_moltenvk;
+ MVKExtension vk_MVK_macos_surface;
+ MVKExtension vk_MVK_ios_surface;
+ MVKExtension vk_KHR_surface;
+ MVKExtension vk_KHR_swapchain;
+ MVKExtension vk_KHR_maintenance1;
+ MVKExtension vk_IMG_format_pvrtc;
+ MVKExtension vk_AMD_negative_viewport_height;
+ MVKExtension vk_KHR_shader_draw_parameters;
+ MVKExtension vk_KHR_get_physical_device_properties2;
+ MVKExtension vk_KHR_push_descriptor;
+ };
+ MVKExtension extensionArray;
+ };
+
+ /** Returns the total number of extensions that are tracked by this object. */
+ static uint32_t getCount() { return sizeof(MVKExtensionList) / sizeof(MVKExtension); }
+
+ /** Returns whether the named extension is enabled. */
+ bool isEnabled(const char* extnName) const;
+
+ /** Enables the named extension. */
+ void enable(const char* extnName);
+
+ /**
+ * Enables the named extensions.
+ *
+ * If parent is non null, the extension must also be enabled in the parent in order
+ * for it to be enabled here. If it is not enabled in the parent, an error is logged
+ * and returned. Returns VK_SUCCESS if all requested extensions were able to be enabled.
+ */
+ VkResult enable(uint32_t count, const char* const* names, MVKExtensionList* parent = nullptr);
+
+ /**
+ * Returns a string containing the names of the enabled extensions, separated by the separator string.
+ * If prefixFirstWithSeparator is true the separator will also appear before the first extension name.
+ */
+ std::string enabledNamesString(const char* separator = " ", bool prefixFirstWithSeparator = false) const;
+
+ MVKExtensionList(bool enableForPlatform = false);
+};
+
diff --git a/MoltenVK/MoltenVK/Loader/MVKLayers.h b/MoltenVK/MoltenVK/Layers/MVKLayers.h
similarity index 90%
rename from MoltenVK/MoltenVK/Loader/MVKLayers.h
rename to MoltenVK/MoltenVK/Layers/MVKLayers.h
index 2fb56dd..f539a31 100644
--- a/MoltenVK/MoltenVK/Loader/MVKLayers.h
+++ b/MoltenVK/MoltenVK/Layers/MVKLayers.h
@@ -18,8 +18,8 @@
#pragma once
-#include "mvk_vulkan.h"
#include "MVKBaseObject.h"
+#include "MVKExtensions.h"
#include <vector>
@@ -50,16 +50,16 @@
*/
VkResult getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties);
- /** Returns whether this layer supports the specified extension. */
- bool hasExtensionNamed(const char* extnName);
+ /** Returns the list of supported extensions. */
+ MVKExtensionList* getSupportedExtensions() { return &_supportedExtensions; }
/** Default constructor. This represents the driver implementation. */
MVKLayer();
protected:
VkLayerProperties _layerProperties;
- std::vector<VkExtensionProperties> _extensions;
-
+ MVKExtensionList _supportedExtensions;
+
};
@@ -70,12 +70,11 @@
public:
- /** Returns a pointer to the driver layer. */
+ /** Returns the driver layer. */
MVKLayer* getDriverLayer();
/**
- * Returns a pointe to the layer with the specified name,
- * or null if no layer was found with that name.
+ * Returns the layer with the specified name, or null if no layer was found with that name.
*
* If pLayerName is null, returns the driver layer, which is
* the same layer returned by the getDriverLayer() function.
diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.mm b/MoltenVK/MoltenVK/Layers/MVKLayers.mm
new file mode 100644
index 0000000..d1764cd
--- /dev/null
+++ b/MoltenVK/MoltenVK/Layers/MVKLayers.mm
@@ -0,0 +1,131 @@
+/*
+ * MVKLayers.mm
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MVKLayers.h"
+#include "MVKEnvironment.h"
+#include "vk_mvk_moltenvk.h"
+#include <mutex>
+
+using namespace std;
+
+
+#pragma mark MVKLayer
+
+const char* MVKLayer::getName() { return (const char*)&_layerProperties.layerName; }
+
+VkLayerProperties* const MVKLayer::getLayerProperties() { return &_layerProperties; }
+
+VkResult MVKLayer::getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties) {
+
+ uint32_t enabledCnt = 0;
+
+ // Iterate extensions and handle those that are enabled. Count them,
+ // and if they are to be returned, and there is room, do so.
+ uint32_t extnCnt = _supportedExtensions.getCount();
+ MVKExtension* extnAry = &_supportedExtensions.extensionArray;
+ for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
+ if (extnAry[extnIdx].enabled) {
+ if (pProperties) {
+ if (enabledCnt < *pCount) {
+ pProperties[enabledCnt] = *(extnAry[extnIdx].pProperties);
+ } else {
+ return VK_INCOMPLETE;
+ }
+ }
+ enabledCnt++;
+ }
+ }
+
+ // Return the count of enabled extensions. This will either be a
+ // count of all enabled extensions, or a count of those returned.
+ *pCount = enabledCnt;
+ return VK_SUCCESS;
+}
+
+
+#pragma mark Object Creation
+
+MVKLayer::MVKLayer() : _supportedExtensions(true) {
+
+ // The core driver layer
+ memset(_layerProperties.layerName, 0, sizeof(_layerProperties.layerName));
+ strcpy(_layerProperties.layerName, "MoltenVK");
+ memset(_layerProperties.description, 0, sizeof(_layerProperties.description));
+ strcpy(_layerProperties.description, "MoltenVK driver layer");
+ _layerProperties.specVersion = MVK_VULKAN_API_VERSION;
+ _layerProperties.implementationVersion = MVK_VERSION;
+}
+
+
+#pragma mark MVKLayerManager
+
+MVKLayer* MVKLayerManager::getDriverLayer() { return &(_layers[0]); }
+
+MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) {
+
+ // If name is null, return the driver layer
+ if ( !pLayerName ) { return getDriverLayer(); }
+
+ // Otherwise look for a layer with the specified name
+ uint32_t layCnt = (uint32_t)_layers.size();
+ for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
+ MVKLayer* pLayer = &_layers[layIdx];
+ if ( strcmp(pLayer->getName(), pLayerName) == 0 ) { return pLayer; }
+ }
+ return VK_NULL_HANDLE;
+}
+
+VkResult MVKLayerManager::getLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
+
+ // If properties aren't actually being requested yet, simply update the returned count
+ if ( !pProperties ) {
+ *pCount = (uint32_t)_layers.size();
+ return VK_SUCCESS;
+ }
+
+ // Othewise, determine how many layers we'll return, and return that count
+ uint32_t layerCnt = (uint32_t)_layers.size();
+ VkResult result = (*pCount <= layerCnt) ? VK_SUCCESS : VK_INCOMPLETE;
+ *pCount = min(layerCnt, *pCount);
+
+ // Now populate the layer properties
+ for (uint32_t layIdx = 0; layIdx < *pCount; layIdx++) {
+ pProperties[layIdx] = *(&_layers[layIdx])->getLayerProperties();
+ }
+
+ return result;
+}
+
+
+#pragma mark Object Creation
+
+// Populate the layers
+MVKLayerManager::MVKLayerManager() {
+ _layers.push_back(MVKLayer());
+}
+
+static mutex _lock;
+static MVKLayerManager* _globalManager = VK_NULL_HANDLE;
+
+MVKLayerManager* MVKLayerManager::globalManager() {
+ lock_guard<mutex> lock(_lock);
+ if ( !_globalManager ) { _globalManager = new MVKLayerManager(); }
+ return _globalManager;
+}
+
+
diff --git a/MoltenVK/MoltenVK/Loader/MVKLayers.mm b/MoltenVK/MoltenVK/Loader/MVKLayers.mm
deleted file mode 100644
index 42f331e..0000000
--- a/MoltenVK/MoltenVK/Loader/MVKLayers.mm
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * MVKLayers.mm
- *
- * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "MVKLayers.h"
-#include "MVKEnvironment.h"
-#include "vk_mvk_moltenvk.h"
-#include <mutex>
-
-using namespace std;
-
-
-#pragma mark MVKLayer
-
-const char* MVKLayer::getName() { return (const char*)&_layerProperties.layerName; }
-
-VkLayerProperties* const MVKLayer::getLayerProperties() { return &_layerProperties; }
-
-VkResult MVKLayer::getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties) {
-
- // If properties aren't actually being requested yet, simply update the returned count
- if ( !pProperties ) {
- *pCount = (uint32_t)_extensions.size();
- return VK_SUCCESS;
- }
-
- // Othewise, determine how many extensions we'll return, and return that count
- uint32_t extCnt = (uint32_t)_extensions.size();
- VkResult result = (*pCount <= extCnt) ? VK_SUCCESS : VK_INCOMPLETE;
- *pCount = min(extCnt, *pCount);
-
- // Now populate the layer properties
- for (uint32_t extIdx = 0; extIdx < *pCount; extIdx++) {
- pProperties[extIdx] = _extensions[extIdx];
- }
-
- return result;
-}
-
-bool MVKLayer::hasExtensionNamed(const char* extnName) {
- for (auto& extn : _extensions) {
- if ( strcmp(extn.extensionName, extnName) == 0 ) { return true; }
- }
- return false;
-}
-
-
-#pragma mark Object Creation
-
-MVKLayer::MVKLayer() {
-
- // The core driver layer
- strcpy(_layerProperties.layerName, "MoltenVK");
- strcpy(_layerProperties.description, "MoltenVK driver layer");
- _layerProperties.specVersion = MVK_VULKAN_API_VERSION;
- _layerProperties.implementationVersion = MVK_VERSION;
-
- // Extensions
- VkExtensionProperties extTmplt;
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME);
- extTmplt.specVersion = VK_MVK_MOLTENVK_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_SURFACE_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_SURFACE_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME);
- extTmplt.specVersion = VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_MAINTENANCE1_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
- extTmplt.specVersion = VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
-#if MVK_IOS
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_MVK_IOS_SURFACE_EXTENSION_NAME);
- extTmplt.specVersion = VK_MVK_IOS_SURFACE_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_IMG_FORMAT_PVRTC_EXTENSION_NAME);
- extTmplt.specVersion = VK_IMG_FORMAT_PVRTC_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-#endif
-#if MVK_MACOS
- memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
- strcpy(extTmplt.extensionName, VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
- extTmplt.specVersion = VK_MVK_MACOS_SURFACE_SPEC_VERSION;
- _extensions.push_back(extTmplt);
-#endif
-}
-
-
-#pragma mark MVKLayerManager
-
-MVKLayer* MVKLayerManager::getDriverLayer() { return &(_layers[0]); }
-
-MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) {
-
- // If name is null, return the driver layer
- if ( !pLayerName ) { return getDriverLayer(); }
-
- // Otherwise look for a layer with the specified name
- uint32_t layCnt = (uint32_t)_layers.size();
- for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
- MVKLayer* pLayer = &_layers[layIdx];
- if ( strcmp(pLayer->getName(), pLayerName) == 0 ) { return pLayer; }
- }
- return VK_NULL_HANDLE;
-}
-
-
-VkResult MVKLayerManager::getLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
-
- // If properties aren't actually being requested yet, simply update the returned count
- if ( !pProperties ) {
- *pCount = (uint32_t)_layers.size();
- return VK_SUCCESS;
- }
-
- // Othewise, determine how many layers we'll return, and return that count
- uint32_t layerCnt = (uint32_t)_layers.size();
- VkResult result = (*pCount <= layerCnt) ? VK_SUCCESS : VK_INCOMPLETE;
- *pCount = min(layerCnt, *pCount);
-
- // Now populate the layer properties
- for (uint32_t layIdx = 0; layIdx < *pCount; layIdx++) {
- pProperties[layIdx] = *(&_layers[layIdx])->getLayerProperties();
- }
-
- return result;
-}
-
-
-#pragma mark Object Creation
-
-// Populate the layers
-MVKLayerManager::MVKLayerManager() {
- _layers.push_back(MVKLayer());
-}
-
-static mutex _lock;
-static MVKLayerManager* _globalManager = VK_NULL_HANDLE;
-
-MVKLayerManager* MVKLayerManager::globalManager() {
- lock_guard<mutex> lock(_lock);
- if ( !_globalManager ) { _globalManager = new MVKLayerManager(); }
- return _globalManager;
-}
-
-
diff --git a/MoltenVK/MoltenVK/OS/MVKOSExtensions.h b/MoltenVK/MoltenVK/OS/MVKOSExtensions.h
index 4c65590..f2e520b 100644
--- a/MoltenVK/MoltenVK/OS/MVKOSExtensions.h
+++ b/MoltenVK/MoltenVK/OS/MVKOSExtensions.h
@@ -18,7 +18,7 @@
#pragma once
-#include <vulkan/vulkan.h>
+#include "mvk_vulkan.h"
#import <Metal/Metal.h>
diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h
index 683ba4b..f15aeac 100644
--- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h
+++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h
@@ -18,7 +18,7 @@
#pragma once
-#include <vulkan/vulkan.h>
+#include "mvk_vulkan.h"
#include <vulkan/vk_icd.h>
#include <string>
diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.mm b/MoltenVK/MoltenVK/Utility/MVKFoundation.cpp
similarity index 95%
rename from MoltenVK/MoltenVK/Utility/MVKFoundation.mm
rename to MoltenVK/MoltenVK/Utility/MVKFoundation.cpp
index 847c223..fab2bcc 100644
--- a/MoltenVK/MoltenVK/Utility/MVKFoundation.mm
+++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.cpp
@@ -1,5 +1,5 @@
/*
- * MVKFoundation.mm
+ * MVKFoundation.cpp
*
* Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
@@ -52,8 +52,8 @@
CASE_RESULT(VK_ERROR_VALIDATION_FAILED_EXT)
CASE_RESULT(VK_ERROR_INVALID_SHADER_NV)
- CASE_RESULT(VK_ERROR_OUT_OF_POOL_MEMORY_KHR)
- CASE_RESULT(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR)
+ CASE_RESULT(VK_ERROR_OUT_OF_POOL_MEMORY)
+ CASE_RESULT(VK_ERROR_INVALID_EXTERNAL_HANDLE)
default:
sprintf(name, "UNKNOWN_VkResult(%d)", vkResult);
diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h
index 2e1ae3e..22539cf 100644
--- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h
+++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h
@@ -20,7 +20,7 @@
#pragma once
-#include <vulkan/vulkan.h>
+#include "mvk_vulkan.h"
#include "MVKLogging.h"
#include <algorithm>
#include <simd/simd.h>
@@ -311,11 +311,13 @@
* Iterates through the contents of the specified Objective-C object pointer
* container and releases each object, and clears the container.
*/
+#ifdef __OBJC__
template<typename C>
void mvkReleaseContainerContents(C& container) {
for (auto elem : container) { [elem release]; }
container.clear();
}
+#endif
/** Removes the first occurance of the specified value from the specified container. */
template<class C, class T>
diff --git a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm
index fee880f..cc6bbfb 100644
--- a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm
+++ b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm
@@ -32,7 +32,7 @@
MVKConfiguration* pConfiguration) {
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
- if (pConfiguration) { *pConfiguration = mvkInst->_mvkConfig; }
+ if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkInst->getMoltenVKConfiguration(); }
}
MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKConfigurationMVK(
@@ -40,7 +40,7 @@
MVKConfiguration* pConfiguration) {
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
- if (pConfiguration) { mvkInst->_mvkConfig = *pConfiguration; }
+ if (pConfiguration) { mvkInst->setMoltenVKConfiguration(pConfiguration); }
return VK_SUCCESS;
}
@@ -142,7 +142,7 @@
MVKDeviceConfiguration* pConfiguration) {
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
- if (pConfiguration) { *pConfiguration = mvkDev->getInstance()->_mvkConfig; }
+ if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkDev->getInstance()->getMoltenVKConfiguration(); }
}
MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKDeviceConfigurationMVK(
@@ -150,7 +150,7 @@
MVKDeviceConfiguration* pConfiguration) {
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
- if (pConfiguration) { mvkDev->getInstance()->_mvkConfig = *pConfiguration; }
+ if (pConfiguration) { mvkDev->getInstance()->setMoltenVKConfiguration(pConfiguration); }
return VK_SUCCESS;
}