mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 04:24:17 +01:00
dedicated decoder for R4G4 and R4G4B4A4 to R8G8B8A8 (#331)
This commit is contained in:
parent
4519a59d74
commit
00968acc1d
@ -556,7 +556,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureDecoder_R4_G4_UNORM_toRGBA4444 : public TextureDecoder, public SingletonClass<TextureDecoder_R4_G4_UNORM_toRGBA4444>
|
class TextureDecoder_R4_G4_UNORM_To_RGBA4 : public TextureDecoder, public SingletonClass<TextureDecoder_R4_G4_UNORM_To_RGBA4>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
@ -594,7 +594,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureDecoder_R4_G4_UNORM_toRGBA4444_vk : public TextureDecoder, public SingletonClass<TextureDecoder_R4_G4_UNORM_toRGBA4444_vk>
|
class TextureDecoder_R4_G4_UNORM_To_RGBA4_vk : public TextureDecoder, public SingletonClass<TextureDecoder_R4_G4_UNORM_To_RGBA4_vk>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
@ -632,6 +632,52 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureDecoder_R4G4_UNORM_To_RGBA8 : public TextureDecoder, public SingletonClass<TextureDecoder_R4G4_UNORM_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)
|
||||||
|
{
|
||||||
|
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<TextureDecoder_R4_G4_B4_A4_UNORM>
|
class TextureDecoder_R4_G4_B4_A4_UNORM : public TextureDecoder, public SingletonClass<TextureDecoder_R4_G4_B4_A4_UNORM>
|
||||||
{
|
{
|
||||||
@ -677,6 +723,67 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TextureDecoder_R4G4B4A4_UNORM_To_RGBA8 : public TextureDecoder, public SingletonClass<TextureDecoder_R4G4B4A4_UNORM_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)
|
||||||
|
{
|
||||||
|
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<TextureDecoder_R8_G8_B8_A8>
|
class TextureDecoder_R8_G8_B8_A8 : public TextureDecoder, public SingletonClass<TextureDecoder_R8_G8_B8_A8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -978,7 +1085,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM : public TextureDecoder, public SingletonClass<TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM>
|
class TextureDecoder_R5G6B5_UNORM_To_RGBA8 : public TextureDecoder, public SingletonClass<TextureDecoder_R5G6B5_UNORM_To_RGBA8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
@ -1236,7 +1343,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16 : public TextureDecoder, public SingletonClass<TextureDecoder_R10_G10_B10_A2_SNORM_toRGBA16>
|
class TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16 : public TextureDecoder, public SingletonClass<TextureDecoder_R10_G10_B10_A2_SNORM_To_RGBA16>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
@ -1281,7 +1388,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureDecoder_A2_B10_G10_R10_UNORM_toRGBA16 : public TextureDecoder, public SingletonClass<TextureDecoder_A2_B10_G10_R10_UNORM_toRGBA16>
|
class TextureDecoder_A2_B10_G10_R10_UNORM_To_RGBA16 : public TextureDecoder, public SingletonClass<TextureDecoder_A2_B10_G10_R10_UNORM_To_RGBA16>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
sint32 getBytesPerTexel(LatteTextureLoaderCtx* textureLoader) override
|
||||||
|
@ -878,7 +878,7 @@ TextureDecoder* OpenGLRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (format == Latte::E_GX2SURFFMT::R4_G4_UNORM)
|
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)
|
else if (format == Latte::E_GX2SURFFMT::R4_G4_B4_A4_UNORM)
|
||||||
texDecoder = TextureDecoder_R4_G4_B4_A4_UNORM::getInstance();
|
texDecoder = TextureDecoder_R4_G4_B4_A4_UNORM::getInstance();
|
||||||
else if (format == Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT)
|
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)
|
else if (format == Latte::E_GX2SURFFMT::R10_G10_B10_A2_UNORM)
|
||||||
texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
||||||
else if (format == Latte::E_GX2SURFFMT::A2_B10_G10_R10_UNORM)
|
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)
|
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)
|
else if (format == Latte::E_GX2SURFFMT::R10_G10_B10_A2_SRGB)
|
||||||
texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
texDecoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
||||||
else if (format == Latte::E_GX2SURFFMT::R11_G11_B10_FLOAT)
|
else if (format == Latte::E_GX2SURFFMT::R11_G11_B10_FLOAT)
|
||||||
|
@ -2588,11 +2588,11 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
{
|
{
|
||||||
if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) {
|
if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
formatInfoOut->decoder = nullptr;
|
formatInfoOut->decoder = TextureDecoder_R4G4_UNORM_To_RGBA8::getInstance();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
|
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
|
else
|
||||||
@ -2642,7 +2642,7 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
case Latte::E_GX2SURFFMT::R5_G6_B5_UNORM:
|
case Latte::E_GX2SURFFMT::R5_G6_B5_UNORM:
|
||||||
if (m_supportedFormatInfo.fmt_r5g6b5_unorm_pack == false) {
|
if (m_supportedFormatInfo.fmt_r5g6b5_unorm_pack == false) {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
formatInfoOut->decoder = TextureDecoder_R5G6B5_UNORM_To_R8G8B8A8_UNORM::getInstance();
|
formatInfoOut->decoder = TextureDecoder_R5G6B5_UNORM_To_RGBA8::getInstance();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Vulkan has R in MSB, GPU7 has it in LSB
|
// 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:
|
case Latte::E_GX2SURFFMT::R4_G4_B4_A4_UNORM:
|
||||||
if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) {
|
if (m_supportedFormatInfo.fmt_r4g4b4a4_unorm_pack == false) {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
formatInfoOut->decoder = nullptr;
|
formatInfoOut->decoder = TextureDecoder_R4G4B4A4_UNORM_To_RGBA8::getInstance();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
|
formatInfoOut->vkImageFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
|
||||||
@ -2694,11 +2694,11 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
break;
|
break;
|
||||||
case Latte::E_GX2SURFFMT::R10_G10_B10_A2_SNORM:
|
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->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;
|
break;
|
||||||
case Latte::E_GX2SURFFMT::R10_G10_B10_A2_SRGB:
|
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->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;
|
//break;
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32; // todo - verify
|
formatInfoOut->vkImageFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32; // todo - verify
|
||||||
formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
formatInfoOut->decoder = TextureDecoder_R10_G10_B10_A2_UNORM::getInstance();
|
||||||
|
Loading…
Reference in New Issue
Block a user