From db59a4f9af462e14d23a752caf3069b4fcf5bd7f Mon Sep 17 00:00:00 2001 From: Emile Belanger Date: Mon, 20 Sep 2021 21:40:47 +0100 Subject: [PATCH] Add buffer synchronisation for GLES when using mapped buffers. --- src/common/rendering/gles/gles_buffers.cpp | 34 ++++++++++++++++--- src/common/rendering/gles/gles_buffers.h | 4 +++ .../rendering/gles/gles_framebuffer.cpp | 2 ++ src/common/rendering/gles/gles_system.cpp | 1 + .../rendering/hwrenderer/data/buffers.h | 2 +- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/common/rendering/gles/gles_buffers.cpp b/src/common/rendering/gles/gles_buffers.cpp index 61296f3627a..58fe0e016ac 100644 --- a/src/common/rendering/gles/gles_buffers.cpp +++ b/src/common/rendering/gles/gles_buffers.cpp @@ -232,6 +232,34 @@ void GLBuffer::Resize(size_t newsize) } } +void GLBuffer::GPUDropSync() +{ +#if !(USE_GLES2) // Only applicable when running on desktop for now + if (mGLSync != NULL) + { + glDeleteSync(mGLSync); + } + + mGLSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +#endif +} + +void GLBuffer::GPUWaitSync() +{ +#if !(USE_GLES2) // Only applicable when running on desktop for now + GLenum status = glClientWaitSync(mGLSync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 50); // Wait for a max of 50ms... + + if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) + { + //Printf("Error on glClientWaitSync: %d\n", status); + } + + glDeleteSync(mGLSync); + + mGLSync = NULL; +#endif +} + //=========================================================================== // @@ -287,16 +315,12 @@ void GLDataBuffer::BindRange(FRenderState *state, size_t start, size_t length) if (mBindingPoint == 3)// VIEWPOINT_BINDINGPOINT { static_cast(state)->ApplyViewport(memory + start); - } - else - { - //glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length); } } void GLDataBuffer::BindBase() { - //glBindBufferBase(mUseType, mBindingPoint, mBufferId); + } diff --git a/src/common/rendering/gles/gles_buffers.h b/src/common/rendering/gles/gles_buffers.h index de51ff31bf6..0bd2053512b 100644 --- a/src/common/rendering/gles/gles_buffers.h +++ b/src/common/rendering/gles/gles_buffers.h @@ -19,6 +19,7 @@ class GLBuffer : virtual public IBuffer int mAllocationSize = 0; bool mPersistent = false; bool nomap = true; + GLsync mGLSync = 0; bool isData = false; char *memory = nullptr; @@ -32,6 +33,9 @@ class GLBuffer : virtual public IBuffer void Resize(size_t newsize) override; void *Lock(unsigned int size) override; void Unlock() override; + + void GPUDropSync(); + void GPUWaitSync(); public: void Bind(); void Upload(size_t start, size_t end); diff --git a/src/common/rendering/gles/gles_framebuffer.cpp b/src/common/rendering/gles/gles_framebuffer.cpp index 658a8aebfe1..3a74ee6bc16 100644 --- a/src/common/rendering/gles/gles_framebuffer.cpp +++ b/src/common/rendering/gles/gles_framebuffer.cpp @@ -240,11 +240,13 @@ void OpenGLFrameBuffer::Swap() Finish.Reset(); Finish.Clock(); + mVertexData->DropSync(); FPSLimit(); SwapBuffers(); mVertexData->NextPipelineBuffer(); + mVertexData->WaitSync(); RenderState()->SetVertexBuffer(screen->mVertexData); // Needed for Raze because it does not reset it diff --git a/src/common/rendering/gles/gles_system.cpp b/src/common/rendering/gles/gles_system.cpp index a72e3f933c5..5ad3a157dbd 100644 --- a/src/common/rendering/gles/gles_system.cpp +++ b/src/common/rendering/gles/gles_system.cpp @@ -15,6 +15,7 @@ EXTERN_CVAR(Bool, gl_customshader); PFNGLMAPBUFFERRANGEEXTPROC glMapBufferRange = NULL; PFNGLUNMAPBUFFEROESPROC glUnmapBuffer = NULL; + #ifdef __ANDROID__ #include diff --git a/src/common/rendering/hwrenderer/data/buffers.h b/src/common/rendering/hwrenderer/data/buffers.h index 7f4402c1c3f..586e5caa02c 100644 --- a/src/common/rendering/hwrenderer/data/buffers.h +++ b/src/common/rendering/hwrenderer/data/buffers.h @@ -6,7 +6,7 @@ class FRenderState; #ifdef __ANDROID__ -#define HW_MAX_PIPELINE_BUFFERS 8 +#define HW_MAX_PIPELINE_BUFFERS 4 #define HW_BLOCK_SSBO 1 #else // On desktop this is only useful fpr letting the GPU run in parallel with the playsim and for that 2 buffers are enough.