From 4a201409c3d48add5c9f03f946189dfc9173b371 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Thu, 25 Jan 2024 10:42:26 -0500 Subject: [PATCH] Add optional support for VkPhysicalDeviceFeatures::wideLines. - 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. - Set lineWidthRange and lineWidthGranularity to reasonable arbitrary values. --- Docs/Whats_New.md | 2 ++ MoltenVK/MoltenVK/Commands/MVKCmdRendering.h | 19 ++++++++++ MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm | 14 ++++++++ .../Commands/MVKCommandEncoderState.h | 5 ++- .../Commands/MVKCommandEncoderState.mm | 22 ++++++++++++ .../MoltenVK/Commands/MVKCommandTypePools.def | 1 + MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 5 +-- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 1 + MoltenVK/MoltenVK/Utility/MVKEnvironment.h | 13 +++++++ MoltenVK/MoltenVK/Vulkan/vulkan.mm | 1 + README.md | 36 +++++++++++++------ 11 files changed, 105 insertions(+), 14 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index fe2135f97..9f8d5655a 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -18,6 +18,8 @@ MoltenVK 1.2.8 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. - 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/Commands/MVKCmdRendering.h b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h index 408f87a5c..2406ede83 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h @@ -607,6 +607,25 @@ class MVKCmdSetPolygonMode : public MVKCommand { }; +#pragma mark - +#pragma mark MVKCmdSetLineWidth + +/** Vulkan command to dynamically set the line width. */ +class MVKCmdSetLineWidth : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + float lineWidth); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + float _lineWidth; +}; + + #pragma mark - #pragma mark MVKCmdSetPrimitiveTopology diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm index 1c14979df..e04eb3d74 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm @@ -512,6 +512,20 @@ } +#pragma mark - +#pragma mark MVKCmdSetLineWidth + +VkResult MVKCmdSetLineWidth::setContent(MVKCommandBuffer* cmdBuff, + float lineWidth) { + _lineWidth = lineWidth; + return VK_SUCCESS; +} + +void MVKCmdSetLineWidth::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_renderingState.setLineWidth(_lineWidth, true); +} + + #pragma mark - #pragma mark MVKCmdSetPrimitiveTopology diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h index 4ab4eb981..0152ce0d8 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -263,6 +263,8 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { void setPolygonMode(VkPolygonMode polygonMode, bool isDynamic); + void setLineWidth(float lineWidth, bool isDynamic); + void setBlendConstants(float blendConstants[4], bool isDynamic); void setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo); @@ -322,7 +324,8 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { MTLPrimitiveType _mtlPrimitiveTopology[StateScope::Count] = { MTLPrimitiveTypePoint, MTLPrimitiveTypePoint }; MTLDepthClipMode _mtlDepthClipEnable[StateScope::Count] = { MTLDepthClipModeClip, MTLDepthClipModeClip }; MTLTriangleFillMode _mtlPolygonMode[StateScope::Count] = { MTLTriangleFillModeFill, MTLTriangleFillModeFill }; - uint32_t _mtlPatchControlPoints[StateScope::Count] = {}; + float _mtlLineWidth[StateScope::Count] = { 1, 1 }; + uint32_t _mtlPatchControlPoints[StateScope::Count] = { 0, 0}; MVKRenderStateFlags _dirtyStates; MVKRenderStateFlags _modifiedStates; bool _mtlSampleLocationsEnable[StateScope::Count] = {}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index d7fa40c0b..dc6399426 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -322,6 +322,11 @@ getContent(_isPolygonModePoint, isDynamic) = (polygonMode == VK_POLYGON_MODE_POINT); } +void MVKRenderingCommandEncoderState::setLineWidth(float lineWidth, bool isDynamic) { + auto mtlLineWidth = lineWidth; + setMTLContent(LineWidth); +} + void MVKRenderingCommandEncoderState::setBlendConstants(float blendConstants[4], bool isDynamic) { MVKColor32 mtlBlendConstants; mvkCopy(mtlBlendConstants.float32, blendConstants, 4); @@ -537,6 +542,13 @@ #pragma mark Encoding +#if MVK_USE_METAL_PRIVATE_API +// An extension of the MTLRenderCommandEncoder protocol to declare the setLineWidth: method. +@protocol MVKMTLRenderCommandEncoderLineWidth +-(void) setLineWidth: (float) width; +@end +#endif + void MVKRenderingCommandEncoderState::encodeImpl(uint32_t stage) { if (stage != kMVKGraphicsStageRasterization) { return; } @@ -549,6 +561,16 @@ auto& bcFlt = getMTLContent(BlendConstants).float32; [rendEnc setBlendColorRed: bcFlt[0] green: bcFlt[1] blue: bcFlt[2] alpha: bcFlt[3]]; } + +#if MVK_USE_METAL_PRIVATE_API + if (isDirty(LineWidth)) { + auto lineWidthRendEnc = (id)rendEnc; + if ([lineWidthRendEnc respondsToSelector: @selector(setLineWidth:)]) { + [lineWidthRendEnc setLineWidth: getMTLContent(LineWidth)]; + } + } +#endif + if (isDirty(DepthBiasEnable) || isDirty(DepthBias)) { if (getMTLContent(DepthBiasEnable)) { auto& db = getMTLContent(DepthBias); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 0983ec704..d64958575 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -104,6 +104,7 @@ MVK_CMD_TYPE_POOL(SetFrontFace) MVK_CMD_TYPE_POOL(SetPrimitiveTopology) MVK_CMD_TYPE_POOL(SetPrimitiveRestartEnable) MVK_CMD_TYPE_POOL(SetPolygonMode) +MVK_CMD_TYPE_POOL(SetLineWidth) MVK_CMD_TYPE_POOL(SetPatchControlPoints) MVK_CMD_TYPE_POOL(SetRasterizerDiscardEnable) MVK_CMD_TYPE_POOLS_FROM_2_THRESHOLDS(BindVertexBuffers, 1, 2) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 9680517f4..5b267d1cc 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -2341,6 +2341,7 @@ _features.depthBiasClamp = true; _features.fillModeNonSolid = true; _features.largePoints = true; + _features.wideLines = bool(MVK_USE_METAL_PRIVATE_API); _features.alphaToOne = true; _features.samplerAnisotropy = true; _features.shaderImageGatherExtended = true; @@ -2761,8 +2762,8 @@ _properties.limits.pointSizeGranularity = 1; _properties.limits.lineWidthRange[0] = 1; - _properties.limits.lineWidthRange[1] = 1; - _properties.limits.lineWidthGranularity = 0; + _properties.limits.lineWidthRange[1] = _features.wideLines ? 8 : 1; + _properties.limits.lineWidthGranularity = _features.wideLines ? 0.125f : 0; _properties.limits.standardSampleLocations = VK_TRUE; _properties.limits.strictLines = _properties.vendorID == kIntelVendorId || _properties.vendorID == kNVVendorId; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 0a37cc78b..2d0d838c5 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -311,6 +311,7 @@ cmdEncoder->_renderingState.setCullMode(_rasterInfo.cullMode, false); cmdEncoder->_renderingState.setFrontFace(_rasterInfo.frontFace, false); cmdEncoder->_renderingState.setPolygonMode(_rasterInfo.polygonMode, false); + cmdEncoder->_renderingState.setLineWidth(_rasterInfo.lineWidth, false); cmdEncoder->_renderingState.setDepthBias(_rasterInfo); cmdEncoder->_renderingState.setDepthClipEnable( !_rasterInfo.depthClampEnable, false ); } diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h index e451c708e..3c200d860 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h @@ -73,6 +73,19 @@ # 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 + * functionality by using certain private Metal API calls, however, doing so will + * disqualify the app using MoltenVK from being distributed via Apple's 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 diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index f8ad12bd5..87aa3c399 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -1466,6 +1466,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLineWidth( float lineWidth) { MVKTraceVulkanCallStart(); + MVKAddCmd(SetLineWidth, commandBuffer, lineWidth); MVKTraceVulkanCallEnd(); } diff --git a/README.md b/README.md index 8becfd8c3..eb3f0a0b2 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ Table of Contents - [Using MoltenVK Directly](#download) - [Fetching **MoltenVK** Source Code](#install) - [Building **MoltenVK**](#building) + - [Building from the Command Line](#command_line_build) + - [Hiding _Vulkan_ API Symbols](#hiding_vulkan_symbols) + - [Accessing _Metal_ Private API calls](#metal_private_api) - [Running **MoltenVK** Demo Applications](#demos) - [Using **MoltenVK** in Your Application](#using) - [**MoltenVK** and *Vulkan* Compliance](#compliance) @@ -236,6 +239,7 @@ to the **MoltenVK** libraries and frameworks in the `Package/Latest` directory, to test your app with either a **_Debug_** build, or a higher-performance **_Release_** build. + ### Building from the Command Line If you prefer to build **MoltenVK** from the command line, or to include the activity in a larger build script, @@ -294,27 +298,37 @@ or ...etc. -### Hiding Vulkan API Symbols -You can optionally build **MoltenVK** with the Vulkan API static call symbols (`vk*`) hidden, to avoid + +### Hiding _Vulkan_ API Symbols + +You can optionally build **MoltenVK** with the _Vulkan_ API static call symbols (`vk*`) hidden, to avoid library linking conflicts when statically bound to a _Vulkan_ loader that also exports identical symbols. To do so, when building **MoltenVK**, set the build setting `MVK_HIDE_VULKAN_SYMBOLS=1`. -This build setting can be set in the `MoltenVK.xcodeproj` *Xcode* project, -or it can be included in any of the `make` build commands. For example: - - make MVK_HIDE_VULKAN_SYMBOLS=1 -or - - make macos MVK_HIDE_VULKAN_SYMBOLS=1 - -...etc. +This build setting can be set in the `MoltenVK.xcodeproj` *Xcode* project, or it can be +included in any of the `make` command-line build commands [mentioned above](#command_line_build). With `MVK_HIDE_VULKAN_SYMBOLS=1`, the _Vulkan_ `vkGetInstanceProcAddr()` call remains statically bound, to provide the application with the ability to retrieve the remaining _Vulkan_ API calls as function pointers. + +### Accessing _Metal_ Private API calls + +You can optionally build **MoltenVK** with access to _Metal_ private API calls. +Doing so will allow **MoltenVK** to extend functionality by using certain private _Metal_ API calls, +however, doing so will 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 +included in any of the `make` command-line build commands [mentioned above](#command_line_build). + +Functionality added with `MVK_USE_METAL_PRIVATE_API` enabled includes: +- `VkPhysicalDeviceFeatures::wideLines` + + Running **MoltenVK** Demo Applications --------------------------------------