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

Add support for extension VK_KHR_synchronization2 #2021

Merged
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
1 change: 1 addition & 0 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_KHR_surface`
- `VK_KHR_swapchain`
- `VK_KHR_swapchain_mutable_format`
- `VK_KHR_synchronization2`
- `VK_KHR_timeline_semaphore`
- `VK_KHR_uniform_buffer_standard_layout`
- `VK_KHR_variable_pointers`
Expand Down
2 changes: 2 additions & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ MoltenVK 1.2.6

Released TBD

- Add support for extensions:
- `VK_KHR_synchronization2`
- Fix rare case where vertex attribute buffers are not bound to Metal
when no other bindings change between pipelines.
- Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`.
Expand Down
8 changes: 4 additions & 4 deletions MoltenVK/MoltenVK/API/mvk_datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,13 +414,13 @@ MTLWinding mvkMTLWindingFromSpvExecutionMode(uint32_t spvMode);
MTLTessellationPartitionMode mvkMTLTessellationPartitionModeFromSpvExecutionMode(uint32_t spvMode);

/**
* Returns the combination of Metal MTLRenderStage bits corresponding to the specified Vulkan VkPiplineStageFlags,
* Returns the combination of Metal MTLRenderStage bits corresponding to the specified Vulkan VkPipelineStageFlags2,
* taking into consideration whether the barrier is to be placed before or after the specified pipeline stages.
*/
MTLRenderStages mvkMTLRenderStagesFromVkPipelineStageFlags(VkPipelineStageFlags vkStages, bool placeBarrierBefore);
MTLRenderStages mvkMTLRenderStagesFromVkPipelineStageFlags(VkPipelineStageFlags2 vkStages, bool placeBarrierBefore);

/** Returns the combination of Metal MTLBarrierScope bits corresponding to the specified Vulkan VkAccessFlags. */
MTLBarrierScope mvkMTLBarrierScopeFromVkAccessFlags(VkAccessFlags vkAccess);
/** Returns the combination of Metal MTLBarrierScope bits corresponding to the specified Vulkan VkAccessFlags2. */
MTLBarrierScope mvkMTLBarrierScopeFromVkAccessFlags(VkAccessFlags2 vkAccess);
cdavis5e marked this conversation as resolved.
Show resolved Hide resolved

#pragma mark -
#pragma mark Geometry conversions
Expand Down
41 changes: 22 additions & 19 deletions MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ template <size_t N>
class MVKCmdPipelineBarrier : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
const VkDependencyInfo* pDependencyInfo);

VkResult setContent(MVKCommandBuffer* cmdBuff,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
Expand All @@ -59,8 +62,6 @@ class MVKCmdPipelineBarrier : public MVKCommand {
bool coversTextures();

MVKSmallVector<MVKPipelineBarrier, N> _barriers;
VkPipelineStageFlags _srcStageMask;
VkPipelineStageFlags _dstStageMask;
VkDependencyFlags _dependencyFlags;
};

Expand Down Expand Up @@ -281,49 +282,46 @@ class MVKCmdPushDescriptorSetWithTemplate : public MVKCommand {


#pragma mark -
#pragma mark MVKCmdSetResetEvent
#pragma mark MVKCmdSetEvent

/** Abstract Vulkan command to set or reset an event. */
class MVKCmdSetResetEvent : public MVKCommand {
/** Vulkan command to set an event. */
class MVKCmdSetEvent : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags stageMask);

protected:
MVKEvent* _mvkEvent;

};


#pragma mark -
#pragma mark MVKCmdSetEvent
const VkDependencyInfo* pDependencyInfo);

/** Vulkan command to set an event. */
class MVKCmdSetEvent : public MVKCmdSetResetEvent {
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags stageMask);

public:
void encode(MVKCommandEncoder* cmdEncoder) override;

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

MVKEvent* _mvkEvent;
};


#pragma mark -
#pragma mark MVKCmdResetEvent

/** Vulkan command to reset an event. */
class MVKCmdResetEvent : public MVKCmdSetResetEvent {
class MVKCmdResetEvent : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags2 stageMask);

void encode(MVKCommandEncoder* cmdEncoder) override;

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

MVKEvent* _mvkEvent;
};


Expand All @@ -339,6 +337,11 @@ template <size_t N>
class MVKCmdWaitEvents : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
uint32_t eventCount,
const VkEvent* pEvents,
const VkDependencyInfo* pDependencyInfos);

