diff --git a/src/Cafe/HW/Latte/Core/LatteTextureLoader.h b/src/Cafe/HW/Latte/Core/LatteTextureLoader.h index 25321006..82144f3a 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureLoader.h +++ b/src/Cafe/HW/Latte/Core/LatteTextureLoader.h @@ -978,6 +978,57 @@ public: } }; +class TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM : public TextureDecoder, public SingletonClass +{ +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) + { + uint8* blockData = LatteTextureLoader_GetInput(textureLoader, x, y); + sint32 pixelOffset = (x + yc * textureLoader->width) * 4; + uint16 v0 = (*(uint16*)(blockData + 0)); + + uint8 c0 = (v0 & 0x1F); + uint8 c1 = (v0 >> 5) & 0x3F; + uint8 c2 = (v0 >> 11) & 0x1F; + + c0 = (c0 << 3) | c0 >> 3;// blue + c1 = (c1 << 2) | c1 >> 4;// green + c2 = (c2 << 3) | c2 >> 3;// red + + *(uint8*)(outputData + pixelOffset + 0) = c0;// blue + *(uint8*)(outputData + pixelOffset + 1) = c1;// green + *(uint8*)(outputData + pixelOffset + 2) = c2;// red + *(uint8*)(outputData + pixelOffset + 3) = 255;//alpha + } + } + } + + void decodePixelToRGBA(uint8* blockData, uint8* outputPixel, uint8 blockOffsetX, uint8 blockOffsetY) override + { + uint16 v0 = *(uint16*)(blockData + 0); + uint8 c0 = (v0 & 0x1F);// red + uint8 c1 = (v0 >> 5) & 0x3F;// green + uint8 c2 = (v0 >> 11) & 0x1F; // blue + c0 = (c0 << 3) | c0 >> 3; + c1 = (c1 << 2) | c1 >> 4; + c2 = (c2 << 3) | c2 >> 3; + *(outputPixel + 0) = c0;// red + *(outputPixel + 1) = c1;// green + *(outputPixel + 2) = c2;// blue + *(outputPixel + 3) = 255;// alpha + } +}; + class TextureDecoder_R5_G5_B5_A1_UNORM : public TextureDecoder, public SingletonClass { public: diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index cf5fc72b..33cdbd0e 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -2642,7 +2642,7 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD case Latte::E_GX2SURFFMT::R5_G6_B5_UNORM: if (m_supportedFormatInfo.fmt_r5g6b5_unorm_pack == false) { formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM; - formatInfoOut->decoder = nullptr; + formatInfoOut->decoder = TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM::getInstance(); } else { // Vulkan has R in MSB, GPU7 has it in LSB