From 340a98950f5afda4fc1892a1d6bc2966df279583 Mon Sep 17 00:00:00 2001 From: dpjudas Date: Sat, 5 Apr 2025 03:08:03 +0200 Subject: [PATCH] Update ZVulkan to support graphics pipeline libraries --- .../ZVulkan/include/zvulkan/vulkanbuilders.h | 26 +++++---- .../ZVulkan/include/zvulkan/vulkaninstance.h | 2 + libraries/ZVulkan/src/vulkanbuilders.cpp | 54 +++++++++++++++---- libraries/ZVulkan/src/vulkandevice.cpp | 5 ++ libraries/ZVulkan/src/vulkaninstance.cpp | 12 +++++ 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h b/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h index 7b56519a1..ce98cf1d4 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h +++ b/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h @@ -401,28 +401,36 @@ public: GraphicsPipelineBuilder& PolygonMode(VkPolygonMode mode) {rasterizer.polygonMode = mode; return *this;}; + GraphicsPipelineBuilder& Flags(VkPipelineCreateFlags flags); + GraphicsPipelineBuilder& LibraryFlags(VkGraphicsPipelineLibraryFlagsEXT flags); + GraphicsPipelineBuilder& AddLibrary(VulkanPipeline* pipeline); + GraphicsPipelineBuilder& DebugName(const char* name) { debugName = name; return *this; } std::unique_ptr Create(VulkanDevice *device); private: - VkGraphicsPipelineCreateInfo pipelineInfo = { }; - VkPipelineVertexInputStateCreateInfo vertexInputInfo = { }; - VkPipelineInputAssemblyStateCreateInfo inputAssembly = { }; + VkGraphicsPipelineCreateInfo pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; + VkPipelineVertexInputStateCreateInfo vertexInputInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; VkViewport viewport = { }; VkRect2D scissor = { }; - VkPipelineViewportStateCreateInfo viewportState = { }; - VkPipelineRasterizationStateCreateInfo rasterizer = { }; - VkPipelineMultisampleStateCreateInfo multisampling = { }; - VkPipelineColorBlendStateCreateInfo colorBlending = { }; - VkPipelineDepthStencilStateCreateInfo depthStencil = { }; - VkPipelineDynamicStateCreateInfo dynamicState = {}; + VkPipelineViewportStateCreateInfo viewportState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + VkPipelineRasterizationStateCreateInfo rasterizer = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + VkPipelineMultisampleStateCreateInfo multisampling = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + VkPipelineColorBlendStateCreateInfo colorBlending = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + VkPipelineDepthStencilStateCreateInfo depthStencil = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + VkPipelineDynamicStateCreateInfo dynamicState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + + VkPipelineLibraryCreateInfoKHR libraryCreate = { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR }; + VkGraphicsPipelineLibraryCreateInfoEXT pipelineLibrary = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; std::vector shaderStages; std::vector colorBlendAttachments; std::vector vertexInputBindings; std::vector vertexInputAttributes; std::vector dynamicStates; + std::vector libraries; struct ShaderSpecialization { diff --git a/libraries/ZVulkan/include/zvulkan/vulkaninstance.h b/libraries/ZVulkan/include/zvulkan/vulkaninstance.h index 993846a3b..e53874124 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkaninstance.h +++ b/libraries/ZVulkan/include/zvulkan/vulkaninstance.h @@ -29,6 +29,7 @@ public: VkPhysicalDeviceRayQueryFeaturesKHR RayQuery = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR }; VkPhysicalDeviceDescriptorIndexingFeatures DescriptorIndexing = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT }; VkPhysicalDeviceFaultFeaturesEXT Fault = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT }; + VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT GraphicsPipelineLibrary = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT }; }; class VulkanDeviceProperties @@ -39,6 +40,7 @@ public: VkPhysicalDeviceAccelerationStructurePropertiesKHR AccelerationStructure = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR }; VkPhysicalDeviceDescriptorIndexingProperties DescriptorIndexing = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT }; VkPhysicalDeviceLayeredDriverPropertiesMSFT LayeredDriver = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT }; + VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT GraphicsPipelineLibrary = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT }; }; class VulkanPhysicalDevice diff --git a/libraries/ZVulkan/src/vulkanbuilders.cpp b/libraries/ZVulkan/src/vulkanbuilders.cpp index dff46c0e1..684aa9769 100644 --- a/libraries/ZVulkan/src/vulkanbuilders.cpp +++ b/libraries/ZVulkan/src/vulkanbuilders.cpp @@ -892,7 +892,6 @@ ColorBlendAttachmentBuilder& ColorBlendAttachmentBuilder::BlendMode(VkBlendOp op GraphicsPipelineBuilder::GraphicsPipelineBuilder() { - pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineInfo.pVertexInputState = &vertexInputInfo; pipelineInfo.pInputAssemblyState = &inputAssembly; pipelineInfo.pViewportState = &viewportState; @@ -905,23 +904,19 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder() pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipelineInfo.basePipelineIndex = -1; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputInfo.vertexBindingDescriptionCount = 0; vertexInputInfo.pVertexBindingDescriptions = nullptr; vertexInputInfo.vertexAttributeDescriptionCount = 0; vertexInputInfo.pVertexAttributeDescriptions = nullptr; - inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; inputAssembly.primitiveRestartEnable = VK_FALSE; - viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.viewportCount = 1; viewportState.pViewports = &viewport; viewportState.scissorCount = 1; viewportState.pScissors = &scissor; - depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; depthStencil.depthBoundsTestEnable = VK_FALSE; depthStencil.minDepthBounds = 0.0f; @@ -930,7 +925,6 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder() depthStencil.front = {}; depthStencil.back = {}; - rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.depthClampEnable = VK_FALSE; rasterizer.rasterizerDiscardEnable = VK_FALSE; rasterizer.polygonMode = VK_POLYGON_MODE_FILL; @@ -942,7 +936,6 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder() rasterizer.depthBiasClamp = 0.0f; rasterizer.depthBiasSlopeFactor = 0.0f; - multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.sampleShadingEnable = VK_FALSE; multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; multisampling.minSampleShading = 1.0f; @@ -950,15 +943,30 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder() multisampling.alphaToCoverageEnable = VK_FALSE; multisampling.alphaToOneEnable = VK_FALSE; - colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.logicOpEnable = VK_FALSE; colorBlending.logicOp = VK_LOGIC_OP_COPY; colorBlending.blendConstants[0] = 0.0f; colorBlending.blendConstants[1] = 0.0f; colorBlending.blendConstants[2] = 0.0f; colorBlending.blendConstants[3] = 0.0f; +} - dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; +GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddLibrary(VulkanPipeline* pipeline) +{ + libraries.push_back(pipeline->pipeline); + return *this; +} + +GraphicsPipelineBuilder& GraphicsPipelineBuilder::Flags(VkPipelineCreateFlags flags) +{ + pipelineInfo.flags = flags; + return *this; +} + +GraphicsPipelineBuilder& GraphicsPipelineBuilder::LibraryFlags(VkGraphicsPipelineLibraryFlagsEXT flags) +{ + pipelineLibrary.flags = flags; + return *this; } GraphicsPipelineBuilder& GraphicsPipelineBuilder::RasterizationSamples(VkSampleCountFlagBits samples) @@ -1191,6 +1199,29 @@ std::unique_ptr GraphicsPipelineBuilder::Create(VulkanDevice* de colorBlending.pAttachments = colorBlendAttachments.data(); colorBlending.attachmentCount = (uint32_t)colorBlendAttachments.size(); + if (!libraries.empty()) + { + auto flags = pipelineInfo.flags; + pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; + pipelineInfo.flags = flags; + libraryCreate.libraryCount = (uint32_t)libraries.size(); + libraryCreate.pLibraries = libraries.data(); + } + + const void** ppNext = &pipelineInfo.pNext; + + if (libraryCreate.libraryCount > 0 && device->SupportsExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME)) + { + *ppNext = &libraryCreate; + ppNext = &libraryCreate.pNext; + } + + if (pipelineLibrary.flags != 0 && device->SupportsExtension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) + { + *ppNext = &pipelineLibrary; + ppNext = &pipelineLibrary.pNext; + } + VkPipeline pipeline = 0; VkResult result = vkCreateGraphicsPipelines(device->device, cache ? cache->cache : VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline); device->CheckVulkanError(result, "Could not create graphics pipeline"); @@ -1721,6 +1752,10 @@ VulkanDeviceBuilder::VulkanDeviceBuilder() // Extensions desired for debugging OptionalExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME); + + // For pipeline building + OptionalExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); + OptionalExtension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME); } VulkanDeviceBuilder& VulkanDeviceBuilder::RequireExtension(const std::string& extensionName) @@ -1823,6 +1858,7 @@ std::vector VulkanDeviceBuilder::FindDevices(const std:: enabledFeatures.DescriptorIndexing.descriptorBindingVariableDescriptorCount = deviceFeatures.DescriptorIndexing.descriptorBindingVariableDescriptorCount; enabledFeatures.DescriptorIndexing.shaderSampledImageArrayNonUniformIndexing = deviceFeatures.DescriptorIndexing.shaderSampledImageArrayNonUniformIndexing; enabledFeatures.Fault.deviceFault = deviceFeatures.Fault.deviceFault; + enabledFeatures.GraphicsPipelineLibrary.graphicsPipelineLibrary = deviceFeatures.GraphicsPipelineLibrary.graphicsPipelineLibrary; // Figure out which queue can present if (surface) diff --git a/libraries/ZVulkan/src/vulkandevice.cpp b/libraries/ZVulkan/src/vulkandevice.cpp index 28cc7a03e..fae9c700c 100644 --- a/libraries/ZVulkan/src/vulkandevice.cpp +++ b/libraries/ZVulkan/src/vulkandevice.cpp @@ -141,6 +141,11 @@ void VulkanDevice::CreateDevice() *next = &EnabledFeatures.Fault; next = &EnabledFeatures.Fault.pNext; } + if (SupportsExtension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) + { + *next = &EnabledFeatures.GraphicsPipelineLibrary; + next = &EnabledFeatures.GraphicsPipelineLibrary.pNext; + } VkResult result = vkCreateDevice(PhysicalDevice.Device, &deviceCreateInfo, nullptr, &device); CheckVulkanError(result, "Could not create vulkan device"); diff --git a/libraries/ZVulkan/src/vulkaninstance.cpp b/libraries/ZVulkan/src/vulkaninstance.cpp index b7bf300b7..e53fd355a 100644 --- a/libraries/ZVulkan/src/vulkaninstance.cpp +++ b/libraries/ZVulkan/src/vulkaninstance.cpp @@ -267,12 +267,18 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance *next = &dev.Properties.LayeredDriver; next = &dev.Properties.LayeredDriver.pNext; } + if (checkForExtension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) + { + *next = &dev.Properties.GraphicsPipelineLibrary; + next = &dev.Properties.GraphicsPipelineLibrary.pNext; + } vkGetPhysicalDeviceProperties2(dev.Device, &deviceProperties2); dev.Properties.Properties = deviceProperties2.properties; dev.Properties.AccelerationStructure.pNext = nullptr; dev.Properties.DescriptorIndexing.pNext = nullptr; dev.Properties.LayeredDriver.pNext = nullptr; + dev.Properties.GraphicsPipelineLibrary.pNext = nullptr; VkPhysicalDeviceFeatures2 deviceFeatures2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; @@ -302,6 +308,11 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance *next = &dev.Features.Fault; next = &dev.Features.Fault.pNext; } + if (checkForExtension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) + { + *next = &dev.Features.GraphicsPipelineLibrary; + next = &dev.Features.GraphicsPipelineLibrary.pNext; + } vkGetPhysicalDeviceFeatures2(dev.Device, &deviceFeatures2); dev.Features.Features = deviceFeatures2.features; @@ -310,6 +321,7 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance dev.Features.RayQuery.pNext = nullptr; dev.Features.DescriptorIndexing.pNext = nullptr; dev.Features.Fault.pNext = nullptr; + dev.Features.GraphicsPipelineLibrary.pNext = nullptr; } else {