@ -22,6 +22,7 @@
# include "common/common_funcs.h"
# include "common/common_types.h"
# include "common/logging/log.h"
# include "common/settings.h"
# include "video_core/compatible_formats.h"
# include "video_core/delayed_destruction_ring.h"
# include "video_core/dirty_flags.h"
@ -384,6 +385,15 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
template < class P >
void TextureCache < P > : : TickFrame ( ) {
const bool enabled_gc = Settings : : values . use_caches_gc . GetValue ( ) ;
if ( ! enabled_gc ) {
// @Note(Blinkhawk): compile error with SCOPE_EXIT on msvc.
sentenced_images . Tick ( ) ;
sentenced_framebuffers . Tick ( ) ;
sentenced_image_view . Tick ( ) ;
+ + frame_tick ;
return ;
}
const bool high_priority_mode = total_used_memory > = expected_memory ;
const bool aggressive_mode = total_used_memory > = critical_memory ;
const u64 ticks_to_destroy = high_priority_mode ? 60 : 100 ;
@ -397,22 +407,20 @@ void TextureCache<P>::TickFrame() {
}
const auto [ image_id , image ] = * deletion_iterator ;
const bool is_alias = True ( image - > flags & ImageFlagBits : : Alias ) ;
if ( is_alias & & image - > aliased_images . size ( ) < = 1 ) {
+ + deletion_iterator ;
continue ;
}
const bool is_bad_overlap = True ( image - > flags & ImageFlagBits : : BadOverlap ) ;
const bool must_download = image - > IsSafeDownload ( ) ;
const u64 ticks_needed = is_bad_overlap ? ticks_to_destroy > > 4 : ticks_to_destroy ;
const bool should_care =
aggressive_mode | | is_bad_overlap | | is_alias | | ( high_priority_mode & & ! must_download ) ;
bool should_care = is_bad_overlap | | is_alias | | ( high_priority_mode & & ! must_download ) ;
const u64 ticks_needed =
is_bad_overlap
? ticks_to_destroy > > 4
: ( ( should_care & & aggressive_mode ) ? ticks_to_destroy > > 1 : ticks_to_destroy ) ;
should_care | = aggressive_mode ;
if ( should_care & & image - > frame_tick + ticks_needed < frame_tick ) {
if ( is_bad_overlap ) {
const bool overlap_check =
std : : ranges : : all_of ( image - > overlapping_images , [ & ] ( const ImageId & overlap_id ) {
auto & overlap = slot_images [ overlap_id ] ;
return ( overlap . frame_tick > = image - > frame_tick ) & &
( overlap . modification_tick > image - > modification_tick ) ;
return overlap . frame_tick > = image - > frame_tick ;
} ) ;
if ( ! overlap_check ) {
+ + deletion_iterator ;
@ -420,23 +428,20 @@ void TextureCache<P>::TickFrame() {
}
}
if ( ! is_bad_overlap & & must_download ) {
if ( is_alias ) {
const bool alias_check =
std : : ranges : : all_of ( image - > aliased_images , [ & ] ( const AliasedImage & alias ) {
auto & alias_image = slot_images [ alias . id ] ;
return ( alias_image . frame_tick > = image - > frame_tick ) & &
( alias_image . modification_tick > image - > modification_tick ) ;
} ) ;
if ( ! alias_check ) {
+ + deletion_iterator ;
continue ;
}
const bool alias_check =
std : : ranges : : none_of ( image - > aliased_images , [ & ] ( const AliasedImage & alias ) {
auto & alias_image = slot_images [ alias . id ] ;
return ( alias_image . frame_tick < image - > frame_tick ) | |
( alias_image . modification_tick < image - > modification_tick ) ;
} ) ;
if ( alias_check ) {
auto map = runtime . DownloadStagingBuffer ( image - > unswizzled_size_bytes ) ;
const auto copies = FullDownloadCopies ( image - > info ) ;
image - > DownloadMemory ( map , copies ) ;
runtime . Finish ( ) ;
SwizzleImage ( gpu_memory , image - > gpu_addr , image - > info , copies , map . mapped_span ) ;
}
auto map = runtime . DownloadStagingBuffer ( image - > unswizzled_size_bytes ) ;
const auto copies = FullDownloadCopies ( image - > info ) ;
image - > DownloadMemory ( map , copies ) ;
runtime . Finish ( ) ;
SwizzleImage ( gpu_memory , image - > gpu_addr , image - > info , copies , map . mapped_span ) ;
}
if ( True ( image - > flags & ImageFlagBits : : Tracked ) ) {
UntrackImage ( * image ) ;