diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1249004eda0..864987234b0 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1765,6 +1765,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) { @@ -1774,7 +1776,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 917b87efeaa..263d1d7c90f 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -79,7 +79,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 7a20278e5aa..2ed7994aee6 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -199,7 +199,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; @@ -208,7 +210,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;