Skip to content

Commit 2e900ca

Browse files
Added functions vmaAllocateMemoryPages, vmaFreeMemoryPages to VmaRecorder and VmaReplay. Bumped recording file format version to 1.5.
Support for sparse binding is now finished and ready!
1 parent 1ae513a commit 2e900ca

File tree

5 files changed

+268
-45
lines changed

5 files changed

+268
-45
lines changed

docs/Recording file format.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Formats with only minor version incremented are backward compatible.
2323
VmaReplay application supports all older versions.
2424
Current version is:
2525

26-
1,4
26+
1,5
2727

2828
# Configuration
2929

@@ -152,6 +152,10 @@ No parameters.
152152

153153
- allocation : pointer
154154

155+
**vmaFreeMemoryPages** (min format version: 1.5)
156+
157+
- allocations : list of pointers
158+
155159
**vmaCreateLostAllocation** (min format version 1.2)
156160

157161
- allocation (output) : pointer
@@ -170,6 +174,20 @@ No parameters.
170174
- allocation (output) : pointer
171175
- allocationCreateInfo.pUserData : string (may contain additional commas)
172176

177+
**vmaAllocateMemoryPages** (min format version 1.5)
178+
179+
- vkMemoryRequirements.size : uint64
180+
- vkMemoryRequirements.alignment : uint64
181+
- vkMemoryRequirements.memoryTypeBits : uint32
182+
- allocationCreateInfo.flags : uint32
183+
- allocationCreateInfo.usage : uint32
184+
- allocationCreateInfo.requiredFlags : uint32
185+
- allocationCreateInfo.preferredFlags : uint32
186+
- allocationCreateInfo.memoryTypeBits : uint32
187+
- allocationCreateInfo.pool : pointer
188+
- allocations (output) : list of pointers
189+
- allocationCreateInfo.pUserData : string (may contain additional commas)
190+
173191
**vmaAllocateMemoryForBuffer, vmaAllocateMemoryForImage** (min format version 1.2)
174192

175193
- vkMemoryRequirements.size : uint64
@@ -230,10 +248,14 @@ If `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` was used with the allocatio
230248
It may contain additional commas.
231249
It should not contain end-of-line characters - results are then undefined.
232250

251+
**list of (...)** (min format version: 1.5)
252+
253+
An ordered sequence of values of some type, separated by single space.
254+
233255
# Example file
234256

235257
Vulkan Memory Allocator,Calls recording
236-
1,4
258+
1,5
237259
Config,Begin
238260
PhysicalDevice,apiVersion,4198477
239261
PhysicalDevice,driverVersion,8388653

src/VmaReplay/Common.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
#include "Common.h"
22

3+
bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out)
4+
{
5+
out.clear();
6+
StrRange currRange = { s.beg, nullptr };
7+
while(currRange.beg < s.end)
8+
{
9+
currRange.end = currRange.beg;
10+
while(currRange.end < s.end && *currRange.end != ' ')
11+
{
12+
++currRange.end;
13+
}
14+
15+
uint64_t ptr = 0;
16+
if(!StrRangeToPtr(currRange, ptr))
17+
{
18+
return false;
19+
}
20+
out.push_back(ptr);
21+
22+
currRange.beg = currRange.end + 1;
23+
}
24+
return true;
25+
}
26+
327
////////////////////////////////////////////////////////////////////////////////
428
// LineSplit class
529

src/VmaReplay/Common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ inline bool StrRangeToBool(const StrRange& s, bool& out)
111111

112112
return true;
113113
}
114+
bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out);
114115

