mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-11 17:20:56 +00:00
Add support for EXT_graphics_pipeline_library
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user