diff --git a/src/Cafe/HW/Latte/Core/LatteTextureLoader.h b/src/Cafe/HW/Latte/Core/LatteTextureLoader.h index 82144f3a..353ea924 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureLoader.h +++ b/src/Cafe/HW/Latte/Core/LatteTextureLoader.h @@ -556,7 +556,7 @@ public: } }; -class TextureDecoder_R4_G4_UNORM_toRGBA4444 : public TextureDecoder, public SingletonClass +class TextureDecoder_R4_G4_UNORM_To_RGBA4 : public TextureDecoder, public SingletonClass { public: sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override @@ -594,7 +594,7 @@ public: } }; -class TextureDecoder_R4_G4_UNORM_toRGBA4444_vk : public TextureDecoder, public SingletonClass +class TextureDecoder_R4_G4_UNORM_To_RGBA4_vk : public TextureDecoder, public SingletonClass { public: sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override @@ -632,6 +632,52 @@ public: } }; +class TextureDecoder_R4G4_UNORM_To_RGBA8 : 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; + uint8 v0 = (*(uint8*)(blockData + 0)); + + uint8 red4 = (v0 >> 4) & 0xF; + uint8 green4 = (v0 & 0xF); + + red4 = (red4 << 4) | red4; + green4 = (green4 << 4) | green4; + + *(uint8*)(outputData + pixelOffset + 0) = red4; + *(uint8*)(outputData + pixelOffset + 1) = green4; + *(uint8*)(outputData + pixelOffset + 2) = 0; + *(uint8*)(outputData + pixelOffset + 3) = 255; + } + } + } + + void decodePixelToRGBA(uint8* blockData, uint8* outputPixel, uint8 blockOffsetX, uint8 blockOffsetY) override + { + uint8 v0 = *(blockData + 0); + uint8 red4 = (v0 >> 4) & 0xF; + uint8 green4 = (v0 & 0xF); + red4 = (red4 << 4) | red4; + green4 = (green4 << 4) | green4; + *(outputPixel + 0) = red4; + *(outputPixel + 1) = green4; + *(outputPixel + 2) = 0; + *(outputPixel + 3) = 255; + } +}; class TextureDecoder_R4_G4_B4_A4_UNORM : public TextureDecoder, public SingletonClass { @@ -677,6 +723,67 @@ public: } }; + +class TextureDecoder_R4G4B4A4_UNORM_To_RGBA8 : 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; + uint8 v0 = (*(uint8*)(blockData + 0)); + uint8 v1 = (*(uint8*)(blockData + 1)); + + uint8 red4 = (v0 & 0xF); + uint8 green4 = (v0 >> 4) & 0xF; + uint8 blue4 = (v1) & 0xF; + uint8 alpha4 = (v1 >> 4) & 0xF; + + red4 = (red4 << 4) | red4; + green4 = (green4 << 4) | green4; + blue4 = (blue4 << 4) | blue4; + alpha4 = (alpha4 << 4) | alpha4; + + *(uint8*)(outputData + pixelOffset + 0) = red4; + *(uint8*)(outputData + pixelOffset + 1) = green4; + *(uint8*)(outputData + pixelOffset + 2) = blue4; + *(uint8*)(outputData + pixelOffset + 3) = alpha4; + } + } + } + + void decodePixelToRGBA(uint8* blockData, uint8* outputPixel, uint8 blockOffsetX, uint8 blockOffsetY) override + { + uint8 v0 = *(blockData + 0); + uint8 v1 = *(blockData + 1); + + uint8 red4 = (v0 & 0xF); + uint8 green4 = (v0 >> 4) & 0xF; + uint8 blue4 = (v1) & 0xF; + uint8 alpha4 = (v1 >> 4) & 0xF; + + red4 = (red4 << 4) | red4; + green4 = (green4 << 4) | green4; + blue4 = (blue4 << 4) | blue4; + alpha4 = (alpha4 << 4) | alpha4; + + *(outputPixel + 0) = red4; + *(outputPixel + 1) = green4; + *(outputPixel + 2) = blue4; + *(outputPixel + 3) = alpha4; + } +}; + class TextureDecoder_R8_G8_B8_A8 : public TextureDecoder, public SingletonClass { public: @@ -978,7 +1085,7 @@ public: } }; -class TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM : public TextureDecoder, public SingletonClass +class TextureDecoder_R5G6B5_UNORM_To_RGBA8 : public TextureDecoder, public SingletonClass { public: sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override @@ -1236,7 +1343,7 @@ public: } }; -class TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16 : public TextureDecoder, public SingletonClass +class TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16 : public TextureDecoder, public SingletonClass { public: sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override @@ -1281,7 +1388,7 @@ public: } }; -class TextureDecoder_A2_B10_G10_R10_UNORM_toRGBA16 : public TextureDecoder, public SingletonClass +class TextureDecoder_A2_B10_G10_R10_UNORM_To_RGBA16 : public TextureDecoder, public SingletonClass { public: sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp index 269f30e8..c72d52ca 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp @@ -878,7 +878,7 @@ TextureDecoder* OpenGLRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT } if (format == Latte::E_GX2SURFFMT::R4_G4_UNORM) - texDecoder = TextureDecoder_R4_G4_UNORM_toRGBA4444::getInstance(); + texDecoder = TextureDecoder_R4_G4_UNORM_To_RGBA4::getInstance(); else if (format == Latte::E_GX2SURFFMT::R4_G4_B4_A4_UNORM) texDecoder = TextureDecoder_R4_G4_B4_A4_UNORM::getInstance(); else if (format == Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT) @@ -964,9 +964,9 @@ TextureDecoder* OpenGLRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT else if (format == Latte::E_GX2SURFFMT::R10_G10_B10_A2_UNORM) texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance(); else if (format == Latte::E_GX2SURFFMT::A2_B10_G10_R10_UNORM) - texDecoder = TextureDecoder_A2_B10_G10_R10_UNORM_toRGBA16::getInstance(); + texDecoder = TextureDecoder_A2_B10_G10_R10_UNORM_To_RGBA16::getInstance(); else if (format == Latte::E_GX2SURFFMT::R10_G10_B10_A2_SNORM) - texDecoder = TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16::getInstance(); + texDecoder = TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16::getInstance(); else if (format == Latte::E_GX2SURFFMT::R10_G10_B10_A2_SRGB) texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance(); else if (format == Latte::E_GX2SURFFMT::R11_G11_B10_FLOAT) diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index 33cdbd0e..759dac59 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -2588,11 +2588,11 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD { if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) { formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM; - formatInfoOut->decoder = nullptr; + formatInfoOut->decoder = TextureDecoder_R4G4_UNORM_To_RGBA8::getInstance(); } else { formatInfoOut->vkImageFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16; - formatInfoOut->decoder = TextureDecoder_R4_G4_UNORM_toRGBA4444_vk::getInstance(); + formatInfoOut->decoder = TextureDecoder_R4_G4_UNORM_To_RGBA4_vk::getInstance(); } } else @@ -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 = TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM::getInstance(); + formatInfoOut->decoder = TextureDecoder_R5G6B5_UNORM_To_RGBA8::getInstance(); } else { // Vulkan has R in MSB, GPU7 has it in LSB @@ -2680,7 +2680,7 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD case Latte::E_GX2SURFFMT::R4_G4_B4_A4_UNORM: if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) { formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM; - formatInfoOut->decoder = nullptr; + formatInfoOut->decoder = TextureDecoder_R4G4B4A4_UNORM_To_RGBA8::getInstance(); } else { formatInfoOut->vkImageFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16; @@ -2694,11 +2694,11 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD break; case Latte::E_GX2SURFFMT::R10_G10_B10_A2_SNORM: formatInfoOut->vkImageFormat = VK_FORMAT_R16G16B16A16_SNORM; // Vulkan has VK_FORMAT_A2R10G10B10_SNORM_PACK32 but it doesnt work? - formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16::getInstance(); + formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16::getInstance(); break; case Latte::E_GX2SURFFMT::R10_G10_B10_A2_SRGB: //formatInfoOut->vkImageFormat = VK_FORMAT_R16G16B16A16_SNORM; // Vulkan has no uncompressed SRGB format with more than 8 bits per channel - //formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16::getInstance(); + //formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16::getInstance(); //break; formatInfoOut->vkImageFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32; // todo - verify formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();