#include "XCEngine/RHI/OpenGL/OpenGLFence.h" #include namespace XCEngine { namespace RHI { OpenGLFence::OpenGLFence() : m_sync(nullptr) , m_fenceValue(0) , m_completedValue(0) , m_signaled(false) { } OpenGLFence::~OpenGLFence() { Shutdown(); } bool OpenGLFence::Initialize(bool signaled) { m_fenceValue = signaled ? 1 : 0; m_completedValue = m_fenceValue; m_signaled = signaled; return true; } void OpenGLFence::Shutdown() { if (m_sync) { glDeleteSync(static_cast(m_sync)); m_sync = nullptr; } } void OpenGLFence::Signal() { glFlush(); m_fenceValue++; m_signaled = true; } void OpenGLFence::Signal(uint64_t value) { glFlush(); m_fenceValue = value; m_completedValue = value; m_signaled = true; if (m_sync) { glDeleteSync(static_cast(m_sync)); } m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } void OpenGLFence::Wait(uint64_t timeoutNs) { if (m_signaled && m_sync) { GLsync sync = static_cast(m_sync); glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); } glFinish(); m_completedValue = m_fenceValue; m_signaled = true; } void OpenGLFence::Reset() { if (m_sync) { glDeleteSync(static_cast(m_sync)); m_sync = nullptr; } m_signaled = false; } bool OpenGLFence::IsSignaled() const { return m_signaled; } FenceStatus OpenGLFence::GetStatus() const { if (!m_sync) { return m_signaled ? FenceStatus::Signaled : FenceStatus::Unsignaled; } GLsync sync = static_cast(m_sync); GLint status = 0; glGetSynciv(sync, GL_SYNC_STATUS, sizeof(status), nullptr, &status); if (status == GL_SIGNALED) { return FenceStatus::Signaled; } return FenceStatus::Unsignaled; } uint64_t OpenGLFence::GetCompletedValue() const { return m_completedValue; } void* OpenGLFence::GetNativeHandle() { if (!m_sync) { m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } return m_sync; } } // namespace RHI } // namespace XCEngine