115116
class LineSplit
116117
{

src/VmaReplay/VmaReplay.cpp

Lines changed: 153 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ enum class VMA_FUNCTION
7171
CreateImage,
7272
DestroyImage,
7373
FreeMemory,
74+
FreeMemoryPages,
7475
CreateLostAllocation,
7576
AllocateMemory,
77+
AllocateMemoryPages,
7678
AllocateMemoryForBuffer,
7779
AllocateMemoryForImage,
7880
MapMemory,
@@ -94,8 +96,10 @@ static const char* VMA_FUNCTION_NAMES[] = {
9496
"vmaCreateImage",
9597
"vmaDestroyImage",
9698
"vmaFreeMemory",
99+
"vmaFreeMemoryPages",
97100
"vmaCreateLostAllocation",
98101
"vmaAllocateMemory",
102+
"vmaAllocateMemoryPages",
99103
"vmaAllocateMemoryForBuffer",
100104
"vmaAllocateMemoryForImage",
101105
"vmaMapMemory",
@@ -145,7 +149,7 @@ static size_t g_DumpStatsAfterLineNextIndex = 0;
145149
static bool ValidateFileVersion()
146150
{
147151
if(GetVersionMajor(g_FileVersion) == 1 &&
148-
GetVersionMinor(g_FileVersion) <= 4)
152+
GetVersionMinor(g_FileVersion) <= 5)
149153
{
150154
return true;
151155
}
@@ -195,7 +199,7 @@ class Statistics
195199
void RegisterCreateImage(uint32_t usage, uint32_t tiling);
196200
void RegisterCreateBuffer(uint32_t usage);
197201
void RegisterCreatePool();
198-
void RegisterCreateAllocation();
202+
void RegisterCreateAllocation(size_t allocCount = 1);
199203

200204
void UpdateMemStats(const VmaStats& currStats);
201205

@@ -364,9 +368,9 @@ void Statistics::RegisterCreatePool()
364368
++m_PoolCreationCount;
365369
}
366370

367-
void Statistics::RegisterCreateAllocation()
371+
void Statistics::RegisterCreateAllocation(size_t allocCount)
368372
{
369-
++m_AllocationCreationCount;
373+
m_AllocationCreationCount += allocCount;
370374
}
371375

372376
void Statistics::UpdateMemStats(const VmaStats& currStats)
@@ -955,10 +959,10 @@ class Player
955959
};
956960
struct Allocation
957961
{
958-
uint32_t allocationFlags;
959-
VmaAllocation allocation;
960-
VkBuffer buffer;
961-
VkImage image;
962+
uint32_t allocationFlags = 0;
963+
VmaAllocation allocation = VK_NULL_HANDLE;
964+
VkBuffer buffer = VK_NULL_HANDLE;
965+
VkImage image = VK_NULL_HANDLE;
962966
};
963967
std::unordered_map<uint64_t, Pool> m_Pools;
964968
std::unordered_map<uint64_t, Allocation> m_Allocations;
@@ -1003,12 +1007,14 @@ class Player
10031007
void ExecuteDestroyPool(size_t lineNumber, const CsvSplit& csvSplit);
10041008
void ExecuteSetAllocationUserData(size_t lineNumber, const CsvSplit& csvSplit);
10051009
void ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit);
1006-
void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyBuffer); DestroyAllocation(lineNumber, csvSplit); }
1010+
void ExecuteDestroyBuffer(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyBuffer); DestroyAllocation(lineNumber, csvSplit, "vmaDestroyBuffer"); }
10071011
void ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit);
1008-
void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyImage); DestroyAllocation(lineNumber, csvSplit); }
1009-
void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemory); DestroyAllocation(lineNumber, csvSplit); }
1012+
void ExecuteDestroyImage(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::DestroyImage); DestroyAllocation(lineNumber, csvSplit, "vmaDestroyImage"); }
1013+
void ExecuteFreeMemory(size_t lineNumber, const CsvSplit& csvSplit) { m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemory); DestroyAllocation(lineNumber, csvSplit, "vmaFreeMemory"); }
1014+
void ExecuteFreeMemoryPages(size_t lineNumber, const CsvSplit& csvSplit);
10101015
void ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit);
10111016
void ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit);
1017+
void ExecuteAllocateMemoryPages(size_t lineNumber, const CsvSplit& csvSplit);
10121018
void ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType);
10131019
void ExecuteMapMemory(size_t lineNumber, const CsvSplit& csvSplit);
10141020
void ExecuteUnmapMemory(size_t lineNumber, const CsvSplit& csvSplit);
@@ -1019,7 +1025,7 @@ class Player
10191025
void ExecuteMakePoolAllocationsLost(size_t lineNumber, const CsvSplit& csvSplit);
10201026
void ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit);
10211027

1022-
void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit);
1028+
void DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName);
10231029
};
10241030

