From f3338e70807f66df53d7e7adf71245947a743520 Mon Sep 17 00:00:00 2001 From: psucien Date: Fri, 19 Jul 2024 21:29:31 +0200 Subject: [PATCH] initial preparations for subresources upload --- src/video_core/amdgpu/resource.h | 5 ----- src/video_core/texture_cache/image_info.cpp | 12 ++++++++---- src/video_core/texture_cache/image_info.h | 1 + src/video_core/texture_cache/texture_cache.cpp | 15 +++++++++------ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index 619d078f5..6ab3306b4 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -227,11 +227,6 @@ struct Image { bool IsTiled() const { return GetTilingMode() != TilingMode::Display_Linear; } - - size_t GetSize() const { - // TODO: Derive this properly from tiling params - return Pitch() * (height + 1) * NumComponents(GetDataFmt()); - } }; static_assert(sizeof(Image) == 32); // 256bits diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index f63647115..ccac9131e 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -128,6 +128,7 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group, size.width = attrib.width; size.height = attrib.height; pitch = attrib.tiling_mode == TilingMode::Linear ? size.width : (size.width + 127) & (~127); + usage.vo_buffer = true; const bool is_32bpp = attrib.pixel_format != VideoOutFormat::A16R16G16B16Float; ASSERT(is_32bpp); @@ -141,7 +142,7 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group, guest_size_bytes = pitch * ((size.height + 63) & (~63)) * 4; } } - usage.vo_buffer = true; + mips_layout.emplace_back(0, guest_size_bytes); } ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer, @@ -161,7 +162,9 @@ ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer, usage.render_target = true; guest_address = buffer.Address(); - guest_size_bytes = buffer.GetColorSliceSize() * buffer.NumSlices(); + const auto color_slice_sz = buffer.GetColorSliceSize(); + guest_size_bytes = color_slice_sz * buffer.NumSlices(); + mips_layout.emplace_back(0, color_slice_sz); } ImageInfo::ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, u32 num_slices, @@ -179,7 +182,9 @@ ImageInfo::ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, u32 num_slice usage.depth_target = true; guest_address = buffer.Address(); - guest_size_bytes = buffer.GetDepthSliceSize() * num_slices; + const auto depth_slice_sz = buffer.GetDepthSliceSize(); + guest_size_bytes = depth_slice_sz * num_slices; + mips_layout.emplace_back(0, depth_slice_sz); } ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept { @@ -198,7 +203,6 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept { usage.texture = true; guest_address = image.Address(); - guest_size_bytes = image.GetSize(); mips_layout.reserve(resources.levels); const auto num_bits = NumBits(image.GetDataFmt()); diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index c898bebbf..b98410b90 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h @@ -43,6 +43,7 @@ struct ImageInfo { } usage{}; // Usage data tracked during image lifetime bool is_cube = false; + bool is_volume = false; bool is_tiled = false; bool is_read_only = false; vk::Format pixel_format = vk::Format::eUndefined; diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 70ddb8d5f..192bd9ceb 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -246,21 +246,24 @@ void TextureCache::RefreshImage(Image& image) { return; } + ASSERT(image.info.resources.levels == image.info.mips_layout.size()); const u8* image_data = reinterpret_cast(image.cpu_addr); for (u32 m = 0; m < image.info.resources.levels; m++) { - const u32 width = image.info.size.width >> m; - const u32 height = image.info.size.height >> m; - const u32 map_size = width * height * image.info.resources.layers; + const u32 width = std::max(image.info.size.width >> m, 1u); + const u32 height = std::max(image.info.size.height >> m, 1u); + const u32 depth = image.info.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u; + const u32 map_size = image.info.mips_layout[m].second * image.info.resources.layers; // Upload data to the staging buffer. const auto [data, offset, _] = staging.Map(map_size, 16); if (image.info.is_tiled) { ConvertTileToLinear(data, image_data, width, height, Config::isNeoMode()); } else { - std::memcpy(data, image_data, map_size); + std::memcpy(data, + image_data + image.info.mips_layout[m].first * image.info.resources.layers, + map_size); } staging.Commit(map_size); - image_data += map_size; // Copy to the image. const vk::BufferImageCopy image_copy = { @@ -274,7 +277,7 @@ void TextureCache::RefreshImage(Image& image) { .layerCount = u32(image.info.resources.layers), }, .imageOffset = {0, 0, 0}, - .imageExtent = {width, height, 1}, + .imageExtent = {width, height, depth}, }; scheduler.EndRendering();