diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index c048e9bf376796..6ab98a9473f9c9 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -103,6 +103,11 @@ void RasterizerGLES3::begin_frame(double frame_step) { } void RasterizerGLES3::end_frame(bool p_swap_buffers) { + GLES3::Utilities *utils = GLES3::Utilities::get_singleton(); + utils->capture_timestamps_end(); +} + +void RasterizerGLES3::end_viewport(bool p_swap_buffers) { if (p_swap_buffers) { DisplayServer::get_singleton()->swap_buffers(); } else { @@ -352,13 +357,6 @@ RasterizerGLES3::~RasterizerGLES3() { } void RasterizerGLES3::prepare_for_blitting_render_targets() { - // This is a hack, but this function is called one time after all viewports have been updated. - // So it marks the end of the frame for all viewports - // In the OpenGL renderer we have to call end_frame for each viewport so we can swap the - // buffers for each window before proceeding to the next. - // This allows us to only increment the frame after all viewports are done. - GLES3::Utilities *utils = GLES3::Utilities::get_singleton(); - utils->capture_timestamps_end(); } void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect, uint32_t p_layer, bool p_first) { @@ -474,7 +472,7 @@ void RasterizerGLES3::set_boot_image(const Ref &p_image, const Color &p_c copy_effects->copy_to_rect(screenrect); glBindTexture(GL_TEXTURE_2D, 0); - end_frame(true); + end_viewport(true); texture_storage->texture_free(texture); } diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index b19ca0e9c9d16a..d9f436a2ec4ae0 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -93,6 +93,7 @@ class RasterizerGLES3 : public RendererCompositor { void prepare_for_blitting_render_targets(); void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount); + void end_viewport(bool p_swap_buffers); void end_frame(bool p_swap_buffers); void finalize(); diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index a9f77c9072c4f7..ba4049b4310057 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -8751,9 +8751,13 @@ void RenderingDeviceVulkan::swap_buffers() { _finalize_command_bufers(); - screen_prepared = false; // Swap buffers. - context->swap_buffers(); + if (!screen_prepared) { + context->flush(true, true, false); + } else { + screen_prepared = false; + context->swap_buffers(); + } frame = (frame + 1) % frame_count; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 7a397a170de675..2107300d643c7a 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -2367,9 +2367,11 @@ void VulkanContext::append_command_buffer(VkCommandBuffer p_command_buffer) { command_buffer_count++; } -void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { +void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending, bool p_sync) { // Ensure everything else pending is executed. - vkDeviceWaitIdle(device); + if (p_sync) { + vkDeviceWaitIdle(device); + } // Flush the pending setup buffer. @@ -2412,7 +2414,9 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { ERR_FAIL_COND(err); } - vkDeviceWaitIdle(device); + if (p_sync) { + vkDeviceWaitIdle(device); + } } Error VulkanContext::prepare_buffers() { @@ -2473,7 +2477,7 @@ Error VulkanContext::swap_buffers() { return OK; } - // print_line("swapbuffers?"); + // print_line("swap_buffers"); VkResult err; #if 0 diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 2ccfd13739055c..49290f2863eb77 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -326,8 +326,9 @@ class VulkanContext { void set_setup_buffer(VkCommandBuffer p_command_buffer); void append_command_buffer(VkCommandBuffer p_command_buffer); void resize_notify(); - void flush(bool p_flush_setup = false, bool p_flush_pending = false); + void flush(bool p_flush_setup = false, bool p_flush_pending = false, bool p_sync = true); Error prepare_buffers(); + Error flush_buffers(); Error swap_buffers(); Error initialize(); diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h index 179c41f28680df..929c661009473f 100644 --- a/servers/rendering/dummy/rasterizer_dummy.h +++ b/servers/rendering/dummy/rasterizer_dummy.h @@ -89,6 +89,8 @@ class RasterizerDummy : public RendererCompositor { void prepare_for_blitting_render_targets() override {} void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) override {} + void end_viewport(bool p_swap_buffers) override {} + void end_frame(bool p_swap_buffers) override { if (p_swap_buffers) { DisplayServer::get_singleton()->swap_buffers(); diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index ff7792741c0bab..13767a38759167 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -99,6 +99,7 @@ class RendererCompositor { virtual void prepare_for_blitting_render_targets() = 0; virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0; + virtual void end_viewport(bool p_swap_buffers) = 0; virtual void end_frame(bool p_swap_buffers) = 0; virtual void finalize() = 0; virtual uint64_t get_frame_number() const = 0; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 705fb9e8e54929..9b073821c26fe9 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -123,6 +123,7 @@ class RendererCompositorRD : public RendererCompositor { void prepare_for_blitting_render_targets(); void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount); + void end_viewport(bool p_swap_buffers) {} void end_frame(bool p_swap_buffers); void finalize(); diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 6b47c29382ad62..d184e774b129a3 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -749,7 +749,6 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) { if (blits.size() > 0) { RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size()); } - RSG::rasterizer->end_frame(true); } else if (blits.size() > 0) { if (!blit_to_screen_list.has(vp->viewport_to_screen)) { blit_to_screen_list[vp->viewport_to_screen] = Vector(); @@ -759,6 +758,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) { blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]); } } + RSG::rasterizer->end_viewport(p_swap_buffers && blits.size() > 0); } } } else { @@ -788,10 +788,10 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) { Vector blit_to_screen_vec; blit_to_screen_vec.push_back(blit); RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blit_to_screen_vec.ptr(), 1); - RSG::rasterizer->end_frame(true); } else { blit_to_screen_list[vp->viewport_to_screen].push_back(blit); } + RSG::rasterizer->end_viewport(p_swap_buffers); } } @@ -813,8 +813,8 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) { RENDER_TIMESTAMP("< Render Viewports"); - if (p_swap_buffers) { - //this needs to be called to make screen swapping more efficient + if (p_swap_buffers && !blit_to_screen_list.is_empty()) { + // This needs to be called to make screen swapping more efficient. RSG::rasterizer->prepare_for_blitting_render_targets(); for (const KeyValue> &E : blit_to_screen_list) { diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 65a6da8ac308c1..6aaae1c0e26706 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -91,10 +91,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { RSG::viewport->draw_viewports(p_swap_buffers); RSG::canvas_render->update(); - if (!OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) { - // Already called for gl_compatibility renderer. - RSG::rasterizer->end_frame(p_swap_buffers); - } + RSG::rasterizer->end_frame(p_swap_buffers); XRServer *xr_server = XRServer::get_singleton(); if (xr_server != nullptr) {