From 801e7f3c2f23bcf94147ce1a8c5590a7d6a6487c Mon Sep 17 00:00:00 2001 From: nastys <@a.a> Date: Thu, 20 Jan 2022 22:06:55 +0100 Subject: [PATCH] macOS: Implement texture swizzling for 16-bit formats --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 57 ++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index fe3c70148d..a04f31a0fa 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -145,6 +145,33 @@ struct convert_16_block_32 } } }; + +struct convert_16_block_32_swizzled +{ + template + static void copy_mipmap_level(std::span dst, std::span src, u16 width_in_block, u16 row_count, u16 depth, u8 border, u32 dst_pitch_in_block, u32 (*converter)(const u16)) + { + u32 padded_width, padded_height; + if (border) + { + padded_width = rsx::next_pow2(width_in_block + border + border); + padded_height = rsx::next_pow2(row_count + border + border); + } + else + { + padded_width = width_in_block; + padded_height = row_count; + } + + u32 size = padded_width * padded_height * depth * 2; + std::vector tmp(size); + + rsx::convert_linear_swizzle_3d(src.data(), tmp.data(), padded_width, padded_height, depth); + + std::span src_span = tmp; + convert_16_block_32::copy_mipmap_level(dst, src_span, width_in_block, row_count, depth, border, dst_pitch_in_block, padded_width, converter); + } +}; #endif struct copy_unmodified_block @@ -827,32 +854,50 @@ namespace rsx // convert the following formats to B8G8R8A8_UNORM, because they are not supported by Metal case CELL_GCM_TEXTURE_R6G5B5: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb655_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_rgb655_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb655_to_bgra8); break; } case CELL_GCM_TEXTURE_D1R5G5B5: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_d1rgb5_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_d1rgb5_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_d1rgb5_to_bgra8); break; } case CELL_GCM_TEXTURE_A1R5G5B5: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_a1rgb5_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_a1rgb5_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_a1rgb5_to_bgra8); break; } case CELL_GCM_TEXTURE_A4R4G4B4: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_argb4_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_argb4_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_argb4_to_bgra8); break; } case CELL_GCM_TEXTURE_R5G5B5A1: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb5a1_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_rgb5a1_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb5a1_to_bgra8); break; } case CELL_GCM_TEXTURE_R5G6B5: { - convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb565_to_bgra8); + if (is_swizzled) + convert_16_block_32_swizzled::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), &convert_rgb565_to_bgra8); + else + convert_16_block_32::copy_mipmap_level(utils::bless(dst_buffer), utils::bless>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb565_to_bgra8); break; } #endif