From 826e0785bf6b852a4231f5f3d87655b2cf4e1856 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 24 Nov 2022 20:45:06 +0100 Subject: [PATCH] Fermi2D: Cleanup and address feedback. --- src/video_core/engines/sw_blitter/blitter.cpp | 16 +-- .../engines/sw_blitter/converter.cpp | 6 + .../engines/sw_blitter/generate_converters.py | 136 ++++++++++++++++++ 3 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 src/video_core/engines/sw_blitter/generate_converters.py 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 input, std::span output, u32 src_width, - u32 src_height, u32 dst_width, u32 dst_height, size_t bpp) { +void NearestNeighbor(std::span input, std::span 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(src_width) / dst_width) * (1ULL << 32)); const size_t dy_dv = std::llround((static_cast(src_height) / dst_height) * (1ULL << 32)); size_t src_y = 0; @@ -44,8 +44,8 @@ void NeighrestNeighbor(std::span input, std::span output, u32 src_ } } -void NeighrestNeighborFast(std::span input, std::span output, u32 src_width, - u32 src_height, u32 dst_width, u32 dst_height) { +void NearestNeighborFast(std::span input, std::span output, u32 src_width, + u32 src_height, u32 dst_width, u32 dst_height) { const size_t dx_du = std::llround((static_cast(src_width) / dst_width) * (1ULL << 32)); const size_t dy_dv = std::llround((static_cast(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 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 component_types = " + self.build_component_type_array() + ";") + print(" static constexpr std::array component_sizes = " + self.build_component_sizes_array() + ";") + print(" static constexpr std::array 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>())") + 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()