Skip to content

Commit

Permalink
Add optional support for VkPhysicalDeviceFeatures::wideLines.
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
billhollings committed Jan 25, 2024
1 parent 680b9d4 commit 5992dda
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 19 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

float _lineWidth;
};


#pragma mark -
#pragma mark MVKCmdSetPrimitiveTopology

Expand Down
14 changes: 14 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 4 additions & 1 deletion MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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] = {};
Expand Down
22 changes: 22 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 <MTLRenderCommandEncoder>
-(void) setLineWidth: (float) width;
@end
#endif

void MVKRenderingCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage != kMVKGraphicsStageRasterization) { return; }

Expand All @@ -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<MVKMTLRenderCommandEncoderLineWidth>)rendEnc;
if ([lineWidthRendEnc respondsToSelector: @selector(setLineWidth:)]) {
[lineWidthRendEnc setLineWidth: getMTLContent(LineWidth)];
}
}
#endif

if (isDirty(DepthBiasEnable) || isDirty(DepthBias)) {
if (getMTLContent(DepthBiasEnable)) {
auto& db = getMTLContent(DepthBias);
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
Expand Down
13 changes: 13 additions & 0 deletions MoltenVK/MoltenVK/Utility/MVKEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/Vulkan/vulkan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLineWidth(
float lineWidth) {

MVKTraceVulkanCallStart();
MVKAddCmd(SetLineWidth, commandBuffer, lineWidth);
MVKTraceVulkanCallEnd();
}

Expand Down
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.


<a name="command_line_build"></a>
### 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,
Expand Down Expand Up @@ -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
<a name="hiding_vulkan_symbols"></a>
### 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.


<a name="metal_private_api"></a>
### 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.

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`


<a name="demos"></a>
Running **MoltenVK** Demo Applications
--------------------------------------
Expand Down

0 comments on commit 5992dda

Please sign in to comment.