VkResult setContent(MVKCommandBuffer* cmdBuff,
uint32_t eventCount,
const VkEvent* pEvents,
Expand Down
116 changes: 81 additions & 35 deletions MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@
#pragma mark -
#pragma mark MVKCmdPipelineBarrier

template <size_t N>
VkResult MVKCmdPipelineBarrier<N>::setContent(MVKCommandBuffer* cmdBuff,
const VkDependencyInfo* pDependencyInfo) {
_dependencyFlags = pDependencyInfo->dependencyFlags;

_barriers.clear(); // Clear for reuse
_barriers.reserve(pDependencyInfo->memoryBarrierCount +
pDependencyInfo->bufferMemoryBarrierCount +
pDependencyInfo->imageMemoryBarrierCount);

for (uint32_t i = 0; i < pDependencyInfo->memoryBarrierCount; i++) {
_barriers.emplace_back(pDependencyInfo->pMemoryBarriers[i]);
}
for (uint32_t i = 0; i < pDependencyInfo->bufferMemoryBarrierCount; i++) {
_barriers.emplace_back(pDependencyInfo->pBufferMemoryBarriers[i]);
}
for (uint32_t i = 0; i < pDependencyInfo->imageMemoryBarrierCount; i++) {
_barriers.emplace_back(pDependencyInfo->pImageMemoryBarriers[i]);
}

return VK_SUCCESS;
}

template <size_t N>
VkResult MVKCmdPipelineBarrier<N>::setContent(MVKCommandBuffer* cmdBuff,
VkPipelineStageFlags srcStageMask,
Expand All @@ -40,21 +63,19 @@
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier* pImageMemoryBarriers) {
_srcStageMask = srcStageMask;
_dstStageMask = dstStageMask;
_dependencyFlags = dependencyFlags;

_barriers.clear(); // Clear for reuse
_barriers.reserve(memoryBarrierCount + bufferMemoryBarrierCount + imageMemoryBarrierCount);

for (uint32_t i = 0; i < memoryBarrierCount; i++) {
_barriers.emplace_back(pMemoryBarriers[i]);
_barriers.emplace_back(pMemoryBarriers[i], srcStageMask, dstStageMask);
}
for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
_barriers.emplace_back(pBufferMemoryBarriers[i]);
_barriers.emplace_back(pBufferMemoryBarriers[i], srcStageMask, dstStageMask);
}
for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
_barriers.emplace_back(pImageMemoryBarriers[i]);
_barriers.emplace_back(pImageMemoryBarriers[i], srcStageMask, dstStageMask);
}

return VK_SUCCESS;
Expand All @@ -67,13 +88,9 @@
// Calls below invoke MTLBlitCommandEncoder so must apply this first.
// Check if pipeline barriers are available and we are in a renderpass.
if (cmdEncoder->getDevice()->_pMetalFeatures->memoryBarriers && cmdEncoder->_mtlRenderEncoder) {
MTLRenderStages srcStages = mvkMTLRenderStagesFromVkPipelineStageFlags(_srcStageMask, false);
MTLRenderStages dstStages = mvkMTLRenderStagesFromVkPipelineStageFlags(_dstStageMask, true);

id<MTLResource> resources[_barriers.size()];
uint32_t rezCnt = 0;

for (auto& b : _barriers) {
MTLRenderStages srcStages = mvkMTLRenderStagesFromVkPipelineStageFlags(b.srcStageMask, false);
MTLRenderStages dstStages = mvkMTLRenderStagesFromVkPipelineStageFlags(b.dstStageMask, true);
switch (b.type) {
case MVKPipelineBarrier::Memory: {
MTLBarrierScope scope = (mvkMTLBarrierScopeFromVkAccessFlags(b.srcAccessMask) |
Expand All @@ -84,27 +101,30 @@
break;
}

case MVKPipelineBarrier::Buffer:
resources[rezCnt++] = b.mvkBuffer->getMTLBuffer();
case MVKPipelineBarrier::Buffer: {
id<MTLResource> mtlRez = b.mvkBuffer->getMTLBuffer();
[cmdEncoder->_mtlRenderEncoder memoryBarrierWithResources: &mtlRez
count: 1
afterStages: srcStages
beforeStages: dstStages];
break;

case MVKPipelineBarrier::Image:
for (uint8_t planeIndex = 0; planeIndex < b.mvkImage->getPlaneCount(); planeIndex++) {
resources[rezCnt++] = b.mvkImage->getMTLTexture(planeIndex);
}
}
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->_mtlRenderEncoder memoryBarrierWithResources: mtlRezs
count: plnCnt
afterStages: srcStages
beforeStages: dstStages];
break;

}
default:
break;
}
}

