mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-14 18:19:36 +01:00
Some preparations
This commit is contained in:
1 parent
be833550ec
commit
b5de9e0cc3
5 files changed
+52
-5
No files matched your search
@@ -3,6 +3,21 @@
|
||||
#include "Common/GPU/OpenGL/GLRenderManager.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
void GLCachedReadback::Destroy(bool skipGLCalls) {
|
||||
if (buffer && !skipGLCalls) {
|
||||
glDeleteBuffers(1, &buffer);
|
||||
}
|
||||
buffer = 0;
|
||||
}
|
||||
|
||||
void GLFrameData::Destroy(bool skipGLCalls) {
|
||||
readbacks_.IterateMut([=](const GLReadbackKey &key, GLCachedReadback *value) {
|
||||
value->Destroy(skipGLCalls);
|
||||
delete value;
|
||||
});
|
||||
readbacks_.Clear();
|
||||
}
|
||||
|
||||
void GLDeleter::Take(GLDeleter &other) {
|
||||
_assert_msg_(IsEmpty(), "Deleter already has stuff");
|
||||
shaders = std::move(other.shaders);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "Common/GPU/OpenGL/GLCommon.h"
|
||||
#include "Common/Data/Collections/Hashmaps.h"
|
||||
|
||||
class GLRShader;
|
||||
class GLRBuffer;
|
||||
@@ -35,8 +36,24 @@ public:
|
||||
std::vector<GLPushBuffer *> pushBuffers;
|
||||
};
|
||||
|
||||
// TODO: To be safe, should probably add some more stuff here, like format and even readback count, maybe.
|
||||
struct GLReadbackKey {
|
||||
const GLRFramebuffer *framebuf;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct GLCachedReadback {
|
||||
GLuint buffer; // PBO
|
||||
size_t bufferSize;
|
||||
|
||||
void Destroy(bool skipGLCalls);
|
||||
};
|
||||
|
||||
// Per-frame data, round-robin so we can overlap submission with execution of the previous frame.
|
||||
struct GLFrameData {
|
||||
GLFrameData() : readbacks_(8) {}
|
||||
|
||||
bool skipSwap = false;
|
||||
|
||||
std::mutex fenceMutex;
|
||||
@@ -49,4 +66,8 @@ struct GLFrameData {
|
||||
GLDeleter deleter;
|
||||
GLDeleter deleter_prev;
|
||||
std::set<GLPushBuffer *> activePushBuffers;
|
||||
|
||||
DenseHashMap<GLReadbackKey, GLCachedReadback *, nullptr> readbacks_;
|
||||
|
||||
void Destroy(bool skipGLCalls);
|
||||
};
|
||||
@@ -47,7 +47,9 @@ GLRenderManager::~GLRenderManager() {
|
||||
for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) {
|
||||
_assert_(frameData_[i].deleter.IsEmpty());
|
||||
_assert_(frameData_[i].deleter_prev.IsEmpty());
|
||||
frameData_[i].Destroy(skipGLCalls_);
|
||||
}
|
||||
|
||||
// Was anything deleted during shutdown?
|
||||
deleter_.Perform(this, skipGLCalls_);
|
||||
_assert_(deleter_.IsEmpty());
|
||||
@@ -108,6 +110,7 @@ void GLRenderManager::ThreadEnd() {
|
||||
// Since we're in shutdown, we should skip the GL calls on Android.
|
||||
frameData_[i].deleter.Perform(this, skipGLCalls_);
|
||||
frameData_[i].deleter_prev.Perform(this, skipGLCalls_);
|
||||
frameData_[i].Destroy(skipGLCalls_);
|
||||
}
|
||||
deleter_.Perform(this, skipGLCalls_);
|
||||
for (int i = 0; i < (int)steps_.size(); i++) {
|
||||
@@ -292,6 +295,8 @@ void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR
|
||||
bool GLRenderManager::CopyFramebufferToMemory(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, Draw::ReadbackMode mode, const char *tag) {
|
||||
_assert_(pixels);
|
||||
|
||||
curRenderStep_ = nullptr;
|
||||
|
||||
GLRStep *step = new GLRStep{ GLRStepType::READBACK };
|
||||
step->readback.src = src;
|
||||
step->readback.srcRect = { x, y, w, h };
|
||||
@@ -301,8 +306,9 @@ bool GLRenderManager::CopyFramebufferToMemory(GLRFramebuffer *src, int aspectBit
|
||||
step->tag = tag;
|
||||
steps_.push_back(step);
|
||||
|
||||
curRenderStep_ = nullptr;
|
||||
FlushSync();
|
||||
if (mode == Draw::ReadbackMode::BLOCK) {
|
||||
FlushSync();
|
||||
}
|
||||
|
||||
Draw::DataFormat srcFormat;
|
||||
if (aspectBits & GL_COLOR_BUFFER_BIT) {
|
||||
@@ -316,13 +322,17 @@ bool GLRenderManager::CopyFramebufferToMemory(GLRFramebuffer *src, int aspectBit
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
queueRunner_.CopyFromReadbackBuffer(src, w, h, srcFormat, destFormat, pixelStride, pixels);
|
||||
|
||||
queueRunner_.CopyFromReadbackBuffer(mode == Draw::ReadbackMode::OLD_DATA_OK ? src : nullptr, w, h, srcFormat, destFormat, pixelStride, pixels);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) {
|
||||
_assert_(texture);
|
||||
_assert_(pixels);
|
||||
|
||||
curRenderStep_ = nullptr;
|
||||
|
||||
GLRStep *step = new GLRStep{ GLRStepType::READBACK_IMAGE };
|
||||
step->readback_image.texture = texture;
|
||||
step->readback_image.mipLevel = mipLevel;
|
||||
@@ -330,7 +340,6 @@ void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, i
|
||||
step->tag = tag;
|
||||
steps_.push_back(step);
|
||||
|
||||
curRenderStep_ = nullptr;
|
||||
FlushSync();
|
||||
|
||||
queueRunner_.CopyFromReadbackBuffer(nullptr, w, h, Draw::DataFormat::R8G8B8A8_UNORM, destFormat, pixelStride, pixels);
|
||||
|
||||
@@ -28,6 +28,7 @@ struct QueueProfileContext {
|
||||
|
||||
class VKRFramebuffer;
|
||||
|
||||
// TODO: To be safe, should probably add some more stuff here, like format and even readback count, maybe.
|
||||
struct ReadbackKey {
|
||||
const VKRFramebuffer *framebuf;
|
||||
int width;
|
||||
|
||||
+2
-1
@@ -581,9 +581,10 @@ struct DeviceCaps {
|
||||
bool multiViewSupported;
|
||||
bool isTilingGPU; // This means that it benefits from correct store-ops, msaa without backing memory, etc.
|
||||
bool sampleRateShadingSupported;
|
||||
|
||||
bool verySlowShaderCompiler;
|
||||
|
||||
bool pboSupported; // Only makes sense in OpenGL.
|
||||
|
||||
// From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it.
|
||||
bool supportsD3D9;
|
||||
|
||||
|
||||
Reference in new issue
Block a user