Remove astc recompression method

This commit is contained in:
CamilleLaVey
2026-09-17 03:31:53 -04:00
parent 052a04e610
commit 86f826c313
16 changed files with 45 additions and 242 deletions
@@ -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<u32, MAX_MIP_LEVELS> mip_level_offsets{};
@@ -12,6 +12,7 @@
#include <boost/container/small_vector.hpp>
#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<P>::DownloadImageIntoBuffer(typename TextureCache<P>::Image* i
}
}
template <class P>
bool TextureCache<P>::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<u8, Tegra::Memory::GuestMemoryFlags::UnsafeRead> guest_data(
*gpu_memory, image.gpu_addr, image.guest_size_bytes, &swizzle_data_buffer);
const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(guest_data.data()),
image.guest_size_bytes);
if (image.guest_data_hash == hash) {
return true;
}
image.guest_data_hash = hash;
return false;
}
template <class P>
void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
if (False(image.flags & ImageFlagBits::CpuModified)) {
@@ -1085,6 +1109,10 @@ void TextureCache<P>::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);
@@ -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 <typename StagingBuffer>
void UploadImageContents(Image& image, StagingBuffer& staging_buffer);
+2 -57
View File
@@ -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<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory
void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8> output,
std::span<BufferImageCopy> copies) {
u32 output_offset = 0;
Common::ScratchBuffer<u8> decode_scratch;
const Extent2D tile_size = DefaultBlockSize(info.format);
for (BufferImageCopy& copy : copies) {
@@ -940,10 +922,7 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
const auto input_offset = input.subspan(copy.buffer_offset);
copy.buffer_offset = output_offset;
const auto recompression_setting = Settings::values.astc_recompression.GetValue();
const bool astc = IsPixelFormatASTC(info.format);
if (astc && recompression_setting == Settings::AstcRecompression::Uncompressed) {
if (IsPixelFormatASTC(info.format)) {
Tegra::Texture::ASTC::Decompress(
input_offset, copy.image_extent.width, copy.image_extent.height,
copy.image_subresource.num_layers * copy.image_extent.depth, tile_size.width,
@@ -952,36 +931,6 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
output_offset += copy.image_extent.width * copy.image_extent.height *
copy.image_extent.depth * copy.image_subresource.num_layers *
BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
} else if (astc) {
// BC1 uses 0.5 bytes per texel
// BC3 uses 1 byte per texel
const auto compress = recompression_setting == Settings::AstcRecompression::Bc1
? Tegra::Texture::BCN::CompressBC1
: Tegra::Texture::BCN::CompressBC3;
const auto bpp_div = recompression_setting == Settings::AstcRecompression::Bc1 ? 2 : 1;
const u32 plane_dim = copy.image_extent.width * copy.image_extent.height;
const u32 level_size = plane_dim * copy.image_extent.depth *
copy.image_subresource.num_layers *
BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
decode_scratch.resize_destructive(level_size);
Tegra::Texture::ASTC::Decompress(
input_offset, copy.image_extent.width, copy.image_extent.height,
copy.image_subresource.num_layers * copy.image_extent.depth, tile_size.width,
tile_size.height, decode_scratch);
compress(decode_scratch, copy.image_extent.width, copy.image_extent.height,
copy.image_subresource.num_layers * copy.image_extent.depth,
output.subspan(output_offset));
const u32 aligned_plane_dim = Common::AlignUp(copy.image_extent.width, 4) *
Common::AlignUp(copy.image_extent.height, 4);
copy.buffer_size =
(aligned_plane_dim * copy.image_extent.depth * copy.image_subresource.num_layers) /
bpp_div;
output_offset += static_cast<u32>(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<const u8> input, const ImageInfo& info, std::span<u8
}
bool CanConvertFromGuest(const ImageInfo& info) {
if (!IsPixelFormatASTC(info.format) || info.type == ImageType::Linear) {
return false;
}
return Settings::values.astc_recompression.GetValue() ==
Settings::AstcRecompression::Uncompressed;
return IsPixelFormatASTC(info.format) && info.type != ImageType::Linear;
}
boost::container::small_vector<BufferImageCopy, 16> ConvertImageFromGuest(