summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-07 20:38:14 -0300
committerGravatar ReinUsesLisp2020-04-07 20:38:14 -0300
commitd7db0881808376864eb71eb5dde8b651a5cf891d (patch)
treefceb12bc74d567151cb15da8b51001683dc12976 /src
parentfile_sys: fix LayeredFS error when loading some games made with… (#3602) (diff)
downloadyuzu-d7db0881808376864eb71eb5dde8b651a5cf891d.tar.gz
yuzu-d7db0881808376864eb71eb5dde8b651a5cf891d.tar.xz
yuzu-d7db0881808376864eb71eb5dde8b651a5cf891d.zip
video_core/texture: Use a LUT to convert sRGB texture borders
This is a reversed look up table extracted from https://gist.github.com/rygorous/2203834#file-gistfile1-cpp-L41-L62 that is used in https://github.com/devkitPro/deko3d/blob/04d4e9e587fa3dc5447b43d273bc45f440226e41/source/maxwell/tsc_generate.cpp#L38 Games usually bind 0xFD expecting a float texture border of 1.0f. The conversion previous to this commit was multiplying the uint8 sRGB texture border color by 255. This is close to 1.0f but when that difference matters, some graphical glitches appear. This look up table is manually changed in the edges, clamping towards 0.0f and 1.0f. While we are at it, move this logic to its own translation unit.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/textures/texture.cpp58
-rw-r--r--src/video_core/textures/texture.h11
3 files changed, 61 insertions, 9 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index effe76a63..f7febd6a2 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -148,6 +148,7 @@ add_library(video_core STATIC
148 textures/convert.h 148 textures/convert.h
149 textures/decoders.cpp 149 textures/decoders.cpp
150 textures/decoders.h 150 textures/decoders.h
151 textures/texture.cpp
151 textures/texture.h 152 textures/texture.h
152 video_core.cpp 153 video_core.cpp
153 video_core.h 154 video_core.h
diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp
new file mode 100644
index 000000000..b1417db1e
--- /dev/null
+++ b/src/video_core/textures/texture.cpp
@@ -0,0 +1,58 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6
7#include "video_core/textures/texture.h"
8
9namespace Tegra::Texture {
10
11namespace {
12
13constexpr std::array<float, 256> SRGB_CONVERSION_LUT = {
14 0.000000f, 0.000000f, 0.000000f, 0.000012f, 0.000021f, 0.000033f, 0.000046f, 0.000062f,
15 0.000081f, 0.000102f, 0.000125f, 0.000151f, 0.000181f, 0.000214f, 0.000251f, 0.000293f,
16 0.000338f, 0.000388f, 0.000443f, 0.000503f, 0.000568f, 0.000639f, 0.000715f, 0.000798f,
17 0.000887f, 0.000983f, 0.001085f, 0.001195f, 0.001312f, 0.001437f, 0.001569f, 0.001710f,
18 0.001860f, 0.002019f, 0.002186f, 0.002364f, 0.002551f, 0.002748f, 0.002955f, 0.003174f,
19 0.003403f, 0.003643f, 0.003896f, 0.004160f, 0.004436f, 0.004725f, 0.005028f, 0.005343f,
20 0.005672f, 0.006015f, 0.006372f, 0.006744f, 0.007130f, 0.007533f, 0.007950f, 0.008384f,
21 0.008834f, 0.009301f, 0.009785f, 0.010286f, 0.010805f, 0.011342f, 0.011898f, 0.012472f,
22 0.013066f, 0.013680f, 0.014313f, 0.014967f, 0.015641f, 0.016337f, 0.017054f, 0.017793f,
23 0.018554f, 0.019337f, 0.020144f, 0.020974f, 0.021828f, 0.022706f, 0.023609f, 0.024536f,
24 0.025489f, 0.026468f, 0.027473f, 0.028504f, 0.029563f, 0.030649f, 0.031762f, 0.032904f,
25 0.034074f, 0.035274f, 0.036503f, 0.037762f, 0.039050f, 0.040370f, 0.041721f, 0.043103f,
26 0.044518f, 0.045964f, 0.047444f, 0.048956f, 0.050503f, 0.052083f, 0.053699f, 0.055349f,
27 0.057034f, 0.058755f, 0.060513f, 0.062307f, 0.064139f, 0.066008f, 0.067915f, 0.069861f,
28 0.071845f, 0.073869f, 0.075933f, 0.078037f, 0.080182f, 0.082369f, 0.084597f, 0.086867f,
29 0.089180f, 0.091535f, 0.093935f, 0.096378f, 0.098866f, 0.101398f, 0.103977f, 0.106601f,
30 0.109271f, 0.111988f, 0.114753f, 0.117565f, 0.120426f, 0.123335f, 0.126293f, 0.129301f,
31 0.132360f, 0.135469f, 0.138629f, 0.141841f, 0.145105f, 0.148421f, 0.151791f, 0.155214f,
32 0.158691f, 0.162224f, 0.165810f, 0.169453f, 0.173152f, 0.176907f, 0.180720f, 0.184589f,
33 0.188517f, 0.192504f, 0.196549f, 0.200655f, 0.204820f, 0.209046f, 0.213334f, 0.217682f,
34 0.222093f, 0.226567f, 0.231104f, 0.235704f, 0.240369f, 0.245099f, 0.249894f, 0.254754f,
35 0.259681f, 0.264674f, 0.269736f, 0.274864f, 0.280062f, 0.285328f, 0.290664f, 0.296070f,
36 0.301546f, 0.307094f, 0.312713f, 0.318404f, 0.324168f, 0.330006f, 0.335916f, 0.341902f,
37 0.347962f, 0.354097f, 0.360309f, 0.366597f, 0.372961f, 0.379403f, 0.385924f, 0.392524f,
38 0.399202f, 0.405960f, 0.412798f, 0.419718f, 0.426719f, 0.433802f, 0.440967f, 0.448216f,
39 0.455548f, 0.462965f, 0.470465f, 0.478052f, 0.485725f, 0.493484f, 0.501329f, 0.509263f,
40 0.517285f, 0.525396f, 0.533595f, 0.541885f, 0.550265f, 0.558736f, 0.567299f, 0.575954f,
41 0.584702f, 0.593542f, 0.602477f, 0.611507f, 0.620632f, 0.629852f, 0.639168f, 0.648581f,
42 0.658092f, 0.667700f, 0.677408f, 0.687214f, 0.697120f, 0.707127f, 0.717234f, 0.727443f,
43 0.737753f, 0.748167f, 0.758685f, 0.769305f, 0.780031f, 0.790861f, 0.801798f, 0.812839f,
44 0.823989f, 0.835246f, 0.846611f, 0.858085f, 0.869668f, 0.881360f, 0.893164f, 0.905078f,
45 0.917104f, 0.929242f, 0.941493f, 0.953859f, 0.966338f, 1.000000f, 1.000000f, 1.000000f,
46};
47
48} // Anonymous namespace
49
50std::array<float, 4> TSCEntry::GetBorderColor() const noexcept {
51 if (!srgb_conversion) {
52 return border_color;
53 }
54 return {SRGB_CONVERSION_LUT[srgb_border_color_r], SRGB_CONVERSION_LUT[srgb_border_color_g],
55 SRGB_CONVERSION_LUT[srgb_border_color_b], border_color[3]};
56}
57
58} // namespace Tegra::Texture
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index 7edc4abe1..262cd3cc1 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -336,6 +336,8 @@ struct TSCEntry {
336 std::array<u8, 0x20> raw; 336 std::array<u8, 0x20> raw;
337 }; 337 };
338 338
339 std::array<float, 4> GetBorderColor() const noexcept;
340
339 float GetMaxAnisotropy() const { 341 float GetMaxAnisotropy() const {
340 const u32 min_value = [] { 342 const u32 min_value = [] {
341 switch (static_cast<Anisotropy>(Settings::values.max_anisotropy)) { 343 switch (static_cast<Anisotropy>(Settings::values.max_anisotropy)) {
@@ -368,15 +370,6 @@ struct TSCEntry {
368 constexpr u32 mask = 1U << (13 - 1); 370 constexpr u32 mask = 1U << (13 - 1);
369 return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f; 371 return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f;
370 } 372 }
371
372 std::array<float, 4> GetBorderColor() const {
373 if (srgb_conversion) {
374 return {static_cast<float>(srgb_border_color_r) / 255.0f,
375 static_cast<float>(srgb_border_color_g) / 255.0f,
376 static_cast<float>(srgb_border_color_b) / 255.0f, border_color[3]};
377 }
378 return border_color;
379 }
380}; 373};
381static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); 374static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size");
382 375