diff --git a/Common/MVKCommonEnvironment.h b/Common/MVKCommonEnvironment.h index 548fd204..e51638fd 100644 --- a/Common/MVKCommonEnvironment.h +++ b/Common/MVKCommonEnvironment.h @@ -125,6 +125,19 @@ extern "C" { (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000)) #endif +/** + * Enable use of private Metal APIs. + * + * Enabling this build setting during a MoltenVK build will allow MoltenVK to + * extend its functionality by using certain private Metal API calls, but it + * will also disqualify the app from being distributed via Apple App Stores. + * + * Disabled by default. + */ +#ifndef MVK_USE_METAL_PRIVATE_API +# define MVK_USE_METAL_PRIVATE_API 0 +#endif + /** Directive to identify public symbols. */ #define MVK_PUBLIC_SYMBOL __attribute__((visibility("default"))) __attribute__((used)) diff --git a/Docs/MoltenVK_Configuration_Parameters.md b/Docs/MoltenVK_Configuration_Parameters.md index 8852020f..5e02256d 100644 --- a/Docs/MoltenVK_Configuration_Parameters.md +++ b/Docs/MoltenVK_Configuration_Parameters.md @@ -663,3 +663,16 @@ Determines the style used to implement _Vulkan_ semaphore (`VkSemaphore`) functi In the special case of `VK_SEMAPHORE_TYPE_TIMELINE` semaphores, **MoltenVK** will always use `MTLSharedEvent` if it is available on the platform, regardless of the value of this parameter. + +--------------------------------------- +#### MVK_CONFIG_USE_METAL_PRIVATE_API + +##### Type: Boolean +##### Default: Value of `MVK_USE_METAL_PRIVATE_API` + +If enabled, **MoltenVK** will _use_ private interfaces exposed by _Metal_ to implement _Vulkan_ +features that are difficult to support otherwise. + +Unlike `MVK_USE_METAL_PRIVATE_API`, this setting may be overridden at run time. + +This option is not available unless MoltenVK were built with `MVK_USE_METAL_PRIVATE_API` set to `1`. diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index f1ef55b2..fc72286a 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -20,6 +20,10 @@ Released TBD - Add `MVK_USE_METAL_PRIVATE_API` build setting to allow **MoltenVK** to be built with access to _Metal_ private API calls. - Add support for `VkPhysicalDeviceFeatures::wideLines` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. +- Add support for the `VkPhysicalDeviceFeatures::logicOp` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. +- Add support for the `VkPhysicalDeviceFeatures::depthBounds` feature on AMD GPUs when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. +- Add support for the `VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. +- Add support for Metal native pipeline sample masks when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. - Fix potential crash when using multi-planar images. - Ensure buffers available for buffer addresses in push constants. - Support `libMoltenVK.dylib` for _iOS Simulator_ architecture. diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index 4a1940d1..e71435e0 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -140,6 +140,10 @@ 45557A5321C9EFF3008868BD /* MVKCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.mm */; }; 45557A5421C9EFF3008868BD /* MVKCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 45557A5121C9EFF3008868BD /* MVKCodec.h */; }; 45557A5521C9EFF3008868BD /* MVKCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 45557A5121C9EFF3008868BD /* MVKCodec.h */; }; + 45E3A40B2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = 45E3A4062166B922005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h */; }; + 45E3A40C2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = 45E3A4062166B922005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h */; }; + 45E3A40D2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 45E3A40A2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m */; }; + 45E3A40E2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 45E3A40A2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m */; }; 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 */; }; @@ -582,6 +586,8 @@ 45557A4D21C9EFF3008868BD /* MVKCodec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCodec.mm; sourceTree = ""; }; 45557A5121C9EFF3008868BD /* MVKCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCodec.h; sourceTree = ""; }; 45557A5721CD83C3008868BD /* MVKDXTnCodec.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKDXTnCodec.def; sourceTree = ""; }; + 45E3A4062166B922005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h"; sourceTree = ""; }; + 45E3A40A2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m"; sourceTree = ""; }; A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdDispatch.h; sourceTree = ""; }; A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDispatch.mm; sourceTree = ""; }; A909F65A213B190600FCD6BE /* MVKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKExtensions.h; sourceTree = ""; }; @@ -904,6 +910,8 @@ 453638302508A4C6000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m */, A9E53DFE21064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.h */, A9E53DFA21064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.m */, + 45E3A4062166B922005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h */, + 45E3A40A2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m */, A9E53DD32100B197002781DD /* MTLSamplerDescriptor+MoltenVK.h */, A9E53DCD2100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m */, A9E53DD02100B197002781DD /* MTLTextureDescriptor+MoltenVK.h */, @@ -1086,6 +1094,7 @@ A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */, A9F3D9DC24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */, A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */, + 45E3A40B2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h in Headers */, A94FB7F81C7DFB4800632CA3 /* MVKPipeline.h in Headers */, A94FB7F01C7DFB4800632CA3 /* MVKImage.h in Headers */, 4553AEFD2251617100E8EBCD /* MVKBlockObserver.h in Headers */, @@ -1163,6 +1172,7 @@ A94FB7C51C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */, A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */, A9F3D9DD24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */, + 45E3A40C2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h in Headers */, A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */, A9C327582AAFBD3A0025EE79 /* MVKConfigMembers.def in Headers */, A94FB7F11C7DFB4800632CA3 /* MVKImage.h in Headers */, @@ -1776,6 +1786,7 @@ A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */, A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */, A99C90F0229455B300A061DA /* MVKCmdDebug.mm in Sources */, + 45E3A40D2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1836,6 +1847,7 @@ A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */, A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */, A99C90F1229455B300A061DA /* MVKCmdDebug.mm in Sources */, + 45E3A40E2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MoltenVK/MoltenVK/API/mvk_datatypes.h b/MoltenVK/MoltenVK/API/mvk_datatypes.h index de3d08a5..902dc0cb 100644 --- a/MoltenVK/MoltenVK/API/mvk_datatypes.h +++ b/MoltenVK/MoltenVK/API/mvk_datatypes.h @@ -342,6 +342,9 @@ MTLBlendOperation mvkMTLBlendOperationFromVkBlendOp(VkBlendOp vkBlendOp); /** Returns the Metal MTLBlendFactor corresponding to the specified Vulkan VkBlendFactor. */ MTLBlendFactor mvkMTLBlendFactorFromVkBlendFactor(VkBlendFactor vkBlendFactor); +/** Returns the Metal MTLLogicOperation corresponding to the specified Vulkan VkLogicOp. */ +NSUInteger mvkMTLLogicOperationFromVkLogicOp(VkLogicOp vkBlendOp); + /** * Returns the Metal MTLVertexFormat corresponding to the specified * Vulkan VkFormat as used as a vertex attribute format. diff --git a/MoltenVK/MoltenVK/API/mvk_private_api.h b/MoltenVK/MoltenVK/API/mvk_private_api.h index 38ec2f3d..4a6ae35e 100644 --- a/MoltenVK/MoltenVK/API/mvk_private_api.h +++ b/MoltenVK/MoltenVK/API/mvk_private_api.h @@ -240,6 +240,8 @@ typedef struct { MVKConfigCompressionAlgorithm shaderSourceCompressionAlgorithm; /**< MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM */ VkBool32 shouldMaximizeConcurrentCompilation; /**< MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION */ float timestampPeriodLowPassAlpha; /**< MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA */ + VkBool32 useMetalPrivateAPI; /**< MVK_CONFIG_USE_METAL_PRIVATE_API */ + uint32_t _unused_struct_padding; } MVKConfiguration; // Legacy support for renamed struct elements. diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h index 4b5dadcb..1f6d2559 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h @@ -375,6 +375,41 @@ protected: }; +#pragma mark - +#pragma mark MVKCmdSetDepthBounds + +/** Vulkan command to set depth bounds. */ +class MVKCmdSetDepthBounds : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + float minDepthBounds, + float maxDepthBounds); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + float _minDepthBounds; + float _maxDepthBounds; +}; + + +#pragma mark - +#pragma mark MVKCmdSetDepthBoundsTestEnable + +/** Vulkan command to enable depth bounds testing. */ +class MVKCmdSetDepthBoundsTestEnable : public MVKSingleValueCommand { + +public: + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; +}; + + #pragma mark - #pragma mark MVKCmdSetStencilTestEnable diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm index 132f0927..0c9d8ed9 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm @@ -327,6 +327,30 @@ void MVKCmdSetDepthCompareOp::encode(MVKCommandEncoder* cmdEncoder) { } +#pragma mark - +#pragma mark MVKCmdSetDepthBounds + +VkResult MVKCmdSetDepthBounds::setContent(MVKCommandBuffer* cmdBuff, + float minDepthBounds, + float maxDepthBounds) { + _minDepthBounds = minDepthBounds; + _maxDepthBounds = maxDepthBounds; + return VK_SUCCESS; +} + +void MVKCmdSetDepthBounds::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_renderingState.setDepthBounds(_minDepthBounds, _maxDepthBounds, true); +} + + +#pragma mark - +#pragma mark MVKCmdSetDepthBoundsTestEnable + +void MVKCmdSetDepthBoundsTestEnable::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_renderingState.setDepthBoundsTestEnable(_value, true); +} + + #pragma mark - #pragma mark MVKCmdSetStencilTestEnable diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h index f90ecf8e..125a8db5 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -239,6 +239,11 @@ struct MVKDepthBias { float depthBiasClamp; }; +struct MVKDepthBounds { + float minDepthBound; + float maxDepthBound; +}; + struct MVKStencilReference { uint32_t frontFaceValue; uint32_t backFaceValue; @@ -272,6 +277,8 @@ public: void setDepthBiasEnable(VkBool32 depthBiasEnable); void setDepthClipEnable(bool depthClip, bool isDynamic); + void setDepthBounds(float minDepthBounds, float maxDepthBounds, bool isDynamic); + void setDepthBoundsTestEnable(VkBool32 depthBoundsTestEnable, bool isDynamic); void setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo); void setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference); @@ -318,6 +325,7 @@ protected: MVKMTLScissors _mtlScissors[StateScope::Count] = {}; MVKColor32 _mtlBlendConstants[StateScope::Count] = {}; MVKDepthBias _mtlDepthBias[StateScope::Count] = {}; + MVKDepthBounds _mtlDepthBounds[StateScope::Count] = {}; MVKStencilReference _mtlStencilReference[StateScope::Count] = {}; MTLCullMode _mtlCullMode[StateScope::Count] = { MTLCullModeNone, MTLCullModeNone }; MTLWinding _mtlFrontFace[StateScope::Count] = { MTLWindingClockwise, MTLWindingClockwise }; @@ -332,6 +340,7 @@ protected: bool _mtlDepthBiasEnable[StateScope::Count] = {}; bool _mtlPrimitiveRestartEnable[StateScope::Count] = {}; bool _mtlRasterizerDiscardEnable[StateScope::Count] = {}; + bool _mtlDepthBoundsTestEnable[StateScope::Count] = {}; bool _cullBothFaces[StateScope::Count] = {}; bool _isPolygonModePoint[StateScope::Count] = {}; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 71135a6e..8df4dde9 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -369,6 +369,16 @@ void MVKRenderingCommandEncoderState::setDepthClipEnable(bool depthClip, bool is setMTLContent(DepthClipEnable); } +void MVKRenderingCommandEncoderState::setDepthBounds(float minDepthBounds, float maxDepthBounds, bool isDynamic) { + MVKDepthBounds mtlDepthBounds = { minDepthBounds, maxDepthBounds }; + setMTLContent(DepthBounds); +} + +void MVKRenderingCommandEncoderState::setDepthBoundsTestEnable(VkBool32 depthBoundsTestEnable, bool isDynamic) { + auto mtlDepthBoundsTestEnable = static_cast(depthBoundsTestEnable); + setMTLContent(DepthBoundsTestEnable); +} + void MVKRenderingCommandEncoderState::setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) { bool isDynamic = false; MVKStencilReference mtlStencilReference = { @@ -545,6 +555,14 @@ bool MVKRenderingCommandEncoderState::needsMetalRenderPassRestart() { // An extension of the MTLRenderCommandEncoder protocol to declare the setLineWidth: method. @protocol MVKMTLRenderCommandEncoderLineWidth -(void) setLineWidth: (float) width; +@end + +// An extension of the MTLRenderCommandEncoder protocol containing a declaration of the +// -setDepthBoundsTestAMD:minDepth:maxDepth: method. +@protocol MVKMTLRenderCommandEncoderDepthBoundsAMD + +- (void)setDepthBoundsTestAMD:(BOOL)enable minDepth:(float)minDepth maxDepth:(float)maxDepth; + @end #endif @@ -584,6 +602,21 @@ void MVKRenderingCommandEncoderState::encodeImpl(uint32_t stage) { [rendEnc setDepthClipMode: getMTLContent(DepthClipEnable)]; } +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI && (isDirty(DepthBoundsTestEnable) || isDirty(DepthBounds)) && + _cmdEncoder->_pDeviceFeatures->depthBounds) { + if (getMTLContent(DepthBoundsTestEnable)) { + auto& db = getMTLContent(DepthBounds); + [(id)_cmdEncoder->_mtlRenderEncoder setDepthBoundsTestAMD: YES + minDepth: db.minDepthBound + maxDepth: db.maxDepthBound]; + } else { + [(id)_cmdEncoder->_mtlRenderEncoder setDepthBoundsTestAMD: NO + minDepth: 0.0f + maxDepth: 1.0f]; + } + } +#endif if (isDirty(StencilReference)) { auto& sr = getMTLContent(StencilReference); [rendEnc setStencilFrontReferenceValue: sr.frontFaceValue backReferenceValue: sr.backFaceValue]; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index d6495857..a79fd199 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -90,6 +90,8 @@ MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetScissor, 1) MVK_CMD_TYPE_POOL(SetBlendConstants) MVK_CMD_TYPE_POOL(SetDepthBias) MVK_CMD_TYPE_POOL(SetDepthBiasEnable) +MVK_CMD_TYPE_POOL(SetDepthBounds) +MVK_CMD_TYPE_POOL(SetDepthBoundsTestEnable) MVK_CMD_TYPE_POOL(SetDepthTestEnable) MVK_CMD_TYPE_POOL(SetDepthWriteEnable) MVK_CMD_TYPE_POOL(SetDepthClipEnable) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index ac5c38c9..ef7fbcbe 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -366,7 +366,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { portabilityFeatures->multisampleArrayImage = _metalFeatures.multisampleArrayTextures; portabilityFeatures->mutableComparisonSamplers = _metalFeatures.depthSampleCompare; portabilityFeatures->pointPolygons = false; - portabilityFeatures->samplerMipLodBias = false; + portabilityFeatures->samplerMipLodBias = getMVKConfig().useMetalPrivateAPI; portabilityFeatures->separateStencilMaskRef = true; portabilityFeatures->shaderSampleRateInterpolationFunctions = _metalFeatures.pullModelInterpolation; portabilityFeatures->tessellationIsolines = false; @@ -2338,10 +2338,11 @@ void MVKPhysicalDevice::initFeatures() { _features.fullDrawIndexUint32 = true; _features.independentBlend = true; _features.sampleRateShading = true; + _features.logicOp = getMVKConfig().useMetalPrivateAPI; _features.depthBiasClamp = true; _features.fillModeNonSolid = true; _features.largePoints = true; - _features.wideLines = static_cast(MVK_USE_METAL_PRIVATE_API); + _features.wideLines = getMVKConfig().useMetalPrivateAPI; _features.alphaToOne = true; _features.samplerAnisotropy = true; _features.shaderImageGatherExtended = true; @@ -2442,6 +2443,13 @@ void MVKPhysicalDevice::initFeatures() { _features.shaderStorageImageArrayDynamicIndexing = _metalFeatures.arrayOfTextures; +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI && _properties.vendorID == kAMDVendorId) { + // Only AMD drivers have the method we need for now. + _features.depthBounds = true; + } +#endif + if (supportsMTLFeatureSet(macOS_GPUFamily1_v2)) { _features.tessellationShader = true; _features.dualSrcBlend = true; @@ -2522,6 +2530,10 @@ void MVKPhysicalDevice::initLimits() { _properties.limits.maxImageDimension3D = _metalFeatures.maxTextureLayers; _properties.limits.maxImageArrayLayers = _metalFeatures.maxTextureLayers; + // Max sum of API and shader values. Bias not publicly supported in API, but can be applied in the shader directly. + // The lack of API value is covered by VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias. + // Metal does not specify a limit for the shader value, so choose something reasonable. + _properties.limits.maxSamplerLodBias = getMVKConfig().useMetalPrivateAPI ? 16 : 4; _properties.limits.maxSamplerAnisotropy = 16; _properties.limits.maxVertexInputAttributes = 31; @@ -2798,11 +2810,6 @@ void MVKPhysicalDevice::initLimits() { #endif } - // Max sum of API and shader values. Bias not supported in API, but can be applied in shader directly. - // The lack of API value is covered by VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias. - // Metal does not specify limit for shader value, so choose something reasonable. - _properties.limits.maxSamplerLodBias = 4; - _properties.limits.minTexelOffset = -8; _properties.limits.maxTexelOffset = 7; _properties.limits.minTexelGatherOffset = _properties.limits.minTexelOffset; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 52d9061b..5c4e06f9 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -2221,6 +2221,11 @@ MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateI mtlSampDesc.mipFilter = (pCreateInfo->unnormalizedCoordinates ? MTLSamplerMipFilterNotMipmapped : mvkMTLSamplerMipFilterFromVkSamplerMipmapMode(pCreateInfo->mipmapMode)); +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI) { + mtlSampDesc.lodBiasMVK = pCreateInfo->mipLodBias; + } +#endif mtlSampDesc.lodMinClamp = pCreateInfo->minLod; mtlSampDesc.lodMaxClamp = pCreateInfo->maxLod; mtlSampDesc.maxAnisotropy = (pCreateInfo->anisotropyEnable diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 7e7ba8c8..34929aed 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -23,6 +23,9 @@ #include "MVKOSExtensions.h" #include "MVKStrings.h" #include "MTLRenderPipelineDescriptor+MoltenVK.h" +#if MVK_USE_METAL_PRIVATE_API +#include "MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h" +#endif #include "mvk_datatypes.hpp" #ifndef MVK_USE_CEREAL @@ -304,6 +307,9 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage) cmdEncoder->_renderingState.setPrimitiveTopology(_vkPrimitiveTopology, false); cmdEncoder->_renderingState.setPrimitiveRestartEnable(_primitiveRestartEnable, false); cmdEncoder->_renderingState.setBlendConstants(_blendConstants, false); + if (_device->_enabledFeatures.depthBounds) { + cmdEncoder->_renderingState.setDepthBounds(_depthStencilInfo.minDepthBounds, _depthStencilInfo.maxDepthBounds, false); + } cmdEncoder->_renderingState.setStencilReferenceValues(_depthStencilInfo); cmdEncoder->_renderingState.setViewports(_viewports.contents(), 0, false); cmdEncoder->_renderingState.setScissors(_scissors.contents(), 0, false); @@ -1299,9 +1305,15 @@ bool MVKGraphicsPipeline::addFragmentShaderToPipeline(MTLRenderPipelineDescripto shaderConfig.options.mslOptions.sample_dref_lod_array_as_grad = true; } if (_isRasterizing && pCreateInfo->pMultisampleState) { // Must ignore allowed bad pMultisampleState pointer if rasterization disabled - if (pCreateInfo->pMultisampleState->pSampleMask && pCreateInfo->pMultisampleState->pSampleMask[0] != 0xffffffff) { - shaderConfig.options.mslOptions.additional_fixed_sample_mask = pCreateInfo->pMultisampleState->pSampleMask[0]; +#if MVK_USE_METAL_PRIVATE_API + if (!getMVKConfig().useMetalPrivateAPI) { +#endif + if (pCreateInfo->pMultisampleState->pSampleMask && pCreateInfo->pMultisampleState->pSampleMask[0] != 0xffffffff) { + shaderConfig.options.mslOptions.additional_fixed_sample_mask = pCreateInfo->pMultisampleState->pSampleMask[0]; + } +#if MVK_USE_METAL_PRIVATE_API } +#endif shaderConfig.options.mslOptions.force_sample_rate_shading = pCreateInfo->pMultisampleState->sampleShadingEnable && pCreateInfo->pMultisampleState->minSampleShading != 0.0f; } if (std::any_of(shaderOutputs.begin(), shaderOutputs.end(), [](const SPIRVShaderOutput& output) { return output.builtin == spv::BuiltInLayer; })) { @@ -1616,6 +1628,12 @@ void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescripto colorDesc.alphaBlendOperation = mvkMTLBlendOperationFromVkBlendOp(pCA->alphaBlendOp); colorDesc.sourceAlphaBlendFactor = mvkMTLBlendFactorFromVkBlendFactor(pCA->srcAlphaBlendFactor); colorDesc.destinationAlphaBlendFactor = mvkMTLBlendFactorFromVkBlendFactor(pCA->dstAlphaBlendFactor); +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI) { + colorDesc.logicOpEnabledMVK = pCreateInfo->pColorBlendState->logicOpEnable; + colorDesc.logicOpMVK = mvkMTLLogicOperationFromVkLogicOp(pCreateInfo->pColorBlendState->logicOp); + } +#endif } } } @@ -1642,6 +1660,11 @@ void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescripto // Multisampling - must ignore allowed bad pMultisampleState pointer if rasterization disabled if (_isRasterizing && pCreateInfo->pMultisampleState) { plDesc.rasterSampleCount = mvkSampleCountFromVkSampleCountFlagBits(pCreateInfo->pMultisampleState->rasterizationSamples); +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI && pCreateInfo->pMultisampleState->pSampleMask) { + plDesc.sampleMaskMVK = pCreateInfo->pMultisampleState->pSampleMask[0]; + } +#endif plDesc.alphaToCoverageEnabled = pCreateInfo->pMultisampleState->alphaToCoverageEnable; plDesc.alphaToOneEnabled = pCreateInfo->pMultisampleState->alphaToOneEnable; diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h new file mode 100644 index 00000000..b5a8beee --- /dev/null +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h @@ -0,0 +1,46 @@ +/* + * MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.h + * + * Copyright (c) 2018-2023 Chip Davis + * + * 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 + +#import + + +/** Extensions to MTLRenderPipelineColorAttachmentDescriptor to support MoltenVK. */ +@interface MTLRenderPipelineColorAttachmentDescriptor (MoltenVK) + +/** + * Replacement for the logicOpEnabled property. + * + * This property allows support under all OS versions. Delegates to the logicOpEnabled + * property if it is available. otherwise, returns NO when read and does nothing when set. + */ +@property(nonatomic, readwrite, getter=isLogicOpEnabledMVK) BOOL logicOpEnabledMVK; + +/** + * Replacement for the logicOp property. + * + * This property allows support under all OS versions. Delegates to the logicOp + * property if it is available. otherwise, returns MTLLogicOperationCopy when + * read and does nothing when set. + * + * The value is treated as an NSUInteger to support OS versions on which the enum is unavailable. + */ +@property(nonatomic, readwrite) NSUInteger logicOpMVK; + +@end diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m new file mode 100644 index 00000000..ac4fe9bd --- /dev/null +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m @@ -0,0 +1,67 @@ +/* + * MTLRenderPipelineDescriptor+MoltenVK.m + * + * Copyright (c) 2018-2023 Chip Davis + * + * 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 "MVKCommonEnvironment.h" + +#if MVK_USE_METAL_PRIVATE_API + +#include "MTLRenderPipelineDescriptor+MoltenVK.h" + +typedef NSUInteger MTLLogicOperation; + +@interface MTLRenderPipelineColorAttachmentDescriptor () + +- (BOOL)isLogicOpEnabled; +- (void)setLogicOpEnabled: (BOOL)enable; +- (MTLLogicOperation)logicOp; +- (void)setLogicOp: (MTLLogicOperation)op; + +@end + +@implementation MTLRenderPipelineColorAttachmentDescriptor (MoltenVK) + +- (BOOL)isLogicOpEnabledMVK { + if ([self respondsToSelector:@selector(isLogicOpEnabled)]) { + return [self isLogicOpEnabled]; + } + return NO; +} + +- (void)setLogicOpEnabledMVK: (BOOL)enable { + if ([self respondsToSelector:@selector(setLogicOpEnabled:)]) { + [self setLogicOpEnabled: enable]; + } +} + +- (NSUInteger)logicOpMVK { + if ([self respondsToSelector:@selector(logicOp)]) { + return [self logicOp]; + } + return 3 /* MTLLogicOperationCopy */; +} + +- (void)setLogicOpMVK: (MTLLogicOperation)op { + if ([self respondsToSelector:@selector(setLogicOp:)]) { + [self setLogicOp: (MTLLogicOperation)op]; + } +} + +@end + +#endif /* MVK_CONFIG_SUPPORT_METAL_SPIS */ diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h index 90921377..45d44c0d 100644 --- a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h @@ -33,4 +33,13 @@ */ @property(nonatomic, readwrite) MTLPrimitiveTopologyClass inputPrimitiveTopologyMVK; +/** + * Replacement for the sampleMask property. + * + * This property allows support under all OS versions. Delegates to the sampleMask + * property if it is available. otherwise, returns 0xFFFFFFFF when + * read and does nothing when set. + */ +@property(nonatomic, readwrite) NSUInteger sampleMaskMVK; + @end diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m index 42adb999..1e47304d 100644 --- a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m @@ -20,6 +20,16 @@ #include "MTLRenderPipelineDescriptor+MoltenVK.h" #include "MVKCommonEnvironment.h" +#if MVK_USE_METAL_PRIVATE_API +// These properties aren't public yet. +@interface MTLRenderPipelineDescriptor () + +@property(nonatomic, readwrite) NSUInteger sampleMask; +@property(nonatomic, readwrite) float sampleCoverage; + +@end +#endif + @implementation MTLRenderPipelineDescriptor (MoltenVK) -(MTLPrimitiveTopologyClass) inputPrimitiveTopologyMVK { @@ -31,4 +41,15 @@ if ([self respondsToSelector: @selector(setInputPrimitiveTopology:)]) { [self setInputPrimitiveTopology:topology]; } } +#if MVK_USE_METAL_PRIVATE_API +-(NSUInteger) sampleMaskMVK { + if ( [self respondsToSelector: @selector(sampleMask)] ) { return self.sampleMask; } + return 0xFFFFFFFFFFFFFFFFULL; +} + +-(void) setSampleMaskMVK: (NSUInteger) mask { + if ([self respondsToSelector: @selector(setSampleMask:)]) { self.sampleMask = mask; } +} +#endif + @end diff --git a/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.h index 39c87231..09055bc9 100644 --- a/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.h +++ b/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.h @@ -41,4 +41,13 @@ */ @property(nonatomic, readwrite) /*MTLSamplerBorderColor*/ NSUInteger borderColorMVK; +/** + * Replacement for the lodBias property. + * + * This property allows support under all OS versions. Delegates to the lodBias + * property if it is available. otherwise, returns 0 when read and + * does nothing when set. + */ +@property(nonatomic, readwrite) float lodBiasMVK; + @end diff --git a/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.m index 1ffd51ab..20805c55 100644 --- a/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.m +++ b/MoltenVK/MoltenVK/OS/MTLSamplerDescriptor+MoltenVK.m @@ -21,6 +21,15 @@ #include "MVKCommonEnvironment.h" +#if MVK_USE_METAL_PRIVATE_API +/** Additional methods not necessarily declared in . */ +@interface MTLSamplerDescriptor () + +@property(nonatomic, readwrite) float lodBias; + +@end +#endif + @implementation MTLSamplerDescriptor (MoltenVK) -(MTLCompareFunction) compareFunctionMVK { @@ -45,4 +54,15 @@ #endif } +#if MVK_USE_METAL_PRIVATE_API +-(float) lodBiasMVK { + if ( [self respondsToSelector: @selector(lodBias)] ) { return self.lodBias; } + return 0.0f; +} + +-(void) setLodBiasMVK: (float) bias { + if ( [self respondsToSelector: @selector(setLodBias:)] ) { self.lodBias = bias; } +} +#endif + @end diff --git a/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def b/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def index 82ad7824..88416938 100644 --- a/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def +++ b/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def @@ -81,6 +81,8 @@ MVK_CONFIG_MEMBER(useMetalArgumentBuffers, MVKUseMetalArgumentBuf MVK_CONFIG_MEMBER(shaderSourceCompressionAlgorithm, MVKConfigCompressionAlgorithm, SHADER_COMPRESSION_ALGORITHM) MVK_CONFIG_MEMBER(shouldMaximizeConcurrentCompilation, VkBool32, SHOULD_MAXIMIZE_CONCURRENT_COMPILATION) MVK_CONFIG_MEMBER(timestampPeriodLowPassAlpha, float, TIMESTAMP_PERIOD_LOWPASS_ALPHA) +MVK_CONFIG_MEMBER(useMetalPrivateAPI, VkBool32, USE_METAL_PRIVATE_API) +MVK_CONFIG_MEMBER(_unused_struct_padding, uint32_t, _UNUSED_STRUCT_PADDING) #undef MVK_CONFIG_MEMBER #undef MVK_CONFIG_MEMBER_STRING diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp index f8ec3e16..e6b93ff9 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp @@ -66,6 +66,9 @@ void mvkSetConfig(MVKConfiguration& dstMVKConfig, const MVKConfiguration& srcMVK // Clamp timestampPeriodLowPassAlpha between 0.0 and 1.0. dstMVKConfig.timestampPeriodLowPassAlpha = mvkClamp(dstMVKConfig.timestampPeriodLowPassAlpha, 0.0f, 1.0f); + // Only allow useMetalPrivateAPI to be enabled if we were built with support for it. + dstMVKConfig.useMetalPrivateAPI = dstMVKConfig.useMetalPrivateAPI && MVK_USE_METAL_PRIVATE_API; + // For each string member of the destination MVKConfiguration, store the contents // in a std::string, then repoint the member to the contents of the std::string. #define MVK_CONFIG_MEMBER(member, mbrType, name) diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h index 295e466a..40af1453 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h @@ -23,7 +23,9 @@ #include "mvk_vulkan.h" #include "mvk_private_api.h" #include "MVKLogging.h" +#ifdef __cplusplus #include +#endif // Expose MoltenVK Apple surface extension functionality @@ -73,23 +75,12 @@ # define MVK_SUPPORT_IOSURFACE_BOOL (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_11_0) #endif -/** - * Enable use of private Metal APIs. - * - * Enabling this build setting during a MoltenVK build will allow MoltenVK to - * extend its functionality by using certain private Metal API calls, but it - * will also disqualify the app from being distributed via Apple App Stores. - * - * Disabled by default. - */ -#ifndef MVK_USE_METAL_PRIVATE_API -# define MVK_USE_METAL_PRIVATE_API 0 -#endif - #pragma mark - #pragma mark MoltenVK Configuration +#ifdef __cplusplus + /** The number of members of MVKConfiguration that are strings. */ static constexpr uint32_t kMVKConfigurationStringCount = 1; @@ -105,6 +96,8 @@ void mvkSetGlobalConfig(const MVKConfiguration& srcMVKConfig); */ void mvkSetConfig(MVKConfiguration& dstMVKConfig, const MVKConfiguration& srcMVKConfig, std::string* stringHolders); +#endif + /** * Enable debug mode. * By default, disabled for Release builds and enabled for Debug builds. @@ -348,3 +341,14 @@ void mvkSetConfig(MVKConfiguration& dstMVKConfig, const MVKConfiguration& srcMVK #ifndef MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA # define MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA 1.0 #endif + +/** + * Enable the use of Metal private interfaces, also known as "Service Provider Interfaces" (SPIs), + * to support Vulkan features. Enabled by default if support is included. + */ +#ifndef MVK_CONFIG_USE_METAL_PRIVATE_API +# define MVK_CONFIG_USE_METAL_PRIVATE_API MVK_USE_METAL_PRIVATE_API +#endif + +#undef MVK_CONFIG__UNUSED_STRUCT_PADDING +#define MVK_CONFIG__UNUSED_STRUCT_PADDING 0 diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm index f4bcd7a5..6e737228 100644 --- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm +++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm @@ -433,6 +433,52 @@ MVK_PUBLIC_SYMBOL MTLBlendFactor mvkMTLBlendFactorFromVkBlendFactor(VkBlendFacto } } +#if MVK_USE_METAL_PRIVATE_API + +// This isn't in any public header yet. I'm really just guessing based on the D3D11 values here. +typedef NS_ENUM(NSUInteger, MTLLogicOperation) { + MTLLogicOperationClear, + MTLLogicOperationSet, + MTLLogicOperationCopy, + MTLLogicOperationCopyInverted, + MTLLogicOperationNoop, + MTLLogicOperationInvert, + MTLLogicOperationAnd, + MTLLogicOperationNand, + MTLLogicOperationOr, + MTLLogicOperationNor, + MTLLogicOperationXor, + MTLLogicOperationEquivalence, + MTLLogicOperationAndReverse, + MTLLogicOperationAndInverted, + MTLLogicOperationOrReverse, + MTLLogicOperationOrInverted, +}; + +MVK_PUBLIC_SYMBOL NSUInteger mvkMTLLogicOperationFromVkLogicOp(VkLogicOp vkLogicOp) { + switch (vkLogicOp) { + case VK_LOGIC_OP_CLEAR: return MTLLogicOperationClear; + case VK_LOGIC_OP_AND: return MTLLogicOperationAnd; + case VK_LOGIC_OP_AND_REVERSE: return MTLLogicOperationAndReverse; + case VK_LOGIC_OP_COPY: return MTLLogicOperationCopy; + case VK_LOGIC_OP_AND_INVERTED: return MTLLogicOperationAndInverted; + case VK_LOGIC_OP_NO_OP: return MTLLogicOperationNoop; + case VK_LOGIC_OP_XOR: return MTLLogicOperationXor; + case VK_LOGIC_OP_OR: return MTLLogicOperationOr; + case VK_LOGIC_OP_NOR: return MTLLogicOperationNor; + case VK_LOGIC_OP_EQUIVALENT: return MTLLogicOperationEquivalence; + case VK_LOGIC_OP_INVERT: return MTLLogicOperationInvert; + case VK_LOGIC_OP_OR_REVERSE: return MTLLogicOperationOrReverse; + case VK_LOGIC_OP_COPY_INVERTED: return MTLLogicOperationCopyInverted; + case VK_LOGIC_OP_OR_INVERTED: return MTLLogicOperationOrInverted; + case VK_LOGIC_OP_NAND: return MTLLogicOperationNand; + case VK_LOGIC_OP_SET: return MTLLogicOperationSet; + default: return MTLLogicOperationCopy; + } +} + +#endif + MVK_PUBLIC_SYMBOL MTLVertexStepFunction mvkMTLVertexStepFunctionFromVkVertexInputRate(VkVertexInputRate vkVtxStep) { switch (vkVtxStep) { case VK_VERTEX_INPUT_RATE_VERTEX: return MTLVertexStepFunctionPerVertex; diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index ad048e80..4da6afcd 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -1498,6 +1498,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBounds( float maxDepthBounds) { MVKTraceVulkanCallStart(); + MVKAddCmd(SetDepthBounds, commandBuffer, minDepthBounds, maxDepthBounds); MVKTraceVulkanCallEnd(); } @@ -2653,6 +2654,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBoundsTestEnable( VkBool32 depthBoundsTestEnable) { MVKTraceVulkanCallStart(); + MVKAddCmd(SetDepthBoundsTestEnable, commandBuffer, depthBoundsTestEnable); MVKTraceVulkanCallEnd(); } diff --git a/README.md b/README.md index 76735c23..b172c77b 100644 --- a/README.md +++ b/README.md @@ -317,9 +317,10 @@ _Vulkan_ API calls as function pointers. ### Accessing _Metal_ Private API calls -You can optionally build **MoltenVK** with access to private _Metal_ API calls. -Doing so will allow **MoltenVK** to extend its functionality by using certain private _Metal_ -API calls, but it will also disqualify the app from being distributed via _Apple_ App Stores. +You can optionally build **MoltenVK** with access to private _Metal_ API calls, also known +as "Service Provider Interfaces" (SPIs). Doing so will allow **MoltenVK** to extend its +functionality by using certain private _Metal_ API calls, but it will also disqualify the +app from being distributed via _Apple_ App Stores. To do so, when building **MoltenVK**, set the build setting `MVK_USE_METAL_PRIVATE_API=1`. This build setting can be set in the `MoltenVK.xcodeproj` *Xcode* project, or it can be @@ -327,6 +328,10 @@ included in any of the `make` command-line build commands [mentioned above](#com Functionality added with `MVK_USE_METAL_PRIVATE_API` enabled includes: - `VkPhysicalDeviceFeatures::wideLines` +- `VkPhysicalDeviceFeatures::logicOp` +- `VkPhysicalDeviceFeatures::depthBounds` *(requires an AMD GPU)* +- `VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias` +- `VkGraphicsPipelineRasterizationCreateInfo::sampleMask`, using `MTLRenderPipelineDescriptor.sampleMask` instead of emulating it in the fragment shader