Disable depth and/or stencil testing if corresponding attachment is missing.
MVKDepthStencilCommandEncoderState track whether depth and stencil attachements exist, and modify testing accordingly. Add MVKMTLDepthStencilDescriptorData::disable() function. MoltenVK_Runtime_UserGuide.md remove VkEvent as known limitation.
This commit is contained in:
parent
e2ce1a6329
commit
25acafdb3f
@ -512,8 +512,6 @@ This section documents the known limitations in this version of **MoltenVK**.
|
||||
In order to use Vulkan layers such as the validation layers, use the Vulkan loader and layers from the
|
||||
[LunarG Vulkan SDK](https://vulkan.lunarg.com).
|
||||
|
||||
- `VkEvents` are not supported.
|
||||
|
||||
- Application-controlled memory allocations using `VkAllocationCallbacks` are ignored.
|
||||
|
||||
- Pipeline statistics query pool using `VK_QUERY_TYPE_PIPELINE_STATISTICS` is not supported.
|
||||
|
@ -23,6 +23,7 @@ Released TBD
|
||||
- Add support for `VkEvent`, using either native `MTLEvent` or emulation when `MTLEvent` not available.
|
||||
- `vkInvalidateMappedMemoryRanges()` synchronizes managed device memory to CPU.
|
||||
- Revert to supporting host-coherent memory for linear images on macOS.
|
||||
- Disable depth and/or stencil testing if corresponding attachment is missing.
|
||||
- Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
|
||||
- Fix crash when `VkDeviceCreateInfo` specifies queue families out of numerical order.
|
||||
- Fix crash in `vkDestroyPipelineLayout()`.
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
* will be encoded to Metal, otherwise it is marked as clean, so the contents will NOT
|
||||
* be encoded. Default state can be left unencoded on a new Metal encoder.
|
||||
*/
|
||||
void beginMetalRenderPass() { if (_isModified) { markDirty(); } }
|
||||
virtual void beginMetalRenderPass() { if (_isModified) { markDirty(); } }
|
||||
|
||||
/**
|
||||
* If the content of this instance is dirty, marks this instance as no longer dirty
|
||||
@ -237,6 +237,8 @@ public:
|
||||
*/
|
||||
void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask);
|
||||
|
||||
void beginMetalRenderPass() override;
|
||||
|
||||
/** Constructs this instance for the specified command encoder. */
|
||||
MVKDepthStencilCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
||||
: MVKCommandEncoderState(cmdEncoder) {}
|
||||
@ -248,7 +250,9 @@ protected:
|
||||
const VkStencilOpState& vkStencil,
|
||||
bool enabled);
|
||||
|
||||
MVKMTLDepthStencilDescriptorData _depthStencilData;
|
||||
MVKMTLDepthStencilDescriptorData _depthStencilData = kMVKMTLDepthStencilDescriptorDataDefault;
|
||||
bool _hasDepthAttachment = false;
|
||||
bool _hasStencilAttachment = false;
|
||||
};
|
||||
|
||||
|
||||
|
@ -312,26 +312,43 @@ void MVKDepthStencilCommandEncoderState::setStencilWriteMask(VkStencilFaceFlags
|
||||
markDirty();
|
||||
}
|
||||
|
||||
void MVKDepthStencilCommandEncoderState::beginMetalRenderPass() {
|
||||
MVKRenderSubpass* mvkSubpass = _cmdEncoder->getSubpass();
|
||||
MTLPixelFormat mtlDSFormat = _cmdEncoder->getMTLPixelFormatFromVkFormat(mvkSubpass->getDepthStencilFormat());
|
||||
|
||||
bool prevHasDepthAttachment = _hasDepthAttachment;
|
||||
_hasDepthAttachment = mvkMTLPixelFormatIsDepthFormat(mtlDSFormat);
|
||||
if (_hasDepthAttachment != prevHasDepthAttachment) { markDirty(); }
|
||||
|
||||
bool prevHasStencilAttachment = _hasStencilAttachment;
|
||||
_hasStencilAttachment = mvkMTLPixelFormatIsStencilFormat(mtlDSFormat);
|
||||
if (_hasStencilAttachment != prevHasStencilAttachment) { markDirty(); }
|
||||
}
|
||||
|
||||
void MVKDepthStencilCommandEncoderState::encodeImpl(uint32_t stage) {
|
||||
if (stage != kMVKGraphicsStageRasterization && stage != kMVKGraphicsStageVertex) { return; }
|
||||
MVKRenderSubpass *subpass = _cmdEncoder->getSubpass();
|
||||
id<MTLDepthStencilState> mtlDSS = nil;
|
||||
if (stage != kMVKGraphicsStageVertex && subpass->getDepthStencilFormat() != VK_FORMAT_UNDEFINED) {
|
||||
mtlDSS = _cmdEncoder->getCommandEncodingPool()->getMTLDepthStencilState(_depthStencilData);
|
||||
} else {
|
||||
// If there is no depth attachment but the depth/stencil state contains a non-always depth
|
||||
// test, Metal Validation will give the following error:
|
||||
// "validateDepthStencilState:3657: failed assertion `MTLDepthStencilDescriptor sets
|
||||
// depth test but MTLRenderPassDescriptor has a nil depthAttachment texture'"
|
||||
// Check the subpass to see if there is a depth/stencil attachment, and if not use
|
||||
// a depth/stencil state with depth test always, depth write disabled, and no stencil state.
|
||||
mtlDSS = _cmdEncoder->getCommandEncodingPool()->getMTLDepthStencilState(false, false);
|
||||
}
|
||||
[_cmdEncoder->_mtlRenderEncoder setDepthStencilState: mtlDSS];
|
||||
auto cmdEncPool = _cmdEncoder->getCommandEncodingPool();
|
||||
switch (stage) {
|
||||
case kMVKGraphicsStageRasterization: {
|
||||
// If renderpass does not have a depth or a stencil attachment, disable corresponding test
|
||||
MVKMTLDepthStencilDescriptorData adjustedDSData = _depthStencilData;
|
||||
adjustedDSData.disable(!_hasDepthAttachment, !_hasStencilAttachment);
|
||||
[_cmdEncoder->_mtlRenderEncoder setDepthStencilState: cmdEncPool->getMTLDepthStencilState(adjustedDSData)];
|
||||
break;
|
||||
}
|
||||
case kMVKGraphicsStageVertex: {
|
||||
// Vertex stage of tessellation pipeline requires depth/stencil testing be disabled
|
||||
[_cmdEncoder->_mtlRenderEncoder setDepthStencilState: cmdEncPool->getMTLDepthStencilState(false, false)];
|
||||
break;
|
||||
}
|
||||
default: // Do nothing on other stages
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MVKDepthStencilCommandEncoderState::resetImpl() {
|
||||
_depthStencilData = kMVKMTLDepthStencilDescriptorDataDefault;
|
||||
_hasDepthAttachment = false;
|
||||
_hasStencilAttachment = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,18 +207,24 @@ typedef struct MVKMTLDepthStencilDescriptorData_t {
|
||||
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
||||
}
|
||||
|
||||
MVKMTLDepthStencilDescriptorData_t() {
|
||||
/** Disable depth and/or stencil testing. */
|
||||
void disable(bool disableDepth, bool disableStencil) {
|
||||
if (disableDepth) {
|
||||
depthCompareFunction = MTLCompareFunctionAlways;
|
||||
depthWriteEnabled = false;
|
||||
}
|
||||
if (disableStencil) {
|
||||
frontFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||
backFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||
}
|
||||
}
|
||||
|
||||
// Start with all zeros to ensure memory comparisons will work,
|
||||
// even if the structure contains alignment gaps.
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
depthCompareFunction = MTLCompareFunctionAlways;
|
||||
depthWriteEnabled = false;
|
||||
|
||||
frontFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||
backFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||
}
|
||||
MVKMTLDepthStencilDescriptorData_t() {
|
||||
// Start with all zeros to ensure memory comparisons will work,
|
||||
// even if the structure contains alignment gaps.
|
||||
memset(this, 0, sizeof(*this));
|
||||
disable(true, true);
|
||||
}
|
||||
|
||||
} __attribute__((aligned(sizeof(uint64_t)))) MVKMTLDepthStencilDescriptorData;
|
||||
|
||||
@ -345,10 +351,7 @@ public:
|
||||
id<MTLRenderPipelineState> newCmdClearMTLRenderPipelineState(MVKRPSKeyClearAtt& attKey,
|
||||
MVKVulkanAPIDeviceObject* owner);
|
||||
|
||||
/**
|
||||
* Returns a new MTLDepthStencilState dedicated to rendering to several
|
||||
* attachments to support clearing regions of those attachments.
|
||||
*/
|
||||
/** Returns a new MTLDepthStencilState that always writes to the depth and/or stencil attachments. */
|
||||
id<MTLDepthStencilState> newMTLDepthStencilState(bool useDepth, bool useStencil);
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user