summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-11-24 20:45:06 +0100
committerGravatar Fernando Sahmkow2022-11-24 21:00:48 +0100
commit826e0785bf6b852a4231f5f3d87655b2cf4e1856 (patch)
treed97e5d6cfb6e29b9c633699b86fb246ba61caacc /src
parentGPU: Implement additional render target formats. (diff)
downloadyuzu-826e0785bf6b852a4231f5f3d87655b2cf4e1856.tar.gz
yuzu-826e0785bf6b852a4231f5f3d87655b2cf4e1856.tar.xz
yuzu-826e0785bf6b852a4231f5f3d87655b2cf4e1856.zip
Fermi2D: Cleanup and address feedback.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/sw_blitter/blitter.cpp16
-rw-r--r--src/video_core/engines/sw_blitter/converter.cpp6
-rw-r--r--src/video_core/engines/sw_blitter/generate_converters.py136
3 files changed, 150 insertions, 8 deletions
diff --git a/src/video_core/engines/sw_blitter/blitter.cpp b/src/video_core/engines/sw_blitter/blitter.cpp
index c923a80e9..2f1ea4626 100644
--- a/src/video_core/engines/sw_blitter/blitter.cpp
+++ b/src/video_core/engines/sw_blitter/blitter.cpp
@@ -26,8 +26,8 @@ namespace {
26 26
27constexpr size_t ir_components = 4; 27constexpr size_t ir_components = 4;
28 28
29void NeighrestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_width, 29void NearestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_width, u32 src_height,
30 u32 src_height, u32 dst_width, u32 dst_height, size_t bpp) { 30 u32 dst_width, u32 dst_height, size_t bpp) {
31 const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32)); 31 const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32));
32 const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32)); 32 const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32));
33 size_t src_y = 0; 33 size_t src_y = 0;
@@ -44,8 +44,8 @@ void NeighrestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_
44 } 44 }
45} 45}
46 46
47void NeighrestNeighborFast(std::span<const f32> input, std::span<f32> output, u32 src_width, 47void NearestNeighborFast(std::span<const f32> input, std::span<f32> output, u32 src_width,
48 u32 src_height, u32 dst_width, u32 dst_height) { 48 u32 src_height, u32 dst_width, u32 dst_height) {
49 const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32)); 49 const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32));
50 const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32)); 50 const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32));
51 size_t src_y = 0; 51 size_t src_y = 0;
@@ -171,8 +171,8 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst,
171 src.format != dst.format || src_extent_x != dst_extent_x || src_extent_y != dst_extent_y; 171 src.format != dst.format || src_extent_x != dst_extent_x || src_extent_y != dst_extent_y;
172 172
173 const auto convertion_phase_same_format = [&]() { 173 const auto convertion_phase_same_format = [&]() {
174 NeighrestNeighbor(impl->src_buffer, impl->dst_buffer, src_extent_x, src_extent_y, 174 NearestNeighbor(impl->src_buffer, impl->dst_buffer, src_extent_x, src_extent_y,
175 dst_extent_x, dst_extent_y, dst_bytes_per_pixel); 175 dst_extent_x, dst_extent_y, dst_bytes_per_pixel);
176 }; 176 };
177 177
178 const auto convertion_phase_ir = [&]() { 178 const auto convertion_phase_ir = [&]() {
@@ -182,8 +182,8 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst,
182 input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src); 182 input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src);
183 183
184 if (config.filter != Fermi2D::Filter::Bilinear) { 184 if (config.filter != Fermi2D::Filter::Bilinear) {
185 NeighrestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x, 185 NearestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x,
186 src_extent_y, dst_extent_x, dst_extent_y); 186 src_extent_y, dst_extent_x, dst_extent_y);
187 } else { 187 } else {
188 Bilinear(impl->intermediate_src, impl->intermediate_dst, src_extent_x, src_extent_y, 188 Bilinear(impl->intermediate_src, impl->intermediate_dst, src_extent_x, src_extent_y,
189 dst_extent_x, dst_extent_y); 189 dst_extent_x, dst_extent_y);
diff --git a/src/video_core/engines/sw_blitter/converter.cpp b/src/video_core/engines/sw_blitter/converter.cpp
index 37c5eff69..cd46dfd4f 100644
--- a/src/video_core/engines/sw_blitter/converter.cpp
+++ b/src/video_core/engines/sw_blitter/converter.cpp
@@ -41,6 +41,12 @@ enum class ComponentType : u32 {
41 41
42namespace { 42namespace {
43 43
44/*
45 * Note: Use generate_converters.py to generate the structs and searches for new render target
46 * formats and copy paste them to this file in order to update. just call "python
47 * generate_converters.py" and get the code from the output. modify the file to add new formats.
48 */
49
44constexpr std::array<f32, 256> SRGB_TO_RGB_LUT = { 50constexpr std::array<f32, 256> SRGB_TO_RGB_LUT = {
45 0.000000e+00f, 3.035270e-04f, 6.070540e-04f, 9.105810e-04f, 1.214108e-03f, 1.517635e-03f, 51 0.000000e+00f, 3.035270e-04f, 6.070540e-04f, 9.105810e-04f, 1.214108e-03f, 1.517635e-03f,
46 1.821162e-03f, 2.124689e-03f, 2.428216e-03f, 2.731743e-03f, 3.035270e-03f, 3.346536e-03f, 52 1.821162e-03f, 2.124689e-03f, 2.428216e-03f, 2.731743e-03f, 3.035270e-03f, 3.346536e-03f,
diff --git a/src/video_core/engines/sw_blitter/generate_converters.py b/src/video_core/engines/sw_blitter/generate_converters.py
new file mode 100644
index 000000000..f641564f7
--- /dev/null
+++ b/src/video_core/engines/sw_blitter/generate_converters.py
@@ -0,0 +1,136 @@
1# SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-3.0-or-later
3
4import re
5
6class Format:
7 def __init__(self, string_value):
8 self.name = string_value
9 tmp = string_value.split('_')
10 self.component_type = tmp[1]
11 component_data = re.findall(r"\w\d+", tmp[0])
12 self.num_components = len(component_data)
13 sizes = []
14 swizzle = []
15 for data in component_data:
16 swizzle.append(data[0])
17 sizes.append(int(data[1:]))
18 self.sizes = sizes
19 self.swizzle = swizzle
20
21 def build_component_type_array(self):
22 result = "{ "
23 b = False
24 for i in range(0, self.num_components):
25 if b:
26 result += ", "
27 b = True
28 result += "ComponentType::" + self.component_type
29 result += " }"
30 return result
31
32 def build_component_sizes_array(self):
33 result = "{ "
34 b = False
35 for i in range(0, self.num_components):
36 if b:
37 result += ", "
38 b = True
39 result += str(self.sizes[i])
40 result += " }"
41 return result
42
43 def build_component_swizzle_array(self):
44 result = "{ "
45 b = False
46 for i in range(0, self.num_components):
47 if b:
48 result += ", "
49 b = True
50 swizzle = self.swizzle[i]
51 if swizzle == "X":
52 swizzle = "None"
53 result += "Swizzle::" + swizzle
54 result += " }"
55 return result
56
57 def print_declaration(self):
58 print("struct " + self.name + "Traits {")
59 print(" static constexpr size_t num_components = " + str(self.num_components) + ";")
60 print(" static constexpr std::array<ComponentType, num_components> component_types = " + self.build_component_type_array() + ";")
61 print(" static constexpr std::array<size_t, num_components> component_sizes = " + self.build_component_sizes_array() + ";")
62 print(" static constexpr std::array<Swizzle, num_components> component_swizzle = " + self.build_component_swizzle_array() + ";")
63 print("};\n")
64
65 def print_case(self):
66 print("case RenderTargetFormat::" + self.name + ":")
67 print(" return impl->converters_cache")
68 print(" .emplace(format, std::make_unique<ConverterImpl<" + self.name + "Traits>>())")
69 print(" .first->second.get();")
70 print(" break;")
71
72txt = """
73R32G32B32A32_FLOAT
74R32G32B32A32_SINT
75R32G32B32A32_UINT
76R32G32B32X32_FLOAT
77R32G32B32X32_SINT
78R32G32B32X32_UINT
79R16G16B16A16_UNORM
80R16G16B16A16_SNORM
81R16G16B16A16_SINT
82R16G16B16A16_UINT
83R16G16B16A16_FLOAT
84R32G32_FLOAT
85R32G32_SINT
86R32G32_UINT
87R16G16B16X16_FLOAT
88A8R8G8B8_UNORM
89A8R8G8B8_SRGB
90A2B10G10R10_UNORM
91A2B10G10R10_UINT
92A2R10G10B10_UNORM
93A8B8G8R8_UNORM
94A8B8G8R8_SRGB
95A8B8G8R8_SNORM
96A8B8G8R8_SINT
97A8B8G8R8_UINT
98R16G16_UNORM
99R16G16_SNORM
100R16G16_SINT
101R16G16_UINT
102R16G16_FLOAT
103B10G11R11_FLOAT
104R32_SINT
105R32_UINT
106R32_FLOAT
107X8R8G8B8_UNORM
108X8R8G8B8_SRGB
109R5G6B5_UNORM
110A1R5G5B5_UNORM
111R8G8_UNORM
112R8G8_SNORM
113R8G8_SINT
114R8G8_UINT
115R16_UNORM
116R16_SNORM
117R16_SINT
118R16_UINT
119R16_FLOAT
120R8_UNORM
121R8_SNORM
122R8_SINT
123R8_UINT
124X1R5G5B5_UNORM
125X8B8G8R8_UNORM
126X8B8G8R8_SRGB
127"""
128
129x = txt.split()
130y = list(map(lambda a: Format(a), x))
131formats = list(y)
132for format in formats:
133 format.print_declaration()
134
135for format in formats:
136 format.print_case()