Skip to content

Commit

Permalink
GL/GLES: implement mapping for various texture formats (xbmc#25205)
Browse files Browse the repository at this point in the history
GL: implement mapping for various texture formats
  • Loading branch information
sarbes authored Sep 6, 2024
1 parent b798693 commit eb9b34c
Show file tree
Hide file tree
Showing 4 changed files with 504 additions and 78 deletions.
196 changes: 165 additions & 31 deletions xbmc/guilib/TextureGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "TextureGL.h"

#include "ServiceBroker.h"
#include "guilib/TextureFormats.h"
#include "guilib/TextureManager.h"
#include "rendering/RenderSystem.h"
#include "settings/AdvancedSettings.h"
Expand All @@ -19,6 +20,118 @@

#include <memory>

namespace
{
// clang-format off
static const std::map<KD_TEX_FMT, TextureFormat> TextureMapping
{
#if defined(GL_EXT_texture_sRGB_R8) && (GL_EXT_texture_sRGB_RG8)
{KD_TEX_FMT_SDR_R8, {GL_R8, GL_SR8_EXT, GL_RED}},
{KD_TEX_FMT_SDR_RG8, {GL_RG8, GL_SRG8_EXT, GL_RG}},
#else
{KD_TEX_FMT_SDR_R8, {GL_R8, GL_FALSE, GL_RED}},
{KD_TEX_FMT_SDR_RG8, {GL_RG8, GL_FALSE, GL_RG}},
#endif
{KD_TEX_FMT_SDR_R5G6B5, {GL_RGB565, GL_FALSE, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}},
{KD_TEX_FMT_SDR_RGB5_A1, {GL_RGB5_A1, GL_FALSE, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}},
{KD_TEX_FMT_SDR_RGBA4, {GL_RGBA4, GL_FALSE, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}},
{KD_TEX_FMT_SDR_RGB8, {GL_RGB8, GL_SRGB8, GL_RGB}},
{KD_TEX_FMT_SDR_RGBA8, {GL_RGBA8, GL_SRGB8_ALPHA8, GL_RGBA}},
{KD_TEX_FMT_SDR_BGRA8, {GL_RGBA8, GL_SRGB8_ALPHA8, GL_BGRA}},

#if defined(GL_VERSION_3_0)
{KD_TEX_FMT_HDR_R16f, {GL_R16F, GL_FALSE, GL_RED, GL_HALF_FLOAT}},
{KD_TEX_FMT_HDR_RG16f, {GL_RG16F, GL_FALSE, GL_RG, GL_HALF_FLOAT}},
{KD_TEX_FMT_HDR_R11F_G11F_B10F, {GL_R11F_G11F_B10F, GL_FALSE, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}},
{KD_TEX_FMT_HDR_RGB9_E5, {GL_RGB9_E5, GL_FALSE, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}},
{KD_TEX_FMT_HDR_RGB10_A2, {GL_RGB10_A2, GL_FALSE, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}},
{KD_TEX_FMT_HDR_RGBA16f, {GL_RGBA16F, GL_FALSE, GL_RGBA, GL_HALF_FLOAT}},
#endif

#if defined(GL_EXT_texture_compression_s3tc) && (GL_EXT_texture_sRGB)
{KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}},
{KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}},
{KD_TEX_FMT_S3TC_RGB8_A4, {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}},
{KD_TEX_FMT_S3TC_RGBA8, {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}},
#elif defined(GL_EXT_texture_compression_s3tc)
{KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT}},
{KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}},
{KD_TEX_FMT_S3TC_RGB8_A4, {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}},
{KD_TEX_FMT_S3TC_RGBA8, {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}},
#elif defined(GL_EXT_texture_compression_dxt1)
{KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT}},
{KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}},
#endif

#if defined(GL_EXT_texture_compression_rgtc)
{KD_TEX_FMT_RGTC_R11, {GL_COMPRESSED_RED_RGTC1_EXT}},
{KD_TEX_FMT_RGTC_RG11, {GL_COMPRESSED_RED_GREEN_RGTC2_EXT}},
#endif

#if defined(GL_ARB_texture_compression_bptc)
{KD_TEX_FMT_BPTC_RGB16F, {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB}},
{KD_TEX_FMT_BPTC_RGBA8, {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB}},
#endif

#if defined(GL_VERSION_4_3)
{KD_TEX_FMT_ETC1_RGB8, {GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2}},

