texture_cache: Use pre-allocated buffer for texture uploads
This commit is contained in:
parent
9933121256
commit
c448b3af2f
4 changed files with 28 additions and 13 deletions
|
@ -39,6 +39,12 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
|
|||
sampler_descriptor.mipmap_filter.Assign(Tegra::Texture::TextureMipmapFilter::Linear);
|
||||
sampler_descriptor.cubemap_anisotropy.Assign(1);
|
||||
|
||||
// These values were chosen based on typical peak swizzle data sizes seen in some titles
|
||||
static constexpr size_t SWIZZLE_DATA_BUFFER_INITIAL_CAPACITY = 8_MiB;
|
||||
static constexpr size_t UNSWIZZLE_DATA_BUFFER_INITIAL_CAPACITY = 1_MiB;
|
||||
swizzle_data_buffer.reserve(SWIZZLE_DATA_BUFFER_INITIAL_CAPACITY);
|
||||
unswizzle_data_buffer.reserve(UNSWIZZLE_DATA_BUFFER_INITIAL_CAPACITY);
|
||||
|
||||
// Make sure the first index is reserved for the null resources
|
||||
// This way the null resource becomes a compile time constant
|
||||
void(slot_images.insert(NullImageParams{}));
|
||||
|
@ -734,13 +740,21 @@ void TextureCache<P>::UploadImageContents(Image& image, StagingBuffer& staging)
|
|||
gpu_memory->ReadBlockUnsafe(gpu_addr, mapped_span.data(), mapped_span.size_bytes());
|
||||
const auto uploads = FullUploadSwizzles(image.info);
|
||||
runtime.AccelerateImageUpload(image, staging, uploads);
|
||||
} else if (True(image.flags & ImageFlagBits::Converted)) {
|
||||
std::vector<u8> unswizzled_data(image.unswizzled_size_bytes);
|
||||
auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, unswizzled_data);
|
||||
ConvertImage(unswizzled_data, image.info, mapped_span, copies);
|
||||
return;
|
||||
}
|
||||
const size_t guest_size_bytes = image.guest_size_bytes;
|
||||
swizzle_data_buffer.resize(guest_size_bytes);
|
||||
gpu_memory->ReadBlockUnsafe(gpu_addr, swizzle_data_buffer.data(), guest_size_bytes);
|
||||
|
||||
if (True(image.flags & ImageFlagBits::Converted)) {
|
||||
unswizzle_data_buffer.resize(image.unswizzled_size_bytes);
|
||||
auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data_buffer,
|
||||
unswizzle_data_buffer);
|
||||
ConvertImage(unswizzle_data_buffer, image.info, mapped_span, copies);
|
||||
image.UploadMemory(staging, copies);
|
||||
} else {
|
||||
const auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, mapped_span);
|
||||
const auto copies =
|
||||
UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data_buffer, mapped_span);
|
||||
image.UploadMemory(staging, copies);
|
||||
}
|
||||
}
|
||||
|
@ -910,7 +924,7 @@ void TextureCache<P>::InvalidateScale(Image& image) {
|
|||
}
|
||||
|
||||
template <class P>
|
||||
u64 TextureCache<P>::GetScaledImageSizeBytes(ImageBase& image) {
|
||||
u64 TextureCache<P>::GetScaledImageSizeBytes(const ImageBase& image) {
|
||||
const u64 scale_up = static_cast<u64>(Settings::values.resolution_info.up_scale *
|
||||
Settings::values.resolution_info.up_scale);
|
||||
const u64 down_shift = static_cast<u64>(Settings::values.resolution_info.down_shift +
|
||||
|
|
|
@ -368,7 +368,7 @@ private:
|
|||
void InvalidateScale(Image& image);
|
||||
bool ScaleUp(Image& image);
|
||||
bool ScaleDown(Image& image);
|
||||
u64 GetScaledImageSizeBytes(ImageBase& image);
|
||||
u64 GetScaledImageSizeBytes(const ImageBase& image);
|
||||
|
||||
Runtime& runtime;
|
||||
|
||||
|
@ -417,6 +417,9 @@ private:
|
|||
|
||||
std::unordered_map<GPUVAddr, ImageAllocId> image_allocs_table;
|
||||
|
||||
std::vector<u8> swizzle_data_buffer;
|
||||
std::vector<u8> unswizzle_data_buffer;
|
||||
|
||||
u64 modification_tick = 0;
|
||||
u64 frame_tick = 0;
|
||||
};
|
||||
|
|
|
@ -765,8 +765,9 @@ bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config
|
|||
}
|
||||
|
||||
std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr,
|
||||
const ImageInfo& info, std::span<u8> output) {
|
||||
const size_t guest_size_bytes = CalculateGuestSizeInBytes(info);
|
||||
const ImageInfo& info, std::span<const u8> input,
|
||||
std::span<u8> output) {
|
||||
const size_t guest_size_bytes = input.size_bytes();
|
||||
const u32 bpp_log2 = BytesPerBlockLog2(info.format);
|
||||
const Extent3D size = info.size;
|
||||
|
||||
|
@ -789,10 +790,6 @@ std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, GP
|
|||
.image_extent = size,
|
||||
}};
|
||||
}
|
||||
const auto input_data = std::make_unique<u8[]>(guest_size_bytes);
|
||||
gpu_memory.ReadBlockUnsafe(gpu_addr, input_data.get(), guest_size_bytes);
|
||||
const std::span<const u8> input(input_data.get(), guest_size_bytes);
|
||||
|
||||
const LevelInfo level_info = MakeLevelInfo(info);
|
||||
const s32 num_layers = info.resources.layers;
|
||||
const s32 num_levels = info.resources.levels;
|
||||
|
|
|
@ -59,6 +59,7 @@ struct OverlapResult {
|
|||
|
||||
[[nodiscard]] std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory,
|
||||
GPUVAddr gpu_addr, const ImageInfo& info,
|
||||
std::span<const u8> input,
|
||||
std::span<u8> output);
|
||||
|
||||
[[nodiscard]] BufferCopy UploadBufferCopy(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr,
|
||||
|
|
Loading…
Reference in a new issue