diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index ec794bc5d..e68dff5d5 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -869,12 +869,16 @@ bool WrappedVulkan::Serialise_vkFlushMappedMemoryRanges(SerialiserType &ser, VkD if(!state->refData) { // if we're in this case, the range should be for the whole memory region. - RDCASSERT(MemRange.offset == state->mapOffset && memRangeSize == state->mapSize); + RDCASSERT(MemRange.offset == state->mapOffset && memRangeSize == state->mapSize, + MemRange.offset, memRangeSize, state->mapOffset, state->mapSize); // allocate ref data so we can compare next time to minimise serialised data state->refData = AllocAlignedBuffer((size_t)state->mapSize); } + // the memory range offset should always be at least the map offset + RDCASSERT(MemRange.offset >= state->mapOffset, MemRange.offset, state->mapOffset); + // it's no longer safe to use state->mappedPtr, we need to save *precisely* what // was serialised. We do this by copying out of the serialiser since we know this // memory is not changing @@ -882,7 +886,7 @@ bool WrappedVulkan::Serialise_vkFlushMappedMemoryRanges(SerialiserType &ser, VkD const byte *serialisedData = ser.GetWriter()->GetData() + offs; - memcpy(state->refData, serialisedData, (size_t)memRangeSize); + memcpy(state->refData + MemRange.offset - state->mapOffset, serialisedData, (size_t)memRangeSize); } return true; diff --git a/util/test/demos/vk/vk_misaligned_dirty.cpp b/util/test/demos/vk/vk_misaligned_dirty.cpp index 43a34bbbd..29abc9039 100644 --- a/util/test/demos/vk/vk_misaligned_dirty.cpp +++ b/util/test/demos/vk/vk_misaligned_dirty.cpp @@ -95,8 +95,8 @@ RD_TEST(VK_Misaligned_Dirty, VulkanGraphicsTest) float counter = 0; while(Running()) { - mapped[2] = counter; counter += 1.0f; + mapped[2] = counter; VkCommandBuffer cmd = GetCommandBuffer(); @@ -106,10 +106,10 @@ RD_TEST(VK_Misaligned_Dirty, VulkanGraphicsTest) setMarker(cmd, "First Submit"); vkCmdUpdateBuffer(cmd, copy_src.buffer, sizeof(Vec3f), sizeof(Vec4f), &tri[0].col); vkEndCommandBuffer(cmd); - Submit(0, 2, {cmd}); + Submit(0, 3, {cmd}); - mapped[2] = counter; counter += 1.0f; + mapped[2] = counter; cmd = GetCommandBuffer(); @@ -149,7 +149,19 @@ RD_TEST(VK_Misaligned_Dirty, VulkanGraphicsTest) vkEndCommandBuffer(cmd); - Submit(1, 2, {cmd}); + Submit(1, 3, {cmd}); + + mapped[2] = counter - 1.0f; + + cmd = GetCommandBuffer(); + + // create a dummy submit which uses the memory. This will serialise the whole memory contents + // (we don't create reference data until after this) + vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo()); + setMarker(cmd, "Third Submit"); + vkCmdUpdateBuffer(cmd, copy_src.buffer, sizeof(Vec3f), sizeof(Vec4f), &tri[0].col); + vkEndCommandBuffer(cmd); + Submit(2, 3, {cmd}); Present(); } diff --git a/util/test/tests/Vulkan/VK_Misaligned_Dirty.py b/util/test/tests/Vulkan/VK_Misaligned_Dirty.py index 58c6773d6..c3c8900d4 100644 --- a/util/test/tests/Vulkan/VK_Misaligned_Dirty.py +++ b/util/test/tests/Vulkan/VK_Misaligned_Dirty.py @@ -78,9 +78,11 @@ class VK_Misaligned_Dirty(rdtest.TestCase): checkpoint1 = self.find_draw("First Submit") checkpoint2 = self.find_draw("Second Submit") + checkpoint3 = self.find_draw("Third Submit") self.check(checkpoint1 is not None) self.check(checkpoint2 is not None) + self.check(checkpoint3 is not None) resources = self.controller.GetResources() @@ -99,13 +101,18 @@ class VK_Misaligned_Dirty(rdtest.TestCase): self.controller.SetFrameEvent(checkpoint1.eventId, False) val = struct.unpack('f', self.controller.GetBufferData(copy_src, 116, 4)) - self.check(val[0] == 10.0) + self.check(val[0] == 11.0) self.controller.SetFrameEvent(checkpoint2.eventId, False) val = struct.unpack('f', self.controller.GetBufferData(copy_src, 116, 4)) - self.check(val[0] == 11.0) + self.check(val[0] == 12.0) val = struct.unpack('f', self.controller.GetBufferData(vb, 116, 4)) + self.check(val[0] == 12.0) + + self.controller.SetFrameEvent(checkpoint3.eventId, False) + + val = struct.unpack('f', self.controller.GetBufferData(copy_src, 116, 4)) self.check(val[0] == 11.0) rdtest.log.success("buffers have correct values in both submits")