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