@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
@ -22,7 +22,8 @@ BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const
MemoryAllocator & memory_allocator_ , PresentManager & present_manager_ ,
MemoryAllocator & memory_allocator_ , PresentManager & present_manager_ ,
Scheduler & scheduler_ , const PresentFilters & filters_ )
Scheduler & scheduler_ , const PresentFilters & filters_ )
: device_memory { device_memory_ } , device { device_ } , memory_allocator { memory_allocator_ } ,
: device_memory { device_memory_ } , device { device_ } , memory_allocator { memory_allocator_ } ,
present_manager { present_manager_ } , scheduler { scheduler_ } , filters { filters_ } , image_count { 1 } ,
present_manager { present_manager_ } , scheduler { scheduler_ } , filters { filters_ } ,
image_count { 1 } , image_index { 0 } ,
swapchain_view_format { VK_FORMAT_B8G8R8A8_UNORM } { }
swapchain_view_format { VK_FORMAT_B8G8R8A8_UNORM } { }
BlitScreen : : ~ BlitScreen ( ) = default ;
BlitScreen : : ~ BlitScreen ( ) = default ;
@ -87,57 +88,49 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
bool resource_update_required = false ;
bool resource_update_required = false ;
bool presentation_recreate_required = false ;
bool presentation_recreate_required = false ;
// Recreate dynamic resources if the adapting filter changed
if ( ! window_adapt | | scaling_filter ! = filters . get_scaling_filter ( ) ) {
if ( ! window_adapt | | scaling_filter ! = filters . get_scaling_filter ( ) ) {
resource_update_required = true ;
resource_update_required = true ;
}
}
// Recreate dynamic resources if the image count changed
const size_t old_swapchain_image_count =
std : : exchange ( image_count , current_swapchain_image_count ) ;
if ( old_swapchain_image_count ! = current_swapchain_image_count ) {
if ( image_count ! = current_swapchain_image_count ) {
resource_update_required = true ;
resource_update_required = true ;
image_count = current_swapchain_image_count ;
}
}
// Recreate the presentation frame if the format or dimensions of the window changed
const VkFormat old_swapchain_view_format =
std : : exchange ( swapchain_view_format , current_swapchain_view_format ) ;
if ( old_swapchain_view_format ! = current_swapchain_view_format | |
if ( swapchain_view_format ! = current_swapchain_view_format | |
layout . width ! = frame - > width | | layout . height ! = frame - > height ) {
layout . width ! = frame - > width | | layout . height ! = frame - > height ) {
resource_update_required = true ;
resource_update_required = true ;
presentation_recreate_required = true ;
presentation_recreate_required = true ;
swapchain_view_format = current_swapchain_view_format ;
}
}
// If we have a pending resource update, perform it
if ( resource_update_required ) {
if ( resource_update_required ) {
// Wait for idle to ensure no resources are in use
WaitIdle ( ) ;
WaitIdle ( ) ;
// Update window adapt pass
SetWindowAdaptPass ( ) ;
SetWindowAdaptPass ( ) ;
// Update frame format if needed
if ( presentation_recreate_required ) {
if ( presentation_recreate_required ) {
present_manager . RecreateFrame ( frame , layout . width , layout . height , swapchain_view_format ,
present_manager . RecreateFrame ( frame , layout . width , layout . height , swapchain_view_format ,
window_adapt - > GetRenderPass ( ) ) ;
window_adapt - > GetRenderPass ( ) ) ;
}
}
image_index = 0 ;
}
}
// Add additional layers if needed
const VkExtent2D window_size {
const VkExtent2D window_size {
. width = layout . screen . GetWidth ( ) ,
. width = layout . screen . GetWidth ( ) ,
. height = layout . screen . GetHeight ( ) ,
. height = layout . screen . GetHeight ( ) ,
} ;
} ;
while ( layers . size ( ) < framebuffers . size ( ) ) {
if ( layers . size ( ) ! = framebuffers . size ( ) ) {
layers . clear ( ) ;
for ( size_t i = 0 ; i < framebuffers . size ( ) ; + + i ) {
layers . emplace_back ( device , memory_allocator , scheduler , device_memory , image_count ,
layers . emplace_back ( device , memory_allocator , scheduler , device_memory , image_count ,
window_size , window_adapt - > GetDescriptorSetLayout ( ) , filters ) ;
window_size , window_adapt - > GetDescriptorSetLayout ( ) , filters ) ;
}
}
}
// Perform the draw
window_adapt - > Draw ( rasterizer , scheduler , image_index , layers , framebuffers , layout , frame ) ;
window_adapt - > Draw ( rasterizer , scheduler , image_index , layers , framebuffers , layout , frame ) ;
// Advance to next image
if ( + + image_index > = image_count ) {
if ( + + image_index > = image_count ) {
image_index = 0 ;
image_index = 0 ;
}
}
@ -146,16 +139,20 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
vk : : Framebuffer BlitScreen : : CreateFramebuffer ( const Layout : : FramebufferLayout & layout ,
vk : : Framebuffer BlitScreen : : CreateFramebuffer ( const Layout : : FramebufferLayout & layout ,
VkImageView image_view ,
VkImageView image_view ,
VkFormat current_view_format ) {
VkFormat current_view_format ) {
const bool format_updated =
std : : exchange ( swapchain_view_format , current_view_format ) ! = current_view_format ;
bool format_updated = swapchain_view_format ! = current_view_format ;
swapchain_view_format = current_view_format ;
if ( ! window_adapt | | scaling_filter ! = filters . get_scaling_filter ( ) | | format_updated ) {
if ( ! window_adapt | | scaling_filter ! = filters . get_scaling_filter ( ) | | format_updated ) {
WaitIdle ( ) ;
WaitIdle ( ) ;
SetWindowAdaptPass ( ) ;
SetWindowAdaptPass ( ) ;
image_index = 0 ;
}
}
const VkExtent2D extent {
const VkExtent2D extent {
. width = layout . width ,
. width = layout . width ,
. height = layout . height ,
. height = layout . height ,
} ;
} ;
return CreateFramebuffer ( image_view , extent , window_adapt - > GetRenderPass ( ) ) ;
return CreateFramebuffer ( image_view , extent , window_adapt - > GetRenderPass ( ) ) ;
}
}