mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-25 18:46:55 +01:00
MoltenVk: Add missing texture decoders (#332)
This commit is contained in:
parent
551f821109
commit
b724a657e6
@ -1203,6 +1203,58 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureDecoder_R5_G5_B5_A1_UNORM_swappedRB_To_RGBA8 : public TextureDecoder, public SingletonClass<TextureDecoder_R5_G5_B5_A1_UNORM_swappedRB_To_RGBA8>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//2656
|
||||||
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode(LatteTextureLoaderCtx* textureLoader, uint8* outputData) override
|
||||||
|
{
|
||||||
|
for (sint32 y = 0; y < textureLoader->height; y += textureLoader->stepY)
|
||||||
|
{
|
||||||
|
sint32 yc = y;
|
||||||
|
for (sint32 x = 0; x < textureLoader->width; x += textureLoader->stepX)
|
||||||
|
{
|
||||||
|
uint16* blockData = (uint16*)LatteTextureLoader_GetInput(textureLoader, x, y);
|
||||||
|
sint32 pixelOffset = (x + yc * textureLoader->width) * 4;
|
||||||
|
uint32 colorData = (*(uint16*)(blockData + 0));
|
||||||
|
// swap order of components
|
||||||
|
uint8 red = (colorData >> 0) & 0x1F;
|
||||||
|
uint8 green = (colorData >> 5) & 0x1F;
|
||||||
|
uint8 blue = (colorData >> 10) & 0x1F;
|
||||||
|
uint8 alpha = (colorData >> 15) & 0x1;
|
||||||
|
|
||||||
|
red = red << 3 | red >> 2;
|
||||||
|
green = green << 3 | green >> 2;
|
||||||
|
blue = blue << 3 | blue >> 2;
|
||||||
|
alpha = alpha * 0xff;
|
||||||
|
|
||||||
|
// MSB...LSB : ABGR
|
||||||
|
colorData = (alpha << 24) | (blue << 16) | (green << 8) | red;
|
||||||
|
*(uint32*)(outputData + pixelOffset + 0) = colorData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void decodePixelToRGBA(uint8* blockData, uint8* outputPixel, uint8 blockOffsetX, uint8 blockOffsetY) override
|
||||||
|
{
|
||||||
|
uint16 colorData = (*(uint16*)blockData);
|
||||||
|
uint8 red = (colorData >> 0) & 0x1F;
|
||||||
|
uint8 green = (colorData >> 5) & 0x1F;
|
||||||
|
uint8 blue = (colorData >> 10) & 0x1F;
|
||||||
|
uint8 alpha = (colorData >> 15) & 0x1;
|
||||||
|
*(outputPixel + 0) = (red << 3) | (red >> 2);
|
||||||
|
*(outputPixel + 1) = (green << 3) | (green >> 2);
|
||||||
|
*(outputPixel + 2) = (blue << 3) | (blue >> 2);
|
||||||
|
*(outputPixel + 3) = alpha * 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class uint16_R5_G5_B5_A1_swapOpenGL
|
class uint16_R5_G5_B5_A1_swapOpenGL
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -1316,6 +1368,56 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureDecoder_A1_B5_G5_R5_UNORM_vulkan_To_RGBA8 : public TextureDecoder, public SingletonClass<TextureDecoder_A1_B5_G5_R5_UNORM_vulkan_To_RGBA8>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode(LatteTextureLoaderCtx* textureLoader, uint8* outputData) override
|
||||||
|
{
|
||||||
|
for (sint32 y = 0; y < textureLoader->height; y += textureLoader->stepY)
|
||||||
|
{
|
||||||
|
sint32 yc = y;
|
||||||
|
for (sint32 x = 0; x < textureLoader->width; x += textureLoader->stepX)
|
||||||
|
{
|
||||||
|
uint16* blockData = (uint16*)LatteTextureLoader_GetInput(textureLoader, x, y);
|
||||||
|
sint32 pixelOffset = (x + yc * textureLoader->width) * 4;
|
||||||
|
uint32 colorData = (*(uint16*)(blockData + 0));
|
||||||
|
// swap order of components
|
||||||
|
uint8 red = (colorData >> 11) & 0x1F;
|
||||||
|
uint8 green = (colorData >> 6) & 0x1F;
|
||||||
|
uint8 blue = (colorData >> 1) & 0x1F;
|
||||||
|
uint8 alpha = (colorData >> 0) & 0x1;
|
||||||
|
|
||||||
|
red = red << 3 | red >> 2;
|
||||||
|
green = green << 3 | green >> 2;
|
||||||
|
blue = blue << 3 | blue >> 2;
|
||||||
|
alpha = alpha * 0xff;
|
||||||
|
|
||||||
|
// MSB...LSB ABGR
|
||||||
|
colorData = red | (green << 8) | (blue << 16) | (alpha << 24);
|
||||||
|
*(uint32*)(outputData + pixelOffset + 0) = colorData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void decodePixelToRGBA(uint8* blockData, uint8* outputPixel, uint8 blockOffsetX, uint8 blockOffsetY) override
|
||||||
|
{
|
||||||
|
uint16 colorData = (*(uint16*)blockData);
|
||||||
|
uint8 red5 = (colorData >> 11) & 0x1F;
|
||||||
|
uint8 green5 = (colorData >> 6) & 0x1F;
|
||||||
|
uint8 blue5 = (colorData >> 1) & 0x1F;
|
||||||
|
uint8 alpha1 = (colorData >> 0) & 0x1;
|
||||||
|
*(outputPixel + 0) = (red5 << 3) | (red5 >> 2);
|
||||||
|
*(outputPixel + 1) = (green5 << 3) | (green5 >> 2);
|
||||||
|
*(outputPixel + 2) = (blue5 << 3) | (blue5 >> 2);
|
||||||
|
*(outputPixel + 3) = (alpha1 << 3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TextureDecoder_R10_G10_B10_A2_UNORM : public TextureDecoder, public SingletonClass<TextureDecoder_R10_G10_B10_A2_UNORM>
|
class TextureDecoder_R10_G10_B10_A2_UNORM : public TextureDecoder, public SingletonClass<TextureDecoder_R10_G10_B10_A2_UNORM>
|
||||||
{
|
{
|
||||||
|
@ -2653,7 +2653,7 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
case Latte::E_GX2SURFFMT::R5_G5_B5_A1_UNORM:
|
case Latte::E_GX2SURFFMT::R5_G5_B5_A1_UNORM:
|
||||||
if (m_supportedFormatInfo.fmt_a1r5g5b5_unorm_pack == false) {
|
if (m_supportedFormatInfo.fmt_a1r5g5b5_unorm_pack == false) {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
formatInfoOut->decoder = nullptr;
|
formatInfoOut->decoder = TextureDecoder_R5_G5_B5_A1_UNORM_swappedRB_To_RGBA8::getInstance();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// used in Super Mario 3D World for the hidden Luigi sprites
|
// used in Super Mario 3D World for the hidden Luigi sprites
|
||||||
@ -2665,7 +2665,7 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
case Latte::E_GX2SURFFMT::A1_B5_G5_R5_UNORM:
|
case Latte::E_GX2SURFFMT::A1_B5_G5_R5_UNORM:
|
||||||
if (m_supportedFormatInfo.fmt_a1r5g5b5_unorm_pack == false) {
|
if (m_supportedFormatInfo.fmt_a1r5g5b5_unorm_pack == false) {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
formatInfoOut->decoder = nullptr;
|
formatInfoOut->decoder = TextureDecoder_A1_B5_G5_R5_UNORM_vulkan_To_RGBA8::getInstance();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// used by VC64 (e.g. Ocarina of Time)
|
// used by VC64 (e.g. Ocarina of Time)
|
||||||
|
Loading…
Reference in New Issue
Block a user