From aaeb2d195830fa187600e6f7e9aeeb46ed782b81 Mon Sep 17 00:00:00 2001 From: Rahul Rameshbabu Date: Wed, 18 Sep 2024 20:01:36 -0700 Subject: [PATCH] Implement X11 HW-synced swapping using glXJoinSwapGroupNV, glXBindSwapBarrierNV, and the existing traits This change is meant to be analogous to commit 634344aef504 ("From Marius Heise, "here is a patch that implements Win32 HW-synced swapping using wglJoinSwapGroupNV, wglBindSwapBarrierNV and the existing traits. It was tested with multiple ATI FirePro S400 cards.") for the X11 backend. Tested using multiple NVIDIA A5000 cards. The NVIDIA driver stack requires that the swap group join and bind calls occur on the same thread context that is doing the swap buffer operation. Signed-off-by: Rahul Rameshbabu --- include/osgViewer/api/X11/GraphicsWindowX11 | 3 ++ src/osgViewer/GraphicsWindowX11.cpp | 40 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 0af24fdb123..d1c806d55f4 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -125,6 +125,9 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub /** Set mouse cursor to a specific shape.*/ virtual void setCursor(MouseCursor cursor); + /** Set swap group. */ + virtual void setSwapGroup(bool on, GLuint group, GLuint barrier); + /** WindowData is used to pass in the X11 window handle attached the GraphicsContext::Traits structure. */ struct WindowData : public osg::Referenced { diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index f48560b28a0..c7753b39247 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -1316,6 +1316,12 @@ void GraphicsWindowX11::swapBuffersImplementation() glXWaitVideoSyncSGI(1, 0, &counter); } #endif + static bool init = false; + if (_traits.valid() && _traits->swapGroupEnabled && !init) { + setSwapGroup(_traits->swapGroupEnabled, _traits->swapGroup, _traits->swapBarrier); + init = true; + } + glXSwapBuffers( _display, _window ); #endif @@ -1767,6 +1773,40 @@ void GraphicsWindowX11::transformMouseXY(float& x, float& y) } } +#ifndef OSG_USE_EGL +void GraphicsWindowX11::setSwapGroup(bool on, GLuint group, GLuint barrier) +{ + if (_traits.valid()) + { + _traits->swapGroupEnabled = on; + _traits->swapGroup = group; + _traits->swapBarrier = barrier; + } + + typedef Bool (GL_APIENTRY *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group); + PFNGLXJOINSWAPGROUPNVPROC glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glXGetProcAddress( (GLubyte *)"glXJoinSwapGroupNV" ); + + typedef Bool (GL_APIENTRY *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier); + PFNGLXBINDSWAPBARRIERNVPROC glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glXGetProcAddress( (GLubyte *)"glXBindSwapBarrierNV" ); + + if ((!glXJoinSwapGroupNV) || (!glXBindSwapBarrierNV)) + { + OSG_INFO << "GraphicsWindowX11::setSwapGroup(bool, GLuint, GLuint) not supported" << std::endl; + return; + } + + int swapGroup = (on ? group : 0); + Bool resultJoin = glXJoinSwapGroupNV(_display, _window, swapGroup); + OSG_INFO << "GraphicsWindowX11::glXJoinSwapGroupNV (" << swapGroup + << ") returned " << resultJoin << std::endl; + + int swapBarrier = (on ? barrier : 0); + Bool resultBind = glXBindSwapBarrierNV(_display, swapGroup, swapBarrier); + OSG_INFO << "GraphicsWindowX11::glXBindSwapBarrierNV (" << swapGroup << ", " + << swapBarrier << ") returned " << resultBind << std::endl; +} +#endif + void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, int& unmodifiedKeySymbol) { unsigned char buffer_return[32];