From d44ce7b93b1fe6fcc777d79f582750825a6d7464 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 27 Jan 2026 19:05:42 +0000 Subject: [PATCH] fix etc2/bc7 --- src/qt_common/config/shared_translation.cpp | 6 +- src/video_core/host_shaders/astc_decoder.comp | 113 +++++++----------- .../renderer_vulkan/vk_compute_pass.cpp | 14 +-- .../renderer_vulkan/vk_texture_cache.cpp | 3 - 4 files changed, 57 insertions(+), 79 deletions(-) diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 0db5ec940e..ef2df46fd1 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -482,8 +482,10 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) {Settings::EnumMetadata::Index(), { PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")), - PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")), - PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")), + PAIR(AstcRecompression, Bc1, tr("BC1")), + PAIR(AstcRecompression, Bc3, tr("BC3")), + PAIR(AstcRecompression, Bc7, tr("BC7")), + PAIR(AstcRecompression, Etc2, tr("ETC2")), }}); translations->insert({Settings::EnumMetadata::Index(), { diff --git a/src/video_core/host_shaders/astc_decoder.comp b/src/video_core/host_shaders/astc_decoder.comp index 2f316fe293..edf761bdd3 100644 --- a/src/video_core/host_shaders/astc_decoder.comp +++ b/src/video_core/host_shaders/astc_decoder.comp @@ -437,8 +437,7 @@ void DecodeIntegerSequence(uint max_range, uint num_values) { EncodingData val = EncodingData(encoding_values[max_range]); const uint encoding = Encoding(val); const uint num_bits = NumBits(val); - uint vals_decoded = 0; - while (vals_decoded < num_values && !result_limit_reached) { + for (uint vals_decoded = 0; vals_decoded < num_values && !result_limit_reached; ) { switch (encoding) { case QUINT: DecodeQuintBlock(num_bits); @@ -571,10 +570,8 @@ void DecodeColorValues(uvec4 modes, uint num_partitions, uint color_data_bits, o ivec2 BitTransferSigned(int a, int b) { ivec2 transferred; - transferred.y = b >> 1; - transferred.y |= a & 0x80; - transferred.x = a >> 1; - transferred.x &= 0x3F; + transferred.x = (a >> 1) & 0x3F; + transferred.y = (b >> 1) | (a & 0x80); if ((transferred.x & 0x20) > 0) { transferred.x -= 0x40; } @@ -831,38 +828,6 @@ uvec4 GetUnquantizedWeightVector(uint t, uint s, uvec2 size, uint plane_index, b return weight_vec; } -int FindLayout(uint mode) { - if ((mode & 3) != 0) { - if ((mode & 8) != 0) { - if ((mode & 4) != 0) { - if ((mode & 0x100) != 0) { - return 4; - } - return 3; - } - return 2; - } - if ((mode & 4) != 0) { - return 1; - } - return 0; - } - if ((mode & 0x100) != 0) { - if ((mode & 0x80) != 0) { - if ((mode & 0x20) != 0) { - return 8; - } - return 7; - } - return 9; - } - if ((mode & 0x80) != 0) { - return 6; - } - return 5; -} - - void FillError(ivec3 coord) { for (uint j = 0; j < block_dims.y; j++) { for (uint i = 0; i < block_dims.x; i++) { @@ -908,9 +873,40 @@ bool IsError(uint mode) { return false; } -uvec2 DecodeBlockSize(uint mode) { +int FindLayout(uint mode) { + if ((mode & 3) != 0) { + if ((mode & 8) != 0) { + if ((mode & 4) != 0) { + if ((mode & 0x100) != 0) { + return 4; + } + return 3; + } + return 2; + } + if ((mode & 4) != 0) { + return 1; + } + return 0; + } + if ((mode & 0x100) != 0) { + if ((mode & 0x80) != 0) { + if ((mode & 0x20) != 0) { + return 8; + } + return 7; + } + return 9; + } + if ((mode & 0x80) != 0) { + return 6; + } + return 5; +} + +uvec2 DecodeBlockSize(uint layout, uint mode) { uint A, B; - switch (FindLayout(mode)) { + switch (layout) { case 0: A = (mode >> 5) & 0x3; B = (mode >> 7) & 0x3; @@ -967,6 +963,11 @@ uint DecodeMaxWeight(uint mode) { void DecompressBlock(ivec3 coord) { uint mode = StreamBits(11); + const uint num_partitions = StreamBits(2) + 1; + const uint mode_layout = FindLayout(mode); + const bool dual_plane = (mode_layout != 9) && ((mode & 0x400) != 0); + const uvec2 size_params = DecodeBlockSize(mode_layout, mode); + if (IsError(mode)) { FillError(coord); return; @@ -976,15 +977,8 @@ void DecompressBlock(ivec3 coord) { FillVoidExtentLDR(coord); return; } - const uvec2 size_params = DecodeBlockSize(mode); - if ((size_params.x > block_dims.x) || (size_params.y > block_dims.y)) { - FillError(coord); - return; - } - const uint num_partitions = StreamBits(2) + 1; - const uint mode_layout = FindLayout(mode); - const bool dual_plane = (mode_layout != 9) && ((mode & 0x400) != 0); - if (num_partitions > 4 || (num_partitions == 4 && dual_plane)) { + if (((size_params.x > block_dims.x) || (size_params.y > block_dims.y)) + || (num_partitions > 4 || (num_partitions == 4 && dual_plane))) { FillError(coord); return; } @@ -1002,25 +996,10 @@ void DecompressBlock(ivec3 coord) { const uint base_mode = base_cem & 3; const uint max_weight = DecodeMaxWeight(mode); const uint weight_bits = GetPackedBitSize(size_params, dual_plane, max_weight); - uint remaining_bits = 128 - weight_bits - total_bitsread; - uint extra_cem_bits = 0; - if (base_mode > 0) { - switch (num_partitions) { - case 2: - extra_cem_bits += 2; - break; - case 3: - extra_cem_bits += 5; - break; - case 4: - extra_cem_bits += 8; - break; - default: - return; - } - } - remaining_bits -= extra_cem_bits; + const uint extra_cem_bits = base_mode > 0 ? ((0x85200 >> (num_partitions * 4)) & 0x0f) : 0; const uint plane_selector_bits = dual_plane ? 2 : 0; + const uint remaining_bits = 128 - weight_bits - total_bitsread; + remaining_bits -= extra_cem_bits; remaining_bits -= plane_selector_bits; if (remaining_bits > 128) { // Bad data, more remaining bits than 4 bytes diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index b03e78b3a7..2e515d1d33 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -538,16 +538,16 @@ ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, ComputePassDescriptorQueue& compute_pass_descriptor_queue_, MemoryAllocator& memory_allocator_) : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, - ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, - COMPUTE_PUSH_CONSTANT_RANGE, ASTC_DECODER_COMP_SPV), - scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, - compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{ - memory_allocator_} {} + ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, + COMPUTE_PUSH_CONSTANT_RANGE, ASTC_DECODER_COMP_SPV) + , scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_} + , compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{memory_allocator_} +{} ASTCDecoderPass::~ASTCDecoderPass() = default; -void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, - std::span swizzles) { +void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, std::span swizzles) { + ASSERT(image.info.size.depth == 1); using namespace VideoCommon::Accelerated; const std::array block_dims{ VideoCore::Surface::DefaultBlockWidth(image.info.format), diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 95c753d61a..d57d1568e4 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2437,16 +2437,13 @@ void TextureCacheRuntime::AccelerateImageUpload( if (IsPixelFormatASTC(image.info.format)) { return astc_decoder_pass->Assemble(image, map, swizzles); } - if (bl3d_unswizzle_pass && IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D && image.info.resources.levels == 1 && image.info.resources.layers == 1) { - return bl3d_unswizzle_pass->Unswizzle(image, map, swizzles, z_start, z_count); } - ASSERT(false); }