10251031
Player::Player()
@@ -1121,45 +1127,49 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
11211127
// Nothing.
11221128
}
11231129
}
1124-
else if(StrRangeEq(functionName, "vmaCreatePool"))
1130+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreatePool]))
11251131
ExecuteCreatePool(lineNumber, csvSplit);
1126-
else if(StrRangeEq(functionName, "vmaDestroyPool"))
1132+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyPool]))
11271133
ExecuteDestroyPool(lineNumber, csvSplit);
1128-
else if(StrRangeEq(functionName, "vmaSetAllocationUserData"))
1134+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::SetAllocationUserData]))
11291135
ExecuteSetAllocationUserData(lineNumber, csvSplit);
1130-
else if(StrRangeEq(functionName, "vmaCreateBuffer"))
1136+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateBuffer]))
11311137
ExecuteCreateBuffer(lineNumber, csvSplit);
1132-
else if(StrRangeEq(functionName, "vmaDestroyBuffer"))
1138+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyBuffer]))
11331139
ExecuteDestroyBuffer(lineNumber, csvSplit);
1134-
else if(StrRangeEq(functionName, "vmaCreateImage"))
1140+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateImage]))
11351141
ExecuteCreateImage(lineNumber, csvSplit);
1136-
else if(StrRangeEq(functionName, "vmaDestroyImage"))
1142+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::DestroyImage]))
11371143
ExecuteDestroyImage(lineNumber, csvSplit);
1138-
else if(StrRangeEq(functionName, "vmaFreeMemory"))
1144+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FreeMemory]))
11391145
ExecuteFreeMemory(lineNumber, csvSplit);
1140-
else if(StrRangeEq(functionName, "vmaCreateLostAllocation"))
1146+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FreeMemoryPages]))
1147+
ExecuteFreeMemoryPages(lineNumber, csvSplit);
1148+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::CreateLostAllocation]))
11411149
ExecuteCreateLostAllocation(lineNumber, csvSplit);
1142-
else if(StrRangeEq(functionName, "vmaAllocateMemory"))
1150+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemory]))
11431151
ExecuteAllocateMemory(lineNumber, csvSplit);
1144-
else if(StrRangeEq(functionName, "vmaAllocateMemoryForBuffer"))
1152+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryPages]))
1153+
ExecuteAllocateMemoryPages(lineNumber, csvSplit);
1154+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryForBuffer]))
11451155
ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::BUFFER);
1146-
else if(StrRangeEq(functionName, "vmaAllocateMemoryForImage"))
1156+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::AllocateMemoryForImage]))
11471157
ExecuteAllocateMemoryForBufferOrImage(lineNumber, csvSplit, OBJECT_TYPE::IMAGE);
1148-
else if(StrRangeEq(functionName, "vmaMapMemory"))
1158+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MapMemory]))
11491159
ExecuteMapMemory(lineNumber, csvSplit);
1150-
else if(StrRangeEq(functionName, "vmaUnmapMemory"))
1160+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::UnmapMemory]))
11511161
ExecuteUnmapMemory(lineNumber, csvSplit);
1152-
else if(StrRangeEq(functionName, "vmaFlushAllocation"))
1162+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::FlushAllocation]))
11531163
ExecuteFlushAllocation(lineNumber, csvSplit);
1154-
else if(StrRangeEq(functionName, "vmaInvalidateAllocation"))
1164+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::InvalidateAllocation]))
11551165
ExecuteInvalidateAllocation(lineNumber, csvSplit);
1156-
else if(StrRangeEq(functionName, "vmaTouchAllocation"))
1166+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::TouchAllocation]))
11571167
ExecuteTouchAllocation(lineNumber, csvSplit);
1158-
else if(StrRangeEq(functionName, "vmaGetAllocationInfo"))
1168+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::GetAllocationInfo]))
11591169
ExecuteGetAllocationInfo(lineNumber, csvSplit);
1160-
else if(StrRangeEq(functionName, "vmaMakePoolAllocationsLost"))
1170+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::MakePoolAllocationsLost]))
11611171
ExecuteMakePoolAllocationsLost(lineNumber, csvSplit);
1162-
else if(StrRangeEq(functionName, "vmaResizeAllocation"))
1172+
else if(StrRangeEq(functionName, VMA_FUNCTION_NAMES[(uint32_t)VMA_FUNCTION::ResizeAllocation]))
11631173
ExecuteResizeAllocation(lineNumber, csvSplit);
11641174
else
11651175
{
@@ -2029,7 +2039,7 @@ void Player::ExecuteCreateBuffer(size_t lineNumber, const CsvSplit& csvSplit)
20292039
}
20302040
}
20312041

2032-
void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit)
2042+
void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit, const char* functionName)
20332043
{
20342044
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
20352045
{
@@ -2059,7 +2069,7 @@ void Player::DestroyAllocation(size_t lineNumber, const CsvSplit& csvSplit)
20592069
{
20602070
if(IssueWarning())
20612071
{
2062-
printf("Line %zu: Invalid parameters for vmaDestroyBuffer.\n", lineNumber);
2072+
printf("Line %zu: Invalid parameters for %s.\n", lineNumber, functionName);
20632073
}
20642074
}
20652075
}
@@ -2127,6 +2137,53 @@ void Player::ExecuteCreateImage(size_t lineNumber, const CsvSplit& csvSplit)
21272137
}
21282138
}
21292139

