From 86f826c313a097b89e2b846c725e834377661073 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Thu, 17 Sep 2026 03:31:53 -0400 Subject: [PATCH] Remove astc recompression method --- src/common/settings.cpp | 1 - src/common/settings.h | 7 -- src/common/settings_enums.h | 1 - src/qt_common/config/shared_translation.cpp | 12 --- src/qt_common/config/uisettings.h | 1 - src/video_core/CMakeLists.txt | 4 +- .../renderer_opengl/gl_texture_cache.cpp | 30 +------ .../renderer_vulkan/maxwell_to_vk.cpp | 21 ++--- .../renderer_vulkan/vk_texture_cache.cpp | 7 +- src/video_core/surface.cpp | 10 +-- src/video_core/texture_cache/image_base.h | 2 + src/video_core/texture_cache/texture_cache.h | 28 ++++++ .../texture_cache/texture_cache_base.h | 2 + src/video_core/texture_cache/util.cpp | 59 +------------ src/video_core/textures/bcn.cpp | 86 ------------------- src/video_core/textures/bcn.h | 16 ---- 16 files changed, 45 insertions(+), 242 deletions(-) delete mode 100644 src/video_core/textures/bcn.cpp delete mode 100644 src/video_core/textures/bcn.h diff --git a/src/common/settings.cpp b/src/common/settings.cpp index bc46b61bb4..7605305a04 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -48,7 +48,6 @@ SWITCHABLE(AnisotropyMode, true); SWITCHABLE(AntiAliasing, false); SWITCHABLE(AspectRatio, true); SWITCHABLE(AstcDecodeMode, true); -SWITCHABLE(AstcRecompression, true); SWITCHABLE(AudioMode, true); SWITCHABLE(CpuBackend, true); SWITCHABLE(CpuAccuracy, true); diff --git a/src/common/settings.h b/src/common/settings.h index 48d4ca427d..d15427187c 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -65,7 +65,6 @@ SWITCHABLE(AnisotropyMode, true); SWITCHABLE(AntiAliasing, false); SWITCHABLE(AspectRatio, true); SWITCHABLE(AstcDecodeMode, true); -SWITCHABLE(AstcRecompression, true); SWITCHABLE(AudioMode, true); SWITCHABLE(CpuBackend, true); SWITCHABLE(CpuAccuracy, true); @@ -563,12 +562,6 @@ struct Values { true, true}; - SwitchableSetting astc_recompression{linkage, - AstcRecompression::Uncompressed, - "astc_recompression", - Category::RendererAdvanced}; - - SwitchableSetting sync_memory_operations{linkage, false, "sync_memory_operations", diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 1d7c25cf09..73568e257c 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -130,7 +130,6 @@ ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu); ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16); ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous); -ENUM(AstcRecompression, Uncompressed, Bc1, Bc3); ENUM(FramePacingMode, Target_Auto, Target_30, Target_60, Target_90, Target_120); ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); ENUM(VramUsageMode, Conservative, Aggressive); diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 96e569aa21..1f6792f86c 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -179,11 +179,6 @@ std::unique_ptr InitializeTranslations(QObject* parent) { "GPU: Use the GPU's compute shaders to decode ASTC textures (recommended).\n" "CPU Asynchronously: Use the CPU to decode ASTC textures on demand. Eliminates" "ASTC decoding\nstuttering but may present artifacts.")); - INSERT(Settings, astc_recompression, tr("ASTC Recompression Method:"), - tr("Most GPUs lack support for ASTC textures and must decompress to an" - "intermediate format: RGBA8.\n" - "BC1/BC3: The intermediate format will be recompressed to BC1 or BC3 format,\n" - " saving VRAM but degrading image quality.")); INSERT(Settings, frame_pacing_mode, tr("Frame Pacing Mode (Vulkan only)"), tr("Controls how the emulator manages frame pacing to reduce stuttering and make the " "frame rate smoother and more consistent.")); @@ -379,13 +374,6 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) { PAIR(AstcDecodeMode, Gpu, tr("GPU")), PAIR(AstcDecodeMode, CpuAsynchronous, tr("CPU Asynchronous")), }}); - translations->insert( - {Settings::EnumMetadata::Index(), - { - PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")), - PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")), - PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")), - }}); translations->insert({Settings::EnumMetadata::Index(), { PAIR(FramePacingMode, Target_Auto, tr("Auto")), diff --git a/src/qt_common/config/uisettings.h b/src/qt_common/config/uisettings.h index 794d1a029b..58a538367a 100644 --- a/src/qt_common/config/uisettings.h +++ b/src/qt_common/config/uisettings.h @@ -262,6 +262,5 @@ Q_DECLARE_METATYPE(Settings::ResolutionSetup); Q_DECLARE_METATYPE(Settings::ScalingFilter); Q_DECLARE_METATYPE(Settings::AntiAliasing); Q_DECLARE_METATYPE(Settings::RendererBackend); -Q_DECLARE_METATYPE(Settings::AstcRecompression); Q_DECLARE_METATYPE(Settings::AstcDecodeMode); Q_DECLARE_METATYPE(Settings::SpirvOptimizeMode); diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 64d14ab2a6..77883b6484 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -256,8 +256,6 @@ add_library(video_core STATIC texture_cache/util.h textures/astc.h textures/astc.cpp - textures/bcn.cpp - textures/bcn.h textures/decoders.cpp textures/decoders.h textures/texture.cpp @@ -406,7 +404,7 @@ if (ENABLE_OPENGL) endif() target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PUBLIC shader_recompiler stb bc_decoder gpu_logging) +target_link_libraries(video_core PUBLIC shader_recompiler bc_decoder gpu_logging) if (ENABLE_OPENGL) target_link_libraries(video_core PUBLIC glad) endif() diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 48aa32bc90..2589e42109 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -235,9 +235,7 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array& color) { if (Settings::values.accelerate_astc.GetValue() != Settings::AstcDecodeMode::Gpu) { return false; } - return Settings::values.astc_recompression.GetValue() == - Settings::AstcRecompression::Uncompressed && - info.size.depth == 1; + return info.size.depth == 1; } [[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info, @@ -1880,8 +1878,9 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu case Settings::AstcDecodeMode::Gpu: if (WillUseAcceleratedAstcDecode(runtime->device, info)) { flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; + break; } - break; + [[fallthrough]]; case Settings::AstcDecodeMode::CpuAsynchronous: flags |= VideoCommon::ImageFlagBits::AsynchronousDecode; break; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 4603870bfa..fa9554db59 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -6,7 +6,6 @@ #include "common/common_types.h" #include "common/math_util.h" -#include "common/settings.h" #include "video_core/surface.h" namespace VideoCore::Surface { @@ -469,14 +468,7 @@ u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { static_cast(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); - switch (Settings::values.astc_recompression.GetValue()) { - case Settings::AstcRecompression::Bc1: - return uncompressed_size / 8; - case Settings::AstcRecompression::Bc3: - return uncompressed_size / 4; - default: - return uncompressed_size; - } + return uncompressed_size; } } // namespace VideoCore::Surface diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 79fc8505d6..9e0a293962 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -95,6 +95,7 @@ struct ImageBase { u32 scale_rating = 0; u64 scale_tick = 0; bool has_scaled = false; + u32 guest_data_checks = 0; size_t channel = 0; @@ -105,6 +106,7 @@ struct ImageBase { VAddr cpu_addr_end = 0; u64 modification_tick = 0; + u64 guest_data_hash = 0; size_t lru_index = SIZE_MAX; std::array mip_level_offsets{}; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 861d9f63d0..489ceda94e 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -12,6 +12,7 @@ #include #include "common/alignment.h" +#include "common/cityhash.h" #include "common/settings.h" #include "common/slot_vector.h" #include "video_core/control/channel_state.h" @@ -1074,6 +1075,29 @@ void TextureCache

::DownloadImageIntoBuffer(typename TextureCache

::Image* i } } +template +bool TextureCache

