From 481fe3553decff35fcd039aee54ff1b5ec266355 Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Sun, 27 Sep 2020 14:46:46 -0500 Subject: [PATCH] MVKPipeline: Don't rely on the index buffer to tell apart indexed draws. This was a good heuristic, because the index buffer must be bound for indexed draws. However, it may also be bound for non-indexed draws--for example, if an indexed draw were immediately followed by a non-indexed draw, as happens in some `dEQP-VK.synchronization.*` tests. Therefore, we can't tell from the presence or absence of the index buffer what kind of draw we're in. We'll have to keep track of this state in the command encoder. --- MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm | 8 ++++++++ MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 3 +++ MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm index bd63403c..57819360 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm @@ -108,6 +108,8 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) { return; } + cmdEncoder->_isIndexedDraw = false; + auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); MVKPiplineStages stages; @@ -302,6 +304,8 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) { return; } + cmdEncoder->_isIndexedDraw = true; + auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); MVKPiplineStages stages; @@ -510,6 +514,8 @@ static const uint32_t kMVKDrawIndirectVertexCountUpperBound = 131072; void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_isIndexedDraw = false; + auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); bool needsInstanceAdjustment = cmdEncoder->getSubpass()->isMultiview() && cmdEncoder->getDevice()->getPhysicalDevice()->canUseInstancingForMultiview(); @@ -820,6 +826,8 @@ VkResult MVKCmdDrawIndexedIndirect::setContent(MVKCommandBuffer* cmdBuff, void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_isIndexedDraw = true; + MVKIndexMTLBufferBinding& ibb = cmdEncoder->_graphicsResourcesState._mtlIndexBufferBinding; auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); bool needsInstanceAdjustment = cmdEncoder->getSubpass()->isMultiview() && diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 9002d59e..9bcbd524 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -449,6 +449,9 @@ public: /** Indicates whether the current render subpass is able to render to an array (layered) framebuffer. */ bool _canUseLayeredRendering; + /** Indicates whether the current draw is an indexed draw. */ + bool _isIndexedDraw; + #pragma mark Construction diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index aa7f30d3..1e072849 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -207,7 +207,7 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage) id plState; const MVKIndexMTLBufferBinding& indexBuff = cmdEncoder->_graphicsResourcesState._mtlIndexBufferBinding; - if (!indexBuff.mtlBuffer) { + if (!cmdEncoder->_isIndexedDraw) { plState = getTessVertexStageState(); } else if (indexBuff.mtlIndexType == MTLIndexTypeUInt16) { plState = getTessVertexStageIndex16State();