blob: 2b1731aba565d70f1709bbe2a86cd82f18ae9f3a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include "UnityPrefix.h"
#if ENABLE_PROFILER
#include "ThreadedTimerQuery.h"
#include "GfxDeviceWorker.h"
#include "Runtime/Threads/ThreadUtility.h"
#include "Runtime/Threads/ThreadedStreamBuffer.h"
#include "Runtime/GfxDevice/threaded/GfxDeviceClient.h"
#include "Runtime/GfxDevice/threaded/GfxCommands.h"
ThreadedTimerQuery::ThreadedTimerQuery(GfxDeviceClient& device)
: m_ClientDevice(device)
{
m_ClientQuery = new ClientDeviceTimerQuery;
DebugAssert(Thread::CurrentThreadIsMainThread());
if (m_ClientDevice.IsSerializing())
{
ThreadedStreamBuffer& stream = *m_ClientDevice.GetCommandQueue();
stream.WriteValueType<GfxCommand>(kGfxCmd_TimerQuery_Constructor);
stream.WriteValueType<ClientDeviceTimerQuery*>(m_ClientQuery);
GFXDEVICE_LOCKSTEP_CLIENT();
}
else
m_ClientQuery->internalQuery = GetRealGfxDevice().CreateTimerQuery();
}
ThreadedTimerQuery::~ThreadedTimerQuery()
{
DebugAssert(Thread::CurrentThreadIsMainThread());
if (m_ClientDevice.IsSerializing())
{
ThreadedStreamBuffer& stream = *m_ClientDevice.GetCommandQueue();
stream.WriteValueType<GfxCommand>(kGfxCmd_TimerQuery_Destructor);
stream.WriteValueType<ClientDeviceTimerQuery*>(m_ClientQuery);
GFXDEVICE_LOCKSTEP_CLIENT();
}
else
{
Assert(m_ClientQuery);
GetRealGfxDevice().DeleteTimerQuery(m_ClientQuery->GetInternal());
delete m_ClientQuery;
}
m_ClientQuery = NULL;
}
void ThreadedTimerQuery::Measure()
{
DebugAssert(Thread::CurrentThreadIsMainThread());
if (m_ClientDevice.IsSerializing())
{
ThreadedStreamBuffer& stream = *m_ClientDevice.GetCommandQueue();
stream.WriteValueType<GfxCommand>(kGfxCmd_TimerQuery_Measure);
stream.WriteValueType<ClientDeviceTimerQuery*>(m_ClientQuery);
GFXDEVICE_LOCKSTEP_CLIENT();
}
else
m_ClientQuery->GetInternal()->Measure();
}
ProfileTimeFormat ThreadedTimerQuery::GetElapsed(UInt32 flags)
{
DebugAssert(Thread::CurrentThreadIsMainThread());
if (m_ClientDevice.IsSerializing())
{
// See if we have the result already
ProfileTimeFormat time = GetElapsedIfReady();
if (time != kInvalidProfileTime)
return time;
// Request result from worker thread
ThreadedStreamBuffer& stream = *m_ClientDevice.GetCommandQueue();
stream.WriteValueType<GfxCommand>(kGfxCmd_TimerQuery_GetElapsed);
stream.WriteValueType<ClientDeviceTimerQuery*>(m_ClientQuery);
stream.WriteValueType<UInt32>(flags);
if (flags & GfxTimerQuery::kWaitClientThread)
{
m_ClientDevice.SubmitCommands();
m_ClientDevice.GetGfxDeviceWorker()->WaitForSignal();
}
GFXDEVICE_LOCKSTEP_CLIENT();
return GetElapsedIfReady();
}
else
return m_ClientQuery->GetInternal()->GetElapsed(flags);
}
ProfileTimeFormat ThreadedTimerQuery::GetElapsedIfReady()
{
if (!m_ClientQuery->pending)
{
// Be careful since UInt64 isn't guaranteed atomic
UnityMemoryBarrier();
return m_ClientQuery->elapsed;
}
return kInvalidProfileTime;
}
void ThreadedTimerQuery::DoLockstep()
{
m_ClientDevice.DoLockstep();
}
#endif
|