From 4fbd00e04c00735fdcc135c588b884fbb9b71efc Mon Sep 17 00:00:00 2001 From: Peter Kim Date: Fri, 11 Feb 2022 20:38:22 +0900 Subject: Fix T94268: Closing SteamVR and restarting VR Session crashes Blender Crash was caused since the function pointers `s_xrGetOpenGLGraphicsRequirementsKHR_fn`/ `s_xrGetD3D11GraphicsRequirementsKHR_fn` were static and were not updated with the correct proc address after being set the first time. As stated in the OpenXR spec: "function pointers returned by xrGetInstanceProcAddr using one XrInstance may not be valid when used with objects related to a different XrInstance". Although it would seem reasonable that the proc address would not change if the instance was the same (hence the `static XrInstance s_instance;`), in testing, repeated calls to `xrGetInstanceProcAddress()` with the same instance still can result in changes (at least for the SteamVR runtime) so the workaround is to simply set the function pointers every time, essentially trivializing their `static` designations. Reviewed By: Severin Maniphest Tasks: T94268 Differential Revision: https://developer.blender.org/D14023 --- intern/ghost/intern/GHOST_XrGraphicsBinding.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'intern/ghost') diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp index 936b973c97e..6eaf55afacd 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp @@ -84,16 +84,26 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { #endif static PFN_xrGetOpenGLGraphicsRequirementsKHR s_xrGetOpenGLGraphicsRequirementsKHR_fn = nullptr; + // static XrInstance s_instance = XR_NULL_HANDLE; XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR}; const XrVersion gl_version = XR_MAKE_VERSION( ctx_gl.m_contextMajorVersion, ctx_gl.m_contextMinorVersion, 0); + /* Although it would seem reasonable that the proc address would not change if the instance was + * the same, in testing, repeated calls to #xrGetInstanceProcAddress() with the same instance + * can still result in changes so the workaround is to simply set the function pointer every + * time (trivializing its 'static' designation). */ + // if (instance != s_instance) { + // s_instance = instance; + s_xrGetOpenGLGraphicsRequirementsKHR_fn = nullptr; + //} if (!s_xrGetOpenGLGraphicsRequirementsKHR_fn && XR_FAILED(xrGetInstanceProcAddr( instance, "xrGetOpenGLGraphicsRequirementsKHR", (PFN_xrVoidFunction *)&s_xrGetOpenGLGraphicsRequirementsKHR_fn))) { s_xrGetOpenGLGraphicsRequirementsKHR_fn = nullptr; + return false; } s_xrGetOpenGLGraphicsRequirementsKHR_fn(instance, system_id, &gpu_requirements); @@ -305,14 +315,24 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding { std::string *r_requirement_info) const override { static PFN_xrGetD3D11GraphicsRequirementsKHR s_xrGetD3D11GraphicsRequirementsKHR_fn = nullptr; + // static XrInstance s_instance = XR_NULL_HANDLE; XrGraphicsRequirementsD3D11KHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR}; + /* Although it would seem reasonable that the proc address would not change if the instance was + * the same, in testing, repeated calls to #xrGetInstanceProcAddress() with the same instance + * can still result in changes so the workaround is to simply set the function pointer every + * time (trivializing its 'static' designation). */ + // if (instance != s_instance) { + // s_instance = instance; + s_xrGetD3D11GraphicsRequirementsKHR_fn = nullptr; + //} if (!s_xrGetD3D11GraphicsRequirementsKHR_fn && XR_FAILED(xrGetInstanceProcAddr( instance, "xrGetD3D11GraphicsRequirementsKHR", (PFN_xrVoidFunction *)&s_xrGetD3D11GraphicsRequirementsKHR_fn))) { s_xrGetD3D11GraphicsRequirementsKHR_fn = nullptr; + return false; } s_xrGetD3D11GraphicsRequirementsKHR_fn(instance, system_id, &gpu_requirements); -- cgit v1.2.3 From 2cad80cbc4775447152a631bbfcabbf8d642e833 Mon Sep 17 00:00:00 2001 From: Peter Kim Date: Fri, 11 Feb 2022 20:42:30 +0900 Subject: Fix incompatible swapchain format for Quest 2 When using a RGBA16 (`GL_RGBA16`, `DXGI_FORMAT_R16G16B16A16_UNORM`) swapchain format with Quest 2, no image is presented to the headset. This can occur when using the SteamVR runtime with an AMD graphics card (ex. T95374). Workaround is to move this format after the Quest 2-compatible RGBA16F formats in the candidates list so that the RGBA16F formats are chosen instead. Reviewed By: Severin Differential Revision: https://developer.blender.org/D14024 --- intern/ghost/intern/GHOST_XrGraphicsBinding.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'intern/ghost') diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp index 6eaf55afacd..c6d513f0ac5 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp @@ -175,11 +175,18 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override { std::vector gpu_binding_formats = { +#if 0 /* RGB10A2, RGBA16 don't seem to work with Oculus head-sets, \ + * so move them after RGBA16F for the time being. */ GL_RGB10_A2, GL_RGBA16, - GL_RGBA16F, - GL_RGBA8, - GL_SRGB8_ALPHA8, +#endif + GL_RGBA16F, +#if 1 + GL_RGB10_A2, + GL_RGBA16, +#endif + GL_RGBA8, + GL_SRGB8_ALPHA8, }; std::optional result = choose_swapchain_format_from_candidates(gpu_binding_formats, @@ -361,14 +368,15 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override { std::vector gpu_binding_formats = { -# if 0 /* RGB10A2 doesn't seem to work with Oculus head-sets, \ - * so move it after RGB16AF for the time being. */ +# if 0 /* RGB10A2, RGBA16 don't seem to work with Oculus head-sets, \ + * so move them after RGBA16F for the time being. */ DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, # endif - DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_FLOAT, # if 1 DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, # endif DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, -- cgit v1.2.3