Unwrap the whole pNext chain of VkMemoryAllocateInfo

* Without unwrapping the whole chain it's hard to unwrap only one part
  since we need to modify the previous part to update pNext, and so on.
This commit is contained in:
baldurk
2017-02-21 18:41:47 +00:00
parent 422e5e6a79
commit 5b26aa76a0
@@ -252,32 +252,121 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
ObjDisp(device)->DestroyBuffer(Unwrap(device), buf, NULL);
}
VkDedicatedAllocationMemoryAllocateInfoNV unwrappedDedicated;
unwrappedDedicated.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
size_t memSize = 0;
VkGenericStruct *curStruct = (VkGenericStruct *)&info;
const void *next = info.pNext;
while(next)
// we don't have to unwrap every struct, but unwrapping a struct means we need to copy
// the previous one in the chain locally to modify the pNext pointer. So we just copy
// all of them locally
{
const VkGenericStruct *nextStruct = (const VkGenericStruct *)next;
// unwrap and replace the dedicated allocation struct in the chain
if(nextStruct->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)
const VkGenericStruct *next = (const VkGenericStruct *)info.pNext;
while(next)
{
const VkDedicatedAllocationMemoryAllocateInfoNV *dedicated =
(const VkDedicatedAllocationMemoryAllocateInfoNV *)nextStruct;
unwrappedDedicated.pNext = nextStruct->pNext;
unwrappedDedicated.buffer = Unwrap(dedicated->buffer);
unwrappedDedicated.image = Unwrap(dedicated->image);
curStruct->pNext = (const VkGenericStruct *)&unwrappedDedicated;
curStruct = (VkGenericStruct *)&unwrappedDedicated;
}
else
{
break;
}
// we need to unwrap this struct
if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)
memSize += sizeof(VkDedicatedAllocationMemoryAllocateInfoNV);
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV)
memSize += sizeof(VkExportMemoryAllocateInfoNV);
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV)
memSize += sizeof(VkExportMemoryWin32HandleInfoNV);
else if(next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV)
memSize += sizeof(VkImportMemoryWin32HandleInfoNV);
next = nextStruct->pNext;
next = next->pNext;
}
}
byte *tempMem = GetTempMemory(memSize);
{
VkGenericStruct *nextChainTail = (VkGenericStruct *)&info;
const VkGenericStruct *nextInput = (const VkGenericStruct *)info.pNext;
while(nextInput)
{
// unwrap and replace the dedicated allocation struct in the chain
if(nextInput->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)
{
const VkDedicatedAllocationMemoryAllocateInfoNV *dedicatedIn =
(const VkDedicatedAllocationMemoryAllocateInfoNV *)nextInput;
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;
}
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;
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV)
{
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;
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV)
{
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;
}
else
{
RDCERR("unrecognised struct %d in vkAllocateMemoryInfo pNext chain", nextInput->sType);
// can't patch this struct, have to just copy it and hope it's the last in the chain
nextChainTail->pNext = nextInput;
}
nextInput = nextInput->pNext;
}
}
VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, pAllocator, pMemory);