diff --git a/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp b/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp index 97bc9e88fe..3bdd5175f8 100644 --- a/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp +++ b/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include @@ -77,9 +78,34 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage, bool deferred) { + if (const std::optional ref = TryGetReservedBuffer(size, usage, deferred)) { + return *ref; + } + return CreateStagingBuffer(size, usage, deferred); } +std::optional StagingBufferPool::TryGetReservedBuffer(size_t size, + MemoryUsage usage, + bool deferred) { + StagingBuffers& cache_level = GetCache(usage)[Common::Log2Ceil64(size)]; + + // TODO: don't always return true + const auto is_free = [](const StagingBuffer& entry) { return true; }; + auto& entries = cache_level.entries; + const auto hint_it = entries.begin() + cache_level.iterate_index; + auto it = std::find_if(entries.begin() + cache_level.iterate_index, entries.end(), is_free); + if (it == entries.end()) { + it = std::find_if(entries.begin(), hint_it, is_free); + if (it == hint_it) { + return std::nullopt; + } + } + cache_level.iterate_index = std::distance(entries.begin(), it) + 1; + + return it->Ref(); +} + StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred) { const u32 log2 = Common::Log2Ceil64(size); diff --git a/src/video_core/renderer_metal/mtl_staging_buffer_pool.h b/src/video_core/renderer_metal/mtl_staging_buffer_pool.h index e065272531..d81f11df80 100644 --- a/src/video_core/renderer_metal/mtl_staging_buffer_pool.h +++ b/src/video_core/renderer_metal/mtl_staging_buffer_pool.h @@ -71,6 +71,9 @@ private: StagingBufferRef GetStagingBuffer(size_t size, MemoryUsage usage, bool deferred = false); + std::optional TryGetReservedBuffer(size_t size, MemoryUsage usage, + bool deferred); + StagingBufferRef CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred); StagingBuffersCache& GetCache(MemoryUsage usage); diff --git a/src/video_core/renderer_metal/mtl_texture_cache.cpp b/src/video_core/renderer_metal/mtl_texture_cache.cpp index cf37577595..fb1ea37835 100644 --- a/src/video_core/renderer_metal/mtl_texture_cache.cpp +++ b/src/video_core/renderer_metal/mtl_texture_cache.cpp @@ -5,6 +5,7 @@ #include #include #include + #include #include "common/bit_cast.h" @@ -59,7 +60,8 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info, GPUVAddr gpu_ : VideoCommon::ImageBase(info, gpu_addr_, cpu_addr_), runtime{&runtime_} { MTL::TextureDescriptor* texture_descriptor = MTL::TextureDescriptor::alloc()->init(); // TODO: don't hardcode the format - texture_descriptor->setPixelFormat(MTL::PixelFormatRGBA8Unorm); + texture_descriptor->setPixelFormat(info.size.width == 1600 ? MTL::PixelFormatRGBA8Unorm + : MTL::PixelFormatASTC_4x4_sRGB); texture_descriptor->setWidth(info.size.width); texture_descriptor->setHeight(info.size.height); diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 03a0b7280b..9f24741493 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -49,8 +49,8 @@ size_t GetStreamBufferSize(const Device& device) { StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_) : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, - stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size / - StagingBufferPool::NUM_SYNCS} { + stream_buffer_size{GetStreamBufferSize(device)}, + region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} { VkBufferCreateInfo stream_ci = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr,