Skip to content

Commit a807b9a

Browse files
Initial implementation of Timestamp Packet write
Change-Id: Ic498bcf9795f54fbb5fb5a8d07ed17fa70dc4f1a Signed-off-by: Dunajski, Bartosz <[email protected]>
1 parent 02b8055 commit a807b9a

32 files changed

+429
-95
lines changed

runtime/command_queue/command_queue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ class CommandQueue : public BaseObject<_cl_command_queue> {
331331
Context &getContext() { return *context; }
332332
Context *getContextPtr() { return context; }
333333

334-
LinearStream &getCS(size_t minRequiredSize = 1024u);
334+
MOCKABLE_VIRTUAL LinearStream &getCS(size_t minRequiredSize);
335335
IndirectHeap &getIndirectHeap(IndirectHeap::Type heapType,
336336
size_t minRequiredSize);
337337

runtime/command_queue/enqueue_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ void CommandQueueHw<GfxFamily>::enqueueHandler(Surface **surfacesForResidency,
269269
&blockedCommandsData,
270270
hwTimeStamps,
271271
hwPerfCounter,
272+
nullptr,
272273
preemption,
273274
blockQueue,
274275
commandType);

runtime/command_queue/gpgpu_walker.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "runtime/helpers/dispatch_info.h"
3434
#include "runtime/helpers/kernel_commands.h"
3535
#include "runtime/helpers/task_information.h"
36+
#include "runtime/helpers/timestamp_packet.h"
3637
#include "runtime/indirect_heap/indirect_heap.h"
3738
#include "runtime/kernel/kernel.h"
3839
#include "runtime/program/kernel_info.h"
@@ -124,6 +125,8 @@ inline cl_uint computeDimensions(const size_t workItems[3]) {
124125
template <typename GfxFamily>
125126
class GpgpuWalkerHelper {
126127
public:
128+
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
129+
127130
static void addAluReadModifyWriteRegister(
128131
LinearStream *pCommandStream,
129132
uint32_t aluRegister,
@@ -199,10 +202,17 @@ class GpgpuWalkerHelper {
199202
KernelOperation **blockedCommandsData,
200203
HwTimeStamps *hwTimeStamps,
201204
OCLRT::HwPerfCounter *hwPerfCounter,
205+
TimestampPacket *timestampPacket,
202206
PreemptionMode preemptionMode,
203207
bool blockQueue,
204208
uint32_t commandType = 0);
205209

210+
static void setupTimestampPacket(
211+
LinearStream *cmdStream,
212+
WALKER_HANDLE walkerHandle,
213+
TimestampPacket *timestampPacket,
214+
TimestampPacket::WriteOperationType writeOperationType);
215+
206216
static void dispatchScheduler(
207217
CommandQueue &commandQueue,
208218
DeviceQueueHw<GfxFamily> &devQueueHw,
@@ -214,6 +224,7 @@ class GpgpuWalkerHelper {
214224

215225
template <typename GfxFamily>
216226
struct EnqueueOperation {
227+
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
217228
static size_t getTotalSizeRequiredCS(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const MultiDispatchInfo &multiDispatchInfo);
218229
static size_t getSizeRequiredCS(uint32_t cmdType, bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const Kernel *pKernel);
219230

@@ -239,6 +250,9 @@ LinearStream &getCommandStream(CommandQueue &commandQueue, bool reserveProfiling
239250
SchedulerKernel &scheduler = commandQueue.getDevice().getExecutionEnvironment()->getBuiltIns()->getSchedulerKernel(parentKernel->getContext());
240251
expectedSizeCS += EnqueueOperation<GfxFamily>::getSizeRequiredCS(eventType, reserveProfilingCmdsSpace, reservePerfCounterCmdsSpace, commandQueue, &scheduler);
241252
}
253+
if (DebugManager.flags.EnableTimestampPacket.get()) {
254+
expectedSizeCS += 2 * sizeof(typename GfxFamily::PIPE_CONTROL);
255+
}
242256
return commandQueue.getCS(expectedSizeCS);
243257
}
244258

runtime/command_queue/gpgpu_walker.inl

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ void GpgpuWalkerHelper<GfxFamily>::addAluReadModifyWriteRegister(
104104
pCmd4->setDestinationRegisterAddress(aluRegister);
105105

106106
// Add PIPE_CONTROL to flush caches
107-
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
108107
auto pCmd5 = reinterpret_cast<PIPE_CONTROL *>(pCommandStream->getSpace(sizeof(PIPE_CONTROL)));
109108
*pCmd5 = PIPE_CONTROL::sInit();
110109
pCmd5->setCommandStreamerStallEnable(true);
@@ -157,7 +156,6 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchProfilingCommandsStart(
157156
HwTimeStamps &hwTimeStamps,
158157
OCLRT::LinearStream *commandStream) {
159158
using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM;
160-
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
161159

162160
// PIPE_CONTROL for global timestamp
163161
uint64_t TimeStampAddress = reinterpret_cast<uint64_t>(&(hwTimeStamps.GlobalStartTS));
@@ -185,7 +183,6 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchProfilingCommandsEnd(
185183
OCLRT::LinearStream *commandStream) {
186184

187185
using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM;
188-
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
189186

190187
// PIPE_CONTROL for global timestamp
191188
auto pPipeControlCmd = (PIPE_CONTROL *)commandStream->getSpace(sizeof(PIPE_CONTROL));
@@ -340,7 +337,6 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchPerfCountersCommandsStart(
340337
OCLRT::HwPerfCounter &hwPerfCounter,
341338
OCLRT::LinearStream *commandStream) {
342339

343-
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
344340
using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM;
345341
using MI_REPORT_PERF_COUNT = typename GfxFamily::MI_REPORT_PERF_COUNT;
346342

@@ -387,7 +383,6 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchPerfCountersCommandsEnd(
387383
OCLRT::HwPerfCounter &hwPerfCounter,
388384
OCLRT::LinearStream *commandStream) {
389385

390-
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
391386
using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM;
392387
using MI_REPORT_PERF_COUNT = typename GfxFamily::MI_REPORT_PERF_COUNT;
393388

@@ -440,6 +435,7 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchWalker(
440435
KernelOperation **blockedCommandsData,
441436
HwTimeStamps *hwTimeStamps,
442437
OCLRT::HwPerfCounter *hwPerfCounter,
438+
TimestampPacket *timestampPacket,
443439
PreemptionMode preemptionMode,
444440
bool blockQueue,
445441
uint32_t commandType) {
@@ -519,6 +515,7 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchWalker(
519515

520516
DEBUG_BREAK_IF(offsetInterfaceDescriptorTable % 64 != 0);
521517

518+
size_t currentDispatchIndex = 0;
522519
for (auto &dispatchInfo : multiDispatchInfo) {
523520
auto &kernel = *dispatchInfo.getKernel();
524521

@@ -613,11 +610,20 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchWalker(
613610
// Implement enabling special WA DisableLSQCROPERFforOCL if needed
614611
GpgpuWalkerHelper<GfxFamily>::applyWADisableLSQCROPERFforOCL(commandStream, kernel, true);
615612

613+
bool setupTimestampPacket = (DebugManager.flags.EnableTimestampPacket.get()) && (currentDispatchIndex == numDispatches - 1);
614+
if (setupTimestampPacket) {
615+
GpgpuWalkerHelper<GfxFamily>::setupTimestampPacket(commandStream, nullptr, timestampPacket, TimestampPacket::WriteOperationType::Start);
616+
}
617+
616618
// Program the walker. Invokes execution so all state should already be programmed
617619
typedef typename GfxFamily::GPGPU_WALKER GPGPU_WALKER;
618620
auto pGpGpuWalkerCmd = (GPGPU_WALKER *)commandStream->getSpace(sizeof(GPGPU_WALKER));
619621
*pGpGpuWalkerCmd = GfxFamily::cmdInitGpgpuWalker;
620622

623+
if (setupTimestampPacket) {
624+
GpgpuWalkerHelper<GfxFamily>::setupTimestampPacket(commandStream, pGpGpuWalkerCmd, timestampPacket, TimestampPacket::WriteOperationType::End);
625+
}
626+
621627
size_t globalOffsets[3] = {offset.x, offset.y, offset.z};
622628
size_t startWorkGroups[3] = {swgs.x, swgs.y, swgs.z};
623629
size_t numWorkGroups[3] = {nwgs.x, nwgs.y, nwgs.z};
@@ -645,6 +651,7 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchWalker(
645651
GpgpuWalkerHelper<GfxFamily>::applyWADisableLSQCROPERFforOCL(commandStream, kernel, false);
646652

647653
PreemptionHelper::applyPreemptionWaCmdsEnd<GfxFamily>(commandStream, commandQueue.getDevice());
654+
currentDispatchIndex++;
648655
}
649656

650657
// If hwTimeStamps is passed (not nullptr), then we know that profiling is enabled
@@ -656,6 +663,24 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchWalker(
656663
}
657664
}
658665

666+
template <typename GfxFamily>
667+
void GpgpuWalkerHelper<GfxFamily>::setupTimestampPacket(
668+
LinearStream *cmdStream,
669+
WALKER_HANDLE walkerHandle,
670+
TimestampPacket *timestampPacket,
671+
TimestampPacket::WriteOperationType writeOperationType) {
672+
673+
uint64_t address = timestampPacket->pickAddressForPipeControlWrite(writeOperationType);
674+
675+
auto pipeControlCmd = cmdStream->getSpaceForCmd<PIPE_CONTROL>();
676+
*pipeControlCmd = PIPE_CONTROL::sInit();
677+
pipeControlCmd->setCommandStreamerStallEnable(true);
678+
pipeControlCmd->setPostSyncOperation(PIPE_CONTROL::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA);
679+
pipeControlCmd->setAddress(static_cast<uint32_t>(address & 0x0000FFFFFFFFULL));
680+
pipeControlCmd->setAddressHigh(static_cast<uint32_t>(address >> 32));
681+
pipeControlCmd->setImmediateData(0);
682+
}
683+
659684
template <typename GfxFamily>
660685
void GpgpuWalkerHelper<GfxFamily>::dispatchScheduler(
661686
CommandQueue &commandQueue,
@@ -667,7 +692,6 @@ void GpgpuWalkerHelper<GfxFamily>::dispatchScheduler(
667692

668693
using INTERFACE_DESCRIPTOR_DATA = typename GfxFamily::INTERFACE_DESCRIPTOR_DATA;
669694
using GPGPU_WALKER = typename GfxFamily::GPGPU_WALKER;
670-
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
671695
using MI_BATCH_BUFFER_START = typename GfxFamily::MI_BATCH_BUFFER_START;
672696

673697
OCLRT::LinearStream *commandStream = nullptr;
@@ -802,14 +826,14 @@ size_t GpgpuWalkerHelper<GfxFamily>::getSizeForWADisableLSQCROPERFforOCL(const K
802826
template <typename GfxFamily>
803827
size_t EnqueueOperation<GfxFamily>::getTotalSizeRequiredCS(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const MultiDispatchInfo &multiDispatchInfo) {
804828
size_t size = KernelCommandsHelper<GfxFamily>::getSizeRequiredCS() +
805-
sizeof(typename GfxFamily::PIPE_CONTROL) * (KernelCommandsHelper<GfxFamily>::isPipeControlWArequired() ? 2 : 1);
829+
sizeof(PIPE_CONTROL) * (KernelCommandsHelper<GfxFamily>::isPipeControlWArequired() ? 2 : 1);
806830
if (reserveProfilingCmdsSpace) {
807-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL) + 4 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
831+
size += 2 * sizeof(PIPE_CONTROL) + 4 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
808832
}
809833
if (reservePerfCounters) {
810834
//start cmds
811835
//P_C: flush CS & TimeStamp BEGIN
812-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL);
836+
size += 2 * sizeof(PIPE_CONTROL);
813837
//SRM NOOPID & Frequency
814838
size += 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
815839
//gp registers
@@ -821,7 +845,7 @@ size_t EnqueueOperation<GfxFamily>::getTotalSizeRequiredCS(bool reserveProfiling
821845

822846
//end cmds
823847
//P_C: flush CS & TimeStamp END;
824-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL);
848+
size += 2 * sizeof(PIPE_CONTROL);
825849
//OA buffer (status head, tail)
826850
size += 3 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
827851
//report perf count
@@ -858,15 +882,15 @@ size_t EnqueueOperation<GfxFamily>::getSizeRequiredCS(uint32_t cmdType, bool res
858882
template <typename GfxFamily>
859883
size_t EnqueueOperation<GfxFamily>::getSizeRequiredCSKernel(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const Kernel *pKernel) {
860884
size_t size = sizeof(typename GfxFamily::GPGPU_WALKER) + KernelCommandsHelper<GfxFamily>::getSizeRequiredCS() +
861-
sizeof(typename GfxFamily::PIPE_CONTROL) * (KernelCommandsHelper<GfxFamily>::isPipeControlWArequired() ? 2 : 1);
885+
sizeof(PIPE_CONTROL) * (KernelCommandsHelper<GfxFamily>::isPipeControlWArequired() ? 2 : 1);
862886
size += PreemptionHelper::getPreemptionWaCsSize<GfxFamily>(commandQueue.getDevice());
863887
if (reserveProfilingCmdsSpace) {
864-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL) + 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
888+
size += 2 * sizeof(PIPE_CONTROL) + 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
865889
}
866890
if (reservePerfCounters) {
867891
//start cmds
868892
//P_C: flush CS & TimeStamp BEGIN
869-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL);
893+
size += 2 * sizeof(PIPE_CONTROL);
870894
//SRM NOOPID & Frequency
871895
size += 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
872896
//gp registers
@@ -878,7 +902,7 @@ size_t EnqueueOperation<GfxFamily>::getSizeRequiredCSKernel(bool reserveProfilin
878902

879903
//end cmds
880904
//P_C: flush CS & TimeStamp END;
881-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL);
905+
size += 2 * sizeof(PIPE_CONTROL);
882906
//OA buffer (status head, tail)
883907
size += 3 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
884908
//report perf count
@@ -899,7 +923,7 @@ template <typename GfxFamily>
899923
size_t EnqueueOperation<GfxFamily>::getSizeRequiredCSNonKernel(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue) {
900924
size_t size = 0;
901925
if (reserveProfilingCmdsSpace) {
902-
size += 2 * sizeof(typename GfxFamily::PIPE_CONTROL) + 4 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
926+
size += 2 * sizeof(PIPE_CONTROL) + 4 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
903927
}
904928
return size;
905929
}

runtime/helpers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ set(RUNTIME_SRCS_HELPERS_BASE
8585
${CMAKE_CURRENT_SOURCE_DIR}/string_helpers.h
8686
${CMAKE_CURRENT_SOURCE_DIR}/surface_formats.cpp
8787
${CMAKE_CURRENT_SOURCE_DIR}/surface_formats.h
88+
${CMAKE_CURRENT_SOURCE_DIR}/timestamp_packet.h
8889
${CMAKE_CURRENT_SOURCE_DIR}/task_information.cpp
8990
${CMAKE_CURRENT_SOURCE_DIR}/task_information.h
9091
${CMAKE_CURRENT_SOURCE_DIR}/uint16_avx2.h

runtime/helpers/timestamp_packet.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2018, Intel Corporation
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included
12+
* in all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+
* OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#pragma once
24+
25+
#include <cstdint>
26+
#include <array>
27+
28+
namespace OCLRT {
29+
class TimestampPacket {
30+
public:
31+
enum class DataIndex : uint32_t {
32+
ContextStart,
33+
GlobalStart,
34+
ContextEnd,
35+
GlobalEnd,
36+
Max
37+
};
38+
39+
enum class WriteOperationType : uint32_t {
40+
Start,
41+
End
42+
};
43+
44+
const uint32_t *pickDataPtr() const { return &(data[0]); }
45+
46+
uint64_t pickAddressForPipeControlWrite(WriteOperationType operationType) const {
47+
auto index = WriteOperationType::Start == operationType
48+
? static_cast<uint32_t>(DataIndex::ContextStart)
49+
: static_cast<uint32_t>(DataIndex::ContextEnd);
50+
51+
return reinterpret_cast<uint64_t>(&data[index]);
52+
}
53+
54+
uint32_t pickDataValue(DataIndex index) const { return data[static_cast<uint32_t>(index)]; }
55+
56+
protected:
57+
std::array<uint32_t, static_cast<uint32_t>(DataIndex::Max)> data = {{1, 1, 1, 1}};
58+
};
59+
} // namespace OCLRT

runtime/memory_manager/memory_manager.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@
3030
#include "runtime/helpers/aligned_memory.h"
3131
#include "runtime/helpers/basic_math.h"
3232
#include "runtime/helpers/options.h"
33+
#include "runtime/helpers/timestamp_packet.h"
3334
#include "runtime/memory_manager/deferred_deleter.h"
3435
#include "runtime/utilities/stackvec.h"
3536
#include "runtime/utilities/tag_allocator.h"
3637

3738
#include <algorithm>
3839

3940
namespace OCLRT {
40-
constexpr size_t ProfilingTagCount = 512;
41-
constexpr size_t PerfCounterTagCount = 512;
41+
constexpr size_t TagCount = 512;
4242

4343
struct ReusableAllocationRequirements {
4444
size_t requiredMinimalSize;
@@ -226,11 +226,16 @@ void MemoryManager::applyCommonCleanup() {
226226
if (this->paddingAllocation) {
227227
this->freeGraphicsMemory(this->paddingAllocation);
228228
}
229-
if (profilingTimeStampAllocator)
229+
if (profilingTimeStampAllocator) {
230230
profilingTimeStampAllocator->cleanUpResources();
231-
232-
if (perfCounterAllocator)
231+
}
232+
if (perfCounterAllocator) {
233233
perfCounterAllocator->cleanUpResources();
234+
}
235+
236+
if (timestampPacketAllocator) {
237+
timestampPacketAllocator->cleanUpResources();
238+
}
234239

235240
cleanAllocationList(-1, TEMPORARY_ALLOCATION);
236241
cleanAllocationList(-1, REUSABLE_ALLOCATION);
@@ -263,18 +268,25 @@ void MemoryManager::freeAllocationsList(uint32_t waitTaskCount, AllocationsList
263268

264269
TagAllocator<HwTimeStamps> *MemoryManager::getEventTsAllocator() {
265270
if (profilingTimeStampAllocator.get() == nullptr) {
266-
profilingTimeStampAllocator.reset(new TagAllocator<HwTimeStamps>(this, ProfilingTagCount, MemoryConstants::cacheLineSize));
271+
profilingTimeStampAllocator = std::make_unique<TagAllocator<HwTimeStamps>>(this, TagCount, MemoryConstants::cacheLineSize);
267272
}
268273
return profilingTimeStampAllocator.get();
269274
}
270275

271276
TagAllocator<HwPerfCounter> *MemoryManager::getEventPerfCountAllocator() {
272277
if (perfCounterAllocator.get() == nullptr) {
273-
perfCounterAllocator.reset(new TagAllocator<HwPerfCounter>(this, PerfCounterTagCount, MemoryConstants::cacheLineSize));
278+
perfCounterAllocator = std::make_unique<TagAllocator<HwPerfCounter>>(this, TagCount, MemoryConstants::cacheLineSize);
274279
}
275280
return perfCounterAllocator.get();
276281
}
277282

283+
TagAllocator<TimestampPacket> *MemoryManager::getTimestampPacketAllocator() {
284+
if (timestampPacketAllocator.get() == nullptr) {
285+
timestampPacketAllocator = std::make_unique<TagAllocator<TimestampPacket>>(this, TagCount, MemoryConstants::cacheLineSize);
286+
}
287+
return timestampPacketAllocator.get();
288+
}
289+
278290
void MemoryManager::pushAllocationForResidency(GraphicsAllocation *gfxAllocation) {
279291
residencyAllocations.push_back(gfxAllocation);
280292
}

0 commit comments

Comments
 (0)