From dff44dc2b17afb71ed6fd59d17de52db04156b41 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 9 Mar 2017 17:23:00 +0000 Subject: [PATCH] Fix for interaction between KHX extensions and NV_dedicated_allocation --- renderdoc/driver/vulkan/vk_common.h | 39 ++++++++ .../vulkan/wrappers/vk_resource_funcs.cpp | 99 +++++++++---------- 2 files changed, 85 insertions(+), 53 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 1dcdb9d79..729a41f24 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -165,6 +165,45 @@ struct VkGenericStruct const VkGenericStruct *pNext; }; +// utility function for when we're modifying one struct in a pNext chain, this +// lets us just copy across a struct unmodified into some temporary memory and +// append it onto a pNext chain we're building +template +void CopyNextChainedStruct(byte *&tempMem, const VkGenericStruct *nextInput, + VkGenericStruct *&nextChainTail) +{ + const VkStruct *instruct = (const VkStruct *)nextInput; + VkStruct *outstruct = (VkStruct *)tempMem; + + tempMem = (byte *)(outstruct + 1); + + // copy the struct, nothing to unwrap + *outstruct = *instruct; + + // default to NULL. It will be overwritten next time if there is a next object + outstruct->pNext = NULL; + + // append this onto the chain + nextChainTail->pNext = (const VkGenericStruct *)outstruct; + nextChainTail = (VkGenericStruct *)outstruct; +} + +// this is similar to the above function, but for use after we've modified a struct locally +// e.g. to unwrap some members or patch flags, etc. +template +void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, + VkGenericStruct *&nextChainTail) +{ + tempMem = (byte *)(outputStruct + 1); + + // default to NULL. It will be overwritten in the next step if there is a next object + outputStruct->pNext = NULL; + + // append this onto the chain + nextChainTail->pNext = (const VkGenericStruct *)outputStruct; + nextChainTail = (VkGenericStruct *)outputStruct; +} + #define RENDERDOC_LAYER_NAME "VK_LAYER_RENDERDOC_Capture" #define IMPLEMENT_FUNCTION_SERIALISED(ret, func, ...) \ diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 6673e1b99..74d3d2437 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -264,8 +264,14 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate // we need to unwrap this struct if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) memSize += sizeof(VkDedicatedAllocationMemoryAllocateInfoNV); + // the rest we don't need to unwrap, but we need to copy locally for chaining else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV) memSize += sizeof(VkExportMemoryAllocateInfoNV); + else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHX) + memSize += sizeof(VkExportMemoryAllocateInfoKHX); + else if(next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHX) + memSize += sizeof(VkImportMemoryFdInfoKHX); + #ifdef VK_NV_external_memory_win32 else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV) memSize += sizeof(VkExportMemoryWin32HandleInfoNV); @@ -278,6 +284,18 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate RDCERR("Support for VK_NV_external_memory_win32 not compiled in"); #endif +#ifdef VK_KHX_external_memory_win32 + else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + memSize += sizeof(VkExportMemoryWin32HandleInfoKHX); + else if(next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + memSize += sizeof(VkImportMemoryWin32HandleInfoKHX); +#else + else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + RDCERR("Support for VK_KHX_external_memory_win32 not compiled in"); + else if(next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + RDCERR("Support for VK_KHX_external_memory_win32 not compiled in"); +#endif + next = next->pNext; } } @@ -297,56 +315,45 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate VkDedicatedAllocationMemoryAllocateInfoNV *dedicatedOut = (VkDedicatedAllocationMemoryAllocateInfoNV *)tempMem; - tempMem = (byte *)(dedicatedOut + 1); - // copy and unwrap the struct dedicatedOut->sType = dedicatedIn->sType; dedicatedOut->buffer = Unwrap(dedicatedIn->buffer); dedicatedOut->image = Unwrap(dedicatedIn->image); - // default to NULL. It will be overwritten in the next step if there is a next object - dedicatedOut->pNext = NULL; - - // append this onto the chain - nextChainTail->pNext = (const VkGenericStruct *)dedicatedOut; - nextChainTail = (VkGenericStruct *)dedicatedOut; + AppendModifiedChainedStruct(tempMem, dedicatedOut, nextChainTail); } else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV) { - const VkExportMemoryAllocateInfoNV *instruct = - (const VkExportMemoryAllocateInfoNV *)nextInput; - VkExportMemoryAllocateInfoNV *outstruct = (VkExportMemoryAllocateInfoNV *)tempMem; - - tempMem = (byte *)(outstruct + 1); - - // copy the struct, nothing to unwrap - *outstruct = *instruct; - - // default to NULL. It will be overwritten in the next step if there is a next object - outstruct->pNext = NULL; - - // append this onto the chain - nextChainTail->pNext = (const VkGenericStruct *)outstruct; - nextChainTail = (VkGenericStruct *)outstruct; + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); + } + else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHX) + { + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); + } + else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHX) + { + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); + } + else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + { +#ifdef VK_KHX_external_memory_win32 + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); +#else + RDCERR("Support for VK_KHX_external_memory_win32 not compiled in"); +#endif + } + else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHX) + { +#ifdef VK_KHX_external_memory_win32 + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); +#else + RDCERR("Support for VK_KHX_external_memory_win32 not compiled in"); +#endif } else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV) { #ifdef VK_NV_external_memory_win32 - const VkExportMemoryWin32HandleInfoNV *instruct = - (const VkExportMemoryWin32HandleInfoNV *)nextInput; - VkExportMemoryWin32HandleInfoNV *outstruct = (VkExportMemoryWin32HandleInfoNV *)tempMem; - - tempMem = (byte *)(outstruct + 1); - - // copy the struct, nothing to unwrap - *outstruct = *instruct; - - // default to NULL. It will be overwritten in the next step if there is a next object - outstruct->pNext = NULL; - - // append this onto the chain - nextChainTail->pNext = (const VkGenericStruct *)outstruct; - nextChainTail = (VkGenericStruct *)outstruct; + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); #else RDCERR("Support for VK_NV_external_memory_win32 not compiled in"); #endif @@ -354,21 +361,7 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV) { #ifdef VK_NV_external_memory_win32 - const VkImportMemoryWin32HandleInfoNV *instruct = - (const VkImportMemoryWin32HandleInfoNV *)nextInput; - VkImportMemoryWin32HandleInfoNV *outstruct = (VkImportMemoryWin32HandleInfoNV *)tempMem; - - tempMem = (byte *)(outstruct + 1); - - // copy the struct, nothing to unwrap - *outstruct = *instruct; - - // default to NULL. It will be overwritten in the next step if there is a next object - outstruct->pNext = NULL; - - // append this onto the chain - nextChainTail->pNext = (const VkGenericStruct *)outstruct; - nextChainTail = (VkGenericStruct *)outstruct; + CopyNextChainedStruct(tempMem, nextInput, nextChainTail); #else RDCERR("Support for VK_NV_external_memory_win32 not compiled in"); #endif