From 260f9393d74311d7a12192934cebeacb819286f1 Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Tue, 8 Sep 2020 14:31:17 -0500 Subject: [PATCH] Support the VK_KHR_create_renderpass2 extension. This will be needed for two other Vulkan 1.2 extensions, `VK_KHR_depth_stencil_resolve` and `VK_KHR_separate_depth_stencil_layouts`. Most of this is just changing MVKRenderPass to store everything internally in `RenderPass2` format. I also added some basic handling for a few things I left out from earlier changes, input attachment aspect masks and dependency view offsets. The former won't become important until Metal supports depth/stencil framebuffer fetch. The latter won't be needed until we start using untracked resources, and therefore need to insert explicit fences and/or barriers between subpasses. We don't need either right now, but I've handled them regardless. --- Docs/MoltenVK_Runtime_UserGuide.md | 1 + Docs/Whats_New.md | 1 + MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h | 8 ++ .../MoltenVK/Commands/MVKCmdRenderPass.mm | 18 +++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 2 + MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 5 + MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 4 + MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h | 27 +++- MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm | 124 +++++++++++++++++- MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 48 +++++++ 11 files changed, 225 insertions(+), 14 deletions(-) diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index b03c059c..68ed658f 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -259,6 +259,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_KHR_16bit_storage` - `VK_KHR_8bit_storage` - `VK_KHR_bind_memory2` +- `VK_KHR_create_renderpass2` - `VK_KHR_dedicated_allocation` - `VK_KHR_descriptor_update_template` - `VK_KHR_device_group` diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 8bbc2a76..f13de5af 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -25,6 +25,7 @@ Released TBD - A feature struct for `VK_KHR_shader_draw_parameters` - All extensions that were promoted to core in Vulkan 1.1 - Add support for extensions: + - `VK_KHR_create_renderpass2` - `VK_KHR_external_fence` (non-functional groundwork for future extensions, including support for GCD and Mach semaphores) - `VK_KHR_external_fence_capabilities` (non-functional groundwork for future diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h index a03abf09..1dd2ea5a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h @@ -67,6 +67,9 @@ public: VkResult setContent(MVKCommandBuffer* cmdBuff, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); + VkResult setContent(MVKCommandBuffer* cmdBuff, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo); void encode(MVKCommandEncoder* cmdEncoder) override; @@ -91,6 +94,9 @@ class MVKCmdNextSubpass : public MVKCommand { public: VkResult setContent(MVKCommandBuffer* cmdBuff, VkSubpassContents contents); + VkResult setContent(MVKCommandBuffer* cmdBuff, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); void encode(MVKCommandEncoder* cmdEncoder) override; @@ -109,6 +115,8 @@ class MVKCmdEndRenderPass : public MVKCommand { public: VkResult setContent(MVKCommandBuffer* cmdBuff); + VkResult setContent(MVKCommandBuffer* cmdBuff, + const VkSubpassEndInfo* pSubpassEndInfo); void encode(MVKCommandEncoder* cmdEncoder) override; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm index f89ae298..2e1e5ad1 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm @@ -60,6 +60,13 @@ VkResult MVKCmdBeginRenderPass::setContent(MVKCommandBuffer* cmdBuff, return VK_SUCCESS; } +template +VkResult MVKCmdBeginRenderPass::setContent(MVKCommandBuffer* cmdBuff, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo) { + return setContent(cmdBuff, pRenderPassBegin, pSubpassBeginInfo->contents); +} + template void MVKCmdBeginRenderPass::encode(MVKCommandEncoder* cmdEncoder) { // MVKLogDebug("Encoding vkCmdBeginRenderPass(). Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds()); @@ -81,6 +88,12 @@ VkResult MVKCmdNextSubpass::setContent(MVKCommandBuffer* cmdBuff, return VK_SUCCESS; } +VkResult MVKCmdNextSubpass::setContent(MVKCommandBuffer* cmdBuff, + const VkSubpassBeginInfo* pBeginSubpassInfo, + const VkSubpassEndInfo* pEndSubpassInfo) { + return setContent(cmdBuff, pBeginSubpassInfo->contents); +} + void MVKCmdNextSubpass::encode(MVKCommandEncoder* cmdEncoder) { if (cmdEncoder->getMultiviewPassIndex() + 1 < cmdEncoder->getSubpass()->getMultiviewMetalPassCount()) cmdEncoder->beginNextMultiviewPass(); @@ -96,6 +109,11 @@ VkResult MVKCmdEndRenderPass::setContent(MVKCommandBuffer* cmdBuff) { return VK_SUCCESS; } +VkResult MVKCmdEndRenderPass::setContent(MVKCommandBuffer* cmdBuff, + const VkSubpassEndInfo* pEndSubpassInfo) { + return VK_SUCCESS; +} + void MVKCmdEndRenderPass::encode(MVKCommandEncoder* cmdEncoder) { // MVKLogDebug("Encoding vkCmdEndRenderPass(). Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds()); if (cmdEncoder->getMultiviewPassIndex() + 1 < cmdEncoder->getSubpass()->getMultiviewMetalPassCount()) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index c1062d00..23d74f5d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -563,6 +563,8 @@ public: MVKRenderPass* createRenderPass(const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); + MVKRenderPass* createRenderPass(const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator); void destroyRenderPass(MVKRenderPass* mvkRP, const VkAllocationCallbacks* pAllocator); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 18c78995..e21d8aa1 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -2793,6 +2793,11 @@ MVKRenderPass* MVKDevice::createRenderPass(const VkRenderPassCreateInfo* pCreate return new MVKRenderPass(this, pCreateInfo); } +MVKRenderPass* MVKDevice::createRenderPass(const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator) { + return new MVKRenderPass(this, pCreateInfo); +} + void MVKDevice::destroyRenderPass(MVKRenderPass* mvkRP, const VkAllocationCallbacks* pAllocator) { if (mvkRP) { mvkRP->destroy(); } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 49cdc7f6..0d13f563 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -644,6 +644,10 @@ void MVKInstance::initProcAddrs() { // Device extension functions: ADD_DVC_EXT_ENTRY_POINT(vkBindBufferMemory2KHR, KHR_BIND_MEMORY_2); ADD_DVC_EXT_ENTRY_POINT(vkBindImageMemory2KHR, KHR_BIND_MEMORY_2); + ADD_DVC_EXT_ENTRY_POINT(vkCreateRenderPass2KHR, KHR_CREATE_RENDERPASS_2); + ADD_DVC_EXT_ENTRY_POINT(vkCmdBeginRenderPass2KHR, KHR_CREATE_RENDERPASS_2); + ADD_DVC_EXT_ENTRY_POINT(vkCmdNextSubpass2KHR, KHR_CREATE_RENDERPASS_2); + ADD_DVC_EXT_ENTRY_POINT(vkCmdEndRenderPass2KHR, KHR_CREATE_RENDERPASS_2); ADD_DVC_EXT_ENTRY_POINT(vkCreateDescriptorUpdateTemplateKHR, KHR_DESCRIPTOR_UPDATE_TEMPLATE); ADD_DVC_EXT_ENTRY_POINT(vkDestroyDescriptorUpdateTemplateKHR, KHR_DESCRIPTOR_UPDATE_TEMPLATE); ADD_DVC_EXT_ENTRY_POINT(vkUpdateDescriptorSetWithTemplateKHR, KHR_DESCRIPTOR_UPDATE_TEMPLATE); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h index f36d8bc8..f8decdac 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h @@ -117,7 +117,12 @@ public: void encodeStoreActions(MVKCommandEncoder* cmdEncoder, bool isRenderingEntireAttachment, bool storeOverride = false); /** Constructs an instance for the specified parent renderpass. */ - MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription* pCreateInfo, uint32_t viewMask); + MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription* pCreateInfo, + const VkRenderPassInputAttachmentAspectCreateInfo* pInputAspects, + uint32_t viewMask); + + /** Constructs an instance for the specified parent renderpass. */ + MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription2* pCreateInfo); private: @@ -130,11 +135,11 @@ private: MVKRenderPass* _renderPass; uint32_t _subpassIndex; uint32_t _viewMask; - MVKSmallVector _inputAttachments; - MVKSmallVector _colorAttachments; - MVKSmallVector _resolveAttachments; + MVKSmallVector _inputAttachments; + MVKSmallVector _colorAttachments; + MVKSmallVector _resolveAttachments; MVKSmallVector _preserveAttachments; - VkAttachmentReference _depthStencilAttachment; + VkAttachmentReference2 _depthStencilAttachment; id _mtlDummyTex = nil; }; @@ -186,6 +191,10 @@ public: MVKRenderPassAttachment(MVKRenderPass* renderPass, const VkAttachmentDescription* pCreateInfo); + /** Constructs an instance for the specified parent renderpass. */ + MVKRenderPassAttachment(MVKRenderPass* renderPass, + const VkAttachmentDescription2* pCreateInfo); + protected: bool isFirstUseOfAttachment(MVKRenderSubpass* subpass); bool isLastUseOfAttachment(MVKRenderSubpass* subpass); @@ -194,8 +203,9 @@ protected: bool hasResolveAttachment, bool isStencil, bool storeOverride); + void validateFormat(); - VkAttachmentDescription _info; + VkAttachmentDescription2 _info; MVKRenderPass* _renderPass; uint32_t _attachmentIndex; uint32_t _firstUseSubpassIdx; @@ -231,6 +241,9 @@ public: /** Constructs an instance for the specified device. */ MVKRenderPass(MVKDevice* device, const VkRenderPassCreateInfo* pCreateInfo); + /** Constructs an instance for the specified device. */ + MVKRenderPass(MVKDevice* device, const VkRenderPassCreateInfo2* pCreateInfo); + protected: friend class MVKRenderSubpass; friend class MVKRenderPassAttachment; @@ -239,7 +252,7 @@ protected: MVKSmallVector _attachments; MVKSmallVector _subpasses; - MVKSmallVector _subpassDependencies; + MVKSmallVector _subpassDependencies; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm index d51433ea..c3eeb6a3 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm @@ -400,11 +400,60 @@ MVKMTLFmtCaps MVKRenderSubpass::getRequiredFormatCapabilitiesForAttachmentAt(uin MVKRenderSubpass::MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription* pCreateInfo, + const VkRenderPassInputAttachmentAspectCreateInfo* pInputAspects, uint32_t viewMask) { _renderPass = renderPass; _subpassIndex = (uint32_t)_renderPass->_subpasses.size(); _viewMask = viewMask; + // Add attachments + _inputAttachments.reserve(pCreateInfo->inputAttachmentCount); + for (uint32_t i = 0; i < pCreateInfo->inputAttachmentCount; i++) { + const VkAttachmentReference& att = pCreateInfo->pInputAttachments[i]; + _inputAttachments.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, att.attachment, att.layout, 0}); + } + if (pInputAspects && pInputAspects->aspectReferenceCount) { + for (uint32_t i = 0; i < pInputAspects->aspectReferenceCount; i++) { + const VkInputAttachmentAspectReference& aspectRef = pInputAspects->pAspectReferences[i]; + if (aspectRef.subpass == _subpassIndex) { + _inputAttachments[aspectRef.inputAttachmentIndex].aspectMask = aspectRef.aspectMask; + } + } + } + + _colorAttachments.reserve(pCreateInfo->colorAttachmentCount); + for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) { + const VkAttachmentReference& att = pCreateInfo->pColorAttachments[i]; + _colorAttachments.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, att.attachment, att.layout, 0}); + } + + if (pCreateInfo->pResolveAttachments) { + _resolveAttachments.reserve(pCreateInfo->colorAttachmentCount); + for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) { + const VkAttachmentReference& att = pCreateInfo->pResolveAttachments[i]; + _resolveAttachments.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, att.attachment, att.layout, 0}); + } + } + + if (pCreateInfo->pDepthStencilAttachment) { + _depthStencilAttachment.attachment = pCreateInfo->pDepthStencilAttachment->attachment; + _depthStencilAttachment.layout = pCreateInfo->pDepthStencilAttachment->layout; + } else { + _depthStencilAttachment.attachment = VK_ATTACHMENT_UNUSED; + } + + _preserveAttachments.reserve(pCreateInfo->preserveAttachmentCount); + for (uint32_t i = 0; i < pCreateInfo->preserveAttachmentCount; i++) { + _preserveAttachments.push_back(pCreateInfo->pPreserveAttachments[i]); + } +} + +MVKRenderSubpass::MVKRenderSubpass(MVKRenderPass* renderPass, + const VkSubpassDescription2* pCreateInfo) { + _renderPass = renderPass; + _subpassIndex = (uint32_t)_renderPass->_subpasses.size(); + _viewMask = pCreateInfo->viewMask; + // Add attachments _inputAttachments.reserve(pCreateInfo->inputAttachmentCount); for (uint32_t i = 0; i < pCreateInfo->inputAttachmentCount; i++) { @@ -563,12 +612,7 @@ bool MVKRenderPassAttachment::shouldUseClearAttachment(MVKRenderSubpass* subpass return (_info.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); } -MVKRenderPassAttachment::MVKRenderPassAttachment(MVKRenderPass* renderPass, - const VkAttachmentDescription* pCreateInfo) { - _info = *pCreateInfo; - _renderPass = renderPass; - _attachmentIndex = uint32_t(_renderPass->_attachments.size()); - +void MVKRenderPassAttachment::validateFormat() { // Validate pixel format is supported MVKPixelFormats* pixFmts = _renderPass->getPixelFormats(); if ( !pixFmts->isSupportedOrSubstitutable(_info.format) ) { @@ -606,6 +650,32 @@ MVKRenderPassAttachment::MVKRenderPassAttachment(MVKRenderPass* renderPass, } } +MVKRenderPassAttachment::MVKRenderPassAttachment(MVKRenderPass* renderPass, + const VkAttachmentDescription* pCreateInfo) { + _info.flags = pCreateInfo->flags; + _info.format = pCreateInfo->format; + _info.samples = pCreateInfo->samples; + _info.loadOp = pCreateInfo->loadOp; + _info.storeOp = pCreateInfo->storeOp; + _info.stencilLoadOp = pCreateInfo->stencilLoadOp; + _info.stencilStoreOp = pCreateInfo->stencilStoreOp; + _info.initialLayout = pCreateInfo->initialLayout; + _info.finalLayout = pCreateInfo->finalLayout; + _renderPass = renderPass; + _attachmentIndex = uint32_t(_renderPass->_attachments.size()); + + validateFormat(); +} + +MVKRenderPassAttachment::MVKRenderPassAttachment(MVKRenderPass* renderPass, + const VkAttachmentDescription2* pCreateInfo) { + _info = *pCreateInfo; + _renderPass = renderPass; + _attachmentIndex = uint32_t(_renderPass->_attachments.size()); + + validateFormat(); +} + #pragma mark - #pragma mark MVKRenderPass @@ -619,9 +689,13 @@ bool MVKRenderPass::isMultiview() const { return _subpasses[0].isMultiview(); } MVKRenderPass::MVKRenderPass(MVKDevice* device, const VkRenderPassCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) { + const VkRenderPassInputAttachmentAspectCreateInfo* pInputAspectCreateInfo = nullptr; const VkRenderPassMultiviewCreateInfo* pMultiviewCreateInfo = nullptr; for (auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) { switch (next->sType) { + case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO: + pInputAspectCreateInfo = (const VkRenderPassInputAttachmentAspectCreateInfo*)next; + break; case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: pMultiviewCreateInfo = (const VkRenderPassMultiviewCreateInfo*)next; break; @@ -631,14 +705,50 @@ MVKRenderPass::MVKRenderPass(MVKDevice* device, } const uint32_t* viewMasks = nullptr; + const int32_t* viewOffsets = nullptr; if (pMultiviewCreateInfo && pMultiviewCreateInfo->subpassCount) { viewMasks = pMultiviewCreateInfo->pViewMasks; } + if (pMultiviewCreateInfo && pMultiviewCreateInfo->dependencyCount) { + viewOffsets = pMultiviewCreateInfo->pViewOffsets; + } // Add subpasses and dependencies first _subpasses.reserve(pCreateInfo->subpassCount); for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - _subpasses.emplace_back(this, &pCreateInfo->pSubpasses[i], viewMasks ? viewMasks[i] : 0); + _subpasses.emplace_back(this, &pCreateInfo->pSubpasses[i], pInputAspectCreateInfo, viewMasks ? viewMasks[i] : 0); + } + _subpassDependencies.reserve(pCreateInfo->dependencyCount); + for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) { + VkSubpassDependency2 dependency = { + .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, + .pNext = nullptr, + .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass, + .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass, + .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask, + .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask, + .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask, + .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask, + .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags, + .viewOffset = viewOffsets ? viewOffsets[i] : 0, + }; + _subpassDependencies.push_back(dependency); + } + + // Add attachments after subpasses, so each attachment can link to subpasses + _attachments.reserve(pCreateInfo->attachmentCount); + for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { + _attachments.emplace_back(this, &pCreateInfo->pAttachments[i]); + } +} + +MVKRenderPass::MVKRenderPass(MVKDevice* device, + const VkRenderPassCreateInfo2* pCreateInfo) : MVKVulkanAPIDeviceObject(device) { + + // Add subpasses and dependencies first + _subpasses.reserve(pCreateInfo->subpassCount); + for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { + _subpasses.emplace_back(this, &pCreateInfo->pSubpasses[i]); } _subpassDependencies.reserve(pCreateInfo->dependencyCount); for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) { diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 6b4be3b3..cbb1f16d 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -42,6 +42,7 @@ MVK_EXTENSION(KHR_16bit_storage, KHR_16BIT_STORAGE, DEVICE) MVK_EXTENSION(KHR_8bit_storage, KHR_8BIT_STORAGE, DEVICE) MVK_EXTENSION(KHR_bind_memory2, KHR_BIND_MEMORY_2, DEVICE) +MVK_EXTENSION(KHR_create_renderpass2, KHR_CREATE_RENDERPASS_2, DEVICE) MVK_EXTENSION(KHR_dedicated_allocation, KHR_DEDICATED_ALLOCATION, DEVICE) MVK_EXTENSION(KHR_descriptor_update_template, KHR_DESCRIPTOR_UPDATE_TEMPLATE, DEVICE) MVK_EXTENSION(KHR_device_group, KHR_DEVICE_GROUP, DEVICE) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index b360b066..f0e18246 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2253,6 +2253,54 @@ MVK_PUBLIC_CORE_ALIAS(vkBindBufferMemory2); MVK_PUBLIC_CORE_ALIAS(vkBindImageMemory2); +#pragma mark - +#pragma mark VK_KHR_create_renderpass2 extension + +MVK_PUBLIC_SYMBOL VkResult vkCreateRenderPass2KHR( + VkDevice device, + const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass) { + + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); + MVKRenderPass* mvkRendPass = mvkDev->createRenderPass(pCreateInfo, pAllocator); + *pRenderPass = (VkRenderPass)mvkRendPass; + VkResult rslt = mvkRendPass->getConfigurationResult(); + MVKTraceVulkanCallEnd(); + return rslt; +} + +MVK_PUBLIC_SYMBOL void vkCmdBeginRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo) { + + MVKTraceVulkanCallStart(); + MVKAddCmdFrom2Thresholds(BeginRenderPass, pRenderPassBegin->clearValueCount, 1, 2, commandBuffer, pRenderPassBegin, pSubpassBeginInfo); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_SYMBOL void vkCmdNextSubpass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(NextSubpass, commandBuffer, pSubpassBeginInfo, pSubpassEndInfo); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_SYMBOL void vkCmdEndRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfo* pSubpassEndInfo) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(EndRenderPass, commandBuffer, pSubpassEndInfo); + MVKTraceVulkanCallEnd(); +} + + #pragma mark - #pragma mark VK_KHR_descriptor_update_template extension