Update ZVulkan to support graphics pipeline libraries

This commit is contained in:
dpjudas 2025-04-05 03:08:03 +02:00
commit 340a98950f
5 changed files with 81 additions and 18 deletions

View file

@ -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<VulkanPipeline> 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<VkPipelineShaderStageCreateInfo> shaderStages;
std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachments;
std::vector<VkVertexInputBindingDescription> vertexInputBindings;
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes;
std::vector<VkDynamicState> dynamicStates;
std::vector<VkPipeline> libraries;
struct ShaderSpecialization
{

View file

@ -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

View file

@ -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<VulkanPipeline> 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<VulkanCompatibleDevice> 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)

View file

@ -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");

View file

@ -267,12 +267,18 @@ std::vector<VulkanPhysicalDevice> 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<VulkanPhysicalDevice> 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<VulkanPhysicalDevice> VulkanInstance::GetPhysicalDevices(VkInstance
dev.Features.RayQuery.pNext = nullptr;
dev.Features.DescriptorIndexing.pNext = nullptr;
dev.Features.Fault.pNext = nullptr;
dev.Features.GraphicsPipelineLibrary.pNext = nullptr;
}
else
{