Some preparations

This commit is contained in:
Henrik Rydgård committed 2023-02-16 23:17:08 +01:00
1 parent be833550ec
commit b5de9e0cc3
5 files changed
+52 -5

No files matched your search

+15
View File
@@ -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);
+21
View File
@@ -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);
};
+13 -4
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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;