1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #pragma once
19 
20 #include <list>
21 #include <string>
22 #include <vector>
23 
24 #include "Common/Swap.h"
25 #include "GPU/GPU.h"
26 #include "Core/MemMap.h"
27 #include "GPU/ge_constants.h"
28 #include "GPU/Common/ShaderCommon.h"
29 
30 struct PspGeListArgs;
31 struct GPUgstate;
32 class PointerWrap;
33 
34 enum DisplayListStatus {
35 	// The list has been completed
36 	PSP_GE_LIST_COMPLETED = 0,
37 	// The list is queued but not executed yet
38 	PSP_GE_LIST_QUEUED = 1,
39 	// The list is currently being executed
40 	PSP_GE_LIST_DRAWING = 2,
41 	// The list was stopped because it encountered stall address
42 	PSP_GE_LIST_STALLING = 3,
43 	// The list is paused because of a signal or sceGeBreak
44 	PSP_GE_LIST_PAUSED = 4,
45 };
46 
47 enum DisplayListState {
48   // No state assigned, the list is empty
49   PSP_GE_DL_STATE_NONE = 0,
50   // The list has been queued
51   PSP_GE_DL_STATE_QUEUED = 1,
52   // The list is being executed
53   PSP_GE_DL_STATE_RUNNING = 2,
54   // The list was completed and will be removed
55   PSP_GE_DL_STATE_COMPLETED = 3,
56   // The list has been paused by a signal
57   PSP_GE_DL_STATE_PAUSED = 4,
58 };
59 
60 enum SignalBehavior {
61 	PSP_GE_SIGNAL_NONE             = 0x00,
62 	PSP_GE_SIGNAL_HANDLER_SUSPEND  = 0x01,
63 	PSP_GE_SIGNAL_HANDLER_CONTINUE = 0x02,
64 	PSP_GE_SIGNAL_HANDLER_PAUSE    = 0x03,
65 	PSP_GE_SIGNAL_SYNC             = 0x08,
66 	PSP_GE_SIGNAL_JUMP             = 0x10,
67 	PSP_GE_SIGNAL_CALL             = 0x11,
68 	PSP_GE_SIGNAL_RET              = 0x12,
69 	PSP_GE_SIGNAL_RJUMP            = 0x13,
70 	PSP_GE_SIGNAL_RCALL            = 0x14,
71 	PSP_GE_SIGNAL_OJUMP            = 0x15,
72 	PSP_GE_SIGNAL_OCALL            = 0x16,
73 
74 	PSP_GE_SIGNAL_RTBP0            = 0x20,
75 	PSP_GE_SIGNAL_RTBP1            = 0x21,
76 	PSP_GE_SIGNAL_RTBP2            = 0x22,
77 	PSP_GE_SIGNAL_RTBP3            = 0x23,
78 	PSP_GE_SIGNAL_RTBP4            = 0x24,
79 	PSP_GE_SIGNAL_RTBP5            = 0x25,
80 	PSP_GE_SIGNAL_RTBP6            = 0x26,
81 	PSP_GE_SIGNAL_RTBP7            = 0x27,
82 	PSP_GE_SIGNAL_OTBP0            = 0x28,
83 	PSP_GE_SIGNAL_OTBP1            = 0x29,
84 	PSP_GE_SIGNAL_OTBP2            = 0x2A,
85 	PSP_GE_SIGNAL_OTBP3            = 0x2B,
86 	PSP_GE_SIGNAL_OTBP4            = 0x2C,
87 	PSP_GE_SIGNAL_OTBP5            = 0x2D,
88 	PSP_GE_SIGNAL_OTBP6            = 0x2E,
89 	PSP_GE_SIGNAL_OTBP7            = 0x2F,
90 	PSP_GE_SIGNAL_RCBP             = 0x30,
91 	PSP_GE_SIGNAL_OCBP             = 0x38,
92 	PSP_GE_SIGNAL_BREAK1           = 0xF0,
93 	PSP_GE_SIGNAL_BREAK2           = 0xFF,
94 };
95 
96 enum GPURunState {
97 	GPUSTATE_RUNNING = 0,
98 	GPUSTATE_DONE = 1,
99 	GPUSTATE_STALL = 2,
100 	GPUSTATE_INTERRUPT = 3,
101 	GPUSTATE_ERROR = 4,
102 };
103 
104 enum GPUSyncType {
105 	GPU_SYNC_DRAW,
106 	GPU_SYNC_LIST,
107 };
108 
109 // Used for debug
110 struct FramebufferInfo {
111 	u32 fb_address;
112 	u32 z_address;
113 	int format;
114 	u32 width;
115 	u32 height;
116 	void* fbo;
117 };
118 
119 struct DisplayListStackEntry {
120 	u32 pc;
121 	u32 offsetAddr;
122 	u32 baseAddr;
123 };
124 
125 struct DisplayList {
126 	int id;
127 	u32 startpc;
128 	u32 pc;
129 	u32 stall;
130 	DisplayListState state;
131 	SignalBehavior signal;
132 	int subIntrBase;
133 	u16 subIntrToken;
134 	DisplayListStackEntry stack[32];
135 	int stackptr;
136 	bool interrupted;
137 	u64 waitTicks;
138 	bool interruptsEnabled;
139 	bool pendingInterrupt;
140 	bool started;
141 	PSPPointer<u32_le> context;
142 	u32 offsetAddr;
143 	bool bboxResult;
144 	u32 stackAddr;
145 
146 	u32 padding;  // Android x86-32 does not round the structure size up to the closest multiple of 8 like the other platforms.
147 };
148 
149 enum GPUInvalidationType {
150 	// Affects all memory.  Not considered highly.
151 	GPU_INVALIDATE_ALL,
152 	// Indicates some memory may have changed.
153 	GPU_INVALIDATE_HINT,
154 	// Reliable invalidation (where any hashing, etc. is unneeded, it'll always invalidate.)
155 	GPU_INVALIDATE_SAFE,
156 	// Forced invalidation for when the texture hash may not catch changes.
157 	GPU_INVALIDATE_FORCE,
158 };
159 
160 namespace Draw {
161 class DrawContext;
162 }
163 
164 class GPUInterface {
165 public:
~GPUInterface()166 	virtual ~GPUInterface() {}
167 
168 	static const int DisplayListMaxCount = 64;
169 
170 	virtual Draw::DrawContext *GetDrawContext() = 0;
171 
172 	// Initialization
173 	virtual bool IsReady() = 0;
174 	virtual void CancelReady() = 0;
175 	virtual void InitClear() = 0;
176 	virtual void Reinitialize() = 0;
177 
178 	// Frame managment
179 	virtual void BeginHostFrame() = 0;
180 	virtual void EndHostFrame() = 0;
181 
182 	// Draw queue management
183 	virtual DisplayList* getList(int listid) = 0;
184 	// TODO: Much of this should probably be shared between the different GPU implementations.
185 	virtual u32  EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) = 0;
186 	virtual u32  DequeueList(int listid) = 0;
187 	virtual u32  UpdateStall(int listid, u32 newstall) = 0;
188 	virtual u32  DrawSync(int mode) = 0;
189 	virtual int  ListSync(int listid, int mode) = 0;
190 	virtual u32  Continue() = 0;
191 	virtual u32  Break(int mode) = 0;
192 	virtual int  GetStack(int index, u32 stackPtr) = 0;
193 
194 	virtual void InterruptStart(int listid) = 0;
195 	virtual void InterruptEnd(int listid) = 0;
196 	virtual void SyncEnd(GPUSyncType waitType, int listid, bool wokeThreads) = 0;
197 
198 	virtual void PreExecuteOp(u32 op, u32 diff) = 0;
199 	virtual void ExecuteOp(u32 op, u32 diff) = 0;
200 	virtual bool InterpretList(DisplayList& list) = 0;
201 
202 	// Framebuffer management
203 	virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0;
204 	virtual void BeginFrame() = 0;  // Can be a good place to draw the "memory" framebuffer for accelerated plugins
205 	virtual void CopyDisplayToOutput(bool reallyDirty) = 0;
206 
207 	// Tells the GPU to update the gpuStats structure.
208 	virtual void GetStats(char *buffer, size_t bufsize) = 0;
209 
210 	// Invalidate any cached content sourced from the specified range.
211 	// If size = -1, invalidate everything.
212 	virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type) = 0;
213 	virtual void NotifyVideoUpload(u32 addr, int size, int width, int format) = 0;
214 	// Update either RAM from VRAM, or VRAM from RAM... or even VRAM from VRAM.
215 	virtual bool PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
216 	virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
217 	virtual bool PerformMemoryDownload(u32 dest, int size) = 0;
218 	virtual bool PerformMemoryUpload(u32 dest, int size) = 0;
219 	virtual bool PerformStencilUpload(u32 dest, int size) = 0;
220 
221 	// Will cause the texture cache to be cleared at the start of the next frame.
222 	virtual void ClearCacheNextFrame() = 0;
223 
224 	// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
225 	virtual void EnableInterrupts(bool enable) = 0;
226 
227 	virtual void DeviceLost() = 0;
228 	virtual void DeviceRestore() = 0;
229 	virtual void ReapplyGfxState() = 0;
230 	virtual void DoState(PointerWrap &p) = 0;
231 
232 	// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
233 	virtual void Resized() = 0;
234 	virtual void ClearShaderCache() = 0;
235 	virtual void CleanupBeforeUI() = 0;
236 	virtual bool FramebufferDirty() = 0;
237 	virtual bool FramebufferReallyDirty() = 0;
238 	virtual bool BusyDrawing() = 0;
239 
240 	// If any jit is being used inside the GPU.
241 	virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
242 
243 	// Debugging
244 	virtual void DumpNextFrame() = 0;
245 	virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
246 	virtual const std::list<int>& GetDisplayLists() = 0;
247 	// TODO: Currently Qt only, needs to be cleaned up.
248 	virtual std::vector<FramebufferInfo> GetFramebufferList() = 0;
249 	virtual s64 GetListTicks(int listid) = 0;
250 
251 	// For debugging. The IDs returned are opaque, do not poke in them or display them in any way.
252 	virtual std::vector<std::string> DebugGetShaderIDs(DebugShaderType type) = 0;
253 	virtual std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) = 0;
254 };
255