diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b8ecd9255..32213160a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index c3c1ebebaf..451e8dd426 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -436,6 +436,7 @@ + @@ -871,6 +872,7 @@ + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 6dfa552f1b..3c0a310aff 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -464,6 +464,9 @@ UI + + GPU\OpenGL + @@ -878,6 +881,9 @@ UI + + GPU\OpenGL + diff --git a/Common/GPU/OpenGL/GLFrameData.cpp b/Common/GPU/OpenGL/GLFrameData.cpp new file mode 100644 index 0000000000..fa5a051d30 --- /dev/null +++ b/Common/GPU/OpenGL/GLFrameData.cpp @@ -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(); +} diff --git a/Common/GPU/OpenGL/GLFrameData.h b/Common/GPU/OpenGL/GLFrameData.h new file mode 100644 index 0000000000..a50fbe7d55 --- /dev/null +++ b/Common/GPU/OpenGL/GLFrameData.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +#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 shaders; + std::vector programs; + std::vector buffers; + std::vector textures; + std::vector inputLayouts; + std::vector framebuffers; + std::vector 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 activePushBuffers; +}; diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index b79ff6b6ae..0db0575eae 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -6,6 +6,7 @@ #include #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" diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 1c45abd7e3..b10caa2541 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -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 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; diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index fe0b42aafd..281a42353f 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -10,11 +10,12 @@ #include #include -#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 shaders; - std::vector programs; - std::vector buffers; - std::vector textures; - std::vector inputLayouts; - std::vector framebuffers; - std::vector 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 activePushBuffers; - }; - - FrameData frameData_[MAX_INFLIGHT_FRAMES]; + GLFrameData frameData_[MAX_INFLIGHT_FRAMES]; // Submission time state bool insideFrame_ = false; diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 6932d49ecf..218ce2f8ec 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -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 diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 2b62ff352d..ed11027f32 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -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 \