CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/Common/GPUDebugInterface.h
Views: 1401
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 <string>
22
23
#include "Common/Math/expression_parser.h"
24
#include "Core/MemMap.h"
25
#include "GPU/GPU.h"
26
#include "GPU/GPUInterface.h"
27
28
struct GPUDebugOp {
29
u32 pc;
30
u8 cmd;
31
u32 op;
32
std::string desc;
33
};
34
35
enum GPUDebugBufferFormat {
36
// These match GEBufferFormat.
37
GPU_DBG_FORMAT_565 = 0,
38
GPU_DBG_FORMAT_5551 = 1,
39
GPU_DBG_FORMAT_4444 = 2,
40
GPU_DBG_FORMAT_8888 = 3,
41
GPU_DBG_FORMAT_INVALID = 0xFF,
42
43
// These are reversed versions.
44
GPU_DBG_FORMAT_REVERSE_FLAG = 4,
45
GPU_DBG_FORMAT_565_REV = 4,
46
GPU_DBG_FORMAT_5551_REV = 5,
47
GPU_DBG_FORMAT_4444_REV = 6,
48
49
// 565 is just reversed, the others have B and R swapped.
50
GPU_DBG_FORMAT_565_BGRA = 0x04,
51
GPU_DBG_FORMAT_BRSWAP_FLAG = 0x08,
52
GPU_DBG_FORMAT_5551_BGRA = 0x09,
53
GPU_DBG_FORMAT_4444_BGRA = 0x0A,
54
GPU_DBG_FORMAT_8888_BGRA = 0x0B,
55
56
// These don't, they're for depth/stencil buffers.
57
GPU_DBG_FORMAT_FLOAT = 0x10,
58
GPU_DBG_FORMAT_16BIT = 0x11,
59
GPU_DBG_FORMAT_8BIT = 0x12,
60
GPU_DBG_FORMAT_24BIT_8X = 0x13,
61
GPU_DBG_FORMAT_24X_8BIT = 0x14,
62
63
GPU_DBG_FORMAT_FLOAT_DIV_256 = 0x18,
64
GPU_DBG_FORMAT_24BIT_8X_DIV_256 = 0x1B,
65
66
// This is used for screenshots, mainly.
67
GPU_DBG_FORMAT_888_RGB = 0x20,
68
};
69
70
enum GPUDebugFramebufferType {
71
// The current render target.
72
GPU_DBG_FRAMEBUF_RENDER,
73
// The current display target (not the displayed screen, though.)
74
GPU_DBG_FRAMEBUF_DISPLAY,
75
};
76
77
inline GPUDebugBufferFormat &operator |=(GPUDebugBufferFormat &lhs, const GPUDebugBufferFormat &rhs) {
78
lhs = GPUDebugBufferFormat((int)lhs | (int)rhs);
79
return lhs;
80
}
81
82
struct GPUDebugBuffer {
83
GPUDebugBuffer() {
84
}
85
86
GPUDebugBuffer(void *data, u32 stride, u32 height, GEBufferFormat fmt, bool reversed = false)
87
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
88
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
89
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
90
}
91
}
92
93
GPUDebugBuffer(void *data, u32 stride, u32 height, GETextureFormat fmt, bool reversed = false)
94
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
95
if (reversed && fmt_ < GPU_DBG_FORMAT_8888) {
96
fmt_ |= GPU_DBG_FORMAT_REVERSE_FLAG;
97
}
98
}
99
100
GPUDebugBuffer(void *data, u32 stride, u32 height, GPUDebugBufferFormat fmt)
101
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(fmt), flipped_(false) {
102
}
103
104
GPUDebugBuffer(GPUDebugBuffer &&other) noexcept {
105
alloc_ = other.alloc_;
106
data_ = other.data_;
107
height_ = other.height_;
108
stride_ = other.stride_;
109
flipped_ = other.flipped_;
110
fmt_ = other.fmt_;
111
other.alloc_ = false;
112
other.data_ = nullptr;
113
}
114
115
~GPUDebugBuffer() {
116
Free();
117
}
118
119
GPUDebugBuffer &operator = (GPUDebugBuffer &&other) noexcept {
120
if (this != &other) {
121
Free();
122
alloc_ = other.alloc_;
123
data_ = other.data_;
124
height_ = other.height_;
125
stride_ = other.stride_;
126
flipped_ = other.flipped_;
127
fmt_ = other.fmt_;
128
other.alloc_ = false;
129
other.data_ = nullptr;
130
}
131
132
return *this;
133
}
134
135
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false, bool reversed = false);
136
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false);
137
void Free();
138
139
void ZeroBytes();
140
141
u8 *GetData() {
142
return data_;
143
}
144
145
u32 GetRawPixel(int x, int y) const;
146
void SetRawPixel(int x, int y, u32 c);
147
148
const u8 *GetData() const {
149
return data_;
150
}
151
152
u32 GetHeight() const {
153
return height_;
154
}
155
156
u32 GetStride() const {
157
return stride_;
158
}
159
160
bool GetFlipped() const {
161
return flipped_;
162
}
163
164
GPUDebugBufferFormat GetFormat() const {
165
return fmt_;
166
}
167
168
u32 PixelSize() const;
169
170
private:
171
bool alloc_ = false;
172
u8 *data_ = nullptr;
173
u32 stride_ = 0;
174
u32 height_ = 0;
175
GPUDebugBufferFormat fmt_ = GPU_DBG_FORMAT_INVALID;
176
bool flipped_ = false;
177
};
178
179
struct GPUDebugVertex {
180
float u;
181
float v;
182
float x;
183
float y;
184
float z;
185
u8 c[4];
186
float nx;
187
float ny;
188
float nz;
189
};
190
191
class GPUDebugInterface {
192
public:
193
virtual ~GPUDebugInterface() {}
194
virtual bool GetCurrentDisplayList(DisplayList &list) = 0;
195
virtual std::vector<DisplayList> ActiveDisplayLists() = 0;
196
virtual void ResetListPC(int listID, u32 pc) = 0;
197
virtual void ResetListStall(int listID, u32 stall) = 0;
198
virtual void ResetListState(int listID, DisplayListState state) = 0;
199
200
GPUDebugOp DissassembleOp(u32 pc) {
201
return DissassembleOp(pc, Memory::Read_U32(pc));
202
}
203
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op) = 0;
204
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc) = 0;
205
206
// Enter/exit stepping mode. Mainly for better debug stats on time taken.
207
virtual void NotifySteppingEnter() = 0;
208
virtual void NotifySteppingExit() = 0;
209
210
virtual u32 GetRelativeAddress(u32 data) = 0;
211
virtual u32 GetVertexAddress() = 0;
212
virtual u32 GetIndexAddress() = 0;
213
virtual GPUgstate GetGState() = 0;
214
// Needs to be called from the GPU thread.
215
// Calling from a separate thread (e.g. UI) may fail.
216
virtual void SetCmdValue(u32 op) = 0;
217
virtual void DispatchFlush() = 0;
218
219
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
220
virtual uint32_t GetAddrTranslation() = 0;
221
222
virtual bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
223
return false;
224
}
225
226
// Needs to be called from the GPU thread, so on the same thread as a notification is fine.
227
// Calling from a separate thread (e.g. UI) may fail.
228
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) {
229
// False means unsupported.
230
return false;
231
}
232
233
// Similar to GetCurrentFramebuffer().
234
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
235
return false;
236
}
237
238
// Similar to GetCurrentFramebuffer().
239
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
240
return false;
241
}
242
243
// Similar to GetCurrentFramebuffer(), with texture level specification.
244
virtual bool GetCurrentTexture(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) {
245
return false;
246
}
247
248
virtual bool GetCurrentClut(GPUDebugBuffer &buffer) {
249
return false;
250
}
251
252
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) {
253
return false;
254
}
255
};
256
257
bool GPUDebugInitExpression(GPUDebugInterface *g, const char *str, PostfixExpression &exp);
258
bool GPUDebugExecExpression(GPUDebugInterface *g, PostfixExpression &exp, uint32_t &result);
259
bool GPUDebugExecExpression(GPUDebugInterface *g, const char *str, uint32_t &result);
260
261