Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/Common/GPUDebugInterface.h
3186 views
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 <vector>
21
#include <list>
22
#include <string>
23
24
#include "Common/Math/expression_parser.h"
25
#include "Core/MemMap.h"
26
#include "GPU/GPU.h"
27
#include "GPU/GPUDefinitions.h"
28
#include "GPU/GPUState.h"
29
#include "GPU/ge_constants.h"
30
#include "GPU/Debugger/Debugger.h"
31
32
class FramebufferManagerCommon;
33
class TextureCacheCommon;
34
35
struct VirtualFramebuffer;
36
struct DisplayList;
37
38
namespace GPURecord {
39
class Recorder;
40
}
41
class GPUBreakpoints;
42
43
struct GPUDebugOp {
44
u32 pc;
45
u8 cmd;
46
u32 op;
47
std::string desc;
48
};
49
50
enum GPUDebugBufferFormat {
51
// These match GEBufferFormat.
52
GPU_DBG_FORMAT_565 = 0,
53
GPU_DBG_FORMAT_5551 = 1,
54
GPU_DBG_FORMAT_4444 = 2,
55
GPU_DBG_FORMAT_8888 = 3,
56
GPU_DBG_FORMAT_INVALID = 0xFF,
57
58
// These are reversed versions.
59
GPU_DBG_FORMAT_REVERSE_FLAG = 4,
60
GPU_DBG_FORMAT_565_REV = 4,
61
GPU_DBG_FORMAT_5551_REV = 5,
62
GPU_DBG_FORMAT_4444_REV = 6,
63
64
// 565 is just reversed, the others have B and R swapped.
65
GPU_DBG_FORMAT_565_BGRA = 0x04,
66
GPU_DBG_FORMAT_BRSWAP_FLAG = 0x08,
67
GPU_DBG_FORMAT_5551_BGRA = 0x09,
68
GPU_DBG_FORMAT_4444_BGRA = 0x0A,
69
GPU_DBG_FORMAT_8888_BGRA = 0x0B,
70
71
// These don't, they're for depth/stencil buffers.
72
GPU_DBG_FORMAT_FLOAT = 0x10,
73
GPU_DBG_FORMAT_16BIT = 0x11,
74
GPU_DBG_FORMAT_8BIT = 0x12,
75
GPU_DBG_FORMAT_24BIT_8X = 0x13,
76
GPU_DBG_FORMAT_24X_8BIT = 0x14,
77
78
GPU_DBG_FORMAT_FLOAT_DIV_256 = 0x18,
79
GPU_DBG_FORMAT_24BIT_8X_DIV_256 = 0x1B,
80
81
// This is used for screenshots, mainly.
82
GPU_DBG_FORMAT_888_RGB = 0x20,
83
};
84
85
enum GPUDebugFramebufferType {
86
// The current render target.
87
GPU_DBG_FRAMEBUF_RENDER,
88
// The current display target (not the displayed screen, though.)
89
GPU_DBG_FRAMEBUF_DISPLAY,
90
};
91
92
inline GPUDebugBufferFormat &operator |=(GPUDebugBufferFormat &lhs, const GPUDebugBufferFormat &rhs) {
93
lhs = GPUDebugBufferFormat((int)lhs | (int)rhs);
94
return lhs;
95
}
96
97
struct GPUDebugBuffer {
98
GPUDebugBuffer() {
99
}
100
101
GPUDebugBuffer(void *data, u32 stride, u32 height, GEBufferFormat fmt, bool reversed = false)
102
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
103
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
104
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
105
}
106
}
107
108
GPUDebugBuffer(void *data, u32 stride, u32 height, GETextureFormat fmt, bool reversed = false)
109
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
110
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
111
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
112
}
113
}
114
115
GPUDebugBuffer(void *data, u32 stride, u32 height, GPUDebugBufferFormat fmt)
116
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(fmt), flipped_(false) {
117
}
118
119
GPUDebugBuffer(GPUDebugBuffer &&other) noexcept {
120
alloc_ = other.alloc_;
121
data_ = other.data_;
122
height_ = other.height_;
123
stride_ = other.stride_;
124
flipped_ = other.flipped_;
125
fmt_ = other.fmt_;
126
other.alloc_ = false;
127
other.data_ = nullptr;
128
}
129
130
~GPUDebugBuffer() {
131
Free();
132
}
133
134
GPUDebugBuffer &operator = (GPUDebugBuffer &&other) noexcept {
135
if (this != &other) {
136
Free();
137
alloc_ = other.alloc_;
138
data_ = other.data_;
139
height_ = other.height_;
140
stride_ = other.stride_;
141
flipped_ = other.flipped_;
142
fmt_ = other.fmt_;
143
other.alloc_ = false;
144
other.data_ = nullptr;
145
}
146
147
return *this;
148
}
149
150
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false, bool reversed = false);
151
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false);
152
void Free();
153
154
void ZeroBytes();
155
156
u32 GetRawPixel(int x, int y) const;
157
void SetRawPixel(int x, int y, u32 c);
158
159
u8 *GetData() {
160
return data_;
161
}
162
163
const u8 *GetData() const {
164
return data_;
165
}
166
167
u32 GetHeight() const {
168
return height_;
169
}
170
171
u32 GetStride() const {
172
return stride_;
173
}
174
175
bool GetFlipped() const {
176
return flipped_;
177
}
178
179
GPUDebugBufferFormat GetFormat() const {
180
return fmt_;
181
}
182
183
u32 PixelSize() const;
184
185
private:
186
bool alloc_ = false;
187
u8 *data_ = nullptr;
188
u32 stride_ = 0;
189
u32 height_ = 0;
190
GPUDebugBufferFormat fmt_ = GPU_DBG_FORMAT_INVALID;
191
bool flipped_ = false;
192
};
193
194
struct GPUDebugVertex {
195
float u;
196
float v;
197
float x;
198
float y;
199
float z;
200
u8 c[4];
201
float nx;
202
float ny;
203
float nz;
204
};
205
206
class GPUDebugInterface {
207
public:
208
virtual ~GPUDebugInterface() = default;
209
virtual bool GetCurrentDisplayList(DisplayList &list) = 0;
210
virtual int GetCurrentPrimCount() = 0;
211
virtual std::vector<DisplayList> ActiveDisplayLists() = 0;
212
virtual void ResetListPC(int listID, u32 pc) = 0;
213
virtual void ResetListStall(int listID, u32 stall) = 0;
214
virtual void ResetListState(int listID, DisplayListState state) = 0;
215
216
virtual GPUDebugOp DisassembleOp(u32 pc, u32 op) = 0;
217
virtual std::vector<GPUDebugOp> DisassembleOpRange(u32 startpc, u32 endpc) = 0;
218
219
virtual u32 GetRelativeAddress(u32 data) = 0;
220
virtual u32 GetVertexAddress() = 0;
221
virtual u32 GetIndexAddress() = 0;
222
virtual const GPUgstate &GetGState() = 0;
223
// Needs to be called from the GPU thread.
224
// Calling from a separate thread (e.g. UI) may fail.
225
virtual void SetCmdValue(u32 op) = 0;
226
virtual void Flush() = 0;
227
228
virtual void GetStats(char *buffer, size_t bufsize) = 0;
229
230
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
231
virtual uint32_t GetAddrTranslation() = 0;
232
233
// TODO: Make a proper debug interface instead of accessing directly?
234
virtual FramebufferManagerCommon *GetFramebufferManagerCommon() = 0;
235
virtual TextureCacheCommon *GetTextureCacheCommon() = 0;
236
237
virtual std::vector<const VirtualFramebuffer *> GetFramebufferList() const = 0;
238
239
virtual std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) = 0;
240
virtual std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) = 0;
241
virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
242
virtual const std::list<int> &GetDisplayListQueue() = 0;
243
virtual const DisplayList &GetDisplayList(int index) = 0;
244
245
virtual int PrimsThisFrame() const = 0;
246
virtual int PrimsLastFrame() const = 0;
247
248
virtual void ClearBreakNext() = 0;
249
virtual void SetBreakNext(GPUDebug::BreakNext next) = 0 ;
250
virtual void SetBreakCount(int c, bool relative = false) = 0 ;
251
virtual GPUDebug::BreakNext GetBreakNext() const = 0;
252
virtual int GetBreakCount() const = 0;
253
virtual bool SetRestrictPrims(std::string_view rule) = 0 ;
254
virtual std::string_view GetRestrictPrims() = 0;
255
256
virtual GPURecord::Recorder *GetRecorder() = 0;
257
virtual GPUBreakpoints *GetBreakpoints() = 0;
258
259
virtual bool GetCurrentDrawAsDebugVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
260
return false;
261
}
262
263
// Needs to be called from the GPU thread, so on the same thread as a notification is fine.
264
// Calling from a separate thread (e.g. UI) may fail.
265
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) {
266
// False means unsupported.
267
return false;
268
}
269
270
// Similar to GetCurrentFramebuffer().
271
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
272
return false;
273
}
274
275
// Similar to GetCurrentFramebuffer().
276
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
277
return false;
278
}
279
280
// Similar to GetCurrentFramebuffer(), with texture level specification.
281
virtual bool GetCurrentTexture(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) {
282
return false;
283
}
284
285
virtual bool GetCurrentClut(GPUDebugBuffer &buffer) {
286
return false;
287
}
288
289
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) {
290
return false;
291
}
292
};
293
294
bool GPUDebugInitExpression(GPUDebugInterface *g, const char *str, PostfixExpression &exp);
295
bool GPUDebugExecExpression(GPUDebugInterface *g, PostfixExpression &exp, uint32_t &result);
296
bool GPUDebugExecExpression(GPUDebugInterface *g, const char *str, uint32_t &result);
297
298