mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Patch VkRenderPassMultiviewCreateInfo when making single-subpass RPs
This commit is contained in:
@@ -286,6 +286,7 @@ enum VkFlagWithNoBits
|
||||
size_t GetNextPatchSize(const void *next);
|
||||
void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
|
||||
VkBaseInStructure *infoStruct);
|
||||
void CopyNextChainForPatching(const char *structName, byte *&tempMem, VkBaseInStructure *infoStruct);
|
||||
|
||||
template <typename VkStruct>
|
||||
const VkBaseInStructure *FindNextStruct(const VkStruct *haystack, VkStructureType needle)
|
||||
|
||||
@@ -982,6 +982,7 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
|
||||
break; \
|
||||
}
|
||||
|
||||
#undef UNWRAP_STRUCT_INNER
|
||||
#define UNWRAP_STRUCT_INNER(StructType, StructName, ...) \
|
||||
{ \
|
||||
const StructName *in = (const StructName *)nextInput; \
|
||||
@@ -1562,3 +1563,186 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
|
||||
nextInput = nextInput->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
void CopyNextChainForPatching(const char *structName, byte *&tempMem, VkBaseInStructure *infoStruct)
|
||||
{
|
||||
VkBaseInStructure *nextChainTail = infoStruct;
|
||||
const VkBaseInStructure *nextInput = (const VkBaseInStructure *)infoStruct->pNext;
|
||||
|
||||
// simplified version of UnwrapNextChain which just copies everything. Useful for when we need to
|
||||
// shallow duplicate a next chain (e.g. because we'll copy and patch one struct)
|
||||
|
||||
#undef COPY_STRUCT_CAPTURE_ONLY
|
||||
#define COPY_STRUCT_CAPTURE_ONLY(StructType, StructName) \
|
||||
case StructType: \
|
||||
CopyNextChainedStruct(sizeof(StructName), tempMem, nextInput, nextChainTail); \
|
||||
break;
|
||||
|
||||
#undef COPY_STRUCT
|
||||
#define COPY_STRUCT(StructType, StructName) \
|
||||
case StructType: \
|
||||
CopyNextChainedStruct(sizeof(StructName), tempMem, nextInput, nextChainTail); \
|
||||
break;
|
||||
|
||||
#undef UNWRAP_STRUCT_INNER
|
||||
#define UNWRAP_STRUCT_INNER(StructType, StructName, ...) \
|
||||
case StructType: \
|
||||
CopyNextChainedStruct(sizeof(StructName), tempMem, nextInput, nextChainTail); \
|
||||
break;
|
||||
|
||||
#undef UNWRAP_STRUCT
|
||||
#define UNWRAP_STRUCT(StructType, StructName, ...) \
|
||||
case StructType: \
|
||||
CopyNextChainedStruct(sizeof(StructName), tempMem, nextInput, nextChainTail); \
|
||||
break;
|
||||
|
||||
#undef UNWRAP_STRUCT_CAPTURE_ONLY
|
||||
#define UNWRAP_STRUCT_CAPTURE_ONLY(StructType, StructName, ...) \
|
||||
case StructType: \
|
||||
CopyNextChainedStruct(sizeof(StructName), tempMem, nextInput, nextChainTail); \
|
||||
break;
|
||||
|
||||
nextChainTail->pNext = NULL;
|
||||
while(nextInput)
|
||||
{
|
||||
switch(nextInput->sType)
|
||||
{
|
||||
PROCESS_SIMPLE_STRUCTS();
|
||||
|
||||
// complex structs to handle - require multiple allocations
|
||||
case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkBindSparseInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkDescriptorSetAllocateInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkDescriptorSetLayoutCreateInfo), tempMem, nextInput,
|
||||
nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkDeviceGroupDeviceCreateInfo), tempMem, nextInput,
|
||||
nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkFramebufferCreateInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkGraphicsPipelineCreateInfo), tempMem, nextInput,
|
||||
nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkComputePipelineCreateInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkPipelineLayoutCreateInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR:
|
||||
CopyNextChainedStruct(sizeof(VkPresentInfoKHR), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkRenderPassAttachmentBeginInfo), tempMem, nextInput,
|
||||
nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkSemaphoreWaitInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_SUBMIT_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkSubmitInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
|
||||
CopyNextChainedStruct(sizeof(VkWriteDescriptorSet), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
|
||||
// NV win32 external memory extensions
|
||||
#if ENABLED(RDOC_WIN32)
|
||||
// Structs that can be copied into place
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV,
|
||||
VkImportMemoryWin32HandleInfoNV);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV,
|
||||
VkExportMemoryWin32HandleInfoNV);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
|
||||
VkImportMemoryWin32HandleInfoKHR);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
|
||||
VkExportMemoryWin32HandleInfoKHR);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR,
|
||||
VkMemoryWin32HandlePropertiesKHR);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
|
||||
VkExportSemaphoreWin32HandleInfoKHR);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR,
|
||||
VkD3D12FenceSubmitInfoKHR);
|
||||
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
|
||||
VkExportFenceWin32HandleInfoKHR);
|
||||
|
||||
UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
|
||||
VkMemoryGetWin32HandleInfoKHR, UnwrapInPlace(out->memory));
|
||||
UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
|
||||
VkImportSemaphoreWin32HandleInfoKHR,
|
||||
UnwrapInPlace(out->semaphore));
|
||||
UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
|
||||
VkSemaphoreGetWin32HandleInfoKHR, UnwrapInPlace(out->semaphore));
|
||||
UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
|
||||
VkImportFenceWin32HandleInfoKHR, UnwrapInPlace(out->fence));
|
||||
UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
|
||||
VkFenceGetWin32HandleInfoKHR, UnwrapInPlace(out->fence));
|
||||
|
||||
case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV:
|
||||
case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR:
|
||||
CopyNextChainedStruct(sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHR), tempMem, nextInput,
|
||||
nextChainTail);
|
||||
break;
|
||||
#else
|
||||
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV:
|
||||
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV:
|
||||
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR:
|
||||
case VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR:
|
||||
case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV:
|
||||
case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR:
|
||||
{
|
||||
RDCERR("Support for win32 external memory extensions not compiled in");
|
||||
nextChainTail->pNext = nextInput;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT:
|
||||
case VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT:
|
||||
case VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT:
|
||||
case VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT:
|
||||
case VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT:
|
||||
{
|
||||
// could be implemented but would need extra work or doesn't make sense right now
|
||||
RDCERR("Struct %s not handled in %s pNext chain", ToStr(nextInput->sType).c_str(),
|
||||
structName);
|
||||
nextChainTail->pNext = nextInput;
|
||||
break;
|
||||
}
|
||||
|
||||
UNHANDLED_STRUCTS()
|
||||
{
|
||||
RDCERR("Unhandled struct %s in %s pNext chain", ToStr(nextInput->sType).c_str(),
|
||||
structName);
|
||||
nextChainTail->pNext = nextInput;
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_STRUCTURE_TYPE_MAX_ENUM:
|
||||
{
|
||||
RDCERR("Invalid value %x in %s pNext chain", nextInput->sType, structName);
|
||||
nextChainTail->pNext = nextInput;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextInput = nextInput->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,33 @@ static void MakeSubpassLoadRP(RPCreateInfo &info, const RPCreateInfo *origInfo,
|
||||
info.subpassCount = 1;
|
||||
info.pSubpasses = origInfo->pSubpasses + s;
|
||||
|
||||
// VK_KHR_multiview
|
||||
const VkRenderPassMultiviewCreateInfo *multiview =
|
||||
(const VkRenderPassMultiviewCreateInfo *)FindNextStruct(
|
||||
origInfo, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO);
|
||||
|
||||
static VkRenderPassMultiviewCreateInfo patched;
|
||||
|
||||
if(multiview)
|
||||
{
|
||||
// remove from the chain, the caller ensured we have a mutable chain so we won't be trashing the
|
||||
// pNext chain we'll look up for any subsequent subpasses
|
||||
RemoveNextStruct(&info, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO);
|
||||
patched = *multiview;
|
||||
|
||||
// keep the view mask for our target subpass
|
||||
patched.subpassCount = 1;
|
||||
patched.pViewMasks = patched.pViewMasks + s;
|
||||
|
||||
// view offsets are not allowed for self-dependencies, and we remove all other dependencies.
|
||||
patched.dependencyCount = 0;
|
||||
patched.pViewOffsets = NULL;
|
||||
|
||||
// add onto the chain
|
||||
patched.pNext = info.pNext;
|
||||
info.pNext = &patched;
|
||||
}
|
||||
|
||||
// remove any non-self dependencies
|
||||
info.dependencyCount = 0;
|
||||
for(uint32_t i = 0; i < origInfo->dependencyCount; i++)
|
||||
@@ -932,6 +959,11 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d
|
||||
|
||||
VkRenderPassCreateInfo loadInfo = CreateInfo;
|
||||
|
||||
{
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(loadInfo.pNext));
|
||||
CopyNextChainForPatching("VkRenderPassCreateInfo", tempMem, (VkBaseInStructure *)&loadInfo);
|
||||
}
|
||||
|
||||
rpinfo.loadRPs.resize(CreateInfo.subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
@@ -1037,6 +1069,11 @@ VkResult WrappedVulkan::vkCreateRenderPass(VkDevice device, const VkRenderPassCr
|
||||
|
||||
info.pDependencies = deps.data();
|
||||
|
||||
{
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
|
||||
CopyNextChainForPatching("VkRenderPassCreateInfo", tempMem, (VkBaseInStructure *)&info);
|
||||
}
|
||||
|
||||
rpinfo.loadRPs.resize(pCreateInfo->subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
@@ -1152,6 +1189,12 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass2(SerialiserType &ser, VkDevice
|
||||
|
||||
VkRenderPassCreateInfo2 loadInfo = CreateInfo;
|
||||
|
||||
{
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(loadInfo.pNext));
|
||||
CopyNextChainForPatching("VkRenderPassCreateInfo2", tempMem,
|
||||
(VkBaseInStructure *)&loadInfo);
|
||||
}
|
||||
|
||||
rpinfo.loadRPs.resize(CreateInfo.subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
@@ -1258,6 +1301,11 @@ VkResult WrappedVulkan::vkCreateRenderPass2(VkDevice device,
|
||||
|
||||
info.pDependencies = deps.data();
|
||||
|
||||
{
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
|
||||
CopyNextChainForPatching("VkRenderPassCreateInfo2", tempMem, (VkBaseInStructure *)&info);
|
||||
}
|
||||
|
||||
rpinfo.loadRPs.resize(pCreateInfo->subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
|
||||
Reference in New Issue
Block a user