2140+
void Player::ExecuteFreeMemoryPages(size_t lineNumber, const CsvSplit& csvSplit)
2141+
{
2142+
m_Stats.RegisterFunctionCall(VMA_FUNCTION::FreeMemoryPages);
2143+
2144+
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 1, false))
2145+
{
2146+
std::vector<uint64_t> origAllocPtrs;
2147+
if(StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX), origAllocPtrs))
2148+
{
2149+
const size_t allocCount = origAllocPtrs.size();
2150+
size_t notNullCount = 0;
2151+
for(size_t i = 0; i < allocCount; ++i)
2152+
{
2153+
const uint64_t origAllocPtr = origAllocPtrs[i];
2154+
if(origAllocPtr != 0)
2155+
{
2156+
const auto it = m_Allocations.find(origAllocPtr);
2157+
if(it != m_Allocations.end())
2158+
{
2159+
Destroy(it->second);
2160+
m_Allocations.erase(it);
2161+
++notNullCount;
2162+
}
2163+
else
2164+
{
2165+
if(IssueWarning())
2166+
{
2167+
printf("Line %zu: Allocation %llX not found.\n", lineNumber, origAllocPtr);
2168+
}
2169+
}
2170+
}
2171+
}
2172+
if(notNullCount)
2173+
{
2174+
UpdateMemStats();
2175+
}
2176+
}
2177+
else
2178+
{
2179+
if(IssueWarning())
2180+
{
2181+
printf("Line %zu: Invalid parameters for vmaFreeMemoryPages.\n", lineNumber);
2182+
}
2183+
}
2184+
}
2185+
}
2186+
21302187
void Player::ExecuteCreateLostAllocation(size_t lineNumber, const CsvSplit& csvSplit)
21312188
{
21322189
m_Stats.RegisterFunctionCall(VMA_FUNCTION::CreateLostAllocation);
@@ -2206,6 +2263,68 @@ void Player::ExecuteAllocateMemory(size_t lineNumber, const CsvSplit& csvSplit)
22062263
}
22072264
}
22082265

2266+
void Player::ExecuteAllocateMemoryPages(size_t lineNumber, const CsvSplit& csvSplit)
2267+
{
2268+
m_Stats.RegisterFunctionCall(VMA_FUNCTION::AllocateMemoryPages);
2269+
2270+
if(ValidateFunctionParameterCount(lineNumber, csvSplit, 11, true))
2271+
{
2272+
VkMemoryRequirements memReq = {};
2273+
VmaAllocationCreateInfo allocCreateInfo = {};
2274+
uint64_t origPool = 0;
2275+
std::vector<uint64_t> origPtrs;
2276+
2277+
if(StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX), memReq.size) &&
2278+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 1), memReq.alignment) &&
2279+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 2), memReq.memoryTypeBits) &&
2280+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 3), allocCreateInfo.flags) &&
2281+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 4), (uint32_t&)allocCreateInfo.usage) &&
2282+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 5), allocCreateInfo.requiredFlags) &&
2283+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 6), allocCreateInfo.preferredFlags) &&
2284+
StrRangeToUint(csvSplit.GetRange(FIRST_PARAM_INDEX + 7), allocCreateInfo.memoryTypeBits) &&
2285+
StrRangeToPtr(csvSplit.GetRange(FIRST_PARAM_INDEX + 8), origPool) &&
2286+
StrRangeToPtrList(csvSplit.GetRange(FIRST_PARAM_INDEX + 9), origPtrs))
2287+
{
2288+
const size_t allocCount = origPtrs.size();
2289+
if(allocCount > 0)
2290+
{
2291+
FindPool(lineNumber, origPool, allocCreateInfo.pool);
2292+
2293+
if(csvSplit.GetCount() > FIRST_PARAM_INDEX + 10)
2294+
{
2295+
PrepareUserData(
2296+
lineNumber,
2297+
allocCreateInfo.flags,
2298+
csvSplit.GetRange(FIRST_PARAM_INDEX + 10),
2299+
csvSplit.GetLine(),
2300+
allocCreateInfo.pUserData);
2301+
}
2302+
2303+
UpdateMemStats();
2304+
m_Stats.RegisterCreateAllocation(allocCount);
2305+
2306+
std::vector<VmaAllocation> allocations(allocCount);
2307+
2308+
VkResult res = vmaAllocateMemoryPages(m_Allocator, &memReq, &allocCreateInfo, allocCount, allocations.data(), nullptr);
2309+
for(size_t i = 0; i < allocCount; ++i)
2310+
{
2311+
Allocation allocDesc = {};
2312+
allocDesc.allocationFlags = allocCreateInfo.flags;
2313+
allocDesc.allocation = allocations[i];
2314+
AddAllocation(lineNumber, origPtrs[i], res, "vmaAllocateMemoryPages", std::move(allocDesc));
2315+
}
2316+
}
2317+
}
2318+
else
2319+
{
2320+
if(IssueWarning())
2321+
{
2322+
printf("Line %zu: Invalid parameters for vmaAllocateMemoryPages.\n", lineNumber);
2323+
}
2324+
}
2325+
}
2326+
}
2327+
22092328
void Player::ExecuteAllocateMemoryForBufferOrImage(size_t lineNumber, const CsvSplit& csvSplit, OBJECT_TYPE objType)
22102329
{
22112330
switch(objType)

0 commit comments

Comments
 (0)