diff options
| author | Mike <contact@mikelittman.me> | 2026-10-14 00:03:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-14 13:03:37 +0800 |
| commit | 9cc783022a202a1d00b5dc8eaf01ffddbc9fa39f (patch) | |
| tree | 9a5b23fb63c2e09d1815d913272f7a17f96750e4 /indra/llrender | |
| parent | 1b7d456077ba61c987fc06561e30127a1cc18968 (diff) | |
Stop Apple OpenGL from waiting on a null fence (#34)
glFinish and glWaitSync both crash in GLDFenceRec::getStatus when the
fence record is null. On Apple, flush texture uploads instead and do
not call glFinish before deleting buffers.
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 52 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 7 |
2 files changed, 34 insertions, 25 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 82bc00fe7a..b01c81fc28 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1855,31 +1855,41 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) // post a sync to the main thread (will execute before tex name swap lambda below) // glFlush calls here are partly superstitious and partly backed by observation // on AMD hardware - glFlush(); - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - if (sync) + if (gGLManager.mIsApple) { - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() - { - LL_PROFILE_ZONE_NAMED("cglt - wait sync"); - { - LL_PROFILE_ZONE_NAMED("glWaitSync"); - glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - } - { - LL_PROFILE_ZONE_NAMED("glDeleteSync"); - glDeleteSync(sync); - } - }); + // Apple's GL/Metal translator faults in GLDFenceRec::getStatus + // (null fence, address 0x24) while executing glWaitSync. + // glFenceSync and glFinish both enqueue that wait. Flush the + // upload onto the serial OpenGL queue and let the main thread + // issue later commands behind it. + glFlush(); } else { - // glFenceSync failed. glWaitSync(0) is dispatched to Apple's - // OpenGL thread, which faults in GLDFenceRec::getStatus. - glFinish(); + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + if (sync) + { + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); + } + else + { + glFinish(); + } } } } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a827927809..6a885d2a09 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -317,14 +317,13 @@ static void delete_buffers(S32 count, GLuint* buffers) { if (gGLManager.mIsApple) { - // Apple's GL/Metal translator crashes in GLDFenceRec::getStatus - // (null fence, fault at +0x24) when glDeleteBuffers waits on a - // sync that was never created. Unbind and finish first. + // Unbind, then delete one name at a time. Do not glFinish(): + // that drains a queued glWaitSync and faults in + // GLDFenceRec::getStatus when Apple's fence record is null. glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); LLVertexBuffer::sGLRenderBuffer = 0; LLVertexBuffer::sGLRenderIndices = 0; - glFinish(); for (GLuint name : sFreeList[idx]) { if (name) |
