Why is the correct solution to modify wglFlush()/wglFinish(), rather than modifying ddraw to do a full present?
I am not sure how that can be changed in ddraw at all, only in wined3d in theory as in this case ddraw correctly hits wined3d swapchain present path? It seems to me there is nothing wrong in ddraw or wined3d. The issue comes from child window rendering implementation in winex11.drv and is specific to winex11, I am not sure how and why that should be detected and worked around in d3d side?
Why do we need the full glFinish()? glXWaitForSbcOML() is in theory enough—we don't actually need to wait for the whole present to be done; we just need to wait for X11 to be aware of it, so that the following blit works, which is what I understand that our usage of glXWaitForSbcOML() does. I don't have a perfect grasp on this code, but it seems suspicious that we need the full glFinish() in wglFlush() and wglFinish() but not in wglSwapBuffers()—why can't we use the same logic as we use in the latter?
glXWaitForSbcOML() waits for sbc value change (Swap Buffer Counter, see [1]). Swap doesn't happen on glFlush / glFinish and this counter is not incremented. So for wglSwapBuffers() glXWaitForSbcOML() waits until the buffer is actually swapped (implying that preceding GL drawing is complete), which is not possible on glFlush/Finish. The fallback code (working on Nvidia) in wglSwapBuffer doesn't do neither glFlush nor glFinish, I am not immediately sure if that is and oversight or glxSwapBuffer actually does glFlush and waits for current GL drawing to backbuffer to finish (likely the latter although I don't see it in spec), but we do need to GL pipeline to complete before blitting in wglFlush if we want the latest image to appear on screen, otherwise nothing is going to wait for that (and removing that glFinish in the problematic game reintroduces the issue). 1. https://registry.khronos.org/OpenGL/extensions/OML/GLX_OML_sync_control.txt -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7094#note_91483