From 7c817f3ecdccd22bd54b1fb1e72f4bf25bc65122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 19 Jul 2024 09:42:25 +0200 Subject: [PATCH] Add helper for Vulkan struct chaining --- Common/GPU/Vulkan/VulkanContext.cpp | 39 +++++++++++-------------- Common/GPU/Vulkan/VulkanContext.h | 5 ++++ Common/GPU/Vulkan/VulkanFrameData.cpp | 4 +-- Common/GPU/Vulkan/VulkanFramebuffer.cpp | 2 +- Common/GPU/Vulkan/thin3d_vulkan.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index 72cd721c9e..307c5269db 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -278,12 +278,12 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { VkPhysicalDevicePushDescriptorPropertiesKHR pushProps{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR}; VkPhysicalDeviceExternalMemoryHostPropertiesEXT extHostMemProps{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT}; VkPhysicalDeviceDepthStencilResolveProperties depthStencilResolveProps{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES}; - - props2.pNext = &pushProps; - pushProps.pNext = &extHostMemProps; - extHostMemProps.pNext = &depthStencilResolveProps; + ChainStruct(props2, &pushProps); + ChainStruct(props2, &extHostMemProps); + ChainStruct(props2, &depthStencilResolveProps); vkGetPhysicalDeviceProperties2(physical_devices_[i], &props2); - // Don't want bad pointers sitting around. + + // Don't want bad pointers sitting around. Probably not really necessary. props2.pNext = nullptr; pushProps.pNext = nullptr; extHostMemProps.pNext = nullptr; @@ -702,21 +702,20 @@ VkResult VulkanContext::CreateDevice(int physical_device) { VkPhysicalDevicePresentIdFeaturesKHR presentIdFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR }; VkPhysicalDeviceProvokingVertexFeaturesEXT provokingVertexFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT }; - features2.pNext = &multiViewFeatures; - multiViewFeatures.pNext = &presentWaitFeatures; - presentWaitFeatures.pNext = &presentIdFeatures; + ChainStruct(features2, &multiViewFeatures); + ChainStruct(features2, &presentWaitFeatures); + ChainStruct(features2, &presentIdFeatures); if (extensionsLookup_.EXT_provoking_vertex) { - presentIdFeatures.pNext = &provokingVertexFeatures; - provokingVertexFeatures.pNext = nullptr; - } else { - presentIdFeatures.pNext = nullptr; + ChainStruct(features2, &provokingVertexFeatures); } vkGetPhysicalDeviceFeatures2(physical_devices_[physical_device_], &features2); deviceFeatures_.available.standard = features2.features; deviceFeatures_.available.multiview = multiViewFeatures; deviceFeatures_.available.presentWait = presentWaitFeatures; deviceFeatures_.available.presentId = presentIdFeatures; - deviceFeatures_.available.provokingVertex = provokingVertexFeatures; + if (extensionsLookup_.EXT_provoking_vertex) { + deviceFeatures_.available.provokingVertex = provokingVertexFeatures; + } } else { vkGetPhysicalDeviceFeatures(physical_devices_[physical_device_], &deviceFeatures_.available.standard); deviceFeatures_.available.multiview = {}; @@ -772,15 +771,11 @@ VkResult VulkanContext::CreateDevice(int physical_device) { if (extensionsLookup_.KHR_get_physical_device_properties2) { device_info.pNext = &features2; features2.features = deviceFeatures_.enabled.standard; - features2.pNext = &deviceFeatures_.enabled.multiview; - deviceFeatures_.enabled.multiview.pNext = &deviceFeatures_.enabled.presentWait; - deviceFeatures_.enabled.presentWait.pNext = &deviceFeatures_.enabled.presentId; + ChainStruct(features2, &deviceFeatures_.enabled.multiview); + ChainStruct(features2, &deviceFeatures_.enabled.presentWait); + ChainStruct(features2, &deviceFeatures_.enabled.presentId); if (extensionsLookup_.EXT_provoking_vertex) { - // TODO: Write some proper chaining thing. - deviceFeatures_.enabled.presentId.pNext = &deviceFeatures_.enabled.provokingVertex; - deviceFeatures_.enabled.provokingVertex.pNext = nullptr; - } else { - deviceFeatures_.enabled.presentId.pNext = nullptr; + ChainStruct(features2, &deviceFeatures_.enabled.provokingVertex); } } else { device_info.pEnabledFeatures = &deviceFeatures_.enabled.standard; @@ -1833,7 +1828,7 @@ void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequiremen VkMemoryRequirements2KHR memReq2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR}; VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR}; - memReq2.pNext = &memDedicatedReq; + ChainStruct(memReq2, &memDedicatedReq); vkGetImageMemoryRequirements2(GetDevice(), &memReqInfo2, &memReq2); diff --git a/Common/GPU/Vulkan/VulkanContext.h b/Common/GPU/Vulkan/VulkanContext.h index 629fb7c5f1..4f1e368cdb 100644 --- a/Common/GPU/Vulkan/VulkanContext.h +++ b/Common/GPU/Vulkan/VulkanContext.h @@ -44,6 +44,11 @@ VK_DEFINE_HANDLE(VmaAllocation); std::string VulkanVendorString(uint32_t vendorId); +template inline void ChainStruct(R &root, T *newStruct) { + newStruct->pNext = root.pNext; + root.pNext = newStruct; +} + // Not all will be usable on all platforms, of course... enum WindowSystem { #ifdef _WIN32 diff --git a/Common/GPU/Vulkan/VulkanFrameData.cpp b/Common/GPU/Vulkan/VulkanFrameData.cpp index cc7cd23016..9eb65ddfd3 100644 --- a/Common/GPU/Vulkan/VulkanFrameData.cpp +++ b/Common/GPU/Vulkan/VulkanFrameData.cpp @@ -132,13 +132,13 @@ VkResult FrameData::QueuePresent(VulkanContext *vulkan, FrameDataShared &shared) if (shared.measurePresentTime) { if (vulkan->Extensions().KHR_present_id && vulkan->GetDeviceFeatures().enabled.presentId.presentId) { + ChainStruct(present, &presentID); presentID.pPresentIds = &frameId; presentID.swapchainCount = 1; - present.pNext = &presentID; } else if (vulkan->Extensions().GOOGLE_display_timing) { + ChainStruct(present, &presentGOOGLE); presentGOOGLE.pTimes = &presentTimeGOOGLE; presentGOOGLE.swapchainCount = 1; - present.pNext = &presentGOOGLE; } } diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.cpp b/Common/GPU/Vulkan/VulkanFramebuffer.cpp index 2ad479e875..5e6d7a61a1 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.cpp +++ b/Common/GPU/Vulkan/VulkanFramebuffer.cpp @@ -505,7 +505,7 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas VkAttachmentReference2KHR depthResolveReference2{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR }; VkSubpassDescriptionDepthStencilResolveKHR depthStencilResolve{ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR }; if (hasDepth && multisample) { - subpass2.pNext = &depthStencilResolve; + ChainStruct(subpass2, &depthStencilResolve); depthResolveReference2.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; depthResolveReference2.attachment = 1; depthResolveReference2.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 9c9eec4367..1101d38e25 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -1246,7 +1246,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc, const char raster->ToVulkan(&gDesc.rs); if (renderManager_.GetVulkanContext()->GetDeviceFeatures().enabled.provokingVertex.provokingVertexLast) { - gDesc.rs.pNext = &gDesc.rs_provoking; + ChainStruct(gDesc.rs, &gDesc.rs_provoking); gDesc.rs_provoking.provokingVertexMode = VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 074fa8abd0..9babb43e39 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -286,7 +286,7 @@ static VulkanPipeline *CreateVulkanPipeline(VulkanRenderManager *renderManager, rs.depthClampEnable = key.depthClampEnable; if (renderManager->GetVulkanContext()->GetDeviceFeatures().enabled.provokingVertex.provokingVertexLast) { - rs.pNext = &desc->rs_provoking; + ChainStruct(rs, &desc->rs_provoking); desc->rs_provoking.provokingVertexMode = VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; }