diff options
-rw-r--r-- | intern/ghost/intern/GHOST_XrGraphicsBinding.cpp | 40 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 12 |
4 files changed, 50 insertions, 10 deletions
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp index 973f1b30b09..aa230bf8deb 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp @@ -70,16 +70,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); @@ -151,11 +161,18 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override { std::vector<int64_t> 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, @@ -291,14 +308,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); @@ -327,14 +354,15 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override { std::vector<int64_t> 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, diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index b4b92acbb56..440f74af64b 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1750,6 +1750,8 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, GPUOffScreen *ofs, GPUViewport *viewport) { + const bool is_xr_surface = ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0); + /* Create temporary viewport if needed or update the existing viewport. */ GPUViewport *render_viewport = viewport; if (viewport == NULL) { @@ -1759,7 +1761,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, drw_notify_view_update_offscreen(depsgraph, engine_type, region, v3d, render_viewport); } - GPU_viewport_bind_from_offscreen(render_viewport, ofs); + GPU_viewport_bind_from_offscreen(render_viewport, ofs, is_xr_surface); /* Just here to avoid an assert but shouldn't be required in practice. */ GPU_framebuffer_restore(); diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index daf817adbe8..be989635f84 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -63,7 +63,9 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport, /** * Should be called from DRW after DRW_opengl_context_enable. */ -void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs); +void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, + struct GPUOffScreen *ofs, + bool is_xr_surface); /** * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`. */ diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index d910153e912..fd4a87bc544 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -183,7 +183,9 @@ void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect) viewport->active_view = view; } -void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) +void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, + struct GPUOffScreen *ofs, + bool is_xr_surface) { GPUTexture *color, *depth; GPUFrameBuffer *fb; @@ -192,7 +194,13 @@ void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth); - gpu_viewport_textures_free(viewport); + /* XR surfaces will already check for texture size changes and free if necessary (see + * #wm_xr_session_surface_offscreen_ensure()), so don't free here as it has a significant + * performance impact (leads to texture re-creation in #gpu_viewport_textures_create() every VR + * drawing iteration).*/ + if (!is_xr_surface) { + gpu_viewport_textures_free(viewport); + } /* This is the only texture we can share. */ viewport->depth_tx = depth; |