Skip to content

Commit

Permalink
Support the depth bounds test.
Browse files Browse the repository at this point in the history
This isn't even a regular SPI. It's not even present in the Metal
framework. It's exposed by the driver. Only AMD drivers support the
method we need for now.
  • Loading branch information
cdavis5e committed Jan 29, 2024
1 parent f8b9743 commit 60a429f
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ 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.
Expand Down
35 changes: 35 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,41 @@ class MVKCmdSetDepthCompareOp : public MVKSingleValueCommand<VkCompareOp> {
};


#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<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

float _minDepthBounds;
float _maxDepthBounds;
};


#pragma mark -
#pragma mark MVKCmdSetDepthBoundsTestEnable

/** Vulkan command to enable depth bounds testing. */
class MVKCmdSetDepthBoundsTestEnable : public MVKSingleValueCommand<VkBool32> {

public:
void encode(MVKCommandEncoder* cmdEncoder) override;

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
};


#pragma mark -
#pragma mark MVKCmdSetStencilTestEnable

Expand Down
24 changes: 24 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,30 @@
}


#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

Expand Down
9 changes: 9 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ struct MVKDepthBias {
float depthBiasClamp;
};

struct MVKDepthBounds {
float minDepthBound;
float maxDepthBound;
};

struct MVKStencilReference {
uint32_t frontFaceValue;
uint32_t backFaceValue;
Expand Down Expand Up @@ -272,6 +277,8 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
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);

Expand Down Expand Up @@ -318,6 +325,7 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
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 };
Expand All @@ -332,6 +340,7 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
bool _mtlDepthBiasEnable[StateScope::Count] = {};
bool _mtlPrimitiveRestartEnable[StateScope::Count] = {};
bool _mtlRasterizerDiscardEnable[StateScope::Count] = {};
bool _mtlDepthBoundsTestEnable[StateScope::Count] = {};
bool _cullBothFaces[StateScope::Count] = {};
bool _isPolygonModePoint[StateScope::Count] = {};
};
Expand Down
33 changes: 33 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,16 @@
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<bool>(depthBoundsTestEnable);
setMTLContent(DepthBoundsTestEnable);
}

void MVKRenderingCommandEncoderState::setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) {
bool isDynamic = false;
MVKStencilReference mtlStencilReference = {
Expand Down Expand Up @@ -545,6 +555,14 @@
// An extension of the MTLRenderCommandEncoder protocol to declare the setLineWidth: method.
@protocol MVKMTLRenderCommandEncoderLineWidth <MTLRenderCommandEncoder>
-(void) setLineWidth: (float) width;
@end

// An extension of the MTLRenderCommandEncoder protocol containing a declaration of the
// -setDepthBoundsTestAMD:minDepth:maxDepth: method.
@protocol MVKMTLRenderCommandEncoderDepthBoundsAMD <MTLRenderCommandEncoder>

- (void)setDepthBoundsTestAMD:(BOOL)enable minDepth:(float)minDepth maxDepth:(float)maxDepth;

@end
#endif

Expand Down Expand Up @@ -584,6 +602,21 @@ -(void) setLineWidth: (float) width;
[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<MVKMTLRenderCommandEncoderDepthBoundsAMD>)_cmdEncoder->_mtlRenderEncoder setDepthBoundsTestAMD: YES
minDepth: db.minDepthBound
maxDepth: db.maxDepthBound];
} else {
[(id<MVKMTLRenderCommandEncoderDepthBoundsAMD>)_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];
Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,13 @@

_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;
Expand Down
3 changes: 3 additions & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@
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);
Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/Vulkan/vulkan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBounds(
float maxDepthBounds) {

MVKTraceVulkanCallStart();
MVKAddCmd(SetDepthBounds, commandBuffer, minDepthBounds, maxDepthBounds);
MVKTraceVulkanCallEnd();
}

Expand Down Expand Up @@ -2653,6 +2654,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBoundsTestEnable(
VkBool32 depthBoundsTestEnable) {

MVKTraceVulkanCallStart();
MVKAddCmd(SetDepthBoundsTestEnable, commandBuffer, depthBoundsTestEnable);
MVKTraceVulkanCallEnd();
}

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ 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

Expand Down

0 comments on commit 60a429f

Please sign in to comment.