summaryrefslogtreecommitdiff
path: root/Runtime/GfxDevice/threaded/GfxDeviceWorker.h
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