summaryrefslogtreecommitdiff
path: root/src/video_core/textures
diff options
context:
space:
mode:
authorGravatar Liam2023-05-20 17:15:36 -0400
committerGravatar Liam2023-05-23 12:54:40 -0400
commit415c78b87c008f0d963679ea9bc06c8aa566b506 (patch)
tree11e6a5d2211a99660a48678059c703e849c06da3 /src/video_core/textures
parentMerge pull request #10392 from danilaml/update-cubeb-again (diff)
downloadyuzu-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.cpp5
-rw-r--r--src/video_core/textures/bcn.cpp87
-rw-r--r--src/video_core/textures/bcn.h17
-rw-r--r--src/video_core/textures/workers.cpp15
-rw-r--r--src/video_core/textures/workers.h12
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
22class InputBitStream { 22class InputBitStream {
23public: 23public:
@@ -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
11namespace Tegra::Texture::BCN {
12
13using BCNCompressor = void(u8* block_output, const u8* block_input, bool any_alpha);
14
15template <u32 BytesPerBlock, bool ThresholdAlpha = false>
16void 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
70void 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
79void 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
9namespace Tegra::Texture::BCN {
10
11void CompressBC1(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
12 std::span<uint8_t> output);
13
14void 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
6namespace Tegra::Texture {
7
8Common::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
8namespace Tegra::Texture {
9
10Common::ThreadWorker& GetThreadWorkers();
11
12}