fix(metal): fix buffer to texture copy

This commit is contained in:
Samuliak 2024-04-09 16:31:04 +02:00
parent 786cd8a708
commit efda44779f
No known key found for this signature in database
4 changed files with 34 additions and 3 deletions

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm> #include <algorithm>
#include <iostream>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -77,9 +78,34 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage, StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage,
bool deferred) { bool deferred) {
if (const std::optional<StagingBufferRef> ref = TryGetReservedBuffer(size, usage, deferred)) {
return *ref;
}
return CreateStagingBuffer(size, usage, deferred); return CreateStagingBuffer(size, usage, deferred);
} }
std::optional<StagingBufferRef> 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, StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage,
bool deferred) { bool deferred) {
const u32 log2 = Common::Log2Ceil64(size); const u32 log2 = Common::Log2Ceil64(size);

View file

@ -71,6 +71,9 @@ private:
StagingBufferRef GetStagingBuffer(size_t size, MemoryUsage usage, bool deferred = false); StagingBufferRef GetStagingBuffer(size_t size, MemoryUsage usage, bool deferred = false);
std::optional<StagingBufferRef> TryGetReservedBuffer(size_t size, MemoryUsage usage,
bool deferred);
StagingBufferRef CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred); StagingBufferRef CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred);
StagingBuffersCache& GetCache(MemoryUsage usage); StagingBuffersCache& GetCache(MemoryUsage usage);

View file

@ -5,6 +5,7 @@
#include <array> #include <array>
#include <span> #include <span>
#include <vector> #include <vector>
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
#include "common/bit_cast.h" #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_} { : VideoCommon::ImageBase(info, gpu_addr_, cpu_addr_), runtime{&runtime_} {
MTL::TextureDescriptor* texture_descriptor = MTL::TextureDescriptor::alloc()->init(); MTL::TextureDescriptor* texture_descriptor = MTL::TextureDescriptor::alloc()->init();
// TODO: don't hardcode the format // 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->setWidth(info.size.width);
texture_descriptor->setHeight(info.size.height); texture_descriptor->setHeight(info.size.height);

View file

@ -49,8 +49,8 @@ size_t GetStreamBufferSize(const Device& device) {
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
Scheduler& scheduler_) Scheduler& scheduler_)
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size / stream_buffer_size{GetStreamBufferSize(device)},
StagingBufferPool::NUM_SYNCS} { region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} {
VkBufferCreateInfo stream_ci = { VkBufferCreateInfo stream_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,