From 4879f6da6e34eee2a32c03e8e673b10ba763a283 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 24 Apr 2018 14:45:42 +0100 Subject: [PATCH] Mark which members of VkDescriptorImageInfo are valid to serialise * We need to pass flags down from the parent struct to know, since it depends on the type of descriptor. This could happen in any case, but is most likely for templated descriptor updates where the memory that is referenced could be garbage. --- renderdoc/driver/vulkan/vk_serialise.cpp | 47 +++++++++++++++++++++++- renderdoc/serialise/serialiser.h | 7 ++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index eac1590d7..cfbcd3c13 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -1509,6 +1509,15 @@ void Deserialise(const VkDescriptorSetAllocateInfo &el) delete[] el.pSetLayouts; } +enum class VkDescriptorImageInfoValidity +{ + Neither = 0x0, + Sampler = 0x1, + ImageView = 0x100, +}; + +BITMASK_OPERATORS(VkDescriptorImageInfoValidity); + template void DoSerialise(SerialiserType &ser, VkDescriptorImageInfo &el) { @@ -1516,8 +1525,20 @@ void DoSerialise(SerialiserType &ser, VkDescriptorImageInfo &el) // might still have recorded some updates to it OPTIONAL_RESOURCES(); - SERIALISE_MEMBER(sampler); - SERIALISE_MEMBER(imageView); + VkDescriptorImageInfoValidity validity = (VkDescriptorImageInfoValidity)ser.GetStructArg(); + + RDCASSERT(validity != VkDescriptorImageInfoValidity::Neither, (uint64_t)validity); + + if(validity & VkDescriptorImageInfoValidity::Sampler) + SERIALISE_MEMBER(sampler); + else + SERIALISE_MEMBER_EMPTY(sampler); + + if(validity & VkDescriptorImageInfoValidity::ImageView) + SERIALISE_MEMBER(imageView); + else + SERIALISE_MEMBER_EMPTY(imageView); + SERIALISE_MEMBER(imageLayout); } @@ -1556,6 +1577,23 @@ void DoSerialise(SerialiserType &ser, VkWriteDescriptorSet &el) el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || el.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) { + VkDescriptorImageInfoValidity validity = VkDescriptorImageInfoValidity::Neither; + + if(el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + el.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + validity = validity | VkDescriptorImageInfoValidity::Sampler; + + if(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) + validity = validity | VkDescriptorImageInfoValidity::ImageView; + + // set the validity flags so the serialisation of VkDescriptorImageInfo knows which members are + // safe to read. We pass this as just flags so the comparisons happen here once, not per-element + // in this array + ser.SetStructArg((uint64_t)validity); + SERIALISE_MEMBER_ARRAY(pImageInfo, descriptorCount); } else @@ -1861,6 +1899,11 @@ void DoSerialise(SerialiserType &ser, DescriptorSetSlot &el) // might still have recorded the contents of it OPTIONAL_RESOURCES(); + // all members are valid because it's either NULL or pointing at an existing element, it won't + // point to garbage. + ser.SetStructArg( + uint64_t(VkDescriptorImageInfoValidity::Sampler | VkDescriptorImageInfoValidity::ImageView)); + SERIALISE_MEMBER(bufferInfo); SERIALISE_MEMBER(imageInfo); SERIALISE_MEMBER(texelBufferView); diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index 8a61fd35d..0ce6ebd19 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -134,6 +134,11 @@ public: SDFile &GetStructuredFile() { return *m_StructuredFile; } void WriteStructuredFile(const SDFile &file, RENDERDOC_ProgressCallback progress); void SetDrawChunk() { m_DrawChunk = true; } + // the struct argument allows nested structs to pass a bit of data so a child struct can have + // context from a parent struct if needed to serialise properly. Rarely used, primarily to be able + // to flag if some context-sensitive members might be invalid + void SetStructArg(uint64_t arg) { m_StructArg = arg; } + uint64_t GetStructArg() { return m_StructArg; } ////////////////////////////////////////// // Public serialisation interface @@ -1562,6 +1567,8 @@ private: void *m_pUserData = NULL; + uint64_t m_StructArg = 0; + StreamWriter *m_Write = NULL; StreamReader *m_Read = NULL;