Add support for EXT_graphics_pipeline_library

This commit is contained in:
baldurk
2022-04-13 13:57:48 +01:00
parent a6301ef6d8
commit 20c986fc06
22 changed files with 820 additions and 112 deletions
+12 -2
View File
@@ -352,8 +352,18 @@ struct Pipeline
DOCUMENT("The :class:`ResourceId` of the pipeline object.");
ResourceId pipelineResourceId;
DOCUMENT("The :class:`ResourceId` of the pipeline layout object.");
ResourceId pipelineLayoutResourceId;
DOCUMENT("The :class:`ResourceId` of the compute pipeline layout object.");
ResourceId pipelineComputeLayoutResourceId;
DOCUMENT(R"(The :class:`ResourceId` of the pre-rasterization pipeline layout object.
When not using pipeline libraries, this will be identical to :data:`pipelineFragmentLayoutResourceId`.
)");
ResourceId pipelinePreRastLayoutResourceId;
DOCUMENT(R"(The :class:`ResourceId` of the fragment pipeline layout object.
When not using pipeline libraries, this will be identical to :data:`pipelinePreRastLayoutResourceId`.
)");
ResourceId pipelineFragmentLayoutResourceId;
DOCUMENT("The flags used to create the pipeline object.");
uint32_t flags = 0;
+1 -1
View File
@@ -51,6 +51,7 @@ Maintainers can update this file by updating vk.xml in this folder and running `
* `VK_EXT_full_screen_exclusive`
* `VK_EXT_global_priority`
* `VK_EXT_global_priority_query`
* `VK_EXT_graphics_pipeline_library`
* `VK_EXT_hdr_metadata`
* `VK_EXT_headless_surface`
* `VK_EXT_host_query_reset`
@@ -236,7 +237,6 @@ Ray tracing extensions are now standard and will likely be supported at some poi
* `VK_EXT_image_drm_format_modifier`
* `VK_EXT_image_view_min_lod`
* `VK_EXT_multi_draw`
* `VK_EXT_graphics_pipeline_library`
* `VK_EXT_pageable_device_local_memory`
* `VK_EXT_physical_device_drm`
* `VK_EXT_primitive_topology_list_restart`
+8
View File
@@ -888,6 +888,7 @@ DECLARE_REFLECTION_STRUCT(VkFramebufferAttachmentImageInfo);
DECLARE_REFLECTION_STRUCT(VkFramebufferAttachmentsCreateInfo);
DECLARE_REFLECTION_STRUCT(VkFramebufferCreateInfo);
DECLARE_REFLECTION_STRUCT(VkGraphicsPipelineCreateInfo);
DECLARE_REFLECTION_STRUCT(VkGraphicsPipelineLibraryCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkHdrMetadataEXT);
DECLARE_REFLECTION_STRUCT(VkImageBlit2);
DECLARE_REFLECTION_STRUCT(VkImageCopy2);
@@ -965,6 +966,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGroupProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceHostQueryResetFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShadingRateKHR);
@@ -1263,6 +1266,7 @@ DECLARE_DESERIALISE_TYPE(VkFramebufferAttachmentImageInfo);
DECLARE_DESERIALISE_TYPE(VkFramebufferAttachmentsCreateInfo);
DECLARE_DESERIALISE_TYPE(VkFramebufferCreateInfo);
DECLARE_DESERIALISE_TYPE(VkGraphicsPipelineCreateInfo);
DECLARE_DESERIALISE_TYPE(VkGraphicsPipelineLibraryCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkImageBlit2);
DECLARE_DESERIALISE_TYPE(VkImageCopy2);
DECLARE_DESERIALISE_TYPE(VkImageCreateInfo);
@@ -1336,6 +1340,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM)
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGroupProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateKHR);
@@ -1754,6 +1760,7 @@ DECLARE_REFLECTION_ENUM(VkFormatFeatureFlagBits);
DECLARE_REFLECTION_ENUM(VkFormatFeatureFlagBits2);
DECLARE_REFLECTION_ENUM(VkFragmentShadingRateCombinerOpKHR);
DECLARE_REFLECTION_ENUM(VkFramebufferCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkGraphicsPipelineLibraryFlagBitsEXT);
DECLARE_REFLECTION_ENUM(VkFrontFace);
DECLARE_REFLECTION_ENUM(VkImageAspectFlagBits);
DECLARE_REFLECTION_ENUM(VkImageCreateFlagBits);
@@ -1769,6 +1776,7 @@ DECLARE_REFLECTION_ENUM(VkLogicOp);
DECLARE_REFLECTION_ENUM(VkMemoryAllocateFlagBits);
DECLARE_REFLECTION_ENUM(VkMemoryHeapFlagBits);
DECLARE_REFLECTION_ENUM(VkMemoryPropertyFlagBits);
DECLARE_REFLECTION_ENUM(VkObjectType);
DECLARE_REFLECTION_ENUM(VkPerformanceCounterDescriptionFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkPerformanceCounterScopeKHR);
DECLARE_REFLECTION_ENUM(VkPerformanceCounterStorageKHR);
+4 -1
View File
@@ -956,6 +956,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME, VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION,
},
{
VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION,
},
{
VK_EXT_HDR_METADATA_EXTENSION_NAME, VK_EXT_HDR_METADATA_SPEC_VERSION,
},
@@ -4554,7 +4557,7 @@ void WrappedVulkan::AddUsage(VulkanActionTreeNode &actionNode, rdcarray<DebugMes
int32_t bindset = types[t].bindmap[i].bindset;
int32_t bind = types[t].bindmap[i].bind;
if(bindset >= (int32_t)descSets.size())
if(bindset >= (int32_t)descSets.size() || descSets[bindset].descSet == ResourceId())
{
msg.description =
StringFormat::Fmt("Shader referenced a descriptor set %i that was not bound", bindset);
+16 -9
View File
@@ -2416,16 +2416,13 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
poolSizes[newBindings[i].descriptorType].descriptorCount += newBindings[i].descriptorCount;
}
const rdcarray<ResourceId> &pipeDescSetLayouts =
creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts;
// need to add our added bindings to the first descriptor set
rdcarray<VkDescriptorSetLayoutBinding> bindings(newBindings, newBindingsCount);
// if there are fewer sets bound than were declared in the pipeline layout, only process the
// bound sets (as otherwise we'd fail to copy from them). Assume the application knew what it
// was doing and the other sets are statically unused.
setLayouts.resize(RDCMIN(pipe.descSets.size(), pipeDescSetLayouts.size()));
setLayouts.resize(RDCMIN(pipe.descSets.size(), pipeInfo.descSetLayouts.size()));
size_t boundDescs = setLayouts.size();
@@ -2572,9 +2569,15 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
// if the shader had no descriptor sets at all, i will be invalid, so just skip and add a set
// with only our own bindings.
if(i < pipeDescSetLayouts.size() && i < pipe.descSets.size() &&
if(i < pipeInfo.descSetLayouts.size() && i < pipe.descSets.size() &&
pipe.descSets[i].pipeLayout != ResourceId())
{
const VulkanCreationInfo::PipelineLayout &pipelineLayoutInfo =
creationInfo.m_PipelineLayout[pipe.descSets[i].pipeLayout];
if(pipelineLayoutInfo.descSetLayouts[i] == ResourceId())
continue;
// use the descriptor set layout from when it was bound. If the pipeline layout declared a
// descriptor set layout for this set, but it's statically unused, it may be complete
// garbage and doesn't match what the shader uses. However the pipeline layout at descriptor
@@ -2582,8 +2585,7 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
// then the pipeline layout at bind time must be compatible with the pipeline's pipeline
// layout, so we're fine too.
const DescSetLayout &origLayout =
creationInfo.m_DescSetLayout[creationInfo.m_PipelineLayout[pipe.descSets[i].pipeLayout]
.descSetLayouts[i]];
creationInfo.m_DescSetLayout[pipelineLayoutInfo.descSetLayouts[i]];
WrappedVulkan::DescriptorSetInfo &setInfo =
m_pDriver->m_DescriptorSetState[pipe.descSets[i].descSet];
@@ -2768,13 +2770,18 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
if(pipe.descSets[i].descSet == ResourceId())
continue;
const VulkanCreationInfo::PipelineLayout &pipelineLayoutInfo =
creationInfo.m_PipelineLayout[pipe.descSets[i].pipeLayout];
if(pipelineLayoutInfo.descSetLayouts[i] == ResourceId())
continue;
// as above we use the pipeline layout that was originally used to bind this descriptor set
// and not the pipeline layout from the pipeline, in case the pipeline statically doesn't use
// this set and so its descriptor set layout is garbage (doesn't match the actual bound
// descriptor set)
const DescSetLayout &origLayout =
creationInfo.m_DescSetLayout[creationInfo.m_PipelineLayout[pipe.descSets[i].pipeLayout]
.descSetLayouts[i]];
creationInfo.m_DescSetLayout[pipelineLayoutInfo.descSetLayouts[i]];
WrappedVulkan::DescriptorSetInfo &setInfo =
m_pDriver->m_DescriptorSetState[pipe.descSets[i].descSet];
+314 -15
View File
@@ -133,6 +133,67 @@ VulkanDynamicStateIndex ConvertDynamicState(VkDynamicState state)
return VkDynamicCount;
}
static VkGraphicsPipelineLibraryFlagsEXT DynamicStateValidState(VkDynamicState state)
{
const VkGraphicsPipelineLibraryFlagsEXT vinput =
VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
const VkGraphicsPipelineLibraryFlagsEXT vert =
VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
const VkGraphicsPipelineLibraryFlagsEXT frag = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
const VkGraphicsPipelineLibraryFlagsEXT colout =
VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
switch(state)
{
case VK_DYNAMIC_STATE_VIEWPORT: return vert;
case VK_DYNAMIC_STATE_SCISSOR: return vert;
case VK_DYNAMIC_STATE_LINE_WIDTH: return frag;
case VK_DYNAMIC_STATE_DEPTH_BIAS: return frag;
case VK_DYNAMIC_STATE_BLEND_CONSTANTS: return colout;
case VK_DYNAMIC_STATE_DEPTH_BOUNDS: return frag;
case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: return frag;
case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: return frag;
case VK_DYNAMIC_STATE_STENCIL_REFERENCE: return frag;
case VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV: return vert;
case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT: return vert;
case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: return frag | colout;
case VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR:
return (VkGraphicsPipelineLibraryFlagsEXT)0;
case VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV: return vert;
case VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV: return vert;
case VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV: return vert;
case VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR: return vert | frag;
case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: return vert;
case VK_DYNAMIC_STATE_CULL_MODE: return vert;
case VK_DYNAMIC_STATE_FRONT_FACE: return vert;
case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY: return vinput;
case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: return vert;
case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: return vert;
case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE: return vinput;
case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE: return frag;
case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE: return frag;
case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP: return frag;
case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE: return frag;
case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE: return frag;
case VK_DYNAMIC_STATE_STENCIL_OP: return frag;
case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT: return vinput;
case VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT: return vert;
case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE: return vert;
case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE: return frag;
case VK_DYNAMIC_STATE_LOGIC_OP_EXT: return colout;
case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE: return vinput;
case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT: return colout;
case VK_DYNAMIC_STATE_MAX_ENUM: break;
}
RDCERR("Unexpected vulkan state %u", state);
return VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
}
void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
{
@@ -142,6 +203,8 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
flags = pCreateInfo->flags;
anyStageFlags = 0;
VkDescriptorSetLayoutBindingFlagsCreateInfo *bindingFlags =
(VkDescriptorSetLayoutBindingFlagsCreateInfo *)FindNextStruct(
pCreateInfo, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO);
@@ -165,6 +228,8 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
bindings[b].descriptorType = pCreateInfo->pBindings[i].descriptorType;
bindings[b].stageFlags = pCreateInfo->pBindings[i].stageFlags;
anyStageFlags |= bindings[b].stageFlags;
if(bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
dynamicCount++;
@@ -361,7 +426,21 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
graphicsPipe = true;
layout = GetResID(pCreateInfo->layout);
// this is used to e.g. filter specified dynamic states so we only consider the ones valid for
// this pipeline. If we're not using libraries, all states are valid
VkGraphicsPipelineLibraryFlagsEXT availStages =
VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
const VkGraphicsPipelineLibraryCreateInfoEXT *graphicsLibraryCreate =
(const VkGraphicsPipelineLibraryCreateInfoEXT *)FindNextStruct(
pCreateInfo, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
if(graphicsLibraryCreate)
availStages = libraryFlags = graphicsLibraryCreate->flags;
vertLayout = fragLayout = GetResID(pCreateInfo->layout);
renderpass = GetResID(pCreateInfo->renderPass);
subpass = pCreateInfo->subpass;
@@ -388,7 +467,16 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
if(pCreateInfo->pDynamicState)
{
for(uint32_t i = 0; i < pCreateInfo->pDynamicState->dynamicStateCount; i++)
dynamicStates[ConvertDynamicState(pCreateInfo->pDynamicState->pDynamicStates[i])] = true;
{
VkDynamicState d = pCreateInfo->pDynamicState->pDynamicStates[i];
// ignore dynamic states not available for this library (e.g.
// VK_DYNAMIC_STATE_VERTEX_INPUT_EXT in a library with only FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)
if((DynamicStateValidState(d) & availStages) == 0)
continue;
dynamicStates[ConvertDynamicState(d)] = true;
}
// if the viewports and counts are dynamic this supersets the viewport only being dynamic. For
// ease of code elsewhere, turn off the older one if both are specified so that we don't call
@@ -486,8 +574,16 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
}
}
topology = pCreateInfo->pInputAssemblyState->topology;
primitiveRestartEnable = pCreateInfo->pInputAssemblyState->primitiveRestartEnable ? true : false;
if(pCreateInfo->pInputAssemblyState)
{
topology = pCreateInfo->pInputAssemblyState->topology;
primitiveRestartEnable = pCreateInfo->pInputAssemblyState->primitiveRestartEnable ? true : false;
}
else
{
topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
primitiveRestartEnable = false;
}
if(pCreateInfo->pTessellationState)
patchControlPoints = pCreateInfo->pTessellationState->patchControlPoints;
@@ -553,16 +649,33 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
}
// VkPipelineRasterStateCreateInfo
depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false;
rasterizerDiscardEnable = pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false;
polygonMode = pCreateInfo->pRasterizationState->polygonMode;
cullMode = pCreateInfo->pRasterizationState->cullMode;
frontFace = pCreateInfo->pRasterizationState->frontFace;
depthBiasEnable = pCreateInfo->pRasterizationState->depthBiasEnable ? true : false;
depthBiasConstantFactor = pCreateInfo->pRasterizationState->depthBiasConstantFactor;
depthBiasClamp = pCreateInfo->pRasterizationState->depthBiasClamp;
depthBiasSlopeFactor = pCreateInfo->pRasterizationState->depthBiasSlopeFactor;
lineWidth = pCreateInfo->pRasterizationState->lineWidth;
if(pCreateInfo->pRasterizationState)
{
depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false;
rasterizerDiscardEnable =
pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false;
polygonMode = pCreateInfo->pRasterizationState->polygonMode;
cullMode = pCreateInfo->pRasterizationState->cullMode;
frontFace = pCreateInfo->pRasterizationState->frontFace;
depthBiasEnable = pCreateInfo->pRasterizationState->depthBiasEnable ? true : false;
depthBiasConstantFactor = pCreateInfo->pRasterizationState->depthBiasConstantFactor;
depthBiasClamp = pCreateInfo->pRasterizationState->depthBiasClamp;
depthBiasSlopeFactor = pCreateInfo->pRasterizationState->depthBiasSlopeFactor;
lineWidth = pCreateInfo->pRasterizationState->lineWidth;
}
else
{
depthClampEnable = false;
rasterizerDiscardEnable = false;
polygonMode = VK_POLYGON_MODE_FILL;
cullMode = VK_CULL_MODE_NONE;
frontFace = VK_FRONT_FACE_CLOCKWISE;
depthBiasEnable = false;
depthBiasConstantFactor = 0.0f;
depthBiasClamp = 0.0f;
depthBiasSlopeFactor = 0.0f;
lineWidth = 1.0f;
}
// VkPipelineRasterizationStateStreamCreateInfoEXT
rasterizationStream = 0;
@@ -752,6 +865,188 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
attachments[i].channelWriteMask = 0;
}
}
const VkPipelineLibraryCreateInfoKHR *libraryReference =
(const VkPipelineLibraryCreateInfoKHR *)FindNextStruct(
pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR);
if(libraryReference)
{
// unconditionally pull in state from libraries - the state must not overlap (or must be
// identical where overlap is inevitable)
for(uint32_t l = 0; l < libraryReference->libraryCount; l++)
{
ResourceId pipeid = GetResID(libraryReference->pLibraries[l]);
parentLibraries.push_back(pipeid);
const Pipeline &pipeInfo = info.m_Pipeline[pipeid];
for(size_t i = 0; i < VkDynamicCount; i++)
dynamicStates[i] |= pipeInfo.dynamicStates[i];
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT)
{
vertexBindings = pipeInfo.vertexBindings;
vertexAttrs = pipeInfo.vertexAttrs;
topology = pipeInfo.topology;
primitiveRestartEnable = pipeInfo.primitiveRestartEnable;
}
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT)
{
renderpass = pipeInfo.renderpass;
subpass = pipeInfo.subpass;
for(uint32_t i = 0; i < 5; i++)
shaders[i] = pipeInfo.shaders[i];
vertLayout = pipeInfo.vertLayout;
viewportCount = pipeInfo.viewportCount;
viewports = pipeInfo.viewports;
scissors = pipeInfo.scissors;
depthClampEnable = pipeInfo.depthClampEnable;
rasterizerDiscardEnable = pipeInfo.rasterizerDiscardEnable;
polygonMode = pipeInfo.polygonMode;
cullMode = pipeInfo.cullMode;
frontFace = pipeInfo.frontFace;
depthBiasEnable = pipeInfo.depthBiasEnable;
depthBiasConstantFactor = pipeInfo.depthBiasConstantFactor;
depthBiasClamp = pipeInfo.depthBiasClamp;
depthBiasSlopeFactor = pipeInfo.depthBiasSlopeFactor;
lineWidth = pipeInfo.lineWidth;
rasterizationStream = pipeInfo.rasterizationStream;
depthClipEnable = pipeInfo.depthClipEnable;
patchControlPoints = pipeInfo.patchControlPoints;
tessellationDomainOrigin = pipeInfo.tessellationDomainOrigin;
conservativeRasterizationMode = pipeInfo.conservativeRasterizationMode;
extraPrimitiveOverestimationSize = pipeInfo.extraPrimitiveOverestimationSize;
lineRasterMode = pipeInfo.lineRasterMode;
stippleEnabled = pipeInfo.stippleEnabled;
stippleFactor = pipeInfo.stippleFactor;
stipplePattern = pipeInfo.stipplePattern;
discardRectangles = pipeInfo.discardRectangles;
discardMode = pipeInfo.discardMode;
}
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)
{
renderpass = pipeInfo.renderpass;
subpass = pipeInfo.subpass;
shaders[4] = pipeInfo.shaders[4];
fragLayout = pipeInfo.fragLayout;
rasterizationSamples = pipeInfo.rasterizationSamples;
sampleShadingEnable = pipeInfo.sampleShadingEnable;
minSampleShading = pipeInfo.minSampleShading;
sampleMask = pipeInfo.sampleMask;
alphaToCoverageEnable = pipeInfo.alphaToCoverageEnable;
alphaToOneEnable = pipeInfo.alphaToOneEnable;
sampleLocations = pipeInfo.sampleLocations;
depthTestEnable = pipeInfo.depthTestEnable;
depthWriteEnable = pipeInfo.depthWriteEnable;
depthCompareOp = pipeInfo.depthCompareOp;
depthBoundsEnable = pipeInfo.depthBoundsEnable;
stencilTestEnable = pipeInfo.stencilTestEnable;
front = pipeInfo.front;
back = pipeInfo.back;
minDepthBounds = pipeInfo.minDepthBounds;
maxDepthBounds = pipeInfo.maxDepthBounds;
}
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)
{
renderpass = pipeInfo.renderpass;
subpass = pipeInfo.subpass;
rasterizationSamples = pipeInfo.rasterizationSamples;
sampleShadingEnable = pipeInfo.sampleShadingEnable;
minSampleShading = pipeInfo.minSampleShading;
sampleMask = pipeInfo.sampleMask;
alphaToCoverageEnable = pipeInfo.alphaToCoverageEnable;
alphaToOneEnable = pipeInfo.alphaToOneEnable;
logicOpEnable = pipeInfo.logicOpEnable;
logicOp = pipeInfo.logicOp;
memcpy(blendConst, pipeInfo.blendConst, sizeof(blendConst));
attachments = pipeInfo.attachments;
viewMask = pipeInfo.viewMask;
colorFormats = pipeInfo.colorFormats;
depthFormat = pipeInfo.depthFormat;
stencilFormat = pipeInfo.stencilFormat;
}
}
}
// calculate descSetLayouts. If only one layout is set, just copy the layouts from it
if(vertLayout == ResourceId())
{
descSetLayouts = info.m_PipelineLayout[fragLayout].descSetLayouts;
}
else if(fragLayout == ResourceId())
{
descSetLayouts = info.m_PipelineLayout[vertLayout].descSetLayouts;
}
// if they're both the same (both must be non-empty or we would have hit a case above) it doesn't
// matter
else if(vertLayout == fragLayout)
{
descSetLayouts = info.m_PipelineLayout[vertLayout].descSetLayouts;
}
else
{
// in this case vertLayout is not the same as fragLayout, so we have independent sets and this
// is the linked pipeline
// fortunately one of the requirements of independent set is that any descriptor sets which
// contain any fragment visible descriptors are present in the fragment layout, and vice-versa
// for non-fragment. Any sets which contain both must be identical in both.
// That means we can start by picking all the set layouts from the fragment pipeline layout that
// reference fragments (ignoring any others that may be empty or not but are ignored), then for
// all other sets unconditionally pick the one from the vertex layout
const rdcarray<ResourceId> &vSets = info.m_PipelineLayout[vertLayout].descSetLayouts;
const rdcarray<ResourceId> &fSets = info.m_PipelineLayout[fragLayout].descSetLayouts;
descSetLayouts.resize(RDCMAX(vSets.size(), fSets.size()));
for(size_t i = 0; i < fSets.size(); i++)
{
if((info.m_DescSetLayout[fSets[i]].anyStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) != 0)
descSetLayouts[i] = fSets[i];
}
for(size_t i = 0; i < vSets.size(); i++)
{
if(descSetLayouts[i] == ResourceId())
descSetLayouts[i] = vSets[i];
}
// it's possible we have sets which are unused by both - maybe empty, dummy, or they only appear
// in the layout which ignores them. Pick from whichever layout contained that element as it
// doesn't matter.
for(size_t i = 0; i < descSetLayouts.size(); i++)
{
if(descSetLayouts[i] == ResourceId())
{
if(i < vSets.size())
descSetLayouts[i] = vSets[i];
else
descSetLayouts[i] = fSets[i];
}
}
}
}
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
@@ -761,7 +1056,9 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
graphicsPipe = false;
layout = GetResID(pCreateInfo->layout);
compLayout = GetResID(pCreateInfo->layout);
descSetLayouts = info.m_PipelineLayout[compLayout].descSetLayouts;
// need to figure out which states are valid to be NULL
@@ -847,6 +1144,8 @@ void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan
VulkanCreationInfo &info,
const VkPipelineLayoutCreateInfo *pCreateInfo)
{
flags = pCreateInfo->flags;
if(pCreateInfo->pSetLayouts)
{
descSetLayouts.resize(pCreateInfo->setLayoutCount);
+24 -1
View File
@@ -160,6 +160,9 @@ struct DescSetLayout
uint32_t inlineCount;
uint32_t inlineByteSize;
// the cummulative stageFlags for all bindings in this layout
VkShaderStageFlags anyStageFlags;
bool operator==(const DescSetLayout &other) const;
bool operator!=(const DescSetLayout &other) const { return !(*this == other); }
};
@@ -254,7 +257,26 @@ struct VulkanCreationInfo
bool graphicsPipe = false;
ResourceId layout;
// VkGraphicsPipelineLibraryCreateInfoEXT
VkGraphicsPipelineLibraryFlagsEXT libraryFlags;
rdcarray<ResourceId> parentLibraries;
ResourceId compLayout;
// these will be the same in some cases, but can be different if the application is using
// INDEPENDENT_SETS_BIT_KHR
ResourceId vertLayout;
ResourceId fragLayout;
// this is the list of descriptor set layouts for a 'complete' pipeline.
// when vertLayout == fragLayout (i.e. no independent sets), for compute pipelines, or if only
// one is set, then this will be trivially equal to the set of layouts in the pipeline layout.
// when they are different and both non-empty, it will be the list of descriptor sets
// cherry-picked from each. Specifically all of the descriptor sets that have fragment shader
// bindings taken from the fragment layout, and then all of the remaining sets from the vertex
// layout
rdcarray<ResourceId> descSetLayouts;
ResourceId renderpass;
uint32_t subpass;
@@ -415,6 +437,7 @@ struct VulkanCreationInfo
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
const VkPipelineLayoutCreateInfo *pCreateInfo);
VkPipelineLayoutCreateFlags flags;
rdcarray<VkPushConstantRange> pushRanges;
rdcarray<ResourceId> descSetLayouts;
};
+51 -21
View File
@@ -168,6 +168,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkFragmentShadingRateAttachmentInfoKHR); \
COPY_STRUCT(VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, VkFormatProperties2); \
COPY_STRUCT(VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, VkFormatProperties3); \
COPY_STRUCT(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, \
VkGraphicsPipelineLibraryCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_HDR_METADATA_EXT, VkHdrMetadataEXT) \
COPY_STRUCT(VK_STRUCTURE_TYPE_IMAGE_BLIT_2, VkImageBlit2); \
COPY_STRUCT(VK_STRUCTURE_TYPE_IMAGE_COPY_2, VkImageCopy2); \
@@ -254,6 +256,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, \
VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, \
VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT, \
VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, VkPhysicalDeviceGroupProperties) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, \
VkPhysicalDeviceShaderFloat16Int8Features); \
@@ -742,7 +748,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_GEOMETRY_NV: \
case VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV: \
case VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA: \
@@ -791,8 +796,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT: \
@@ -1076,24 +1079,51 @@ size_t GetNextPatchSize(const void *pNext)
memSize += GetNextPatchSize(info->pStages[s].pNext);
// need to copy the base struct of each of these so we can potentially patch pNext inside it
memSize += sizeof(*info->pVertexInputState);
memSize += GetNextPatchSize(info->pVertexInputState->pNext);
memSize += sizeof(*info->pInputAssemblyState);
memSize += GetNextPatchSize(info->pInputAssemblyState->pNext);
memSize += sizeof(*info->pTessellationState);
memSize += GetNextPatchSize(info->pTessellationState->pNext);
memSize += sizeof(*info->pViewportState);
memSize += GetNextPatchSize(info->pViewportState->pNext);
memSize += sizeof(*info->pRasterizationState);
memSize += GetNextPatchSize(info->pRasterizationState->pNext);
memSize += sizeof(*info->pMultisampleState);
memSize += GetNextPatchSize(info->pMultisampleState->pNext);
memSize += sizeof(*info->pDepthStencilState);
memSize += GetNextPatchSize(info->pDepthStencilState->pNext);
memSize += sizeof(*info->pColorBlendState);
memSize += GetNextPatchSize(info->pColorBlendState->pNext);
memSize += sizeof(*info->pDynamicState);
memSize += GetNextPatchSize(info->pDynamicState->pNext);
if(info->pVertexInputState)
{
memSize += sizeof(*info->pVertexInputState);
memSize += GetNextPatchSize(info->pVertexInputState->pNext);
}
if(info->pInputAssemblyState)
{
memSize += sizeof(*info->pInputAssemblyState);
memSize += GetNextPatchSize(info->pInputAssemblyState->pNext);
}
if(info->pTessellationState)
{
memSize += sizeof(*info->pTessellationState);
memSize += GetNextPatchSize(info->pTessellationState->pNext);
}
if(info->pViewportState)
{
memSize += sizeof(*info->pViewportState);
memSize += GetNextPatchSize(info->pViewportState->pNext);
}
if(info->pRasterizationState)
{
memSize += sizeof(*info->pRasterizationState);
memSize += GetNextPatchSize(info->pRasterizationState->pNext);
}
if(info->pMultisampleState)
{
memSize += sizeof(*info->pMultisampleState);
memSize += GetNextPatchSize(info->pMultisampleState->pNext);
}
if(info->pDepthStencilState)
{
memSize += sizeof(*info->pDepthStencilState);
memSize += GetNextPatchSize(info->pDepthStencilState->pNext);
}
if(info->pColorBlendState)
{
memSize += sizeof(*info->pColorBlendState);
memSize += GetNextPatchSize(info->pColorBlendState->pNext);
}
if(info->pDynamicState)
{
memSize += sizeof(*info->pDynamicState);
memSize += GetNextPatchSize(info->pDynamicState->pNext);
}
break;
}
case VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO:
+4 -4
View File
@@ -85,20 +85,20 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
VkDescriptorSetLayout *descSetLayouts;
// descSet will be the index of our new descriptor set
uint32_t descSet =
(uint32_t)m_pDriver->GetDebugManager()->GetPipelineLayoutInfo(p.layout).descSetLayouts.size();
uint32_t descSet = (uint32_t)p.descSetLayouts.size();
descSetLayouts = new VkDescriptorSetLayout[descSet + 1];
for(uint32_t i = 0; i < descSet; i++)
descSetLayouts[i] = m_pDriver->GetResourceManager()->GetCurrentHandle<VkDescriptorSetLayout>(
m_pDriver->GetDebugManager()->GetPipelineLayoutInfo(p.layout).descSetLayouts[i]);
p.descSetLayouts[i]);
// this layout has storage image and
descSetLayouts[descSet] = m_DescSetLayout;
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
const rdcarray<VkPushConstantRange> &push =
m_pDriver->GetDebugManager()->GetPipelineLayoutInfo(p.layout).pushRanges;
m_pDriver->GetDebugManager()->GetPipelineLayoutInfo(p.vertLayout).pushRanges;
VkPipelineLayoutCreateInfo pipeLayoutInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+4 -2
View File
@@ -1585,7 +1585,8 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state)
// VERTEX_BIT. Find it, and make it COMPUTE_BIT
VkPushConstantRange push;
uint32_t numPush = 0;
rdcarray<VkPushConstantRange> oldPush = creationInfo.m_PipelineLayout[pipeInfo.layout].pushRanges;
rdcarray<VkPushConstantRange> oldPush =
creationInfo.m_PipelineLayout[pipeInfo.vertLayout].pushRanges;
// ensure the push range is visible to the compute shader
for(const VkPushConstantRange &range : oldPush)
@@ -1632,7 +1633,8 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state)
// To get around this we patch descriptor set layouts at create time so that COMPUTE_BIT is
// present wherever VERTEX_BIT was, so we can use the application's descriptor sets and layouts
const rdcarray<ResourceId> &sets = creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts;
const rdcarray<ResourceId> &sets =
creationInfo.m_PipelineLayout[pipeInfo.vertLayout].descSetLayouts;
setLayouts.reserve(sets.size());
+19 -10
View File
@@ -1096,9 +1096,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
{
const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.compute.pipeline];
ret.compute.pipelineLayoutResourceId = rm->GetOriginalID(p.layout);
const VulkanCreationInfo::PipelineLayout &pl = c.m_PipelineLayout[p.layout];
ret.compute.pipelineComputeLayoutResourceId = rm->GetOriginalID(p.compLayout);
ret.compute.flags = p.flags;
@@ -1116,7 +1114,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
stage.reflection = p.shaders[i].refl;
stage.pushConstantRangeByteOffset = stage.pushConstantRangeByteSize = 0;
for(const VkPushConstantRange &pr : pl.pushRanges)
for(const VkPushConstantRange &pr : c.m_PipelineLayout[p.compLayout].pushRanges)
{
if(pr.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
{
@@ -1166,7 +1164,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
}
else
{
ret.compute.pipelineLayoutResourceId = ResourceId();
ret.compute.pipelineComputeLayoutResourceId = ResourceId();
ret.compute.flags = 0;
ret.computeShader = VKPipe::Shader();
}
@@ -1175,9 +1173,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
{
const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.graphics.pipeline];
ret.graphics.pipelineLayoutResourceId = rm->GetOriginalID(p.layout);
const VulkanCreationInfo::PipelineLayout &pl = c.m_PipelineLayout[p.layout];
ret.graphics.pipelinePreRastLayoutResourceId = rm->GetOriginalID(p.vertLayout);
ret.graphics.pipelineFragmentLayoutResourceId = rm->GetOriginalID(p.fragLayout);
ret.graphics.flags = p.flags;
@@ -1235,7 +1232,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
stages[i]->reflection = p.shaders[i].refl;
stages[i]->pushConstantRangeByteOffset = stages[i]->pushConstantRangeByteSize = 0;
for(const VkPushConstantRange &pr : pl.pushRanges)
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
for(const VkPushConstantRange &pr : c.m_PipelineLayout[p.vertLayout].pushRanges)
{
if(pr.stageFlags & ShaderMaskFromIndex(i))
{
@@ -1543,7 +1541,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
}
else
{
ret.graphics.pipelineLayoutResourceId = ResourceId();
ret.graphics.pipelinePreRastLayoutResourceId = ResourceId();
ret.graphics.pipelineFragmentLayoutResourceId = ResourceId();
ret.graphics.flags = 0;
@@ -1901,6 +1900,16 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
const uint32_t *srcOffset = (*srcs[p])[i].offsets.begin();
VKPipe::DescriptorSet &dst = (*dsts[p])[i];
if(src == ResourceId())
{
dst.inlineData.clear();
dst.descriptorSetResourceId = ResourceId();
dst.pushDescriptor = false;
dst.layoutResourceId = ResourceId();
dst.bindings.clear();
continue;
}
dst.inlineData = m_pDriver->m_DescriptorSetState[src].data.inlineBytes;
curBind.bindset = (uint32_t)i;
+107 -12
View File
@@ -163,6 +163,7 @@ DECL_VKFLAG(VkSubmit);
DECL_VKFLAG_EXT(VkPipelineStage, 2);
DECL_VKFLAG_EXT(VkAccess, 2);
DECL_VKFLAG_EXT(VkFormatFeature, 2);
DECL_VKFLAG_EXT(VkGraphicsPipelineLibrary, EXT);
DECL_VKFLAG(VkRendering);
// serialise a member as flags - cast to the Bits enum for serialisation so the stringification
@@ -678,6 +679,14 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, \
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT) \
\
/* VK_EXT_graphics_pipeline_library */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, \
VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT, \
VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, \
VkGraphicsPipelineLibraryCreateInfoEXT) \
\
/* VK_EXT_hdr_metadata */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_HDR_METADATA_EXT, VkHdrMetadataEXT) \
\
@@ -1354,11 +1363,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT) \
\
/* VK_EXT_graphics_pipeline_library */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT) \
\
/* VK_EXT_multi_draw */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT) \
@@ -1801,10 +1805,13 @@ void DoSerialise(SerialiserType &ser, VkDebugMarkerObjectTagInfoEXT &el)
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDebugUtilsObjectNameInfoEXT &el)
{
RDCERR("Serialising VkDebugUtilsObjectNameInfoEXT - this should be handled specially");
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(objectType);
// can't handle it here without duplicating objectType logic
RDCEraseEl(el);
el.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
SERIALISE_MEMBER_EMPTY(objectHandle);
SERIALISE_MEMBER(pObjectName).Important();
}
template <>
@@ -3197,7 +3204,7 @@ void DoSerialise(SerialiserType &ser, VkGraphicsPipelineCreateInfo &el)
// present.
// this bool just means "we can use SERIALISE_MEMBER_OPT" - i.e. the struct is present, or NULL.
const bool hasValidRasterization =
bool hasValidRasterization =
ser.IsReading() || (ser.IsWriting() && el.pRasterizationState &&
el.pRasterizationState->rasterizerDiscardEnable == VK_FALSE);
@@ -3240,16 +3247,52 @@ void DoSerialise(SerialiserType &ser, VkGraphicsPipelineCreateInfo &el)
SERIALISE_MEMBER_OPT(pRasterizationState);
if(hasValidRasterization)
bool forceMSAAState = false;
bool forceDepthState = false;
bool forceBlendState = false;
const VkGraphicsPipelineLibraryCreateInfoEXT *graphicsLibraryCreate =
(const VkGraphicsPipelineLibraryCreateInfoEXT *)FindNextStruct(
&el, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
if(graphicsLibraryCreate)
{
if(graphicsLibraryCreate->flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)
{
forceMSAAState = true;
forceDepthState = true;
}
if(graphicsLibraryCreate->flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)
{
forceMSAAState = true;
forceBlendState = true;
}
}
if(hasValidRasterization || forceMSAAState)
{
SERIALISE_MEMBER_OPT(pMultisampleState);
SERIALISE_MEMBER_OPT(pDepthStencilState);
SERIALISE_MEMBER_OPT(pColorBlendState);
}
else
{
SERIALISE_MEMBER_OPT_EMPTY(pMultisampleState);
}
if(hasValidRasterization || forceDepthState)
{
SERIALISE_MEMBER_OPT(pDepthStencilState);
}
else
{
SERIALISE_MEMBER_OPT_EMPTY(pDepthStencilState);
}
if(hasValidRasterization || forceBlendState)
{
SERIALISE_MEMBER_OPT(pColorBlendState);
}
else
{
SERIALISE_MEMBER_OPT_EMPTY(pColorBlendState);
}
@@ -6088,6 +6131,55 @@ void Deserialise(const VkDisplayNativeHdrSurfaceCapabilitiesAMD &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(graphicsPipelineLibrary);
}
template <>
void Deserialise(const VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(graphicsPipelineLibraryFastLinking);
SERIALISE_MEMBER(graphicsPipelineLibraryIndependentInterpolationDecoration);
}
template <>
void Deserialise(const VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkGraphicsPipelineLibraryCreateInfoEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_VKFLAGS(VkGraphicsPipelineLibraryFlagsEXT, flags);
}
template <>
void Deserialise(const VkGraphicsPipelineLibraryCreateInfoEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkImageFormatListCreateInfo &el)
{
@@ -10309,6 +10401,7 @@ INSTANTIATE_SERIALISE_TYPE(VkFramebufferAttachmentImageInfo);
INSTANTIATE_SERIALISE_TYPE(VkFramebufferAttachmentsCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkFramebufferCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkGraphicsPipelineCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkGraphicsPipelineLibraryCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkHdrMetadataEXT);
INSTANTIATE_SERIALISE_TYPE(VkImageBlit2);
INSTANTIATE_SERIALISE_TYPE(VkImageCopy2);
@@ -10386,6 +10479,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCO
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGroupProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeatures);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateKHR);
+40 -2
View File
@@ -869,13 +869,51 @@ void VulkanShaderCache::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &p
&ds,
&cb,
&dyn,
rm->GetCurrentHandle<VkPipelineLayout>(pipeInfo.layout),
VK_NULL_HANDLE,
rm->GetCurrentHandle<VkRenderPass>(pipeInfo.renderpass),
pipeInfo.subpass,
VK_NULL_HANDLE, // base pipeline handle
0, // base pipeline index
};
// if the layouts are the same object (non-library case) we can just use it directly
if(pipeInfo.vertLayout == pipeInfo.fragLayout)
{
ret.layout = rm->GetCurrentHandle<VkPipelineLayout>(pipeInfo.vertLayout);
}
else
{
ret.layout = m_CombinedPipeLayouts[pipeline];
if(ret.layout == VK_NULL_HANDLE)
{
rdcarray<VkDescriptorSetLayout> descSetLayouts;
for(ResourceId setLayout : pipeInfo.descSetLayouts)
descSetLayouts.push_back(rm->GetCurrentHandle<VkDescriptorSetLayout>(setLayout));
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
const VulkanCreationInfo::PipelineLayout &pipeLayoutInfo =
m_pDriver->m_CreationInfo.m_PipelineLayout[pipeInfo.vertLayout];
const rdcarray<VkPushConstantRange> &push = pipeLayoutInfo.pushRanges;
VkPipelineLayoutCreateInfo pipeLayoutCreateInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
NULL,
pipeLayoutInfo.flags,
(uint32_t)descSetLayouts.size(),
descSetLayouts.data(),
(uint32_t)push.size(),
push.data(),
};
VkResult vkr = m_pDriver->vkCreatePipelineLayout(m_pDriver->GetDev(), &pipeLayoutCreateInfo,
NULL, &m_CombinedPipeLayouts[pipeline]);
m_pDriver->CheckVkResult(vkr);
ret.layout = m_CombinedPipeLayouts[pipeline];
}
}
static VkFormat colFormats[16] = {};
static VkPipelineRenderingCreateInfo dynRenderCreate = {
VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, NULL, pipeInfo.viewMask, 0, colFormats,
@@ -987,7 +1025,7 @@ void VulkanShaderCache::MakeComputePipelineInfo(VkComputePipelineCreateInfo &pip
NULL,
pipeInfo.flags,
stage,
rm->GetCurrentHandle<VkPipelineLayout>(pipeInfo.layout),
rm->GetCurrentHandle<VkPipelineLayout>(pipeInfo.compLayout),
VK_NULL_HANDLE, // base pipeline handle
0, // base pipeline index
};
@@ -124,6 +124,10 @@ private:
WrappedVulkan *m_pDriver = NULL;
VkDevice m_Device = VK_NULL_HANDLE;
// combined pipeline layouts constructed out of independent set pipeline layouts, for use in a
// single combined graphics pipeline create info
std::map<ResourceId, VkPipelineLayout> m_CombinedPipeLayouts;
bytebuf m_PipeCacheBlob;
VkPipelineCache m_PipelineCache = VK_NULL_HANDLE;
+17 -5
View File
@@ -1413,17 +1413,28 @@ void VulkanReplay::FetchShaderFeedback(uint32_t eventId)
feedbackStorageSize += 16 + Vulkan_Debug_PrintfBufferSize() + 1024;
}
ResourceId pipeLayouts[] = {pipeInfo.vertLayout, pipeInfo.fragLayout};
if(result.compute)
{
const rdcarray<ResourceId> &descSetLayoutIds =
creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts;
pipeLayouts[0] = pipeInfo.compLayout;
pipeLayouts[1] = ResourceId();
}
if(pipeInfo.vertLayout == pipeInfo.fragLayout)
pipeLayouts[1] = ResourceId();
for(size_t i = 0; i < ARRAY_COUNT(pipeLayouts); i++)
{
if(pipeLayouts[i] == ResourceId())
continue;
rdcspv::Binding key;
for(size_t set = 0; set < descSetLayoutIds.size(); set++)
for(size_t set = 0; set < pipeInfo.descSetLayouts.size(); set++)
{
key.set = (uint32_t)set;
const DescSetLayout &layout = creationInfo.m_DescSetLayout[descSetLayoutIds[set]];
const DescSetLayout &layout = creationInfo.m_DescSetLayout[pipeInfo.descSetLayouts[set]];
for(size_t binding = 0; binding < layout.bindings.size(); binding++)
{
@@ -1533,7 +1544,8 @@ void VulkanReplay::FetchShaderFeedback(uint32_t eventId)
// create pipeline layout with new descriptor set layouts
{
const rdcarray<VkPushConstantRange> &push =
creationInfo.m_PipelineLayout[pipeInfo.layout].pushRanges;
creationInfo.m_PipelineLayout[result.compute ? pipeInfo.compLayout : pipeInfo.vertLayout]
.pushRanges;
VkPipelineLayoutCreateInfo pipeLayoutInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+21 -11
View File
@@ -165,21 +165,26 @@ public:
const VulkanCreationInfo::Pipeline &pipe =
m_Creation.m_Pipeline[compute ? state.compute.pipeline : state.graphics.pipeline];
const VulkanCreationInfo::PipelineLayout &pipeLayout = m_Creation.m_PipelineLayout[pipe.layout];
for(const VkPushConstantRange &range : pipeLayout.pushRanges)
{
if(range.stageFlags & stage)
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
const VulkanCreationInfo::PipelineLayout &pipeLayout =
m_Creation.m_PipelineLayout[compute ? pipe.compLayout : pipe.vertLayout];
for(const VkPushConstantRange &range : pipeLayout.pushRanges)
{
pushData.resize(RDCMAX((uint32_t)pushData.size(), range.offset + range.size));
if(range.stageFlags & stage)
{
pushData.resize(RDCMAX((uint32_t)pushData.size(), range.offset + range.size));
RDCASSERT(range.offset + range.size < sizeof(state.pushconsts));
RDCASSERT(range.offset + range.size < sizeof(state.pushconsts));
memcpy(pushData.data() + range.offset, state.pushconsts + range.offset, range.size);
memcpy(pushData.data() + range.offset, state.pushconsts + range.offset, range.size);
}
}
}
m_DescSets.resize(RDCMIN(descSets.size(), pipeLayout.descSetLayouts.size()));
m_DescSets.resize(RDCMIN(descSets.size(), pipe.descSetLayouts.size()));
for(size_t set = 0; set < m_DescSets.size(); set++)
{
uint32_t dynamicOffset = 0;
@@ -189,6 +194,12 @@ public:
if(descSets[set].descSet == ResourceId() || descSets[set].pipeLayout == ResourceId())
continue;
const VulkanCreationInfo::PipelineLayout &pipeLayoutInfo =
m_Creation.m_PipelineLayout[descSets[set].pipeLayout];
if(pipeLayoutInfo.descSetLayouts[set] == ResourceId())
continue;
DescSetSnapshot &dstSet = m_DescSets[set];
const BindingStorage &bindStorage =
@@ -202,9 +213,7 @@ public:
// set bind time must have been compatible and valid so we can use it. If this set *is* used
// then the pipeline layout at bind time must be compatible with the pipeline's pipeline
// layout, so we're fine too.
const DescSetLayout &setLayout =
m_Creation
.m_DescSetLayout[m_Creation.m_PipelineLayout[descSets[set].pipeLayout].descSetLayouts[set]];
const DescSetLayout &setLayout = m_Creation.m_DescSetLayout[pipeLayoutInfo.descSetLayouts[set]];
for(size_t bind = 0; bind < setLayout.bindings.size(); bind++)
{
@@ -4304,7 +4313,8 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
}
// create pipeline layout with new descriptor set layouts
const rdcarray<VkPushConstantRange> &push = c.m_PipelineLayout[pipe.layout].pushRanges;
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
const rdcarray<VkPushConstantRange> &push = c.m_PipelineLayout[pipe.vertLayout].pushRanges;
VkPipelineLayoutCreateInfo pipeLayoutInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+4 -4
View File
@@ -286,7 +286,8 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
ResourceId pipeLayoutId = pipeinfo.layout;
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
ResourceId pipeLayoutId = pipeinfo.vertLayout;
VkPipelineLayout layout =
vk->GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
@@ -524,7 +525,7 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(vk->GetResourceManager()->GetCurrentHandle<VkPipeline>(compute.pipeline)));
ResourceId pipeLayoutId = vk->GetDebugManager()->GetPipelineInfo(compute.pipeline).layout;
ResourceId pipeLayoutId = vk->GetDebugManager()->GetPipelineInfo(compute.pipeline).compLayout;
VkPipelineLayout layout =
vk->GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
@@ -544,9 +545,8 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
void VulkanRenderState::BindDescriptorSets(WrappedVulkan *vk, VkCommandBuffer cmd,
VulkanStatePipeline &pipe, VkPipelineBindPoint bindPoint)
{
ResourceId pipeLayoutId = vk->GetDebugManager()->GetPipelineInfo(pipe.pipeline).layout;
const rdcarray<ResourceId> &descSetLayouts =
vk->GetDebugManager()->GetPipelineLayoutInfo(pipeLayoutId).descSetLayouts;
vk->GetDebugManager()->GetPipelineInfo(pipe.pipeline).descSetLayouts;
for(size_t i = 0; i < descSetLayouts.size(); i++)
{
+66
View File
@@ -2078,6 +2078,59 @@ rdcstr DoStringise(const VkStructureType &el)
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const VkObjectType &el)
{
BEGIN_ENUM_STRINGISE(VkObjectType);
{
STRINGISE_ENUM(VK_OBJECT_TYPE_UNKNOWN)
STRINGISE_ENUM(VK_OBJECT_TYPE_INSTANCE)
STRINGISE_ENUM(VK_OBJECT_TYPE_PHYSICAL_DEVICE)
STRINGISE_ENUM(VK_OBJECT_TYPE_DEVICE)
STRINGISE_ENUM(VK_OBJECT_TYPE_QUEUE)
STRINGISE_ENUM(VK_OBJECT_TYPE_SEMAPHORE)
STRINGISE_ENUM(VK_OBJECT_TYPE_COMMAND_BUFFER)
STRINGISE_ENUM(VK_OBJECT_TYPE_FENCE)
STRINGISE_ENUM(VK_OBJECT_TYPE_DEVICE_MEMORY)
STRINGISE_ENUM(VK_OBJECT_TYPE_BUFFER)
STRINGISE_ENUM(VK_OBJECT_TYPE_IMAGE)
STRINGISE_ENUM(VK_OBJECT_TYPE_EVENT)
STRINGISE_ENUM(VK_OBJECT_TYPE_QUERY_POOL)
STRINGISE_ENUM(VK_OBJECT_TYPE_BUFFER_VIEW)
STRINGISE_ENUM(VK_OBJECT_TYPE_IMAGE_VIEW)
STRINGISE_ENUM(VK_OBJECT_TYPE_SHADER_MODULE)
STRINGISE_ENUM(VK_OBJECT_TYPE_PIPELINE_CACHE)
STRINGISE_ENUM(VK_OBJECT_TYPE_PIPELINE_LAYOUT)
STRINGISE_ENUM(VK_OBJECT_TYPE_RENDER_PASS)
STRINGISE_ENUM(VK_OBJECT_TYPE_PIPELINE)
STRINGISE_ENUM(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
STRINGISE_ENUM(VK_OBJECT_TYPE_SAMPLER)
STRINGISE_ENUM(VK_OBJECT_TYPE_DESCRIPTOR_POOL)
STRINGISE_ENUM(VK_OBJECT_TYPE_DESCRIPTOR_SET)
STRINGISE_ENUM(VK_OBJECT_TYPE_FRAMEBUFFER)
STRINGISE_ENUM(VK_OBJECT_TYPE_COMMAND_POOL)
STRINGISE_ENUM(VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION)
STRINGISE_ENUM(VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
STRINGISE_ENUM(VK_OBJECT_TYPE_SURFACE_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_SWAPCHAIN_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_DISPLAY_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_DISPLAY_MODE_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT)
STRINGISE_ENUM(VK_OBJECT_TYPE_CU_MODULE_NVX)
STRINGISE_ENUM(VK_OBJECT_TYPE_CU_FUNCTION_NVX)
STRINGISE_ENUM(VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT)
STRINGISE_ENUM(VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_VALIDATION_CACHE_EXT)
STRINGISE_ENUM(VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV)
STRINGISE_ENUM(VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL)
STRINGISE_ENUM(VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR)
STRINGISE_ENUM(VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV)
STRINGISE_ENUM(VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT)
STRINGISE_ENUM(VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA)
}
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const VkComponentSwizzle &el)
{
@@ -3270,6 +3323,19 @@ rdcstr DoStringise(const VkFormatFeatureFlagBits2 &el)
END_BITFIELD_STRINGISE();
}
template <>
rdcstr DoStringise(const VkGraphicsPipelineLibraryFlagBitsEXT &el)
{
BEGIN_BITFIELD_STRINGISE(VkGraphicsPipelineLibraryFlagBitsEXT);
{
STRINGISE_BITFIELD_BIT(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT);
STRINGISE_BITFIELD_BIT(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
STRINGISE_BITFIELD_BIT(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
STRINGISE_BITFIELD_BIT(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
}
END_BITFIELD_STRINGISE();
}
template <>
rdcstr DoStringise(const VkRenderingFlagBits &el)
{
@@ -3277,6 +3277,11 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
{
descsets[firstSet + i].pipeLayout = GetResID(layout);
descsets[firstSet + i].descSet = GetResID(pDescriptorSets[i]);
descsets[firstSet + i].offsets.clear();
if(descSetLayouts[firstSet + i] == ResourceId())
continue;
uint32_t dynCount =
m_CreationInfo.m_DescSetLayout[descSetLayouts[firstSet + i]].dynamicCount;
descsets[firstSet + i].offsets.assign(offsIter, dynCount);
@@ -3340,8 +3345,11 @@ void WrappedVulkan::vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read);
for(uint32_t i = 0; i < setCount; i++)
record->cmdInfo->boundDescSets.insert(
{GetResID(pDescriptorSets[i]), GetRecord(pDescriptorSets[i])});
{
if(pDescriptorSets[i] != VK_NULL_HANDLE)
record->cmdInfo->boundDescSets.insert(
{GetResID(pDescriptorSets[i]), GetRecord(pDescriptorSets[i])});
}
}
}
@@ -2872,6 +2872,13 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT);
{
CHECK_PHYS_EXT_FEATURE(graphicsPipelineLibrary);
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceDynamicRenderingFeatures,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES);
{
@@ -23,6 +23,7 @@
******************************************************************************/
#include "../vk_core.h"
#include "../vk_replay.h"
#include "driver/shaders/spirv/spirv_reflect.h"
template <>
@@ -157,7 +158,10 @@ bool WrappedVulkan::Serialise_vkCreatePipelineLayout(SerialiserType &ser, VkDevi
AddResource(PipelineLayout, ResourceType::ShaderBinding, "Pipeline Layout");
DerivedResource(device, PipelineLayout);
for(uint32_t i = 0; i < CreateInfo.setLayoutCount; i++)
DerivedResource(CreateInfo.pSetLayouts[i], PipelineLayout);
{
if(CreateInfo.pSetLayouts[i] != VK_NULL_HANDLE)
DerivedResource(CreateInfo.pSetLayouts[i], PipelineLayout);
}
}
return true;
@@ -198,9 +202,16 @@ VkResult WrappedVulkan::vkCreatePipelineLayout(VkDevice device,
for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
{
VkResourceRecord *layoutrecord = GetRecord(pCreateInfo->pSetLayouts[i]);
record->AddParent(layoutrecord);
if(layoutrecord)
{
record->AddParent(layoutrecord);
record->pipeLayoutInfo->layouts.push_back(*layoutrecord->descInfo->layout);
record->pipeLayoutInfo->layouts.push_back(*layoutrecord->descInfo->layout);
}
else
{
record->pipeLayoutInfo->layouts.push_back(DescSetLayout());
}
}
}
else
@@ -447,6 +458,8 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache),
1, unwrapped, NULL, &pipe);
AddResource(Pipeline, ResourceType::PipelineState, "Graphics Pipeline");
if(ret != VK_SUCCESS)
{
RDCERR("Failed on resource serialise-creation, VkResult: %s", ToStr(ret).c_str());
@@ -472,9 +485,57 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
live = GetResourceManager()->WrapResource(Unwrap(device), pipe);
GetResourceManager()->AddLiveResource(Pipeline, pipe);
VkGraphicsPipelineCreateInfo shadInstantiatedInfo = CreateInfo;
VkPipelineShaderStageCreateInfo shadInstantiations[6];
// search for inline shaders, and create shader modules for them so we have objects to pull
// out for recreating graphics pipelines (and to replace for shader editing)
for(uint32_t s = 0; s < shadInstantiatedInfo.stageCount; s++)
{
shadInstantiations[s] = shadInstantiatedInfo.pStages[s];
if(shadInstantiations[s].module == VK_NULL_HANDLE)
{
const VkShaderModuleCreateInfo *inlineShad =
(const VkShaderModuleCreateInfo *)FindNextStruct(
&shadInstantiations[s], VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
const VkDebugUtilsObjectNameInfoEXT *shadName =
(const VkDebugUtilsObjectNameInfoEXT *)FindNextStruct(
&shadInstantiations[s], VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT);
if(inlineShad)
{
vkCreateShaderModule(device, inlineShad, NULL, &shadInstantiations[s].module);
// this will be a replay ID, there is no equivalent original ID
ResourceId shadId = GetResID(shadInstantiations[s].module);
AddResource(shadId, ResourceType::Shader, "Shader Module");
DerivedResource(device, shadId);
DerivedResource(pipe, shadId);
const char *names[] = {" vertex shader", " tess control shader", " tess eval shader",
" geometry shader", " fragment shader"};
if(shadName)
GetReplay()->GetResourceDesc(shadId).SetCustomName(shadName->pObjectName);
else
GetReplay()->GetResourceDesc(shadId).name =
GetReplay()->GetResourceDesc(Pipeline).name +
names[StageIndex(shadInstantiations[s].stage)];
}
else
{
RDCERR("NULL module in stage %s (entry %s) with no linked module create info",
ToStr(shadInstantiations[s].stage).c_str(), shadInstantiations[s].pName);
}
}
}
shadInstantiatedInfo.pStages = shadInstantiations;
VulkanCreationInfo::Pipeline &pipeInfo = m_CreationInfo.m_Pipeline[live];
pipeInfo.Init(GetResourceManager(), m_CreationInfo, live, &CreateInfo);
pipeInfo.Init(GetResourceManager(), m_CreationInfo, live, &shadInstantiatedInfo);
ResourceId renderPassID = GetResID(CreateInfo.renderPass);
@@ -498,7 +559,6 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
}
}
AddResource(Pipeline, ResourceType::PipelineState, "Graphics Pipeline");
DerivedResource(device, Pipeline);
if(origCache != VK_NULL_HANDLE)
DerivedResource(origCache, Pipeline);
@@ -512,7 +572,21 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
if(CreateInfo.layout != VK_NULL_HANDLE)
DerivedResource(CreateInfo.layout, Pipeline);
for(uint32_t i = 0; i < CreateInfo.stageCount; i++)
DerivedResource(CreateInfo.pStages[i].module, Pipeline);
{
if(CreateInfo.pStages[i].module != VK_NULL_HANDLE)
DerivedResource(CreateInfo.pStages[i].module, Pipeline);
}
VkPipelineLibraryCreateInfoKHR *libraryInfo = (VkPipelineLibraryCreateInfoKHR *)FindNextStruct(
&CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR);
if(libraryInfo)
{
for(uint32_t l = 0; l < libraryInfo->libraryCount; l++)
{
DerivedResource(libraryInfo->pLibraries[l], Pipeline);
}
}
}
return true;
@@ -618,7 +692,8 @@ VkResult WrappedVulkan::vkCreateGraphicsPipelines(VkDevice device, VkPipelineCac
for(uint32_t s = 0; s < pCreateInfos[i].stageCount; s++)
{
VkResourceRecord *modulerecord = GetRecord(pCreateInfos[i].pStages[s].module);
record->AddParent(modulerecord);
if(modulerecord)
record->AddParent(modulerecord);
}
VkPipelineLibraryCreateInfoKHR *libraryInfo =
+5 -3
View File
@@ -1992,12 +1992,14 @@ template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VKPipe::Pipeline &el)
{
SERIALISE_MEMBER(pipelineResourceId);
SERIALISE_MEMBER(pipelineLayoutResourceId);
SERIALISE_MEMBER(pipelineComputeLayoutResourceId);
SERIALISE_MEMBER(pipelinePreRastLayoutResourceId);
SERIALISE_MEMBER(pipelineFragmentLayoutResourceId);
SERIALISE_MEMBER(flags);
SERIALISE_MEMBER(descriptorSets);
SIZE_CHECK(48);
SIZE_CHECK(64);
}
template <typename SerialiserType>
@@ -2346,7 +2348,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el)
SERIALISE_MEMBER(conditionalRendering);
SIZE_CHECK(2064);
SIZE_CHECK(2096);
}
#pragma endregion Vulkan pipeline state