From 3a988400a702ede4137ee3f6d885796c03d727ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 30 Jan 2018 13:32:10 +0100 Subject: [PATCH] Simpler way to deal with the GL deleter --- ext/native/thin3d/GLQueueRunner.cpp | 47 +++++++++++++++++++++++++-- ext/native/thin3d/GLQueueRunner.h | 2 -- ext/native/thin3d/GLRenderManager.cpp | 13 +++----- ext/native/thin3d/GLRenderManager.h | 21 ++++++------ 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 333ebd6d74..9fd394c8be 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -424,9 +424,52 @@ void GLQueueRunner::RunSteps(const std::vector &steps) { } void GLQueueRunner::LogSteps(const std::vector &steps) { - + for (int i = 0; i < steps.size(); i++) { + const GLRStep &step = *steps[i]; + switch (step.stepType) { + case GLRStepType::RENDER: + LogRenderPass(step); + break; + case GLRStepType::COPY: + LogCopy(step); + break; + case GLRStepType::BLIT: + LogBlit(step); + break; + case GLRStepType::READBACK: + LogReadback(step); + break; + case GLRStepType::READBACK_IMAGE: + LogReadbackImage(step); + break; + default: + Crash(); + break; + } + delete steps[i]; + } } +// TODO: Improve these. +void GLQueueRunner::LogRenderPass(const GLRStep &pass) { + ILOG("RenderPass (%d commands)", (int)pass.commands.size()); +} + +void GLQueueRunner::LogCopy(const GLRStep &pass) { + ILOG("Copy"); +} + +void GLQueueRunner::LogBlit(const GLRStep &pass) { + ILOG("Blit"); +} + +void GLQueueRunner::LogReadback(const GLRStep &pass) { + ILOG("Readback"); +} + +void GLQueueRunner::LogReadbackImage(const GLRStep &pass) { + ILOG("ReadbackImage"); +} void GLQueueRunner::PerformBlit(const GLRStep &step) { // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing @@ -990,7 +1033,7 @@ void GLQueueRunner::PerformReadback(const GLRStep &pass) { const GLuint format = GL_RGBA; const GLuint type = GL_UNSIGNED_BYTE; const int srcAlignment = 4; - int dstAlignment = DataFormatSizeInBytes(pass.readback.dstFormat); + int dstAlignment = (int)DataFormatSizeInBytes(pass.readback.dstFormat); int pixelStride = pass.readback.srcRect.w; // Apply the correct alignment. diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index c5ff40c832..8d50e0ca44 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -355,8 +355,6 @@ private: void LogReadback(const GLRStep &pass); void LogReadbackImage(const GLRStep &pass); - void ResizeReadbackBuffer(size_t requiredSize); - void fbo_ext_create(const GLRInitStep &step); void fbo_bind_fb_target(bool read, GLuint name); GLenum fbo_get_fb_target(bool read, GLuint **cached); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 2792e76d1a..abd267aee1 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -13,7 +13,6 @@ #endif void GLDeleter::Perform() { - deleterMutex_.lock(); for (auto shader : shaders) { delete shader; } @@ -38,7 +37,6 @@ void GLDeleter::Perform() { delete framebuffer; } framebuffers.clear(); - deleterMutex_.unlock(); } GLRenderManager::GLRenderManager() { @@ -357,8 +355,6 @@ void GLRenderManager::Finish() { frameData.pull_condVar.notify_all(); } - frameData_[curFrame_].deleter.Take(deleter_); - curFrame_++; if (curFrame_ >= MAX_INFLIGHT_FRAMES) curFrame_ = 0; @@ -380,10 +376,6 @@ void GLRenderManager::Submit(int frame, bool triggerFence) { // When !triggerFence, we notify after syncing with Vulkan. - // Putting deletes here is safe but only because OpenGL has its own delete handling.. - // ideally we'd like to wait a frame or two. - frameData.deleter.Perform(); - if (useThread_ && triggerFence) { VLOG("PULL: Frame %d.readyForFence = true", frame); @@ -414,6 +406,10 @@ void GLRenderManager::Run(int frame) { BeginSubmitFrame(frame); FrameData &frameData = frameData_[frame]; + + // Delete stuff from the last round. + frameData.deleter_prev.Perform(); + auto &stepsOnThread = frameData_[frame].steps; auto &initStepsOnThread = frameData_[frame].initSteps; // queueRunner_.LogSteps(stepsOnThread); @@ -424,6 +420,7 @@ void GLRenderManager::Run(int frame) { switch (frameData.type) { case GLRRunType::END: + frameData.deleter_prev.Take(frameData.deleter); EndSubmitFrame(frame); break; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 6bd2d7caf1..239ff0f3c0 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -148,12 +148,12 @@ enum class GLRRunType { SYNC, }; +// Synchronize this externally if needed, no mutex anymore. class GLDeleter { public: void Perform(); void Take(GLDeleter &other) { - deleterMutex_.lock(); _assert_msg_(G3D, shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty(), "Deleter already has stuff"); shaders = std::move(other.shaders); programs = std::move(other.programs); @@ -167,7 +167,6 @@ public: other.textures.clear(); other.inputLayouts.clear(); other.framebuffers.clear(); - deleterMutex_.unlock(); } std::vector shaders; @@ -176,7 +175,6 @@ public: std::vector textures; std::vector inputLayouts; std::vector framebuffers; - std::mutex deleterMutex_; }; class GLRInputLayout { @@ -291,22 +289,22 @@ public: } void DeleteShader(GLRShader *shader) { - deleter_.shaders.push_back(shader); + frameData_[curFrame_].deleter.shaders.push_back(shader); } void DeleteProgram(GLRProgram *program) { - deleter_.programs.push_back(program); + frameData_[curFrame_].deleter.programs.push_back(program); } void DeleteBuffer(GLRBuffer *buffer) { - deleter_.buffers.push_back(buffer); + frameData_[curFrame_].deleter.buffers.push_back(buffer); } void DeleteTexture(GLRTexture *texture) { - deleter_.textures.push_back(texture); + frameData_[curFrame_].deleter.textures.push_back(texture); } void DeleteInputLayout(GLRInputLayout *inputLayout) { - deleter_.inputLayouts.push_back(inputLayout); + frameData_[curFrame_].deleter.inputLayouts.push_back(inputLayout); } void DeleteFramebuffer(GLRFramebuffer *framebuffer) { - deleter_.framebuffers.push_back(framebuffer); + frameData_[curFrame_].deleter.framebuffers.push_back(framebuffer); } void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil); @@ -696,7 +694,10 @@ private: bool hasBegun = false; uint32_t curSwapchainImage = -1; + std::mutex deleter_mutex; GLDeleter deleter; + GLDeleter deleter_prev; + std::set activePushBuffers; }; @@ -721,8 +722,6 @@ private: bool nextFrame = false; bool firstFrame = true; - GLDeleter deleter_; - bool useThread_ = true; int curFrame_ = 0;