Move GLFrameData out of GLRenderManager.

Small refactor to prepare for adding delayed readback support to the
OpenGL backend.
This commit is contained in:
Henrik Rydgård 2023-02-06 10:46:52 +01:00
parent 86a5a82050
commit d502198aa3
10 changed files with 147 additions and 112 deletions

View file

@ -632,6 +632,8 @@ add_library(Common STATIC
Common/GPU/OpenGL/gl3stub.h
Common/GPU/OpenGL/GLFeatures.cpp
Common/GPU/OpenGL/GLFeatures.h
Common/GPU/OpenGL/GLFrameData.cpp
Common/GPU/OpenGL/GLFrameData.h
Common/GPU/OpenGL/thin3d_gl.cpp
Common/GPU/OpenGL/GLRenderManager.cpp
Common/GPU/OpenGL/GLRenderManager.h

View file

@ -436,6 +436,7 @@
<ClInclude Include="GPU\OpenGL\DataFormatGL.h" />
<ClInclude Include="GPU\OpenGL\gl3stub.h" />
<ClInclude Include="GPU\OpenGL\GLFeatures.h" />
<ClInclude Include="GPU\OpenGL\GLFrameData.h" />
<ClInclude Include="GPU\OpenGL\GLQueueRunner.h" />
<ClInclude Include="GPU\OpenGL\GLRenderManager.h" />
<ClInclude Include="GPU\OpenGL\GLSLProgram.h" />
@ -871,6 +872,7 @@
<ClCompile Include="GPU\OpenGL\DataFormatGL.cpp" />
<ClCompile Include="GPU\OpenGL\gl3stub.c" />
<ClCompile Include="GPU\OpenGL\GLFeatures.cpp" />
<ClCompile Include="GPU\OpenGL\GLFrameData.cpp" />
<ClCompile Include="GPU\OpenGL\GLQueueRunner.cpp" />
<ClCompile Include="GPU\OpenGL\GLRenderManager.cpp" />
<ClCompile Include="GPU\OpenGL\GLSLProgram.cpp" />

View file

@ -464,6 +464,9 @@
<ClInclude Include="UI\PopupScreens.h">
<Filter>UI</Filter>
</ClInclude>
<ClInclude Include="GPU\OpenGL\GLFrameData.h">
<Filter>GPU\OpenGL</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ABI.cpp" />
@ -878,6 +881,9 @@
<ClCompile Include="UI\PopupScreens.cpp">
<Filter>UI</Filter>
</ClCompile>
<ClCompile Include="GPU\OpenGL\GLFrameData.cpp">
<Filter>GPU\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Crypto">

View file

@ -0,0 +1,75 @@
#include "Common/GPU/OpenGL/GLCommon.h"
#include "Common/GPU/OpenGL/GLFrameData.h"
#include "Common/GPU/OpenGL/GLRenderManager.h"
#include "Common/Log.h"
void GLDeleter::Take(GLDeleter &other) {
_assert_msg_(IsEmpty(), "Deleter already has stuff");
shaders = std::move(other.shaders);
programs = std::move(other.programs);
buffers = std::move(other.buffers);
textures = std::move(other.textures);
inputLayouts = std::move(other.inputLayouts);
framebuffers = std::move(other.framebuffers);
pushBuffers = std::move(other.pushBuffers);
other.shaders.clear();
other.programs.clear();
other.buffers.clear();
other.textures.clear();
other.inputLayouts.clear();
other.framebuffers.clear();
other.pushBuffers.clear();
}
// Runs on the GPU thread.
void GLDeleter::Perform(GLRenderManager *renderManager, bool skipGLCalls) {
for (auto pushBuffer : pushBuffers) {
renderManager->UnregisterPushBuffer(pushBuffer);
if (skipGLCalls) {
pushBuffer->Destroy(false);
}
delete pushBuffer;
}
pushBuffers.clear();
for (auto shader : shaders) {
if (skipGLCalls)
shader->shader = 0; // prevent the glDeleteShader
delete shader;
}
shaders.clear();
for (auto program : programs) {
if (skipGLCalls)
program->program = 0; // prevent the glDeleteProgram
delete program;
}
programs.clear();
for (auto buffer : buffers) {
if (skipGLCalls)
buffer->buffer_ = 0;
delete buffer;
}
buffers.clear();
for (auto texture : textures) {
if (skipGLCalls)
texture->texture = 0;
delete texture;
}
textures.clear();
for (auto inputLayout : inputLayouts) {
// No GL objects in an inputLayout yet
delete inputLayout;
}
inputLayouts.clear();
for (auto framebuffer : framebuffers) {
if (skipGLCalls) {
framebuffer->handle = 0;
framebuffer->color_texture.texture = 0;
framebuffer->z_stencil_buffer = 0;
framebuffer->z_stencil_texture.texture = 0;
framebuffer->z_buffer = 0;
framebuffer->stencil_buffer = 0;
}
delete framebuffer;
}
framebuffers.clear();
}

View file

@ -0,0 +1,52 @@
#pragma once
#include <mutex>
#include <condition_variable>
#include <vector>
#include <set>
#include "Common/GPU/OpenGL/GLCommon.h"
class GLRShader;
class GLRBuffer;
class GLRTexture;
class GLRInputLayout;
class GLRFramebuffer;
class GLPushBuffer;
class GLRProgram;
class GLRenderManager;
class GLDeleter {
public:
void Perform(GLRenderManager *renderManager, bool skipGLCalls);
bool IsEmpty() const {
return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty() && pushBuffers.empty();
}
void Take(GLDeleter &other);
std::vector<GLRShader *> shaders;
std::vector<GLRProgram *> programs;
std::vector<GLRBuffer *> buffers;
std::vector<GLRTexture *> textures;
std::vector<GLRInputLayout *> inputLayouts;
std::vector<GLRFramebuffer *> framebuffers;
std::vector<GLPushBuffer *> pushBuffers;
};
// Per-frame data, round-robin so we can overlap submission with execution of the previous frame.
struct GLFrameData {
bool skipSwap = false;
std::mutex fenceMutex;
std::condition_variable fenceCondVar;
bool readyForFence = true;
// Swapchain.
bool hasBegun = false;
GLDeleter deleter;
GLDeleter deleter_prev;
std::set<GLPushBuffer *> activePushBuffers;
};

View file

@ -6,6 +6,7 @@
#include <unordered_map>
#include "Common/GPU/OpenGL/GLCommon.h"
#include "Common/GPU/OpenGL/GLFrameData.h"
#include "Common/GPU/DataFormat.h"
#include "Common/GPU/Shader.h"
#include "Common/GPU/thin3d.h"

View file

@ -41,77 +41,6 @@ GLRTexture::~GLRTexture() {
}
}
void GLDeleter::Take(GLDeleter &other) {
_assert_msg_(IsEmpty(), "Deleter already has stuff");
shaders = std::move(other.shaders);
programs = std::move(other.programs);
buffers = std::move(other.buffers);
textures = std::move(other.textures);
inputLayouts = std::move(other.inputLayouts);
framebuffers = std::move(other.framebuffers);
pushBuffers = std::move(other.pushBuffers);
other.shaders.clear();
other.programs.clear();
other.buffers.clear();
other.textures.clear();
other.inputLayouts.clear();
other.framebuffers.clear();
other.pushBuffers.clear();
}
// Runs on the GPU thread.
void GLDeleter::Perform(GLRenderManager *renderManager, bool skipGLCalls) {
for (auto pushBuffer : pushBuffers) {
renderManager->UnregisterPushBuffer(pushBuffer);
if (skipGLCalls) {
pushBuffer->Destroy(false);
}
delete pushBuffer;
}
pushBuffers.clear();
for (auto shader : shaders) {
if (skipGLCalls)
shader->shader = 0; // prevent the glDeleteShader
delete shader;
}
shaders.clear();
for (auto program : programs) {
if (skipGLCalls)
program->program = 0; // prevent the glDeleteProgram
delete program;
}
programs.clear();
for (auto buffer : buffers) {
if (skipGLCalls)
buffer->buffer_ = 0;
delete buffer;
}
buffers.clear();
for (auto texture : textures) {
if (skipGLCalls)
texture->texture = 0;
delete texture;
}
textures.clear();
for (auto inputLayout : inputLayouts) {
// No GL objects in an inputLayout yet
delete inputLayout;
}
inputLayouts.clear();
for (auto framebuffer : framebuffers) {
if (skipGLCalls) {
framebuffer->handle = 0;
framebuffer->color_texture.texture = 0;
framebuffer->z_stencil_buffer = 0;
framebuffer->z_stencil_texture.texture = 0;
framebuffer->z_buffer = 0;
framebuffer->stencil_buffer = 0;
}
delete framebuffer;
}
framebuffers.clear();
}
GLRenderManager::~GLRenderManager() {
_dbg_assert_(!run_);
@ -414,7 +343,7 @@ void GLRenderManager::BeginFrame() {
int curFrame = GetCurFrame();
FrameData &frameData = frameData_[curFrame];
GLFrameData &frameData = frameData_[curFrame];
{
VLOG("PUSH: BeginFrame (curFrame = %d, readyForFence = %d, time=%0.3f)", curFrame, (int)frameData.readyForFence, time_now_d());
std::unique_lock<std::mutex> lock(frameData.fenceMutex);
@ -435,7 +364,7 @@ void GLRenderManager::Finish() {
curRenderStep_ = nullptr; // EndCurRenderStep is this simple here.
int curFrame = GetCurFrame();
FrameData &frameData = frameData_[curFrame];
GLFrameData &frameData = frameData_[curFrame];
frameData_[curFrame].deleter.Take(deleter_);
@ -463,7 +392,7 @@ void GLRenderManager::Finish() {
// Render thread. Returns true if the caller should handle a swap.
bool GLRenderManager::Run(GLRRenderThreadTask &task) {
FrameData &frameData = frameData_[task.frame];
GLFrameData &frameData = frameData_[task.frame];
if (!frameData.hasBegun) {
frameData.hasBegun = true;

View file

@ -10,11 +10,12 @@
#include <queue>
#include <condition_variable>
#include "Common/GPU/OpenGL/GLCommon.h"
#include "Common/GPU/MiscTypes.h"
#include "Common/Data/Convert/SmallDataConvert.h"
#include "Common/Log.h"
#include "GLQueueRunner.h"
#include "Common/GPU/OpenGL/GLQueueRunner.h"
#include "Common/GPU/OpenGL/GLFrameData.h"
#include "Common/GPU/OpenGL/GLCommon.h"
class GLRInputLayout;
class GLPushBuffer;
@ -373,25 +374,6 @@ enum class GLRRunType {
class GLRenderManager;
class GLPushBuffer;
class GLDeleter {
public:
void Perform(GLRenderManager *renderManager, bool skipGLCalls);
bool IsEmpty() const {
return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty() && pushBuffers.empty();
}
void Take(GLDeleter &other);
std::vector<GLRShader *> shaders;
std::vector<GLRProgram *> programs;
std::vector<GLRBuffer *> buffers;
std::vector<GLRTexture *> textures;
std::vector<GLRInputLayout *> inputLayouts;
std::vector<GLRFramebuffer *> framebuffers;
std::vector<GLPushBuffer *> pushBuffers;
};
// These are enqueued from the main thread,
// and the render thread pops them off
struct GLRRenderThreadTask {
@ -1035,23 +1017,7 @@ private:
frameData_[frame].activePushBuffers.insert(buffer);
}
// Per-frame data, round-robin so we can overlap submission with execution of the previous frame.
struct FrameData {
bool skipSwap = false;
std::mutex fenceMutex;
std::condition_variable fenceCondVar;
bool readyForFence = true;
// Swapchain.
bool hasBegun = false;
GLDeleter deleter;
GLDeleter deleter_prev;
std::set<GLPushBuffer *> activePushBuffers;
};
FrameData frameData_[MAX_INFLIGHT_FRAMES];
GLFrameData frameData_[MAX_INFLIGHT_FRAMES];
// Submission time state
bool insideFrame_ = false;

View file

@ -42,6 +42,7 @@ NATIVE_FILES :=\
$(SRC)/Common/GPU/OpenGL/GLDebugLog.cpp \
$(SRC)/Common/GPU/OpenGL/GLSLProgram.cpp \
$(SRC)/Common/GPU/OpenGL/GLFeatures.cpp \
$(SRC)/Common/GPU/OpenGL/GLFrameData.cpp \
$(SRC)/Common/GPU/OpenGL/GLRenderManager.cpp \
$(SRC)/Common/GPU/OpenGL/GLQueueRunner.cpp \
$(SRC)/Common/GPU/OpenGL/DataFormatGL.cpp

View file

@ -279,6 +279,7 @@ SOURCES_CXX += \
$(COMMONDIR)/GPU/OpenGL/GLDebugLog.cpp \
$(COMMONDIR)/GPU/OpenGL/GLSLProgram.cpp \
$(COMMONDIR)/GPU/OpenGL/GLFeatures.cpp \
$(COMMONDIR)/GPU/OpenGL/GLFrameData.cpp \
$(COMMONDIR)/GPU/OpenGL/GLRenderManager.cpp \
$(COMMONDIR)/GPU/OpenGL/GLQueueRunner.cpp \
$(COMMONDIR)/GPU/OpenGL/DataFormatGL.cpp \