From 5e62d828d7f341006551dec272572a7be77e07d5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 11 Feb 2019 17:39:08 +0000 Subject: [PATCH] Add support for EGL_EXT/KHR_swap_buffers_with_damage --- renderdoc/driver/gl/egl_dispatch_table.h | 24 ++++--- renderdoc/driver/gl/egl_hooks.cpp | 88 ++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 14 deletions(-) diff --git a/renderdoc/driver/gl/egl_dispatch_table.h b/renderdoc/driver/gl/egl_dispatch_table.h index dbae60619..d0fe3906c 100644 --- a/renderdoc/driver/gl/egl_dispatch_table.h +++ b/renderdoc/driver/gl/egl_dispatch_table.h @@ -57,17 +57,21 @@ typedef EGLBoolean(EGLAPIENTRY *PFN_eglGetConfigAttrib)(EGLDisplay dpy, EGLConfi EGLint attribute, EGLint *value); typedef const char *(EGLAPIENTRY *PFN_eglQueryString)(EGLDisplay dpy, EGLint name); typedef PFNEGLPOSTSUBBUFFERNVPROC PFN_eglPostSubBufferNV; +typedef PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC PFN_eglSwapBuffersWithDamageEXT; +typedef PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC PFN_eglSwapBuffersWithDamageKHR; -#define EGL_HOOKED_SYMBOLS(FUNC) \ - FUNC(BindAPI, false); \ - FUNC(GetProcAddress, false); \ - FUNC(GetDisplay, false); \ - FUNC(CreateContext, false); \ - FUNC(DestroyContext, false); \ - FUNC(CreateWindowSurface, false); \ - FUNC(MakeCurrent, false); \ - FUNC(SwapBuffers, false); \ - FUNC(PostSubBufferNV, true); +#define EGL_HOOKED_SYMBOLS(FUNC) \ + FUNC(BindAPI, false); \ + FUNC(GetProcAddress, false); \ + FUNC(GetDisplay, false); \ + FUNC(CreateContext, false); \ + FUNC(DestroyContext, false); \ + FUNC(CreateWindowSurface, false); \ + FUNC(MakeCurrent, false); \ + FUNC(SwapBuffers, false); \ + FUNC(PostSubBufferNV, true); \ + FUNC(SwapBuffersWithDamageEXT, true); \ + FUNC(SwapBuffersWithDamageKHR, true); #define EGL_NONHOOKED_SYMBOLS(FUNC) \ FUNC(ChooseConfig, false); \ diff --git a/renderdoc/driver/gl/egl_hooks.cpp b/renderdoc/driver/gl/egl_hooks.cpp index 8803c18d7..8d61fa99f 100644 --- a/renderdoc/driver/gl/egl_hooks.cpp +++ b/renderdoc/driver/gl/egl_hooks.cpp @@ -56,6 +56,10 @@ public: std::map configs; std::map windows; + // indicates we're in a swap function, so don't process the swap any further if we recurse - could + // happen due to driver implementation of one function calling another + bool swapping = false; + bool IsYFlipped(EGLDisplay dpy, EGLSurface surface) { const char *extString = EGL.QueryString(dpy, EGL_EXTENSIONS); @@ -367,7 +371,7 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers_renderdoc_hooked(EGLDisplay dp SCOPED_LOCK(glLock); eglhook.driver.SetDriverType(eglhook.activeAPI); - if(!eglhook.driver.UsesVRFrameMarkers()) + if(!eglhook.driver.UsesVRFrameMarkers() && !eglhook.swapping) { GLWindowingData data; data.egl_dpy = dpy; @@ -379,7 +383,12 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers_renderdoc_hooked(EGLDisplay dp eglhook.driver.SwapBuffers(surface); } - return EGL.SwapBuffers(dpy, surface); + { + eglhook.swapping = true; + EGLBoolean ret = EGL.SwapBuffers(dpy, surface); + eglhook.swapping = false; + return ret; + } } HOOK_EXPORT EGLBoolean EGLAPIENTRY eglPostSubBufferNV_renderdoc_hooked(EGLDisplay dpy, @@ -398,10 +407,69 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglPostSubBufferNV_renderdoc_hooked(EGLDispla SCOPED_LOCK(glLock); eglhook.driver.SetDriverType(eglhook.activeAPI); - if(!eglhook.driver.UsesVRFrameMarkers()) + if(!eglhook.driver.UsesVRFrameMarkers() && !eglhook.swapping) eglhook.driver.SwapBuffers((void *)eglhook.windows[surface]); - return EGL.PostSubBufferNV(dpy, surface, x, y, width, height); + { + eglhook.swapping = true; + EGLBoolean ret = EGL.PostSubBufferNV(dpy, surface, x, y, width, height); + eglhook.swapping = false; + return ret; + } +} + +HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT_renderdoc_hooked(EGLDisplay dpy, + EGLSurface surface, + EGLint *rects, + EGLint n_rects) +{ + if(RenderDoc::Inst().IsReplayApp()) + { + if(!EGL.SwapBuffersWithDamageEXT) + EGL.PopulateForReplay(); + + return EGL.SwapBuffersWithDamageEXT(dpy, surface, rects, n_rects); + } + + SCOPED_LOCK(glLock); + + eglhook.driver.SetDriverType(eglhook.activeAPI); + if(!eglhook.driver.UsesVRFrameMarkers() && !eglhook.swapping) + eglhook.driver.SwapBuffers((void *)eglhook.windows[surface]); + + { + eglhook.swapping = true; + EGLBoolean ret = EGL.SwapBuffersWithDamageEXT(dpy, surface, rects, n_rects); + eglhook.swapping = false; + return ret; + } +} + +HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR_renderdoc_hooked(EGLDisplay dpy, + EGLSurface surface, + EGLint *rects, + EGLint n_rects) +{ + if(RenderDoc::Inst().IsReplayApp()) + { + if(!EGL.SwapBuffersWithDamageKHR) + EGL.PopulateForReplay(); + + return EGL.SwapBuffersWithDamageKHR(dpy, surface, rects, n_rects); + } + + SCOPED_LOCK(glLock); + + eglhook.driver.SetDriverType(eglhook.activeAPI); + if(!eglhook.driver.UsesVRFrameMarkers() && !eglhook.swapping) + eglhook.driver.SwapBuffers((void *)eglhook.windows[surface]); + + { + eglhook.swapping = true; + EGLBoolean ret = EGL.SwapBuffersWithDamageKHR(dpy, surface, rects, n_rects); + eglhook.swapping = false; + return ret; + } } HOOK_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY @@ -491,6 +559,18 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy, EGLSurface return eglPostSubBufferNV_renderdoc_hooked(dpy, surface, x, y, width, height); } +HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, + EGLint *rects, EGLint n_rects) +{ + return eglSwapBuffersWithDamageEXT_renderdoc_hooked(dpy, surface, rects, n_rects); +} + +HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, + EGLint *rects, EGLint n_rects) +{ + return eglSwapBuffersWithDamageKHR_renderdoc_hooked(dpy, surface, rects, n_rects); +} + HOOK_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *func) { return eglGetProcAddress_renderdoc_hooked(func);