Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use concurrent compute command encoders. #2431

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
[mtlTessCtlEncoder setBuffer: vtxOutBuff->_mtlBuffer
offset: vtxOutBuff->_offset
atIndex: cmdEncoder->getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKTessCtlInputBufferBinding)];
[mtlTessCtlEncoder memoryBarrierWithResources:&vtxOutBuff->_mtlBuffer count:1];
}

NSUInteger sgSize = pipeline->getTessControlStageState().threadExecutionWidth;
Expand Down Expand Up @@ -475,6 +476,7 @@
[mtlTessCtlEncoder setBuffer: vtxOutBuff->_mtlBuffer
offset: vtxOutBuff->_offset
atIndex: cmdEncoder->getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKTessCtlInputBufferBinding)];
[mtlTessCtlEncoder memoryBarrierWithResources:&vtxOutBuff->_mtlBuffer count:1];
}
// The vertex shader produced output in the correct order, so there's no need to use
// an index buffer here.
Expand Down Expand Up @@ -792,6 +794,8 @@
[mtlTessCtlEncoder dispatchThreadgroups: MTLSizeMake(mvkCeilingDivide<NSUInteger>(_drawCount, mtlConvertState.threadExecutionWidth), 1, 1)
threadsPerThreadgroup: MTLSizeMake(mtlConvertState.threadExecutionWidth, 1, 1)];
}
id<MTLBuffer> barrierBuffers[] = {tempIndirectBuff->_mtlBuffer, tcParamsBuff->_mtlBuffer};
[mtlTessCtlEncoder memoryBarrierWithResources:barrierBuffers count:2];
// Mark pipelines, resources, and vertex push constants as dirty
// so I apply them during the next stage.
cmdEncoder->_graphicsPipelineState.beginMetalRenderPass();
Expand Down Expand Up @@ -891,6 +895,7 @@
[mtlTessCtlEncoder setBuffer: vtxOutBuff->_mtlBuffer
offset: vtxOutBuff->_offset
atIndex: cmdEncoder->getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKTessCtlInputBufferBinding)];
[mtlTessCtlEncoder memoryBarrierWithResources:&vtxOutBuff->_mtlBuffer count:1];
}
[mtlTessCtlEncoder dispatchThreadgroupsWithIndirectBuffer: mtlIndBuff
indirectBufferOffset: mtlIndBuffOfst
Expand Down Expand Up @@ -1237,6 +1242,7 @@
[mtlTessCtlEncoder setBuffer: vtxIndexBuff->_mtlBuffer
offset: vtxIndexBuff->_offset
atIndex: pipeline->getIndirectParamsIndex().stages[kMVKShaderStageVertex]];
[mtlTessCtlEncoder memoryBarrierWithResources:&vtxIndexBuff->_mtlBuffer count:1];
[mtlTessCtlEncoder setStageInRegion: MTLRegionMake2D(0, 0, vertexCount, vertexCount)];
if ([mtlTessCtlEncoder respondsToSelector: @selector(setStageInRegionWithIndirectBuffer:indirectBufferOffset:)]) {
[mtlTessCtlEncoder setStageInRegionWithIndirectBuffer: mtlIndBuff
Expand Down Expand Up @@ -1275,11 +1281,13 @@
[mtlTessCtlEncoder setBuffer: tcParamsBuff->_mtlBuffer
offset: mtlParmBuffOfst
atIndex: pipeline->getIndirectParamsIndex().stages[kMVKShaderStageTessCtl]];
if (drawIdx == 0) [mtlTessCtlEncoder memoryBarrierWithResources:&tcParamsBuff->_mtlBuffer count:1];
mtlParmBuffOfst += paramsIncr;
if (pipeline->needsVertexOutputBuffer()) {
[mtlTessCtlEncoder setBuffer: vtxOutBuff->_mtlBuffer
offset: vtxOutBuff->_offset
atIndex: cmdEncoder->getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKTessCtlInputBufferBinding)];
[mtlTessCtlEncoder memoryBarrierWithResources:&vtxOutBuff->_mtlBuffer count:1];
}
[mtlTessCtlEncoder dispatchThreadgroupsWithIndirectBuffer: mtlIndBuff
indirectBufferOffset: mtlTempIndBuffOfst
Expand Down
34 changes: 34 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,40 @@

auto& mtlFeats = cmdEncoder->getMetalFeatures();

if (cmdEncoder->_mtlComputeEncoder) {
for (auto& b : _barriers) {
const uint64_t stages = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT|VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT
|VK_PIPELINE_STAGE_2_TRANSFER_BIT|VK_PIPELINE_STAGE_2_COPY_BIT|VK_PIPELINE_STAGE_2_BLIT_BIT|VK_PIPELINE_STAGE_2_CLEAR_BIT;

if (!(b.srcStageMask & stages) || !(b.dstStageMask & stages))
continue;

switch (b.type) {
case MVKPipelineBarrier::Memory: {
[cmdEncoder->_mtlComputeEncoder memoryBarrierWithScope:MTLBarrierScopeBuffers|MTLBarrierScopeTextures];
break;
}

case MVKPipelineBarrier::Buffer: {
id<MTLResource> mtlRez = b.mvkBuffer->getMTLBuffer();
[cmdEncoder->_mtlComputeEncoder memoryBarrierWithResources:&mtlRez count:1];
break;
}
case MVKPipelineBarrier::Image: {
uint32_t plnCnt = b.mvkImage->getPlaneCount();
id<MTLResource> mtlRezs[plnCnt];
for (uint8_t plnIdx = 0; plnIdx < plnCnt; plnIdx++) {
mtlRezs[plnIdx] = b.mvkImage->getMTLTexture(plnIdx);
}
[cmdEncoder->_mtlComputeEncoder memoryBarrierWithResources:mtlRezs count:plnCnt];
break;
}
default:
break;
}
}
}

#if MVK_MACOS
// Calls below invoke MTLBlitCommandEncoder so must apply this first.
// Check if pipeline barriers are available and we are in a renderpass.
Expand Down
4 changes: 3 additions & 1 deletion MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ class MVKCommandEncoder : public MVKBaseDeviceObject {
/** The current Metal render encoder. */
id<MTLRenderCommandEncoder> _mtlRenderEncoder;

/** The current Metal compute encoder. */
id<MTLComputeCommandEncoder> _mtlComputeEncoder;

/** Tracks the current graphics pipeline bound to the encoder. */
MVKPipelineCommandEncoderState _graphicsPipelineState;

Expand Down Expand Up @@ -504,7 +507,6 @@ class MVKCommandEncoder : public MVKBaseDeviceObject {
MVKSmallVector<GPUCounterQuery, 16> _timestampStageCounterQueries;
MVKSmallVector<VkClearValue, kMVKDefaultAttachmentCount> _clearValues;
MVKSmallVector<MVKImageView*, kMVKDefaultAttachmentCount> _attachments;
id<MTLComputeCommandEncoder> _mtlComputeEncoder;
id<MTLBlitCommandEncoder> _mtlBlitEncoder;
id<MTLFence> _stageCountersMTLFence;
MVKPushConstantsCommandEncoderState _vertexPushConstants;
Expand Down
2 changes: 1 addition & 1 deletion MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@
id<MTLComputeCommandEncoder> MVKCommandEncoder::getMTLComputeEncoder(MVKCommandUse cmdUse, bool markCurrentComputeStateDirty) {
if ( !_mtlComputeEncoder ) {
endCurrentMetalEncoding();
_mtlComputeEncoder = [_mtlCmdBuffer computeCommandEncoder];
_mtlComputeEncoder = [_mtlCmdBuffer computeCommandEncoderWithDispatchType:MTLDispatchTypeConcurrent];
retainIfImmediatelyEncoding(_mtlComputeEncoder);
beginMetalComputeEncoding(cmdUse);
markCurrentComputeStateDirty = false; // Already marked dirty above in endCurrentMetalEncoding()
Expand Down