diff --git a/README.md b/README.md index b271e29cc..2f297fce1 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3629. +This is the source code for early-access 3630. ## Legal Notice diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 37a60d915..278a0d2b1 100755 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -18,6 +18,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#include #include #include #include @@ -423,6 +424,7 @@ public: madvise(virtual_base, virtual_size, MADV_HUGEPAGE); #endif + placeholders.add({0, virtual_size}); good = true; } @@ -431,6 +433,10 @@ public: } void Map(size_t virtual_offset, size_t host_offset, size_t length) { + { + std::scoped_lock lock{placeholder_mutex}; + placeholders.subtract({virtual_offset, virtual_offset + length}); + } void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, host_offset); @@ -441,6 +447,19 @@ public: // The method name is wrong. We're still talking about the virtual range. // We don't want to unmap, we want to reserve this memory. + { + std::scoped_lock lock{placeholder_mutex}; + auto it = placeholders.find({virtual_offset - 1, virtual_offset + length + 1}); + + if (it != placeholders.end()) { + size_t prev_upper = virtual_offset + length; + virtual_offset = std::min(virtual_offset, it->lower()); + length = std::max(it->upper(), prev_upper) - virtual_offset; + } + + placeholders.add({virtual_offset, virtual_offset + length}); + } + void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); @@ -484,6 +503,9 @@ private: } int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create + + boost::icl::interval_set placeholders; ///< Mapped placeholders + std::mutex placeholder_mutex; ///< Mutex for placeholders }; #else // ^^^ Linux ^^^ vvv Generic vvv diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index ea5318dc0..e276bc5ce 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -34,7 +34,7 @@ BufferCache

::BufferCache(VideoCore::RasterizerInterface& rasterizer_, const s64 min_spacing_critical = device_memory - 512_MiB; const s64 mem_threshold = std::min(device_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; minimum_memory = static_cast( std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 9e0db1452..4cd54d492 100755 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -3,6 +3,7 @@ #include "common/common_types.h" #include "common/math_util.h" +#include "common/settings.h" #include "video_core/surface.h" namespace VideoCore::Surface { @@ -375,11 +376,20 @@ std::pair GetASTCBlockSize(PixelFormat format) { return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; } -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) { +u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { constexpr u64 RGBA8_PIXEL_SIZE = 4; const u64 base_block_size = static_cast(DefaultBlockWidth(format)) * static_cast(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; - return (base_size * base_block_size) / BytesPerBlock(format); + const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); + + switch (Settings::values.astc_recompression.GetValue()) { + case Settings::AstcRecompression::Bc1: + return uncompressed_size / 8; + case Settings::AstcRecompression::Bc3: + return uncompressed_size / 4; + default: + return uncompressed_size; + } } } // namespace VideoCore::Surface diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 562c65051..e0b06aaf9 100755 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -511,6 +511,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format); std::pair GetASTCBlockSize(PixelFormat format); -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format); +u64 TranscodedAstcSize(u64 base_size, PixelFormat format); } // namespace VideoCore::Surface diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 661bba96c..08d70c51f 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -53,7 +53,7 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& const s64 min_spacing_critical = device_memory - 512_MiB; const s64 mem_threshold = std::min(device_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; expected_memory = static_cast( std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); @@ -79,7 +79,6 @@ void TextureCache

::RunGarbageCollector() { if (num_iterations == 0) { return true; } - --num_iterations; auto& image = slot_images[image_id]; if (True(image.flags & ImageFlagBits::IsDecoding)) { // This image is still being decoded, deleting it will invalidate the slot @@ -94,6 +93,7 @@ void TextureCache

::RunGarbageCollector() { if (!high_priority_mode && must_download) { return false; } + --num_iterations; if (must_download) { auto map = runtime.DownloadStagingBuffer(image.unswizzled_size_bytes); const auto copies = FullDownloadCopies(image.info); @@ -1908,7 +1908,7 @@ void TextureCache

::RegisterImage(ImageId image_id) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory += Common::AlignUp(tentative_size, 1024); image.lru_index = lru_cache.Insert(image_id, frame_tick); @@ -2077,7 +2077,7 @@ void TextureCache

::DeleteImage(ImageId image_id, bool immediate_delete) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory -= Common::AlignUp(tentative_size, 1024); const GPUVAddr gpu_addr = image.gpu_addr;