::IsAstcDataUnchanged(Image& image) { + static constexpr u32 CHECK_THRESHOLD = 4; + if (False(image.flags & ImageFlagBits::Converted) || + True(image.flags & ImageFlagBits::GpuModified) || + !IsPixelFormatASTC(image.info.format)) { + return false; + } + if (image.guest_data_checks < CHECK_THRESHOLD) { + ++image.guest_data_checks; + return false; + } + Tegra::Memory::GpuGuestMemory guest_data( + *gpu_memory, image.gpu_addr, image.guest_size_bytes, &swizzle_data_buffer); + const u64 hash = Common::CityHash64(reinterpret_cast(guest_data.data()), + image.guest_size_bytes); + if (image.guest_data_hash == hash) { + return true; + } + image.guest_data_hash = hash; + return false; +} + template void TextureCache

::RefreshContents(Image& image, ImageId image_id) { if (False(image.flags & ImageFlagBits::CpuModified)) { @@ -1085,6 +1109,10 @@ void TextureCache

::RefreshContents(Image& image, ImageId image_id) { TrackImage(image, image_id); + if (IsAstcDataUnchanged(image)) { + return; + } + if (image.info.num_samples > 1 && !runtime.CanUploadMSAA()) { LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented"); runtime.TransitionImageLayout(image); diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 8fbd7f61bc..29f5bdde83 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -298,6 +298,8 @@ private: void RefreshContents(Image& image, ImageId image_id); + [[nodiscard]] bool IsAstcDataUnchanged(Image& image); + /// Upload data from guest to an image template void UploadImageContents(Image& image, StagingBuffer& staging_buffer); diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 8d275ff8eb..d8cae4f3ee 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -22,7 +22,6 @@ #include "common/common_types.h" #include "common/div_ceil.h" #include "common/scratch_buffer.h" -#include "common/settings.h" #include "video_core/compatible_formats.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/guest_memory.h" @@ -34,7 +33,6 @@ #include "video_core/texture_cache/samples_helper.h" #include "video_core/texture_cache/util.h" #include "video_core/textures/astc.h" -#include "video_core/textures/bcn.h" #include "video_core/textures/decoders.h" namespace VideoCommon { @@ -608,21 +606,6 @@ u32 CalculateConvertedSizeBytes(const ImageInfo& info) noexcept { return info.size.width * BytesPerBlock(info.format); } static constexpr Extent2D TILE_SIZE{1, 1}; - if (IsPixelFormatASTC(info.format) && Settings::values.astc_recompression.GetValue() != - Settings::AstcRecompression::Uncompressed) { - const u32 bpp_div = - Settings::values.astc_recompression.GetValue() == Settings::AstcRecompression::Bc1 ? 2 - : 1; - // NumBlocksPerLayer doesn't account for this correctly, so we have to do it manually. - u32 output_size = 0; - for (s32 i = 0; i < info.resources.levels; i++) { - const auto mip_size = AdjustMipSize(info.size, i); - const u32 plane_dim = - Common::AlignUp(mip_size.width, 4U) * Common::AlignUp(mip_size.height, 4U); - output_size += (plane_dim * info.size.depth * info.resources.layers) / bpp_div; - } - return output_size; - } return NumBlocksPerLayer(info, TILE_SIZE) * info.resources.layers * ConvertedBytesPerBlock(info.format); } @@ -925,7 +908,6 @@ boost::container::small_vector UnswizzleImage(Tegra::Memory void ConvertImage(std::span input, const ImageInfo& info, std::span output, std::span copies) { u32 output_offset = 0; - Common::ScratchBuffer decode_scratch; const Extent2D tile_size = DefaultBlockSize(info.format); for (BufferImageCopy& copy : copies) { @@ -940,10 +922,7 @@ void ConvertImage(std::span input, const ImageInfo& info, std::span input, const ImageInfo& info, std::span(copy.buffer_size); } else { DecompressBCn(input_offset, output.subspan(output_offset), copy, info.format); output_offset += copy.image_extent.width * copy.image_extent.height * @@ -995,11 +944,7 @@ void ConvertImage(std::span input, const ImageInfo& info, std::span ConvertImageFromGuest( diff --git a/src/video_core/textures/bcn.cpp b/src/video_core/textures/bcn.cpp deleted file mode 100644 index 16ddbe3202..0000000000 --- a/src/video_core/textures/bcn.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include "common/alignment.h" -#include "video_core/textures/bcn.h" -#include "video_core/textures/workers.h" - -namespace Tegra::Texture::BCN { - -using BCNCompressor = void(u8* block_output, const u8* block_input, bool any_alpha); - -template -void CompressBCN(std::span data, uint32_t width, uint32_t height, uint32_t depth, - std::span output, BCNCompressor f) { - constexpr u8 alpha_threshold = 128; - constexpr u32 bytes_per_px = 4; - const u32 plane_dim = width * height; - - Common::ThreadWorker& workers{GetThreadWorkers()}; - - for (u32 z = 0; z < depth; z++) { - for (u32 y = 0; y < height; y += 4) { - auto compress_row = [z, y, width, height, plane_dim, f, data, output]() { - for (u32 x = 0; x < width; x += 4) { - // Gather 4x4 block of RGBA texels - u8 input_colors[4][4][4]; - bool any_alpha = false; - - for (u32 j = 0; j < 4; j++) { - for (u32 i = 0; i < 4; i++) { - const size_t coord = - (z * plane_dim + (y + j) * width + (x + i)) * bytes_per_px; - - if ((x + i < width) && (y + j < height)) { - if constexpr (ThresholdAlpha) { - if (data[coord + 3] >= alpha_threshold) { - input_colors[j][i][0] = data[coord + 0]; - input_colors[j][i][1] = data[coord + 1]; - input_colors[j][i][2] = data[coord + 2]; - input_colors[j][i][3] = 255; - } else { - any_alpha = true; - memset(input_colors[j][i], 0, bytes_per_px); - } - } else { - memcpy(input_colors[j][i], &data[coord], bytes_per_px); - } - } else { - memset(input_colors[j][i], 0, bytes_per_px); - } - } - } - - const u32 bytes_per_row = BytesPerBlock * Common::DivideUp(width, 4U); - const u32 bytes_per_plane = bytes_per_row * Common::DivideUp(height, 4U); - f(output.data() + z * bytes_per_plane + (y / 4) * bytes_per_row + - (x / 4) * BytesPerBlock, - reinterpret_cast(input_colors), any_alpha); - } - }; - workers.QueueWork(std::move(compress_row)); - } - workers.WaitForRequests(); - } -} - -void CompressBC1(std::span data, uint32_t width, uint32_t height, uint32_t depth, - std::span output) { - CompressBCN<8, true>(data, width, height, depth, output, - [](u8* block_output, const u8* block_input, bool any_alpha) { - stb_compress_bc1_block(block_output, block_input, any_alpha, - STB_DXT_NORMAL); - }); -} - -void CompressBC3(std::span data, uint32_t width, uint32_t height, uint32_t depth, - std::span output) { - CompressBCN<16, false>(data, width, height, depth, output, - [](u8* block_output, const u8* block_input, bool any_alpha) { - stb_compress_bc3_block(block_output, block_input, STB_DXT_NORMAL); - }); -} - -} // namespace Tegra::Texture::BCN diff --git a/src/video_core/textures/bcn.h b/src/video_core/textures/bcn.h deleted file mode 100644 index d5d2a16c91..0000000000 --- a/src/video_core/textures/bcn.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -#include "common/common_types.h" - -namespace Tegra::Texture::BCN { - -void CompressBC1(std::span data, u32 width, u32 height, u32 depth, std::span output); - -void CompressBC3(std::span data, u32 width, u32 height, u32 depth, std::span output); - -} // namespace Tegra::Texture::BCN