diff --git a/renderdoc/driver/vulkan/CMakeLists.txt b/renderdoc/driver/vulkan/CMakeLists.txt index 1932850ef..30d26840c 100644 --- a/renderdoc/driver/vulkan/CMakeLists.txt +++ b/renderdoc/driver/vulkan/CMakeLists.txt @@ -21,6 +21,7 @@ set(sources vk_resources.h vk_state.cpp vk_state.h + vk_serialise.cpp vk_stringise.cpp vk_layer.cpp official/vk_layer.h @@ -79,12 +80,6 @@ elseif(UNIX) install (FILES ${json_out} DESTINATION ${VULKAN_LAYER_FOLDER}) endif() -# GCC 6.1 may or may not complain about enum reference casts -if(CMAKE_COMPILER_IS_GNUCXX) - set_source_files_properties(vk_common.cpp - PROPERTIES COMPILE_FLAGS "-Wno-strict-aliasing") -endif() - add_library(rdoc_vulkan OBJECT ${sources}) target_compile_definitions(rdoc_vulkan ${definitions}) target_include_directories(rdoc_vulkan ${RDOC_INCLUDES}) diff --git a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj index ba2b98c3e..532b4c7b7 100644 --- a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj +++ b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj @@ -104,6 +104,7 @@ true + diff --git a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters index 88c622fdc..0f3138815 100644 --- a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters +++ b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters @@ -100,6 +100,9 @@ Util + + Util + diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 51b667760..f35dab37e 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -1439,1958 +1439,3 @@ StencilOp MakeStencilOp(VkStencilOp op) return StencilOp::Keep; } - -// we know the object will be a non-dispatchable object type -#define SerialiseObjectInternal(type, name, obj, opt) \ - { \ - VulkanResourceManager *rm = (VulkanResourceManager *)GetUserData(); \ - ResourceId id; \ - if(m_Mode >= WRITING) \ - id = GetResID(obj); \ - Serialise(name, id); \ - if(m_Mode < WRITING) \ - { \ - obj = VK_NULL_HANDLE; \ - if(id != ResourceId()) \ - { \ - if(rm->HasLiveResource(id)) \ - obj = Unwrap(rm->GetLiveHandle(id)); \ - else if(!opt) \ - /* It can be OK for a resource to have no live equivalent if the */ \ - /* capture decided its not needed, which some APIs do fairly often. */ \ - RDCWARN("Capture may be missing reference to " #type " resource."); \ - } \ - } \ - } - -#define SerialiseObject(type, name, obj) SerialiseObjectInternal(type, name, obj, false) -#define SerialiseObjectOptional(type, name, obj) SerialiseObjectInternal(type, name, obj, true) - -static void SerialiseNext(Serialiser *ser, VkStructureType &sType, const void *&pNext) -{ - ser->Serialise("sType", sType); - - if(ser->IsReading()) - { - pNext = NULL; - } - else - { - if(pNext == NULL) - return; - - VkGenericStruct *next = (VkGenericStruct *)pNext; - - while(next) - { - // we can ignore this entirely, we don't need to serialise or replay it as we won't - // actually use external memory. Unwrapping, if necessary, happens elsewhere - if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV || - - next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR || - next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR) - { - // do nothing - } - // likewise we don't create real swapchains, so we can ignore surface counters - else if(next->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT) - { - // do nothing - } - // 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. - else if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV || - next->sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR) - { - // do nothing - } - else - { - RDCERR("Unrecognised extension structure type %d", next->sType); - } - - next = (VkGenericStruct *)next->pNext; - } - } -} - -template -void SerialiseOptionalObject(Serialiser *ser, const char *name, T *&el) -{ - bool present; - - present = el != NULL; - ser->Serialise((string(name) + "Present").c_str(), present); - if(present) - { - if(ser->IsReading()) - el = new T; - ser->Serialise(name, *el); - } - else if(ser->IsReading()) - { - el = NULL; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el) -{ - ScopedContext scope(this, name, "VkDeviceQueueCreateInfo", 0, true); - - // RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO); - if(m_Mode >= WRITING && el.sType != VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO) - RDCWARN("sType not set properly: %u", el.sType); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("queueFamilyIndex", el.queueFamilyIndex); - Serialise("queueCount", el.queueCount); - if(m_Mode == READING) - el.pQueuePriorities = NULL; - SerialisePODArray("pQueuePriorities", (float *&)el.pQueuePriorities, el.queueCount); -} - -// technically this doesn't need a serialise function as it's POD, -// but we give it one just for ease of printing etc. -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceFeatures &el) -{ - ScopedContext scope(this, name, "VkPhysicalDeviceFeatures", 0, true); - - Serialise("robustBufferAccess", el.robustBufferAccess); - Serialise("fullDrawIndexUint32", el.fullDrawIndexUint32); - Serialise("imageCubeArray", el.imageCubeArray); - Serialise("independentBlend", el.independentBlend); - Serialise("geometryShader", el.geometryShader); - Serialise("tessellationShader", el.tessellationShader); - Serialise("sampleRateShading", el.sampleRateShading); - Serialise("dualSrcBlend", el.dualSrcBlend); - Serialise("logicOp", el.logicOp); - Serialise("multiDrawIndirect", el.multiDrawIndirect); - Serialise("drawIndirectFirstInstance", el.drawIndirectFirstInstance); - Serialise("depthClamp", el.depthClamp); - Serialise("depthBiasClamp", el.depthBiasClamp); - Serialise("fillModeNonSolid", el.fillModeNonSolid); - Serialise("depthBounds", el.depthBounds); - Serialise("wideLines", el.wideLines); - Serialise("largePoints", el.largePoints); - Serialise("alphaToOne", el.alphaToOne); - Serialise("multiViewport", el.multiViewport); - Serialise("samplerAnisotropy", el.samplerAnisotropy); - Serialise("textureCompressionETC2", el.textureCompressionETC2); - Serialise("textureCompressionASTC_LDR", el.textureCompressionASTC_LDR); - Serialise("textureCompressionBC", el.textureCompressionBC); - Serialise("occlusionQueryPrecise", el.occlusionQueryPrecise); - Serialise("pipelineStatisticsQuery", el.pipelineStatisticsQuery); - Serialise("vertexPipelineStoresAndAtomics", el.vertexPipelineStoresAndAtomics); - Serialise("fragmentStoresAndAtomics", el.fragmentStoresAndAtomics); - Serialise("shaderTessellationAndGeometryPointSize", el.shaderTessellationAndGeometryPointSize); - Serialise("shaderImageGatherExtended", el.shaderImageGatherExtended); - Serialise("shaderStorageImageExtendedFormats", el.shaderStorageImageExtendedFormats); - Serialise("shaderStorageImageMultisample", el.shaderStorageImageMultisample); - Serialise("shaderStorageImageReadWithoutFormat", el.shaderStorageImageReadWithoutFormat); - Serialise("shaderStorageImageWriteWithoutFormat", el.shaderStorageImageWriteWithoutFormat); - Serialise("shaderUniformBufferArrayDynamicIndexing", el.shaderUniformBufferArrayDynamicIndexing); - Serialise("shaderSampledImageArrayDynamicIndexing", el.shaderSampledImageArrayDynamicIndexing); - Serialise("shaderStorageBufferArrayDynamicIndexing", el.shaderStorageBufferArrayDynamicIndexing); - Serialise("shaderStorageImageArrayDynamicIndexing", el.shaderStorageImageArrayDynamicIndexing); - Serialise("shaderClipDistance", el.shaderClipDistance); - Serialise("shaderCullDistance", el.shaderCullDistance); - Serialise("shaderFloat64", el.shaderFloat64); - Serialise("shaderInt64", el.shaderInt64); - Serialise("shaderInt16", el.shaderInt16); - Serialise("shaderResourceResidency", el.shaderResourceResidency); - Serialise("shaderResourceMinLod", el.shaderResourceMinLod); - Serialise("sparseBinding", el.sparseBinding); - Serialise("sparseResidencyBuffer", el.sparseResidencyBuffer); - Serialise("sparseResidencyImage2D", el.sparseResidencyImage2D); - Serialise("sparseResidencyImage3D", el.sparseResidencyImage3D); - Serialise("sparseResidency2Samples", el.sparseResidency2Samples); - Serialise("sparseResidency4Samples", el.sparseResidency4Samples); - Serialise("sparseResidency8Samples", el.sparseResidency8Samples); - Serialise("sparseResidency16Samples", el.sparseResidency16Samples); - Serialise("sparseResidencyAliased", el.sparseResidencyAliased); - Serialise("variableMultisampleRate", el.variableMultisampleRate); - Serialise("inheritedQueries", el.inheritedQueries); -} - -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceMemoryProperties &el) -{ - ScopedContext scope(this, name, "VkPhysicalDeviceMemoryProperties", 0, true); - - VkMemoryType *types = el.memoryTypes; - VkMemoryHeap *heaps = el.memoryHeaps; - - SerialisePODArray("memoryTypes", types, el.memoryTypeCount); - SerialisePODArray("memoryHeaps", heaps, el.memoryHeapCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceLimits &el) -{ - ScopedContext scope(this, name, "VkPhysicalDeviceLimits", 0, true); - - Serialise("maxImageDimension1D", el.maxImageDimension1D); - Serialise("maxImageDimension2D", el.maxImageDimension2D); - Serialise("maxImageDimension3D", el.maxImageDimension3D); - Serialise("maxImageDimensionCube", el.maxImageDimensionCube); - Serialise("maxImageArrayLayers", el.maxImageArrayLayers); - Serialise("maxTexelBufferElements", el.maxTexelBufferElements); - Serialise("maxUniformBufferRange", el.maxUniformBufferRange); - Serialise("maxStorageBufferRange", el.maxStorageBufferRange); - Serialise("maxPushConstantsSize", el.maxPushConstantsSize); - Serialise("maxMemoryAllocationCount", el.maxMemoryAllocationCount); - Serialise("maxSamplerAllocationCount", el.maxSamplerAllocationCount); - Serialise("bufferImageGranularity", el.bufferImageGranularity); - Serialise("sparseAddressSpaceSize", el.sparseAddressSpaceSize); - Serialise("maxBoundDescriptorSets", el.maxBoundDescriptorSets); - Serialise("maxPerStageDescriptorSamplers", el.maxPerStageDescriptorSamplers); - Serialise("maxPerStageDescriptorUniformBuffers", el.maxPerStageDescriptorUniformBuffers); - Serialise("maxPerStageDescriptorStorageBuffers", el.maxPerStageDescriptorStorageBuffers); - Serialise("maxPerStageDescriptorSampledImages", el.maxPerStageDescriptorSampledImages); - Serialise("maxPerStageDescriptorStorageImages", el.maxPerStageDescriptorStorageImages); - Serialise("maxPerStageDescriptorInputAttachments", el.maxPerStageDescriptorInputAttachments); - Serialise("maxPerStageResources", el.maxPerStageResources); - Serialise("maxDescriptorSetSamplers", el.maxDescriptorSetSamplers); - Serialise("maxDescriptorSetUniformBuffers", el.maxDescriptorSetUniformBuffers); - Serialise("maxDescriptorSetUniformBuffersDynamic", el.maxDescriptorSetUniformBuffersDynamic); - Serialise("maxDescriptorSetStorageBuffers", el.maxDescriptorSetStorageBuffers); - Serialise("maxDescriptorSetStorageBuffersDynamic", el.maxDescriptorSetStorageBuffersDynamic); - Serialise("maxDescriptorSetSampledImages", el.maxDescriptorSetSampledImages); - Serialise("maxDescriptorSetStorageImages", el.maxDescriptorSetStorageImages); - Serialise("maxDescriptorSetInputAttachments", el.maxDescriptorSetInputAttachments); - Serialise("maxVertexInputAttributes", el.maxVertexInputAttributes); - Serialise("maxVertexInputBindings", el.maxVertexInputBindings); - Serialise("maxVertexInputAttributeOffset", el.maxVertexInputAttributeOffset); - Serialise("maxVertexInputBindingStride", el.maxVertexInputBindingStride); - Serialise("maxVertexOutputComponents", el.maxVertexOutputComponents); - Serialise("maxTessellationGenerationLevel", el.maxTessellationGenerationLevel); - Serialise("maxTessellationPatchSize", el.maxTessellationPatchSize); - Serialise("maxTessellationControlPerVertexInputComponents", - el.maxTessellationControlPerVertexInputComponents); - Serialise("maxTessellationControlPerVertexOutputComponents", - el.maxTessellationControlPerVertexOutputComponents); - Serialise("maxTessellationControlPerPatchOutputComponents", - el.maxTessellationControlPerPatchOutputComponents); - Serialise("maxTessellationControlTotalOutputComponents", - el.maxTessellationControlTotalOutputComponents); - Serialise("maxTessellationEvaluationInputComponents", el.maxTessellationEvaluationInputComponents); - Serialise("maxTessellationEvaluationOutputComponents", - el.maxTessellationEvaluationOutputComponents); - Serialise("maxGeometryShaderInvocations", el.maxGeometryShaderInvocations); - Serialise("maxGeometryInputComponents", el.maxGeometryInputComponents); - Serialise("maxGeometryOutputComponents", el.maxGeometryOutputComponents); - Serialise("maxGeometryOutputVertices", el.maxGeometryOutputVertices); - Serialise("maxGeometryTotalOutputComponents", el.maxGeometryTotalOutputComponents); - Serialise("maxFragmentInputComponents", el.maxFragmentInputComponents); - Serialise("maxFragmentOutputAttachments", el.maxFragmentOutputAttachments); - Serialise("maxFragmentDualSrcAttachments", el.maxFragmentDualSrcAttachments); - Serialise("maxFragmentCombinedOutputResources", el.maxFragmentCombinedOutputResources); - Serialise("maxComputeSharedMemorySize", el.maxComputeSharedMemorySize); - SerialisePODArray<3>("maxComputeWorkGroupCount", el.maxComputeWorkGroupCount); - Serialise("maxComputeWorkGroupInvocations", el.maxComputeWorkGroupInvocations); - SerialisePODArray<3>("maxComputeWorkGroupSize", el.maxComputeWorkGroupSize); - Serialise("subPixelPrecisionBits", el.subPixelPrecisionBits); - Serialise("subTexelPrecisionBits", el.subTexelPrecisionBits); - Serialise("mipmapPrecisionBits", el.mipmapPrecisionBits); - Serialise("maxDrawIndexedIndexValue", el.maxDrawIndexedIndexValue); - Serialise("maxDrawIndirectCount", el.maxDrawIndirectCount); - Serialise("maxSamplerLodBias", el.maxSamplerLodBias); - Serialise("maxSamplerAnisotropy", el.maxSamplerAnisotropy); - Serialise("maxViewports", el.maxViewports); - SerialisePODArray<2>("maxViewportDimensions", el.maxViewportDimensions); - SerialisePODArray<2>("viewportBoundsRange", el.viewportBoundsRange); - Serialise("viewportSubPixelBits", el.viewportSubPixelBits); - uint64_t minMemoryMapAlignment = (uint64_t)el.minMemoryMapAlignment; - Serialise("minMemoryMapAlignment", minMemoryMapAlignment); - el.minMemoryMapAlignment = (size_t)minMemoryMapAlignment; - Serialise("minTexelBufferOffsetAlignment", el.minTexelBufferOffsetAlignment); - Serialise("minUniformBufferOffsetAlignment", el.minUniformBufferOffsetAlignment); - Serialise("minStorageBufferOffsetAlignment", el.minStorageBufferOffsetAlignment); - Serialise("minTexelOffset", el.minTexelOffset); - Serialise("maxTexelOffset", el.maxTexelOffset); - Serialise("minTexelGatherOffset", el.minTexelGatherOffset); - Serialise("maxTexelGatherOffset", el.maxTexelGatherOffset); - Serialise("minInterpolationOffset", el.minInterpolationOffset); - Serialise("maxInterpolationOffset", el.maxInterpolationOffset); - Serialise("subPixelInterpolationOffsetBits", el.subPixelInterpolationOffsetBits); - Serialise("maxFramebufferWidth", el.maxFramebufferWidth); - Serialise("maxFramebufferHeight", el.maxFramebufferHeight); - Serialise("maxFramebufferLayers", el.maxFramebufferLayers); - Serialise("framebufferColorSampleCounts", el.framebufferColorSampleCounts); - Serialise("framebufferDepthSampleCounts", el.framebufferDepthSampleCounts); - Serialise("framebufferStencilSampleCounts", el.framebufferStencilSampleCounts); - Serialise("framebufferNoAttachmentsSampleCounts", el.framebufferNoAttachmentsSampleCounts); - Serialise("maxColorAttachments", el.maxColorAttachments); - Serialise("sampledImageColorSampleCounts", el.sampledImageColorSampleCounts); - Serialise("sampledImageIntegerSampleCounts", el.sampledImageIntegerSampleCounts); - Serialise("sampledImageDepthSampleCounts", el.sampledImageDepthSampleCounts); - Serialise("sampledImageStencilSampleCounts", el.sampledImageStencilSampleCounts); - Serialise("storageImageSampleCounts", el.storageImageSampleCounts); - Serialise("maxSampleMaskWords", el.maxSampleMaskWords); - Serialise("timestampComputeAndGraphics", el.timestampComputeAndGraphics); - Serialise("timestampPeriod", el.timestampPeriod); - Serialise("maxClipDistances", el.maxClipDistances); - Serialise("maxCullDistances", el.maxCullDistances); - Serialise("maxCombinedClipAndCullDistances", el.maxCombinedClipAndCullDistances); - Serialise("discreteQueuePriorities", el.discreteQueuePriorities); - SerialisePODArray<2>("pointSizeRange", el.pointSizeRange); - SerialisePODArray<2>("lineWidthRange", el.lineWidthRange); - Serialise("pointSizeGranularity", el.pointSizeGranularity); - Serialise("lineWidthGranularity", el.lineWidthGranularity); - Serialise("strictLines", el.strictLines); - Serialise("standardSampleLocations", el.standardSampleLocations); - Serialise("optimalBufferCopyOffsetAlignment", el.optimalBufferCopyOffsetAlignment); - Serialise("optimalBufferCopyRowPitchAlignment", el.optimalBufferCopyRowPitchAlignment); - Serialise("nonCoherentAtomSize", el.nonCoherentAtomSize); -} - -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceSparseProperties &el) -{ - ScopedContext scope(this, name, "VkPhysicalDeviceSparseProperties", 0, true); - - Serialise("residencyStandard2DBlockShape", el.residencyStandard2DBlockShape); - Serialise("residencyStandard2DMultisampleBlockShape", el.residencyStandard2DMultisampleBlockShape); - Serialise("residencyStandard3DBlockShape", el.residencyStandard3DBlockShape); - Serialise("residencyAlignedMipSize", el.residencyAlignedMipSize); - Serialise("residencyNonResidentStrict", el.residencyNonResidentStrict); -} - -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceProperties &el) -{ - ScopedContext scope(this, name, "VkPhysicalDeviceProperties", 0, true); - - Serialise("apiVersion", el.apiVersion); - Serialise("driverVersion", el.driverVersion); - Serialise("vendorID", el.vendorID); - Serialise("deviceID", el.deviceID); - Serialise("deviceType", el.deviceType); - - string deviceName; - if(m_Mode == WRITING) - deviceName = el.deviceName; - Serialise("deviceName", deviceName); - if(m_Mode == READING) - { - RDCEraseEl(el.deviceName); - memcpy(el.deviceName, deviceName.c_str(), - RDCMIN(deviceName.size(), (size_t)VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)); - } - - SerialisePODArray("pipelineCacheUUID", el.pipelineCacheUUID); - Serialise("limits", el.limits); - Serialise("sparseProperties", el.sparseProperties); -} - -template <> -void Serialiser::Serialise(const char *name, VkDeviceCreateInfo &el) -{ - ScopedContext scope(this, name, "VkDeviceCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pQueueCreateInfos", (VkDeviceQueueCreateInfo *&)el.pQueueCreateInfos, - el.queueCreateInfoCount); - - // need to do this by hand to use string DB - Serialise("extensionCount", el.enabledExtensionCount); - - if(m_Mode == READING) - el.ppEnabledExtensionNames = - el.enabledExtensionCount ? new char *[el.enabledExtensionCount] : NULL; - - // cast away const on array so we can assign to it on reading - const char **exts = (const char **)el.ppEnabledExtensionNames; - for(uint32_t i = 0; i < el.enabledExtensionCount; i++) - { - string s = ""; - if(m_Mode == WRITING && exts[i] != NULL) - s = exts[i]; - - Serialise("ppEnabledExtensionNames", s); - - if(m_Mode == READING) - { - m_StringDB.insert(s); - exts[i] = m_StringDB.find(s)->c_str(); - } - } - - // need to do this by hand to use string DB - Serialise("layerCount", el.enabledLayerCount); - - if(m_Mode == READING) - el.ppEnabledLayerNames = el.enabledLayerCount ? new char *[el.enabledLayerCount] : NULL; - - // cast away const on array so we can assign to it on reading - const char **layers = (const char **)el.ppEnabledLayerNames; - for(uint32_t i = 0; i < el.enabledLayerCount; i++) - { - string s = ""; - if(m_Mode == WRITING && layers[i] != NULL) - s = layers[i]; - - Serialise("ppEnabledLayerNames", s); - - if(m_Mode == READING) - { - m_StringDB.insert(s); - layers[i] = m_StringDB.find(s)->c_str(); - } - } - - SerialiseOptionalObject(this, "pEnabledFeatures", (VkPhysicalDeviceFeatures *&)el.pEnabledFeatures); -} - -template <> -void Serialiser::Deserialise(const VkDeviceCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - for(uint32_t i = 0; i < el->queueCreateInfoCount; i++) - delete[] el->pQueueCreateInfos[i].pQueuePriorities; - delete[] el->pQueueCreateInfos; - delete[] el->ppEnabledExtensionNames; - delete[] el->ppEnabledLayerNames; - delete el->pEnabledFeatures; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkBufferCreateInfo &el) -{ - ScopedContext scope(this, name, "VkBufferCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkBufferCreateFlagBits &)el.flags); - Serialise("size", el.size); - Serialise("usage", (VkBufferUsageFlagBits &)el.usage); - Serialise("sharingMode", el.sharingMode); - if(m_Mode == READING) - { - el.pQueueFamilyIndices = NULL; - el.queueFamilyIndexCount = 0; - } - if(el.sharingMode == VK_SHARING_MODE_CONCURRENT) - { - SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, - el.queueFamilyIndexCount); - } - else - { - // for backwards compatibility with captures, ignore the family count and serialise empty array - uint32_t zero = 0; - uint32_t *empty = NULL; - SerialisePODArray("pQueueFamilyIndices", empty, zero); - delete[] empty; - } -} - -template <> -void Serialiser::Deserialise(const VkBufferCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pQueueFamilyIndices; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkBufferViewCreateInfo &el) -{ - ScopedContext scope(this, name, "VkBufferViewCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkBuffer, "buffer", el.buffer); - Serialise("format", el.format); - Serialise("offset", el.offset); - Serialise("range", el.range); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageCreateInfo &el) -{ - ScopedContext scope(this, name, "VkImageCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkImageCreateFlagBits &)el.flags); - Serialise("imageType", el.imageType); - Serialise("format", el.format); - Serialise("extent", el.extent); - Serialise("mipLevels", el.mipLevels); - Serialise("arraySize", el.arrayLayers); - Serialise("samples", el.samples); - Serialise("tiling", el.tiling); - Serialise("usage", (VkImageUsageFlagBits &)el.usage); - Serialise("sharingMode", el.sharingMode); - if(m_Mode == READING) - { - el.pQueueFamilyIndices = NULL; - el.queueFamilyIndexCount = 0; - } - if(el.sharingMode == VK_SHARING_MODE_CONCURRENT) - { - SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, - el.queueFamilyIndexCount); - } - else - { - // for backwards compatibility with captures, ignore the family count and serialise empty array - uint32_t zero = 0; - uint32_t empty[1] = {0}; - SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)empty, zero); - } - Serialise("initialLayout", el.initialLayout); -} - -template <> -void Serialiser::Deserialise(const VkImageCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pQueueFamilyIndices; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkImageViewCreateInfo &el) -{ - ScopedContext scope(this, name, "VkImageViewCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkImage, "image", el.image); - Serialise("viewType", el.viewType); - Serialise("format", el.format); - Serialise("components", el.components); - Serialise("subresourceRange", el.subresourceRange); -} - -template <> -void Serialiser::Serialise(const char *name, VkSparseMemoryBind &el) -{ - ScopedContext scope(this, name, "VkSparseMemoryBind", 0, true); - - Serialise("resourceOffset", el.resourceOffset); - Serialise("size", el.size); - SerialiseObject(VkDeviceMemory, "memory", el.memory); - Serialise("memoryOffset", el.memoryOffset); - Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); -} - -template <> -void Serialiser::Serialise(const char *name, VkSparseBufferMemoryBindInfo &el) -{ - ScopedContext scope(this, name, "VkSparseBufferMemoryBindInfo", 0, true); - - SerialiseObject(VkBuffer, "buffer", el.buffer); - SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkSparseImageOpaqueMemoryBindInfo &el) -{ - ScopedContext scope(this, name, "VkSparseImageOpaqueMemoryBindInfo", 0, true); - - SerialiseObject(VkImage, "image", el.image); - SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkSparseImageMemoryBind &el) -{ - ScopedContext scope(this, name, "VkSparseImageMemoryBind", 0, true); - - Serialise("subresource", el.subresource); - Serialise("offset", el.offset); - Serialise("extent", el.extent); - SerialiseObject(VkDeviceMemory, "memory", el.memory); - Serialise("memoryOffset", el.memoryOffset); - Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); -} - -template <> -void Serialiser::Serialise(const char *name, VkSparseImageMemoryBindInfo &el) -{ - ScopedContext scope(this, name, "VkSparseImageMemoryBindInfo", 0, true); - - SerialiseObject(VkImage, "image", el.image); - SerialiseComplexArray("pBinds", (VkSparseImageMemoryBind *&)el.pBinds, el.bindCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkBindSparseInfo &el) -{ - ScopedContext scope(this, name, "VkBindSparseInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("waitSemaphoreCount", el.waitSemaphoreCount); - - if(m_Mode == READING) - el.pWaitSemaphores = el.waitSemaphoreCount ? new VkSemaphore[el.waitSemaphoreCount] : NULL; - - VkSemaphore *waitsems = (VkSemaphore *)el.pWaitSemaphores; - for(uint32_t i = 0; i < el.waitSemaphoreCount; i++) - SerialiseObject(VkSemaphore, "pWaitSemaphores", waitsems[i]); - - SerialiseComplexArray("pBufferBinds", (VkSparseBufferMemoryBindInfo *&)el.pBufferBinds, - el.bufferBindCount); - SerialiseComplexArray("pImageOpaqueBinds", - (VkSparseImageOpaqueMemoryBindInfo *&)el.pImageOpaqueBinds, - el.imageOpaqueBindCount); - SerialiseComplexArray("pImageBinds", (VkSparseImageMemoryBindInfo *&)el.pImageBinds, - el.imageBindCount); - - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("signalSemaphoreCount", el.signalSemaphoreCount); - - if(m_Mode == READING) - el.pSignalSemaphores = el.signalSemaphoreCount ? new VkSemaphore[el.signalSemaphoreCount] : NULL; - - VkSemaphore *sigsems = (VkSemaphore *)el.pSignalSemaphores; - for(uint32_t i = 0; i < el.signalSemaphoreCount; i++) - SerialiseObject(VkSemaphore, "pSignalSemaphores", sigsems[i]); -} - -template <> -void Serialiser::Deserialise(const VkBindSparseInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pWaitSemaphores; - for(uint32_t i = 0; i < el->bufferBindCount; i++) - delete[] el->pBufferBinds[i].pBinds; - delete[] el->pBufferBinds; - for(uint32_t i = 0; i < el->imageOpaqueBindCount; i++) - delete[] el->pImageOpaqueBinds[i].pBinds; - delete[] el->pImageOpaqueBinds; - delete[] el->pImageBinds; - delete[] el->pSignalSemaphores; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkFramebufferCreateInfo &el) -{ - ScopedContext scope(this, name, "VkFramebufferCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("width", el.width); - Serialise("height", el.height); - Serialise("layers", el.layers); - - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("attachmentCount", el.attachmentCount); - - if(m_Mode == READING) - el.pAttachments = el.attachmentCount ? new VkImageView[el.attachmentCount] : NULL; - - VkImageView *attaches = (VkImageView *)el.pAttachments; - for(uint32_t i = 0; i < el.attachmentCount; i++) - SerialiseObject(VkImageView, "pAttachments", attaches[i]); -} - -template <> -void Serialiser::Deserialise(const VkFramebufferCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pAttachments; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkAttachmentDescription &el) -{ - ScopedContext scope(this, name, "VkAttachmentDescription", 0, true); - - Serialise("flags", (VkAttachmentDescriptionFlagBits &)el.flags); - Serialise("format", el.format); - Serialise("samples", el.samples); - Serialise("loadOp", el.loadOp); - Serialise("storeOp", el.storeOp); - Serialise("stencilLoadOp", el.stencilLoadOp); - Serialise("stencilStoreOp", el.stencilStoreOp); - Serialise("initialLayout", el.initialLayout); - Serialise("finalLayout", el.finalLayout); -} - -template <> -void Serialiser::Serialise(const char *name, VkSubpassDescription &el) -{ - ScopedContext scope(this, name, "VkSubpassDescription", 0, true); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("pipelineBindPoint", el.pipelineBindPoint); - SerialiseOptionalObject(this, "pDepthStencilAttachment", - (VkAttachmentReference *&)el.pDepthStencilAttachment); - - if(m_Mode == READING) - { - el.pInputAttachments = NULL; - el.pColorAttachments = NULL; - el.pResolveAttachments = NULL; - el.pPreserveAttachments = NULL; - } - - SerialisePODArray("inputAttachments", (VkAttachmentReference *&)el.pInputAttachments, - el.inputAttachmentCount); - SerialisePODArray("colorAttachments", (VkAttachmentReference *&)el.pColorAttachments, - el.colorAttachmentCount); - - bool hasResolves = (el.pResolveAttachments != NULL); - Serialise("hasResolves", hasResolves); - - if(hasResolves) - SerialisePODArray("resolveAttachments", (VkAttachmentReference *&)el.pResolveAttachments, - el.colorAttachmentCount); - - SerialisePODArray("preserveAttachments", (VkAttachmentReference *&)el.pPreserveAttachments, - el.preserveAttachmentCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkSubpassDependency &el) -{ - ScopedContext scope(this, name, "VkSubpassDependency", 0, true); - - Serialise("srcSubpass", el.srcSubpass); - Serialise("destSubpass", el.dstSubpass); - Serialise("srcStageMask", (VkPipelineStageFlagBits &)el.srcStageMask); - Serialise("destStageMask", (VkPipelineStageFlagBits &)el.dstStageMask); - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - Serialise("dependencyFlags", (VkDependencyFlagBits &)el.dependencyFlags); -} - -template <> -void Serialiser::Serialise(const char *name, VkRenderPassCreateInfo &el) -{ - ScopedContext scope(this, name, "VkRenderPassCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pAttachments", (VkAttachmentDescription *&)el.pAttachments, - el.attachmentCount); - SerialiseComplexArray("pSubpasses", (VkSubpassDescription *&)el.pSubpasses, el.subpassCount); - SerialiseComplexArray("pDependencies", (VkSubpassDependency *&)el.pDependencies, - el.dependencyCount); -} - -template <> -void Serialiser::Deserialise(const VkRenderPassCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pAttachments; - for(uint32_t i = 0; i < el->subpassCount; i++) - { - delete el->pSubpasses[i].pDepthStencilAttachment; - delete[] el->pSubpasses[i].pInputAttachments; - delete[] el->pSubpasses[i].pColorAttachments; - delete[] el->pSubpasses[i].pResolveAttachments; - if(el->pSubpasses[i].pPreserveAttachments) - delete[] el->pSubpasses[i].pPreserveAttachments; - } - delete[] el->pSubpasses; - delete[] el->pDependencies; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkRenderPassBeginInfo &el) -{ - ScopedContext scope(this, name, "VkRenderPassBeginInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); - Serialise("renderArea", el.renderArea); - - if(m_Mode == READING) - el.pClearValues = NULL; - SerialisePODArray("pClearValues", (VkClearValue *&)el.pClearValues, el.clearValueCount); -} - -template <> -void Serialiser::Deserialise(const VkRenderPassBeginInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pClearValues; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkVertexInputBindingDescription &el) -{ - ScopedContext scope(this, name, "VkVertexInputBindingDescription", 0, true); - - Serialise("binding", el.binding); - Serialise("strideInBytes", el.stride); - Serialise("inputRate", el.inputRate); -} - -template <> -void Serialiser::Serialise(const char *name, VkVertexInputAttributeDescription &el) -{ - ScopedContext scope(this, name, "VkVertexInputAttributeDescription", 0, true); - - Serialise("location", el.location); - Serialise("binding", el.binding); - Serialise("format", el.format); - Serialise("offset", el.offset); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineVertexInputStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineVertexInputStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || - el.sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pVertexBindingDescriptions", - (VkVertexInputBindingDescription *&)el.pVertexBindingDescriptions, - el.vertexBindingDescriptionCount); - SerialiseComplexArray("pVertexAttributeDescriptions", - (VkVertexInputAttributeDescription *&)el.pVertexAttributeDescriptions, - el.vertexAttributeDescriptionCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineInputAssemblyStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineInputAssemblyStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || - el.sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("topology", el.topology); - Serialise("primitiveRestartEnable", el.primitiveRestartEnable); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineTessellationStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineTessStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || - el.sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("patchControlPoints", el.patchControlPoints); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineViewportStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineViewportStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - - if(m_Mode == READING) - { - el.pViewports = NULL; - el.pScissors = NULL; - } - - // need to handle these arrays potentially being NULL if they're dynamic - bool hasViews = (el.pViewports != NULL); - bool hasScissors = (el.pScissors != NULL); - - Serialise("hasViews", hasViews); - Serialise("hasScissors", hasScissors); - - if(hasViews) - SerialisePODArray("viewports", (VkViewport *&)el.pViewports, el.viewportCount); - else - Serialise("viewportCount", el.viewportCount); - - if(hasScissors) - SerialisePODArray("scissors", (VkRect2D *&)el.pScissors, el.scissorCount); - else - Serialise("scissorCount", el.scissorCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineRasterizationStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineRasterStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || - el.sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("depthClampEnable", el.depthClampEnable); - Serialise("rasterizerDiscardEnable", el.rasterizerDiscardEnable); - Serialise("polygonMode", el.polygonMode); - Serialise("cullMode", el.cullMode); - Serialise("frontFace", el.frontFace); - Serialise("depthBiasEnable", el.depthBiasEnable); - Serialise("depthBiasConstantFactor", el.depthBiasConstantFactor); - Serialise("depthBiasClamp", el.depthBiasClamp); - Serialise("depthBiasSlopeFactor", el.depthBiasSlopeFactor); - Serialise("lineWidth", el.lineWidth); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineMultisampleStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineMultisampleStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("rasterizationSamples", el.rasterizationSamples); - RDCASSERT(el.rasterizationSamples <= VK_SAMPLE_COUNT_32_BIT); - Serialise("sampleShadingEnable", el.sampleShadingEnable); - Serialise("minSampleShading", el.minSampleShading); - SerialiseOptionalObject(this, "sampleMask", (VkSampleMask *&)el.pSampleMask); - Serialise("alphaToCoverageEnable", el.alphaToCoverageEnable); - Serialise("alphaToOneEnable", el.alphaToOneEnable); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineColorBlendAttachmentState &el) -{ - ScopedContext scope(this, name, "VkPipelineColorBlendAttachmentState", 0, true); - - Serialise("blendEnable", el.blendEnable); - Serialise("srcColorBlendFactor", el.srcColorBlendFactor); - Serialise("dstColorBlendFactor", el.dstColorBlendFactor); - Serialise("colorBlendOp", el.colorBlendOp); - Serialise("srcAlphaBlendFactor", el.srcAlphaBlendFactor); - Serialise("dstAlphaBlendFactor", el.dstAlphaBlendFactor); - Serialise("alphaBlendOp", el.alphaBlendOp); - Serialise("channelWriteMask", el.colorWriteMask); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineColorBlendStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineColorBlendStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("logicOpEnable", el.logicOpEnable); - Serialise("logicOp", el.logicOp); - - Serialise("attachmentCount", el.attachmentCount); - - SerialiseComplexArray("pAttachments", (VkPipelineColorBlendAttachmentState *&)el.pAttachments, - el.attachmentCount); - - SerialisePODArray<4>("blendConstants", el.blendConstants); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineDepthStencilStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineDepthStencilStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || - el.sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("depthTestEnable", el.depthTestEnable); - Serialise("depthWriteEnable", el.depthWriteEnable); - Serialise("depthCompareOp", el.depthCompareOp); - Serialise("depthBoundsTestEnable", el.depthBoundsTestEnable); - Serialise("stencilEnable", el.stencilTestEnable); - Serialise("front", el.front); - Serialise("back", el.back); - Serialise("minDepthBounds", el.minDepthBounds); - Serialise("maxDepthBounds", el.maxDepthBounds); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineDynamicStateCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineDynamicStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - if(m_Mode == READING) - el.pDynamicStates = NULL; - SerialisePODArray("dynamicStates", (VkDynamicState *&)el.pDynamicStates, el.dynamicStateCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkCommandPoolCreateInfo &el) -{ - ScopedContext scope(this, name, "VkCommandPoolCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkCommandPoolCreateFlagBits &)el.flags); - Serialise("queueFamilyIndex", el.queueFamilyIndex); -} - -template <> -void Serialiser::Serialise(const char *name, VkCommandBufferAllocateInfo &el) -{ - ScopedContext scope(this, name, "VkCommandBufferAllocateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkCommandPool, "commandPool", el.commandPool); - Serialise("level", el.level); - Serialise("bufferCount", el.commandBufferCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkCommandBufferInheritanceInfo &el) -{ - ScopedContext scope(this, name, "VkCommandBufferInheritanceInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("subpass", el.subpass); - SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); - Serialise("occlusionQueryEnable", el.occlusionQueryEnable); - Serialise("queryFlags", (VkQueryControlFlagBits &)el.queryFlags); - Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); -} - -template <> -void Serialiser::Serialise(const char *name, VkCommandBufferBeginInfo &el) -{ - ScopedContext scope(this, name, "VkCommandBufferBeginInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkCommandBufferUsageFlagBits &)el.flags); - SerialiseOptionalObject(this, "el.pInheritanceInfo", - (VkCommandBufferInheritanceInfo *&)el.pInheritanceInfo); -} - -template <> -void Serialiser::Deserialise(const VkCommandBufferBeginInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete el->pInheritanceInfo; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkStencilOpState &el) -{ - ScopedContext scope(this, name, "VkStencilOpState", 0, true); - - Serialise("failOp", el.failOp); - Serialise("passOp", el.passOp); - Serialise("depthFailOp", el.depthFailOp); - Serialise("compareOp", el.compareOp); - Serialise("compareMask", el.compareMask); - Serialise("writeMask", el.writeMask); - Serialise("reference", el.reference); -} - -template <> -void Serialiser::Serialise(const char *name, VkQueryPoolCreateInfo &el) -{ - ScopedContext scope(this, name, "VkQueryPoolCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("queryType", el.queryType); - Serialise("queryCount", el.queryCount); - Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); -} - -template <> -void Serialiser::Serialise(const char *name, VkSemaphoreCreateInfo &el) -{ - ScopedContext scope(this, name, "VkSemaphoreCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); -} - -template <> -void Serialiser::Serialise(const char *name, VkEventCreateInfo &el) -{ - ScopedContext scope(this, name, "VkEventCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); -} - -template <> -void Serialiser::Serialise(const char *name, VkFenceCreateInfo &el) -{ - ScopedContext scope(this, name, "VkFenceCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFenceCreateFlagBits &)el.flags); -} - -template <> -void Serialiser::Serialise(const char *name, VkSamplerCreateInfo &el) -{ - ScopedContext scope(this, name, "VkSamplerCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("minFilter", el.minFilter); - Serialise("magFilter", el.magFilter); - Serialise("mipmapMode", el.mipmapMode); - Serialise("addressModeU", el.addressModeU); - Serialise("addressModeV", el.addressModeV); - Serialise("addressModeW", el.addressModeW); - Serialise("mipLodBias", el.mipLodBias); - Serialise("anisotropyEnable", el.anisotropyEnable); - Serialise("maxAnisotropy", el.maxAnisotropy); - Serialise("compareEnable", el.compareEnable); - Serialise("compareOp", el.compareOp); - Serialise("minLod", el.minLod); - Serialise("maxLod", el.maxLod); - Serialise("borderColor", el.borderColor); - Serialise("unnormalizedCoordinates", el.unnormalizedCoordinates); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineShaderStageCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineShaderStageCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("stage", el.stage); - SerialiseObject(VkShaderModule, "module", el.module); - - string s = ""; - if(m_Mode >= WRITING && el.pName != NULL) - s = el.pName; - - Serialise("pName", s); - - if(m_Mode == READING) - { - if(s == "") - { - el.pName = ""; - } - else - { - string str; - str.assign((char *)m_BufferHead - s.length(), s.length()); - m_StringDB.insert(str); - el.pName = m_StringDB.find(str)->c_str(); - } - } - - SerialiseOptionalObject(this, "el.pSpecializationInfo", - (VkSpecializationInfo *&)el.pSpecializationInfo); -} - -template <> -void Serialiser::Serialise(const char *name, VkSpecializationMapEntry &el) -{ - ScopedContext scope(this, name, "VkSpecializationMapEntry", 0, true); - - Serialise("constantId", el.constantID); - Serialise("offset", el.offset); - uint64_t size = el.size; - Serialise("size", size); - if(m_Mode == READING) - el.size = (size_t)size; -} - -template <> -void Serialiser::Serialise(const char *name, VkSpecializationInfo &el) -{ - ScopedContext scope(this, name, "VkSpecializationInfo", 0, true); - - uint64_t dataSize = el.dataSize; - Serialise("dataSize", dataSize); - size_t sz = (size_t)dataSize; - if(m_Mode == READING) - { - el.pData = NULL; - el.dataSize = sz; - } - SerialiseBuffer("pData", (byte *&)el.pData, sz); - - SerialiseComplexArray("pMapEntries", (VkSpecializationMapEntry *&)el.pMapEntries, el.mapEntryCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineCacheCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineCacheCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - - uint64_t initialDataSize = el.initialDataSize; - Serialise("codeSize", initialDataSize); - el.initialDataSize = (size_t)initialDataSize; - - if(m_Mode == READING) - el.pInitialData = NULL; - SerialiseBuffer("initialData", (byte *&)el.pInitialData, el.initialDataSize); -} - -template <> -void Serialiser::Deserialise(const VkPipelineCacheCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[](byte *)(el->pInitialData); - } -} - -template <> -void Serialiser::Serialise(const char *name, VkPipelineLayoutCreateInfo &el) -{ - ScopedContext scope(this, name, "VkPipelineLayoutCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorSetCount", el.setLayoutCount); - - if(m_Mode == READING) - el.pSetLayouts = el.setLayoutCount ? new VkDescriptorSetLayout[el.setLayoutCount] : NULL; - - // cast away const on array so we can assign to it on reading - VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)el.pSetLayouts; - for(uint32_t i = 0; i < el.setLayoutCount; i++) - SerialiseObject(VkDescriptorSetLayout, "layout", layouts[i]); - - SerialiseComplexArray("pPushConstantRanges", (VkPushConstantRange *&)el.pPushConstantRanges, - el.pushConstantRangeCount); -} - -template <> -void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pSetLayouts; - delete[] el->pPushConstantRanges; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkShaderModuleCreateInfo &el) -{ - ScopedContext scope(this, name, "VkShaderModuleCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - - uint64_t codeSize = el.codeSize; - Serialise("codeSize", codeSize); - el.codeSize = (size_t)codeSize; - - size_t sz = (size_t)codeSize; - if(m_Mode == READING) - el.pCode = NULL; - SerialiseBuffer("pCode", (byte *&)el.pCode, sz); -} - -template <> -void Serialiser::Deserialise(const VkShaderModuleCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[](byte *)(el->pCode); - } -} - -template <> -void Serialiser::Serialise(const char *name, VkImageSubresourceRange &el) -{ - ScopedContext scope(this, name, "VkImageSubresourceRange", 0, true); - - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("baseMipLevel", el.baseMipLevel); - Serialise("levelCount", el.levelCount); - Serialise("baseArrayLayer", el.baseArrayLayer); - Serialise("layerCount", el.layerCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageSubresourceLayers &el) -{ - ScopedContext scope(this, name, "VkImageSubresourceLayers", 0, true); - - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("mipLevel", el.mipLevel); - Serialise("baseArrayLayer", el.baseArrayLayer); - Serialise("layerCount", el.layerCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageSubresource &el) -{ - ScopedContext scope(this, name, "VkImageSubresource", 0, true); - - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("mipLevel", el.mipLevel); - Serialise("arrayLayer", el.arrayLayer); -} - -template <> -void Serialiser::Serialise(const char *name, VkMemoryAllocateInfo &el) -{ - ScopedContext scope(this, name, "VkMemoryAllocateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("allocationSize", el.allocationSize); - Serialise("memoryTypeIndex", el.memoryTypeIndex); -} - -template <> -void Serialiser::Serialise(const char *name, VkMemoryBarrier &el) -{ - ScopedContext scope(this, name, "VkMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); -} - -template <> -void Serialiser::Serialise(const char *name, VkBufferMemoryBarrier &el) -{ - ScopedContext scope(this, name, "VkBufferMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue - // family index won't be legitimately larger than 2 billion - Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); - Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); - SerialiseObject(VkBuffer, "buffer", el.buffer); - Serialise("offset", el.offset); - Serialise("size", el.size); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageMemoryBarrier &el) -{ - ScopedContext scope(this, name, "VkImageMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - Serialise("oldLayout", el.oldLayout); - Serialise("newLayout", el.newLayout); - // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue - // family index won't be legitimately larger than 2 billion - Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); - Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); - SerialiseObject(VkImage, "image", el.image); - Serialise("subresourceRange", el.subresourceRange); -} - -template <> -void Serialiser::Serialise(const char *name, VkGraphicsPipelineCreateInfo &el) -{ - ScopedContext scope(this, name, "VkGraphicsPipelineCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); - SerialiseObject(VkPipelineLayout, "layout", el.layout); - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("subpass", el.subpass); - SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); - Serialise("basePipelineIndex", el.basePipelineIndex); - - SerialiseOptionalObject(this, "pVertexInputState", - (VkPipelineVertexInputStateCreateInfo *&)el.pVertexInputState); - SerialiseOptionalObject(this, "pInputAssemblyState", - (VkPipelineInputAssemblyStateCreateInfo *&)el.pInputAssemblyState); - SerialiseOptionalObject(this, "pTessellationState", - (VkPipelineTessellationStateCreateInfo *&)el.pTessellationState); - SerialiseOptionalObject(this, "pViewportState", - (VkPipelineViewportStateCreateInfo *&)el.pViewportState); - SerialiseOptionalObject(this, "pRasterState", - (VkPipelineRasterizationStateCreateInfo *&)el.pRasterizationState); - SerialiseOptionalObject(this, "pMultisampleState", - (VkPipelineMultisampleStateCreateInfo *&)el.pMultisampleState); - SerialiseOptionalObject(this, "pDepthStencilState", - (VkPipelineDepthStencilStateCreateInfo *&)el.pDepthStencilState); - SerialiseOptionalObject(this, "pColorBlendState", - (VkPipelineColorBlendStateCreateInfo *&)el.pColorBlendState); - SerialiseOptionalObject(this, "pDynamicState", - (VkPipelineDynamicStateCreateInfo *&)el.pDynamicState); - - SerialiseComplexArray("pStages", (VkPipelineShaderStageCreateInfo *&)el.pStages, el.stageCount); -} - -template <> -void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - if(el->pVertexInputState) - { - RDCASSERT(el->pVertexInputState->pNext == NULL); // otherwise delete - delete[] el->pVertexInputState->pVertexBindingDescriptions; - delete[] el->pVertexInputState->pVertexAttributeDescriptions; - delete el->pVertexInputState; - } - if(el->pInputAssemblyState) - { - RDCASSERT(el->pInputAssemblyState->pNext == NULL); // otherwise delete - delete el->pInputAssemblyState; - } - if(el->pTessellationState) - { - RDCASSERT(el->pTessellationState->pNext == NULL); // otherwise delete - delete el->pTessellationState; - } - if(el->pViewportState) - { - RDCASSERT(el->pViewportState->pNext == NULL); // otherwise delete - if(el->pViewportState->pViewports) - delete[] el->pViewportState->pViewports; - if(el->pViewportState->pScissors) - delete[] el->pViewportState->pScissors; - delete el->pViewportState; - } - if(el->pRasterizationState) - { - RDCASSERT(el->pRasterizationState->pNext == NULL); // otherwise delete - delete el->pRasterizationState; - } - if(el->pMultisampleState) - { - RDCASSERT(el->pMultisampleState->pNext == NULL); // otherwise delete - delete el->pMultisampleState->pSampleMask; - delete el->pMultisampleState; - } - if(el->pDepthStencilState) - { - RDCASSERT(el->pDepthStencilState->pNext == NULL); // otherwise delete - delete el->pDepthStencilState; - } - if(el->pColorBlendState) - { - RDCASSERT(el->pColorBlendState->pNext == NULL); // otherwise delete - delete[] el->pColorBlendState->pAttachments; - delete el->pColorBlendState; - } - if(el->pDynamicState) - { - RDCASSERT(el->pDynamicState->pNext == NULL); // otherwise delete - if(el->pDynamicState->pDynamicStates) - delete[] el->pDynamicState->pDynamicStates; - delete el->pDynamicState; - } - for(uint32_t i = 0; i < el->stageCount; i++) - { - RDCASSERT(el->pStages[i].pNext == NULL); // otherwise delete - if(el->pStages[i].pSpecializationInfo) - { - delete[](byte *)(el->pStages[i].pSpecializationInfo->pData); - delete[] el->pStages[i].pSpecializationInfo->pMapEntries; - delete el->pStages[i].pSpecializationInfo; - } - } - delete[] el->pStages; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el) -{ - ScopedContext scope(this, name, "VkComputePipelineCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("stage", el.stage); - Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); - SerialiseObject(VkPipelineLayout, "layout", el.layout); - SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); - Serialise("basePipelineIndex", el.basePipelineIndex); -} - -template <> -void Serialiser::Deserialise(const VkComputePipelineCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - RDCASSERT(el->stage.pNext == NULL); // otherwise delete - if(el->stage.pSpecializationInfo) - { - delete[](byte *)(el->stage.pSpecializationInfo->pData); - delete[] el->stage.pSpecializationInfo->pMapEntries; - delete el->stage.pSpecializationInfo; - } - } -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorPoolSize &el) -{ - ScopedContext scope(this, name, "VkDescriptorPoolSize", 0, true); - - Serialise("type", el.type); - Serialise("descriptorCount", el.descriptorCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorPoolCreateInfo &el) -{ - ScopedContext scope(this, name, "VkDescriptorPoolCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkDescriptorPoolCreateFlagBits &)el.flags); - Serialise("maxSets", el.maxSets); - SerialiseComplexArray("pTypeCount", (VkDescriptorPoolSize *&)el.pPoolSizes, el.poolSizeCount); -} - -template <> -void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pPoolSizes; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetAllocateInfo &el) -{ - ScopedContext scope(this, name, "VkDescriptorSetAllocateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkDescriptorPool, "descriptorPool", el.descriptorPool); - - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorSetCount", el.descriptorSetCount); - - if(m_Mode == READING) - el.pSetLayouts = el.descriptorSetCount ? new VkDescriptorSetLayout[el.descriptorSetCount] : NULL; - - // cast away const on array so we can assign to it on reading - VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)el.pSetLayouts; - for(uint32_t i = 0; i < el.descriptorSetCount; i++) - SerialiseObject(VkDescriptorSetLayout, "pSetLayouts", layouts[i]); -} - -template <> -void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete[] el->pSetLayouts; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorImageInfo &el) -{ - ScopedContext scope(this, name, "VkDescriptorImageInfo", 0, true); - - SerialiseObjectOptional(VkSampler, "sampler", el.sampler); - SerialiseObjectOptional(VkImageView, "imageView", el.imageView); - Serialise("imageLayout", el.imageLayout); -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorBufferInfo &el) -{ - ScopedContext scope(this, name, "VkDescriptorBufferInfo", 0, true); - - SerialiseObjectOptional(VkBuffer, "buffer", el.buffer); - Serialise("offset", el.offset); - Serialise("range", el.range); -} - -template <> -void Serialiser::Serialise(const char *name, VkWriteDescriptorSet &el) -{ - ScopedContext scope(this, name, "VkWriteDescriptorSet", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObjectOptional(VkDescriptorSet, "dstSet", el.dstSet); - Serialise("dstBinding", el.dstBinding); - Serialise("dstArrayElement", el.dstArrayElement); - Serialise("descriptorType", el.descriptorType); - - if(m_Mode == READING) - { - el.pImageInfo = NULL; - el.pBufferInfo = NULL; - el.pTexelBufferView = NULL; - } - - // only serialise the array type used, the others are ignored - if(el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - el.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || - el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || - el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || - el.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - { - SerialiseComplexArray("pImageInfo", (VkDescriptorImageInfo *&)el.pImageInfo, el.descriptorCount); - } - else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || - el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || - el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || - el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) - { - SerialiseComplexArray("pBufferInfo", (VkDescriptorBufferInfo *&)el.pBufferInfo, - el.descriptorCount); - } - else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorCount", el.descriptorCount); - - if(m_Mode == READING) - el.pTexelBufferView = el.descriptorCount ? new VkBufferView[el.descriptorCount] : NULL; - - // cast away const on array so we can assign to it on reading - VkBufferView *views = (VkBufferView *)el.pTexelBufferView; - for(uint32_t i = 0; i < el.descriptorCount; i++) - SerialiseObjectOptional(VkBufferView, "pTexelBufferView", views[i]); - } -} - -template <> -void Serialiser::Deserialise(const VkWriteDescriptorSet *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - if(el->pImageInfo) - delete[] el->pImageInfo; - if(el->pBufferInfo) - delete[] el->pBufferInfo; - if(el->pTexelBufferView) - delete[] el->pTexelBufferView; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkCopyDescriptorSet &el) -{ - ScopedContext scope(this, name, "VkCopyDescriptorSet", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObjectOptional(VkDescriptorSet, "srcSet", el.srcSet); - Serialise("srcBinding", el.srcBinding); - Serialise("srcArrayElement", el.srcArrayElement); - SerialiseObjectOptional(VkDescriptorSet, "destSet", el.dstSet); - Serialise("destBinding", el.dstBinding); - Serialise("destArrayElement", el.dstArrayElement); - - Serialise("descriptorCount", el.descriptorCount); -} - -template <> -void Serialiser::Serialise(const char *name, VkPushConstantRange &el) -{ - ScopedContext scope(this, name, "VkPushConstantRange", 0, true); - - Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); - Serialise("offset", el.offset); - Serialise("size", el.size); -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutBinding &el) -{ - ScopedContext scope(this, name, "VkDescriptorSetLayoutBinding", 0, true); - - Serialise("binding", el.binding); - Serialise("descriptorType", el.descriptorType); - Serialise("descriptorCount", el.descriptorCount); - Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); - - bool hasSamplers = el.pImmutableSamplers != NULL; - Serialise("hasSamplers", hasSamplers); - - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - if(m_Mode == READING) - { - if(hasSamplers) - el.pImmutableSamplers = el.descriptorCount ? new VkSampler[el.descriptorCount] : NULL; - else - el.pImmutableSamplers = NULL; - } - - VkSampler *samplers = (VkSampler *)el.pImmutableSamplers; - - for(uint32_t i = 0; hasSamplers && i < el.descriptorCount; i++) - { - SerialiseObject(VkSampler, "pImmutableSampler", samplers[i]); - } -} - -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutCreateInfo &el) -{ - ScopedContext scope(this, name, "VkDescriptorSetLayoutCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pBindings", (VkDescriptorSetLayoutBinding *&)el.pBindings, el.bindingCount); -} - -template <> -void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo *const el) const -{ - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - for(uint32_t i = 0; i < el->bindingCount; i++) - if(el->pBindings[i].pImmutableSamplers) - delete[] el->pBindings[i].pImmutableSamplers; - delete[] el->pBindings; - } -} - -template <> -void Serialiser::Serialise(const char *name, VkComponentMapping &el) -{ - ScopedContext scope(this, name, "VkComponentMapping", 0, true); - - Serialise("r", el.r); - Serialise("g", el.g); - Serialise("b", el.b); - Serialise("a", el.a); -} - -template <> -void Serialiser::Serialise(const char *name, VkBufferImageCopy &el) -{ - ScopedContext scope(this, name, "VkBufferImageCopy", 0, true); - - Serialise("memOffset", el.bufferOffset); - Serialise("bufferRowLength", el.bufferRowLength); - Serialise("bufferImageHeight", el.bufferImageHeight); - Serialise("imageSubresource", el.imageSubresource); - Serialise("imageOffset", el.imageOffset); - Serialise("imageExtent", el.imageExtent); -} - -template <> -void Serialiser::Serialise(const char *name, VkBufferCopy &el) -{ - ScopedContext scope(this, name, "VkBufferCopy", 0, true); - - Serialise("srcOffset", el.srcOffset); - Serialise("dstOffset", el.dstOffset); - Serialise("size", el.size); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageCopy &el) -{ - ScopedContext scope(this, name, "VkImageCopy", 0, true); - - Serialise("srcSubresource", el.srcSubresource); - Serialise("srcOffset", el.srcOffset); - Serialise("dstSubresource", el.dstSubresource); - Serialise("dstOffset", el.dstOffset); - Serialise("extent", el.extent); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageBlit &el) -{ - ScopedContext scope(this, name, "VkImageBlit", 0, true); - - Serialise("srcSubresource", el.srcSubresource); - SerialisePODArray<2>("srcOffsets", el.srcOffsets); - Serialise("dstSubresource", el.dstSubresource); - SerialisePODArray<2>("dstOffsets", el.dstOffsets); -} - -template <> -void Serialiser::Serialise(const char *name, VkImageResolve &el) -{ - ScopedContext scope(this, name, "VkImageResolve", 0, true); - - Serialise("srcSubresource", el.srcSubresource); - Serialise("srcOffset", el.srcOffset); - Serialise("dstSubresource", el.dstSubresource); - Serialise("dstOffset", el.dstOffset); - Serialise("extent", el.extent); -} - -template <> -void Serialiser::Serialise(const char *name, VkRect2D &el) -{ - ScopedContext scope(this, name, "VkRect2D", 0, true); - - Serialise("offset", el.offset); - Serialise("extent", el.extent); -} - -template <> -void Serialiser::Serialise(const char *name, VkSwapchainCreateInfoKHR &el) -{ - ScopedContext scope(this, name, "VkSwapchainCreateInfoKHR", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - - // don't need the surface - - Serialise("minImageCount", el.minImageCount); - Serialise("imageFormat", el.imageFormat); - Serialise("imageColorSpace", el.imageColorSpace); - Serialise("imageExtent", el.imageExtent); - Serialise("imageArrayLayers", el.imageArrayLayers); - Serialise("imageUsage", el.imageUsage); - - // SHARING: sharingMode, queueFamilyCount, pQueueFamilyIndices - - Serialise("preTransform", el.preTransform); - Serialise("compositeAlpha", el.compositeAlpha); - Serialise("presentMode", el.presentMode); - Serialise("clipped", el.clipped); - - // don't need the old swap chain -} - -// this isn't a real vulkan type, it's our own "anything that could be in a descriptor" -// structure that -template <> -void Serialiser::Serialise(const char *name, DescriptorSetSlot &el) -{ - SerialiseObject(VkBuffer, "bufferInfo.buffer", el.bufferInfo.buffer); - Serialise("bufferInfo.offset", el.bufferInfo.offset); - Serialise("bufferInfo.range", el.bufferInfo.range); - - SerialiseObject(VkSampler, "imageInfo.sampler", el.imageInfo.sampler); - SerialiseObject(VkImageView, "imageInfo.imageView", el.imageInfo.imageView); - Serialise("imageInfo.imageLayout", el.imageInfo.imageLayout); - - SerialiseObject(VkBufferView, "texelBufferView", el.texelBufferView); -} diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index cdae6f3e9..6e33088fc 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -245,164 +245,12 @@ void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, ret func(__VA_ARGS__); \ bool CONCAT(Serialise_, func(Serialiser *localSerialiser, __VA_ARGS__)); -template <> -void Serialiser::Serialise(const char *name, VkRect2D &el); -template <> -void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceFeatures &el); -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceMemoryProperties &el); -template <> -void Serialiser::Serialise(const char *name, VkPhysicalDeviceProperties &el); -template <> -void Serialiser::Serialise(const char *name, VkDeviceCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkBufferCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkBufferViewCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkImageCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkImageViewCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkSparseMemoryBind &el); -template <> -void Serialiser::Serialise(const char *name, VkBindSparseInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkFramebufferCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkRenderPassCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkRenderPassBeginInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineInputAssemblyStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineTessellationStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineViewportStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineRasterizationStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineMultisampleStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineDepthStencilStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineColorBlendStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineDynamicStateCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineLayoutCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPushConstantRange &el); -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutBinding &el); -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkDescriptorPoolCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkDescriptorSetAllocateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkWriteDescriptorSet &el); -template <> -void Serialiser::Serialise(const char *name, VkCopyDescriptorSet &el); -template <> -void Serialiser::Serialise(const char *name, VkCommandPoolCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkCommandBufferAllocateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkCommandBufferBeginInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkStencilOpState &el); -template <> -void Serialiser::Serialise(const char *name, VkQueryPoolCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkSemaphoreCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkEventCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkFenceCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkSamplerCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkPipelineCacheCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkShaderModuleCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkImageSubresourceRange &el); -template <> -void Serialiser::Serialise(const char *name, VkImageSubresource &el); -template <> -void Serialiser::Serialise(const char *name, VkImageSubresourceLayers &el); -template <> -void Serialiser::Serialise(const char *name, VkMemoryAllocateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkMemoryBarrier &el); -template <> -void Serialiser::Serialise(const char *name, VkBufferMemoryBarrier &el); -template <> -void Serialiser::Serialise(const char *name, VkImageMemoryBarrier &el); -template <> -void Serialiser::Serialise(const char *name, VkGraphicsPipelineCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkComponentMapping &el); -template <> -void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); -template <> -void Serialiser::Serialise(const char *name, VkBufferImageCopy &el); -template <> -void Serialiser::Serialise(const char *name, VkBufferCopy &el); -template <> -void Serialiser::Serialise(const char *name, VkImageCopy &el); -template <> -void Serialiser::Serialise(const char *name, VkImageBlit &el); -template <> -void Serialiser::Serialise(const char *name, VkImageResolve &el); - -template <> -void Serialiser::Serialise(const char *name, VkSwapchainCreateInfoKHR &el); - -struct DescriptorSetSlot; -template <> -void Serialiser::Serialise(const char *name, DescriptorSetSlot &el); - -template <> -void Serialiser::Deserialise(const VkDeviceCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkBufferCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkImageCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkBindSparseInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkFramebufferCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkRenderPassCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkRenderPassBeginInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkCommandBufferBeginInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkPipelineCacheCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkShaderModuleCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkComputePipelineCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo *const el) const; -template <> -void Serialiser::Deserialise(const VkWriteDescriptorSet *const el) const; -template <> -void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo *const el) const; +// A handy macros to say "is the serialiser reading and we're doing replay-mode stuff?" +// The reason we check both is that checking the first allows the compiler to eliminate the other +// path at compile-time, and the second because we might be just struct-serialising in which case we +// should be doing no work to restore states. +// Writing is unambiguously during capture mode, so we don't have to check both in that case. +#define IsReplayingAndReading() (ser.IsReading() && IsReplayMode(m_State)) // the possible contents of a descriptor set slot, // taken from the VkWriteDescriptorSet @@ -413,6 +261,8 @@ struct DescriptorSetSlot VkBufferView texelBufferView; }; +DECLARE_REFLECTION_STRUCT(DescriptorSetSlot); + #define NUM_VK_IMAGE_ASPECTS 4 #define VK_ACCESS_ALL_READ_BITS \ (VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | \ @@ -560,3 +410,221 @@ enum VulkanChunkType }; #pragma endregion Chunks + +// this is special - these serialise overloads will fetch the ID during capture, serialise the ID +// directly as-if it were the original type, then on replay load up the resource if available. +// Really this is only one type of serialisation, but we declare a couple of overloads to account +// for resources being accessed through different interfaces in different functions +#define SERIALISE_VK_HANDLES() \ + SERIALISE_HANDLE(VkInstance) \ + SERIALISE_HANDLE(VkPhysicalDevice) \ + SERIALISE_HANDLE(VkDevice) \ + SERIALISE_HANDLE(VkQueue) \ + SERIALISE_HANDLE(VkCommandBuffer) \ + SERIALISE_HANDLE(VkFence) \ + SERIALISE_HANDLE(VkDeviceMemory) \ + SERIALISE_HANDLE(VkBuffer) \ + SERIALISE_HANDLE(VkImage) \ + SERIALISE_HANDLE(VkSemaphore) \ + SERIALISE_HANDLE(VkEvent) \ + SERIALISE_HANDLE(VkQueryPool) \ + SERIALISE_HANDLE(VkBufferView) \ + SERIALISE_HANDLE(VkImageView) \ + SERIALISE_HANDLE(VkShaderModule) \ + SERIALISE_HANDLE(VkPipelineCache) \ + SERIALISE_HANDLE(VkPipelineLayout) \ + SERIALISE_HANDLE(VkRenderPass) \ + SERIALISE_HANDLE(VkPipeline) \ + SERIALISE_HANDLE(VkDescriptorSetLayout) \ + SERIALISE_HANDLE(VkSampler) \ + SERIALISE_HANDLE(VkDescriptorPool) \ + SERIALISE_HANDLE(VkDescriptorSet) \ + SERIALISE_HANDLE(VkFramebuffer) \ + SERIALISE_HANDLE(VkCommandPool) \ + SERIALISE_HANDLE(VkSwapchainKHR) \ + SERIALISE_HANDLE(VkSurfaceKHR) + +#define SERIALISE_HANDLE(type) DECLARE_REFLECTION_STRUCT(type) + +SERIALISE_VK_HANDLES(); + +// declare reflect-able types + +DECLARE_REFLECTION_STRUCT(VkOffset2D); +DECLARE_REFLECTION_STRUCT(VkExtent2D); +DECLARE_REFLECTION_STRUCT(VkMemoryType); +DECLARE_REFLECTION_STRUCT(VkMemoryHeap); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLimits); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceSparseProperties); +DECLARE_REFLECTION_STRUCT(VkQueueFamilyProperties); +DECLARE_REFLECTION_STRUCT(VkExtent3D); +DECLARE_REFLECTION_STRUCT(VkPipelineShaderStageCreateInfo); +DECLARE_REFLECTION_STRUCT(VkOffset3D); +DECLARE_REFLECTION_STRUCT(VkCommandBufferInheritanceInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineVertexInputStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkSparseBufferMemoryBindInfo); +DECLARE_REFLECTION_STRUCT(VkSparseImageOpaqueMemoryBindInfo); +DECLARE_REFLECTION_STRUCT(VkSparseImageMemoryBindInfo); +DECLARE_REFLECTION_STRUCT(VkAttachmentDescription); +DECLARE_REFLECTION_STRUCT(VkSubpassDescription); +DECLARE_REFLECTION_STRUCT(VkSubpassDependency); +DECLARE_REFLECTION_STRUCT(VkClearValue); +DECLARE_REFLECTION_STRUCT(VkClearColorValue); +DECLARE_REFLECTION_STRUCT(VkClearDepthStencilValue); +DECLARE_REFLECTION_STRUCT(VkClearAttachment); +DECLARE_REFLECTION_STRUCT(VkClearRect); +DECLARE_REFLECTION_STRUCT(VkViewport); +DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendAttachmentState); +DECLARE_REFLECTION_STRUCT(VkDescriptorPoolSize); +DECLARE_REFLECTION_STRUCT(VkDescriptorImageInfo); +DECLARE_REFLECTION_STRUCT(VkDescriptorBufferInfo); +DECLARE_REFLECTION_STRUCT(VkSpecializationInfo); +DECLARE_REFLECTION_STRUCT(VkAttachmentReference); +DECLARE_REFLECTION_STRUCT(VkSparseImageMemoryBind); +DECLARE_REFLECTION_STRUCT(VkVertexInputBindingDescription); +DECLARE_REFLECTION_STRUCT(VkVertexInputAttributeDescription); +DECLARE_REFLECTION_STRUCT(VkSpecializationMapEntry); +DECLARE_REFLECTION_STRUCT(VkRect2D); +DECLARE_REFLECTION_STRUCT(VkDeviceQueueCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFeatures); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryProperties); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProperties); +DECLARE_REFLECTION_STRUCT(VkDeviceCreateInfo); +DECLARE_REFLECTION_STRUCT(VkBufferCreateInfo); +DECLARE_REFLECTION_STRUCT(VkBufferViewCreateInfo); +DECLARE_REFLECTION_STRUCT(VkImageCreateInfo); +DECLARE_REFLECTION_STRUCT(VkImageViewCreateInfo); +DECLARE_REFLECTION_STRUCT(VkSparseMemoryBind); +DECLARE_REFLECTION_STRUCT(VkBindSparseInfo); +DECLARE_REFLECTION_STRUCT(VkSubmitInfo); +DECLARE_REFLECTION_STRUCT(VkFramebufferCreateInfo); +DECLARE_REFLECTION_STRUCT(VkRenderPassCreateInfo); +DECLARE_REFLECTION_STRUCT(VkRenderPassBeginInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineInputAssemblyStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineTessellationStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineViewportStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineMultisampleStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineDepthStencilStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineDynamicStateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineLayoutCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPushConstantRange); +DECLARE_REFLECTION_STRUCT(VkDescriptorSetLayoutBinding); +DECLARE_REFLECTION_STRUCT(VkDescriptorSetLayoutCreateInfo); +DECLARE_REFLECTION_STRUCT(VkDescriptorPoolCreateInfo); +DECLARE_REFLECTION_STRUCT(VkDescriptorSetAllocateInfo); +DECLARE_REFLECTION_STRUCT(VkWriteDescriptorSet); +DECLARE_REFLECTION_STRUCT(VkCopyDescriptorSet); +DECLARE_REFLECTION_STRUCT(VkCommandPoolCreateInfo); +DECLARE_REFLECTION_STRUCT(VkCommandBufferAllocateInfo); +DECLARE_REFLECTION_STRUCT(VkCommandBufferBeginInfo); +DECLARE_REFLECTION_STRUCT(VkStencilOpState); +DECLARE_REFLECTION_STRUCT(VkQueryPoolCreateInfo); +DECLARE_REFLECTION_STRUCT(VkSemaphoreCreateInfo); +DECLARE_REFLECTION_STRUCT(VkEventCreateInfo); +DECLARE_REFLECTION_STRUCT(VkFenceCreateInfo); +DECLARE_REFLECTION_STRUCT(VkSamplerCreateInfo); +DECLARE_REFLECTION_STRUCT(VkPipelineCacheCreateInfo); +DECLARE_REFLECTION_STRUCT(VkShaderModuleCreateInfo); +DECLARE_REFLECTION_STRUCT(VkImageSubresourceRange); +DECLARE_REFLECTION_STRUCT(VkImageSubresource); +DECLARE_REFLECTION_STRUCT(VkImageSubresourceLayers); +DECLARE_REFLECTION_STRUCT(VkMemoryAllocateInfo); +DECLARE_REFLECTION_STRUCT(VkMemoryBarrier); +DECLARE_REFLECTION_STRUCT(VkBufferMemoryBarrier); +DECLARE_REFLECTION_STRUCT(VkImageMemoryBarrier); +DECLARE_REFLECTION_STRUCT(VkGraphicsPipelineCreateInfo); +DECLARE_REFLECTION_STRUCT(VkComputePipelineCreateInfo); +DECLARE_REFLECTION_STRUCT(VkComponentMapping); +DECLARE_REFLECTION_STRUCT(VkMappedMemoryRange); +DECLARE_REFLECTION_STRUCT(VkBufferImageCopy); +DECLARE_REFLECTION_STRUCT(VkBufferCopy); +DECLARE_REFLECTION_STRUCT(VkImageCopy); +DECLARE_REFLECTION_STRUCT(VkImageBlit); +DECLARE_REFLECTION_STRUCT(VkImageResolve); +DECLARE_REFLECTION_STRUCT(VkSwapchainCreateInfoKHR); +DECLARE_REFLECTION_STRUCT(VkDebugMarkerMarkerInfoEXT); + +DECLARE_DESERIALISE_TYPE(VkDeviceCreateInfo); +DECLARE_DESERIALISE_TYPE(VkBufferCreateInfo); +DECLARE_DESERIALISE_TYPE(VkImageCreateInfo); +DECLARE_DESERIALISE_TYPE(VkBindSparseInfo); +DECLARE_DESERIALISE_TYPE(VkSubmitInfo); +DECLARE_DESERIALISE_TYPE(VkDescriptorSetAllocateInfo); +DECLARE_DESERIALISE_TYPE(VkFramebufferCreateInfo); +DECLARE_DESERIALISE_TYPE(VkRenderPassCreateInfo); +DECLARE_DESERIALISE_TYPE(VkRenderPassBeginInfo); +DECLARE_DESERIALISE_TYPE(VkCommandBufferBeginInfo); +DECLARE_DESERIALISE_TYPE(VkPipelineCacheCreateInfo); +DECLARE_DESERIALISE_TYPE(VkPipelineLayoutCreateInfo); +DECLARE_DESERIALISE_TYPE(VkShaderModuleCreateInfo); +DECLARE_DESERIALISE_TYPE(VkGraphicsPipelineCreateInfo); +DECLARE_DESERIALISE_TYPE(VkComputePipelineCreateInfo); +DECLARE_DESERIALISE_TYPE(VkDescriptorPoolCreateInfo); +DECLARE_DESERIALISE_TYPE(VkWriteDescriptorSet); +DECLARE_DESERIALISE_TYPE(VkDescriptorSetLayoutCreateInfo); + +DECLARE_REFLECTION_ENUM(VkFlagWithNoBits); +DECLARE_REFLECTION_ENUM(VkQueueFlagBits); +DECLARE_REFLECTION_ENUM(VkPipelineCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkPipelineStageFlagBits); +DECLARE_REFLECTION_ENUM(VkBufferUsageFlagBits); +DECLARE_REFLECTION_ENUM(VkImageUsageFlagBits); +DECLARE_REFLECTION_ENUM(VkBufferCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkImageCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkSparseMemoryBindFlagBits); +DECLARE_REFLECTION_ENUM(VkCommandPoolCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkCommandPoolResetFlagBits); +DECLARE_REFLECTION_ENUM(VkCommandBufferUsageFlagBits); +DECLARE_REFLECTION_ENUM(VkDescriptorPoolCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkFenceCreateFlagBits); +DECLARE_REFLECTION_ENUM(VkQueryPipelineStatisticFlagBits); +DECLARE_REFLECTION_ENUM(VkQueryControlFlagBits); +DECLARE_REFLECTION_ENUM(VkQueryResultFlagBits); +DECLARE_REFLECTION_ENUM(VkAttachmentDescriptionFlagBits); +DECLARE_REFLECTION_ENUM(VkSampleCountFlagBits); +DECLARE_REFLECTION_ENUM(VkImageAspectFlagBits); +DECLARE_REFLECTION_ENUM(VkDependencyFlagBits); +DECLARE_REFLECTION_ENUM(VkShaderStageFlagBits); +DECLARE_REFLECTION_ENUM(VkMemoryHeapFlagBits); +DECLARE_REFLECTION_ENUM(VkMemoryPropertyFlagBits); +DECLARE_REFLECTION_ENUM(VkAccessFlagBits); +DECLARE_REFLECTION_ENUM(VkStencilFaceFlagBits); +DECLARE_REFLECTION_ENUM(VkCullModeFlagBits); +DECLARE_REFLECTION_ENUM(VkPipelineBindPoint); +DECLARE_REFLECTION_ENUM(VkIndexType); +DECLARE_REFLECTION_ENUM(VkImageType); +DECLARE_REFLECTION_ENUM(VkImageTiling); +DECLARE_REFLECTION_ENUM(VkImageViewType); +DECLARE_REFLECTION_ENUM(VkVertexInputRate); +DECLARE_REFLECTION_ENUM(VkPolygonMode); +DECLARE_REFLECTION_ENUM(VkFrontFace); +DECLARE_REFLECTION_ENUM(VkBlendFactor); +DECLARE_REFLECTION_ENUM(VkBlendOp); +DECLARE_REFLECTION_ENUM(VkDynamicState); +DECLARE_REFLECTION_ENUM(VkAttachmentLoadOp); +DECLARE_REFLECTION_ENUM(VkAttachmentStoreOp); +DECLARE_REFLECTION_ENUM(VkStencilOp); +DECLARE_REFLECTION_ENUM(VkLogicOp); +DECLARE_REFLECTION_ENUM(VkCompareOp); +DECLARE_REFLECTION_ENUM(VkFilter); +DECLARE_REFLECTION_ENUM(VkSamplerMipmapMode); +DECLARE_REFLECTION_ENUM(VkSamplerAddressMode); +DECLARE_REFLECTION_ENUM(VkBorderColor); +DECLARE_REFLECTION_ENUM(VkPrimitiveTopology); +DECLARE_REFLECTION_ENUM(VkDescriptorType); +DECLARE_REFLECTION_ENUM(VkQueryType); +DECLARE_REFLECTION_ENUM(VkPhysicalDeviceType); +DECLARE_REFLECTION_ENUM(VkSharingMode); +DECLARE_REFLECTION_ENUM(VkCommandBufferLevel); +DECLARE_REFLECTION_ENUM(VkSubpassContents); +DECLARE_REFLECTION_ENUM(VkImageLayout); +DECLARE_REFLECTION_ENUM(VkStructureType); +DECLARE_REFLECTION_ENUM(VkComponentSwizzle); +DECLARE_REFLECTION_ENUM(VkFormat); +DECLARE_REFLECTION_ENUM(VkResult); +DECLARE_REFLECTION_ENUM(VkSurfaceTransformFlagBitsKHR); +DECLARE_REFLECTION_ENUM(VkCompositeAlphaFlagBitsKHR); +DECLARE_REFLECTION_ENUM(VkColorSpaceKHR); +DECLARE_REFLECTION_ENUM(VkPresentModeKHR); diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 2bfbc0c11..65a74813d 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -4955,6 +4955,8 @@ struct VulkanQuadOverdrawCallback : public VulkanDrawcallCallback m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), module); + m_pDriver->GetResourceManager()->AddLiveResource(GetResID(module), module); + bool found = false; for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) { diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 5b256bc98..82957206b 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -58,15 +58,7 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo bindings[b].immutableSampler = new ResourceId[bindings[b].descriptorCount]; for(uint32_t s = 0; s < bindings[b].descriptorCount; s++) - { - // during writing, the create info contains the *wrapped* objects. - // on replay, we have the wrapper map so we can look it up - if(resourceMan->IsWriting()) - bindings[b].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); - else - bindings[b].immutableSampler[s] = - resourceMan->GetNonDispWrapper(pCreateInfo->pBindings[i].pImmutableSamplers[s])->id; - } + bindings[b].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); } } } @@ -125,8 +117,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk { flags = pCreateInfo->flags; - layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; - renderpass = resourceMan->GetNonDispWrapper(pCreateInfo->renderPass)->id; + layout = GetResID(pCreateInfo->layout); + renderpass = GetResID(pCreateInfo->renderPass); subpass = pCreateInfo->subpass; // need to figure out which states are valid to be NULL @@ -134,7 +126,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk // VkPipelineShaderStageCreateInfo for(uint32_t i = 0; i < pCreateInfo->stageCount; i++) { - ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->pStages[i].module)->id; + ResourceId id = GetResID(pCreateInfo->pStages[i].module); // convert shader bit to shader index int stageIndex = StageIndex(pCreateInfo->pStages[i].stage); @@ -358,13 +350,13 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk { flags = pCreateInfo->flags; - layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; + layout = GetResID(pCreateInfo->layout); // need to figure out which states are valid to be NULL // VkPipelineShaderStageCreateInfo { - ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->stage.module)->id; + ResourceId id = GetResID(pCreateInfo->stage.module); Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) shad.module = id; @@ -451,7 +443,7 @@ void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan { descSetLayouts.resize(pCreateInfo->setLayoutCount); for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) - descSetLayouts[i] = resourceMan->GetNonDispWrapper(pCreateInfo->pSetLayouts[i])->id; + descSetLayouts[i] = GetResID(pCreateInfo->pSetLayouts[i]); pushRanges.reserve(pCreateInfo->pushConstantRangeCount); for(uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; i++) @@ -514,7 +506,7 @@ void VulkanCreationInfo::Framebuffer::Init(VulkanResourceManager *resourceMan, attachments.resize(pCreateInfo->attachmentCount); for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { - attachments[i].view = resourceMan->GetNonDispWrapper(pCreateInfo->pAttachments[i])->id; + attachments[i].view = GetResID(pCreateInfo->pAttachments[i]); attachments[i].format = info.m_ImageView[attachments[i].view].format; } } @@ -536,7 +528,7 @@ void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferViewCreateInfo *pCreateInfo) { - buffer = resourceMan->GetNonDispWrapper(pCreateInfo->buffer)->id; + buffer = GetResID(pCreateInfo->buffer); offset = pCreateInfo->offset; size = pCreateInfo->range; } @@ -608,7 +600,7 @@ static TextureSwizzle Convert(VkComponentSwizzle s, int i) void VulkanCreationInfo::ImageView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageViewCreateInfo *pCreateInfo) { - image = resourceMan->GetNonDispWrapper(pCreateInfo->image)->id; + image = GetResID(pCreateInfo->image); format = pCreateInfo->format; range = pCreateInfo->subresourceRange; diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index c733661c1..2a41c78ce 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -25,16 +25,6 @@ #include "vk_manager.h" #include "vk_core.h" -template <> -void Serialiser::Serialise(const char *name, ImageRegionState &el) -{ - ScopedContext scope(this, name, "ImageRegionState", 0, true); - - Serialise("range", el.subresourceRange); - Serialise("prevstate", el.oldLayout); - Serialise("state", el.newLayout); -} - bool VulkanResourceManager::SerialisableResource(ResourceId id, VkResourceRecord *record) { if(record->SpecialResource || id == m_Core->GetContextResourceID()) @@ -208,7 +198,7 @@ void VulkanResourceManager::RecordBarriers(vectorid : GetResID(t.image); + ResourceId id = IsReplayMode(m_State) ? GetNonDispWrapper(t.image)->id : GetResID(t.image); if(id == ResourceId()) { diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index c6c2f49f8..0b886c28e 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -3293,8 +3293,7 @@ void VulkanReplay::SavePipelineState() } else if(info[a].imageInfo.sampler != VK_NULL_HANDLE) { - dst.bindings[b].binds[a].sampler = - rm->GetNonDispWrapper(info[a].imageInfo.sampler)->id; + dst.bindings[b].binds[a].sampler = GetResID(info[a].imageInfo.sampler); } if(dst.bindings[b].binds[a].sampler != ResourceId()) @@ -3339,7 +3338,7 @@ void VulkanReplay::SavePipelineState() if(view != VK_NULL_HANDLE) { - ResourceId viewid = rm->GetNonDispWrapper(view)->id; + ResourceId viewid = GetResID(view); dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_ImageView[viewid].image); @@ -3369,7 +3368,7 @@ void VulkanReplay::SavePipelineState() if(view != VK_NULL_HANDLE) { - ResourceId viewid = rm->GetNonDispWrapper(view)->id; + ResourceId viewid = GetResID(view); dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_BufferView[viewid].buffer); @@ -3408,7 +3407,7 @@ void VulkanReplay::SavePipelineState() if(info[a].bufferInfo.buffer != VK_NULL_HANDLE) dst.bindings[b].binds[a].res = - rm->GetOriginalID(rm->GetNonDispWrapper(info[a].bufferInfo.buffer)->id); + rm->GetOriginalID(GetResID(info[a].bufferInfo.buffer)); dst.bindings[b].binds[a].offset = info[a].bufferInfo.offset; if(dynamicOffset) diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 8bf1c6f8c..b5594f0bc 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -817,6 +817,8 @@ struct ImageRegionState VkImageLayout newLayout; }; +DECLARE_REFLECTION_STRUCT(ImageRegionState); + struct SwapchainInfo { VkFormat format; @@ -1147,6 +1149,8 @@ struct ImageLayouts VkFormat format; }; +DECLARE_REFLECTION_STRUCT(ImageLayouts); + bool IsBlockFormat(VkFormat f); bool IsDepthOrStencilFormat(VkFormat f); bool IsDepthAndStencilFormat(VkFormat f); diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp new file mode 100644 index 000000000..1874fe505 --- /dev/null +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -0,0 +1,1871 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015-2017 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "vk_common.h" +#include "vk_manager.h" +#include "vk_resources.h" + +// simple way to express "resources referenced from this struct don't have to be present." +// since this is used during read when the processing is single-threaded, we make it a static flag. +// If we multi-thread reading, this could be stored in the Serialiser context somehow. +template +struct OptionalResources +{ +private: + OptionalResources() = default; +}; + +// does nothing on writing +template <> +struct OptionalResources> +{ + OptionalResources>(Serialiser &ser) + { + } + ~OptionalResources>() {} +}; + +template <> +struct OptionalResources> +{ + OptionalResources>(Serialiser &ser) + { + Counter++; + } + ~OptionalResources>() { Counter--; } + static int Counter; +}; + +template +OptionalResources ScopedOptional(SerialiserType &ser) +{ + return OptionalResources(ser); +} + +int OptionalResources>::Counter = 0; + +bool OptionalResourcesEnabled() +{ + return OptionalResources>::Counter > 0; +} + +// push/pop the optional flag. This doesn't allow non-optional objects in a sub-struct inside a +// struct that had optional objects... but that doesn't come up and seems unlikely. +#define OPTIONAL_RESOURCES() auto opt__LINE__ = ScopedOptional(ser); + +// serialisation of object handles via IDs. +template +void DoSerialiseViaResourceId(SerialiserType &ser, type &el) +{ + VulkanResourceManager *rm = (VulkanResourceManager *)ser.GetUserData(); + + ResourceId id; + + if(ser.IsWriting() && rm) + id = GetResID(el); + + DoSerialise(ser, id); + + if(ser.IsReading()) + { + el = VK_NULL_HANDLE; + + if(id != ResourceId() && rm) + { + if(rm->HasLiveResource(id)) + { + // we leave this wrapped. + el = rm->GetLiveHandle(id); + } + else if(!OptionalResourcesEnabled()) + { + // It can be OK for a resource to have no live equivalent if the capture decided its not + // needed, which some APIs do fairly often. + RDCWARN("Capture may be missing reference to %s resource.", TypeName()); + } + } + } +} + +#undef SERIALISE_HANDLE +#define SERIALISE_HANDLE(type) \ + template \ + void DoSerialise(SerialiserType &ser, type &el) \ + { \ + DoSerialiseViaResourceId(ser, el); \ + } \ + INSTANTIATE_SERIALISE_TYPE(type); + +SERIALISE_VK_HANDLES(); + +template +static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const void *&pNext) +{ + ser.Serialise("sType", sType); + + if(ser.IsReading()) + { + pNext = NULL; + } + else + { + if(pNext == NULL) + return; + + VkGenericStruct *next = (VkGenericStruct *)pNext; + + while(next) + { + // we can ignore this entirely, we don't need to serialise or replay it as we won't + // actually use external memory. Unwrapping, if necessary, happens elsewhere + if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV || + + next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR || + next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR) + { + // do nothing + } + // likewise we don't create real swapchains, so we can ignore surface counters + else if(next->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT) + { + // do nothing + } + // 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. + else if(next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV || + next->sType == VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR) + { + // do nothing + } + else + { + RDCERR("Unrecognised extension structure type %d", next->sType); + } + + next = (VkGenericStruct *)next->pNext; + } + } +} + +template +void DoSerialise(SerialiserType &ser, VkDeviceQueueCreateInfo &el) +{ + if(ser.IsWriting() && el.sType != VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO) + RDCWARN("sType not set properly: %u", el.sType); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(queueFamilyIndex); + SERIALISE_MEMBER(queueCount); + SERIALISE_MEMBER_ARRAY(pQueuePriorities, queueCount); +} + +// technically this doesn't need a serialise function as it's POD, +// but we give it one just for ease of printing etc. +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFeatures &el) +{ + SERIALISE_MEMBER(robustBufferAccess); + SERIALISE_MEMBER(fullDrawIndexUint32); + SERIALISE_MEMBER(imageCubeArray); + SERIALISE_MEMBER(independentBlend); + SERIALISE_MEMBER(geometryShader); + SERIALISE_MEMBER(tessellationShader); + SERIALISE_MEMBER(sampleRateShading); + SERIALISE_MEMBER(dualSrcBlend); + SERIALISE_MEMBER(logicOp); + SERIALISE_MEMBER(multiDrawIndirect); + SERIALISE_MEMBER(drawIndirectFirstInstance); + SERIALISE_MEMBER(depthClamp); + SERIALISE_MEMBER(depthBiasClamp); + SERIALISE_MEMBER(fillModeNonSolid); + SERIALISE_MEMBER(depthBounds); + SERIALISE_MEMBER(wideLines); + SERIALISE_MEMBER(largePoints); + SERIALISE_MEMBER(alphaToOne); + SERIALISE_MEMBER(multiViewport); + SERIALISE_MEMBER(samplerAnisotropy); + SERIALISE_MEMBER(textureCompressionETC2); + SERIALISE_MEMBER(textureCompressionASTC_LDR); + SERIALISE_MEMBER(textureCompressionBC); + SERIALISE_MEMBER(occlusionQueryPrecise); + SERIALISE_MEMBER(pipelineStatisticsQuery); + SERIALISE_MEMBER(vertexPipelineStoresAndAtomics); + SERIALISE_MEMBER(fragmentStoresAndAtomics); + SERIALISE_MEMBER(shaderTessellationAndGeometryPointSize); + SERIALISE_MEMBER(shaderImageGatherExtended); + SERIALISE_MEMBER(shaderStorageImageExtendedFormats); + SERIALISE_MEMBER(shaderStorageImageMultisample); + SERIALISE_MEMBER(shaderStorageImageReadWithoutFormat); + SERIALISE_MEMBER(shaderStorageImageWriteWithoutFormat); + SERIALISE_MEMBER(shaderUniformBufferArrayDynamicIndexing); + SERIALISE_MEMBER(shaderSampledImageArrayDynamicIndexing); + SERIALISE_MEMBER(shaderStorageBufferArrayDynamicIndexing); + SERIALISE_MEMBER(shaderStorageImageArrayDynamicIndexing); + SERIALISE_MEMBER(shaderClipDistance); + SERIALISE_MEMBER(shaderCullDistance); + SERIALISE_MEMBER(shaderFloat64); + SERIALISE_MEMBER(shaderInt64); + SERIALISE_MEMBER(shaderInt16); + SERIALISE_MEMBER(shaderResourceResidency); + SERIALISE_MEMBER(shaderResourceMinLod); + SERIALISE_MEMBER(sparseBinding); + SERIALISE_MEMBER(sparseResidencyBuffer); + SERIALISE_MEMBER(sparseResidencyImage2D); + SERIALISE_MEMBER(sparseResidencyImage3D); + SERIALISE_MEMBER(sparseResidency2Samples); + SERIALISE_MEMBER(sparseResidency4Samples); + SERIALISE_MEMBER(sparseResidency8Samples); + SERIALISE_MEMBER(sparseResidency16Samples); + SERIALISE_MEMBER(sparseResidencyAliased); + SERIALISE_MEMBER(variableMultisampleRate); + SERIALISE_MEMBER(inheritedQueries); +} + +template +void DoSerialise(SerialiserType &ser, VkMemoryHeap &el) +{ + SERIALISE_MEMBER(size); + SERIALISE_MEMBER(flags); +} + +template +void DoSerialise(SerialiserType &ser, VkMemoryType &el) +{ + SERIALISE_MEMBER(propertyFlags); + SERIALISE_MEMBER(heapIndex); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceMemoryProperties &el) +{ + SERIALISE_MEMBER(memoryTypeCount); + SERIALISE_MEMBER(memoryTypes); + SERIALISE_MEMBER(memoryHeapCount); + SERIALISE_MEMBER(memoryHeaps); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceLimits &el) +{ + SERIALISE_MEMBER(maxImageDimension1D); + SERIALISE_MEMBER(maxImageDimension2D); + SERIALISE_MEMBER(maxImageDimension3D); + SERIALISE_MEMBER(maxImageDimensionCube); + SERIALISE_MEMBER(maxImageArrayLayers); + SERIALISE_MEMBER(maxTexelBufferElements); + SERIALISE_MEMBER(maxUniformBufferRange); + SERIALISE_MEMBER(maxStorageBufferRange); + SERIALISE_MEMBER(maxPushConstantsSize); + SERIALISE_MEMBER(maxMemoryAllocationCount); + SERIALISE_MEMBER(maxSamplerAllocationCount); + SERIALISE_MEMBER(bufferImageGranularity); + SERIALISE_MEMBER(sparseAddressSpaceSize); + SERIALISE_MEMBER(maxBoundDescriptorSets); + SERIALISE_MEMBER(maxPerStageDescriptorSamplers); + SERIALISE_MEMBER(maxPerStageDescriptorUniformBuffers); + SERIALISE_MEMBER(maxPerStageDescriptorStorageBuffers); + SERIALISE_MEMBER(maxPerStageDescriptorSampledImages); + SERIALISE_MEMBER(maxPerStageDescriptorStorageImages); + SERIALISE_MEMBER(maxPerStageDescriptorInputAttachments); + SERIALISE_MEMBER(maxPerStageResources); + SERIALISE_MEMBER(maxDescriptorSetSamplers); + SERIALISE_MEMBER(maxDescriptorSetUniformBuffers); + SERIALISE_MEMBER(maxDescriptorSetUniformBuffersDynamic); + SERIALISE_MEMBER(maxDescriptorSetStorageBuffers); + SERIALISE_MEMBER(maxDescriptorSetStorageBuffersDynamic); + SERIALISE_MEMBER(maxDescriptorSetSampledImages); + SERIALISE_MEMBER(maxDescriptorSetStorageImages); + SERIALISE_MEMBER(maxDescriptorSetInputAttachments); + SERIALISE_MEMBER(maxVertexInputAttributes); + SERIALISE_MEMBER(maxVertexInputBindings); + SERIALISE_MEMBER(maxVertexInputAttributeOffset); + SERIALISE_MEMBER(maxVertexInputBindingStride); + SERIALISE_MEMBER(maxVertexOutputComponents); + SERIALISE_MEMBER(maxTessellationGenerationLevel); + SERIALISE_MEMBER(maxTessellationPatchSize); + SERIALISE_MEMBER(maxTessellationControlPerVertexInputComponents); + SERIALISE_MEMBER(maxTessellationControlPerVertexOutputComponents); + SERIALISE_MEMBER(maxTessellationControlPerPatchOutputComponents); + SERIALISE_MEMBER(maxTessellationControlTotalOutputComponents); + SERIALISE_MEMBER(maxTessellationEvaluationInputComponents); + SERIALISE_MEMBER(maxTessellationEvaluationOutputComponents); + SERIALISE_MEMBER(maxGeometryShaderInvocations); + SERIALISE_MEMBER(maxGeometryInputComponents); + SERIALISE_MEMBER(maxGeometryOutputComponents); + SERIALISE_MEMBER(maxGeometryOutputVertices); + SERIALISE_MEMBER(maxGeometryTotalOutputComponents); + SERIALISE_MEMBER(maxFragmentInputComponents); + SERIALISE_MEMBER(maxFragmentOutputAttachments); + SERIALISE_MEMBER(maxFragmentDualSrcAttachments); + SERIALISE_MEMBER(maxFragmentCombinedOutputResources); + SERIALISE_MEMBER(maxComputeSharedMemorySize); + SERIALISE_MEMBER(maxComputeWorkGroupCount); + SERIALISE_MEMBER(maxComputeWorkGroupInvocations); + SERIALISE_MEMBER(maxComputeWorkGroupSize); + SERIALISE_MEMBER(subPixelPrecisionBits); + SERIALISE_MEMBER(subTexelPrecisionBits); + SERIALISE_MEMBER(mipmapPrecisionBits); + SERIALISE_MEMBER(maxDrawIndexedIndexValue); + SERIALISE_MEMBER(maxDrawIndirectCount); + SERIALISE_MEMBER(maxSamplerLodBias); + SERIALISE_MEMBER(maxSamplerAnisotropy); + SERIALISE_MEMBER(maxViewports); + SERIALISE_MEMBER(maxViewportDimensions); + SERIALISE_MEMBER(viewportBoundsRange); + SERIALISE_MEMBER(viewportSubPixelBits); + + // don't serialise size_t, otherwise capture/replay between different bit-ness won't work + { + uint64_t minMemoryMapAlignment = (uint64_t)el.minMemoryMapAlignment; + ser.Serialise("minMemoryMapAlignment", minMemoryMapAlignment); + if(ser.IsReading()) + el.minMemoryMapAlignment = (size_t)minMemoryMapAlignment; + } + + SERIALISE_MEMBER(minTexelBufferOffsetAlignment); + SERIALISE_MEMBER(minUniformBufferOffsetAlignment); + SERIALISE_MEMBER(minStorageBufferOffsetAlignment); + SERIALISE_MEMBER(minTexelOffset); + SERIALISE_MEMBER(maxTexelOffset); + SERIALISE_MEMBER(minTexelGatherOffset); + SERIALISE_MEMBER(maxTexelGatherOffset); + SERIALISE_MEMBER(minInterpolationOffset); + SERIALISE_MEMBER(maxInterpolationOffset); + SERIALISE_MEMBER(subPixelInterpolationOffsetBits); + SERIALISE_MEMBER(maxFramebufferWidth); + SERIALISE_MEMBER(maxFramebufferHeight); + SERIALISE_MEMBER(maxFramebufferLayers); + SERIALISE_MEMBER(framebufferColorSampleCounts); + SERIALISE_MEMBER(framebufferDepthSampleCounts); + SERIALISE_MEMBER(framebufferStencilSampleCounts); + SERIALISE_MEMBER(framebufferNoAttachmentsSampleCounts); + SERIALISE_MEMBER(maxColorAttachments); + SERIALISE_MEMBER(sampledImageColorSampleCounts); + SERIALISE_MEMBER(sampledImageIntegerSampleCounts); + SERIALISE_MEMBER(sampledImageDepthSampleCounts); + SERIALISE_MEMBER(sampledImageStencilSampleCounts); + SERIALISE_MEMBER(storageImageSampleCounts); + SERIALISE_MEMBER(maxSampleMaskWords); + SERIALISE_MEMBER(timestampComputeAndGraphics); + SERIALISE_MEMBER(timestampPeriod); + SERIALISE_MEMBER(maxClipDistances); + SERIALISE_MEMBER(maxCullDistances); + SERIALISE_MEMBER(maxCombinedClipAndCullDistances); + SERIALISE_MEMBER(discreteQueuePriorities); + SERIALISE_MEMBER(pointSizeRange); + SERIALISE_MEMBER(lineWidthRange); + SERIALISE_MEMBER(pointSizeGranularity); + SERIALISE_MEMBER(lineWidthGranularity); + SERIALISE_MEMBER(strictLines); + SERIALISE_MEMBER(standardSampleLocations); + SERIALISE_MEMBER(optimalBufferCopyOffsetAlignment); + SERIALISE_MEMBER(optimalBufferCopyRowPitchAlignment); + SERIALISE_MEMBER(nonCoherentAtomSize); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceSparseProperties &el) +{ + SERIALISE_MEMBER(residencyStandard2DBlockShape); + SERIALISE_MEMBER(residencyStandard2DMultisampleBlockShape); + SERIALISE_MEMBER(residencyStandard3DBlockShape); + SERIALISE_MEMBER(residencyAlignedMipSize); + SERIALISE_MEMBER(residencyNonResidentStrict); +} + +template +void DoSerialise(SerialiserType &ser, VkQueueFamilyProperties &el) +{ + SERIALISE_MEMBER(queueFlags); + SERIALISE_MEMBER(queueCount); + SERIALISE_MEMBER(timestampValidBits); + SERIALISE_MEMBER(minImageTransferGranularity); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceProperties &el) +{ + SERIALISE_MEMBER(apiVersion); + SERIALISE_MEMBER(driverVersion); + SERIALISE_MEMBER(vendorID); + SERIALISE_MEMBER(deviceID); + SERIALISE_MEMBER(deviceType); + SERIALISE_MEMBER(deviceName); + SERIALISE_MEMBER(pipelineCacheUUID); + SERIALISE_MEMBER(limits); + SERIALISE_MEMBER(sparseProperties); +} + +template +void DoSerialise(SerialiserType &ser, VkDeviceCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pQueueCreateInfos, queueCreateInfoCount); + SERIALISE_MEMBER_ARRAY(ppEnabledExtensionNames, enabledExtensionCount); + SERIALISE_MEMBER_ARRAY(ppEnabledLayerNames, enabledLayerCount); + SERIALISE_MEMBER_OPT(pEnabledFeatures); +} + +template <> +void Deserialise(const VkDeviceCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + for(uint32_t i = 0; i < el.queueCreateInfoCount; i++) + delete[] el.pQueueCreateInfos[i].pQueuePriorities; + delete[] el.pQueueCreateInfos; + delete[] el.ppEnabledExtensionNames; + delete[] el.ppEnabledLayerNames; + delete el.pEnabledFeatures; +} + +template +void DoSerialise(SerialiserType &ser, VkBufferCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkBufferCreateFlagBits, flags); + SERIALISE_MEMBER(size); + SERIALISE_MEMBER_TYPED(VkBufferUsageFlagBits, usage); + SERIALISE_MEMBER(sharingMode); + + // pQueueFamilyIndices should *only* be read if the sharing mode is concurrent + if(el.sharingMode == VK_SHARING_MODE_CONCURRENT) + { + SERIALISE_MEMBER_ARRAY(pQueueFamilyIndices, queueFamilyIndexCount); + } + else if(ser.IsReading()) + { + // otherwise just set to NULL for sanity + el.pQueueFamilyIndices = NULL; + el.queueFamilyIndexCount = 0; + } +} + +template <> +void Deserialise(const VkBufferCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pQueueFamilyIndices; +} + +template +void DoSerialise(SerialiserType &ser, VkBufferViewCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(buffer); + SERIALISE_MEMBER(format); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(range); +} + +template +void DoSerialise(SerialiserType &ser, VkImageCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkImageCreateFlagBits, flags); + SERIALISE_MEMBER(imageType); + SERIALISE_MEMBER(format); + SERIALISE_MEMBER(extent); + SERIALISE_MEMBER(mipLevels); + SERIALISE_MEMBER(arrayLayers); + SERIALISE_MEMBER(samples); + SERIALISE_MEMBER(tiling); + SERIALISE_MEMBER_TYPED(VkImageUsageFlagBits, usage); + SERIALISE_MEMBER(sharingMode); + SERIALISE_MEMBER(initialLayout); + + // pQueueFamilyIndices should *only* be read if the sharing mode is concurrent + if(el.sharingMode == VK_SHARING_MODE_CONCURRENT) + { + SERIALISE_MEMBER_ARRAY(pQueueFamilyIndices, queueFamilyIndexCount); + } + else if(ser.IsReading()) + { + // otherwise just set to NULL for sanity + el.pQueueFamilyIndices = NULL; + el.queueFamilyIndexCount = 0; + } +} + +template <> +void Deserialise(const VkImageCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pQueueFamilyIndices; +} + +template +void DoSerialise(SerialiserType &ser, VkImageViewCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(image); + SERIALISE_MEMBER(viewType); + SERIALISE_MEMBER(format); + SERIALISE_MEMBER(components); + SERIALISE_MEMBER(subresourceRange); +} + +template +void DoSerialise(SerialiserType &ser, VkSparseMemoryBind &el) +{ + SERIALISE_MEMBER(resourceOffset); + SERIALISE_MEMBER(size); + SERIALISE_MEMBER(memory); + SERIALISE_MEMBER(memoryOffset); + SERIALISE_MEMBER_TYPED(VkSparseMemoryBindFlagBits, flags); +} + +template +void DoSerialise(SerialiserType &ser, VkSparseBufferMemoryBindInfo &el) +{ + SERIALISE_MEMBER(buffer); + SERIALISE_MEMBER_ARRAY(pBinds, bindCount); +} + +template +void DoSerialise(SerialiserType &ser, VkSparseImageOpaqueMemoryBindInfo &el) +{ + SERIALISE_MEMBER(image); + SERIALISE_MEMBER_ARRAY(pBinds, bindCount); +} + +template +void DoSerialise(SerialiserType &ser, VkSparseImageMemoryBind &el) +{ + SERIALISE_MEMBER(subresource); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(extent); + SERIALISE_MEMBER(memory); + SERIALISE_MEMBER(memoryOffset); + SERIALISE_MEMBER_TYPED(VkSparseMemoryBindFlagBits, flags); +} + +template +void DoSerialise(SerialiserType &ser, VkSparseImageMemoryBindInfo &el) +{ + SERIALISE_MEMBER(image); + SERIALISE_MEMBER_ARRAY(pBinds, bindCount); +} + +template +void DoSerialise(SerialiserType &ser, VkBindSparseInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_ARRAY(pWaitSemaphores, waitSemaphoreCount); + + SERIALISE_MEMBER_ARRAY(pBufferBinds, bufferBindCount); + SERIALISE_MEMBER_ARRAY(pImageOpaqueBinds, imageOpaqueBindCount); + SERIALISE_MEMBER_ARRAY(pImageBinds, imageBindCount); + + SERIALISE_MEMBER_ARRAY(pSignalSemaphores, signalSemaphoreCount); +} + +template <> +void Deserialise(const VkBindSparseInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pWaitSemaphores; + for(uint32_t i = 0; i < el.bufferBindCount; i++) + delete[] el.pBufferBinds[i].pBinds; + delete[] el.pBufferBinds; + for(uint32_t i = 0; i < el.imageOpaqueBindCount; i++) + delete[] el.pImageOpaqueBinds[i].pBinds; + delete[] el.pImageOpaqueBinds; + for(uint32_t i = 0; i < el.imageBindCount; i++) + delete[] el.pImageBinds[i].pBinds; + delete[] el.pImageBinds; + delete[] el.pSignalSemaphores; +} + +template +void DoSerialise(SerialiserType &ser, VkSubmitInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SUBMIT_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + // bit of a hack, we alias the ptr here to the bits type so we serialise with better type info + union + { + const VkPipelineStageFlagBits **typed; + const VkPipelineStageFlags **orig; + } u; + u.orig = &el.pWaitDstStageMask; + + ser.Serialise("pWaitDstStageMask", *u.typed, el.waitSemaphoreCount, + SerialiserFlags::AllocateMemory); + SERIALISE_MEMBER_ARRAY(pWaitSemaphores, waitSemaphoreCount); + SERIALISE_MEMBER_ARRAY(pCommandBuffers, commandBufferCount); + SERIALISE_MEMBER_ARRAY(pSignalSemaphores, signalSemaphoreCount); +} + +template <> +void Deserialise(const VkSubmitInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pWaitSemaphores; + delete[] el.pCommandBuffers; + delete[] el.pSignalSemaphores; +} + +template +void DoSerialise(SerialiserType &ser, VkFramebufferCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(renderPass); + SERIALISE_MEMBER(width); + SERIALISE_MEMBER(height); + SERIALISE_MEMBER(layers); + SERIALISE_MEMBER_ARRAY(pAttachments, attachmentCount); +} + +template <> +void Deserialise(const VkFramebufferCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pAttachments; +} + +template +void DoSerialise(SerialiserType &ser, VkAttachmentDescription &el) +{ + SERIALISE_MEMBER_TYPED(VkAttachmentDescriptionFlagBits, flags); + SERIALISE_MEMBER(format); + SERIALISE_MEMBER(samples); + SERIALISE_MEMBER(loadOp); + SERIALISE_MEMBER(storeOp); + SERIALISE_MEMBER(stencilLoadOp); + SERIALISE_MEMBER(stencilStoreOp); + SERIALISE_MEMBER(initialLayout); + SERIALISE_MEMBER(finalLayout); +} + +template +void DoSerialise(SerialiserType &ser, VkSubpassDescription &el) +{ + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(pipelineBindPoint); + SERIALISE_MEMBER_OPT(pDepthStencilAttachment); + SERIALISE_MEMBER_ARRAY(pInputAttachments, inputAttachmentCount); + SERIALISE_MEMBER_ARRAY(pResolveAttachments, colorAttachmentCount); + SERIALISE_MEMBER_ARRAY(pColorAttachments, colorAttachmentCount); + SERIALISE_MEMBER_ARRAY(pPreserveAttachments, preserveAttachmentCount); +} + +template +void DoSerialise(SerialiserType &ser, VkSubpassDependency &el) +{ + SERIALISE_MEMBER(srcSubpass); + SERIALISE_MEMBER(dstSubpass); + SERIALISE_MEMBER_TYPED(VkPipelineStageFlagBits, srcStageMask); + SERIALISE_MEMBER_TYPED(VkPipelineStageFlagBits, dstStageMask); + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, srcAccessMask); + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, dstAccessMask); + SERIALISE_MEMBER_TYPED(VkDependencyFlagBits, dependencyFlags); +} + +template +void DoSerialise(SerialiserType &ser, VkAttachmentReference &el) +{ + SERIALISE_MEMBER(attachment); + SERIALISE_MEMBER(layout); +} + +template +void DoSerialise(SerialiserType &ser, VkRenderPassCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pAttachments, attachmentCount); + SERIALISE_MEMBER_ARRAY(pSubpasses, subpassCount); + SERIALISE_MEMBER_ARRAY(pDependencies, dependencyCount); +} + +template <> +void Deserialise(const VkRenderPassCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pAttachments; + for(uint32_t i = 0; i < el.subpassCount; i++) + { + delete el.pSubpasses[i].pDepthStencilAttachment; + delete[] el.pSubpasses[i].pInputAttachments; + delete[] el.pSubpasses[i].pColorAttachments; + delete[] el.pSubpasses[i].pResolveAttachments; + if(el.pSubpasses[i].pPreserveAttachments) + delete[] el.pSubpasses[i].pPreserveAttachments; + } + delete[] el.pSubpasses; + delete[] el.pDependencies; +} + +template +void DoSerialise(SerialiserType &ser, VkRenderPassBeginInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(renderPass); + SERIALISE_MEMBER(framebuffer); + SERIALISE_MEMBER(renderArea); + SERIALISE_MEMBER_ARRAY(pClearValues, clearValueCount); +} + +template <> +void Deserialise(const VkRenderPassBeginInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pClearValues; +} + +template +void DoSerialise(SerialiserType &ser, VkVertexInputBindingDescription &el) +{ + SERIALISE_MEMBER(binding); + SERIALISE_MEMBER(stride); + SERIALISE_MEMBER(inputRate); +} + +template +void DoSerialise(SerialiserType &ser, VkVertexInputAttributeDescription &el) +{ + SERIALISE_MEMBER(location); + SERIALISE_MEMBER(binding); + SERIALISE_MEMBER(format); + SERIALISE_MEMBER(offset); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineVertexInputStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pVertexBindingDescriptions, vertexBindingDescriptionCount); + SERIALISE_MEMBER_ARRAY(pVertexAttributeDescriptions, vertexAttributeDescriptionCount); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineInputAssemblyStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(topology); + SERIALISE_MEMBER(primitiveRestartEnable); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineTessellationStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(patchControlPoints); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineViewportStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + + SERIALISE_MEMBER_ARRAY(pViewports, viewportCount); + SERIALISE_MEMBER_ARRAY(pScissors, scissorCount); + + // need to handle these arrays potentially being NULL if they're dynamic, we still want the count + SERIALISE_MEMBER(viewportCount); + SERIALISE_MEMBER(scissorCount); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineRasterizationStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(depthClampEnable); + SERIALISE_MEMBER(rasterizerDiscardEnable); + SERIALISE_MEMBER(polygonMode); + SERIALISE_MEMBER(cullMode); + SERIALISE_MEMBER(frontFace); + SERIALISE_MEMBER(depthBiasEnable); + SERIALISE_MEMBER(depthBiasConstantFactor); + SERIALISE_MEMBER(depthBiasClamp); + SERIALISE_MEMBER(depthBiasSlopeFactor); + SERIALISE_MEMBER(lineWidth); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineMultisampleStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(rasterizationSamples); + RDCASSERT(el.rasterizationSamples <= VK_SAMPLE_COUNT_32_BIT); + SERIALISE_MEMBER(sampleShadingEnable); + SERIALISE_MEMBER(minSampleShading); + SERIALISE_MEMBER_OPT(pSampleMask); + SERIALISE_MEMBER(alphaToCoverageEnable); + SERIALISE_MEMBER(alphaToOneEnable); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineColorBlendAttachmentState &el) +{ + SERIALISE_MEMBER(blendEnable); + SERIALISE_MEMBER(srcColorBlendFactor); + SERIALISE_MEMBER(dstColorBlendFactor); + SERIALISE_MEMBER(colorBlendOp); + SERIALISE_MEMBER(srcAlphaBlendFactor); + SERIALISE_MEMBER(dstAlphaBlendFactor); + SERIALISE_MEMBER(alphaBlendOp); + SERIALISE_MEMBER(colorWriteMask); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineColorBlendStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(logicOpEnable); + SERIALISE_MEMBER(logicOp); + SERIALISE_MEMBER_ARRAY(pAttachments, attachmentCount); + SERIALISE_MEMBER(blendConstants); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineDepthStencilStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(depthTestEnable); + SERIALISE_MEMBER(depthWriteEnable); + SERIALISE_MEMBER(depthCompareOp); + SERIALISE_MEMBER(depthBoundsTestEnable); + SERIALISE_MEMBER(stencilTestEnable); + SERIALISE_MEMBER(front); + SERIALISE_MEMBER(back); + SERIALISE_MEMBER(minDepthBounds); + SERIALISE_MEMBER(maxDepthBounds); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineDynamicStateCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pDynamicStates, dynamicStateCount); +} + +template +void DoSerialise(SerialiserType &ser, VkCommandPoolCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkCommandPoolCreateFlagBits, flags); + SERIALISE_MEMBER(queueFamilyIndex); +} + +template +void DoSerialise(SerialiserType &ser, VkCommandBufferAllocateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(commandPool); + SERIALISE_MEMBER(level); + SERIALISE_MEMBER(commandBufferCount); +} + +template +void DoSerialise(SerialiserType &ser, VkCommandBufferInheritanceInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(renderPass); + SERIALISE_MEMBER(subpass); + SERIALISE_MEMBER(framebuffer); + SERIALISE_MEMBER(occlusionQueryEnable); + SERIALISE_MEMBER_TYPED(VkQueryControlFlagBits, queryFlags); + SERIALISE_MEMBER_TYPED(VkQueryPipelineStatisticFlagBits, pipelineStatistics); +} + +template +void DoSerialise(SerialiserType &ser, VkCommandBufferBeginInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkCommandBufferUsageFlagBits, flags); + SERIALISE_MEMBER_OPT(pInheritanceInfo); +} + +template <> +void Deserialise(const VkCommandBufferBeginInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete el.pInheritanceInfo; +} + +template +void DoSerialise(SerialiserType &ser, VkStencilOpState &el) +{ + SERIALISE_MEMBER(failOp); + SERIALISE_MEMBER(passOp); + SERIALISE_MEMBER(depthFailOp); + SERIALISE_MEMBER(compareOp); + SERIALISE_MEMBER(compareMask); + SERIALISE_MEMBER(writeMask); + SERIALISE_MEMBER(reference); +} + +template +void DoSerialise(SerialiserType &ser, VkQueryPoolCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(queryType); + SERIALISE_MEMBER(queryCount); + SERIALISE_MEMBER_TYPED(VkQueryPipelineStatisticFlagBits, pipelineStatistics); +} + +template +void DoSerialise(SerialiserType &ser, VkSemaphoreCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); +} + +template +void DoSerialise(SerialiserType &ser, VkEventCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); +} + +template +void DoSerialise(SerialiserType &ser, VkFenceCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFenceCreateFlagBits, flags); +} + +template +void DoSerialise(SerialiserType &ser, VkSamplerCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(minFilter); + SERIALISE_MEMBER(magFilter); + SERIALISE_MEMBER(mipmapMode); + SERIALISE_MEMBER(addressModeU); + SERIALISE_MEMBER(addressModeV); + SERIALISE_MEMBER(addressModeW); + SERIALISE_MEMBER(mipLodBias); + SERIALISE_MEMBER(anisotropyEnable); + SERIALISE_MEMBER(maxAnisotropy); + SERIALISE_MEMBER(compareEnable); + SERIALISE_MEMBER(compareOp); + SERIALISE_MEMBER(minLod); + SERIALISE_MEMBER(maxLod); + SERIALISE_MEMBER(borderColor); + SERIALISE_MEMBER(unnormalizedCoordinates); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineShaderStageCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER(stage); + SERIALISE_MEMBER(module); + SERIALISE_MEMBER(pName); + SERIALISE_MEMBER_OPT(pSpecializationInfo); +} + +template +void DoSerialise(SerialiserType &ser, VkSpecializationMapEntry &el) +{ + SERIALISE_MEMBER(constantID); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(constantID); + + // don't serialise size_t, otherwise capture/replay between different bit-ness won't work + { + uint64_t size = el.size; + ser.Serialise("size", size); + if(ser.IsReading()) + el.size = (size_t)size; + } +} + +template +void DoSerialise(SerialiserType &ser, VkSpecializationInfo &el) +{ + SERIALISE_MEMBER_ARRAY(pData, dataSize); + SERIALISE_MEMBER_ARRAY(pMapEntries, mapEntryCount); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineCacheCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + + // don't serialise size_t, otherwise capture/replay between different bit-ness won't work + { + uint64_t initialDataSize = el.initialDataSize; + ser.Serialise("initialDataSize", initialDataSize); + if(ser.IsReading()) + el.initialDataSize = (size_t)initialDataSize; + } + + SERIALISE_MEMBER_ARRAY(pInitialData, initialDataSize); +} + +template <> +void Deserialise(const VkPipelineCacheCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + FreeAlignedBuffer((byte *)el.pInitialData); +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineLayoutCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pSetLayouts, setLayoutCount); + SERIALISE_MEMBER_ARRAY(pPushConstantRanges, pushConstantRangeCount); +} + +template <> +void Deserialise(const VkPipelineLayoutCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pSetLayouts; + delete[] el.pPushConstantRanges; +} + +template +void DoSerialise(SerialiserType &ser, VkShaderModuleCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + + // serialise as void* so it goes through as a buffer, not an actual array of integers. + { + const void *pCode = el.pCode; + ser.Serialise("pCode", pCode, el.codeSize, SerialiserFlags::AllocateMemory); + if(ser.IsReading()) + el.pCode = (uint32_t *)pCode; + } +} + +template <> +void Deserialise(const VkShaderModuleCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + FreeAlignedBuffer((byte *)el.pCode); +} + +template +void DoSerialise(SerialiserType &ser, VkImageSubresourceRange &el) +{ + SERIALISE_MEMBER_TYPED(VkImageAspectFlagBits, aspectMask); + SERIALISE_MEMBER(baseMipLevel); + SERIALISE_MEMBER(levelCount); + SERIALISE_MEMBER(baseArrayLayer); + SERIALISE_MEMBER(layerCount); +} + +template +void DoSerialise(SerialiserType &ser, VkImageSubresourceLayers &el) +{ + SERIALISE_MEMBER_TYPED(VkImageAspectFlagBits, aspectMask); + SERIALISE_MEMBER(mipLevel); + SERIALISE_MEMBER(baseArrayLayer); + SERIALISE_MEMBER(layerCount); +} + +template +void DoSerialise(SerialiserType &ser, VkImageSubresource &el) +{ + SERIALISE_MEMBER_TYPED(VkImageAspectFlagBits, aspectMask); + SERIALISE_MEMBER(mipLevel); + SERIALISE_MEMBER(arrayLayer); +} + +template +void DoSerialise(SerialiserType &ser, VkMemoryAllocateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(allocationSize); + SERIALISE_MEMBER(memoryTypeIndex); +} + +template +void DoSerialise(SerialiserType &ser, VkMemoryBarrier &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_MEMORY_BARRIER); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, srcAccessMask); + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, dstAccessMask); +} + +template +void DoSerialise(SerialiserType &ser, VkBufferMemoryBarrier &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, srcAccessMask); + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, dstAccessMask); + // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue + // family index won't be legitimately larger than 2 billion + SERIALISE_MEMBER_TYPED(int32_t, srcQueueFamilyIndex); + SERIALISE_MEMBER_TYPED(int32_t, dstQueueFamilyIndex); + SERIALISE_MEMBER(buffer); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(size); +} + +template +void DoSerialise(SerialiserType &ser, VkImageMemoryBarrier &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, srcAccessMask); + SERIALISE_MEMBER_TYPED(VkAccessFlagBits, dstAccessMask); + SERIALISE_MEMBER(oldLayout); + SERIALISE_MEMBER(newLayout); + // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue + // family index won't be legitimately larger than 2 billion + SERIALISE_MEMBER_TYPED(int32_t, srcQueueFamilyIndex); + SERIALISE_MEMBER_TYPED(int32_t, dstQueueFamilyIndex); + SERIALISE_MEMBER(image); + SERIALISE_MEMBER(subresourceRange); +} + +template +void DoSerialise(SerialiserType &ser, VkGraphicsPipelineCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkPipelineCreateFlagBits, flags); + SERIALISE_MEMBER(layout); + SERIALISE_MEMBER(renderPass); + SERIALISE_MEMBER(subpass); + SERIALISE_MEMBER(basePipelineHandle); + SERIALISE_MEMBER(basePipelineIndex); + + SERIALISE_MEMBER_OPT(pVertexInputState); + SERIALISE_MEMBER_OPT(pInputAssemblyState); + SERIALISE_MEMBER_OPT(pTessellationState); + SERIALISE_MEMBER_OPT(pViewportState); + SERIALISE_MEMBER_OPT(pRasterizationState); + SERIALISE_MEMBER_OPT(pMultisampleState); + SERIALISE_MEMBER_OPT(pDepthStencilState); + SERIALISE_MEMBER_OPT(pColorBlendState); + SERIALISE_MEMBER_OPT(pDynamicState); + SERIALISE_MEMBER_ARRAY(pStages, stageCount); +} + +template <> +void Deserialise(const VkGraphicsPipelineCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + if(el.pVertexInputState) + { + RDCASSERT(el.pVertexInputState->pNext == NULL); // otherwise delete + delete[] el.pVertexInputState->pVertexBindingDescriptions; + delete[] el.pVertexInputState->pVertexAttributeDescriptions; + delete el.pVertexInputState; + } + if(el.pInputAssemblyState) + { + RDCASSERT(el.pInputAssemblyState->pNext == NULL); // otherwise delete + delete el.pInputAssemblyState; + } + if(el.pTessellationState) + { + RDCASSERT(el.pTessellationState->pNext == NULL); // otherwise delete + delete el.pTessellationState; + } + if(el.pViewportState) + { + RDCASSERT(el.pViewportState->pNext == NULL); // otherwise delete + if(el.pViewportState->pViewports) + delete[] el.pViewportState->pViewports; + if(el.pViewportState->pScissors) + delete[] el.pViewportState->pScissors; + delete el.pViewportState; + } + if(el.pRasterizationState) + { + RDCASSERT(el.pRasterizationState->pNext == NULL); // otherwise delete + delete el.pRasterizationState; + } + if(el.pMultisampleState) + { + RDCASSERT(el.pMultisampleState->pNext == NULL); // otherwise delete + delete el.pMultisampleState->pSampleMask; + delete el.pMultisampleState; + } + if(el.pDepthStencilState) + { + RDCASSERT(el.pDepthStencilState->pNext == NULL); // otherwise delete + delete el.pDepthStencilState; + } + if(el.pColorBlendState) + { + RDCASSERT(el.pColorBlendState->pNext == NULL); // otherwise delete + delete[] el.pColorBlendState->pAttachments; + delete el.pColorBlendState; + } + if(el.pDynamicState) + { + RDCASSERT(el.pDynamicState->pNext == NULL); // otherwise delete + if(el.pDynamicState->pDynamicStates) + delete[] el.pDynamicState->pDynamicStates; + delete el.pDynamicState; + } + for(uint32_t i = 0; i < el.stageCount; i++) + { + RDCASSERT(el.pStages[i].pNext == NULL); // otherwise delete + if(el.pStages[i].pSpecializationInfo) + { + FreeAlignedBuffer((byte *)el.pStages[i].pSpecializationInfo->pData); + delete[] el.pStages[i].pSpecializationInfo->pMapEntries; + delete el.pStages[i].pSpecializationInfo; + } + } + delete[] el.pStages; +} + +template +void DoSerialise(SerialiserType &ser, VkComputePipelineCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(stage); + SERIALISE_MEMBER_TYPED(VkPipelineCreateFlagBits, flags); + SERIALISE_MEMBER(layout); + SERIALISE_MEMBER(basePipelineHandle); + SERIALISE_MEMBER(basePipelineIndex); +} + +template <> +void Deserialise(const VkComputePipelineCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + RDCASSERT(el.stage.pNext == NULL); // otherwise delete + if(el.stage.pSpecializationInfo) + { + FreeAlignedBuffer((byte *)(el.stage.pSpecializationInfo->pData)); + delete[] el.stage.pSpecializationInfo->pMapEntries; + delete el.stage.pSpecializationInfo; + } +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorPoolSize &el) +{ + SERIALISE_MEMBER(type); + SERIALISE_MEMBER(descriptorCount); +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorPoolCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkDescriptorPoolCreateFlagBits, flags); + SERIALISE_MEMBER(maxSets); + SERIALISE_MEMBER_ARRAY(pPoolSizes, poolSizeCount); +} + +template <> +void Deserialise(const VkDescriptorPoolCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pPoolSizes; +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorSetAllocateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(descriptorPool); + SERIALISE_MEMBER_ARRAY(pSetLayouts, descriptorSetCount); +} + +template <> +void Deserialise(const VkDescriptorSetAllocateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + delete[] el.pSetLayouts; +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorImageInfo &el) +{ + // Resources in this struct are optional, because if we decided a descriptor wasn't used - we + // might still have recorded some updates to it + OPTIONAL_RESOURCES(); + + SERIALISE_MEMBER(sampler); + SERIALISE_MEMBER(imageView); + SERIALISE_MEMBER(imageLayout); +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorBufferInfo &el) +{ + // Resources in this struct are optional, because if we decided a descriptor wasn't used - we + // might still have recorded some updates to it + OPTIONAL_RESOURCES(); + + SERIALISE_MEMBER(buffer); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(range); +} + +template +void DoSerialise(SerialiserType &ser, VkWriteDescriptorSet &el) +{ + // Resources in this struct are optional, because if we decided a descriptor wasn't used - we + // might still have recorded some updates to it + OPTIONAL_RESOURCES(); + + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(dstSet); + SERIALISE_MEMBER(dstBinding); + SERIALISE_MEMBER(dstArrayElement); + SERIALISE_MEMBER(descriptorType); + + if(ser.IsReading()) + { + el.pImageInfo = NULL; + el.pBufferInfo = NULL; + el.pTexelBufferView = NULL; + } + + // only serialise the array type used, the others are ignored + if(el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + el.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || + el.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + { + SERIALISE_MEMBER_ARRAY(pImageInfo, descriptorCount); + } + else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + { + SERIALISE_MEMBER_ARRAY(pBufferInfo, descriptorCount); + } + else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + SERIALISE_MEMBER_ARRAY(pTexelBufferView, descriptorCount); + } +} + +template <> +void Deserialise(const VkWriteDescriptorSet &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + if(el.pImageInfo) + delete[] el.pImageInfo; + if(el.pBufferInfo) + delete[] el.pBufferInfo; + if(el.pTexelBufferView) + delete[] el.pTexelBufferView; +} + +template +void DoSerialise(SerialiserType &ser, VkCopyDescriptorSet &el) +{ + // Resources in this struct are optional, because if we decided a descriptor wasn't used - we + // might still have recorded some copies to or from it + OPTIONAL_RESOURCES(); + + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(srcSet); + SERIALISE_MEMBER(srcBinding); + SERIALISE_MEMBER(srcArrayElement); + SERIALISE_MEMBER(dstSet); + SERIALISE_MEMBER(dstBinding); + SERIALISE_MEMBER(dstArrayElement); + SERIALISE_MEMBER(descriptorCount); +} + +template +void DoSerialise(SerialiserType &ser, VkPushConstantRange &el) +{ + SERIALISE_MEMBER_TYPED(VkShaderStageFlagBits, stageFlags); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(size); +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorSetLayoutBinding &el) +{ + SERIALISE_MEMBER(binding); + SERIALISE_MEMBER(descriptorType); + SERIALISE_MEMBER_TYPED(VkShaderStageFlagBits, stageFlags); + SERIALISE_MEMBER_ARRAY(pImmutableSamplers, descriptorCount); + + // serialise count separately after, as if pImmutableSamplers is NULL, count would be set to 0 + SERIALISE_MEMBER(descriptorCount); +} + +template +void DoSerialise(SerialiserType &ser, VkDescriptorSetLayoutCreateInfo &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + SERIALISE_MEMBER_ARRAY(pBindings, bindingCount); +} + +template <> +void Deserialise(const VkDescriptorSetLayoutCreateInfo &el) +{ + RDCASSERT(el.pNext == NULL); // otherwise delete + for(uint32_t i = 0; i < el.bindingCount; i++) + if(el.pBindings[i].pImmutableSamplers) + delete[] el.pBindings[i].pImmutableSamplers; + delete[] el.pBindings; +} + +template +void DoSerialise(SerialiserType &ser, VkComponentMapping &el) +{ + SERIALISE_MEMBER(r); + SERIALISE_MEMBER(g); + SERIALISE_MEMBER(b); + SERIALISE_MEMBER(a); +} + +template +void DoSerialise(SerialiserType &ser, VkMappedMemoryRange &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(memory); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(size); +} + +template +void DoSerialise(SerialiserType &ser, VkBufferImageCopy &el) +{ + SERIALISE_MEMBER(bufferOffset); + SERIALISE_MEMBER(bufferRowLength); + SERIALISE_MEMBER(bufferImageHeight); + SERIALISE_MEMBER(imageSubresource); + SERIALISE_MEMBER(imageOffset); + SERIALISE_MEMBER(imageExtent); +} + +template +void DoSerialise(SerialiserType &ser, VkBufferCopy &el) +{ + SERIALISE_MEMBER(srcOffset); + SERIALISE_MEMBER(dstOffset); + SERIALISE_MEMBER(size); +} + +template +void DoSerialise(SerialiserType &ser, VkImageCopy &el) +{ + SERIALISE_MEMBER(srcSubresource); + SERIALISE_MEMBER(srcOffset); + SERIALISE_MEMBER(dstSubresource); + SERIALISE_MEMBER(dstOffset); + SERIALISE_MEMBER(extent); +} + +template +void DoSerialise(SerialiserType &ser, VkImageBlit &el) +{ + SERIALISE_MEMBER(srcSubresource); + SERIALISE_MEMBER(srcOffsets); + SERIALISE_MEMBER(dstSubresource); + SERIALISE_MEMBER(dstOffsets); +} + +template +void DoSerialise(SerialiserType &ser, VkImageResolve &el) +{ + SERIALISE_MEMBER(srcSubresource); + SERIALISE_MEMBER(srcOffset); + SERIALISE_MEMBER(dstSubresource); + SERIALISE_MEMBER(dstOffset); + SERIALISE_MEMBER(extent); +} + +template +void DoSerialise(SerialiserType &ser, VkClearColorValue &el) +{ + SERIALISE_MEMBER(uint32); +} + +template +void DoSerialise(SerialiserType &ser, VkClearDepthStencilValue &el) +{ + SERIALISE_MEMBER(depth); + SERIALISE_MEMBER(stencil); +} + +template +void DoSerialise(SerialiserType &ser, VkClearValue &el) +{ + SERIALISE_MEMBER(depthStencil); + SERIALISE_MEMBER(color); +} + +template +void DoSerialise(SerialiserType &ser, VkClearRect &el) +{ + SERIALISE_MEMBER(rect); + SERIALISE_MEMBER(baseArrayLayer); + SERIALISE_MEMBER(layerCount); +} + +template +void DoSerialise(SerialiserType &ser, VkClearAttachment &el) +{ + SERIALISE_MEMBER(aspectMask); + SERIALISE_MEMBER(colorAttachment); + SERIALISE_MEMBER(clearValue); +} + +template +void DoSerialise(SerialiserType &ser, VkRect2D &el) +{ + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER(extent); +} + +template +void DoSerialise(SerialiserType &ser, VkOffset2D &el) +{ + SERIALISE_MEMBER(x); + SERIALISE_MEMBER(y); +} + +template +void DoSerialise(SerialiserType &ser, VkOffset3D &el) +{ + SERIALISE_MEMBER(x); + SERIALISE_MEMBER(y); + SERIALISE_MEMBER(z); +} + +template +void DoSerialise(SerialiserType &ser, VkExtent2D &el) +{ + SERIALISE_MEMBER(width); + SERIALISE_MEMBER(height); +} + +template +void DoSerialise(SerialiserType &ser, VkExtent3D &el) +{ + SERIALISE_MEMBER(width); + SERIALISE_MEMBER(height); + SERIALISE_MEMBER(depth); +} + +template +void DoSerialise(SerialiserType &ser, VkViewport &el) +{ + SERIALISE_MEMBER(x); + SERIALISE_MEMBER(y); + SERIALISE_MEMBER(width); + SERIALISE_MEMBER(height); + SERIALISE_MEMBER(minDepth); + SERIALISE_MEMBER(maxDepth); +} + +template +void DoSerialise(SerialiserType &ser, VkSwapchainCreateInfoKHR &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags); + + // don't need the surface + + SERIALISE_MEMBER(minImageCount); + SERIALISE_MEMBER(imageFormat); + SERIALISE_MEMBER(imageColorSpace); + SERIALISE_MEMBER(imageExtent); + SERIALISE_MEMBER(imageArrayLayers); + SERIALISE_MEMBER(imageUsage); + SERIALISE_MEMBER(imageSharingMode); + + // SHARING: queueFamilyCount, pQueueFamilyIndices + + SERIALISE_MEMBER(preTransform); + SERIALISE_MEMBER(compositeAlpha); + SERIALISE_MEMBER(presentMode); + SERIALISE_MEMBER(clipped); + + // don't need the old swap chain +} + +template +void DoSerialise(SerialiserType &ser, VkDebugMarkerMarkerInfoEXT &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(pMarkerName); + SERIALISE_MEMBER(color); +} + +// this isn't a real vulkan type, it's our own "anything that could be in a descriptor" +// structure that +template +void DoSerialise(SerialiserType &ser, DescriptorSetSlot &el) +{ + // Resources in this struct are optional, because if we decided a descriptor wasn't used - we + // might still have recorded the contents of it + OPTIONAL_RESOURCES(); + + SERIALISE_MEMBER(bufferInfo); + SERIALISE_MEMBER(imageInfo); + SERIALISE_MEMBER(texelBufferView); +} + +template +void DoSerialise(SerialiserType &ser, ImageRegionState &el) +{ + SERIALISE_MEMBER(subresourceRange); + SERIALISE_MEMBER(oldLayout); + SERIALISE_MEMBER(newLayout); +} + +template +void DoSerialise(SerialiserType &ser, ImageLayouts &el) +{ + SERIALISE_MEMBER(subresourceStates); + SERIALISE_MEMBER(layerCount); + SERIALISE_MEMBER(levelCount); + SERIALISE_MEMBER(sampleCount); + SERIALISE_MEMBER(extent); + SERIALISE_MEMBER(format); +} + +INSTANTIATE_SERIALISE_TYPE(VkOffset2D); +INSTANTIATE_SERIALISE_TYPE(VkExtent2D); +INSTANTIATE_SERIALISE_TYPE(VkMemoryType); +INSTANTIATE_SERIALISE_TYPE(VkMemoryHeap); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceLimits); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceSparseProperties); +INSTANTIATE_SERIALISE_TYPE(VkQueueFamilyProperties); +INSTANTIATE_SERIALISE_TYPE(VkExtent3D); +INSTANTIATE_SERIALISE_TYPE(VkPipelineShaderStageCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkOffset3D); +INSTANTIATE_SERIALISE_TYPE(VkCommandBufferInheritanceInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineVertexInputStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkSparseBufferMemoryBindInfo); +INSTANTIATE_SERIALISE_TYPE(VkSparseImageOpaqueMemoryBindInfo); +INSTANTIATE_SERIALISE_TYPE(VkSparseImageMemoryBindInfo); +INSTANTIATE_SERIALISE_TYPE(VkAttachmentDescription); +INSTANTIATE_SERIALISE_TYPE(VkSubpassDescription); +INSTANTIATE_SERIALISE_TYPE(VkSubpassDependency); +INSTANTIATE_SERIALISE_TYPE(VkClearValue); +INSTANTIATE_SERIALISE_TYPE(VkClearColorValue); +INSTANTIATE_SERIALISE_TYPE(VkClearDepthStencilValue); +INSTANTIATE_SERIALISE_TYPE(VkClearAttachment); +INSTANTIATE_SERIALISE_TYPE(VkClearRect); +INSTANTIATE_SERIALISE_TYPE(VkViewport); +INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendAttachmentState); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorPoolSize); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorImageInfo); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorBufferInfo); +INSTANTIATE_SERIALISE_TYPE(VkSpecializationInfo); +INSTANTIATE_SERIALISE_TYPE(VkAttachmentReference); +INSTANTIATE_SERIALISE_TYPE(VkSparseImageMemoryBind); +INSTANTIATE_SERIALISE_TYPE(VkVertexInputBindingDescription); +INSTANTIATE_SERIALISE_TYPE(VkVertexInputAttributeDescription); +INSTANTIATE_SERIALISE_TYPE(VkSpecializationMapEntry); +INSTANTIATE_SERIALISE_TYPE(VkRect2D); +INSTANTIATE_SERIALISE_TYPE(VkDeviceQueueCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFeatures); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryProperties); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProperties); +INSTANTIATE_SERIALISE_TYPE(VkDeviceCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkBufferCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkBufferViewCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkImageCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkImageViewCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkSparseMemoryBind); +INSTANTIATE_SERIALISE_TYPE(VkBindSparseInfo); +INSTANTIATE_SERIALISE_TYPE(VkSubmitInfo); +INSTANTIATE_SERIALISE_TYPE(VkFramebufferCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkRenderPassCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkRenderPassBeginInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineTessellationStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineViewportStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineMultisampleStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineDynamicStateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineLayoutCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPushConstantRange); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetLayoutBinding); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetLayoutCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorPoolCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetAllocateInfo); +INSTANTIATE_SERIALISE_TYPE(VkWriteDescriptorSet); +INSTANTIATE_SERIALISE_TYPE(VkCopyDescriptorSet); +INSTANTIATE_SERIALISE_TYPE(VkCommandPoolCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkCommandBufferAllocateInfo); +INSTANTIATE_SERIALISE_TYPE(VkCommandBufferBeginInfo); +INSTANTIATE_SERIALISE_TYPE(VkStencilOpState); +INSTANTIATE_SERIALISE_TYPE(VkQueryPoolCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkSemaphoreCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkEventCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkFenceCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkSamplerCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkPipelineCacheCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkShaderModuleCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkImageSubresourceRange); +INSTANTIATE_SERIALISE_TYPE(VkImageSubresource); +INSTANTIATE_SERIALISE_TYPE(VkImageSubresourceLayers); +INSTANTIATE_SERIALISE_TYPE(VkMemoryAllocateInfo); +INSTANTIATE_SERIALISE_TYPE(VkMemoryBarrier); +INSTANTIATE_SERIALISE_TYPE(VkBufferMemoryBarrier); +INSTANTIATE_SERIALISE_TYPE(VkImageMemoryBarrier); +INSTANTIATE_SERIALISE_TYPE(VkGraphicsPipelineCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkComputePipelineCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkComponentMapping); +INSTANTIATE_SERIALISE_TYPE(VkMappedMemoryRange); +INSTANTIATE_SERIALISE_TYPE(VkBufferImageCopy); +INSTANTIATE_SERIALISE_TYPE(VkBufferCopy); +INSTANTIATE_SERIALISE_TYPE(VkImageCopy); +INSTANTIATE_SERIALISE_TYPE(VkImageBlit); +INSTANTIATE_SERIALISE_TYPE(VkImageResolve); +INSTANTIATE_SERIALISE_TYPE(VkSwapchainCreateInfoKHR); +INSTANTIATE_SERIALISE_TYPE(VkDebugMarkerMarkerInfoEXT); + +INSTANTIATE_SERIALISE_TYPE(DescriptorSetSlot); +INSTANTIATE_SERIALISE_TYPE(ImageRegionState); +INSTANTIATE_SERIALISE_TYPE(ImageLayouts); \ No newline at end of file diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp index 1ab231677..971267039 100644 --- a/renderdoc/driver/vulkan/vk_stringise.cpp +++ b/renderdoc/driver/vulkan/vk_stringise.cpp @@ -1310,106 +1310,6 @@ std::string DoStringise(const VkResult &el) END_ENUM_STRINGISE(); } -template <> -std::string DoStringise(const VkMemoryType &el) -{ - return StringFormat::Fmt("VkMemoryType", el.heapIndex, - ToStr((VkMemoryPropertyFlagBits)el.propertyFlags).c_str()); -} - -template <> -std::string DoStringise(const VkMemoryHeap &el) -{ - return StringFormat::Fmt("VkMemoryHeap<%.3fMB, %s>", float(el.size) / (1024.0f * 1024.0f), - ToStr((VkMemoryHeapFlagBits)el.flags).c_str()); -} - -template <> -std::string DoStringise(const VkRect2D &el) -{ - return StringFormat::Fmt("VkRect2D<%dx%d+%d+%d>", el.extent.width, el.extent.height, el.offset.x, - el.offset.y); -} - -template <> -std::string DoStringise(const VkClearRect &el) -{ - return StringFormat::Fmt("VkClearRect<%dx%d+%d+%d %u->%u>", el.rect.extent.width, - el.rect.extent.height, el.rect.offset.x, el.rect.offset.y, - el.baseArrayLayer, el.baseArrayLayer + el.layerCount); -} - -template <> -std::string DoStringise(const VkClearAttachment &el) -{ - return StringFormat::Fmt("%s[%u] = %s", ToStr((VkImageAspectFlagBits)el.aspectMask).c_str(), - el.colorAttachment, ToStr(el.clearValue).c_str()); -} - -template <> -std::string DoStringise(const VkQueueFamilyProperties &el) -{ - return StringFormat::Fmt("%s x %u, %u bits, %s", ToStr((VkQueueFlagBits)el.queueFlags).c_str(), - el.queueCount, el.timestampValidBits, - ToStr(el.minImageTransferGranularity).c_str()); -} - -template <> -std::string DoStringise(const VkExtent2D &el) -{ - return StringFormat::Fmt("VkExtent<%u,%u>", el.width, el.height); -} - -template <> -std::string DoStringise(const VkExtent3D &el) -{ - return StringFormat::Fmt("VkExtent<%u,%u,%u>", el.width, el.height, el.depth); -} - -template <> -std::string DoStringise(const VkOffset2D &el) -{ - return StringFormat::Fmt("VkOffset<%d,%d>", el.x, el.y); -} - -template <> -std::string DoStringise(const VkOffset3D &el) -{ - return StringFormat::Fmt("VkOffset<%d,%d,%d>", el.x, el.y, el.z); -} - -template <> -std::string DoStringise(const VkViewport &el) -{ - return StringFormat::Fmt("VkViewport<%f,%f, %fx%f, %f-%f>", el.x, el.y, el.width, el.height, - el.minDepth, el.maxDepth); -} - -template <> -std::string DoStringise(const VkClearColorValue &el) -{ - return StringFormat::Fmt("VkClearColorValue<%f,%f,%f,%f>", el.float32[0], el.float32[1], - el.float32[2], el.float32[3]); -} -template <> -std::string DoStringise(const VkClearDepthStencilValue &el) -{ - return StringFormat::Fmt("VkClearDepthStencilValue<%f %u>", el.depth, el.stencil); -} -template <> -std::string DoStringise(const VkClearValue &el) -{ - return StringFormat::Fmt("VkClearValue[ col:<%f,%f,%f,%f> / d:%f s:%u ]", el.color.float32[0], - el.color.float32[1], el.color.float32[2], el.color.float32[3], - el.depthStencil.depth, el.depthStencil.stencil); -} - -template <> -std::string DoStringise(const VkAttachmentReference &el) -{ - return StringFormat::Fmt("VkAttachmentReference<%u, %s>", el.attachment, ToStr(el.layout).c_str()); -} - //////////////////////////////////////////////////////////// // VK_KHR_surface //////////////////////////////////////////////////////////// @@ -1484,3 +1384,9 @@ std::string DoStringise(const VkPresentModeKHR &el) } END_ENUM_STRINGISE(); } + +template <> +std::string DoStringise(const VkExtent3D &el) +{ + return StringFormat::Fmt("VkExtent3D(%u, %u, %u)", el.width, el.height, el.depth); +}