mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 08:40:55 +00:00
Don't replace shaders for incomplete pipeline libraries
Before, RenderDoc would treat these incomplete pipeline libraries as if they were complete pipelines, and thus attempt to create pipelines with incomplete data, producing several validation errors and on some devices crashes. For instance, a pipeline library that only contains a vertex or fragment shader but not input assembly state would use invalid input assembly state (specifically, VulkanShaderCache::MakeGraphicsPipelineInfo would use the topology value from VulkanCreationInfo::Pipeline, which is set to VK_PRIMITIVE_TOPOLOGY_MAX_ENUM (0x7fffffff) if the pipeline has no input assembly state by VulkanCreationInfo::Pipeline::Init). Additionally, those pipeline libraries were treated as complete graphics pipelines, not libraries, as VulkanShaderCache::MakeGraphicsPipelineInfo removes VK_PIPELINE_CREATE_LIBRARY_BIT_KHR and no VkGraphicsPipelineLibraryCreateInfoEXT was added to the pNext chain. RenderDoc already merges the pipeline libraries into complete graphics pipelines, so there is no reason to recreate the libraries with modified shaders.
This commit is contained in:
committed by
Baldur Karlsson
parent
91c13a0e9f
commit
3b2bb46d9a
@@ -966,17 +966,16 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
|
||||
// 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;
|
||||
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;
|
||||
availStages = graphicsLibraryCreate->flags;
|
||||
|
||||
vertLayout = fragLayout = GetResID(pCreateInfo->layout);
|
||||
renderpass = GetResID(pCreateInfo->renderPass);
|
||||
@@ -1451,7 +1450,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
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)
|
||||
if(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT)
|
||||
{
|
||||
vertexBindings = pipeInfo.vertexBindings;
|
||||
vertexAttrs = pipeInfo.vertexAttrs;
|
||||
@@ -1460,7 +1459,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
primitiveRestartEnable = pipeInfo.primitiveRestartEnable;
|
||||
}
|
||||
|
||||
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT)
|
||||
if(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT)
|
||||
{
|
||||
renderpass = pipeInfo.renderpass;
|
||||
subpass = pipeInfo.subpass;
|
||||
@@ -1511,7 +1510,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
flags |= pipeInfo.flags;
|
||||
}
|
||||
|
||||
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)
|
||||
if(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)
|
||||
{
|
||||
renderpass = pipeInfo.renderpass;
|
||||
subpass = pipeInfo.subpass;
|
||||
@@ -1540,7 +1539,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
flags |= pipeInfo.flags;
|
||||
}
|
||||
|
||||
if(pipeInfo.libraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)
|
||||
if(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)
|
||||
{
|
||||
renderpass = pipeInfo.renderpass;
|
||||
subpass = pipeInfo.subpass;
|
||||
|
||||
@@ -240,7 +240,7 @@ struct VulkanCreationInfo
|
||||
bool graphicsPipe = false;
|
||||
|
||||
// VkGraphicsPipelineLibraryCreateInfoEXT
|
||||
VkGraphicsPipelineLibraryFlagsEXT libraryFlags;
|
||||
VkGraphicsPipelineLibraryFlagsEXT availStages;
|
||||
rdcarray<ResourceId> parentLibraries;
|
||||
|
||||
ResourceId compLayout;
|
||||
|
||||
@@ -4850,6 +4850,17 @@ void VulkanReplay::RefreshDerivedReplacements()
|
||||
ResourceId pipesrcid = it->first;
|
||||
const VulkanCreationInfo::Pipeline &pipeInfo = it->second;
|
||||
|
||||
// don't replace incomplete pipeline libraries (we already pull the full state into the final
|
||||
// pipeline, so these are not used in replay; the libraries contain invalid dummy data for the
|
||||
// non-available parts)
|
||||
if(!(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) ||
|
||||
!(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) ||
|
||||
!(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) ||
|
||||
!(pipeInfo.availStages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ResourceId origsrcid = rm->GetOriginalID(pipesrcid);
|
||||
|
||||
// only look at pipelines from the capture, no replay-time programs.
|
||||
|
||||
Reference in New Issue
Block a user