{KD_TEX_FMT_ETC2_R11, {GL_COMPRESSED_R11_EAC}},
{KD_TEX_FMT_ETC2_RG11, {GL_COMPRESSED_RG11_EAC}},
{KD_TEX_FMT_ETC2_RGB8, {GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2}},
{KD_TEX_FMT_ETC2_RGB8_A1, {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}},
{KD_TEX_FMT_ETC2_RGBA8, {GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}},
#endif

#if defined(GL_KHR_texture_compression_astc_ldr) || (GL_KHR_texture_compression_astc_hdr)
{KD_TEX_FMT_ASTC_LDR_4x4, {GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}},
{KD_TEX_FMT_ASTC_LDR_5x4, {GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}},
{KD_TEX_FMT_ASTC_LDR_5x5, {GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}},
{KD_TEX_FMT_ASTC_LDR_6x5, {GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}},
{KD_TEX_FMT_ASTC_LDR_6x6, {GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}},
{KD_TEX_FMT_ASTC_LDR_8x5, {GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}},
{KD_TEX_FMT_ASTC_LDR_8x6, {GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}},
{KD_TEX_FMT_ASTC_LDR_8x8, {GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}},
{KD_TEX_FMT_ASTC_LDR_10x5, {GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR}},
{KD_TEX_FMT_ASTC_LDR_10x6, {GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR}},
{KD_TEX_FMT_ASTC_LDR_10x8, {GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}},
{KD_TEX_FMT_ASTC_LDR_10x10, {GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}},
{KD_TEX_FMT_ASTC_LDR_12x10, {GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR}},
{KD_TEX_FMT_ASTC_LDR_12x12, {GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}},

{KD_TEX_FMT_ASTC_HDR_4x4, {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}},
{KD_TEX_FMT_ASTC_HDR_5x4, {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}},
{KD_TEX_FMT_ASTC_HDR_5x5, {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}},
{KD_TEX_FMT_ASTC_HDR_6x5, {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}},
{KD_TEX_FMT_ASTC_HDR_6x6, {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}},
{KD_TEX_FMT_ASTC_HDR_8x5, {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}},
{KD_TEX_FMT_ASTC_HDR_8x6, {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}},
{KD_TEX_FMT_ASTC_HDR_8x8, {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}},
{KD_TEX_FMT_ASTC_HDR_10x5, {GL_COMPRESSED_RGBA_ASTC_10x5_KHR}},
{KD_TEX_FMT_ASTC_HDR_10x6, {GL_COMPRESSED_RGBA_ASTC_10x6_KHR}},
{KD_TEX_FMT_ASTC_HDR_10x8, {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}},
{KD_TEX_FMT_ASTC_HDR_10x10, {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}},
{KD_TEX_FMT_ASTC_HDR_12x10, {GL_COMPRESSED_RGBA_ASTC_12x10_KHR}},
{KD_TEX_FMT_ASTC_HDR_12x12, {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}},
#endif
};

static const std::map<KD_TEX_SWIZ, Textureswizzle> SwizzleMap
{
{KD_TEX_SWIZ_RGBA, {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}},
{KD_TEX_SWIZ_RGB1, {GL_RED, GL_GREEN, GL_BLUE, GL_ONE}},
{KD_TEX_SWIZ_RRR1, {GL_RED, GL_RED, GL_RED, GL_ONE}},
{KD_TEX_SWIZ_111R, {GL_ONE, GL_ONE, GL_ONE, GL_RED}},
{KD_TEX_SWIZ_RRRG, {GL_RED, GL_RED, GL_RED, GL_GREEN}},
{KD_TEX_SWIZ_RRRR, {GL_RED, GL_RED, GL_RED, GL_RED}},
{KD_TEX_SWIZ_GGG1, {GL_GREEN, GL_GREEN, GL_GREEN, GL_ONE}},
{KD_TEX_SWIZ_111G, {GL_ONE, GL_ONE, GL_ONE, GL_GREEN}},
{KD_TEX_SWIZ_GGGA, {GL_GREEN, GL_GREEN, GL_GREEN, GL_ALPHA}},
{KD_TEX_SWIZ_GGGG, {GL_GREEN, GL_GREEN, GL_GREEN, GL_GREEN}},
};
// clang-format on
} // namespace

std::unique_ptr<CTexture> CTexture::CreateTexture(unsigned int width,
unsigned int height,
XB_FMT format)
Expand All @@ -33,6 +146,8 @@ CGLTexture::CGLTexture(unsigned int width, unsigned int height, XB_FMT format)
CServiceBroker::GetRenderSystem()->GetRenderVersion(major, minor);
if (major >= 3)
m_isOglVersion3orNewer = true;
if (major > 3 || (major == 3 && minor >= 3))
m_isOglVersion33orNewer = true;
}

