diff options
| author | 2023-05-20 17:15:36 -0400 | |
|---|---|---|
| committer | 2023-05-23 12:54:40 -0400 | |
| commit | 415c78b87c008f0d963679ea9bc06c8aa566b506 (patch) | |
| tree | 11e6a5d2211a99660a48678059c703e849c06da3 /src/video_core/texture_cache | |
| parent | Merge pull request #10392 from danilaml/update-cubeb-again (diff) | |
| download | yuzu-415c78b87c008f0d963679ea9bc06c8aa566b506.tar.gz yuzu-415c78b87c008f0d963679ea9bc06c8aa566b506.tar.xz yuzu-415c78b87c008f0d963679ea9bc06c8aa566b506.zip | |
textures: add BC1 and BC3 compressors and recompression setting
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index f1071aa23..1463f157b 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include "common/bit_util.h" | 18 | #include "common/bit_util.h" |
| 19 | #include "common/common_types.h" | 19 | #include "common/common_types.h" |
| 20 | #include "common/div_ceil.h" | 20 | #include "common/div_ceil.h" |
| 21 | #include "common/scratch_buffer.h" | ||
| 22 | #include "common/settings.h" | ||
| 21 | #include "video_core/compatible_formats.h" | 23 | #include "video_core/compatible_formats.h" |
| 22 | #include "video_core/engines/maxwell_3d.h" | 24 | #include "video_core/engines/maxwell_3d.h" |
| 23 | #include "video_core/memory_manager.h" | 25 | #include "video_core/memory_manager.h" |
| @@ -28,6 +30,7 @@ | |||
| 28 | #include "video_core/texture_cache/samples_helper.h" | 30 | #include "video_core/texture_cache/samples_helper.h" |
| 29 | #include "video_core/texture_cache/util.h" | 31 | #include "video_core/texture_cache/util.h" |
| 30 | #include "video_core/textures/astc.h" | 32 | #include "video_core/textures/astc.h" |
| 33 | #include "video_core/textures/bcn.h" | ||
| 31 | #include "video_core/textures/decoders.h" | 34 | #include "video_core/textures/decoders.h" |
| 32 | 35 | ||
| 33 | namespace VideoCommon { | 36 | namespace VideoCommon { |
| @@ -585,6 +588,21 @@ u32 CalculateConvertedSizeBytes(const ImageInfo& info) noexcept { | |||
| 585 | return info.size.width * BytesPerBlock(info.format); | 588 | return info.size.width * BytesPerBlock(info.format); |
| 586 | } | 589 | } |
| 587 | static constexpr Extent2D TILE_SIZE{1, 1}; | 590 | static constexpr Extent2D TILE_SIZE{1, 1}; |
| 591 | if (IsPixelFormatASTC(info.format) && Settings::values.astc_recompression.GetValue() != | ||
| 592 | Settings::AstcRecompression::Uncompressed) { | ||
| 593 | const u32 bpp_div = | ||
| 594 | Settings::values.astc_recompression.GetValue() == Settings::AstcRecompression::Bc1 ? 2 | ||
| 595 | : 1; | ||
| 596 | // NumBlocksPerLayer doesn't account for this correctly, so we have to do it manually. | ||
| 597 | u32 output_size = 0; | ||
| 598 | for (s32 i = 0; i < info.resources.levels; i++) { | ||
| 599 | const auto mip_size = AdjustMipSize(info.size, i); | ||
| 600 | const u32 plane_dim = | ||
| 601 | Common::AlignUp(mip_size.width, 4U) * Common::AlignUp(mip_size.height, 4U); | ||
| 602 | output_size += (plane_dim * info.size.depth * info.resources.layers) / bpp_div; | ||
| 603 | } | ||
| 604 | return output_size; | ||
| 605 | } | ||
| 588 | return NumBlocksPerLayer(info, TILE_SIZE) * info.resources.layers * CONVERTED_BYTES_PER_BLOCK; | 606 | return NumBlocksPerLayer(info, TILE_SIZE) * info.resources.layers * CONVERTED_BYTES_PER_BLOCK; |
| 589 | } | 607 | } |
| 590 | 608 | ||
| @@ -885,6 +903,7 @@ BufferCopy UploadBufferCopy(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, | |||
| 885 | void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8> output, | 903 | void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8> output, |
| 886 | std::span<BufferImageCopy> copies) { | 904 | std::span<BufferImageCopy> copies) { |
| 887 | u32 output_offset = 0; | 905 | u32 output_offset = 0; |
| 906 | Common::ScratchBuffer<u8> decode_scratch; | ||
| 888 | 907 | ||
| 889 | const Extent2D tile_size = DefaultBlockSize(info.format); | 908 | const Extent2D tile_size = DefaultBlockSize(info.format); |
| 890 | for (BufferImageCopy& copy : copies) { | 909 | for (BufferImageCopy& copy : copies) { |
| @@ -895,22 +914,58 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8 | |||
| 895 | ASSERT(copy.image_extent == mip_size); | 914 | ASSERT(copy.image_extent == mip_size); |
| 896 | ASSERT(copy.buffer_row_length == Common::AlignUp(mip_size.width, tile_size.width)); | 915 | ASSERT(copy.buffer_row_length == Common::AlignUp(mip_size.width, tile_size.width)); |
| 897 | ASSERT(copy.buffer_image_height == Common::AlignUp(mip_size.height, tile_size.height)); | 916 | ASSERT(copy.buffer_image_height == Common::AlignUp(mip_size.height, tile_size.height)); |
| 898 | if (IsPixelFormatASTC(info.format)) { | 917 | |
| 918 | const auto input_offset = input.subspan(copy.buffer_offset); | ||
| 919 | copy.buffer_offset = output_offset; | ||
| 920 | copy.buffer_row_length = mip_size.width; | ||
| 921 | copy.buffer_image_height = mip_size.height; | ||
| 922 | |||
| 923 | const auto recompression_setting = Settings::values.astc_recompression.GetValue(); | ||
| 924 | const bool astc = IsPixelFormatASTC(info.format); | ||
| 925 | |||
| 926 | if (astc && recompression_setting == Settings::AstcRecompression::Uncompressed) { | ||
| 899 | Tegra::Texture::ASTC::Decompress( | 927 | Tegra::Texture::ASTC::Decompress( |
| 900 | input.subspan(copy.buffer_offset), copy.image_extent.width, | 928 | input_offset, copy.image_extent.width, copy.image_extent.height, |
| 901 | copy.image_extent.height, | ||
| 902 | copy.image_subresource.num_layers * copy.image_extent.depth, tile_size.width, | 929 | copy.image_subresource.num_layers * copy.image_extent.depth, tile_size.width, |
| 903 | tile_size.height, output.subspan(output_offset)); | 930 | tile_size.height, output.subspan(output_offset)); |
| 931 | |||
| 932 | output_offset += copy.image_extent.width * copy.image_extent.height * | ||
| 933 | copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK; | ||
| 934 | } else if (astc) { | ||
| 935 | // BC1 uses 0.5 bytes per texel | ||
| 936 | // BC3 uses 1 byte per texel | ||
| 937 | const auto compress = recompression_setting == Settings::AstcRecompression::Bc1 | ||
| 938 | ? Tegra::Texture::BCN::CompressBC1 | ||
| 939 | : Tegra::Texture::BCN::CompressBC3; | ||
| 940 | const auto bpp_div = recompression_setting == Settings::AstcRecompression::Bc1 ? 2 : 1; | ||
| 941 | |||
| 942 | const u32 plane_dim = copy.image_extent.width * copy.image_extent.height; | ||
| 943 | const u32 level_size = plane_dim * copy.image_extent.depth * | ||
| 944 | copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK; | ||
| 945 | decode_scratch.resize_destructive(level_size); | ||
| 946 | |||
| 947 | Tegra::Texture::ASTC::Decompress( | ||
| 948 | input_offset, copy.image_extent.width, copy.image_extent.height, | ||
| 949 | copy.image_subresource.num_layers * copy.image_extent.depth, tile_size.width, | ||
| 950 | tile_size.height, decode_scratch); | ||
| 951 | |||
| 952 | compress(decode_scratch, copy.image_extent.width, copy.image_extent.height, | ||
| 953 | copy.image_subresource.num_layers * copy.image_extent.depth, | ||
| 954 | output.subspan(output_offset)); | ||
| 955 | |||
| 956 | const u32 aligned_plane_dim = Common::AlignUp(copy.image_extent.width, 4) * | ||
| 957 | Common::AlignUp(copy.image_extent.height, 4); | ||
| 958 | |||
| 959 | copy.buffer_size = | ||
| 960 | (aligned_plane_dim * copy.image_extent.depth * copy.image_subresource.num_layers) / | ||
| 961 | bpp_div; | ||
| 962 | output_offset += static_cast<u32>(copy.buffer_size); | ||
| 904 | } else { | 963 | } else { |
| 905 | DecompressBC4(input.subspan(copy.buffer_offset), copy.image_extent, | 964 | DecompressBC4(input_offset, copy.image_extent, output.subspan(output_offset)); |
| 906 | output.subspan(output_offset)); | ||
| 907 | } | ||
| 908 | copy.buffer_offset = output_offset; | ||
| 909 | copy.buffer_row_length = mip_size.width; | ||
| 910 | copy.buffer_image_height = mip_size.height; | ||
| 911 | 965 | ||
| 912 | output_offset += copy.image_extent.width * copy.image_extent.height * | 966 | output_offset += copy.image_extent.width * copy.image_extent.height * |
| 913 | copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK; | 967 | copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK; |
| 968 | } | ||
| 914 | } | 969 | } |
| 915 | } | 970 | } |
| 916 | 971 | ||