Support the depth bounds test.
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.
This commit is contained in:
parent
f8b974371b
commit
60a429f353
@ -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.
|
||||
|
@ -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<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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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] = {};
|
||||
};
|
||||
|
@ -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<bool>(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 <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
|
||||
|
||||
@ -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<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];
|
||||
|
@ -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)
|
||||
|
@ -2443,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;
|
||||
|
@ -307,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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user