Skip to content

Commit

Permalink
[opengl3] Prevent viewport's render buffers getting out of sync with …
Browse files Browse the repository at this point in the history
…render target when resized by XR interface
  • Loading branch information
dsnopek committed Sep 8, 2022
1 parent c50febf commit 39e9a36
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 36 deletions.
59 changes: 25 additions & 34 deletions servers/rendering/renderer_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
// to compensate for the loss of sharpness.
const float texture_mipmap_bias = log2f(MIN(scaling_3d_scale, 1.0)) + p_viewport->texture_mipmap_bias;

p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count());
p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->view_count);
}
}
}
Expand Down Expand Up @@ -613,14 +613,7 @@ void RendererViewport::draw_viewports() {
if (xr_interface.is_valid()) {
// Override our size, make sure it matches our required size and is created as a stereo target
Size2 xr_size = xr_interface->get_render_target_size();

// Would have been nice if we could call viewport_set_size here,
// but alas that takes our RID and we now have our pointer,
// also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
vp->size = xr_size;
uint32_t view_count = xr_interface->get_view_count();
RSG::texture_storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
_viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count());

// Inform xr interface we're about to render its viewport, if this returns false we don't render
visible = xr_interface->pre_draw_viewport(vp->render_target);
Expand Down Expand Up @@ -767,7 +760,13 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
}

viewport->use_xr = p_use_xr;
_configure_3d_render_buffers(viewport);

// Re-configure the 3D render buffers when disabling XR. They'll get
// re-configured when enabling XR in draw_viewports().
if (!p_use_xr) {
viewport->view_count = 1;
_configure_3d_render_buffers(viewport);
}
}

void RendererViewport::viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode) {
Expand Down Expand Up @@ -813,34 +812,26 @@ void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_sca
_configure_3d_render_buffers(viewport);
}

uint32_t RendererViewport::Viewport::get_view_count() {
uint32_t view_count = 1;

if (use_xr && XRServer::get_singleton() != nullptr) {
Ref<XRInterface> xr_interface;

xr_interface = XRServer::get_singleton()->get_primary_interface();
if (xr_interface.is_valid()) {
view_count = xr_interface->get_view_count();
}
}

return view_count;
}

void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
ERR_FAIL_COND(p_width < 0 && p_height < 0);

Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);

viewport->size = Size2(p_width, p_height);
_viewport_set_size(viewport, p_width, p_height, viewport->view_count);
}

uint32_t view_count = viewport->get_view_count();
RSG::texture_storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
_configure_3d_render_buffers(viewport);
void RendererViewport::_viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count) {
Size2i new_size(p_width, p_height);
if (p_viewport->size != new_size || p_viewport->view_count != p_view_count) {
p_viewport->size = new_size;
p_viewport->view_count = p_view_count;

viewport->occlusion_buffer_dirty = true;
RSG::texture_storage->render_target_set_size(p_viewport->render_target, p_width, p_height, p_view_count);
_configure_3d_render_buffers(p_viewport);

p_viewport->occlusion_buffer_dirty = true;
}
}

void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
Expand Down Expand Up @@ -880,7 +871,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
// If using OpenGL we can optimize this operation by rendering directly to system_fbo
// instead of rendering to fbo and copying to system_fbo after
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count());
RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->view_count);
RSG::texture_storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
}

Expand All @@ -890,7 +881,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
// if render_direct_to_screen was used, reset size and position
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->view_count);
}

viewport->viewport_to_screen_rect = Rect2();
Expand All @@ -909,15 +900,15 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
// if disabled, reset render_target size and position
if (!p_enable) {
RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->view_count);
}

RSG::texture_storage->render_target_set_direct_to_screen(viewport->render_target, p_enable);
viewport->viewport_render_direct_to_screen = p_enable;

// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count());
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->view_count);
RSG::texture_storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
}
}
Expand Down
5 changes: 3 additions & 2 deletions servers/rendering/renderer_viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class RendererViewport {

Size2i internal_size;
Size2i size;
uint32_t view_count;
RID camera;
RID scenario;

Expand Down Expand Up @@ -150,6 +151,7 @@ class RendererViewport {
RendererScene::RenderInfo render_info;

Viewport() {
view_count = 1;
update_mode = RS::VIEWPORT_UPDATE_WHEN_VISIBLE;
clear_mode = RS::VIEWPORT_CLEAR_ALWAYS;
transparent_bg = false;
Expand All @@ -176,8 +178,6 @@ class RendererViewport {
time_gpu_begin = 0;
time_gpu_end = 0;
}

uint32_t get_view_count();
};

HashMap<String, RID> timestamp_vp_map;
Expand All @@ -196,6 +196,7 @@ class RendererViewport {

private:
Vector<Viewport *> _sort_active_viewports();
void _viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count);
void _configure_3d_render_buffers(Viewport *p_viewport);
void _draw_3d(Viewport *p_viewport);
void _draw_viewport(Viewport *p_viewport);
Expand Down

0 comments on commit 39e9a36

Please sign in to comment.