diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h index ab25be5..f89e858 100644 --- a/include/vk_mem_alloc.h +++ b/include/vk_mem_alloc.h @@ -296,9 +296,9 @@ extern "C" { //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// +// // INTERFACE -// +// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -484,7 +484,7 @@ typedef enum VmaMemoryUsage When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT), you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT in VmaAllocationCreateInfo::flags. - + It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g. vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo() and not with generic memory allocation functions. @@ -548,7 +548,7 @@ typedef enum VmaAllocationCreateFlagBits */ VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004, /** \deprecated Preserved for backward compatibility. Consider using vmaSetAllocationName() instead. - + Set this flag to treat VmaAllocationCreateInfo::pUserData as pointer to a null-terminated string. Instead of copying pointer value, a local copy of the string is made and stored in allocation's `pName`. The string is automatically @@ -575,14 +575,14 @@ typedef enum VmaAllocationCreateFlagBits */ VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100, /** \brief Set this flag if the allocated memory will have aliasing resources. - + Usage of this flag prevents supplying `VkMemoryDedicatedAllocateInfoKHR` when #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is specified. Otherwise created dedicated memory will not be suitable for aliasing resources, resulting in Vulkan Validation Layer errors. */ VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT = 0x00000200, /** Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT). - + - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value, you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect. - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`. @@ -598,7 +598,7 @@ typedef enum VmaAllocationCreateFlagBits VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT = 0x00000400, /** Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT). - + - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value, you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect. - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`. @@ -720,7 +720,7 @@ typedef enum VmaDefragmentationFlagBits VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8, /// A bit mask to extract only `ALGORITHM` bits from entire set of flags. - VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK = + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT | @@ -1113,19 +1113,19 @@ typedef struct VmaStatistics */ uint32_t blockCount; /** \brief Number of #VmaAllocation objects allocated. - + Dedicated allocations have their own blocks, so each one adds 1 to `allocationCount` as well as `blockCount`. */ uint32_t allocationCount; /** \brief Number of bytes allocated in `VkDeviceMemory` blocks. - + \note To avoid confusion, please be aware that what Vulkan calls an "allocation" - a whole `VkDeviceMemory` object (e.g. as in `VkPhysicalDeviceLimits::maxMemoryAllocationCount`) is called a "block" in VMA, while VMA calls "allocation" a #VmaAllocation object that represents a memory region sub-allocated from such block, usually for a single buffer or image. */ VkDeviceSize blockBytes; /** \brief Total number of bytes occupied by all #VmaAllocation objects. - + Always less or equal than `blockBytes`. Difference `(blockBytes - allocationBytes)` is the amount of memory allocated from Vulkan but unused by any #VmaAllocation. @@ -1383,9 +1383,9 @@ typedef struct VmaAllocationInfo */ void* VMA_NULLABLE pUserData; /** \brief Custom allocation name that was set with vmaSetAllocationName(). - + It can change after call to vmaSetAllocationName() for this allocation. - + Another way to set custom name is to pass it in VmaAllocationCreateInfo::pUserData with additional flag #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT set [DEPRECATED]. */ @@ -1425,7 +1425,7 @@ typedef struct VmaDefragmentationMove /// Allocation that should be moved. VmaAllocation VMA_NOT_NULL srcAllocation; /** \brief Temporary allocation pointing to destination memory that will replace `srcAllocation`. - + \warning Do not store this allocation in your data structures! It exists only temporarily, for the duration of the defragmentation pass, to be used for binding new buffer/image to the destination memory using e.g. vmaBindBufferMemory(). vmaEndDefragmentationPass() will destroy it and make `srcAllocation` point to this memory. @@ -1442,16 +1442,16 @@ typedef struct VmaDefragmentationPassMoveInfo /// Number of elements in the `pMoves` array. uint32_t moveCount; /** \brief Array of moves to be performed by the user in the current defragmentation pass. - + Pointer to an array of `moveCount` elements, owned by VMA, created in vmaBeginDefragmentationPass(), destroyed in vmaEndDefragmentationPass(). For each element, you should: - + 1. Create a new buffer/image in the place pointed by VmaDefragmentationMove::dstMemory + VmaDefragmentationMove::dstOffset. 2. Copy data from the VmaDefragmentationMove::srcAllocation e.g. using `vkCmdCopyBuffer`, `vkCmdCopyImage`. 3. Make sure these commands finished executing on the GPU. 4. Destroy the old buffer/image. - + Only then you can finish defragmentation pass by calling vmaEndDefragmentationPass(). After this call, the allocation will point to the new place in memory. @@ -1535,7 +1535,7 @@ typedef struct VmaVirtualAllocationCreateInfo typedef struct VmaVirtualAllocationInfo { /** \brief Offset of the allocation. - + Offset at which the allocation was made. */ VkDeviceSize offset; @@ -2551,9 +2551,9 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// +// // IMPLEMENTATION -// +// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -5022,7 +5022,7 @@ public: VmaIntrusiveLinkedList& operator=(VmaIntrusiveLinkedList&& src); VmaIntrusiveLinkedList& operator=(const VmaIntrusiveLinkedList&) = delete; ~VmaIntrusiveLinkedList() { VMA_HEAVY_ASSERT(IsEmpty()); } - + size_t GetCount() const { return m_Count; } bool IsEmpty() const { return m_Count == 0; } ItemType* Front() { return m_Front; } @@ -5434,7 +5434,7 @@ public: // Writes a string value inside "". // pStr can contain any ANSI characters, including '"', new line etc. - they will be properly escaped. void WriteString(const char* pStr); - + // Begins writing a string value. // Call BeginString, ContinueString, ContinueString, ..., EndString instead of // WriteString to conveniently build the string content incrementally, made of @@ -6412,7 +6412,7 @@ void VmaBlockMetadata::DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size (uint32_t)allocation->GetSuballocationType()); #endif // VMA_STATS_STRING_ENABLED } - + } #if VMA_STATS_STRING_ENABLED @@ -12978,7 +12978,7 @@ VmaDefragmentationContext_T::VmaDefragmentationContext_T( } } } - + switch (m_Algorithm) { case 0: // Default algorithm @@ -13104,7 +13104,7 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo vector = m_pBlockVectors[vectorIndex]; VMA_ASSERT(vector != VMA_NULL); } - + switch (move.operation) { case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY: @@ -13401,7 +13401,7 @@ bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, Vma case CounterStatus::Pass: break; } - + VkDeviceSize offset = moveData.move.srcAllocation->GetOffset(); if (offset != 0 && metadata->GetSumFreeSize() >= moveData.size) { @@ -13585,7 +13585,7 @@ bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector prevFreeRegionSize = nextFreeRegionSize; } } - + // No moves perfomed, update statistics to current vector state if (startMoveCount == m_Moves.size() && !update) { @@ -13872,7 +13872,7 @@ void VmaDefragmentationContext_T::UpdateVectorStatistics(VmaBlockVector& vector, state.avgFreeSize /= freeCount; } -bool VmaDefragmentationContext_T::MoveDataToFreeBlocks(VmaSuballocationType currentType, +bool VmaDefragmentationContext_T::MoveDataToFreeBlocks(VmaSuballocationType currentType, VmaBlockVector& vector, size_t firstFreeBlock, bool& texturePresent, bool& bufferPresent, bool& otherPresent) { @@ -18377,7 +18377,7 @@ for(;;) VmaAllocationInfo allocInfo; vmaGetAllocationInfo(allocator, pMoves[i].srcAllocation, &allocInfo); MyEngineResourceData* resData = (MyEngineResourceData*)allocInfo.pUserData; - + // Recreate and bind this buffer/image at: pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset. VkImageCreateInfo imgCreateInfo = ... VkImage newImg; @@ -18389,7 +18389,7 @@ for(;;) // Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place. vkCmdCopyImage(cmdBuf, resData->img, ..., newImg, ...); } - + // Make sure the copy commands finished executing. vkWaitForFences(...); @@ -18401,7 +18401,7 @@ for(;;) } // Update appropriate descriptors to point to the new places... - + res = vmaEndDefragmentationPass(allocator, defragCtx, &pass); if(res == VK_SUCCESS) break; @@ -19066,13 +19066,13 @@ so you need to create another "staging" allocation and perform explicit transfer VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; bufCreateInfo.size = 65536; bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - + VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; - + VkBuffer buf; VmaAllocation alloc; VmaAllocationInfo allocInfo; diff --git a/src/Common.cpp b/src/Common.cpp index 5f0bc50..21ae4f6 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -68,9 +68,9 @@ void PrintMessage(CONSOLE_COLOR color, const char* msg) { if(color != CONSOLE_COLOR::NORMAL) SetConsoleColor(color); - + printf("%s\n", msg); - + if (color != CONSOLE_COLOR::NORMAL) SetConsoleColor(CONSOLE_COLOR::NORMAL); } @@ -79,9 +79,9 @@ void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg) { if(color != CONSOLE_COLOR::NORMAL) SetConsoleColor(color); - + wprintf(L"%s\n", msg); - + if (color != CONSOLE_COLOR::NORMAL) SetConsoleColor(CONSOLE_COLOR::NORMAL); } diff --git a/src/SparseBindingTest.cpp b/src/SparseBindingTest.cpp index 9f58330..e9addbc 100644 --- a/src/SparseBindingTest.cpp +++ b/src/SparseBindingTest.cpp @@ -153,7 +153,7 @@ void BaseImage::UploadContent() VmaAllocation srcBufAlloc = nullptr; VmaAllocationInfo srcAllocInfo = {}; TEST( vmaCreateBuffer(g_hAllocator, &srcBufCreateInfo, &srcBufAllocCreateInfo, &srcBuf, &srcBufAlloc, &srcAllocInfo) == VK_SUCCESS ); - + // Fill texels with: r = x % 255, g = u % 255, b = 13, a = 25 uint32_t* srcBufPtr = (uint32_t*)srcAllocInfo.pMappedData; for(uint32_t y = 0, sizeY = m_CreateInfo.extent.height; y < sizeY; ++y) @@ -211,7 +211,7 @@ void BaseImage::UploadContent() vkCmdCopyBufferToImage(g_hTemporaryCommandBuffer, srcBuf, m_Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); } - + // Barrier transfer dst to fragment shader read only. { VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; @@ -441,7 +441,7 @@ void TraditionalImage::Init(RandomNumberGenerator& rand) allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; // Default BEST_FIT is clearly better. //allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT; - + ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &m_CreateInfo, &allocCreateInfo, &m_Image, &m_Allocation, nullptr) ); } @@ -513,7 +513,7 @@ void SparseBindingImage::Init(RandomNumberGenerator& rand) VkBindSparseInfo bindSparseInfo = { VK_STRUCTURE_TYPE_BIND_SPARSE_INFO }; bindSparseInfo.pImageOpaqueBinds = &imageBindInfo; bindSparseInfo.imageOpaqueBindCount = 1; - + ERR_GUARD_VULKAN( vkResetFences(g_hDevice, 1, &g_ImmediateFence) ); ERR_GUARD_VULKAN( vkQueueBindSparse(g_hSparseBindingQueue, 1, &bindSparseInfo, g_ImmediateFence) ); ERR_GUARD_VULKAN( vkWaitForFences(g_hDevice, 1, &g_ImmediateFence, VK_TRUE, UINT64_MAX) ); diff --git a/src/Tests.cpp b/src/Tests.cpp index bb41774..c25b23c 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -658,7 +658,7 @@ VkResult MainTest(Result& outResult, const Config& config) { bkgThreads.emplace_back(std::bind(ThreadProc, threadRandSeed + (uint32_t)i)); } - + // Wait for threads reached max allocations while(numThreadsReachedMaxAllocations < config.ThreadCount) Sleep(0); @@ -851,7 +851,7 @@ bool StagingBufferCollection::AcquireBuffer(VkDeviceSize size, VkBuffer& outBuff outMappedPtr = m_Bufs[bestIndex].MappedPtr; return true; } - + // Allocate new buffer with requested size. if(m_TotalSize + size <= MAX_TOTAL_SIZE) { @@ -1001,7 +1001,7 @@ static void UploadGpuData(const AllocInfo* allocInfo, size_t allocInfoCount) ++val; } } - + // Issue copy command from staging buffer to destination buffer. if(!cmdBufferStarted) { @@ -1009,14 +1009,14 @@ static void UploadGpuData(const AllocInfo* allocInfo, size_t allocInfoCount) BeginSingleTimeCommands(); } - + // Transfer to transfer dst layout VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; - + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.srcAccessMask = 0; barrier.dstAccessMask = 0; @@ -1185,7 +1185,7 @@ static void CreateBuffer( { outAllocInfo = {}; outAllocInfo.m_BufferInfo = bufCreateInfo; - + if (persistentlyMapped) allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT; @@ -1471,7 +1471,7 @@ static void ProcessDefragmentationPass(VmaDefragmentationPassMoveInfo& stepInfo) beginImageBarriers.push_back(barrier); - // Second barrier to convert the existing image. This one actually needs a real barrier + // Second barrier to convert the existing image. This one actually needs a real barrier barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; barrier.oldLayout = allocInfo->m_ImageLayout; @@ -1665,7 +1665,7 @@ static void TestJson() VkBufferCreateInfo buffCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; buffCreateInfo.size = 1024; buffCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - + VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; imgCreateInfo.imageType = VK_IMAGE_TYPE_2D; imgCreateInfo.extent.depth = 1; @@ -1825,7 +1825,7 @@ void TestDefragmentationSimple() const VkDeviceSize BUF_SIZE = 0x10000; const VkDeviceSize BLOCK_SIZE = BUF_SIZE * 8; - + const VkDeviceSize MIN_BUF_SIZE = 32; const VkDeviceSize MAX_BUF_SIZE = BUF_SIZE * 4; auto RandomBufSize = [&]() -> VkDeviceSize @@ -1898,7 +1898,7 @@ void TestDefragmentationSimple() DestroyAllocation(allocations[i]); allocations.erase(allocations.begin() + i); } - + // Set data for defragmentation retrieval for (auto& alloc : allocations) vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc); @@ -2114,7 +2114,7 @@ void TestDefragmentationVsMapping() // 16 * 64 KB allocations fit into a single 1 MB block. Create 10 such blocks. constexpr uint32_t START_ALLOC_COUNT = 160; std::vector allocs{START_ALLOC_COUNT}; - + constexpr uint32_t RAND_NUM_PERSISTENTLY_MAPPED_BIT = 0x1000; constexpr uint32_t RAND_NUM_MANUAL_MAP_COUNT_MASK = 0x3; @@ -2317,7 +2317,7 @@ void TestDefragmentationAlgorithms() CreateImage(allocCreateInfo, imageCreateInfo, VK_IMAGE_LAYOUT_GENERAL, false, allocInfo); allocations.push_back(allocInfo); } - + const uint32_t percentToDelete = 55; const size_t numberToDelete = allocations.size() * percentToDelete / 100; for (size_t i = 0; i < numberToDelete; ++i) @@ -2340,7 +2340,7 @@ void TestDefragmentationAlgorithms() // Set data for defragmentation retrieval for (auto& alloc : allocations) vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc); - + std::wstring output = DefragmentationAlgorithmToStr(defragInfo.flags); if (j == 0) output += L"_NoMove"; @@ -2795,7 +2795,7 @@ static void TestDefragmentationIncrementalBasic() void TestDefragmentationIncrementalComplex() { wprintf(L"Test defragmentation incremental complex\n"); - + std::vector allocations; // Create that many allocations to surely fill 3 new blocks of 256 MB. @@ -2886,10 +2886,10 @@ void TestDefragmentationIncrementalComplex() { bufCreateInfo.size = align_up(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16); bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - + AllocInfo alloc; alloc.CreateBuffer(bufCreateInfo, allocCreateInfo); - + additionalAllocations.push_back(alloc); vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &additionalAllocations.back()); } @@ -3259,7 +3259,7 @@ static void TestVirtualBlocks() TEST(allocation0 != VK_NULL_HANDLE); // # Validate the allocation - + VmaVirtualAllocationInfo allocInfo0 = {}; vmaGetVirtualAllocationInfo(block, allocation0, &allocInfo0); TEST(allocInfo0.offset < blockSize); @@ -3407,7 +3407,7 @@ static void TestVirtualBlocksAlgorithms() VkDeviceSize allocOffset, requestedSize, allocationSize; }; std::vector allocations; - + // Make some allocations for(size_t i = 0; i < 20; ++i) { @@ -3424,7 +3424,7 @@ static void TestVirtualBlocksAlgorithms() alloc.requestedSize = allocCreateInfo.size; res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc.allocation, nullptr); TEST(res == VK_SUCCESS); - + VmaVirtualAllocationInfo allocInfo; vmaGetVirtualAllocationInfo(block, alloc.allocation, &allocInfo); TEST(allocInfo.size >= allocCreateInfo.size); @@ -3562,7 +3562,7 @@ static void TestAllocationVersusResourceSize() AllocInfo info; info.CreateBuffer(bufCreateInfo, allocCreateInfo); - + VmaAllocationInfo allocInfo = {}; vmaGetAllocationInfo(g_hAllocator, info.m_Allocation, &allocInfo); //wprintf(L" Buffer size = %llu, allocation size = %llu\n", bufCreateInfo.size, allocInfo.size); @@ -3761,7 +3761,7 @@ static void TestPoolsAndAllocationParameters() uint32_t poolAllocCount = 0, poolBlockCount = 0; BufferInfo bufInfo = {}; VmaAllocationInfo allocInfo[4] = {}; - + // Default parameters allocCreateInfo.flags = 0; res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo[0]); @@ -3967,7 +3967,7 @@ static void TestDebugMargin() VmaPoolCreateInfo poolCreateInfo = {}; TEST(vmaFindMemoryTypeIndexForBufferInfo( g_hAllocator, &bufInfo, &allocCreateInfo, &poolCreateInfo.memoryTypeIndex) == VK_SUCCESS); - + for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex) { switch(algorithmIndex) @@ -3978,7 +3978,7 @@ static void TestDebugMargin() } VmaPool pool = VK_NULL_HANDLE; TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS && pool); - + allocCreateInfo.pool = pool; // Create few buffers of different size. @@ -4223,7 +4223,7 @@ static void TestLinearAllocator() bufInfo.push_back(newBufInfo); } } - + // Allocate buffers until we reach out-of-memory. uint32_t debugIndex = 0; while(res == VK_SUCCESS) @@ -4412,7 +4412,7 @@ static void TestLinearAllocatorMultiBlock() VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.pool = pool; - + std::vector bufInfo; VmaAllocationInfo allocInfo; @@ -4489,7 +4489,7 @@ static void TestLinearAllocatorMultiBlock() VmaDetailedStatistics poolStats = {}; vmaCalculatePoolStatistics(g_hAllocator, pool, &poolStats); TEST(poolStats.statistics.blockCount == 2); - + // Delete half of buffers, LIFO. for(size_t i = 0, countToDelete = bufInfo.size() / 2; i < countToDelete; ++i) { @@ -5347,7 +5347,7 @@ static void TestPool_SameSize() memReq.memoryTypeBits = UINT32_MAX; memReq.alignment = 1; memReq.size = poolCreateInfo.blockSize + 4; - + VmaAllocation alloc = nullptr; res = vmaAllocateMemory(g_hAllocator, &memReq, &allocCreateInfo, &alloc, nullptr); TEST(res == VK_ERROR_OUT_OF_DEVICE_MEMORY && alloc == nullptr); @@ -5399,7 +5399,7 @@ static void TestAllocationsInitialization() // Create one persistently mapped buffer to keep memory of this block mapped, // so that pointer to mapped data will remain (more or less...) valid even // after destruction of other allocations. - + bufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; VkBuffer firstBuf; VmaAllocation firstAlloc; @@ -5605,7 +5605,7 @@ static void TestPool_Benchmark( VkBuffer Buf = VK_NULL_HANDLE; VkImage Image = VK_NULL_HANDLE; VmaAllocation Alloc = VK_NULL_HANDLE; - + Item() { } Item(Item&& src) : BufferSize(src.BufferSize), ImageSize(src.ImageSize), Buf(src.Buf), Image(src.Image), Alloc(src.Alloc) @@ -5808,7 +5808,7 @@ static void TestPool_Benchmark( ++touchExistingCount; } } - + /* printf("Thread %u frame %u: Touch existing %u, create succeeded %u failed %u\n", randSeed, frameIndex, @@ -5942,7 +5942,7 @@ static void TestMemoryUsage() else printf(" %s: memoryTypeBits=0x%X, FAILED with res=%d\n", testName, memoryTypeBits, (int32_t)res); }; - + // 1: Buffer for copy { VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -6180,7 +6180,7 @@ static void TestDeviceCoherentMemory() VmaAllocatorCreateInfo allocatorCreateInfo = {}; SetAllocatorCreateInfo(allocatorCreateInfo); allocatorCreateInfo.flags &= ~VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT; - + VmaAllocator localAllocator = VK_NULL_HANDLE; res = vmaCreateAllocator(&allocatorCreateInfo, &localAllocator); TEST(res == VK_SUCCESS && localAllocator); @@ -6227,7 +6227,7 @@ static void TestBudget() VkBufferCreateInfo bufInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; bufInfo.size = BUF_SIZE; bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; - + VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; if(testIndex == 0) @@ -6372,7 +6372,7 @@ static void TestAliasing() static void TestAllocationAliasing() { wprintf(L"Testing allocation aliasing...\n"); - + /* * Test whether using VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT suppress validation layer error * by don't supplying VkMemoryDedicatedAllocateInfoKHR to creation of dedicated memory @@ -6644,14 +6644,14 @@ static void TestMappingMultithreaded() VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; bufCreateInfo.size = 0x10000; bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - + VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; allocCreateInfo.pool = pool; if(testIndex == TEST_DEDICATED) allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - + std::thread threads[threadCount]; for(uint32_t threadIndex = 0; threadIndex < threadCount; ++threadIndex) { @@ -6659,7 +6659,7 @@ static void TestMappingMultithreaded() // ======== THREAD FUNCTION ======== RandomNumberGenerator rand{threadIndex}; - + enum class MODE { // Don't map this buffer at all. @@ -6676,7 +6676,7 @@ static void TestMappingMultithreaded() }; std::vector bufInfos{threadBufferCount}; std::vector bufModes{threadBufferCount}; - + for(uint32_t bufferIndex = 0; bufferIndex < threadBufferCount; ++bufferIndex) { BufferInfo& bufInfo = bufInfos[bufferIndex]; @@ -6686,12 +6686,12 @@ static void TestMappingMultithreaded() VmaAllocationCreateInfo localAllocCreateInfo = allocCreateInfo; if(mode == MODE::PERSISTENTLY_MAPPED) localAllocCreateInfo.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT; - + VmaAllocationInfo allocInfo; VkResult res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &localAllocCreateInfo, &bufInfo.Buffer, &bufInfo.Allocation, &allocInfo); TEST(res == VK_SUCCESS); - + if(memTypeIndex == UINT32_MAX) memTypeIndex = allocInfo.memoryType; @@ -6770,7 +6770,7 @@ static void TestMappingMultithreaded() for(uint32_t threadIndex = 0; threadIndex < threadCount; ++threadIndex) threads[threadIndex].join(); - + vmaDestroyPool(g_hAllocator, pool); } } @@ -6926,7 +6926,7 @@ static void PerformCustomPoolTest(FILE* file) config.ThreadCount = 1; config.FrameCount = 200; config.ItemsToMakeUnusedPercent = 2; - + AllocationSize allocSize = {}; allocSize.BufferSizeMin = 1024; allocSize.BufferSizeMax = 1024 * 1024; @@ -7506,7 +7506,7 @@ static void BasicTestBuddyAllocator() std::vector bufInfo; BufferInfo newBufInfo; VmaAllocationInfo allocInfo; - + bufCreateInfo.size = 1024 * 256; res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo); @@ -7524,7 +7524,7 @@ static void BasicTestBuddyAllocator() &newBufInfo.Buffer, &newBufInfo.Allocation, &allocInfo); TEST(res == VK_SUCCESS); bufInfo.push_back(newBufInfo); - + // Test very small allocation, smaller than minimum node size. bufCreateInfo.size = 1; res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, @@ -7823,7 +7823,7 @@ static void TestVirtualBlocksAlgorithmsBenchmark() for (size_t i = ALLOCATION_COUNT; i;) vmaVirtualFree(block, allocs[--i]); duration freeDuration = std::chrono::high_resolution_clock::now() - timeBegin; - + vmaDestroyVirtualBlock(block); printf("%llu,%s,%s,%g,%g,%g\n", @@ -8051,7 +8051,7 @@ void Test() FILE* file; fopen_s(&file, "Results.csv", "w"); assert(file != NULL); - + WriteMainTestResultHeader(file); PerformMainTests(file); PerformCustomMainTest(file); @@ -8059,10 +8059,10 @@ void Test() WritePoolTestResultHeader(file); PerformPoolTests(file); PerformCustomPoolTest(file); - + fclose(file); #endif // #if defined(VMA_DEBUG_MARGIN) && VMA_DEBUG_MARGIN > 0 - + wprintf(L"Done, all PASSED.\n"); } diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index a399035..2343687 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -352,7 +352,7 @@ static VkSurfaceFormatKHR ChooseSurfaceFormat() VkSurfaceFormatKHR result = { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; return result; } - + for(const auto& format : g_SurfaceFormats) { if((format.format == VK_FORMAT_B8G8R8A8_UNORM) && @@ -368,7 +368,7 @@ static VkSurfaceFormatKHR ChooseSurfaceFormat() VkPresentModeKHR ChooseSwapPresentMode() { VkPresentModeKHR preferredMode = VSYNC ? VK_PRESENT_MODE_MAILBOX_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR; - + if(std::find(g_PresentModes.begin(), g_PresentModes.end(), preferredMode) != g_PresentModes.end()) { @@ -456,7 +456,7 @@ void VulkanUsage::Init() if(strcmp(extensionProperties.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { if(GetVulkanApiVersion() == VK_API_VERSION_1_0) - { + { enabledInstanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); VK_KHR_get_physical_device_properties2_enabled = true; } @@ -703,11 +703,11 @@ static void CreateMesh() ibInfo.size = indexBufferSize; ibInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; ibInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - + VmaAllocationCreateInfo ibAllocCreateInfo = {}; ibAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; ibAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; - + VkBuffer stagingIndexBuffer = VK_NULL_HANDLE; VmaAllocation stagingIndexBufferAlloc = VK_NULL_HANDLE; VmaAllocationInfo stagingIndexBufferAllocInfo = {}; @@ -756,7 +756,7 @@ static void CreateTexture(uint32_t sizeX, uint32_t sizeY) VmaAllocationCreateInfo stagingBufAllocCreateInfo = {}; stagingBufAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; stagingBufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; - + VkBuffer stagingBuf = VK_NULL_HANDLE; VmaAllocation stagingBufAlloc = VK_NULL_HANDLE; VmaAllocationInfo stagingBufAllocInfo = {}; @@ -800,7 +800,7 @@ static void CreateTexture(uint32_t sizeX, uint32_t sizeY) VmaAllocationCreateInfo imageAllocCreateInfo = {}; imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; - + ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &imageInfo, &imageAllocCreateInfo, &g_hTextureImage, &g_hTextureImageAlloc, nullptr) ); // Transition image layouts, copy image. @@ -886,7 +886,7 @@ static VkFormat FindSupportedFormat( { VkFormatProperties props; vkGetPhysicalDeviceFormatProperties(g_hPhysicalDevice, format, &props); - + if ((tiling == VK_IMAGE_TILING_LINEAR) && ((props.linearTilingFeatures & features) == features)) { @@ -919,7 +919,7 @@ static void CreateSwapchain() // Query surface formats. ERR_GUARD_VULKAN( vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_hPhysicalDevice, g_hSurface, &g_SurfaceCapabilities) ); - + uint32_t formatCount = 0; ERR_GUARD_VULKAN( vkGetPhysicalDeviceSurfaceFormatsKHR(g_hPhysicalDevice, g_hSurface, &formatCount, nullptr) ); g_SurfaceFormats.resize(formatCount); @@ -1099,11 +1099,11 @@ static void CreateSwapchain() VkAttachmentReference colorAttachmentRef = {}; colorAttachmentRef.attachment = 0; colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - + VkAttachmentReference depthStencilAttachmentRef = {}; depthStencilAttachmentRef.attachment = 1; depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - + VkSubpassDescription subpassDesc = {}; subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpassDesc.colorAttachmentCount = 1; @@ -1163,7 +1163,7 @@ static void CreateSwapchain() attributeDescriptions[0].location = 0; attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; attributeDescriptions[0].offset = offsetof(Vertex, pos); - + attributeDescriptions[1].binding = 0; attributeDescriptions[1].location = 1; attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; @@ -1362,7 +1362,7 @@ static void DestroySwapchain(bool destroyActualSwapchain) vkDestroyPipelineLayout(g_hDevice, g_hPipelineLayout, g_Allocs); g_hPipelineLayout = VK_NULL_HANDLE; } - + for(size_t i = g_SwapchainImageViews.size(); i--; ) vkDestroyImageView(g_hDevice, g_SwapchainImageViews[i], g_Allocs); g_SwapchainImageViews.clear(); @@ -1558,7 +1558,7 @@ static void PrintMemoryTypes() sizeStr = SizeToStr(heap.size); flagsStr = HeapFlagsToStr(heap.flags); wprintf(L"Heap %u: %llu B (%s) %s\n", heapIndex, heap.size, sizeStr.c_str(), flagsStr.c_str()); - + for(uint32_t typeIndex = 0; typeIndex < memProps->memoryTypeCount; ++typeIndex) { const VkMemoryType& type = memProps->memoryTypes[typeIndex]; @@ -1762,7 +1762,7 @@ static void PrintMemoryConclusions() if(deviceLocalHeapCount < heapCount) { const uint32_t nonDeviceLocalTypeBits = ~deviceLocalTypeBits & allTypeBits; - + if(CanCreateVertexBuffer(nonDeviceLocalTypeBits)) wprintf(L"- A buffer with VERTEX_BUFFER usage can be created in some non-DEVICE_LOCAL type.\n"); else @@ -1845,7 +1845,7 @@ static void InitializeApplication() #if VMA_VULKAN_VERSION >= 1001000 VkPhysicalDeviceProperties2 physicalDeviceProperties2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; - + #if VMA_VULKAN_VERSION >= 1002000 // Vulkan spec says structure VkPhysicalDeviceVulkan11Properties is "Provided by VK_VERSION_1_2" - is this a mistake? Assuming not... VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES }; @@ -1872,13 +1872,13 @@ static void InitializeApplication() wprintf(L"\n"); VkPhysicalDeviceFeatures2 physicalDeviceFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; - + VkPhysicalDeviceCoherentMemoryFeaturesAMD physicalDeviceCoherentMemoryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD }; if(VK_AMD_device_coherent_memory_enabled) { PnextChainPushFront(&physicalDeviceFeatures, &physicalDeviceCoherentMemoryFeatures); } - + VkPhysicalDeviceBufferDeviceAddressFeaturesKHR physicalDeviceBufferDeviceAddressFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR }; if(VK_KHR_buffer_device_address_enabled) { @@ -1955,7 +1955,7 @@ static void InitializeApplication() queueCreateInfo[0].queueFamilyIndex = g_GraphicsQueueFamilyIndex; queueCreateInfo[0].queueCount = 1; queueCreateInfo[0].pQueuePriorities = &queuePriority; - + if(g_PresentQueueFamilyIndex != g_GraphicsQueueFamilyIndex) { @@ -1965,7 +1965,7 @@ static void InitializeApplication() queueCreateInfo[queueCount].pQueuePriorities = &queuePriority; ++queueCount; } - + if(g_SparseBindingEnabled && g_SparseBindingQueueFamilyIndex != g_GraphicsQueueFamilyIndex && g_SparseBindingQueueFamilyIndex != g_PresentQueueFamilyIndex) @@ -2206,7 +2206,7 @@ static void FinalizeApplication() vmaDestroyBuffer(g_hAllocator, g_hVertexBuffer, g_hVertexBufferAlloc); g_hVertexBuffer = VK_NULL_HANDLE; } - + if(g_hSampler != VK_NULL_HANDLE) { vkDestroySampler(g_hDevice, g_hSampler, g_Allocs); @@ -2293,7 +2293,7 @@ static void DrawFrame() VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; ERR_GUARD_VULKAN( vkBeginCommandBuffer(hCommandBuffer, &commandBufferBeginInfo) ); - + // Acquire swapchain image uint32_t imageIndex = 0; VkResult res = vkAcquireNextImageKHR(g_hDevice, g_hSwapchain, UINT64_MAX, g_hImageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); @@ -2326,7 +2326,7 @@ static void DrawFrame() renderPassBeginInfo.clearValueCount = (uint32_t)_countof(clearValues); renderPassBeginInfo.pClearValues = clearValues; vkCmdBeginRenderPass(hCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - + vkCmdBindPipeline( hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -2369,11 +2369,11 @@ static void DrawFrame() vkCmdDrawIndexed(hCommandBuffer, g_IndexCount, 1, 0, 0, 0); vkCmdEndRenderPass(hCommandBuffer); - + vkEndCommandBuffer(hCommandBuffer); // Submit command buffer - + VkSemaphore submitWaitSemaphores[] = { g_hImageAvailableSemaphore }; VkPipelineStageFlags submitWaitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSemaphore submitSignalSemaphores[] = { g_hRenderFinishedSemaphore }; @@ -2538,7 +2538,7 @@ int MainWindow() wndClassDesc.hInstance = g_hAppInstance; wndClassDesc.lpfnWndProc = WndProc; wndClassDesc.lpszClassName = WINDOW_CLASS_NAME; - + const ATOM hWndClass = RegisterClassEx(&wndClassDesc); assert(hWndClass); @@ -2631,7 +2631,7 @@ int wmain(int argc, wchar_t** argv) } CATCH_PRINT_ERROR(return (int)ExitCode::RuntimeError;) return result; -} +} #else // #ifdef _WIN32