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/FramebufferManagerCommon.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
// TODO: We now have the tools in thin3d to nearly eliminate the backend-specific framebuffer managers.
19
// Here's a list of functionality to unify into FramebufferManagerCommon:
20
// * DrawActiveTexture
21
// * BlitFramebuffer
22
//
23
// Also, in TextureCache we should be able to unify texture-based depal.
24
25
#pragma once
26
27
#include <vector>
28
#include <unordered_map>
29
30
#include "Common/CommonTypes.h"
31
#include "Common/Log.h"
32
#include "Common/GPU/thin3d.h"
33
#include "Core/ConfigValues.h"
34
#include "GPU/GPU.h"
35
#include "GPU/ge_constants.h"
36
#include "GPU/GPUInterface.h"
37
#include "GPU/Common/Draw2D.h"
38
39
enum {
40
FB_USAGE_DISPLAYED_FRAMEBUFFER = 1,
41
FB_USAGE_RENDER_COLOR = 2,
42
FB_USAGE_TEXTURE = 4,
43
FB_USAGE_CLUT = 8,
44
FB_USAGE_DOWNLOAD = 16,
45
FB_USAGE_DOWNLOAD_CLEAR = 32,
46
FB_USAGE_BLUE_TO_ALPHA = 64,
47
FB_USAGE_FIRST_FRAME_SAVED = 128,
48
FB_USAGE_RENDER_DEPTH = 256,
49
FB_USAGE_COLOR_MIXED_DEPTH = 512,
50
FB_USAGE_INVALIDATE_DEPTH = 1024, // used to clear depth buffers.
51
};
52
53
enum {
54
FB_NON_BUFFERED_MODE = 0,
55
FB_BUFFERED_MODE = 1,
56
};
57
58
namespace Draw {
59
class Framebuffer;
60
}
61
62
class VulkanFBO;
63
class ShaderWriter;
64
65
// We have to track VFBs and depth buffers together, since bits are shared between the color alpha channel
66
// and the stencil buffer on the PSP.
67
// Sometimes, virtual framebuffers need to share a Z buffer. We emulate this by copying from on to the next
68
// when such a situation is detected. In order to reliably detect this, we separately track depth buffers,
69
// and they know which color buffer they were used with last.
70
// Two VirtualFramebuffer can occupy the same address range as long as they have different fb_format.
71
// In that case, the one with the highest colorBindSeq number is the valid one.
72
struct VirtualFramebuffer {
73
u32 fb_address;
74
u32 z_address; // If 0, it's a "RAM" framebuffer.
75
u16 fb_stride;
76
u16 z_stride;
77
78
// The original PSP format of the framebuffer.
79
// In reality they are all RGBA8888 for better quality but this is what the PSP thinks it is. This is necessary
80
// when we need to interpret the bits directly (depal or buffer aliasing).
81
// NOTE: CANNOT be changed after creation anymore!
82
GEBufferFormat fb_format;
83
84
Draw::Framebuffer *fbo;
85
86
// width/height: The detected size of the current framebuffer, in original PSP pixels.
87
u16 width;
88
u16 height;
89
90
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than or equal to width/height.
91
// In original PSP pixels - actual framebuffer is this size times the render resolution multiplier.
92
// The buffer may be used to render a width or height from 0 to these values without being recreated.
93
u16 bufferWidth;
94
u16 bufferHeight;
95
96
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
97
// These are simply bufferWidth/Height * renderScaleFactor and are thus redundant.
98
u16 renderWidth;
99
u16 renderHeight;
100
101
// Attempt to keep track of a bounding rectangle of what's been actually drawn. Coarse, but might be smaller
102
// than width/height if framebuffer has been enlarged. In PSP pixels.
103
u16 drawnWidth;
104
u16 drawnHeight;
105
106
// The dimensions at which we are confident that we can read back this buffer without stomping on irrelevant memory.
107
u16 safeWidth;
108
u16 safeHeight;
109
110
// The scale factor at which we are rendering (to achieve higher resolution).
111
u8 renderScaleFactor;
112
113
u16 usageFlags;
114
115
// These are used to track state to try to avoid buffer size shifting back and forth.
116
// You might think that doesn't happen since we mostly grow framebuffers, but we do resize down,
117
// if the size has shrunk for a while and the framebuffer is also larger than the stride.
118
// At this point, the "safe" size is probably a lie, and we have had various issues with readbacks, so this resizes down to avoid them.
119
// An example would be a game that always uses the address 0x00154000 for temp buffers, and uses it for a full-screen effect for 3 frames, then goes back to using it for character shadows or something much smaller.
120
u16 newWidth;
121
u16 newHeight;
122
123
// The frame number at which this was last resized.
124
int lastFrameNewSize;
125
126
// Tracking for downloads-to-CLUT.
127
u16 clutUpdatedBytes;
128
129
// Means that the whole image has already been read back to memory - used when combining small readbacks (gameUsesSequentialCopies_).
130
bool memoryUpdated;
131
132
// TODO: Fold into usageFlags?
133
bool dirtyAfterDisplay;
134
bool reallyDirtyAfterDisplay; // takes frame skipping into account
135
136
// Global sequence numbers for the last time these were bound.
137
// Not based on frames at all. Can be used to determine new-ness of one framebuffer over another,
138
// can even be within a frame.
139
int colorBindSeq;
140
int depthBindSeq;
141
142
// These are mainly used for garbage collection purposes and similar.
143
// Cannot be used to determine new-ness against a similar other buffer, since they are
144
// only at frame granularity.
145
int last_frame_used;
146
int last_frame_attached;
147
int last_frame_render;
148
int last_frame_displayed;
149
int last_frame_clut;
150
int last_frame_failed;
151
int last_frame_depth_updated;
152
int last_frame_depth_render;
153
154
// Convenience methods
155
inline int WidthInBytes() const { return width * BufferFormatBytesPerPixel(fb_format); }
156
inline int BufferWidthInBytes() const { return bufferWidth * BufferFormatBytesPerPixel(fb_format); }
157
inline int FbStrideInBytes() const { return fb_stride * BufferFormatBytesPerPixel(fb_format); }
158
inline int ZStrideInBytes() const { return z_stride * 2; }
159
160
inline int Stride(RasterChannel channel) const { return channel == RASTER_COLOR ? fb_stride : z_stride; }
161
inline u32 Address(RasterChannel channel) const { return channel == RASTER_COLOR ? fb_address : z_address; }
162
inline GEBufferFormat Format(RasterChannel channel) const { return channel == RASTER_COLOR ? fb_format : GE_FORMAT_DEPTH16; }
163
inline int BindSeq(RasterChannel channel) const { return channel == RASTER_COLOR ? colorBindSeq : depthBindSeq; }
164
165
// Computed from stride.
166
int BufferByteSize(RasterChannel channel) const { return BufferByteStride(channel) * height; }
167
int BufferByteStride(RasterChannel channel) const {
168
return channel == RASTER_COLOR ? fb_stride * (fb_format == GE_FORMAT_8888 ? 4 : 2) : z_stride * 2;
169
}
170
int BufferByteWidth(RasterChannel channel) const {
171
return channel == RASTER_COLOR ? width * (fb_format == GE_FORMAT_8888 ? 4 : 2) : width * 2;
172
}
173
};
174
175
struct FramebufferHeuristicParams {
176
u32 fb_address;
177
u32 z_address;
178
u16 fb_stride;
179
u16 z_stride;
180
GEBufferFormat fb_format;
181
bool isClearingDepth;
182
bool isWritingDepth;
183
bool isDrawing;
184
bool isModeThrough;
185
bool isBlending;
186
int viewportWidth;
187
int viewportHeight;
188
int16_t regionWidth;
189
int16_t regionHeight;
190
int16_t scissorLeft;
191
int16_t scissorTop;
192
int16_t scissorRight;
193
int16_t scissorBottom;
194
};
195
196
struct GPUgstate;
197
extern GPUgstate gstate;
198
199
void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPUgstate &gstate);
200
201
enum BindFramebufferColorFlags {
202
BINDFBCOLOR_SKIP_COPY = 0,
203
BINDFBCOLOR_MAY_COPY = 1,
204
BINDFBCOLOR_MAY_COPY_WITH_UV = 3, // includes BINDFBCOLOR_MAY_COPY
205
BINDFBCOLOR_APPLY_TEX_OFFSET = 4,
206
// Used when rendering to a temporary surface (e.g. not the current render target.)
207
BINDFBCOLOR_FORCE_SELF = 8,
208
BINDFBCOLOR_UNCACHED = 16,
209
};
210
211
enum DrawTextureFlags {
212
DRAWTEX_NEAREST = 0,
213
DRAWTEX_LINEAR = 1,
214
DRAWTEX_TO_BACKBUFFER = 8,
215
DRAWTEX_DEPTH = 16,
216
};
217
218
inline DrawTextureFlags operator | (const DrawTextureFlags &lhs, const DrawTextureFlags &rhs) {
219
return DrawTextureFlags((u32)lhs | (u32)rhs);
220
}
221
222
enum class TempFBO {
223
DEPAL,
224
BLIT,
225
// For copies of framebuffers (e.g. shader blending.)
226
COPY,
227
// Used for copies when setting color to depth.
228
Z_COPY,
229
// Used to copy stencil data, means we need a stencil backing.
230
STENCIL,
231
};
232
233
inline Draw::DataFormat GEFormatToThin3D(GEBufferFormat geFormat) {
234
switch (geFormat) {
235
case GE_FORMAT_4444:
236
return Draw::DataFormat::A4R4G4B4_UNORM_PACK16;
237
case GE_FORMAT_5551:
238
return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
239
case GE_FORMAT_565:
240
return Draw::DataFormat::R5G6B5_UNORM_PACK16;
241
case GE_FORMAT_8888:
242
return Draw::DataFormat::R8G8B8A8_UNORM;
243
case GE_FORMAT_DEPTH16:
244
return Draw::DataFormat::D16;
245
default:
246
// TODO: Assert?
247
return Draw::DataFormat::UNDEFINED;
248
}
249
}
250
251
// Dimensions are in bytes, later steps get to convert back into real coordinates as appropriate.
252
// Makes it easy to see if blits match etc.
253
struct BlockTransferRect {
254
VirtualFramebuffer *vfb;
255
RasterChannel channel; // We usually only deal with color, but we have limited depth block transfer support now.
256
257
int x_bytes;
258
int y;
259
int w_bytes;
260
int h;
261
262
std::string ToString() const;
263
264
int w_pixels() const {
265
return w_bytes / BufferFormatBytesPerPixel(vfb->fb_format);
266
}
267
int x_pixels() const {
268
return x_bytes / BufferFormatBytesPerPixel(vfb->fb_format);
269
}
270
};
271
272
namespace Draw {
273
class DrawContext;
274
}
275
276
struct DrawPixelsEntry {
277
Draw::Texture *tex;
278
uint64_t contentsHash;
279
int frameNumber;
280
};
281
282
struct GPUDebugBuffer;
283
class DrawEngineCommon;
284
class PresentationCommon;
285
class ShaderManagerCommon;
286
class TextureCacheCommon;
287
288
class FramebufferManagerCommon {
289
public:
290
FramebufferManagerCommon(Draw::DrawContext *draw);
291
virtual ~FramebufferManagerCommon();
292
293
void SetTextureCache(TextureCacheCommon *tc) {
294
textureCache_ = tc;
295
}
296
void SetShaderManager(ShaderManagerCommon * sm) {
297
shaderManager_ = sm;
298
}
299
void SetDrawEngine(DrawEngineCommon *td) {
300
drawEngine_ = td;
301
}
302
303
void Init(int msaaLevel);
304
virtual void BeginFrame();
305
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format);
306
void DestroyFramebuf(VirtualFramebuffer *v);
307
308
VirtualFramebuffer *DoSetRenderFrameBuffer(FramebufferHeuristicParams &params, u32 skipDrawReason);
309
VirtualFramebuffer *SetRenderFrameBuffer(bool framebufChanged, int skipDrawReason) {
310
// Inlining this part since it's so frequent.
311
if (!framebufChanged && currentRenderVfb_) {
312
currentRenderVfb_->last_frame_render = gpuStats.numFlips;
313
currentRenderVfb_->dirtyAfterDisplay = true;
314
if (!skipDrawReason)
315
currentRenderVfb_->reallyDirtyAfterDisplay = true;
316
return currentRenderVfb_;
317
} else {
318
// This is so that we will be able to drive DoSetRenderFramebuffer with inputs
319
// that come from elsewhere than gstate.
320
FramebufferHeuristicParams inputs;
321
GetFramebufferHeuristicInputs(&inputs, gstate);
322
VirtualFramebuffer *vfb = DoSetRenderFrameBuffer(inputs, skipDrawReason);
323
_dbg_assert_msg_(vfb, "DoSetRenderFramebuffer must return a valid framebuffer.");
324
_dbg_assert_msg_(currentRenderVfb_, "DoSetRenderFramebuffer must set a valid framebuffer.");
325
return vfb;
326
}
327
}
328
void SetDepthFrameBuffer(bool isClearingDepth);
329
330
void RebindFramebuffer(const char *tag);
331
std::vector<const VirtualFramebuffer *> GetFramebufferList() const;
332
333
void CopyDisplayToOutput(bool reallyDirty);
334
335
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, GPUCopyFlag flags, u32 skipDrawReason);
336
void PerformWriteFormattedFromMemory(u32 addr, int size, int width, GEBufferFormat fmt);
337
void UpdateFromMemory(u32 addr, int size);
338
void ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 clearColor);
339
bool PerformWriteStencilFromMemory(u32 addr, int size, WriteStencil flags);
340
341
// We changed our depth mode, gotta start over.
342
// Ideally, we should convert depth buffers here, not just clear them.
343
void ClearAllDepthBuffers();
344
345
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
346
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
347
// read framebuffers is on, in which case this should always return false).
348
// If this returns false, a memory copy will happen and NotifyBlockTransferAfter will be called.
349
bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason);
350
351
// This gets called after the memory copy, in case NotifyBlockTransferBefore returned false.
352
// Otherwise it doesn't get called.
353
void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason);
354
355
bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags, int layer);
356
void ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel, Draw::ReadbackMode mode);
357
358
void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes);
359
void DrawFramebufferToOutput(const u8 *srcPixels, int srcStride, GEBufferFormat srcPixelFormat);
360
361
void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, RasterChannel channel, const char *tag);
362
363
size_t NumVFBs() const { return vfbs_.size(); }
364
365
u32 PrevDisplayFramebufAddr() const {
366
return prevDisplayFramebuf_ ? prevDisplayFramebuf_->fb_address : 0;
367
}
368
u32 CurrentDisplayFramebufAddr() const {
369
return displayFramebuf_ ? displayFramebuf_->fb_address : 0;
370
}
371
372
u32 DisplayFramebufAddr() const {
373
return displayFramebufPtr_;
374
}
375
u32 DisplayFramebufStride() const {
376
return displayStride_;
377
}
378
GEBufferFormat DisplayFramebufFormat() const {
379
return displayFormat_;
380
}
381
382
bool UseBufferedRendering() const {
383
return useBufferedRendering_;
384
}
385
386
// TODO: Maybe just include the last depth buffer address in this, too.
387
bool MayIntersectFramebufferColor(u32 start) const {
388
// Clear the cache/kernel bits.
389
start &= 0x3FFFFFFF;
390
if (Memory::IsVRAMAddress(start))
391
start &= 0x041FFFFF;
392
// Most games only have two framebuffers at the start.
393
if (start >= framebufColorRangeEnd_ || start < PSP_GetVidMemBase()) {
394
return false;
395
}
396
return true;
397
}
398
399
VirtualFramebuffer *GetCurrentRenderVFB() const {
400
return currentRenderVfb_;
401
}
402
403
// This only checks for the color channel, and if there are multiple overlapping ones
404
// with different color depth, this might get things wrong.
405
// DEPRECATED FOR NEW USES - avoid whenever possible.
406
VirtualFramebuffer *GetVFBAt(u32 addr) const;
407
408
// This will only return exact matches of addr+stride+format.
409
VirtualFramebuffer *GetExactVFB(u32 addr, int stride, GEBufferFormat format) const;
410
411
// If this doesn't find the exact VFB, but one with a different color format with matching stride,
412
// it'll resolve the newest one at address to the format requested, and return that.
413
VirtualFramebuffer *ResolveVFB(u32 addr, int stride, GEBufferFormat format);
414
415
// Utility to get the display VFB.
416
VirtualFramebuffer *GetDisplayVFB();
417
418
int GetRenderWidth() const { return currentRenderVfb_ ? currentRenderVfb_->renderWidth : 480; }
419
int GetRenderHeight() const { return currentRenderVfb_ ? currentRenderVfb_->renderHeight : 272; }
420
int GetTargetWidth() const { return currentRenderVfb_ ? currentRenderVfb_->width : 480; }
421
int GetTargetHeight() const { return currentRenderVfb_ ? currentRenderVfb_->height : 272; }
422
int GetTargetBufferWidth() const { return currentRenderVfb_ ? currentRenderVfb_->bufferWidth : 480; }
423
int GetTargetBufferHeight() const { return currentRenderVfb_ ? currentRenderVfb_->bufferHeight : 272; }
424
int GetTargetStride() const { return currentRenderVfb_ ? currentRenderVfb_->fb_stride : 512; }
425
GEBufferFormat GetTargetFormat() const { return currentRenderVfb_ ? currentRenderVfb_->fb_format : displayFormat_; }
426
427
void SetColorUpdated(int skipDrawReason) {
428
if (currentRenderVfb_) {
429
SetColorUpdated(currentRenderVfb_, skipDrawReason);
430
}
431
}
432
void SetSafeSize(u16 w, u16 h);
433
434
void NotifyRenderResized(int msaaLevel);
435
virtual void NotifyDisplayResized();
436
void NotifyConfigChanged();
437
438
void CheckPostShaders();
439
440
virtual void DestroyAllFBOs();
441
442
virtual void DeviceLost();
443
virtual void DeviceRestore(Draw::DrawContext *draw);
444
445
Draw::Framebuffer *GetTempFBO(TempFBO reason, u16 w, u16 h);
446
447
// Debug features
448
virtual bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes);
449
virtual bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer);
450
virtual bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer);
451
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
452
453
const std::vector<VirtualFramebuffer *> &Framebuffers() const {
454
return vfbs_;
455
}
456
457
Draw2D *GetDraw2D() {
458
return &draw2D_;
459
}
460
461
// If a vfb with the target format exists, resolve it (run CopyToColorFromOverlappingFramebuffers).
462
// If it doesn't exist, create it and do the same.
463
// Returns the resolved framebuffer.
464
VirtualFramebuffer *ResolveFramebufferColorToFormat(VirtualFramebuffer *vfb, GEBufferFormat newFormat);
465
466
Draw2DPipeline *Get2DPipeline(Draw2DShader shader);
467
468
// If from==to, returns a copy pipeline.
469
Draw2DPipeline *GetReinterpretPipeline(GEBufferFormat from, GEBufferFormat to, float *scaleFactorX);
470
471
// Public to be used from the texture cache's depal shenanigans.
472
void BlitUsingRaster(
473
Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2,
474
Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2,
475
bool linearFilter,
476
int scaleFactor, // usually unused, except for swizzle...
477
Draw2DPipeline *pipeline, const char *tag);
478
479
void ReleasePipelines();
480
481
int GetMSAALevel() const {
482
return msaaLevel_;
483
}
484
485
void DiscardFramebufferCopy() {
486
currentFramebufferCopy_ = nullptr;
487
}
488
489
bool PresentedThisFrame() const;
490
491
protected:
492
virtual void ReadbackFramebuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel, Draw::ReadbackMode mode);
493
// Used for when a shader is required, such as GLES.
494
virtual bool ReadbackDepthbuffer(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint16_t *pixels, int pixelsStride, int destW, int destH, Draw::ReadbackMode mode);
495
virtual bool ReadbackStencilbuffer(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint8_t *pixels, int pixelsStride, Draw::ReadbackMode mode);
496
void SetViewport2D(int x, int y, int w, int h);
497
Draw::Texture *MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height);
498
void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags);
499
500
void CopyToColorFromOverlappingFramebuffers(VirtualFramebuffer *dest);
501
void CopyToDepthFromOverlappingFramebuffers(VirtualFramebuffer *dest);
502
503
bool UpdateRenderSize(int msaaLevel);
504
505
void FlushBeforeCopy();
506
virtual void DecimateFBOs(); // keeping it virtual to let D3D do a little extra
507
508
// Used by ReadFramebufferToMemory and later framebuffer block copies
509
void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, RasterChannel channel, const char *tag);
510
511
void CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags, int layer, bool *partial);
512
513
void EstimateDrawingSize(u32 fb_address, int fb_stride, GEBufferFormat fb_format, int viewport_width, int viewport_height, int region_width, int region_height, int scissor_width, int scissor_height, int &drawing_width, int &drawing_height);
514
515
void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb);
516
static void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb);
517
void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth);
518
519
void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool allowSizeMismatch = false);
520
521
void ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force = false, bool skipCopy = false);
522
523
static bool ShouldDownloadFramebufferColor(const VirtualFramebuffer *vfb);
524
static bool ShouldDownloadFramebufferDepth(const VirtualFramebuffer *vfb);
525
void DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb);
526
527
bool FindTransferFramebuffer(u32 basePtr, int stride, int x, int y, int w, int h, int bpp, bool destination, BlockTransferRect *rect);
528
529
VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb, RasterChannel channel);
530
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {}
531
532
VirtualFramebuffer *CreateRAMFramebuffer(uint32_t fbAddress, int width, int height, int stride, GEBufferFormat format);
533
534
void UpdateFramebufUsage(VirtualFramebuffer *vfb) const;
535
536
int GetFramebufferLayers() const;
537
538
static void SetColorUpdated(VirtualFramebuffer *dstBuffer, int skipDrawReason) {
539
dstBuffer->memoryUpdated = false;
540
dstBuffer->clutUpdatedBytes = 0;
541
dstBuffer->dirtyAfterDisplay = true;
542
dstBuffer->drawnWidth = dstBuffer->width;
543
dstBuffer->drawnHeight = dstBuffer->height;
544
if ((skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
545
dstBuffer->reallyDirtyAfterDisplay = true;
546
}
547
548
inline int GetBindSeqCount() {
549
return fbBindSeqCount_++;
550
}
551
552
static SkipGPUReadbackMode GetSkipGPUReadbackMode();
553
554
PresentationCommon *presentation_ = nullptr;
555
556
Draw::DrawContext *draw_ = nullptr;
557
558
TextureCacheCommon *textureCache_ = nullptr;
559
ShaderManagerCommon *shaderManager_ = nullptr;
560
DrawEngineCommon *drawEngine_ = nullptr;
561
562
bool needBackBufferYSwap_ = false;
563
564
u32 displayFramebufPtr_ = 0;
565
u32 displayStride_ = 0;
566
GEBufferFormat displayFormat_ = GE_FORMAT_565;
567
u32 prevDisplayFramebufPtr_ = 0;
568
569
int fbBindSeqCount_ = 0;
570
571
VirtualFramebuffer *displayFramebuf_ = nullptr;
572
VirtualFramebuffer *prevDisplayFramebuf_ = nullptr;
573
VirtualFramebuffer *prevPrevDisplayFramebuf_ = nullptr;
574
int frameLastFramebufUsed_ = 0;
575
576
VirtualFramebuffer *currentRenderVfb_ = nullptr;
577
578
Draw::Framebuffer *currentFramebufferCopy_ = nullptr;
579
580
// The range of PSP memory that may contain FBOs. So we can skip iterating.
581
u32 framebufColorRangeEnd_ = 0;
582
583
bool useBufferedRendering_ = false;
584
bool postShaderIsUpscalingFilter_ = false;
585
bool postShaderIsSupersampling_ = false;
586
587
std::vector<VirtualFramebuffer *> vfbs_;
588
std::vector<VirtualFramebuffer *> bvfbs_; // blitting framebuffers (for download)
589
590
std::vector<DrawPixelsEntry> drawPixelsCache_;
591
592
bool gameUsesSequentialCopies_ = false;
593
594
// Sampled in BeginFrame/UpdateSize for safety.
595
float renderWidth_ = 0.0f;
596
float renderHeight_ = 0.0f;
597
598
int msaaLevel_ = 0;
599
int renderScaleFactor_ = 1;
600
int pixelWidth_ = 0;
601
int pixelHeight_ = 0;
602
int bloomHack_ = 0;
603
bool updatePostShaders_ = false;
604
605
Draw::DataFormat preferredPixelsFormat_ = Draw::DataFormat::R8G8B8A8_UNORM;
606
607
struct TempFBOInfo {
608
Draw::Framebuffer *fbo;
609
int last_frame_used;
610
};
611
612
std::unordered_map<u64, TempFBOInfo> tempFBOs_;
613
614
std::vector<Draw::Framebuffer *> fbosToDelete_;
615
616
// Aggressively delete unused FBOs to save gpu memory.
617
enum {
618
FBO_OLD_AGE = 5,
619
FBO_OLD_USAGE_FLAG = 15,
620
};
621
622
// Thin3D stuff for reinterpreting image data between the various 16-bit color formats.
623
// Safe, not optimal - there might be input attachment tricks, etc, but we can't use them
624
// since we don't want N different implementations.
625
Draw2DPipeline *reinterpretFromTo_[4][4]{};
626
627
// Common implementation of stencil buffer upload. Also not 100% optimal, but not performance
628
// critical either.
629
Draw::Pipeline *stencilWritePipeline_ = nullptr;
630
Draw::SamplerState *stencilWriteSampler_ = nullptr;
631
632
// Used on GLES where we can't directly readback depth or stencil, but here for simplicity.
633
Draw::Pipeline *stencilReadbackPipeline_ = nullptr;
634
Draw::SamplerState *stencilReadbackSampler_ = nullptr;
635
Draw::Pipeline *depthReadbackPipeline_ = nullptr;
636
Draw::SamplerState *depthReadbackSampler_ = nullptr;
637
638
// Draw2D pipelines
639
Draw2DPipeline *draw2DPipelineCopyColor_ = nullptr;
640
Draw2DPipeline *draw2DPipelineColorRect2Lin_ = nullptr;
641
Draw2DPipeline *draw2DPipelineCopyDepth_ = nullptr;
642
Draw2DPipeline *draw2DPipelineEncodeDepth_ = nullptr;
643
Draw2DPipeline *draw2DPipeline565ToDepth_ = nullptr;
644
Draw2DPipeline *draw2DPipeline565ToDepthDeswizzle_ = nullptr;
645
646
Draw2D draw2D_;
647
// The fragment shaders are "owned" by the pipelines since they're 1:1.
648
649
// Depth readback helper state
650
u8 *convBuf_ = nullptr;
651
u32 convBufSize_ = 0;
652
};
653
654
// Should probably live elsewhere.
655
bool GetOutputFramebuffer(Draw::DrawContext *draw, GPUDebugBuffer &buffer);
656
657