mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
macOS: Implement texture converter for Metal (2) (#11289)
* macOS: Implement texture converter for Metal (2) * Fix texture conversion formatting
This commit is contained in:
parent
28d7af313b
commit
a0040e6fb1
@ -24,12 +24,128 @@ namespace utils
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifndef __APPLE__
|
||||
u16 convert_rgb655_to_rgb565(const u16 bits)
|
||||
{
|
||||
// g6 = g5
|
||||
// r5 = (((bits & 0xFC00) >> 1) & 0xFC00) << 1 is equivalent to truncating the least significant bit
|
||||
return (bits & 0xF81F) | (bits & 0x3E0) << 1;
|
||||
}
|
||||
#else
|
||||
u32 convert_rgb565_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 r5 = ((bits >> 11) & 0x1F);
|
||||
const u8 g6 = ((bits >> 5) & 0x3F);
|
||||
const u8 b5 = (bits & 0x1F);
|
||||
|
||||
const u8 b8 = ((b5 * 527) + 23) >> 6;
|
||||
const u8 g8 = ((g6 * 259) + 33) >> 6;
|
||||
const u8 r8 = ((r5 * 527) + 23) >> 6;
|
||||
const u8 a8 = 255;
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
u32 convert_argb4_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 b8 = (bits & 0xF0);
|
||||
const u8 g8 = ((bits >> 4) & 0xF0);
|
||||
const u8 r8 = ((bits >> 8) & 0xF0);
|
||||
const u8 a8 = ((bits << 4) & 0xF0);
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
u32 convert_a1rgb5_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 a1 = ((bits >> 11) & 0x80);
|
||||
const u8 r5 = ((bits >> 10) & 0x1F);
|
||||
const u8 g5 = ((bits >> 5) & 0x1F);
|
||||
const u8 b5 = (bits & 0x1F);
|
||||
|
||||
const u8 b8 = ((b5 * 527) + 23) >> 6;
|
||||
const u8 g8 = ((g5 * 527) + 23) >> 6;
|
||||
const u8 r8 = ((r5 * 527) + 23) >> 6;
|
||||
const u8 a8 = a1;
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
u32 convert_rgb5a1_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 r5 = ((bits >> 11) & 0x1F);
|
||||
const u8 g5 = ((bits >> 6) & 0x1F);
|
||||
const u8 b5 = ((bits >> 1) & 0x1F);
|
||||
const u8 a1 = (bits & 0x80);
|
||||
|
||||
const u8 b8 = ((b5 * 527) + 23) >> 6;
|
||||
const u8 g8 = ((g5 * 527) + 23) >> 6;
|
||||
const u8 r8 = ((r5 * 527) + 23) >> 6;
|
||||
const u8 a8 = a1;
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
u32 convert_rgb655_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 r6 = ((bits >> 10) & 0x3F);
|
||||
const u8 g5 = ((bits >> 5) & 0x1F);
|
||||
const u8 b5 = ((bits) & 0x1F);
|
||||
|
||||
const u8 b8 = ((b5 * 527) + 23) >> 6;
|
||||
const u8 g8 = ((g5 * 527) + 23) >> 6;
|
||||
const u8 r8 = ((r6 * 259) + 33) >> 6;
|
||||
const u8 a8 = 1;
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
u32 convert_d1rgb5_to_bgra8(const u16 bits)
|
||||
{
|
||||
const u8 r5 = ((bits >> 10) & 0x1F);
|
||||
const u8 g5 = ((bits >> 5) & 0x1F);
|
||||
const u8 b5 = (bits & 0x1F);
|
||||
|
||||
const u8 b8 = ((b5 * 527) + 23) >> 6;
|
||||
const u8 g8 = ((g5 * 527) + 23) >> 6;
|
||||
const u8 r8 = ((r5 * 527) + 23) >> 6;
|
||||
const u8 a8 = 1;
|
||||
|
||||
return b8 | (g8 << 8) | (r8 << 16) | (a8 << 24);
|
||||
}
|
||||
|
||||
struct convert_16_block_32
|
||||
{
|
||||
template<typename T>
|
||||
static void copy_mipmap_level(std::span<u32> dst, std::span<const T> src, u16 width_in_block, u16 row_count, u16 depth, u8 border, u32 dst_pitch_in_block, u32 src_pitch_in_block, u32 (*converter)(const u16))
|
||||
{
|
||||
static_assert(sizeof(T) == 2, "Type size doesn't match.");
|
||||
|
||||
u32 src_offset = 0, dst_offset = 0;
|
||||
const u32 v_porch = src_pitch_in_block * border;
|
||||
|
||||
for (int layer = 0; layer < depth; ++layer)
|
||||
{
|
||||
// Front
|
||||
src_offset += v_porch;
|
||||
|
||||
for (u32 row = 0; row < row_count; ++row)
|
||||
{
|
||||
for (int col = 0; col < width_in_block; ++col)
|
||||
{
|
||||
dst[dst_offset + col] = converter(src[src_offset + col + border]);
|
||||
}
|
||||
|
||||
src_offset += src_pitch_in_block;
|
||||
dst_offset += dst_pitch_in_block;
|
||||
}
|
||||
|
||||
// Back
|
||||
src_offset += v_porch;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct copy_unmodified_block
|
||||
{
|
||||
@ -692,6 +808,7 @@ namespace rsx
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
case CELL_GCM_TEXTURE_R6G5B5:
|
||||
{
|
||||
if (is_swizzled)
|
||||
@ -701,16 +818,49 @@ namespace rsx
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
|
||||
// TODO: Test if the HILO compressed formats support swizzling (other compressed_* formats ignore this option)
|
||||
case CELL_GCM_TEXTURE_DEPTH16:
|
||||
case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // Untested
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5:
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5:
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
#else
|
||||
// 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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(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<u32>(dst_buffer), utils::bless<const be_t<u16>>(src_layout.data), w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(w, caps.alignment), src_layout.pitch_in_block, &convert_rgb565_to_bgra8);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
|
||||
// TODO: Test if the HILO compressed formats support swizzling (other compressed_* formats ignore this option)
|
||||
case CELL_GCM_TEXTURE_DEPTH16:
|
||||
case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // Untested
|
||||
case CELL_GCM_TEXTURE_G8B8:
|
||||
{
|
||||
word_size = 2;
|
||||
|
@ -205,16 +205,28 @@ namespace vk
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case CELL_GCM_TEXTURE_B8: return VK_FORMAT_R8_UNORM;
|
||||
#ifndef __APPLE__
|
||||
case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_R5G6B5_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; // Expand, discard high bit?
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_R5G6B5_UNORM_PACK16;
|
||||
#else
|
||||
// assign B8G8R8A8_UNORM to formats that are not supported by Metal
|
||||
case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
#endif
|
||||
case CELL_GCM_TEXTURE_B8: return VK_FORMAT_R8_UNORM;
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return VK_FORMAT_BC2_UNORM_BLOCK;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
case CELL_GCM_TEXTURE_G8B8: return VK_FORMAT_R8G8_UNORM;
|
||||
case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; // Expand, discard high bit?
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8: return support.d24_unorm_s8? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
case CELL_GCM_TEXTURE_DEPTH16: return VK_FORMAT_D16_UNORM;
|
||||
@ -222,11 +234,9 @@ namespace vk
|
||||
case CELL_GCM_TEXTURE_X16: return VK_FORMAT_R16_UNORM;
|
||||
case CELL_GCM_TEXTURE_Y16_X16: return VK_FORMAT_R16G16_UNORM;
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return VK_FORMAT_R16G16_SFLOAT;
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT: return VK_FORMAT_R32_SFLOAT;
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
|
||||
case CELL_GCM_TEXTURE_D8R8G8B8: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return VK_FORMAT_R8G8_UNORM;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return VK_FORMAT_R8G8_SNORM;
|
||||
|
@ -32,9 +32,26 @@ namespace vk
|
||||
|
||||
switch (color_format)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
return std::make_pair(VK_FORMAT_R5G6B5_UNORM_PACK16, vk::default_component_map);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_A1R5G5B5_UNORM_PACK16, o_rgb);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_A1R5G5B5_UNORM_PACK16, z_rgb);
|
||||
#else
|
||||
// assign B8G8R8A8_UNORM to formats that are not supported by Metal
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_rgb);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_rgb);
|
||||
#endif
|
||||
case rsx::surface_color_format::a8r8g8b8:
|
||||
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map);
|
||||
|
||||
@ -59,12 +76,6 @@ namespace vk
|
||||
case rsx::surface_color_format::w32z32y32x32:
|
||||
return std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, vk::default_component_map);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_A1R5G5B5_UNORM_PACK16, o_rgb);
|
||||
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
return std::make_pair(VK_FORMAT_A1R5G5B5_UNORM_PACK16, z_rgb);
|
||||
|
||||
case rsx::surface_color_format::b8:
|
||||
{
|
||||
const VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE };
|
||||
|
@ -999,14 +999,20 @@ namespace vk
|
||||
//TODO
|
||||
warn_once("Format incompatibility detected, reporting failure to force data copy (VK_FORMAT=0x%X, GCM_FORMAT=0x%X)", static_cast<u32>(vk_format), gcm_format);
|
||||
return false;
|
||||
#ifndef __APPLE__
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
return (vk_format == VK_FORMAT_R5G6B5_UNORM_PACK16);
|
||||
#else
|
||||
// R5G6B5 is not supported by Metal
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
return (vk_format == VK_FORMAT_B8G8R8A8_UNORM);
|
||||
#endif
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
|
||||
return (vk_format == VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
|
||||
return (vk_format == VK_FORMAT_R32G32B32A32_SFLOAT);
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT:
|
||||
return (vk_format == VK_FORMAT_R32_SFLOAT);
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
return (vk_format == VK_FORMAT_R5G6B5_UNORM_PACK16);
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
case CELL_GCM_TEXTURE_D8R8G8B8:
|
||||
return (vk_format == VK_FORMAT_B8G8R8A8_UNORM || vk_format == VK_FORMAT_D24_UNORM_S8_UINT || vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT);
|
||||
|
Loading…
Reference in New Issue
Block a user