if (rezCnt) {
[cmdEncoder->_mtlRenderEncoder memoryBarrierWithResources: resources
count: rezCnt
afterStages: srcStages
beforeStages: dstStages];
}
} else if (cmdEncoder->getDevice()->_pMetalFeatures->textureBarriers) {
#if !MVK_MACCAT
if (coversTextures()) { [cmdEncoder->_mtlRenderEncoder textureBarrier]; }
Expand Down Expand Up @@ -138,15 +158,15 @@
for (auto& b : _barriers) {
switch (b.type) {
case MVKPipelineBarrier::Memory:
mvkDvc->applyMemoryBarrier(_srcStageMask, _dstStageMask, b, cmdEncoder, cmdUse);
mvkDvc->applyMemoryBarrier(b, cmdEncoder, cmdUse);
break;

case MVKPipelineBarrier::Buffer:
b.mvkBuffer->applyBufferMemoryBarrier(_srcStageMask, _dstStageMask, b, cmdEncoder, cmdUse);
b.mvkBuffer->applyBufferMemoryBarrier(b, cmdEncoder, cmdUse);
break;

case MVKPipelineBarrier::Image:
b.mvkImage->applyImageMemoryBarrier(_srcStageMask, _dstStageMask, b, cmdEncoder, cmdUse);
b.mvkImage->applyImageMemoryBarrier(b, cmdEncoder, cmdUse);
break;

default:
Expand Down Expand Up @@ -493,19 +513,23 @@


#pragma mark -
#pragma mark MVKCmdSetResetEvent
#pragma mark MVKCmdSetEvent

VkResult MVKCmdSetResetEvent::setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags stageMask) {
VkResult MVKCmdSetEvent::setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags stageMask) {
_mvkEvent = (MVKEvent*)event;

return VK_SUCCESS;
}

VkResult MVKCmdSetEvent::setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
const VkDependencyInfo* pDependencyInfo) {
_mvkEvent = (MVKEvent*)event;

#pragma mark -
#pragma mark MVKCmdSetEvent
return VK_SUCCESS;
}

void MVKCmdSetEvent::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->signalEvent(_mvkEvent, true);
Expand All @@ -515,6 +539,14 @@
#pragma mark -
#pragma mark MVKCmdResetEvent

VkResult MVKCmdResetEvent::setContent(MVKCommandBuffer* cmdBuff,
VkEvent event,
VkPipelineStageFlags2 stageMask) {
_mvkEvent = (MVKEvent*)event;

return VK_SUCCESS;
}

void MVKCmdResetEvent::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->signalEvent(_mvkEvent, false);
}
Expand All @@ -523,6 +555,20 @@
#pragma mark -
#pragma mark MVKCmdWaitEvents

template <size_t N>
VkResult MVKCmdWaitEvents<N>::setContent(MVKCommandBuffer* cmdBuff,
uint32_t eventCount,
const VkEvent* pEvents,
const VkDependencyInfo* pDependencyInfos) {
_mvkEvents.clear(); // Clear for reuse
_mvkEvents.reserve(eventCount);
for (uint32_t i = 0; i < eventCount; i++) {
_mvkEvents.push_back((MVKEvent*)pEvents[i]);
}

return VK_SUCCESS;
}

template <size_t N>
VkResult MVKCmdWaitEvents<N>::setContent(MVKCommandBuffer* cmdBuff,
uint32_t eventCount,
Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdQueries.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class MVKCmdWriteTimestamp : public MVKCmdQuery {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkPipelineStageFlagBits pipelineStage,
VkPipelineStageFlags2 stage,
VkQueryPool queryPool,
uint32_t query);

Expand All @@ -94,7 +94,7 @@ class MVKCmdWriteTimestamp : public MVKCmdQuery {
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

VkPipelineStageFlagBits _pipelineStage;
VkPipelineStageFlags2 _stage;
};


Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdQueries.mm
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@
#pragma mark MVKCmdWriteTimestamp

VkResult MVKCmdWriteTimestamp::setContent(MVKCommandBuffer* cmdBuff,
VkPipelineStageFlagBits pipelineStage,
VkPipelineStageFlags2 stage,
VkQueryPool queryPool,
uint32_t query) {

VkResult rslt = MVKCmdQuery::setContent(cmdBuff, queryPool, query);

_pipelineStage = pipelineStage;
_stage = stage;

cmdBuff->recordTimestampCommand();

Expand Down
Loading