From a9fabf414bf6043d821d80b0fe2ef81e3ed47f1c Mon Sep 17 00:00:00 2001 From: John Asper Date: Sun, 21 Mar 2021 12:29:24 -0400 Subject: [PATCH] Fix mapped memory Vulkan validation error If using Vulkan backend and either vertex_size or index_size is not aligned to VkPhysicalDeviceLimits::nonCoherentAtomSize, then the call to vkFlushMappedMemoryRanges in ImGui_ImplVulkan_RenderDrawData will result in the following validation error (on some drivers/cards): Validation Error: [ VUID-VkMappedMemoryRange-size-01389 ] Object 0: handle = 0xb200000000b2, type = VK_OBJECT_TYPE_DEVICE_MEMORY; | MessageID = 0xee4872d | vkFlushMappedMemoryRanges: Size in pMemRanges[1] is VK_WHOLE_SIZE and the mapping end (0x792 = 0x0 + 0x792) not a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize (0x40) and not equal to the end of the memory object (0x800). The Vulkan spec states: If size is equal to VK_WHOLE_SIZE, the end of the current mapping of memory must either be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize bytes from the beginning of the memory object, or be equal to the end of the memory object (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VUID-VkMappedMemoryRange-size-01389) Fix this by setting rb->VertexBufferSize and rb->IndexBufferSize to the aligned size in CreateOrResizeBuffer, and then using them as the size parameter in the calls to vkMapMemory. --- backends/imgui_impl_vulkan.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index d8c00e9b6449..e9433200f049 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -343,7 +343,7 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0); check_vk_result(err); - p_buffer_size = new_size; + p_buffer_size = req.size; } static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height) @@ -429,9 +429,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // Upload vertex/index data into a single contiguous GPU buffer ImDrawVert* vtx_dst = NULL; ImDrawIdx* idx_dst = NULL; - VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); + VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst)); check_vk_result(err); - err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst)); + err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst)); check_vk_result(err); for (int n = 0; n < draw_data->CmdListsCount; n++) {