diff options
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/engines/sw_blitter/blitter.cpp | 97 | ||||
| -rw-r--r-- | src/video_core/engines/sw_blitter/blitter.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/sw_blitter/converter.cpp | 171 | ||||
| -rw-r--r-- | src/video_core/engines/sw_blitter/converter.h | 9 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 4 | ||||
| -rw-r--r-- | src/video_core/surface.cpp | 2 |
7 files changed, 180 insertions, 116 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 2c722c778..c6478ae85 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -62,11 +62,15 @@ void Fermi2D::Blit() { | |||
| 62 | 62 | ||
| 63 | const auto& args = regs.pixels_from_memory; | 63 | const auto& args = regs.pixels_from_memory; |
| 64 | constexpr s64 null_derivate = 1ULL << 32; | 64 | constexpr s64 null_derivate = 1ULL << 32; |
| 65 | Surface src = regs.src; | ||
| 66 | const auto bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format)); | ||
| 67 | const bool delegate_to_gpu = src.width > 512 && src.height > 512 && bytes_per_pixel <= 8 && | ||
| 68 | src.format != regs.dst.format; | ||
| 65 | Config config{ | 69 | Config config{ |
| 66 | .operation = regs.operation, | 70 | .operation = regs.operation, |
| 67 | .filter = args.sample_mode.filter, | 71 | .filter = args.sample_mode.filter, |
| 68 | .must_accelerate = args.du_dx != null_derivate || args.dv_dy != null_derivate || | 72 | .must_accelerate = |
| 69 | args.sample_mode.filter == Filter::Bilinear, | 73 | args.du_dx != null_derivate || args.dv_dy != null_derivate || delegate_to_gpu, |
| 70 | .dst_x0 = args.dst_x0, | 74 | .dst_x0 = args.dst_x0, |
| 71 | .dst_y0 = args.dst_y0, | 75 | .dst_y0 = args.dst_y0, |
| 72 | .dst_x1 = args.dst_x0 + args.dst_width, | 76 | .dst_x1 = args.dst_x0 + args.dst_width, |
| @@ -76,8 +80,7 @@ void Fermi2D::Blit() { | |||
| 76 | .src_x1 = static_cast<s32>((args.du_dx * args.dst_width + args.src_x0) >> 32), | 80 | .src_x1 = static_cast<s32>((args.du_dx * args.dst_width + args.src_x0) >> 32), |
| 77 | .src_y1 = static_cast<s32>((args.dv_dy * args.dst_height + args.src_y0) >> 32), | 81 | .src_y1 = static_cast<s32>((args.dv_dy * args.dst_height + args.src_y0) >> 32), |
| 78 | }; | 82 | }; |
| 79 | Surface src = regs.src; | 83 | |
| 80 | const auto bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format)); | ||
| 81 | const auto need_align_to_pitch = | 84 | const auto need_align_to_pitch = |
| 82 | src.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch && | 85 | src.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch && |
| 83 | static_cast<s32>(src.width) == config.src_x1 && | 86 | static_cast<s32>(src.width) == config.src_x1 && |
diff --git a/src/video_core/engines/sw_blitter/blitter.cpp b/src/video_core/engines/sw_blitter/blitter.cpp index caf51cbe3..c923a80e9 100644 --- a/src/video_core/engines/sw_blitter/blitter.cpp +++ b/src/video_core/engines/sw_blitter/blitter.cpp | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | ||
| 5 | #include <cmath> | ||
| 4 | #include <vector> | 6 | #include <vector> |
| 5 | 7 | ||
| 6 | #include "video_core/engines/sw_blitter/blitter.h" | 8 | #include "video_core/engines/sw_blitter/blitter.h" |
| @@ -22,8 +24,10 @@ using namespace Texture; | |||
| 22 | 24 | ||
| 23 | namespace { | 25 | namespace { |
| 24 | 26 | ||
| 25 | void NeighrestNeighbor(std::span<u8> input, std::span<u8> output, u32 src_width, u32 src_height, | 27 | constexpr size_t ir_components = 4; |
| 26 | u32 dst_width, u32 dst_height, size_t bpp) { | 28 | |
| 29 | void NeighrestNeighbor(std::span<const u8> input, std::span<u8> output, u32 src_width, | ||
| 30 | u32 src_height, u32 dst_width, u32 dst_height, size_t bpp) { | ||
| 27 | 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)); |
| 28 | 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)); |
| 29 | size_t src_y = 0; | 33 | size_t src_y = 0; |
| @@ -40,7 +44,7 @@ void NeighrestNeighbor(std::span<u8> input, std::span<u8> output, u32 src_width, | |||
| 40 | } | 44 | } |
| 41 | } | 45 | } |
| 42 | 46 | ||
| 43 | void NeighrestNeighborFast(std::span<f32> input, std::span<f32> output, u32 src_width, | 47 | void NeighrestNeighborFast(std::span<const f32> input, std::span<f32> output, u32 src_width, |
| 44 | u32 src_height, u32 dst_width, u32 dst_height) { | 48 | u32 src_height, u32 dst_width, u32 dst_height) { |
| 45 | 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)); |
| 46 | 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)); |
| @@ -48,44 +52,62 @@ void NeighrestNeighborFast(std::span<f32> input, std::span<f32> output, u32 src_ | |||
| 48 | for (u32 y = 0; y < dst_height; y++) { | 52 | for (u32 y = 0; y < dst_height; y++) { |
| 49 | size_t src_x = 0; | 53 | size_t src_x = 0; |
| 50 | for (u32 x = 0; x < dst_width; x++) { | 54 | for (u32 x = 0; x < dst_width; x++) { |
| 51 | const size_t read_from = ((src_y * src_width + src_x) >> 32) * 4; | 55 | const size_t read_from = ((src_y * src_width + src_x) >> 32) * ir_components; |
| 52 | const size_t write_to = (y * dst_width + x) * 4; | 56 | const size_t write_to = (y * dst_width + x) * ir_components; |
| 53 | 57 | ||
| 54 | std::memcpy(&output[write_to], &input[read_from], sizeof(f32) * 4); | 58 | std::memcpy(&output[write_to], &input[read_from], sizeof(f32) * ir_components); |
| 55 | src_x += dx_du; | 59 | src_x += dx_du; |
| 56 | } | 60 | } |
| 57 | src_y += dy_dv; | 61 | src_y += dy_dv; |
| 58 | } | 62 | } |
| 59 | } | 63 | } |
| 60 | 64 | ||
| 61 | /* | 65 | void Bilinear(std::span<const f32> input, std::span<f32> output, size_t src_width, |
| 62 | void Bilinear(std::span<f32> input, std::span<f32> output, size_t src_width, | 66 | size_t src_height, size_t dst_width, size_t dst_height) { |
| 63 | size_t src_height, size_t dst_width, size_t dst_height) { | 67 | const auto bilinear_sample = [](std::span<const f32> x0_y0, std::span<const f32> x1_y0, |
| 64 | const auto inv_lerp = [](u32 coord, u32 end) { return | 68 | std::span<const f32> x0_y1, std::span<const f32> x1_y1, |
| 65 | static_cast<f32>(std::min(std::max(static_cast<s32>(coord), 0), end - 1)) / (end); }; | 69 | f32 weight_x, f32 weight_y) { |
| 66 | 70 | std::array<f32, ir_components> result{}; | |
| 67 | 71 | for (size_t i = 0; i < ir_components; i++) { | |
| 72 | const f32 a = std::lerp(x0_y0[i], x1_y0[i], weight_x); | ||
| 73 | const f32 b = std::lerp(x0_y1[i], x1_y1[i], weight_x); | ||
| 74 | result[i] = std::lerp(a, b, weight_y); | ||
| 75 | } | ||
| 76 | return result; | ||
| 77 | }; | ||
| 78 | const f32 dx_du = | ||
| 79 | dst_width > 1 ? static_cast<f32>(src_width - 1) / static_cast<f32>(dst_width - 1) : 0.f; | ||
| 80 | const f32 dy_dv = | ||
| 81 | dst_height > 1 ? static_cast<f32>(src_height - 1) / static_cast<f32>(dst_height - 1) : 0.f; | ||
| 68 | for (u32 y = 0; y < dst_height; y++) { | 82 | for (u32 y = 0; y < dst_height; y++) { |
| 69 | const f32 ty_0 = inv_lerp(y, dst_extent_y); | ||
| 70 | const f32 ty_1 = inv_lerp(y + 1, dst_extent_y); | ||
| 71 | for (u32 x = 0; x < dst_width; x++) { | 83 | for (u32 x = 0; x < dst_width; x++) { |
| 72 | const f32 tx_0 = inv_lerp(x, dst_extent_x); | 84 | const f32 x_low = std::floor(static_cast<f32>(x) * dx_du); |
| 73 | const f32 tx_1 = inv_lerp(x + 1, dst_extent_x); | 85 | const f32 y_low = std::floor(static_cast<f32>(y) * dy_dv); |
| 74 | const std::array<f32, 4> get_pixel = [&](f32 tx, f32 ty, u32 width, u32 height) { | 86 | const f32 x_high = std::ceil(static_cast<f32>(x) * dx_du); |
| 75 | std::array<f32, 4> result{}; | 87 | const f32 y_high = std::ceil(static_cast<f32>(y) * dy_dv); |
| 76 | 88 | const f32 weight_x = (static_cast<f32>(x) * dx_du) - x_low; | |
| 77 | return (std::llround(width * tx) + std::llround(height * ty) * width) * 4; | 89 | const f32 weight_y = (static_cast<f32>(y) * dy_dv) - y_low; |
| 90 | |||
| 91 | const auto read_src = [&](f32 in_x, f32 in_y) { | ||
| 92 | const size_t read_from = | ||
| 93 | ((static_cast<size_t>(in_x) * src_width + static_cast<size_t>(in_y)) >> 32) * | ||
| 94 | ir_components; | ||
| 95 | return std::span<const f32>(&input[read_from], ir_components); | ||
| 78 | }; | 96 | }; |
| 79 | std::array<f32, 4> result{}; | ||
| 80 | 97 | ||
| 81 | const size_t read_from = get_pixel(src_width, src_height); | 98 | auto x0_y0 = read_src(x_low, y_low); |
| 82 | const size_t write_to = get_pixel(tx_0, ty_0, dst_width, dst_height); | 99 | auto x1_y0 = read_src(x_high, y_low); |
| 100 | auto x0_y1 = read_src(x_low, y_high); | ||
| 101 | auto x1_y1 = read_src(x_high, y_high); | ||
| 83 | 102 | ||
| 84 | std::memcpy(&output[write_to], &input[read_from], bpp); | 103 | const auto result = bilinear_sample(x0_y0, x1_y0, x0_y1, x1_y1, weight_x, weight_y); |
| 104 | |||
| 105 | const size_t write_to = (y * dst_width + x) * ir_components; | ||
| 106 | |||
| 107 | std::memcpy(&output[write_to], &result, sizeof(f32) * ir_components); | ||
| 85 | } | 108 | } |
| 86 | } | 109 | } |
| 87 | } | 110 | } |
| 88 | */ | ||
| 89 | 111 | ||
| 90 | } // namespace | 112 | } // namespace |
| 91 | 113 | ||
| @@ -107,8 +129,6 @@ SoftwareBlitEngine::~SoftwareBlitEngine() = default; | |||
| 107 | 129 | ||
| 108 | bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | 130 | bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, |
| 109 | Fermi2D::Config& config) { | 131 | Fermi2D::Config& config) { |
| 110 | UNIMPLEMENTED_IF(config.filter == Fermi2D::Filter::Bilinear); | ||
| 111 | |||
| 112 | const auto get_surface_size = [](Fermi2D::Surface& surface, u32 bytes_per_pixel) { | 132 | const auto get_surface_size = [](Fermi2D::Surface& surface, u32 bytes_per_pixel) { |
| 113 | if (surface.linear == Fermi2D::MemoryLayout::BlockLinear) { | 133 | if (surface.linear == Fermi2D::MemoryLayout::BlockLinear) { |
| 114 | return CalculateSize(true, bytes_per_pixel, surface.width, surface.height, | 134 | return CalculateSize(true, bytes_per_pixel, surface.width, surface.height, |
| @@ -116,9 +136,9 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 116 | } | 136 | } |
| 117 | return static_cast<size_t>(surface.pitch * surface.height); | 137 | return static_cast<size_t>(surface.pitch * surface.height); |
| 118 | }; | 138 | }; |
| 119 | const auto process_pitch_linear = [](bool unpack, std::span<u8> input, std::span<u8> output, | 139 | const auto process_pitch_linear = [](bool unpack, std::span<const u8> input, |
| 120 | u32 extent_x, u32 extent_y, u32 pitch, u32 x0, u32 y0, | 140 | std::span<u8> output, u32 extent_x, u32 extent_y, |
| 121 | size_t bpp) { | 141 | u32 pitch, u32 x0, u32 y0, size_t bpp) { |
| 122 | const size_t base_offset = x0 * bpp; | 142 | const size_t base_offset = x0 * bpp; |
| 123 | const size_t copy_size = extent_x * bpp; | 143 | const size_t copy_size = extent_x * bpp; |
| 124 | for (u32 y = y0; y < extent_y; y++) { | 144 | for (u32 y = y0; y < extent_y; y++) { |
| @@ -157,12 +177,17 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 157 | 177 | ||
| 158 | const auto convertion_phase_ir = [&]() { | 178 | const auto convertion_phase_ir = [&]() { |
| 159 | auto* input_converter = impl->converter_factory.GetFormatConverter(src.format); | 179 | auto* input_converter = impl->converter_factory.GetFormatConverter(src.format); |
| 160 | impl->intermediate_src.resize((src_copy_size / src_bytes_per_pixel) * 4); | 180 | impl->intermediate_src.resize((src_copy_size / src_bytes_per_pixel) * ir_components); |
| 161 | impl->intermediate_dst.resize((dst_copy_size / dst_bytes_per_pixel) * 4); | 181 | impl->intermediate_dst.resize((dst_copy_size / dst_bytes_per_pixel) * ir_components); |
| 162 | input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src); | 182 | input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src); |
| 163 | 183 | ||
| 164 | NeighrestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x, | 184 | if (config.filter != Fermi2D::Filter::Bilinear) { |
| 165 | src_extent_y, dst_extent_x, dst_extent_y); | 185 | NeighrestNeighborFast(impl->intermediate_src, impl->intermediate_dst, src_extent_x, |
| 186 | src_extent_y, dst_extent_x, dst_extent_y); | ||
| 187 | } else { | ||
| 188 | Bilinear(impl->intermediate_src, impl->intermediate_dst, src_extent_x, src_extent_y, | ||
| 189 | dst_extent_x, dst_extent_y); | ||
| 190 | } | ||
| 166 | 191 | ||
| 167 | auto* output_converter = impl->converter_factory.GetFormatConverter(dst.format); | 192 | auto* output_converter = impl->converter_factory.GetFormatConverter(dst.format); |
| 168 | output_converter->ConvertFrom(impl->intermediate_dst, impl->dst_buffer); | 193 | output_converter->ConvertFrom(impl->intermediate_dst, impl->dst_buffer); |
| @@ -183,7 +208,7 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 183 | 208 | ||
| 184 | // Conversion Phase | 209 | // Conversion Phase |
| 185 | if (no_passthrough) { | 210 | if (no_passthrough) { |
| 186 | if (src.format != dst.format) { | 211 | if (src.format != dst.format || config.filter == Fermi2D::Filter::Bilinear) { |
| 187 | convertion_phase_ir(); | 212 | convertion_phase_ir(); |
| 188 | } else { | 213 | } else { |
| 189 | convertion_phase_same_format(); | 214 | convertion_phase_same_format(); |
diff --git a/src/video_core/engines/sw_blitter/blitter.h b/src/video_core/engines/sw_blitter/blitter.h index 3edf40c3e..85b55c836 100644 --- a/src/video_core/engines/sw_blitter/blitter.h +++ b/src/video_core/engines/sw_blitter/blitter.h | |||
| @@ -13,7 +13,7 @@ namespace Tegra::Engines::Blitter { | |||
| 13 | 13 | ||
| 14 | class SoftwareBlitEngine { | 14 | class SoftwareBlitEngine { |
| 15 | public: | 15 | public: |
| 16 | SoftwareBlitEngine(MemoryManager& memory_manager_); | 16 | explicit SoftwareBlitEngine(MemoryManager& memory_manager_); |
| 17 | ~SoftwareBlitEngine(); | 17 | ~SoftwareBlitEngine(); |
| 18 | 18 | ||
| 19 | bool Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, Fermi2D::Config& copy_config); | 19 | bool Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, Fermi2D::Config& copy_config); |
diff --git a/src/video_core/engines/sw_blitter/converter.cpp b/src/video_core/engines/sw_blitter/converter.cpp index 2e376f430..408d87944 100644 --- a/src/video_core/engines/sw_blitter/converter.cpp +++ b/src/video_core/engines/sw_blitter/converter.cpp | |||
| @@ -139,7 +139,7 @@ struct R32B32G32A32_FLOATTraits { | |||
| 139 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; | 139 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; |
| 140 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; | 140 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; |
| 141 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 141 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 142 | Swizzle::A, Swizzle::G, Swizzle::B, Swizzle::R}; | 142 | Swizzle::R, Swizzle::B, Swizzle::G, Swizzle::A}; |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | struct R32G32B32A32_SINTTraits { | 145 | struct R32G32B32A32_SINTTraits { |
| @@ -148,7 +148,7 @@ struct R32G32B32A32_SINTTraits { | |||
| 148 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; | 148 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; |
| 149 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; | 149 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; |
| 150 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 150 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 151 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 151 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | struct R32G32B32A32_UINTTraits { | 154 | struct R32G32B32A32_UINTTraits { |
| @@ -157,7 +157,7 @@ struct R32G32B32A32_UINTTraits { | |||
| 157 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; | 157 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; |
| 158 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; | 158 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32}; |
| 159 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 159 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 160 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 160 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 161 | }; | 161 | }; |
| 162 | 162 | ||
| 163 | struct R16G16B16A16_UNORMTraits { | 163 | struct R16G16B16A16_UNORMTraits { |
| @@ -166,7 +166,7 @@ struct R16G16B16A16_UNORMTraits { | |||
| 166 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 166 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 167 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 167 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 168 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 168 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 169 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 169 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 170 | }; | 170 | }; |
| 171 | 171 | ||
| 172 | struct R16G16B16A16_SNORMTraits { | 172 | struct R16G16B16A16_SNORMTraits { |
| @@ -175,7 +175,7 @@ struct R16G16B16A16_SNORMTraits { | |||
| 175 | ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM}; | 175 | ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM}; |
| 176 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 176 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 177 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 177 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 178 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 178 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | struct R16G16B16A16_SINTTraits { | 181 | struct R16G16B16A16_SINTTraits { |
| @@ -184,7 +184,7 @@ struct R16G16B16A16_SINTTraits { | |||
| 184 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; | 184 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; |
| 185 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 185 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 186 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 186 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 187 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 187 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 188 | }; | 188 | }; |
| 189 | 189 | ||
| 190 | struct R16G16B16A16_UINTTraits { | 190 | struct R16G16B16A16_UINTTraits { |
| @@ -193,7 +193,7 @@ struct R16G16B16A16_UINTTraits { | |||
| 193 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; | 193 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; |
| 194 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 194 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 195 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 195 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 196 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 196 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | struct R16G16B16A16_FLOATTraits { | 199 | struct R16G16B16A16_FLOATTraits { |
| @@ -202,7 +202,7 @@ struct R16G16B16A16_FLOATTraits { | |||
| 202 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; | 202 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; |
| 203 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 203 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 204 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 204 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 205 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; | 205 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | struct R32G32_FLOATTraits { | 208 | struct R32G32_FLOATTraits { |
| @@ -210,8 +210,8 @@ struct R32G32_FLOATTraits { | |||
| 210 | static constexpr std::array<ComponentType, num_components> component_types = { | 210 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 211 | ComponentType::FLOAT, ComponentType::FLOAT}; | 211 | ComponentType::FLOAT, ComponentType::FLOAT}; |
| 212 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; | 212 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; |
| 213 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 213 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 214 | Swizzle::R}; | 214 | Swizzle::G}; |
| 215 | }; | 215 | }; |
| 216 | 216 | ||
| 217 | struct R32G32_SINTTraits { | 217 | struct R32G32_SINTTraits { |
| @@ -219,8 +219,8 @@ struct R32G32_SINTTraits { | |||
| 219 | static constexpr std::array<ComponentType, num_components> component_types = { | 219 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 220 | ComponentType::SINT, ComponentType::SINT}; | 220 | ComponentType::SINT, ComponentType::SINT}; |
| 221 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; | 221 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; |
| 222 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 222 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 223 | Swizzle::R}; | 223 | Swizzle::G}; |
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | struct R32G32_UINTTraits { | 226 | struct R32G32_UINTTraits { |
| @@ -228,8 +228,8 @@ struct R32G32_UINTTraits { | |||
| 228 | static constexpr std::array<ComponentType, num_components> component_types = { | 228 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 229 | ComponentType::UINT, ComponentType::UINT}; | 229 | ComponentType::UINT, ComponentType::UINT}; |
| 230 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; | 230 | static constexpr std::array<size_t, num_components> component_sizes = {32, 32}; |
| 231 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 231 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 232 | Swizzle::R}; | 232 | Swizzle::G}; |
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | struct R16G16B16X16_FLOATTraits { | 235 | struct R16G16B16X16_FLOATTraits { |
| @@ -238,7 +238,7 @@ struct R16G16B16X16_FLOATTraits { | |||
| 238 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; | 238 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; |
| 239 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; | 239 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16}; |
| 240 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 240 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 241 | Swizzle::None, Swizzle::B, Swizzle::G, Swizzle::R}; | 241 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::None}; |
| 242 | }; | 242 | }; |
| 243 | 243 | ||
| 244 | struct A8R8G8B8_UNORMTraits { | 244 | struct A8R8G8B8_UNORMTraits { |
| @@ -247,7 +247,7 @@ struct A8R8G8B8_UNORMTraits { | |||
| 247 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 247 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 248 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 248 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 249 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 249 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 250 | Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A}; | 250 | Swizzle::A, Swizzle::R, Swizzle::G, Swizzle::B}; |
| 251 | }; | 251 | }; |
| 252 | 252 | ||
| 253 | struct A8R8G8B8_SRGBTraits { | 253 | struct A8R8G8B8_SRGBTraits { |
| @@ -256,25 +256,25 @@ struct A8R8G8B8_SRGBTraits { | |||
| 256 | ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; | 256 | ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; |
| 257 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 257 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 258 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 258 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 259 | Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A}; | 259 | Swizzle::A, Swizzle::R, Swizzle::G, Swizzle::B}; |
| 260 | }; | 260 | }; |
| 261 | 261 | ||
| 262 | struct A2B10G10R10_UNORMTraits { | 262 | struct A2B10G10R10_UNORMTraits { |
| 263 | static constexpr size_t num_components = 4; | 263 | static constexpr size_t num_components = 4; |
| 264 | static constexpr std::array<ComponentType, num_components> component_types = { | 264 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 265 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 265 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 266 | static constexpr std::array<size_t, num_components> component_sizes = {10, 10, 10, 2}; | 266 | static constexpr std::array<size_t, num_components> component_sizes = {2, 10, 10, 10}; |
| 267 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 267 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 268 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 268 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 269 | }; | 269 | }; |
| 270 | 270 | ||
| 271 | struct A2B10G10R10_UINTTraits { | 271 | struct A2B10G10R10_UINTTraits { |
| 272 | static constexpr size_t num_components = 4; | 272 | static constexpr size_t num_components = 4; |
| 273 | static constexpr std::array<ComponentType, num_components> component_types = { | 273 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 274 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; | 274 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; |
| 275 | static constexpr std::array<size_t, num_components> component_sizes = {10, 10, 10, 2}; | 275 | static constexpr std::array<size_t, num_components> component_sizes = {2, 10, 10, 10}; |
| 276 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 276 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 277 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 277 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 278 | }; | 278 | }; |
| 279 | 279 | ||
| 280 | struct A8B8G8R8_UNORMTraits { | 280 | struct A8B8G8R8_UNORMTraits { |
| @@ -283,7 +283,7 @@ struct A8B8G8R8_UNORMTraits { | |||
| 283 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 283 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 284 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 284 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 285 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 285 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 286 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 286 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | struct A8B8G8R8_SRGBTraits { | 289 | struct A8B8G8R8_SRGBTraits { |
| @@ -292,7 +292,7 @@ struct A8B8G8R8_SRGBTraits { | |||
| 292 | ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; | 292 | ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; |
| 293 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 293 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 294 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 294 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 295 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 295 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 296 | }; | 296 | }; |
| 297 | 297 | ||
| 298 | struct A8B8G8R8_SNORMTraits { | 298 | struct A8B8G8R8_SNORMTraits { |
| @@ -301,7 +301,7 @@ struct A8B8G8R8_SNORMTraits { | |||
| 301 | ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM}; | 301 | ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM}; |
| 302 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 302 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 303 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 303 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 304 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 304 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 305 | }; | 305 | }; |
| 306 | 306 | ||
| 307 | struct A8B8G8R8_SINTTraits { | 307 | struct A8B8G8R8_SINTTraits { |
| @@ -310,7 +310,7 @@ struct A8B8G8R8_SINTTraits { | |||
| 310 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; | 310 | ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; |
| 311 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 311 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 312 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 312 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 313 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 313 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 314 | }; | 314 | }; |
| 315 | 315 | ||
| 316 | struct A8B8G8R8_UINTTraits { | 316 | struct A8B8G8R8_UINTTraits { |
| @@ -319,7 +319,7 @@ struct A8B8G8R8_UINTTraits { | |||
| 319 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; | 319 | ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; |
| 320 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | 320 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; |
| 321 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 321 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 322 | Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; | 322 | Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; |
| 323 | }; | 323 | }; |
| 324 | 324 | ||
| 325 | struct R16G16_UNORMTraits { | 325 | struct R16G16_UNORMTraits { |
| @@ -327,8 +327,8 @@ struct R16G16_UNORMTraits { | |||
| 327 | static constexpr std::array<ComponentType, num_components> component_types = { | 327 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 328 | ComponentType::UNORM, ComponentType::UNORM}; | 328 | ComponentType::UNORM, ComponentType::UNORM}; |
| 329 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; | 329 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; |
| 330 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 330 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 331 | Swizzle::R}; | 331 | Swizzle::G}; |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | struct R16G16_SNORMTraits { | 334 | struct R16G16_SNORMTraits { |
| @@ -336,8 +336,8 @@ struct R16G16_SNORMTraits { | |||
| 336 | static constexpr std::array<ComponentType, num_components> component_types = { | 336 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 337 | ComponentType::SNORM, ComponentType::SNORM}; | 337 | ComponentType::SNORM, ComponentType::SNORM}; |
| 338 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; | 338 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; |
| 339 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 339 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 340 | Swizzle::R}; | 340 | Swizzle::G}; |
| 341 | }; | 341 | }; |
| 342 | 342 | ||
| 343 | struct R16G16_SINTTraits { | 343 | struct R16G16_SINTTraits { |
| @@ -345,8 +345,8 @@ struct R16G16_SINTTraits { | |||
| 345 | static constexpr std::array<ComponentType, num_components> component_types = { | 345 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 346 | ComponentType::SINT, ComponentType::SINT}; | 346 | ComponentType::SINT, ComponentType::SINT}; |
| 347 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; | 347 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; |
| 348 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 348 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 349 | Swizzle::R}; | 349 | Swizzle::G}; |
| 350 | }; | 350 | }; |
| 351 | 351 | ||
| 352 | struct R16G16_UINTTraits { | 352 | struct R16G16_UINTTraits { |
| @@ -354,8 +354,8 @@ struct R16G16_UINTTraits { | |||
| 354 | static constexpr std::array<ComponentType, num_components> component_types = { | 354 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 355 | ComponentType::UINT, ComponentType::UINT}; | 355 | ComponentType::UINT, ComponentType::UINT}; |
| 356 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; | 356 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; |
| 357 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 357 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 358 | Swizzle::R}; | 358 | Swizzle::G}; |
| 359 | }; | 359 | }; |
| 360 | 360 | ||
| 361 | struct R16G16_FLOATTraits { | 361 | struct R16G16_FLOATTraits { |
| @@ -363,17 +363,17 @@ struct R16G16_FLOATTraits { | |||
| 363 | static constexpr std::array<ComponentType, num_components> component_types = { | 363 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 364 | ComponentType::FLOAT, ComponentType::FLOAT}; | 364 | ComponentType::FLOAT, ComponentType::FLOAT}; |
| 365 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; | 365 | static constexpr std::array<size_t, num_components> component_sizes = {16, 16}; |
| 366 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 366 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 367 | Swizzle::R}; | 367 | Swizzle::G}; |
| 368 | }; | 368 | }; |
| 369 | 369 | ||
| 370 | struct B10G11R11_FLOATTraits { | 370 | struct B10G11R11_FLOATTraits { |
| 371 | static constexpr size_t num_components = 3; | 371 | static constexpr size_t num_components = 3; |
| 372 | static constexpr std::array<ComponentType, num_components> component_types = { | 372 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 373 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; | 373 | ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; |
| 374 | static constexpr std::array<size_t, num_components> component_sizes = {11, 11, 10}; | 374 | static constexpr std::array<size_t, num_components> component_sizes = {10, 11, 11}; |
| 375 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 375 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 376 | Swizzle::R, Swizzle::G, Swizzle::B}; | 376 | Swizzle::B, Swizzle::G, Swizzle::R}; |
| 377 | }; | 377 | }; |
| 378 | 378 | ||
| 379 | struct R32_SINTTraits { | 379 | struct R32_SINTTraits { |
| @@ -400,22 +400,40 @@ struct R32_FLOATTraits { | |||
| 400 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R}; | 400 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R}; |
| 401 | }; | 401 | }; |
| 402 | 402 | ||
| 403 | struct X8R8G8B8_UNORMTraits { | ||
| 404 | static constexpr size_t num_components = 4; | ||
| 405 | static constexpr std::array<ComponentType, num_components> component_types = { | ||
| 406 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | ||
| 407 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | ||
| 408 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | ||
| 409 | Swizzle::None, Swizzle::R, Swizzle::G, Swizzle::B}; | ||
| 410 | }; | ||
| 411 | |||
| 412 | struct X8R8G8B8_SRGBTraits { | ||
| 413 | static constexpr size_t num_components = 4; | ||
| 414 | static constexpr std::array<ComponentType, num_components> component_types = { | ||
| 415 | ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; | ||
| 416 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8}; | ||
| 417 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | ||
| 418 | Swizzle::None, Swizzle::R, Swizzle::G, Swizzle::B}; | ||
| 419 | }; | ||
| 420 | |||
| 403 | struct R5G6B5_UNORMTraits { | 421 | struct R5G6B5_UNORMTraits { |
| 404 | static constexpr size_t num_components = 3; | 422 | static constexpr size_t num_components = 3; |
| 405 | static constexpr std::array<ComponentType, num_components> component_types = { | 423 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 406 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 424 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 407 | static constexpr std::array<size_t, num_components> component_sizes = {5, 6, 5}; | 425 | static constexpr std::array<size_t, num_components> component_sizes = {5, 6, 5}; |
| 408 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 426 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 409 | Swizzle::B, Swizzle::G, Swizzle::R}; | 427 | Swizzle::R, Swizzle::G, Swizzle::B}; |
| 410 | }; | 428 | }; |
| 411 | 429 | ||
| 412 | struct A1R5G5B5_UNORMTraits { | 430 | struct A1R5G5B5_UNORMTraits { |
| 413 | static constexpr size_t num_components = 4; | 431 | static constexpr size_t num_components = 4; |
| 414 | static constexpr std::array<ComponentType, num_components> component_types = { | 432 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 415 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; | 433 | ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; |
| 416 | static constexpr std::array<size_t, num_components> component_sizes = {5, 5, 5, 1}; | 434 | static constexpr std::array<size_t, num_components> component_sizes = {1, 5, 5, 5}; |
| 417 | static constexpr std::array<Swizzle, num_components> component_swizzle = { | 435 | static constexpr std::array<Swizzle, num_components> component_swizzle = { |
| 418 | Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A}; | 436 | Swizzle::A, Swizzle::R, Swizzle::G, Swizzle::B}; |
| 419 | }; | 437 | }; |
| 420 | 438 | ||
| 421 | struct R8G8_UNORMTraits { | 439 | struct R8G8_UNORMTraits { |
| @@ -423,8 +441,8 @@ struct R8G8_UNORMTraits { | |||
| 423 | static constexpr std::array<ComponentType, num_components> component_types = { | 441 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 424 | ComponentType::UNORM, ComponentType::UNORM}; | 442 | ComponentType::UNORM, ComponentType::UNORM}; |
| 425 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; | 443 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; |
| 426 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 444 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 427 | Swizzle::R}; | 445 | Swizzle::G}; |
| 428 | }; | 446 | }; |
| 429 | 447 | ||
| 430 | struct R8G8_SNORMTraits { | 448 | struct R8G8_SNORMTraits { |
| @@ -432,8 +450,8 @@ struct R8G8_SNORMTraits { | |||
| 432 | static constexpr std::array<ComponentType, num_components> component_types = { | 450 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 433 | ComponentType::SNORM, ComponentType::SNORM}; | 451 | ComponentType::SNORM, ComponentType::SNORM}; |
| 434 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; | 452 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; |
| 435 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 453 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 436 | Swizzle::R}; | 454 | Swizzle::G}; |
| 437 | }; | 455 | }; |
| 438 | 456 | ||
| 439 | struct R8G8_SINTTraits { | 457 | struct R8G8_SINTTraits { |
| @@ -441,8 +459,8 @@ struct R8G8_SINTTraits { | |||
| 441 | static constexpr std::array<ComponentType, num_components> component_types = { | 459 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 442 | ComponentType::SINT, ComponentType::SINT}; | 460 | ComponentType::SINT, ComponentType::SINT}; |
| 443 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; | 461 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; |
| 444 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 462 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 445 | Swizzle::R}; | 463 | Swizzle::G}; |
| 446 | }; | 464 | }; |
| 447 | 465 | ||
| 448 | struct R8G8_UINTTraits { | 466 | struct R8G8_UINTTraits { |
| @@ -450,8 +468,8 @@ struct R8G8_UINTTraits { | |||
| 450 | static constexpr std::array<ComponentType, num_components> component_types = { | 468 | static constexpr std::array<ComponentType, num_components> component_types = { |
| 451 | ComponentType::UINT, ComponentType::UINT}; | 469 | ComponentType::UINT, ComponentType::UINT}; |
| 452 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; | 470 | static constexpr std::array<size_t, num_components> component_sizes = {8, 8}; |
| 453 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G, | 471 | static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R, |
| 454 | Swizzle::R}; | 472 | Swizzle::G}; |
| 455 | }; | 473 | }; |
| 456 | 474 | ||
| 457 | struct R16_UNORMTraits { | 475 | struct R16_UNORMTraits { |
| @@ -611,7 +629,7 @@ private: | |||
| 611 | constexpr size_t fp16_mantissa_bits = 10; | 629 | constexpr size_t fp16_mantissa_bits = 10; |
| 612 | constexpr size_t mantissa_mask = | 630 | constexpr size_t mantissa_mask = |
| 613 | ~((1ULL << (fp32_mantissa_bits - fp16_mantissa_bits)) - 1ULL); | 631 | ~((1ULL << (fp32_mantissa_bits - fp16_mantissa_bits)) - 1ULL); |
| 614 | tmp = tmp & mantissa_mask; | 632 | tmp = tmp & static_cast<u32>(mantissa_mask); |
| 615 | // TODO: force the exponent within the range of half float. Not needed in UNORM / SNORM | 633 | // TODO: force the exponent within the range of half float. Not needed in UNORM / SNORM |
| 616 | return std::bit_cast<f32>(tmp); | 634 | return std::bit_cast<f32>(tmp); |
| 617 | }; | 635 | }; |
| @@ -624,12 +642,13 @@ private: | |||
| 624 | }; | 642 | }; |
| 625 | const auto calculate_snorm = [&]() { | 643 | const auto calculate_snorm = [&]() { |
| 626 | return static_cast<f32>( | 644 | return static_cast<f32>( |
| 627 | static_cast<f64>(sign_extend(value, component_sizes[which_component])) / | 645 | static_cast<f32>(sign_extend(value, component_sizes[which_component])) / |
| 628 | ((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL)); | 646 | static_cast<f32>((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL)); |
| 629 | }; | 647 | }; |
| 630 | const auto calculate_unorm = [&]() { | 648 | const auto calculate_unorm = [&]() { |
| 631 | return static_cast<f32>(static_cast<f32>(value) / | 649 | return static_cast<f32>( |
| 632 | ((1ULL << (component_sizes[which_component])) - 1ULL)); | 650 | static_cast<f32>(value) / |
| 651 | static_cast<f32>((1ULL << (component_sizes[which_component])) - 1ULL)); | ||
| 633 | }; | 652 | }; |
| 634 | if constexpr (component_types[which_component] == ComponentType::SNORM) { | 653 | if constexpr (component_types[which_component] == ComponentType::SNORM) { |
| 635 | out_component = calculate_snorm(); | 654 | out_component = calculate_snorm(); |
| @@ -688,14 +707,15 @@ private: | |||
| 688 | return tmp_value >> shift_towards; | 707 | return tmp_value >> shift_towards; |
| 689 | }; | 708 | }; |
| 690 | const auto calculate_unorm = [&]() { | 709 | const auto calculate_unorm = [&]() { |
| 691 | return static_cast<u32>(static_cast<f32>(in_component) * | 710 | return static_cast<u32>( |
| 692 | ((1ULL << (component_sizes[which_component])) - 1ULL)); | 711 | static_cast<f32>(in_component) * |
| 712 | static_cast<f32>((1ULL << (component_sizes[which_component])) - 1ULL)); | ||
| 693 | }; | 713 | }; |
| 694 | if constexpr (component_types[which_component] == ComponentType::SNORM || | 714 | if constexpr (component_types[which_component] == ComponentType::SNORM || |
| 695 | component_types[which_component] == ComponentType::SNORM_FORCE_FP16) { | 715 | component_types[which_component] == ComponentType::SNORM_FORCE_FP16) { |
| 696 | s32 tmp_word = | 716 | s32 tmp_word = static_cast<s32>( |
| 697 | static_cast<s32>(static_cast<f64>(in_component) * | 717 | static_cast<f32>(in_component) * |
| 698 | ((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL)); | 718 | static_cast<f32>((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL)); |
| 699 | insert_to_word(tmp_word); | 719 | insert_to_word(tmp_word); |
| 700 | 720 | ||
| 701 | } else if constexpr (component_types[which_component] == ComponentType::UNORM || | 721 | } else if constexpr (component_types[which_component] == ComponentType::UNORM || |
| @@ -714,11 +734,12 @@ private: | |||
| 714 | insert_to_word(tmp_word); | 734 | insert_to_word(tmp_word); |
| 715 | } else if constexpr (component_sizes[which_component] == 16) { | 735 | } else if constexpr (component_sizes[which_component] == 16) { |
| 716 | static constexpr u32 sign_mask = 0x8000; | 736 | static constexpr u32 sign_mask = 0x8000; |
| 717 | static constexpr u32 mantissa_mask = 0x8000; | 737 | static constexpr u32 mantissa_mask = 0x03ff; |
| 738 | static constexpr u32 exponent_mask = 0x7c00; | ||
| 718 | const u32 tmp_word = std::bit_cast<u32>(in_component); | 739 | const u32 tmp_word = std::bit_cast<u32>(in_component); |
| 719 | const u32 half = ((tmp_word >> 16) & sign_mask) | | 740 | const u32 half = ((tmp_word >> 16) & sign_mask) | |
| 720 | ((((tmp_word & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | | 741 | ((((tmp_word & 0x7f800000) - 0x38000000) >> 13) & exponent_mask) | |
| 721 | ((tmp_word >> 13) & 0x03ff); | 742 | ((tmp_word >> 13) & mantissa_mask); |
| 722 | insert_to_word(half); | 743 | insert_to_word(half); |
| 723 | } else { | 744 | } else { |
| 724 | insert_to_word(to_fp_n(in_component, component_sizes[which_component], | 745 | insert_to_word(to_fp_n(in_component, component_sizes[which_component], |
| @@ -740,7 +761,7 @@ private: | |||
| 740 | } | 761 | } |
| 741 | 762 | ||
| 742 | public: | 763 | public: |
| 743 | void ConvertTo(std::span<u8> input, std::span<f32> output) override { | 764 | void ConvertTo(std::span<const u8> input, std::span<f32> output) override { |
| 744 | const size_t num_pixels = output.size() / components_per_ir_rep; | 765 | const size_t num_pixels = output.size() / components_per_ir_rep; |
| 745 | for (size_t pixel = 0; pixel < num_pixels; pixel++) { | 766 | for (size_t pixel = 0; pixel < num_pixels; pixel++) { |
| 746 | std::array<u32, total_words_per_pixel> words{}; | 767 | std::array<u32, total_words_per_pixel> words{}; |
| @@ -790,11 +811,11 @@ public: | |||
| 790 | } | 811 | } |
| 791 | } | 812 | } |
| 792 | 813 | ||
| 793 | void ConvertFrom(std::span<f32> input, std::span<u8> output) override { | 814 | void ConvertFrom(std::span<const f32> input, std::span<u8> output) override { |
| 794 | const size_t num_pixels = output.size() / total_bytes_per_pixel; | 815 | const size_t num_pixels = output.size() / total_bytes_per_pixel; |
| 795 | for (size_t pixel = 0; pixel < num_pixels; pixel++) { | 816 | for (size_t pixel = 0; pixel < num_pixels; pixel++) { |
| 796 | std::span<f32> old_components(&input[pixel * components_per_ir_rep], | 817 | std::span<const f32> old_components(&input[pixel * components_per_ir_rep], |
| 797 | components_per_ir_rep); | 818 | components_per_ir_rep); |
| 798 | std::array<u32, total_words_per_pixel> words{}; | 819 | std::array<u32, total_words_per_pixel> words{}; |
| 799 | if constexpr (component_swizzle[0] != Swizzle::None) { | 820 | if constexpr (component_swizzle[0] != Swizzle::None) { |
| 800 | ConvertFromComponent<0>(words[bound_words[0]], | 821 | ConvertFromComponent<0>(words[bound_words[0]], |
| @@ -827,7 +848,7 @@ public: | |||
| 827 | } | 848 | } |
| 828 | 849 | ||
| 829 | ConverterImpl() = default; | 850 | ConverterImpl() = default; |
| 830 | ~ConverterImpl() = default; | 851 | ~ConverterImpl() override = default; |
| 831 | }; | 852 | }; |
| 832 | 853 | ||
| 833 | struct ConverterFactory::ConverterFactoryImpl { | 854 | struct ConverterFactory::ConverterFactoryImpl { |
| @@ -850,13 +871,15 @@ Converter* ConverterFactory::GetFormatConverter(RenderTargetFormat format) { | |||
| 850 | 871 | ||
| 851 | class NullConverter : public Converter { | 872 | class NullConverter : public Converter { |
| 852 | public: | 873 | public: |
| 853 | void ConvertTo([[maybe_unused]] std::span<u8> input, std::span<f32> output) override { | 874 | void ConvertTo([[maybe_unused]] std::span<const u8> input, std::span<f32> output) override { |
| 854 | std::fill(output.begin(), output.end(), 0.0f); | 875 | std::fill(output.begin(), output.end(), 0.0f); |
| 855 | } | 876 | } |
| 856 | void ConvertFrom([[maybe_unused]] std::span<f32> input, std::span<u8> output) override { | 877 | void ConvertFrom([[maybe_unused]] std::span<const f32> input, std::span<u8> output) override { |
| 857 | const u8 fill_value = 0U; | 878 | const u8 fill_value = 0U; |
| 858 | std::fill(output.begin(), output.end(), fill_value); | 879 | std::fill(output.begin(), output.end(), fill_value); |
| 859 | } | 880 | } |
| 881 | NullConverter() = default; | ||
| 882 | ~NullConverter() = default; | ||
| 860 | }; | 883 | }; |
| 861 | 884 | ||
| 862 | Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { | 885 | Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { |
| @@ -1011,6 +1034,16 @@ Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { | |||
| 1011 | .emplace(format, std::make_unique<ConverterImpl<R32_FLOATTraits>>()) | 1034 | .emplace(format, std::make_unique<ConverterImpl<R32_FLOATTraits>>()) |
| 1012 | .first->second.get(); | 1035 | .first->second.get(); |
| 1013 | break; | 1036 | break; |
| 1037 | case RenderTargetFormat::X8R8G8B8_UNORM: | ||
| 1038 | return impl->converters_cache | ||
| 1039 | .emplace(format, std::make_unique<ConverterImpl<X8R8G8B8_UNORMTraits>>()) | ||
| 1040 | .first->second.get(); | ||
| 1041 | break; | ||
| 1042 | case RenderTargetFormat::X8R8G8B8_SRGB: | ||
| 1043 | return impl->converters_cache | ||
| 1044 | .emplace(format, std::make_unique<ConverterImpl<X8R8G8B8_SRGBTraits>>()) | ||
| 1045 | .first->second.get(); | ||
| 1046 | break; | ||
| 1014 | case RenderTargetFormat::R5G6B5_UNORM: | 1047 | case RenderTargetFormat::R5G6B5_UNORM: |
| 1015 | return impl->converters_cache | 1048 | return impl->converters_cache |
| 1016 | .emplace(format, std::make_unique<ConverterImpl<R5G6B5_UNORMTraits>>()) | 1049 | .emplace(format, std::make_unique<ConverterImpl<R5G6B5_UNORMTraits>>()) |
diff --git a/src/video_core/engines/sw_blitter/converter.h b/src/video_core/engines/sw_blitter/converter.h index 03337e906..f9bdc516e 100644 --- a/src/video_core/engines/sw_blitter/converter.h +++ b/src/video_core/engines/sw_blitter/converter.h | |||
| @@ -1,21 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #pragma once | ||
| 5 | |||
| 4 | #include <memory> | 6 | #include <memory> |
| 5 | #include <span> | 7 | #include <span> |
| 6 | 8 | ||
| 7 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 8 | 10 | ||
| 9 | #pragma once | ||
| 10 | |||
| 11 | #include "video_core/gpu.h" | 11 | #include "video_core/gpu.h" |
| 12 | 12 | ||
| 13 | namespace Tegra::Engines::Blitter { | 13 | namespace Tegra::Engines::Blitter { |
| 14 | 14 | ||
| 15 | class Converter { | 15 | class Converter { |
| 16 | public: | 16 | public: |
| 17 | virtual void ConvertTo(std::span<u8> input, std::span<f32> output) = 0; | 17 | virtual void ConvertTo(std::span<const u8> input, std::span<f32> output) = 0; |
| 18 | virtual void ConvertFrom(std::span<f32> input, std::span<u8> output) = 0; | 18 | virtual void ConvertFrom(std::span<const f32> input, std::span<u8> output) = 0; |
| 19 | virtual ~Converter() = default; | ||
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | class ConverterFactory { | 22 | class ConverterFactory { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index d0709dc69..87ebf2054 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -61,8 +61,8 @@ enum class RenderTargetFormat : u32 { | |||
| 61 | R32_SINT = 0xE3, | 61 | R32_SINT = 0xE3, |
| 62 | R32_UINT = 0xE4, | 62 | R32_UINT = 0xE4, |
| 63 | R32_FLOAT = 0xE5, | 63 | R32_FLOAT = 0xE5, |
| 64 | // X8R8G8B8_UNORM = 0xE6, | 64 | X8R8G8B8_UNORM = 0xE6, |
| 65 | // X8R8G8B8_SRGB = 0xE7, | 65 | X8R8G8B8_SRGB = 0xE7, |
| 66 | R5G6B5_UNORM = 0xE8, | 66 | R5G6B5_UNORM = 0xE8, |
| 67 | A1R5G5B5_UNORM = 0xE9, | 67 | A1R5G5B5_UNORM = 0xE9, |
| 68 | R8G8_UNORM = 0xEA, | 68 | R8G8_UNORM = 0xEA, |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 6bd133d10..80a7d908f 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
| @@ -118,8 +118,10 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) | |||
| 118 | case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: | 118 | case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: |
| 119 | return PixelFormat::R16G16B16X16_FLOAT; | 119 | return PixelFormat::R16G16B16X16_FLOAT; |
| 120 | case Tegra::RenderTargetFormat::A8R8G8B8_UNORM: | 120 | case Tegra::RenderTargetFormat::A8R8G8B8_UNORM: |
| 121 | case Tegra::RenderTargetFormat::X8R8G8B8_UNORM: | ||
| 121 | return PixelFormat::B8G8R8A8_UNORM; | 122 | return PixelFormat::B8G8R8A8_UNORM; |
| 122 | case Tegra::RenderTargetFormat::A8R8G8B8_SRGB: | 123 | case Tegra::RenderTargetFormat::A8R8G8B8_SRGB: |
| 124 | case Tegra::RenderTargetFormat::X8R8G8B8_SRGB: | ||
| 123 | return PixelFormat::B8G8R8A8_SRGB; | 125 | return PixelFormat::B8G8R8A8_SRGB; |
| 124 | case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: | 126 | case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: |
| 125 | return PixelFormat::A2B10G10R10_UNORM; | 127 | return PixelFormat::A2B10G10R10_UNORM; |