Skip to content

Commit be826d1

Browse files
Merge pull request #474 from IAmNotHanni/master
Add new tests for advanced data uploading
2 parents 811773f + 2fdbc64 commit be826d1

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed

src/Tests.cpp

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6153,6 +6153,248 @@ static void TestMemoryUsage()
61536153
}
61546154
}
61556155

6156+
static void TestDataUploadingWithStagingBuffer()
6157+
{
6158+
wprintf(L"Testing data uploading with staging buffer...\n");
6159+
6160+
// Generate some random data to fill the uniform buffer with.
6161+
const VkDeviceSize bufferSize = 65536;
6162+
std::vector<std::uint8_t> bufferData(bufferSize);
6163+
for (auto& bufferByte : bufferData) {
6164+
bufferByte = static_cast<std::uint8_t>(rand());
6165+
}
6166+
6167+
VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
6168+
uniformBufferCI.size = bufferSize;
6169+
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.
6170+
6171+
VmaAllocationCreateInfo uniformBufferAllocCI = {};
6172+
uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO;
6173+
6174+
VkBuffer uniformBuffer = VK_NULL_HANDLE;
6175+
VmaAllocation uniformBufferAlloc = VK_NULL_HANDLE;
6176+
VmaAllocationInfo uniformBufferAllocInfo = {};
6177+
6178+
VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo);
6179+
TEST(result == VK_SUCCESS);
6180+
6181+
VkBufferCreateInfo stagingBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
6182+
stagingBufferCI.size = bufferSize;
6183+
stagingBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
6184+
6185+
VmaAllocationCreateInfo stagingBufferAllocCI = {};
6186+
stagingBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO;
6187+
stagingBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
6188+
6189+
VkBuffer stagingBuffer = VK_NULL_HANDLE;
6190+
VmaAllocation stagingBufferAlloc = {};
6191+
VmaAllocationInfo stagingBufferAllocInfo = {};
6192+
6193+
result = vmaCreateBuffer(g_hAllocator, &stagingBufferCI, &stagingBufferAllocCI, &stagingBuffer, &stagingBufferAlloc, &stagingBufferAllocInfo);
6194+
TEST(result == VK_SUCCESS);
6195+
6196+
TEST(stagingBufferAllocInfo.pMappedData != nullptr);
6197+
vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), stagingBufferAlloc, 0, bufferData.size());
6198+
6199+
BeginSingleTimeCommands();
6200+
6201+
VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6202+
bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
6203+
bufferMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
6204+
bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6205+
bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6206+
bufferMemBarrier.buffer = stagingBuffer;
6207+
bufferMemBarrier.offset = 0;
6208+
bufferMemBarrier.size = VK_WHOLE_SIZE;
6209+
6210+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr);
6211+
6212+
VkBufferCopy bufferCopy = {};
6213+
bufferCopy.srcOffset = 0;
6214+
bufferCopy.dstOffset = 0;
6215+
bufferCopy.size = bufferSize;
6216+
6217+
vkCmdCopyBuffer(g_hTemporaryCommandBuffer, stagingBuffer, uniformBuffer, 1, &bufferCopy);
6218+
6219+
VkBufferMemoryBarrier bufferMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6220+
bufferMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
6221+
bufferMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer.
6222+
bufferMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6223+
bufferMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6224+
bufferMemBarrier2.buffer = uniformBuffer;
6225+
bufferMemBarrier2.offset = 0;
6226+
bufferMemBarrier2.size = VK_WHOLE_SIZE;
6227+
6228+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier2, 0, nullptr);
6229+
6230+
EndSingleTimeCommands();
6231+
6232+
vmaDestroyBuffer(g_hAllocator, stagingBuffer, stagingBufferAlloc);
6233+
vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc);
6234+
}
6235+
6236+
static void TestDataUploadingWithMappedMemory() {
6237+
wprintf(L"Testing data uploading with mapped memory...\n");
6238+
6239+
// Generate some random data to fill the uniform buffer with.
6240+
const VkDeviceSize bufferSize = 65536;
6241+
std::vector<std::uint8_t> bufferData(bufferSize);
6242+
for (auto& bufferByte : bufferData) {
6243+
bufferByte = static_cast<std::uint8_t>(rand() % 256);
6244+
}
6245+
6246+
VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
6247+
uniformBufferCI.size = bufferSize;
6248+
uniformBufferCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; // Change this if you want to create another type of buffer.
6249+
6250+
VmaAllocationCreateInfo uniformBufferAllocCI = {};
6251+
uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO;
6252+
uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; // We want memory to be mapped.
6253+
6254+
VkBuffer uniformBuffer = VK_NULL_HANDLE;
6255+
VmaAllocation uniformBufferAlloc = VK_NULL_HANDLE;
6256+
VmaAllocationInfo uniformBufferAllocInfo = {};
6257+
6258+
VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo);
6259+
TEST(result == VK_SUCCESS);
6260+
6261+
// We need to check if the uniform buffer really ended up in mappable memory.
6262+
VkMemoryPropertyFlags memPropFlags;
6263+
vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags);
6264+
TEST(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6265+
6266+
TEST(uniformBufferAllocInfo.pMappedData != nullptr);
6267+
vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), uniformBufferAlloc, 0, bufferData.size());
6268+
6269+
BeginSingleTimeCommands();
6270+
6271+
VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6272+
bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
6273+
bufferMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer.
6274+
bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6275+
bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6276+
bufferMemBarrier.buffer = uniformBuffer;
6277+
bufferMemBarrier.offset = 0;
6278+
bufferMemBarrier.size = VK_WHOLE_SIZE;
6279+
6280+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr);
6281+
6282+
EndSingleTimeCommands();
6283+
6284+
vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc);
6285+
}
6286+
6287+
static void TestAdvancedDataUploading() {
6288+
wprintf(L"Testing advanced data uploading...\n");
6289+
6290+
// Generate some random data to fill the uniform buffer with.
6291+
const VkDeviceSize bufferSize = 65536;
6292+
std::vector<std::uint8_t> bufferData(bufferSize);
6293+
for (auto& bufferByte : bufferData) {
6294+
bufferByte = static_cast<std::uint8_t>(rand() % 256);
6295+
}
6296+
6297+
VkBufferCreateInfo uniformBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
6298+
uniformBufferCI.size = bufferSize;
6299+
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.
6300+
6301+
VmaAllocationCreateInfo uniformBufferAllocCI = {};
6302+
uniformBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO;
6303+
uniformBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT
6304+
| VMA_ALLOCATION_CREATE_MAPPED_BIT;
6305+
6306+
VkBuffer uniformBuffer = VK_NULL_HANDLE;
6307+
VmaAllocation uniformBufferAlloc = {};
6308+
VmaAllocationInfo uniformBufferAllocInfo = {};
6309+
6310+
VkResult result = vmaCreateBuffer(g_hAllocator, &uniformBufferCI, &uniformBufferAllocCI, &uniformBuffer, &uniformBufferAlloc, &uniformBufferAllocInfo);
6311+
TEST(result == VK_SUCCESS);
6312+
6313+
VkMemoryPropertyFlags memPropFlags;
6314+
vmaGetAllocationMemoryProperties(g_hAllocator, uniformBufferAlloc, &memPropFlags);
6315+
6316+
if (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
6317+
// The allocation ended up as mapped memory.
6318+
TEST(uniformBufferAllocInfo.pMappedData != nullptr);
6319+
vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), uniformBufferAlloc, 0, bufferData.size());
6320+
6321+
BeginSingleTimeCommands();
6322+
6323+
VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6324+
bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
6325+
bufferMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer.
6326+
bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6327+
bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6328+
bufferMemBarrier.buffer = uniformBuffer;
6329+
bufferMemBarrier.offset = 0;
6330+
bufferMemBarrier.size = VK_WHOLE_SIZE;
6331+
6332+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr);
6333+
6334+
EndSingleTimeCommands();
6335+
}
6336+
else {
6337+
// The allocation did not end up in mapped memory, so we need a staging buffer and a copy operation to update it.
6338+
VkBufferCreateInfo stagingBufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
6339+
stagingBufferCI.size = bufferSize;
6340+
stagingBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
6341+
6342+
VmaAllocationCreateInfo stagingBufferAllocCI = {};
6343+
stagingBufferAllocCI.usage = VMA_MEMORY_USAGE_AUTO;
6344+
stagingBufferAllocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
6345+
6346+
VkBuffer stagingBuffer = VK_NULL_HANDLE;
6347+
VmaAllocation stagingBufferAlloc = {};
6348+
VmaAllocationInfo stagingBufferAllocInfo = {};
6349+
6350+
result = vmaCreateBuffer(g_hAllocator, &stagingBufferCI, &stagingBufferAllocCI, &stagingBuffer, &stagingBufferAlloc, &stagingBufferAllocInfo);
6351+
TEST(result == VK_SUCCESS);
6352+
6353+
TEST(stagingBufferAllocInfo.pMappedData != nullptr);
6354+
vmaCopyMemoryToAllocation(g_hAllocator, bufferData.data(), stagingBufferAlloc, 0, bufferData.size());
6355+
6356+
result = vmaFlushAllocation(g_hAllocator, uniformBufferAlloc, 0, VK_WHOLE_SIZE);
6357+
TEST(result == VK_SUCCESS);
6358+
6359+
BeginSingleTimeCommands();
6360+
6361+
VkBufferMemoryBarrier bufferMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6362+
bufferMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
6363+
bufferMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
6364+
bufferMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6365+
bufferMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6366+
bufferMemBarrier.buffer = stagingBuffer;
6367+
bufferMemBarrier.offset = 0;
6368+
bufferMemBarrier.size = VK_WHOLE_SIZE;
6369+
6370+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier, 0, nullptr);
6371+
6372+
VkBufferCopy bufferCopy = {};
6373+
bufferCopy.srcOffset = 0;
6374+
bufferCopy.dstOffset = 0;
6375+
bufferCopy.size = bufferSize;
6376+
6377+
vkCmdCopyBuffer(g_hTemporaryCommandBuffer, stagingBuffer, uniformBuffer, 1, &bufferCopy);
6378+
6379+
VkBufferMemoryBarrier bufferMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
6380+
bufferMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
6381+
bufferMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // Change this if you want to create another type of buffer.
6382+
bufferMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6383+
bufferMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
6384+
bufferMemBarrier2.buffer = uniformBuffer;
6385+
bufferMemBarrier2.offset = 0;
6386+
bufferMemBarrier2.size = VK_WHOLE_SIZE;
6387+
6388+
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1, &bufferMemBarrier2, 0, nullptr);
6389+
6390+
EndSingleTimeCommands();
6391+
6392+
vmaDestroyBuffer(g_hAllocator, stagingBuffer, stagingBufferAlloc);
6393+
}
6394+
6395+
vmaDestroyBuffer(g_hAllocator, uniformBuffer, uniformBufferAlloc);
6396+
}
6397+
61566398
static uint32_t FindDeviceCoherentMemoryTypeBits()
61576399
{
61586400
VkPhysicalDeviceMemoryProperties memProps;
@@ -8352,6 +8594,9 @@ void Test()
83528594
TestAllocationsInitialization();
83538595
#endif
83548596
TestMemoryUsage();
8597+
TestDataUploadingWithStagingBuffer();
8598+
TestDataUploadingWithMappedMemory();
8599+
TestAdvancedDataUploading();
83558600
TestDeviceCoherentMemory();
83568601
TestStatistics();
83578602
TestAliasing();

0 commit comments

Comments
 (0)