aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache/util.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 20:43:01 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 20:43:01 -0400
commit0d5534a2883329183ae8aa89b3fe1c7b67291ece (patch)
treeaabad4260f301a8a52af16e15e7fb76a700d642f /src/video_core/texture_cache/util.cpp
parente4deef6ba4ea76aac997ed3102f8e9801fd170b9 (diff)
ASTC: decode and re-compress to BC1/BC3 on the GPU; texture cache budget
- accelerate_astc=Gpu with astc_recompression=Bc1/Bc3 now decodes ASTC with the GPU decoder into a temporary RGBA8 image (dedicated memory, freed once the GPU is past it) and compresses it with a new compute shader (bc_encoder.comp: bounding-box endpoints along the colours' covariance, inset 1/16, nearest palette entry; BC3 alpha ramp; BC1 punch-through), then copies the blocks into the image. No CPU decode, so streamed textures are ready the frame they are first used instead of showing placeholders for seconds; the decode pass no longer waits for the GPU on this path. - The CPU path (CpuAsynchronous) fills a new image with zero blocks before its first decode instead of showing stale VRAM, and the transcode pool is a quarter of the hardware threads. - Switch 2 titles: collector thresholds near the device budget, re-read every 60 frames from VK_EXT_memory_budget (another game shrank it from 7.0 to 5.4 GB). - EDEN_NX2_HIDE_WINDOW=0 now leaves the window visible.
Diffstat (limited to 'src/video_core/texture_cache/util.cpp')
-rw-r--r--src/video_core/texture_cache/util.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 7a1a1d89c0..ffc1d59ec3 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -929,6 +929,35 @@ boost::container::small_vector<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory
return copies;
}
+void ConvertedLayout(const ImageInfo& info, std::span<BufferImageCopy> copies) {
+ // Same offsets and sizes as ConvertImage below.
+ const auto recompression = Settings::values.astc_recompression.GetValue();
+ const bool astc = IsPixelFormatASTC(info.format);
+ u64 output_offset = 0;
+ for (BufferImageCopy& copy : copies) {
+ const Extent3D mip_size = AdjustMipSize(info.size, copy.image_subresource.base_level);
+ const u64 layers = static_cast<u64>(copy.image_subresource.num_layers) * copy.image_extent.depth;
+ u64 size;
+ if (astc && recompression == Settings::AstcRecompression::Uncompressed) {
+ size = u64{copy.image_extent.width} * copy.image_extent.height * layers *
+ BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
+ } else if (astc) {
+ const u64 bpp_div =
+ recompression == Settings::AstcRecompression::Bc1 || info.astc_opaque ? 2 : 1;
+ size = u64{Common::AlignUp(copy.image_extent.width, 4U)} *
+ Common::AlignUp(copy.image_extent.height, 4U) * layers / bpp_div;
+ } else {
+ size = u64{copy.image_extent.width} * copy.image_extent.height * layers *
+ ConvertedBytesPerBlock(info.format);
+ }
+ copy.buffer_offset = output_offset;
+ copy.buffer_size = size;
+ copy.buffer_row_length = mip_size.width;
+ copy.buffer_image_height = mip_size.height;
+ output_offset += size;
+ }
+}
+
void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8> output,
std::span<BufferImageCopy> copies) {
u32 output_offset = 0;