CGLTexture::~CGLTexture()
Expand Down Expand Up @@ -119,49 +234,30 @@ void CGLTexture::LoadToGPU()
m_textureWidth = maxSize;
}

GLenum format = GL_BGRA;
GLint numcomponents = GL_RGBA;
SetSwizzle();

TextureFormat glFormat = GetFormatGL(m_textureFormat);

switch (m_format)
if (glFormat.format == GL_FALSE)
{
case XB_FMT_DXT1:
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
break;
case XB_FMT_DXT3:
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case XB_FMT_DXT5:
case XB_FMT_DXT5_YCoCg:
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case XB_FMT_RGB8:
format = GL_RGB;
numcomponents = GL_RGB;
break;
case XB_FMT_A8R8G8B8:
default:
break;
CLog::LogF(LOGDEBUG, "Failed to load texture. Unsupported format {}", m_textureFormat);
m_loadedToGPU = true;
return;
}

if ((m_format & XB_FMT_DXT_MASK) == 0)
if ((m_textureFormat & KD_TEX_FMT_SDR) || (m_textureFormat & KD_TEX_FMT_HDR))
{
glTexImage2D(GL_TEXTURE_2D, 0, numcomponents,
m_textureWidth, m_textureHeight, 0,
format, GL_UNSIGNED_BYTE, m_pixels);
glTexImage2D(GL_TEXTURE_2D, 0, glFormat.internalFormat, m_textureWidth, m_textureHeight, 0,
glFormat.format, glFormat.type, m_pixels);
}
else
{
glCompressedTexImage2D(GL_TEXTURE_2D, 0, format,
m_textureWidth, m_textureHeight, 0,
GetPitch() * GetRows(), m_pixels);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, glFormat.internalFormat, m_textureWidth,
m_textureHeight, 0, GetPitch() * GetRows(), m_pixels);
}

if (IsMipmapped() && m_isOglVersion3orNewer)
{
glGenerateMipmap(GL_TEXTURE_2D);
}

glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

VerifyGLState();

Expand All @@ -185,3 +281,41 @@ void CGLTexture::BindToUnit(unsigned int unit)
glBindTexture(GL_TEXTURE_2D, m_texture);
}

void CGLTexture::SetSwizzle()
{
if (!SwizzleMap.contains(m_textureSwizzle))
return;

Textureswizzle swiz = SwizzleMap.at(m_textureSwizzle);

// GL_TEXTURE_SWIZZLE_RGBA and GL_TEXTURE_SWIZZLE_RGBA_EXT should be the same
// token, but just to be sure...
#if defined(GL_VERSION_3_3) || (GL_ARB_texture_swizzle)
if (m_isOglVersion33orNewer ||
CServiceBroker::GetRenderSystem()->IsExtSupported("GL_ARB_texture_swizzle"))
{
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, &swiz.r);
return;
}
#endif
#if defined(GL_EXT_texture_swizzle)
if (CServiceBroker::GetRenderSystem()->IsExtSupported("GL_EXT_texture_swizzle"))
{
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA_EXT, &swiz.r);
return;
}
#endif
}

TextureFormat CGLTexture::GetFormatGL(KD_TEX_FMT textureFormat)
{
TextureFormat glFormat;

const auto it = TextureMapping.find(textureFormat);
if (it != TextureMapping.cend())
{
glFormat = it->second;
}

return glFormat;
}
24 changes: 22 additions & 2 deletions xbmc/guilib/TextureGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@

#include "system_gl.h"

struct TextureFormat
{
GLenum internalFormat{GL_FALSE};
GLenum internalFormatSRGB{GL_FALSE};
GLint format{GL_FALSE};
GLenum type{GL_UNSIGNED_BYTE};
};

struct Textureswizzle
{
GLint r{GL_RED};
GLint g{GL_GREEN};
GLint b{GL_BLUE};
GLint a{GL_ALPHA};
};

/************************************************************************/
/* CGLTexture */
/************************************************************************/
Expand All @@ -28,7 +44,11 @@ class CGLTexture : public CTexture
void BindToUnit(unsigned int unit) override;

protected:
GLuint m_texture = 0;
bool m_isOglVersion3orNewer = false;
void SetSwizzle();
TextureFormat GetFormatGL(KD_TEX_FMT textureFormat);

GLuint m_texture{0};
bool m_isOglVersion3orNewer{false};
bool m_isOglVersion33orNewer{false};
};

Loading

0 comments on commit eb9b34c

Please sign in to comment.