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/textures | |
| 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/textures')
| -rw-r--r-- | src/video_core/textures/astc.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/textures/bcn.cpp | 87 | ||||
| -rw-r--r-- | src/video_core/textures/bcn.h | 17 | ||||
| -rw-r--r-- | src/video_core/textures/workers.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/textures/workers.h | 12 |
5 files changed, 133 insertions, 3 deletions
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp index a68bc0d77..fef0be31d 100644 --- a/src/video_core/textures/astc.cpp +++ b/src/video_core/textures/astc.cpp | |||
| @@ -16,8 +16,8 @@ | |||
| 16 | #include "common/alignment.h" | 16 | #include "common/alignment.h" |
| 17 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 18 | #include "common/polyfill_ranges.h" | 18 | #include "common/polyfill_ranges.h" |
| 19 | #include "common/thread_worker.h" | ||
| 20 | #include "video_core/textures/astc.h" | 19 | #include "video_core/textures/astc.h" |
| 20 | #include "video_core/textures/workers.h" | ||
| 21 | 21 | ||
| 22 | class InputBitStream { | 22 | class InputBitStream { |
| 23 | public: | 23 | public: |
| @@ -1656,8 +1656,7 @@ void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, | |||
| 1656 | const u32 rows = Common::DivideUp(height, block_height); | 1656 | const u32 rows = Common::DivideUp(height, block_height); |
| 1657 | const u32 cols = Common::DivideUp(width, block_width); | 1657 | const u32 cols = Common::DivideUp(width, block_width); |
| 1658 | 1658 | ||
| 1659 | static Common::ThreadWorker workers{std::max(std::thread::hardware_concurrency(), 2U) / 2, | 1659 | Common::ThreadWorker& workers{GetThreadWorkers()}; |
| 1660 | "ASTCDecompress"}; | ||
| 1661 | 1660 | ||
| 1662 | for (u32 z = 0; z < depth; ++z) { | 1661 | for (u32 z = 0; z < depth; ++z) { |
| 1663 | const u32 depth_offset = z * height * width * 4; | 1662 | const u32 depth_offset = z * height * width * 4; |
diff --git a/src/video_core/textures/bcn.cpp b/src/video_core/textures/bcn.cpp new file mode 100644 index 000000000..671212a49 --- /dev/null +++ b/src/video_core/textures/bcn.cpp | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <stb_dxt.h> | ||
| 5 | #include <string.h> | ||
| 6 | |||
| 7 | #include "common/alignment.h" | ||
| 8 | #include "video_core/textures/bcn.h" | ||
| 9 | #include "video_core/textures/workers.h" | ||
| 10 | |||
| 11 | namespace Tegra::Texture::BCN { | ||
| 12 | |||
| 13 | using BCNCompressor = void(u8* block_output, const u8* block_input, bool any_alpha); | ||
| 14 | |||
| 15 | template <u32 BytesPerBlock, bool ThresholdAlpha = false> | ||
| 16 | void CompressBCN(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, | ||
| 17 | std::span<uint8_t> output, BCNCompressor f) { | ||
| 18 | constexpr u8 alpha_threshold = 128; | ||
| 19 | constexpr u32 bytes_per_px = 4; | ||
| 20 | const u32 plane_dim = width * height; | ||
| 21 | |||
| 22 | Common::ThreadWorker& workers{GetThreadWorkers()}; | ||
| 23 | |||
| 24 | for (u32 z = 0; z < depth; z++) { | ||
| 25 | for (u32 y = 0; y < height; y += 4) { | ||
| 26 | auto compress_row = [z, y, width, height, plane_dim, f, data, output]() { | ||
| 27 | for (u32 x = 0; x < width; x += 4) { | ||
| 28 | // Gather 4x4 block of RGBA texels | ||
| 29 | u8 input_colors[4][4][4]; | ||
| 30 | bool any_alpha = false; | ||
| 31 | |||
| 32 | for (u32 j = 0; j < 4; j++) { | ||
| 33 | for (u32 i = 0; i < 4; i++) { | ||
| 34 | const size_t coord = | ||
| 35 | (z * plane_dim + (y + j) * width + (x + i)) * bytes_per_px; | ||
| 36 | |||
| 37 | if ((x + i < width) && (y + j < height)) { | ||
| 38 | if constexpr (ThresholdAlpha) { | ||
| 39 | if (data[coord + 3] >= alpha_threshold) { | ||
| 40 | input_colors[j][i][0] = data[coord + 0]; | ||
| 41 | input_colors[j][i][1] = data[coord + 1]; | ||
| 42 | input_colors[j][i][2] = data[coord + 2]; | ||
| 43 | input_colors[j][i][3] = 255; | ||
| 44 | } else { | ||
| 45 | any_alpha = true; | ||
| 46 | memset(input_colors[j][i], 0, bytes_per_px); | ||
| 47 | } | ||
| 48 | } else { | ||
| 49 | memcpy(input_colors[j][i], &data[coord], bytes_per_px); | ||
| 50 | } | ||
| 51 | } else { | ||
| 52 | memset(input_colors[j][i], 0, bytes_per_px); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | const u32 bytes_per_row = BytesPerBlock * Common::DivideUp(width, 4U); | ||
| 58 | const u32 bytes_per_plane = bytes_per_row * Common::DivideUp(height, 4U); | ||
| 59 | f(output.data() + z * bytes_per_plane + (y / 4) * bytes_per_row + | ||
| 60 | (x / 4) * BytesPerBlock, | ||
| 61 | reinterpret_cast<u8*>(input_colors), any_alpha); | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | workers.QueueWork(std::move(compress_row)); | ||
| 65 | } | ||
| 66 | workers.WaitForRequests(); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | void CompressBC1(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, | ||
| 71 | std::span<uint8_t> output) { | ||
| 72 | CompressBCN<8, true>(data, width, height, depth, output, | ||
| 73 | [](u8* block_output, const u8* block_input, bool any_alpha) { | ||
| 74 | stb_compress_bc1_block(block_output, block_input, any_alpha, | ||
| 75 | STB_DXT_NORMAL); | ||
| 76 | }); | ||
| 77 | } | ||
| 78 | |||
| 79 | void CompressBC3(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, | ||
| 80 | std::span<uint8_t> output) { | ||
| 81 | CompressBCN<16, false>(data, width, height, depth, output, | ||
| 82 | [](u8* block_output, const u8* block_input, bool any_alpha) { | ||
| 83 | stb_compress_bc3_block(block_output, block_input, STB_DXT_NORMAL); | ||
| 84 | }); | ||
| 85 | } | ||
| 86 | |||
| 87 | } // namespace Tegra::Texture::BCN | ||
diff --git a/src/video_core/textures/bcn.h b/src/video_core/textures/bcn.h new file mode 100644 index 000000000..6464af885 --- /dev/null +++ b/src/video_core/textures/bcn.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <span> | ||
| 7 | #include <stdint.h> | ||
| 8 | |||
| 9 | namespace Tegra::Texture::BCN { | ||
| 10 | |||
| 11 | void CompressBC1(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, | ||
| 12 | std::span<uint8_t> output); | ||
| 13 | |||
| 14 | void CompressBC3(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, | ||
| 15 | std::span<uint8_t> output); | ||
| 16 | |||
| 17 | } // namespace Tegra::Texture::BCN | ||
diff --git a/src/video_core/textures/workers.cpp b/src/video_core/textures/workers.cpp new file mode 100644 index 000000000..a71c305f4 --- /dev/null +++ b/src/video_core/textures/workers.cpp | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "video_core/textures/workers.h" | ||
| 5 | |||
| 6 | namespace Tegra::Texture { | ||
| 7 | |||
| 8 | Common::ThreadWorker& GetThreadWorkers() { | ||
| 9 | static Common::ThreadWorker workers{std::max(std::thread::hardware_concurrency(), 2U) / 2, | ||
| 10 | "ImageTranscode"}; | ||
| 11 | |||
| 12 | return workers; | ||
| 13 | } | ||
| 14 | |||
| 15 | } // namespace Tegra::Texture | ||
diff --git a/src/video_core/textures/workers.h b/src/video_core/textures/workers.h new file mode 100644 index 000000000..008dd05b3 --- /dev/null +++ b/src/video_core/textures/workers.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/thread_worker.h" | ||
| 7 | |||
| 8 | namespace Tegra::Texture { | ||
| 9 | |||
| 10 | Common::ThreadWorker& GetThreadWorkers(); | ||
| 11 | |||
| 12 | } | ||