Serialise all structs in pNext and discard at replay time

* Rather than not serialising structs that we aren't interested in, we serialise
  them (as best as we can in some cases) so that the information is available to
  the user. Also if in future we decide to replay them they are available.
* We also now replay dedicated allocation extension use.
This commit is contained in:
baldurk committed 2018-05-25 18:32:31 +01:00
1 parent f548846463
commit 1569a6f0dd
9 files changed
+1393 -254

No files matched your search

+261 -40
View File
@@ -297,6 +297,8 @@ size_t GetNextPatchSize(const void *pNext)
memSize += sizeof(VkDedicatedAllocationMemoryAllocateInfoNV);
else if(next->sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO)
memSize += sizeof(VkMemoryDedicatedAllocateInfo);
else if(next->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO)
memSize += sizeof(VkMemoryAllocateFlagsInfo);
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)
@@ -328,12 +330,34 @@ size_t GetNextPatchSize(const void *pNext)
RDCERR("Support for VK_KHR_external_memory_win32 not compiled in");
#endif
// vkSamplerCreateInfo
// VkSamplerCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO)
memSize += sizeof(VkSamplerYcbcrConversionInfo);
else if(next->sType == VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT)
memSize += sizeof(VkSamplerReductionModeCreateInfoEXT);
// VkSemaphoreCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO)
memSize += sizeof(VkExportSemaphoreCreateInfoKHR);
#ifdef VK_KHR_external_semaphore_win32
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR)
memSize += sizeof(VkExportSemaphoreWin32HandleInfoKHR);
#else
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR)
RDCERR("Support for VK_KHR_external_memory_win32 not compiled in");
#endif
// VkFenceCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO)
memSize += sizeof(VkExportFenceCreateInfoKHR);
#ifdef VK_KHR_external_fence_win32
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR)
memSize += sizeof(VkExportFenceWin32HandleInfoKHR);
#else
else if(next->sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR)
RDCERR("Support for VK_KHR_external_memory_win32 not compiled in");
#endif
// VkImageCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO)
memSize += sizeof(VkExternalMemoryImageCreateInfo);
@@ -344,6 +368,14 @@ size_t GetNextPatchSize(const void *pNext)
else if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV)
memSize += sizeof(VkDedicatedAllocationImageCreateInfoNV);
// VkBufferCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO)
memSize += sizeof(VkExternalMemoryBufferCreateInfoKHR);
else if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV)
memSize += sizeof(VkDedicatedAllocationBufferCreateInfoNV);
else if(next->sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO)
memSize += sizeof(VkBindBufferMemoryDeviceGroupInfo);
// VkBindImageMemoryInfo
else if(next->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR)
memSize += sizeof(VkBindImageMemorySwapchainInfoKHR);
@@ -352,35 +384,83 @@ size_t GetNextPatchSize(const void *pNext)
else if(next->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO)
memSize += sizeof(VkBindImagePlaneMemoryInfo);
// VkSwapchainCreateInfoKHR
else if(next->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT)
memSize += sizeof(VkSwapchainCounterCreateInfoEXT);
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR)
memSize += sizeof(VkDeviceGroupSwapchainCreateInfoKHR);
// VkDeviceQueueCreateInfo
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT)
memSize += sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT);
// VkSubmitInfo
else if(next->sType == VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO)
memSize += sizeof(VkProtectedSubmitInfo);
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO)
memSize += sizeof(VkDeviceGroupSubmitInfo);
#if defined(VK_KHR_win32_keyed_mutex) || defined(VK_NV_win32_keyed_mutex)
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR)
{
// the KHR and NV structs are identical
memSize += sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHR);
VkWin32KeyedMutexAcquireReleaseInfoKHR *info = (VkWin32KeyedMutexAcquireReleaseInfoKHR *)next;
memSize += info->acquireCount * sizeof(VkDeviceMemory);
memSize += info->releaseCount * sizeof(VkDeviceMemory);
}
#else
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR)
{
RDCERR("Support for VK_KHR_win32_keyed_mutex / VK_NV_win32_keyed_mutex not compiled in");
}
#endif
// VkBindSparseInfo
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO)
memSize += sizeof(VkDeviceGroupBindSparseInfo);
// VkCommandBufferBeginInfo
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO)
memSize += sizeof(VkDeviceGroupCommandBufferBeginInfo);
// VkRenderPassBeginInfo
else if(next->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO)
memSize += sizeof(VkDeviceGroupRenderPassBeginInfo);
next = next->pNext;
}
return memSize;
}
void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *infoStruct)
void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
VkGenericStruct *infoStruct)
{
// during capture, this walks the pNext chain and either copies structs that can be passed
// straight through, or copies and modifies any with vulkan objects that need to be unwrapped.
//
// during replay, we do the same thing to prepare for dispatching to the driver, but we also strip
// out any structs we don't want to replay - e.g. external memory. This means the data is
// serialised and available for future use and for user inspection, but isn't replayed when not
// necesary.
VkGenericStruct *nextChainTail = infoStruct;
const VkGenericStruct *nextInput = (const VkGenericStruct *)infoStruct->pNext;
// start with an empty chain. Every call to AppendModifiedChainedStruct / CopyNextChainedStruct
// pushes on a new entry, but if there's only one entry in the list and it's one we want to skip,
// this needs to start at NULL.
nextChainTail->pNext = NULL;
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;
// copy and unwrap the struct
dedicatedOut->sType = dedicatedIn->sType;
dedicatedOut->buffer = Unwrap(dedicatedIn->buffer);
dedicatedOut->image = Unwrap(dedicatedIn->image);
AppendModifiedChainedStruct(tempMem, dedicatedOut, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO)
if(nextInput->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV ||
nextInput->sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO)
{
// KHR and NV structs are identical
const VkMemoryDedicatedAllocateInfo *dedicatedIn =
(const VkMemoryDedicatedAllocateInfo *)nextInput;
VkMemoryDedicatedAllocateInfo *dedicatedOut = (VkMemoryDedicatedAllocateInfo *)tempMem;
@@ -390,24 +470,33 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
dedicatedOut->buffer = Unwrap(dedicatedIn->buffer);
dedicatedOut->image = Unwrap(dedicatedIn->image);
// we replay this
AppendModifiedChainedStruct(tempMem, dedicatedOut, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO)
{
CopyNextChainedStruct<VkMemoryAllocateFlagsInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV)
{
CopyNextChainedStruct<VkExportMemoryAllocateInfoNV>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportMemoryAllocateInfoNV>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO)
{
CopyNextChainedStruct<VkExportMemoryAllocateInfo>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportMemoryAllocateInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR)
{
CopyNextChainedStruct<VkImportMemoryFdInfoKHR>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkImportMemoryFdInfoKHR>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR)
{
#ifdef VK_KHR_external_memory_win32
CopyNextChainedStruct<VkExportMemoryWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportMemoryWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_KHR_external_memory_win32 not compiled in");
#endif
@@ -415,7 +504,8 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR)
{
#ifdef VK_KHR_external_memory_win32
CopyNextChainedStruct<VkImportMemoryWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkImportMemoryWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_KHR_external_memory_win32 not compiled in");
#endif
@@ -423,7 +513,8 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV)
{
#ifdef VK_NV_external_memory_win32
CopyNextChainedStruct<VkExportMemoryWin32HandleInfoNV>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportMemoryWin32HandleInfoNV>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_NV_external_memory_win32 not compiled in");
#endif
@@ -431,7 +522,8 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
else if(nextInput->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV)
{
#ifdef VK_NV_external_memory_win32
CopyNextChainedStruct<VkImportMemoryWin32HandleInfoNV>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkImportMemoryWin32HandleInfoNV>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_NV_external_memory_win32 not compiled in");
#endif
@@ -451,41 +543,93 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
{
CopyNextChainedStruct<VkSamplerReductionModeCreateInfoEXT>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO)
{
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportSemaphoreCreateInfoKHR>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR)
{
#ifdef VK_KHR_external_semaphore_win32
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportSemaphoreWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_KHR_external_semaphore_win32 not compiled in");
#endif
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO)
{
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportFenceCreateInfoKHR>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR)
{
#ifdef VK_KHR_external_fence_win32
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExportFenceWin32HandleInfoKHR>(tempMem, nextInput, nextChainTail);
#else
RDCERR("Support for VK_KHR_external_fence_win32 not compiled in");
#endif
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO)
{
CopyNextChainedStruct<VkExternalMemoryImageCreateInfo>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExternalMemoryImageCreateInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV)
{
CopyNextChainedStruct<VkExternalMemoryImageCreateInfoNV>(tempMem, nextInput, nextChainTail);
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExternalMemoryImageCreateInfoNV>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR)
{
const VkImageSwapchainCreateInfoKHR *swapIn = (const VkImageSwapchainCreateInfoKHR *)nextInput;
VkImageSwapchainCreateInfoKHR *swapOut = (VkImageSwapchainCreateInfoKHR *)tempMem;
if(IsCaptureMode(state))
{
const VkImageSwapchainCreateInfoKHR *swapIn =
(const VkImageSwapchainCreateInfoKHR *)nextInput;
VkImageSwapchainCreateInfoKHR *swapOut = (VkImageSwapchainCreateInfoKHR *)tempMem;
// copy and unwrap the struct
swapOut->sType = swapIn->sType;
swapOut->swapchain = Unwrap(swapIn->swapchain);
// copy and unwrap the struct
swapOut->sType = swapIn->sType;
swapOut->swapchain = Unwrap(swapIn->swapchain);
AppendModifiedChainedStruct(tempMem, swapOut, nextChainTail);
AppendModifiedChainedStruct(tempMem, swapOut, nextChainTail);
}
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV)
{
CopyNextChainedStruct<VkDedicatedAllocationImageCreateInfoNV>(tempMem, nextInput,
nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO)
{
if(IsCaptureMode(state))
CopyNextChainedStruct<VkExternalMemoryBufferCreateInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV)
{
CopyNextChainedStruct<VkDedicatedAllocationBufferCreateInfoNV>(tempMem, nextInput,
nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO)
{
CopyNextChainedStruct<VkBindBufferMemoryDeviceGroupInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR)
{
const VkBindImageMemorySwapchainInfoKHR *swapIn =
(const VkBindImageMemorySwapchainInfoKHR *)nextInput;
VkBindImageMemorySwapchainInfoKHR *swapOut = (VkBindImageMemorySwapchainInfoKHR *)tempMem;
if(IsCaptureMode(state))
{
const VkBindImageMemorySwapchainInfoKHR *swapIn =
(const VkBindImageMemorySwapchainInfoKHR *)nextInput;
VkBindImageMemorySwapchainInfoKHR *swapOut = (VkBindImageMemorySwapchainInfoKHR *)tempMem;
// copy and unwrap the struct
swapOut->sType = swapIn->sType;
swapOut->swapchain = Unwrap(swapIn->swapchain);
// copy and unwrap the struct
swapOut->sType = swapIn->sType;
swapOut->swapchain = Unwrap(swapIn->swapchain);
AppendModifiedChainedStruct(tempMem, swapOut, nextChainTail);
AppendModifiedChainedStruct(tempMem, swapOut, nextChainTail);
}
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO)
{
@@ -495,6 +639,83 @@ void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *inf
{
CopyNextChainedStruct<VkBindImagePlaneMemoryInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT)
{
if(IsCaptureMode(state))
CopyNextChainedStruct<VkSwapchainCounterCreateInfoEXT>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR)
{
CopyNextChainedStruct<VkDeviceGroupSwapchainCreateInfoKHR>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT)
{
CopyNextChainedStruct<VkDeviceQueueGlobalPriorityCreateInfoEXT>(tempMem, nextInput,
nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO)
{
if(IsCaptureMode(state))
CopyNextChainedStruct<VkProtectedSubmitInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO)
{
CopyNextChainedStruct<VkDeviceGroupSubmitInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
nextInput->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR)
{
#if defined(VK_KHR_win32_keyed_mutex) || defined(VK_NV_win32_keyed_mutex)
if(IsCaptureMode(state))
{
// KHR and NV structs are identical
const VkWin32KeyedMutexAcquireReleaseInfoKHR *mutexIn =
(const VkWin32KeyedMutexAcquireReleaseInfoKHR *)nextInput;
VkWin32KeyedMutexAcquireReleaseInfoKHR *mutexOut =
(VkWin32KeyedMutexAcquireReleaseInfoKHR *)tempMem;
// append immediately so tempMem is incremented
AppendModifiedChainedStruct(tempMem, mutexOut, nextChainTail);
// copy sType and pointers we don't need to patch
mutexOut->sType = mutexIn->sType;
mutexOut->acquireCount = mutexIn->acquireCount;
mutexOut->pAcquireKeys = mutexIn->pAcquireKeys;
mutexOut->pAcquireTimeouts = mutexIn->pAcquireTimeouts;
mutexOut->releaseCount = mutexIn->releaseCount;
mutexOut->pReleaseKeys = mutexIn->pReleaseKeys;
// allocate unwrapped arrays
VkDeviceMemory *unwrappedAcquires = (VkDeviceMemory *)tempMem;
tempMem += sizeof(VkDeviceMemory) * mutexIn->acquireCount;
VkDeviceMemory *unwrappedReleases = (VkDeviceMemory *)tempMem;
tempMem += sizeof(VkDeviceMemory) * mutexIn->releaseCount;
// unwrap the arrays
for(uint32_t mem = 0; mem < mutexIn->acquireCount; mem++)
unwrappedAcquires[mem] = Unwrap(mutexIn->pAcquireSyncs[mem]);
for(uint32_t mem = 0; mem < mutexIn->releaseCount; mem++)
unwrappedReleases[mem] = Unwrap(mutexIn->pReleaseSyncs[mem]);
mutexOut->pAcquireSyncs = unwrappedAcquires;
mutexOut->pReleaseSyncs = unwrappedReleases;
}
#else
RDCERR("Support for VK_KHR_win32_keyed_mutex / VK_NV_win32_keyed_mutex not compiled in");
#endif
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO)
{
CopyNextChainedStruct<VkDeviceGroupBindSparseInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO)
{
CopyNextChainedStruct<VkDeviceGroupCommandBufferBeginInfo>(tempMem, nextInput, nextChainTail);
}
else if(nextInput->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO)
{
CopyNextChainedStruct<VkDeviceGroupRenderPassBeginInfo>(tempMem, nextInput, nextChainTail);
}
else
{
RDCERR("unrecognised struct %d in %s pNext chain", nextInput->sType, structName);
+94 -2
View File
@@ -235,7 +235,8 @@ enum VkFlagWithNoBits
};
size_t GetNextPatchSize(const void *next);
void PatchNextChain(const char *structName, byte *&tempMem, VkGenericStruct *infoStruct);
void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
VkGenericStruct *infoStruct);
template <typename VkStruct>
const VkGenericStruct *FindNextStruct(const VkStruct *haystack, VkStructureType needle)
@@ -627,6 +628,33 @@ DECLARE_REFLECTION_STRUCT(VkDebugUtilsLabelEXT);
DECLARE_REFLECTION_STRUCT(VkSamplerYcbcrConversionCreateInfo);
DECLARE_REFLECTION_STRUCT(VkRenderPassMultiviewCreateInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceQueueInfo2);
DECLARE_REFLECTION_STRUCT(VkExportMemoryAllocateInfoNV);
DECLARE_REFLECTION_STRUCT(VkExternalMemoryImageCreateInfoNV);
DECLARE_REFLECTION_STRUCT(VkExternalMemoryImageCreateInfo);
DECLARE_REFLECTION_STRUCT(VkExportMemoryAllocateInfo);
DECLARE_REFLECTION_STRUCT(VkExternalMemoryBufferCreateInfo);
DECLARE_REFLECTION_STRUCT(VkImportMemoryFdInfoKHR);
DECLARE_REFLECTION_STRUCT(VkExportSemaphoreCreateInfo);
DECLARE_REFLECTION_STRUCT(VkExportFenceCreateInfo);
DECLARE_REFLECTION_STRUCT(VkSwapchainCounterCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationMemoryAllocateInfoNV);
DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationImageCreateInfoNV);
DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationBufferCreateInfoNV);
DECLARE_REFLECTION_STRUCT(VkMemoryDedicatedAllocateInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceQueueGlobalPriorityCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkBindImagePlaneMemoryInfo);
DECLARE_REFLECTION_STRUCT(VkSamplerYcbcrConversionInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceGroupSwapchainCreateInfoKHR);
DECLARE_REFLECTION_STRUCT(VkBindImageMemorySwapchainInfoKHR);
DECLARE_REFLECTION_STRUCT(VkImageSwapchainCreateInfoKHR);
DECLARE_REFLECTION_STRUCT(VkBindImageMemoryDeviceGroupInfo);
DECLARE_REFLECTION_STRUCT(VkBindBufferMemoryDeviceGroupInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceGroupBindSparseInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceGroupSubmitInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceGroupCommandBufferBeginInfo);
DECLARE_REFLECTION_STRUCT(VkDeviceGroupRenderPassBeginInfo);
DECLARE_REFLECTION_STRUCT(VkMemoryAllocateFlagsInfo);
DECLARE_REFLECTION_STRUCT(VkProtectedSubmitInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceCreateInfo);
DECLARE_DESERIALISE_TYPE(VkBufferCreateInfo);
@@ -676,6 +704,62 @@ DECLARE_DESERIALISE_TYPE(VkDebugUtilsLabelEXT);
DECLARE_DESERIALISE_TYPE(VkSamplerYcbcrConversionCreateInfo);
DECLARE_DESERIALISE_TYPE(VkRenderPassMultiviewCreateInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceQueueInfo2);
DECLARE_DESERIALISE_TYPE(VkExportMemoryAllocateInfoNV);
DECLARE_DESERIALISE_TYPE(VkExternalMemoryImageCreateInfoNV);
DECLARE_DESERIALISE_TYPE(VkExportMemoryAllocateInfo);
DECLARE_DESERIALISE_TYPE(VkExternalMemoryBufferCreateInfo);
DECLARE_DESERIALISE_TYPE(VkImportMemoryFdInfoKHR);
DECLARE_DESERIALISE_TYPE(VkExportSemaphoreCreateInfo);
DECLARE_DESERIALISE_TYPE(VkExportFenceCreateInfo);
DECLARE_DESERIALISE_TYPE(VkSwapchainCounterCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationMemoryAllocateInfoNV);
DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationImageCreateInfoNV);
DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationBufferCreateInfoNV);
DECLARE_DESERIALISE_TYPE(VkMemoryDedicatedAllocateInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceQueueGlobalPriorityCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkBindImagePlaneMemoryInfo);
DECLARE_DESERIALISE_TYPE(VkSamplerYcbcrConversionInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceGroupSwapchainCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkBindImageMemorySwapchainInfoKHR);
DECLARE_DESERIALISE_TYPE(VkImageSwapchainCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkBindImageMemoryDeviceGroupInfo);
DECLARE_DESERIALISE_TYPE(VkBindBufferMemoryDeviceGroupInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceGroupBindSparseInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceGroupSubmitInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceGroupCommandBufferBeginInfo);
DECLARE_DESERIALISE_TYPE(VkDeviceGroupRenderPassBeginInfo);
DECLARE_DESERIALISE_TYPE(VkMemoryAllocateFlagsInfo);
DECLARE_DESERIALISE_TYPE(VkProtectedSubmitInfo);
#if defined(VK_KHR_external_memory_win32) || defined(VK_NV_external_memory_win32)
DECLARE_REFLECTION_STRUCT(VkImportMemoryWin32HandleInfoNV);
DECLARE_REFLECTION_STRUCT(VkExportMemoryWin32HandleInfoNV);
DECLARE_REFLECTION_STRUCT(VkImportMemoryWin32HandleInfoKHR);
DECLARE_DESERIALISE_TYPE(VkImportMemoryWin32HandleInfoNV);
DECLARE_DESERIALISE_TYPE(VkExportMemoryWin32HandleInfoNV);
DECLARE_DESERIALISE_TYPE(VkImportMemoryWin32HandleInfoKHR);
#endif
#ifdef VK_KHR_external_fence_win32
DECLARE_REFLECTION_STRUCT(VkExportFenceWin32HandleInfoKHR);
DECLARE_DESERIALISE_TYPE(VkExportFenceWin32HandleInfoKHR);
#endif
#ifdef VK_KHR_external_semaphore_win32
DECLARE_REFLECTION_STRUCT(VkExportSemaphoreWin32HandleInfoKHR);
DECLARE_DESERIALISE_TYPE(VkExportSemaphoreWin32HandleInfoKHR);
#endif
#if defined(VK_KHR_win32_keyed_mutex) || defined(VK_NV_win32_keyed_mutex)
DECLARE_REFLECTION_STRUCT(VkWin32KeyedMutexAcquireReleaseInfoNV);
DECLARE_REFLECTION_STRUCT(VkWin32KeyedMutexAcquireReleaseInfoKHR);
DECLARE_DESERIALISE_TYPE(VkWin32KeyedMutexAcquireReleaseInfoNV);
DECLARE_DESERIALISE_TYPE(VkWin32KeyedMutexAcquireReleaseInfoKHR);
#endif
DECLARE_REFLECTION_ENUM(VkFlagWithNoBits);
DECLARE_REFLECTION_ENUM(VkQueueFlagBits);
@@ -750,4 +834,12 @@ DECLARE_REFLECTION_ENUM(VkChromaLocation);
DECLARE_REFLECTION_ENUM(VkDeviceQueueCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkSubpassDescriptionFlagBits);
DECLARE_REFLECTION_ENUM(VkDescriptorSetLayoutCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkSwapchainCreateFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkSwapchainCreateFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkExternalMemoryHandleTypeFlagBitsNV);
DECLARE_REFLECTION_ENUM(VkExternalMemoryHandleTypeFlagBits);
DECLARE_REFLECTION_ENUM(VkExternalSemaphoreHandleTypeFlagBits);
DECLARE_REFLECTION_ENUM(VkExternalFenceHandleTypeFlagBits);
DECLARE_REFLECTION_ENUM(VkSurfaceCounterFlagBitsEXT);
DECLARE_REFLECTION_ENUM(VkQueueGlobalPriorityEXT);
DECLARE_REFLECTION_ENUM(VkDeviceGroupPresentModeFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkMemoryAllocateFlagBits);
+824 -102
View File
@@ -119,99 +119,139 @@ void DoSerialiseViaResourceId(SerialiserType &ser, type &el)
SERIALISE_VK_HANDLES();
#if ENABLED(RDOC_WIN32)
#define HANDLE_PNEXT_OS() \
/* VK_NV_external_memory_win32 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV, VkImportMemoryWin32HandleInfoNV) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV, VkExportMemoryWin32HandleInfoNV) \
\
/* VK_NV_win32_keyed_mutex */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV, \
VkWin32KeyedMutexAcquireReleaseInfoNV) \
\
/* VK_KHR_win32_keyed_mutex */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR, \
VkWin32KeyedMutexAcquireReleaseInfoKHR) \
\
/* VK_KHR_external_memory_win32 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, \
VkImportMemoryWin32HandleInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR, \
VkImportMemoryWin32HandleInfoKHR) \
\
/* VK_KHR_external_semaphore_win32 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, \
VkExportSemaphoreWin32HandleInfoKHR) \
\
/* VK_KHR_external_fence_win32 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR, VkExportFenceWin32HandleInfoKHR)
#else
#define HANDLE_PNEXT_OS()
#endif
// pNext structure type dispatch
#define HANDLE_PNEXT() \
/* we can ignore all external memory extension structs entirely. We don't need to */ \
/* serialise or replay it as we won't actually use external memory and will just create */ \
/* normal memory to replay with. */ \
\
/* VK_NV_external_memory / VK_NV_external_memory_win32 */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV) \
\
/* VK_NV_win32_keyed_mutex */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV) \
\
/* VK_KHR_external_memory / ..._fd / .._win32 */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR) \
\
/* VK_KHR_external_semaphore / .._fd / ..._win32 */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR) \
\
/* VK_KHR_external_fence / .._fd / ..._win32 */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR) \
\
/* we don't create real swapchains on replay, so we can ignore surface counters */ \
/* VK_EXT_display_control */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT) \
\
/* for now we don't serialise dedicated memory on replay as it's only a performance */ \
/* hint, and is only required in conjunction with shared memory (which we don't */ \
/* replay). In future it might be helpful to serialise this for informational purposes. */ \
\
/* VK_NV_dedicated_allocation */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV) \
\
/* VK_KHR_dedicated_allocation */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO) \
\
/* VK_EXT_global_priority */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT) \
\
/* for now we don't support ycbcr and force-disable the feature bit, so no-one should try */ \
/* to pNext any of these structs anyway, but if they do, we ignore them */ \
/* VK_KHR_sampler_ycbcr_conversion */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO) \
\
/* for now we don't handle true device groups and report all physdevices in separate groups. */ \
/* So we can safely ignore these structures as redundant/unneeded. */ \
/* VK_KHR_sampler_ycbcr_conversion */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO) \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO) \
\
/* Vulkan 1.1 - protected memory */ \
PNEXT_IGNORE(VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO) \
\
/* VK_EXT_conservative_rasterization */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, \
VkPipelineRasterizationConservativeStateCreateInfoEXT) \
\
/* VK_KHR_maintenance2 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, \
VkPipelineTessellationDomainOriginStateCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, VkImageViewUsageCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, \
VkRenderPassInputAttachmentAspectCreateInfo) \
\
/* VK_EXT_vertex_attribute_divisor */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT, \
VkPipelineVertexInputDivisorStateCreateInfoEXT) \
\
/* VK_EXT_sampler_filter_minmax */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT, \
VkSamplerReductionModeCreateInfoEXT) \
\
/* VK_KHR_multiview */ \
#define HANDLE_PNEXT() \
/* we can ignore all external memory extension structs entirely. We don't need to */ \
/* serialise or replay it as we won't actually use external memory and will just create */ \
/* normal memory to replay with. */ \
\
/* OS-specific extensions */ \
HANDLE_PNEXT_OS() \
\
/* VK_NV_external_memory */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV, VkExportMemoryAllocateInfoNV) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV, \
VkExternalMemoryImageCreateInfoNV) \
\
/* VK_KHR_external_memory / ..._fd */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, VkExportMemoryAllocateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, VkExternalMemoryImageCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, \
VkExternalMemoryBufferCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, VkImportMemoryFdInfoKHR) \
\
/* VK_KHR_external_semaphore */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, VkExportSemaphoreCreateInfo) \
\
/* VK_KHR_external_fence */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, VkExportFenceCreateInfo) \
\
/* we don't create real swapchains on replay, so we can ignore surface counters */ \
/* VK_EXT_display_control */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT, VkSwapchainCounterCreateInfoEXT) \
\
/* for now we don't serialise dedicated memory on replay as it's only a performance */ \
/* hint, and is only required in conjunction with shared memory (which we don't */ \
/* replay). In future it might be helpful to serialise this for informational purposes. */ \
\
/* VK_NV_dedicated_allocation */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV, \
VkDedicatedAllocationMemoryAllocateInfoNV) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV, \
VkDedicatedAllocationImageCreateInfoNV) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV, \
VkDedicatedAllocationBufferCreateInfoNV) \
\
/* VK_KHR_dedicated_allocation */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, VkMemoryDedicatedAllocateInfo) \
\
/* VK_EXT_global_priority */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT, \
VkDeviceQueueGlobalPriorityCreateInfoEXT) \
\
/* for now we don't support ycbcr and force-disable the feature bit, so no-one should try */ \
/* to pNext any of these structs anyway, but if they do, we ignore them */ \
/* VK_KHR_sampler_ycbcr_conversion */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, VkBindImagePlaneMemoryInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VkSamplerYcbcrConversionInfo) \
\
/* for now we don't handle true device groups and report all physdevices in separate groups. */ \
/* So we can safely ignore these structures as redundant/unneeded. */ \
/* VK_KHR_device_group */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR, \
VkDeviceGroupSwapchainCreateInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR, \
VkBindImageMemorySwapchainInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR, VkImageSwapchainCreateInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, \
VkBindImageMemoryDeviceGroupInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, \
VkBindBufferMemoryDeviceGroupInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, VkDeviceGroupBindSparseInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, VkDeviceGroupSubmitInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, \
VkDeviceGroupCommandBufferBeginInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, \
VkDeviceGroupRenderPassBeginInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, VkMemoryAllocateFlagsInfo) \
\
/* Vulkan 1.1 - protected memory */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO, VkProtectedSubmitInfo) \
\
/* VK_EXT_conservative_rasterization */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, \
VkPipelineRasterizationConservativeStateCreateInfoEXT) \
\
/* VK_KHR_maintenance2 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, \
VkPipelineTessellationDomainOriginStateCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, VkImageViewUsageCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, \
VkRenderPassInputAttachmentAspectCreateInfo) \
\
/* VK_EXT_vertex_attribute_divisor */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT, \
VkPipelineVertexInputDivisorStateCreateInfoEXT) \
\
/* VK_EXT_sampler_filter_minmax */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT, \
VkSamplerReductionModeCreateInfoEXT) \
\
/* VK_KHR_multiview */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VkRenderPassMultiviewCreateInfo)
template <typename SerialiserType>
@@ -243,10 +283,6 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
// thing user-facing.
ser.Named("pNextType").Hidden();
// any pNext structs that we ignore should not be present on reading - print an error
#define PNEXT_IGNORE(StructType) \
case StructType: RDCERR("Serialised ignore struct %s", ToStr(*nextType).c_str()); break;
// if we come across a struct we should process, then serialise a pointer to it.
#define PNEXT_STRUCT(StructType, StructName) \
case StructType: \
@@ -278,11 +314,6 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
}
else // ser.IsWriting()
{
// any pNext structs that we ignore, just break and keep walking the chain
#undef PNEXT_IGNORE
#define PNEXT_IGNORE(StructType) \
case StructType: break;
// if we come across a struct we should process, then serialise a pointer to its type (to tell the
// reading serialisation what struct is coming up), then a pointer to it.
// We don't have to go any further, the act of serialising this struct will walk the chain further,
@@ -2453,6 +2484,443 @@ void Deserialise(const VkDeviceQueueInfo2 &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportMemoryAllocateInfoNV &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBitsNV, handleTypes);
}
template <>
void Deserialise(const VkExportMemoryAllocateInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExternalMemoryImageCreateInfoNV &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBitsNV, handleTypes);
}
template <>
void Deserialise(const VkExternalMemoryImageCreateInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExternalMemoryImageCreateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBits, handleTypes);
}
template <>
void Deserialise(const VkExternalMemoryImageCreateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportMemoryAllocateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBits, handleTypes);
}
template <>
void Deserialise(const VkExportMemoryAllocateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExternalMemoryBufferCreateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBits, handleTypes);
}
template <>
void Deserialise(const VkExternalMemoryBufferCreateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkImportMemoryFdInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(handleType);
SERIALISE_MEMBER(fd);
}
template <>
void Deserialise(const VkImportMemoryFdInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportSemaphoreCreateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalSemaphoreHandleTypeFlagBits, handleTypes);
}
template <>
void Deserialise(const VkExportSemaphoreCreateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportFenceCreateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalFenceHandleTypeFlagBits, handleTypes);
}
template <>
void Deserialise(const VkExportFenceCreateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkSwapchainCounterCreateInfoEXT &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkSurfaceCounterFlagBitsEXT, surfaceCounters);
}
template <>
void Deserialise(const VkSwapchainCounterCreateInfoEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDedicatedAllocationMemoryAllocateInfoNV &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(image);
SERIALISE_MEMBER(buffer);
}
template <>
void Deserialise(const VkDedicatedAllocationMemoryAllocateInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDedicatedAllocationImageCreateInfoNV &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(dedicatedAllocation);
}
template <>
void Deserialise(const VkDedicatedAllocationImageCreateInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDedicatedAllocationBufferCreateInfoNV &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(dedicatedAllocation);
}
template <>
void Deserialise(const VkDedicatedAllocationBufferCreateInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkMemoryDedicatedAllocateInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(image);
SERIALISE_MEMBER(buffer);
}
template <>
void Deserialise(const VkMemoryDedicatedAllocateInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceQueueGlobalPriorityCreateInfoEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(globalPriority);
}
template <>
void Deserialise(const VkDeviceQueueGlobalPriorityCreateInfoEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkBindImagePlaneMemoryInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(planeAspect);
}
template <>
void Deserialise(const VkBindImagePlaneMemoryInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkSamplerYcbcrConversionInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(conversion);
}
template <>
void Deserialise(const VkSamplerYcbcrConversionInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceGroupSwapchainCreateInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkDeviceGroupPresentModeFlagBitsKHR, modes);
}
template <>
void Deserialise(const VkDeviceGroupSwapchainCreateInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkBindImageMemorySwapchainInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(swapchain);
SERIALISE_MEMBER(imageIndex);
}
template <>
void Deserialise(const VkBindImageMemorySwapchainInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkImageSwapchainCreateInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(swapchain);
}
template <>
void Deserialise(const VkImageSwapchainCreateInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkBindImageMemoryDeviceGroupInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(deviceIndexCount);
SERIALISE_MEMBER_ARRAY(pDeviceIndices, deviceIndexCount);
SERIALISE_MEMBER(splitInstanceBindRegionCount);
SERIALISE_MEMBER_ARRAY(pSplitInstanceBindRegions, splitInstanceBindRegionCount);
}
template <>
void Deserialise(const VkBindImageMemoryDeviceGroupInfo &el)
{
DeserialiseNext(el.pNext);
delete[] el.pDeviceIndices;
delete[] el.pSplitInstanceBindRegions;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkBindBufferMemoryDeviceGroupInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(deviceIndexCount);
SERIALISE_MEMBER_ARRAY(pDeviceIndices, deviceIndexCount);
}
template <>
void Deserialise(const VkBindBufferMemoryDeviceGroupInfo &el)
{
DeserialiseNext(el.pNext);
delete[] el.pDeviceIndices;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceGroupBindSparseInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(resourceDeviceIndex);
SERIALISE_MEMBER(memoryDeviceIndex);
}
template <>
void Deserialise(const VkDeviceGroupBindSparseInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceGroupSubmitInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(waitSemaphoreCount);
SERIALISE_MEMBER_ARRAY(pWaitSemaphoreDeviceIndices, waitSemaphoreCount);
SERIALISE_MEMBER(commandBufferCount);
SERIALISE_MEMBER_ARRAY(pCommandBufferDeviceMasks, commandBufferCount);
SERIALISE_MEMBER(signalSemaphoreCount);
SERIALISE_MEMBER_ARRAY(pSignalSemaphoreDeviceIndices, signalSemaphoreCount);
}
template <>
void Deserialise(const VkDeviceGroupSubmitInfo &el)
{
DeserialiseNext(el.pNext);
delete[] el.pWaitSemaphoreDeviceIndices;
delete[] el.pCommandBufferDeviceMasks;
delete[] el.pSignalSemaphoreDeviceIndices;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceGroupCommandBufferBeginInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(deviceMask);
}
template <>
void Deserialise(const VkDeviceGroupCommandBufferBeginInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDeviceGroupRenderPassBeginInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(deviceMask);
SERIALISE_MEMBER(deviceRenderAreaCount);
SERIALISE_MEMBER_ARRAY(pDeviceRenderAreas, deviceRenderAreaCount);
}
template <>
void Deserialise(const VkDeviceGroupRenderPassBeginInfo &el)
{
DeserialiseNext(el.pNext);
delete[] el.pDeviceRenderAreas;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkMemoryAllocateFlagsInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkMemoryAllocateFlagBits, flags);
SERIALISE_MEMBER(deviceMask);
}
template <>
void Deserialise(const VkMemoryAllocateFlagsInfo &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkProtectedSubmitInfo &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(protectedSubmit);
}
template <>
void Deserialise(const VkProtectedSubmitInfo &el)
{
DeserialiseNext(el.pNext);
}
INSTANTIATE_SERIALISE_TYPE(VkOffset2D);
INSTANTIATE_SERIALISE_TYPE(VkExtent2D);
INSTANTIATE_SERIALISE_TYPE(VkMemoryType);
@@ -2560,7 +3028,261 @@ INSTANTIATE_SERIALISE_TYPE(VkDebugUtilsLabelEXT);
INSTANTIATE_SERIALISE_TYPE(VkSamplerYcbcrConversionCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkRenderPassMultiviewCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceQueueInfo2);
INSTANTIATE_SERIALISE_TYPE(VkExportMemoryAllocateInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkExternalMemoryImageCreateInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkExportMemoryAllocateInfo);
INSTANTIATE_SERIALISE_TYPE(VkExternalMemoryBufferCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkImportMemoryFdInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkExportSemaphoreCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkExportFenceCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkSwapchainCounterCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkDedicatedAllocationMemoryAllocateInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkDedicatedAllocationImageCreateInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkDedicatedAllocationBufferCreateInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkMemoryDedicatedAllocateInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceQueueGlobalPriorityCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkBindImagePlaneMemoryInfo);
INSTANTIATE_SERIALISE_TYPE(VkSamplerYcbcrConversionInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupSwapchainCreateInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkBindImageMemorySwapchainInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkImageSwapchainCreateInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkBindImageMemoryDeviceGroupInfo);
INSTANTIATE_SERIALISE_TYPE(VkBindBufferMemoryDeviceGroupInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupBindSparseInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupSubmitInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupCommandBufferBeginInfo);
INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupRenderPassBeginInfo);
INSTANTIATE_SERIALISE_TYPE(VkMemoryAllocateFlagsInfo);
INSTANTIATE_SERIALISE_TYPE(VkProtectedSubmitInfo);
INSTANTIATE_SERIALISE_TYPE(DescriptorSetSlot);
INSTANTIATE_SERIALISE_TYPE(ImageRegionState);
INSTANTIATE_SERIALISE_TYPE(ImageLayouts);
INSTANTIATE_SERIALISE_TYPE(ImageLayouts);
#if defined(VK_KHR_external_memory_win32) || defined(VK_NV_external_memory_win32)
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkImportMemoryWin32HandleInfoNV &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_TYPED(VkExternalMemoryHandleTypeFlagBitsNV, handleType);
{
uint64_t handle = (uint64_t)el.handle;
ser.Serialise("handle", handle);
// won't be valid on read, though we won't try to replay this anyway
if(ser.IsReading())
el.handle = NULL;
}
}
template <>
void Deserialise(const VkImportMemoryWin32HandleInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportMemoryWin32HandleInfoNV &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
{
// serialise pointer as plain integer, rather than recursing and serialising struct
uint64_t pAttributes = (uint64_t)el.pAttributes;
ser.Serialise("pAttributes", pAttributes).TypedAs("SECURITY_ATTRIBUTES*");
// won't be valid on read, though we won't try to replay this anyway
if(ser.IsReading())
el.pAttributes = NULL;
}
SERIALISE_MEMBER_TYPED(uint32_t, dwAccess);
}
template <>
void Deserialise(const VkExportMemoryWin32HandleInfoNV &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkImportMemoryWin32HandleInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(handleType);
{
uint64_t handle = (uint64_t)el.handle;
ser.Serialise("handle", handle);
// won't be valid on read, though we won't try to replay this anyway
if(ser.IsReading())
el.handle = NULL;
}
{
std::string name = StringFormat::Wide2UTF8(std::wstring(el.name));
ser.Serialise("name", name);
// we don't expose UTF82Wide on all platforms, but as above this struct won't be valid anyway
if(ser.IsReading())
el.name = L"???";
}
}
template <>
void Deserialise(const VkImportMemoryWin32HandleInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
INSTANTIATE_SERIALISE_TYPE(VkImportMemoryWin32HandleInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkExportMemoryWin32HandleInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkImportMemoryWin32HandleInfoKHR);
#endif // #if defined(VK_KHR_external_memory_win32) || defined(VK_NV_external_memory_win32)
#ifdef VK_KHR_external_fence_win32
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportFenceWin32HandleInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
{
// serialise pointer as plain integer, rather than recursing and serialising struct
uint64_t pAttributes = (uint64_t)el.pAttributes;
ser.Serialise("pAttributes", pAttributes).TypedAs("SECURITY_ATTRIBUTES*");
// won't be valid on read, though we won't try to replay this anyway
if(ser.IsReading())
el.pAttributes = NULL;
}
SERIALISE_MEMBER_TYPED(uint32_t, dwAccess);
{
std::string name = StringFormat::Wide2UTF8(std::wstring(el.name));
ser.Serialise("name", name);
// we don't expose UTF82Wide on all platforms, but as above this struct won't be valid anyway
if(ser.IsReading())
el.name = L"???";
}
}
template <>
void Deserialise(const VkExportFenceWin32HandleInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
INSTANTIATE_SERIALISE_TYPE(VkExportFenceWin32HandleInfoKHR);
#endif // #ifdef VK_KHR_external_fence_win32
#ifdef VK_KHR_external_semaphore_win32
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkExportSemaphoreWin32HandleInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
{
// serialise pointer as plain integer, rather than recursing and serialising struct
uint64_t pAttributes = (uint64_t)el.pAttributes;
ser.Serialise("pAttributes", pAttributes).TypedAs("SECURITY_ATTRIBUTES*");
// won't be valid on read, though we won't try to replay this anyway
if(ser.IsReading())
el.pAttributes = NULL;
}
SERIALISE_MEMBER_TYPED(uint32_t, dwAccess);
{
std::string name = StringFormat::Wide2UTF8(std::wstring(el.name));
ser.Serialise("name", name);
// we don't expose UTF82Wide on all platforms, but as above this struct won't be valid anyway
if(ser.IsReading())
el.name = L"???";
}
}
template <>
void Deserialise(const VkExportSemaphoreWin32HandleInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
INSTANTIATE_SERIALISE_TYPE(VkExportSemaphoreWin32HandleInfoKHR);
#endif // #ifdef VK_KHR_external_semaphore_win32
#if defined(VK_KHR_win32_keyed_mutex) || defined(VK_NV_win32_keyed_mutex)
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkWin32KeyedMutexAcquireReleaseInfoNV &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireSyncs, acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireKeys, acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireTimeoutMilliseconds, acquireCount);
SERIALISE_MEMBER(releaseCount);
SERIALISE_MEMBER_ARRAY(pReleaseSyncs, releaseCount);
SERIALISE_MEMBER_ARRAY(pReleaseKeys, releaseCount);
}
template <>
void Deserialise(const VkWin32KeyedMutexAcquireReleaseInfoNV &el)
{
DeserialiseNext(el.pNext);
delete[] el.pAcquireSyncs;
delete[] el.pAcquireKeys;
delete[] el.pAcquireTimeoutMilliseconds;
delete[] el.pReleaseSyncs;
delete[] el.pReleaseKeys;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkWin32KeyedMutexAcquireReleaseInfoKHR &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireSyncs, acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireKeys, acquireCount);
SERIALISE_MEMBER_ARRAY(pAcquireTimeouts, acquireCount);
SERIALISE_MEMBER(releaseCount);
SERIALISE_MEMBER_ARRAY(pReleaseSyncs, releaseCount);
SERIALISE_MEMBER_ARRAY(pReleaseKeys, releaseCount);
}
template <>
void Deserialise(const VkWin32KeyedMutexAcquireReleaseInfoKHR &el)
{
DeserialiseNext(el.pNext);
delete[] el.pAcquireSyncs;
delete[] el.pAcquireKeys;
delete[] el.pAcquireTimeouts;
delete[] el.pReleaseSyncs;
delete[] el.pReleaseKeys;
}
INSTANTIATE_SERIALISE_TYPE(VkWin32KeyedMutexAcquireReleaseInfoNV);
INSTANTIATE_SERIALISE_TYPE(VkWin32KeyedMutexAcquireReleaseInfoKHR);
#endif // #if defined(VK_KHR_win32_keyed_mutex) || defined(VK_NV_win32_keyed_mutex)
+107
View File
@@ -580,6 +580,100 @@ std::string DoStringise(const VkAccessFlagBits &el)
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkExternalMemoryHandleTypeFlagBitsNV &el)
{
BEGIN_BITFIELD_STRINGISE(VkExternalMemoryHandleTypeFlagBitsNV);
{
STRINGISE_BITFIELD_BIT(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkExternalMemoryHandleTypeFlagBits &el)
{
BEGIN_BITFIELD_STRINGISE(VkExternalMemoryHandleTypeFlagBits);
{
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkExternalSemaphoreHandleTypeFlagBits &el)
{
BEGIN_BITFIELD_STRINGISE(VkExternalSemaphoreHandleTypeFlagBits);
{
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkExternalFenceHandleTypeFlagBits &el)
{
BEGIN_BITFIELD_STRINGISE(VkExternalFenceHandleTypeFlagBits);
{
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
STRINGISE_BITFIELD_BIT(VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkSurfaceCounterFlagBitsEXT &el)
{
BEGIN_BITFIELD_STRINGISE(VkSurfaceCounterFlagBitsEXT);
{
STRINGISE_BITFIELD_BIT(VK_SURFACE_COUNTER_VBLANK_EXT);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkDeviceGroupPresentModeFlagBitsKHR &el)
{
BEGIN_BITFIELD_STRINGISE(VkDeviceGroupPresentModeFlagBitsKHR);
{
STRINGISE_BITFIELD_BIT(VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR);
STRINGISE_BITFIELD_BIT(VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR);
STRINGISE_BITFIELD_BIT(VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR);
STRINGISE_BITFIELD_BIT(VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkMemoryAllocateFlagBits &el)
{
BEGIN_BITFIELD_STRINGISE(VkMemoryAllocateFlagBits);
{
STRINGISE_BITFIELD_BIT(VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT);
}
END_BITFIELD_STRINGISE();
}
template <>
std::string DoStringise(const VkStencilFaceFlagBits &el)
{
@@ -1814,6 +1908,19 @@ std::string DoStringise(const VkSwapchainCreateFlagBitsKHR &el)
END_ENUM_STRINGISE();
}
template <>
std::string DoStringise(const VkQueueGlobalPriorityEXT &el)
{
BEGIN_ENUM_STRINGISE(VkQueueGlobalPriorityEXT);
{
STRINGISE_ENUM(VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT)
STRINGISE_ENUM(VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT)
STRINGISE_ENUM(VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT)
STRINGISE_ENUM(VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT)
}
END_ENUM_STRINGISE();
}
template <>
std::string DoStringise(const VkExtent3D &el)
{
@@ -626,6 +626,11 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
unwrappedBeginInfo.pInheritanceInfo = &unwrappedInheritInfo;
}
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedBeginInfo.pNext));
UnwrapNextChain(m_State, "VkCommandBufferBeginInfo", tempMem,
(VkGenericStruct *)&unwrappedBeginInfo);
if(IsActiveReplaying(m_State))
{
const uint32_t length = m_BakedCmdBufferInfo[BakedCommandBuffer].eventCount;
@@ -816,6 +821,10 @@ VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
beginInfo.pInheritanceInfo = &unwrappedInfo;
}
byte *tempMem = GetTempMemory(GetNextPatchSize(beginInfo.pNext));
UnwrapNextChain(m_State, "VkCommandBufferBeginInfo", tempMem, (VkGenericStruct *)&beginInfo);
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), &beginInfo));
@@ -1039,6 +1048,10 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman
unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass);
unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer);
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedInfo.pNext));
UnwrapNextChain(m_State, "VkRenderPassBeginInfo", tempMem, (VkGenericStruct *)&unwrappedInfo);
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
if(IsActiveReplaying(m_State))
@@ -1113,6 +1126,11 @@ void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
VkRenderPassBeginInfo unwrappedInfo = *pRenderPassBegin;
unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass);
unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer);
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedInfo.pNext));
UnwrapNextChain(m_State, "VkRenderPassBeginInfo", tempMem, (VkGenericStruct *)&unwrappedInfo);
SERIALISE_TIME_CALL(
ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents));
@@ -421,7 +421,13 @@ bool WrappedVulkan::Serialise_vkCreateSampler(SerialiserType &ser, VkDevice devi
{
VkSampler samp = VK_NULL_HANDLE;
VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), &CreateInfo, NULL, &samp);
VkSamplerCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkSamplerCreateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), &patched, NULL, &samp);
if(ret != VK_SUCCESS)
{
@@ -466,7 +472,7 @@ VkResult WrappedVulkan::vkCreateSampler(VkDevice device, const VkSamplerCreateIn
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
PatchNextChain("VkSamplerCreateInfo", tempMem, (VkGenericStruct *)&info);
UnwrapNextChain(m_State, "VkSamplerCreateInfo", tempMem, (VkGenericStruct *)&info);
VkResult ret;
SERIALISE_TIME_CALL(
@@ -174,8 +174,21 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(SerialiserType &ser, VkQueue queue,
// don't submit the fence, since we have nothing to wait on it being signalled, and we might
// not have it correctly in the unsignalled state.
VkSubmitInfo unwrapped = submitInfo;
unwrapped.pCommandBuffers =
UnwrapArray(unwrapped.pCommandBuffers, unwrapped.commandBufferCount);
size_t tempMemSize = unwrapped.commandBufferCount * sizeof(VkCommandBuffer) +
GetNextPatchSize(unwrapped.pNext);
byte *tempMem = GetTempMemory(tempMemSize);
VkCommandBuffer *unwrappedCmds = (VkCommandBuffer *)tempMem;
unwrapped.pCommandBuffers = unwrappedCmds;
for(uint32_t i = 0; i < unwrapped.commandBufferCount; i++)
unwrappedCmds[i] = Unwrap(submitInfo.pCommandBuffers[i]);
tempMem += unwrapped.commandBufferCount * sizeof(VkCommandBuffer);
UnwrapNextChain(m_State, "VkSubmitInfo", tempMem, (VkGenericStruct *)&unwrapped);
ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &unwrapped, VK_NULL_HANDLE);
AddEvent();
@@ -448,56 +461,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
tempmemSize += pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore);
tempmemSize += pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore);
VkGenericStruct *next = (VkGenericStruct *)pSubmits[i].pNext;
while(next)
{
if(next->sType == VK_STRUCTURE_TYPE_MAX_ENUM)
{
RDCERR("Invalid extension structure");
}
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR)
{
#ifdef VK_USE_PLATFORM_WIN32_KHR
// make sure the structures are still identical
RDCCOMPILE_ASSERT(sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV) ==
sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHR),
"Structs are different!");
#define NV_DUMMY ((VkWin32KeyedMutexAcquireReleaseInfoNV *)NULL)
#define KHR_DUMMY ((VkWin32KeyedMutexAcquireReleaseInfoKHR *)NULL)
RDCCOMPILE_ASSERT(&NV_DUMMY->acquireCount == &KHR_DUMMY->acquireCount,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->releaseCount == &KHR_DUMMY->releaseCount,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->pAcquireSyncs == &KHR_DUMMY->pAcquireSyncs,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->pReleaseSyncs == &KHR_DUMMY->pReleaseSyncs,
"Structs are different!");
#undef NV_DUMMY
#undef KHR_DUMMY
tempmemSize += sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHR);
VkWin32KeyedMutexAcquireReleaseInfoKHR *info = (VkWin32KeyedMutexAcquireReleaseInfoKHR *)next;
tempmemSize += info->acquireCount * sizeof(VkDeviceMemory);
tempmemSize += info->releaseCount * sizeof(VkDeviceMemory);
#else
RDCERR("Unexpected use of Win32 Keyed Mutex extension without support compiled in");
#endif
}
else if(next->sType == VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR)
{
// nothing to do - this is plain old data with nothing to unwrap so we can keep it in the
// pNext chain as-is
}
else
{
RDCERR("Unexpected extension structure %d", next->sType);
}
next = (VkGenericStruct *)next->pNext;
}
tempmemSize += GetNextPatchSize(pSubmits[i].pNext);
}
byte *memory = GetTempMemory(tempmemSize);
@@ -535,49 +499,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
for(uint32_t o = 0; o < unwrappedSubmits[i].signalSemaphoreCount; o++)
unwrappedSignalSems[o] = Unwrap(pSubmits[i].pSignalSemaphores[o]);
VkGenericStruct **nextptr = (VkGenericStruct **)&unwrappedSubmits[i].pNext;
while(*nextptr)
{
VkGenericStruct *next = *nextptr;
if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR)
{
#ifdef VK_USE_PLATFORM_WIN32_KHR
// allocate local unwrapped struct
VkWin32KeyedMutexAcquireReleaseInfoKHR *unwrappedMutexInfoKHR =
(VkWin32KeyedMutexAcquireReleaseInfoKHR *)memory;
memory += sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHR);
// copy over info from original struct
VkWin32KeyedMutexAcquireReleaseInfoKHR *wrappedMutexInfoKHR =
(VkWin32KeyedMutexAcquireReleaseInfoKHR *)next;
*unwrappedMutexInfoKHR = *wrappedMutexInfoKHR;
// allocate unwrapped arrays
VkDeviceMemory *unwrappedAcquires = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoKHR->acquireCount;
VkDeviceMemory *unwrappedReleases = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoKHR->releaseCount;
// unwrap the arrays
for(uint32_t mem = 0; mem < unwrappedMutexInfoKHR->acquireCount; mem++)
unwrappedAcquires[mem] = Unwrap(wrappedMutexInfoKHR->pAcquireSyncs[mem]);
for(uint32_t mem = 0; mem < unwrappedMutexInfoKHR->releaseCount; mem++)
unwrappedReleases[mem] = Unwrap(wrappedMutexInfoKHR->pReleaseSyncs[mem]);
unwrappedMutexInfoKHR->pAcquireSyncs = unwrappedAcquires;
unwrappedMutexInfoKHR->pReleaseSyncs = unwrappedReleases;
// insert this struct into the chain.
// nextptr is pointing to the address of the pNext, so we can overwrite it to point to our
// locally-allocated unwrapped struct
*nextptr = (VkGenericStruct *)unwrappedMutexInfoKHR;
#endif
}
nextptr = (VkGenericStruct **)&next->pNext;
}
UnwrapNextChain(m_State, "VkSubmitInfo", memory, (VkGenericStruct *)&unwrappedSubmits[i]);
}
VkResult ret;
@@ -911,6 +833,8 @@ VkResult WrappedVulkan::vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
for(uint32_t i = 0; i < bindInfoCount; i++)
{
tempmemSize += GetNextPatchSize(pBindInfo[i].pNext);
// within each batch, need to allocate space for each resource bind
tempmemSize += pBindInfo[i].bufferBindCount * sizeof(VkSparseBufferMemoryBindInfo);
tempmemSize += pBindInfo[i].imageOpaqueBindCount * sizeof(VkSparseImageOpaqueMemoryBindInfo);
@@ -939,6 +863,8 @@ VkResult WrappedVulkan::vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
RDCASSERT(pBindInfo[i].sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO && pBindInfo[i].pNext == NULL);
unwrapped[i] = pBindInfo[i];
UnwrapNextChain(m_State, "VkBindSparseInfo", next, (VkGenericStruct *)&unwrapped[i]);
// unwrap the signal semaphores into a new array
VkSemaphore *signal = (VkSemaphore *)next;
next += sizeof(VkSemaphore) * unwrapped[i].signalSemaphoreCount;
@@ -174,7 +174,7 @@ VkBindImageMemoryInfo *WrappedVulkan::UnwrapInfos(const VkBindImageMemoryInfo *i
for(uint32_t i = 0; i < count; i++)
{
PatchNextChain("VkBindImageMemoryInfo", tempMem, (VkGenericStruct *)&ret[i]);
UnwrapNextChain(m_State, "VkBindImageMemoryInfo", tempMem, (VkGenericStruct *)&ret[i]);
ret[i].image = Unwrap(ret[i].image);
ret[i].memory = Unwrap(ret[i].memory);
}
@@ -258,7 +258,13 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev
// appropriate index on replay
AllocateInfo.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[AllocateInfo.memoryTypeIndex];
VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &AllocateInfo, NULL, &mem);
VkMemoryAllocateInfo patched = AllocateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkMemoryAllocateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &patched, NULL, &mem);
if(ret != VK_SUCCESS)
{
@@ -375,13 +381,15 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
ObjDisp(device)->DestroyBuffer(Unwrap(device), buf, NULL);
}
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
VkMemoryAllocateInfo unwrapped = info;
PatchNextChain("VkMemoryAllocateInfo", tempMem, (VkGenericStruct *)&info);
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrapped.pNext));
UnwrapNextChain(m_State, "VkMemoryAllocateInfo", tempMem, (VkGenericStruct *)&unwrapped);
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, pAllocator, pMemory));
ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &unwrapped, pAllocator, pMemory));
// restore the memoryTypeIndex to the original, as that's what we want to serialise,
// but maintain any potential modifications we made to info.allocationSize
@@ -1001,7 +1009,13 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic
// ensure we can always readback from buffers
CreateInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &CreateInfo, NULL, &buf);
VkBufferCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkBufferCreateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &patched, NULL, &buf);
if(CreateInfo.flags &
(VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT))
@@ -1040,6 +1054,10 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo
// on replay, so that the memory requirements are the same
adjusted_info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
byte *tempMem = GetTempMemory(GetNextPatchSize(adjusted_info.pNext));
UnwrapNextChain(m_State, "VkBufferCreateInfo", tempMem, (VkGenericStruct *)&adjusted_info);
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &adjusted_info, pAllocator, pBuffer));
@@ -1266,7 +1284,13 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
APIProps.SparseResources = true;
}
VkResult ret = ObjDisp(device)->CreateImage(Unwrap(device), &CreateInfo, NULL, &img);
VkImageCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkImageCreateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->CreateImage(Unwrap(device), &patched, NULL, &img);
CreateInfo.usage = origusage;
@@ -1382,7 +1406,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
byte *tempMem = GetTempMemory(GetNextPatchSize(createInfo_adjusted.pNext));
PatchNextChain("VkImageCreateInfo", tempMem, (VkGenericStruct *)&createInfo_adjusted);
UnwrapNextChain(m_State, "VkImageCreateInfo", tempMem, (VkGenericStruct *)&createInfo_adjusted);
VkResult ret;
SERIALISE_TIME_CALL(
@@ -87,7 +87,13 @@ bool WrappedVulkan::Serialise_vkCreateFence(SerialiserType &ser, VkDevice device
{
VkFence fence = VK_NULL_HANDLE;
VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &CreateInfo, NULL, &fence);
VkFenceCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkFenceCreateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &patched, NULL, &fence);
if(ret != VK_SUCCESS)
{
@@ -110,9 +116,14 @@ bool WrappedVulkan::Serialise_vkCreateFence(SerialiserType &ser, VkDevice device
VkResult WrappedVulkan::vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkFence *pFence)
{
VkFenceCreateInfo info = *pCreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
UnwrapNextChain(m_State, "VkFenceCreateInfo", tempMem, (VkGenericStruct *)&info);
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->CreateFence(Unwrap(device), pCreateInfo, pAllocator, pFence));
SERIALISE_TIME_CALL(ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, pAllocator, pFence));
if(ret == VK_SUCCESS)
{
@@ -484,7 +495,13 @@ bool WrappedVulkan::Serialise_vkCreateSemaphore(SerialiserType &ser, VkDevice de
{
VkSemaphore sem = VK_NULL_HANDLE;
VkResult ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), &CreateInfo, NULL, &sem);
VkSemaphoreCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkSemaphoreCreateInfo", tempMem, (VkGenericStruct *)&patched);
VkResult ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), &patched, NULL, &sem);
if(ret != VK_SUCCESS)
{
@@ -528,9 +545,15 @@ VkResult WrappedVulkan::vkCreateSemaphore(VkDevice device, const VkSemaphoreCrea
const VkAllocationCallbacks *pAllocator,
VkSemaphore *pSemaphore)
{
VkSemaphoreCreateInfo info = *pCreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext));
UnwrapNextChain(m_State, "VkSemaphoreCreateInfo", tempMem, (VkGenericStruct *)&info);
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), pCreateInfo, pAllocator, pSemaphore));
ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), &info, pAllocator, pSemaphore));
if(ret == VK_SUCCESS)
{