From 1c0c2216b3aad1032952ec9e24bca7b7d3e8b080 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Sat, 29 Mar 2025 21:25:14 +0100 Subject: [PATCH 1/2] Add new tests for advanced data uploading --- src/Tests.cpp | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/src/Tests.cpp b/src/Tests.cpp index d96d945..a4f29f1 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -6153,6 +6153,264 @@ static void TestMemoryUsage() } } +static void TestDataUploadingWithStagingBuffer() +{ + wprintf(L"Testing data uploading with staging buffer...\n"); + + // Generate some random data to fill the uniform buffer with. + const VkDeviceSize bufferSize = 65536; + std::vector bufferData(bufferSize); + for (auto& bufferByte : bufferData) { + bufferByte = static_cast(rand() % 256); + } + + VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + uniformBufferCI.size = bufferSize; + uniformBufferCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change this if you want to create another type of buffer. + + VmaAllocationCreateInfo uniformBufferAllocCI = {}; + uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; + uniformBufferAllocCI.flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + + VkBuffer uniformBuffer = VK_NULL_HANDLE; + VmaAllocation uniformBufferAlloc = {}; + VmaAllocationInfo uniformBufferAllocInfo = {}; + + VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo); + TEST(result == VK_SUCCESS); + + // We need to check if the uniform buffer really ended NOT up in mappable memory. + VkMemoryPropertyFlags memPropFlags; + vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags); + TEST(!(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)); + + VkBufferCreateInfo stagingBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + stagingBufferCI.size = bufferSize; + stagingBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + VmaAllocationCreateInfo stagingBufferAllocCI = {}; + stagingBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; + stagingBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VkBuffer stagingBuffer = VK_NULL_HANDLE; + VmaAllocation stagingBufferAlloc = {}; + VmaAllocationInfo stagingBufferAllocInfo = {}; + + result = vmaCreateBuffer(g_hAllocator, &stagingBufferCI, &stagingBufferAllocCI, &stagingBuffer, &stagingBufferAlloc, &stagingBufferAllocInfo); + TEST(result == VK_SUCCESS); + + TEST(stagingBufferAllocInfo.pMappedData != nullptr); + std::memcpy(stagingBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); + + result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); + TEST(result == VK_SUCCESS); + + BeginSingleTimeCommands(); + + VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + bufferMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.buffer = stagingBuffer; + bufferMemBarrier.offset = 0; + bufferMemBarrier.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr); + + VkBufferCopy bufferCopy = {}; + bufferCopy.srcOffset = 0; + bufferCopy.dstOffset = 0; + bufferCopy.size = bufferSize; + + vkCmdCopyBuffer(g_hTemporaryCommandBuffer, stagingBuffer, uniformBuffer, 1, &bufferCopy); + + VkBufferMemoryBarrier bufferMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + bufferMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer. + bufferMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier2.buffer = uniformBuffer; + bufferMemBarrier2.offset = 0; + bufferMemBarrier2.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier2, 0, nullptr); + + EndSingleTimeCommands(); + + vmaDestroyBuffer(g_hAllocator, stagingBuffer, stagingBufferAlloc); + vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc); +} + +static void TestDataUploadingWithMappedMemory() { + wprintf(L"Testing data uploading with mapped memory and memcpy...\n"); + + // Generate some random data to fill the uniform buffer with. + const VkDeviceSize bufferSize = 65536; + std::vector bufferData(bufferSize); + for (auto& bufferByte : bufferData) { + bufferByte = static_cast(rand() % 256); + } + + VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + uniformBufferCI.size = bufferSize; + uniformBufferCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; // Change this if you want to create another type of buffer. + + VmaAllocationCreateInfo uniformBufferAllocCI = {}; + uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; + uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; // We want memory to be mapped so we can use memcpy to update it + + VkBuffer uniformBuffer = VK_NULL_HANDLE; + VmaAllocation uniformBufferAlloc = {}; + VmaAllocationInfo uniformBufferAllocInfo = {}; + + VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo); + TEST(result == VK_SUCCESS); + + // We need to check if the uniform buffer really ended up in mappable memory. + VkMemoryPropertyFlags memPropFlags; + vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags); + TEST(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + TEST(uniformBufferAllocInfo.pMappedData != nullptr); + std::memcpy(uniformBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); + + // We don't need to check for VK_MEMORY_PROPERTY_HOST_COHERENT_BIT because both vmaFlushAllocation and vmaInvalidateAllocation check for this internally. + result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); + TEST(result == VK_SUCCESS); + + BeginSingleTimeCommands(); + + VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + bufferMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer. + bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.buffer = uniformBuffer; + bufferMemBarrier.offset = 0; + bufferMemBarrier.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr); + + EndSingleTimeCommands(); + + vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc); +} + +static void TestAdvancedDataUploading() { + wprintf(L"Testing advanced data uploading...\n"); + + // Generate some random data to fill the uniform buffer with. + const VkDeviceSize bufferSize = 65536; + std::vector bufferData(bufferSize); + for (auto& bufferByte : bufferData) { + bufferByte = static_cast(rand() % 256); + } + + VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + uniformBufferCI.size = bufferSize; + uniformBufferCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change this if you want to create another type of buffer. + + VmaAllocationCreateInfo uniformBufferAllocCI = {}; + uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; + uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VkBuffer uniformBuffer = VK_NULL_HANDLE; + VmaAllocation uniformBufferAlloc = {}; + VmaAllocationInfo uniformBufferAllocInfo = {}; + + VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo); + TEST(result == VK_SUCCESS); + + VkMemoryPropertyFlags memPropFlags; + vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags); + + if (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + // The allocation ended up as mapped memory, meaning we can update it simply by using std::memcpy. + TEST(uniformBufferAllocInfo.pMappedData != nullptr); + std::memcpy(uniformBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); + + // We don't need to check for VK_MEMORY_PROPERTY_HOST_COHERENT_BIT because both vmaFlushAllocation and vmaInvalidateAllocation check for this internally. + result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); + TEST(result == VK_SUCCESS); + + BeginSingleTimeCommands(); + + VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + bufferMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer. + bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.buffer = uniformBuffer; + bufferMemBarrier.offset = 0; + bufferMemBarrier.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr); + + EndSingleTimeCommands(); + } + else { + // The allocation did not end up in mapped memory, so we need a staging buffer and a copy operation to update it. + VkBufferCreateInfo stagingBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + stagingBufferCI.size = bufferSize; + stagingBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + VmaAllocationCreateInfo stagingBufferAllocCI = {}; + stagingBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; + stagingBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VkBuffer stagingBuffer = VK_NULL_HANDLE; + VmaAllocation stagingBufferAlloc = {}; + VmaAllocationInfo stagingBufferAllocInfo = {}; + + result = vmaCreateBuffer(g_hAllocator, &stagingBufferCI, &stagingBufferAllocCI, &stagingBuffer, &stagingBufferAlloc, &stagingBufferAllocInfo); + TEST(result == VK_SUCCESS); + + TEST(stagingBufferAllocInfo.pMappedData != nullptr); + std::memcpy(stagingBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); + + result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); + TEST(result == VK_SUCCESS); + + BeginSingleTimeCommands(); + + VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + bufferMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier.buffer = stagingBuffer; + bufferMemBarrier.offset = 0; + bufferMemBarrier.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr); + + VkBufferCopy bufferCopy = {}; + bufferCopy.srcOffset = 0; + bufferCopy.dstOffset = 0; + bufferCopy.size = bufferSize; + + vkCmdCopyBuffer(g_hTemporaryCommandBuffer, stagingBuffer, uniformBuffer, 1, &bufferCopy); + + VkBufferMemoryBarrier bufferMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + bufferMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + bufferMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer. + bufferMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemBarrier2.buffer = uniformBuffer; + bufferMemBarrier2.offset = 0; + bufferMemBarrier2.size = VK_WHOLE_SIZE; + + vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier2, 0, nullptr); + + EndSingleTimeCommands(); + + vmaDestroyBuffer(g_hAllocator, stagingBuffer, stagingBufferAlloc); + } + + vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc); +} + static uint32_t FindDeviceCoherentMemoryTypeBits() { VkPhysicalDeviceMemoryProperties memProps; @@ -8352,6 +8610,9 @@ void Test() TestAllocationsInitialization(); #endif TestMemoryUsage(); + TestDataUploadingWithStagingBuffer(); + TestDataUploadingWithMappedMemory(); + TestAdvancedDataUploading(); TestDeviceCoherentMemory(); TestStatistics(); TestAliasing(); From 2fdbc642c9a31d296af18ee8e2bc3b31ee2d6365 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Tue, 1 Apr 2025 17:08:03 +0200 Subject: [PATCH 2/2] Add changes requested in code review --- src/Tests.cpp | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/Tests.cpp b/src/Tests.cpp index a4f29f1..86b181f 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -6161,7 +6161,7 @@ static void TestDataUploadingWithStagingBuffer() const VkDeviceSize bufferSize = 65536; std::vector bufferData(bufferSize); for (auto& bufferByte : bufferData) { - bufferByte = static_cast(rand() % 256); + bufferByte = static_cast(rand()); } VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -6170,20 +6170,14 @@ static void TestDataUploadingWithStagingBuffer() VmaAllocationCreateInfo uniformBufferAllocCI = {}; uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; - uniformBufferAllocCI.flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkBuffer uniformBuffer = VK_NULL_HANDLE; - VmaAllocation uniformBufferAlloc = {}; + VmaAllocation uniformBufferAlloc = VK_NULL_HANDLE; VmaAllocationInfo uniformBufferAllocInfo = {}; VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo); TEST(result == VK_SUCCESS); - // We need to check if the uniform buffer really ended NOT up in mappable memory. - VkMemoryPropertyFlags memPropFlags; - vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags); - TEST(!(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)); - VkBufferCreateInfo stagingBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; stagingBufferCI.size = bufferSize; stagingBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; @@ -6200,10 +6194,7 @@ static void TestDataUploadingWithStagingBuffer() TEST(result == VK_SUCCESS); TEST(stagingBufferAllocInfo.pMappedData != nullptr); - std::memcpy(stagingBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); - - result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); - TEST(result == VK_SUCCESS); + vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), stagingBufferAlloc, 0, bufferData.size()); BeginSingleTimeCommands(); @@ -6243,7 +6234,7 @@ static void TestDataUploadingWithStagingBuffer() } static void TestDataUploadingWithMappedMemory() { - wprintf(L"Testing data uploading with mapped memory and memcpy...\n"); + wprintf(L"Testing data uploading with mapped memory...\n"); // Generate some random data to fill the uniform buffer with. const VkDeviceSize bufferSize = 65536; @@ -6258,10 +6249,10 @@ static void TestDataUploadingWithMappedMemory() { VmaAllocationCreateInfo uniformBufferAllocCI = {}; uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; - uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; // We want memory to be mapped so we can use memcpy to update it + uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; // We want memory to be mapped. VkBuffer uniformBuffer = VK_NULL_HANDLE; - VmaAllocation uniformBufferAlloc = {}; + VmaAllocation uniformBufferAlloc = VK_NULL_HANDLE; VmaAllocationInfo uniformBufferAllocInfo = {}; VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo); @@ -6273,11 +6264,7 @@ static void TestDataUploadingWithMappedMemory() { TEST(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); TEST(uniformBufferAllocInfo.pMappedData != nullptr); - std::memcpy(uniformBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); - - // We don't need to check for VK_MEMORY_PROPERTY_HOST_COHERENT_BIT because both vmaFlushAllocation and vmaInvalidateAllocation check for this internally. - result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); - TEST(result == VK_SUCCESS); + vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), uniformBufferAlloc, 0, bufferData.size()); BeginSingleTimeCommands(); @@ -6313,7 +6300,8 @@ static void TestAdvancedDataUploading() { VmaAllocationCreateInfo uniformBufferAllocCI = {}; uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO; - uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT + | VMA_ALLOCATION_CREATE_MAPPED_BIT; VkBuffer uniformBuffer = VK_NULL_HANDLE; VmaAllocation uniformBufferAlloc = {}; @@ -6326,13 +6314,9 @@ static void TestAdvancedDataUploading() { vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags); if (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - // The allocation ended up as mapped memory, meaning we can update it simply by using std::memcpy. + // The allocation ended up as mapped memory. TEST(uniformBufferAllocInfo.pMappedData != nullptr); - std::memcpy(uniformBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); - - // We don't need to check for VK_MEMORY_PROPERTY_HOST_COHERENT_BIT because both vmaFlushAllocation and vmaInvalidateAllocation check for this internally. - result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); - TEST(result == VK_SUCCESS); + vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), uniformBufferAlloc, 0, bufferData.size()); BeginSingleTimeCommands(); @@ -6367,7 +6351,7 @@ static void TestAdvancedDataUploading() { TEST(result == VK_SUCCESS); TEST(stagingBufferAllocInfo.pMappedData != nullptr); - std::memcpy(stagingBufferAllocInfo.pMappedData, bufferData.data(), bufferData.size()); + vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), stagingBufferAlloc, 0, bufferData.size()); result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE); TEST(result == VK_SUCCESS);