Merge pull request #65800 from dsnopek/xr-resize-viewport-3
Fix XR rendering in 'opengl3' driver and expose true size via the Viewport node
This commit is contained in:
commit
95df3e7c88
@ -795,11 +795,20 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
|
|||||||
stretch_transform = p_stretch_transform;
|
stretch_transform = p_stretch_transform;
|
||||||
to_screen_rect = p_to_screen_rect;
|
to_screen_rect = p_to_screen_rect;
|
||||||
|
|
||||||
|
#ifndef _3D_DISABLED
|
||||||
|
if (!use_xr) {
|
||||||
|
#endif
|
||||||
|
|
||||||
if (p_allocated) {
|
if (p_allocated) {
|
||||||
RS::get_singleton()->viewport_set_size(viewport, size.width, size.height);
|
RS::get_singleton()->viewport_set_size(viewport, size.width, size.height);
|
||||||
} else {
|
} else {
|
||||||
RS::get_singleton()->viewport_set_size(viewport, 0, 0);
|
RS::get_singleton()->viewport_set_size(viewport, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _3D_DISABLED
|
||||||
|
} // if (!use_xr)
|
||||||
|
#endif
|
||||||
|
|
||||||
_update_global_transform();
|
_update_global_transform();
|
||||||
update_configuration_warnings();
|
update_configuration_warnings();
|
||||||
|
|
||||||
@ -813,6 +822,19 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Size2i Viewport::_get_size() const {
|
Size2i Viewport::_get_size() const {
|
||||||
|
#ifndef _3D_DISABLED
|
||||||
|
if (use_xr) {
|
||||||
|
if (XRServer::get_singleton() != nullptr) {
|
||||||
|
Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
|
||||||
|
if (xr_interface.is_valid() && xr_interface->is_initialized()) {
|
||||||
|
Size2 xr_size = xr_interface->get_render_target_size();
|
||||||
|
return (Size2i)xr_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Size2i();
|
||||||
|
}
|
||||||
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3612,9 +3634,20 @@ void Viewport::_propagate_exit_world_3d(Node *p_node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::set_use_xr(bool p_use_xr) {
|
void Viewport::set_use_xr(bool p_use_xr) {
|
||||||
|
if (use_xr != p_use_xr) {
|
||||||
use_xr = p_use_xr;
|
use_xr = p_use_xr;
|
||||||
|
|
||||||
RS::get_singleton()->viewport_set_use_xr(viewport, use_xr);
|
RS::get_singleton()->viewport_set_use_xr(viewport, use_xr);
|
||||||
|
|
||||||
|
if (!use_xr) {
|
||||||
|
// Set viewport to previous size when exiting XR.
|
||||||
|
if (size_allocated) {
|
||||||
|
RS::get_singleton()->viewport_set_size(viewport, size.width, size.height);
|
||||||
|
} else {
|
||||||
|
RS::get_singleton()->viewport_set_size(viewport, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Viewport::is_using_xr() {
|
bool Viewport::is_using_xr() {
|
||||||
|
@ -179,7 +179,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
|
|||||||
// to compensate for the loss of sharpness.
|
// to compensate for the loss of sharpness.
|
||||||
const float texture_mipmap_bias = log2f(MIN(scaling_3d_scale, 1.0)) + p_viewport->texture_mipmap_bias;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,14 +616,7 @@ void RendererViewport::draw_viewports() {
|
|||||||
if (xr_interface.is_valid()) {
|
if (xr_interface.is_valid()) {
|
||||||
// Override our size, make sure it matches our required size and is created as a stereo target
|
// 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();
|
Size2 xr_size = xr_interface->get_render_target_size();
|
||||||
|
_viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count());
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Inform xr interface we're about to render its viewport, if this returns false we don't render
|
// 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);
|
visible = xr_interface->pre_draw_viewport(vp->render_target);
|
||||||
@ -686,6 +679,10 @@ void RendererViewport::draw_viewports() {
|
|||||||
// commit our eyes
|
// commit our eyes
|
||||||
Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
|
Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
|
||||||
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && blits.size() > 0) {
|
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && blits.size() > 0) {
|
||||||
|
if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") {
|
||||||
|
RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size());
|
||||||
|
RSG::rasterizer->end_frame(true);
|
||||||
|
} else {
|
||||||
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
|
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
|
||||||
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
|
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
|
||||||
}
|
}
|
||||||
@ -694,6 +691,7 @@ void RendererViewport::draw_viewports() {
|
|||||||
blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
|
blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
|
RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
|
||||||
|
|
||||||
@ -777,7 +775,13 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewport->use_xr = p_use_xr;
|
viewport->use_xr = p_use_xr;
|
||||||
|
|
||||||
|
// 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);
|
_configure_3d_render_buffers(viewport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererViewport::viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode) {
|
void RendererViewport::viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode) {
|
||||||
@ -823,34 +827,27 @@ void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_sca
|
|||||||
_configure_3d_render_buffers(viewport);
|
_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) {
|
void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
|
||||||
ERR_FAIL_COND(p_width < 0 && p_height < 0);
|
ERR_FAIL_COND(p_width < 0 && p_height < 0);
|
||||||
|
|
||||||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||||
ERR_FAIL_COND(!viewport);
|
ERR_FAIL_COND(!viewport);
|
||||||
|
ERR_FAIL_COND_MSG(viewport->use_xr, "Cannot set viewport size when using XR");
|
||||||
|
|
||||||
viewport->size = Size2(p_width, p_height);
|
_viewport_set_size(viewport, p_width, p_height, 1);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t view_count = viewport->get_view_count();
|
void RendererViewport::_viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count) {
|
||||||
RSG::texture_storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
|
Size2i new_size(p_width, p_height);
|
||||||
_configure_3d_render_buffers(viewport);
|
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) {
|
void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
|
||||||
@ -890,7 +887,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
|
// 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
|
// instead of rendering to fbo and copying to system_fbo after
|
||||||
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
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);
|
RSG::texture_storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,7 +897,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 render_direct_to_screen was used, reset size and position
|
||||||
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
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_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();
|
viewport->viewport_to_screen_rect = Rect2();
|
||||||
@ -919,7 +916,7 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
|
|||||||
// if disabled, reset render_target size and position
|
// if disabled, reset render_target size and position
|
||||||
if (!p_enable) {
|
if (!p_enable) {
|
||||||
RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
|
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);
|
RSG::texture_storage->render_target_set_direct_to_screen(viewport->render_target, p_enable);
|
||||||
@ -927,7 +924,7 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
|
|||||||
|
|
||||||
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
|
// 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) {
|
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);
|
RSG::texture_storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
|
|
||||||
Size2i internal_size;
|
Size2i internal_size;
|
||||||
Size2i size;
|
Size2i size;
|
||||||
|
uint32_t view_count;
|
||||||
RID camera;
|
RID camera;
|
||||||
RID scenario;
|
RID scenario;
|
||||||
|
|
||||||
@ -150,6 +151,7 @@ public:
|
|||||||
RendererScene::RenderInfo render_info;
|
RendererScene::RenderInfo render_info;
|
||||||
|
|
||||||
Viewport() {
|
Viewport() {
|
||||||
|
view_count = 1;
|
||||||
update_mode = RS::VIEWPORT_UPDATE_WHEN_VISIBLE;
|
update_mode = RS::VIEWPORT_UPDATE_WHEN_VISIBLE;
|
||||||
clear_mode = RS::VIEWPORT_CLEAR_ALWAYS;
|
clear_mode = RS::VIEWPORT_CLEAR_ALWAYS;
|
||||||
transparent_bg = false;
|
transparent_bg = false;
|
||||||
@ -176,8 +178,6 @@ public:
|
|||||||
time_gpu_begin = 0;
|
time_gpu_begin = 0;
|
||||||
time_gpu_end = 0;
|
time_gpu_end = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_view_count();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HashMap<String, RID> timestamp_vp_map;
|
HashMap<String, RID> timestamp_vp_map;
|
||||||
@ -196,6 +196,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<Viewport *> _sort_active_viewports();
|
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 _configure_3d_render_buffers(Viewport *p_viewport);
|
||||||
void _draw_3d(Viewport *p_viewport);
|
void _draw_3d(Viewport *p_viewport);
|
||||||
void _draw_viewport(Viewport *p_viewport);
|
void _draw_viewport(Viewport *p_viewport);
|
||||||
|
Loading…
Reference in New Issue
Block a user