blob: 412991751cc7273f09f1f67dd609f24b70990e07 (
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#pragma once
#if ENABLE_MULTITHREADED_CODE
#include "Runtime/GfxDevice/GfxDevice.h"
#include "Runtime/GfxDevice/threaded/WorkerIDMapper.h"
#include "Runtime/Utilities/dynamic_array.h"
#include "Runtime/Shaders/VBO.h"
#include "Runtime/Threads/Mutex.h"
#include "Runtime/Threads/Semaphore.h"
#include "Runtime/Threads/JobScheduler.h"
#include "External/shaderlab/Library/TextureBinding.h"
#include "Runtime/Filters/Mesh/MeshSkinning.h"
#include <deque>
#define GFXDEVICE_USE_CACHED_STATE 0
#define DEBUG_GFXDEVICE_LOCKSTEP 0
#if DEBUG_GFXDEVICE_LOCKSTEP
#define GFXDEVICE_LOCKSTEP_CLIENT() { DoLockstep(); }
#define GFXDEVICE_LOCKSTEP_WORKER() { DoLockstep(pos, cmd); }
#else
#define GFXDEVICE_LOCKSTEP_CLIENT()
#define GFXDEVICE_LOCKSTEP_WORKER()
#endif
struct ClientDeviceTimerQuery;
class ThreadedStreamBuffer;
class ThreadedDisplayList;
class Thread;
class GfxDeviceWorker : public NonCopyable
{
public:
GfxDeviceWorker(int maxCallDepth, ThreadedStreamBuffer* commandQueue);
~GfxDeviceWorker();
GfxThreadableDevice* Startup(GfxDeviceRenderer renderer, bool threaded, bool forceRef);
void WaitForSignal();
void LockstepWait();
void GetLastFrameStats(GfxDeviceStats& stats);
void CallImmediate(ThreadedDisplayList* dlist);
enum EventType
{
kEventTypePresent,
kEventTypeTimerQueries,
kEventTypeCount
};
void WaitForEvent(EventType type);
void WaitOnCPUFence(UInt32 fence);
bool DidPresentFrame(UInt32 frameID) const;
bool RunCommandIfDataIsAvailable();
private:
void SignalEvent(EventType type);
static void* RunGfxDeviceWorker(void *data);
void Run();
void RunCommand(ThreadedStreamBuffer& stream);
void Signal();
void DoLockstep(int pos, int cmd);
UInt8* ReadBufferData(ThreadedStreamBuffer& stream, int size);
void WritebackData(ThreadedStreamBuffer& stream, const void* data, int size);
#if ENABLE_PROFILER
void PollTimerQueries();
bool PollNextTimerQuery(bool wait);
#endif
#if GFXDEVICE_USE_CACHED_STATE
struct CachedState
{
CachedState();
NormalizationMode normalization;
int backface;
Vector4f ambient;
int fogEnabled;
GfxFogParams fogParams;
};
#endif
int m_CallDepth;
int m_MaxCallDepth;
Thread* m_WorkerThread;
ThreadedStreamBuffer* m_CommandQueue;
ThreadedStreamBuffer* m_MainCommandQueue;
ThreadedStreamBuffer* m_PlaybackCommandQueues;
ThreadedDisplayList** m_PlaybackDisplayLists;
dynamic_array<UInt8> m_TempBuffer;
dynamic_array<SkinMeshInfo> m_ActiveSkins;
dynamic_array<VBO*> m_MappedSkinVBOs;
JobScheduler::JobGroupID m_SkinJobGroup;
Semaphore m_EventSemaphores[kEventTypeCount];
Semaphore m_LockstepSemaphore;
Semaphore m_WaitSemaphore;
volatile UInt32 m_CurrentCPUFence;
volatile UInt32 m_PresentFrameID;
Mutex m_StatsMutex;
GfxDeviceStats m_FrameStats;
GfxThreadableDevice* m_Device;
bool m_IsThreadOwner;
bool m_Quit;
#if GFXDEVICE_USE_CACHED_STATE
CachedState m_Cached;
#endif
#if ENABLE_PROFILER
// Timer queries for GPU profiling
typedef std::deque<ClientDeviceTimerQuery*> TimerQueryList;
TimerQueryList m_PolledTimerQueries;
#endif
#if ENABLE_GFXDEVICE_REMOTE_PROCESS
WorkerIDMapper<DeviceBlendState> m_BlendStateMapper;
WorkerIDMapper<DeviceDepthState> m_DepthStateMapper;
WorkerIDMapper<DeviceStencilState> m_StencilStateMapper;
WorkerIDMapper<DeviceRasterState> m_RasterStateMapper;
WorkerIDMapper<VBO> m_VBOMapper;
WorkerIDMapper<void> m_TextureCombinerMapper;
WorkerIDMapper<void> m_RenderSurfaceMapper;
WorkerIDMapper<GpuProgramParameters> m_GpuProgramParametersMapper;
WorkerIDMapper<GpuProgram> m_GpuProgramMapper;
ClientIDMapper m_GpuProgramClientMapper;
#endif
};
#endif
|