summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {
constexpr size_t ir_components = 4;
-void NeighrestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_width,
- u32 src_height, u32 dst_width, u32 dst_height, size_t bpp) {
+void NearestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_width, u32 src_height,
+ u32 dst_width, u32 dst_height, size_t bpp) {
const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32));
const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32));
size_t src_y = 0;
@@ -44,8 +44,8 @@ void NeighrestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_
}
}
-void NeighrestNeighborFast(std::span<const f32> input, std::span<f32> output, u32 src_width,
- u32 src_height, u32 dst_width, u32 dst_height) {
+void NearestNeighborFast(std::span<const f32> input, std::span<f32> output, u32 src_width,
+ u32 src_height, u32 dst_width, u32 dst_height) {
const size_t dx_du = std::llround((static_cast<f64>(src_width) / dst_width) * (1ULL << 32));
const size_t dy_dv = std::llround((static_cast<f64>(src_height) / dst_height) * (1ULL << 32));
size_t src_y = 0;
@@ -171,8 +171,8 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst,
src.format != dst.format || src_extent_x != dst_extent_x || src_extent_y != dst_extent_y;
const auto convertion_phase_same_format = [&]() {
- NeighrestNeighbor(impl->src_buffer, impl->dst_buffer, src_extent_x, src_extent_y,
- dst_extent_x, dst_extent_y, dst_bytes_per_pixel);
+ NearestNeighbor(impl->src_buffer, impl->dst_buffer, src_extent_x, src_extent_y,
+ dst_extent_x, dst_extent_y, dst_bytes_per_pixel);
};
const auto convertion_phase_ir = [&]() {
@@ -182,8 +182,8 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst,
input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src);
if (config.filter != Fermi2D::Filter::Bilinear) {
- NeighrestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x,
- src_extent_y, dst_extent_x, dst_extent_y);
+ NearestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x,
+ src_extent_y, dst_extent_x, dst_extent_y);
} else {
Bilinear(impl->intermediate_src, impl->intermediate_dst, src_extent_x, src_extent_y,
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 {
namespace {
+/*
+ * Note: Use generate_converters.py to generate the structs and searches for new render target
+ * formats and copy paste them to this file in order to update. just call "python
+ * generate_converters.py" and get the code from the output. modify the file to add new formats.
+ */
+
constexpr std::array<f32, 256> SRGB_TO_RGB_LUT = {
0.000000e+00f, 3.035270e-04f, 6.070540e-04f, 9.105810e-04f, 1.214108e-03f, 1.517635e-03f,
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 @@
+# SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import re
+
+class Format:
+ def __init__(self, string_value):
+ self.name = string_value
+ tmp = string_value.split('_')
+ self.component_type = tmp[1]
+ component_data = re.findall(r"\w\d+", tmp[0])
+ self.num_components = len(component_data)
+ sizes = []
+ swizzle = []
+ for data in component_data:
+ swizzle.append(data[0])
+ sizes.append(int(data[1:]))
+ self.sizes = sizes
+ self.swizzle = swizzle
+
+ def build_component_type_array(self):
+ result = "{ "
+ b = False
+ for i in range(0, self.num_components):
+ if b:
+ result += ", "
+ b = True
+ result += "ComponentType::" + self.component_type
+ result += " }"
+ return result
+
+ def build_component_sizes_array(self):
+ result = "{ "
+ b = False
+ for i in range(0, self.num_components):
+ if b:
+ result += ", "
+ b = True
+ result += str(self.sizes[i])
+ result += " }"
+ return result
+
+ def build_component_swizzle_array(self):
+ result = "{ "
+ b = False
+ for i in range(0, self.num_components):
+ if b:
+ result += ", "
+ b = True
+ swizzle = self.swizzle[i]
+ if swizzle == "X":
+ swizzle = "None"
+ result += "Swizzle::" + swizzle
+ result += " }"
+ return result
+
+ def print_declaration(self):
+ print("struct " + self.name + "Traits {")
+ print(" static constexpr size_t num_components = " + str(self.num_components) + ";")
+ print(" static constexpr std::array<ComponentType, num_components> component_types = " + self.build_component_type_array() + ";")
+ print(" static constexpr std::array<size_t, num_components> component_sizes = " + self.build_component_sizes_array() + ";")
+ print(" static constexpr std::array<Swizzle, num_components> component_swizzle = " + self.build_component_swizzle_array() + ";")
+ print("};\n")
+
+ def print_case(self):
+ print("case RenderTargetFormat::" + self.name + ":")
+ print(" return impl->converters_cache")
+ print(" .emplace(format, std::make_unique<ConverterImpl<" + self.name + "Traits>>())")
+ print(" .first->second.get();")
+ print(" break;")
+
+txt = """
+R32G32B32A32_FLOAT
+R32G32B32A32_SINT
+R32G32B32A32_UINT
+R32G32B32X32_FLOAT
+R32G32B32X32_SINT
+R32G32B32X32_UINT
+R16G16B16A16_UNORM
+R16G16B16A16_SNORM
+R16G16B16A16_SINT
+R16G16B16A16_UINT
+R16G16B16A16_FLOAT
+R32G32_FLOAT
+R32G32_SINT
+R32G32_UINT
+R16G16B16X16_FLOAT
+A8R8G8B8_UNORM
+A8R8G8B8_SRGB
+A2B10G10R10_UNORM
+A2B10G10R10_UINT
+A2R10G10B10_UNORM
+A8B8G8R8_UNORM
+A8B8G8R8_SRGB
+A8B8G8R8_SNORM
+A8B8G8R8_SINT
+A8B8G8R8_UINT
+R16G16_UNORM
+R16G16_SNORM
+R16G16_SINT
+R16G16_UINT
+R16G16_FLOAT
+B10G11R11_FLOAT
+R32_SINT
+R32_UINT
+R32_FLOAT
+X8R8G8B8_UNORM
+X8R8G8B8_SRGB
+R5G6B5_UNORM
+A1R5G5B5_UNORM
+R8G8_UNORM
+R8G8_SNORM
+R8G8_SINT
+R8G8_UINT
+R16_UNORM
+R16_SNORM
+R16_SINT
+R16_UINT
+R16_FLOAT
+R8_UNORM
+R8_SNORM
+R8_SINT
+R8_UINT
+X1R5G5B5_UNORM
+X8B8G8R8_UNORM
+X8B8G8R8_SRGB
+"""
+
+x = txt.split()
+y = list(map(lambda a: Format(a), x))
+formats = list(y)
+for format in formats:
+ format.print_declaration()
+
+for format in formats:
+ format.print_case()