OpenGL: Prefer glClientWaitSync for OGLSync objects

At least on Nvidia, glClientWaitSync with a timeout of 0 (non-blocking) is faster than glGetSynciv of GL_SYNC_STATUS.
This commit is contained in:
ameerj 2023-03-07 22:33:11 -05:00
parent 6d61430311
commit 03137086db
5 changed files with 16 additions and 10 deletions

View File

@ -27,9 +27,7 @@ bool GLInnerFence::IsSignaled() const {
return true; return true;
} }
ASSERT(sync_object.handle != 0); ASSERT(sync_object.handle != 0);
GLint sync_status; return sync_object.IsSignaled();
glGetSynciv(sync_object.handle, GL_SYNC_STATUS, 1, nullptr, &sync_status);
return sync_status == GL_SIGNALED;
} }
void GLInnerFence::Wait() { void GLInnerFence::Wait() {

View File

@ -621,10 +621,7 @@ bool GraphicsPipeline::IsBuilt() noexcept {
if (built_fence.handle == 0) { if (built_fence.handle == 0) {
return false; return false;
} }
// Timeout of zero means this is non-blocking is_built = built_fence.IsSignaled();
const auto sync_status = glClientWaitSync(built_fence.handle, 0, 0);
ASSERT(sync_status != GL_WAIT_FAILED);
is_built = sync_status != GL_TIMEOUT_EXPIRED;
return is_built; return is_built;
} }

View File

@ -3,6 +3,7 @@
#include <string_view> #include <string_view>
#include <glad/glad.h> #include <glad/glad.h>
#include "common/assert.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_shader_util.h"
@ -158,6 +159,15 @@ void OGLSync::Release() {
handle = 0; handle = 0;
} }
bool OGLSync::IsSignaled() const noexcept {
// At least on Nvidia, glClientWaitSync with a timeout of 0
// is faster than glGetSynciv of GL_SYNC_STATUS.
// Timeout of 0 means this check is non-blocking.
const auto sync_status = glClientWaitSync(handle, 0, 0);
ASSERT(sync_status != GL_WAIT_FAILED);
return sync_status != GL_TIMEOUT_EXPIRED;
}
void OGLFramebuffer::Create() { void OGLFramebuffer::Create() {
if (handle != 0) if (handle != 0)
return; return;

View File

@ -263,6 +263,9 @@ public:
/// Deletes the internal OpenGL resource /// Deletes the internal OpenGL resource
void Release(); void Release();
/// Checks if the sync has been signaled
bool IsSignaled() const noexcept;
GLsync handle = 0; GLsync handle = 0;
}; };

View File

@ -714,9 +714,7 @@ std::optional<size_t> TextureCacheRuntime::StagingBuffers::FindBuffer(size_t req
continue; continue;
} }
if (syncs[index].handle != 0) { if (syncs[index].handle != 0) {
GLint status; if (!syncs[index].IsSignaled()) {
glGetSynciv(syncs[index].handle, GL_SYNC_STATUS, 1, nullptr, &status);
if (status != GL_SIGNALED) {
continue; continue;
} }
syncs[index].Release(); syncs[index].Release();