mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Fallback Vulkan 1555 textures to RGBA8 on Android
This commit is contained in:
@@ -164,11 +164,20 @@ static const VkColorFormatInfo kelvin_color_format_vk_map[66] = {
|
||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5] = {
|
||||
#ifdef __ANDROID__
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
#else
|
||||
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
||||
#endif
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5] = {
|
||||
#ifdef __ANDROID__
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ONE },
|
||||
#else
|
||||
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ONE },
|
||||
#endif
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A4R4G4B4] = {
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
@@ -196,7 +205,11 @@ static const VkColorFormatInfo kelvin_color_format_vk_map[66] = {
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A1R5G5B5] = {
|
||||
#ifdef __ANDROID__
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
#else
|
||||
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
||||
#endif
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G6B5] = {
|
||||
VK_FORMAT_R5G6B5_UNORM_PACK16,
|
||||
@@ -225,8 +238,13 @@ static const VkColorFormatInfo kelvin_color_format_vk_map[66] = {
|
||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5] = {
|
||||
#ifdef __ANDROID__
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ONE },
|
||||
#else
|
||||
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ONE },
|
||||
#endif
|
||||
},
|
||||
[NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A4R4G4B4] = {
|
||||
VK_FORMAT_R8G8B8A8_UNORM, // Converted
|
||||
|
||||
@@ -51,6 +51,68 @@ static VkSamplerAddressMode lookup_texture_address_mode(int idx)
|
||||
return pgraph_texture_addr_vk_map[idx];
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
static uint8_t android_vk_expand_5_to_8(uint8_t value)
|
||||
{
|
||||
return (value << 3) | (value >> 2);
|
||||
}
|
||||
|
||||
static bool android_vk_texture_needs_rgba8_upload(TextureShape s)
|
||||
{
|
||||
switch (s.color_format) {
|
||||
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5:
|
||||
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5:
|
||||
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A1R5G5B5:
|
||||
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t *android_vk_texture_convert_to_rgba8(TextureShape s,
|
||||
const uint8_t *src,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int depth,
|
||||
unsigned int row_pitch,
|
||||
unsigned int slice_pitch,
|
||||
size_t *converted_size)
|
||||
{
|
||||
size_t size = width * height * depth * 4;
|
||||
uint8_t *converted = g_malloc(size);
|
||||
|
||||
for (unsigned int z = 0; z < depth; z++) {
|
||||
const uint8_t *src_slice = src + z * slice_pitch;
|
||||
uint8_t *dst_slice = converted + z * width * height * 4;
|
||||
|
||||
for (unsigned int y = 0; y < height; y++) {
|
||||
const uint8_t *src_row = src_slice + y * row_pitch;
|
||||
uint8_t *dst_row = dst_slice + y * width * 4;
|
||||
|
||||
for (unsigned int x = 0; x < width; x++) {
|
||||
uint16_t pixel = lduw_le_p(src_row + x * 2);
|
||||
uint8_t *out = dst_row + x * 4;
|
||||
|
||||
out[0] = android_vk_expand_5_to_8((pixel >> 10) & 0x1F);
|
||||
out[1] = android_vk_expand_5_to_8((pixel >> 5) & 0x1F);
|
||||
out[2] = android_vk_expand_5_to_8(pixel & 0x1F);
|
||||
out[3] =
|
||||
(s.color_format == NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5 ||
|
||||
s.color_format == NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5) ?
|
||||
0xFF :
|
||||
((pixel & 0x8000) ? 0xFF : 0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (converted_size) {
|
||||
*converted_size = size;
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: Move to common
|
||||
// FIXME: We can shrink the size of this structure
|
||||
// FIXME: Use simple allocator
|
||||
@@ -198,6 +260,14 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx)
|
||||
s, texture_data_ptr, palette_data_ptr, adjusted_width,
|
||||
adjusted_height, 1, adjusted_pitch, 0, &converted_size);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (!converted && android_vk_texture_needs_rgba8_upload(s)) {
|
||||
converted = android_vk_texture_convert_to_rgba8(
|
||||
s, texture_data_ptr, adjusted_width, adjusted_height, 1,
|
||||
adjusted_pitch, 0, &converted_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!converted) {
|
||||
int dst_stride = adjusted_width * f.bytes_per_pixel;
|
||||
assert(adjusted_width <= s.width);
|
||||
@@ -292,6 +362,14 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx)
|
||||
s, unswizzled, palette_data_ptr, width, height, 1,
|
||||
pitch, 0, &converted_size);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (!converted && android_vk_texture_needs_rgba8_upload(s)) {
|
||||
converted = android_vk_texture_convert_to_rgba8(
|
||||
s, unswizzled, width, height, 1, pitch, 0,
|
||||
&converted_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (converted) {
|
||||
g_free(unswizzled);
|
||||
} else {
|
||||
@@ -372,6 +450,14 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx)
|
||||
s, unswizzled, palette_data_ptr, width, height, depth,
|
||||
row_pitch, slice_pitch, &converted_size);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (!converted && android_vk_texture_needs_rgba8_upload(s)) {
|
||||
converted = android_vk_texture_convert_to_rgba8(
|
||||
s, unswizzled, width, height, depth, row_pitch,
|
||||
slice_pitch, &converted_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (converted) {
|
||||
g_free(unswizzled);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user