Implemented sRGB support for DXT encoded textures (#2026)

* Added sRGB support for DXT compressed textures - OpenGL

* Added sRGB support for DXT compressed textures - Vulkan and Metal

* Added detection if OpenGL driver supports sRGB compressed textures (EXT_texture_sRGB extension)

* Fixed whitespace to use spaces rather than tabs

* Test for GL_EXT_texture_sRGB or GL_EXT_texture_compression_s3tc_srgb support for sRGB DXT compressed textures

* GL ES uses GL_EXT_texture_compression_s3tc_srgb instead of GL_EXT_texture_sRGB
This commit is contained in:
BStringhamVRSK
2020-01-15 11:26:29 -07:00
committed by Romain Guy
parent b351e709c1
commit 041f26a7c5
9 changed files with 50 additions and 2 deletions

View File

@@ -261,6 +261,7 @@ enum class CompressedPixelDataType : uint16_t {
// Available everywhere except Android/iOS
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
// ASTC formats are available with a GLES extension
RGBA_ASTC_4x4,
@@ -414,6 +415,7 @@ enum class TextureFormat : uint16_t {
// Available everywhere except Android/iOS
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
// ASTC formats are available with a GLES extension
RGBA_ASTC_4x4,
@@ -468,7 +470,11 @@ static constexpr bool isETC2Compression(TextureFormat format) noexcept {
//! returns whether this format is an ETC3 compressed format
static constexpr bool isS3TCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::DXT1_RGB && format <= TextureFormat::DXT5_RGBA;
return format >= TextureFormat::DXT1_RGB && format <= TextureFormat::DXT5_SRGBA;
}
static constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
return format >= TextureFormat::DXT1_SRGB && format <= TextureFormat::DXT5_SRGBA;
}
//! Texture Cubemap Face

View File

@@ -117,10 +117,14 @@ size_t getFormatSize(TextureFormat format) noexcept {
case TextureFormat::DXT1_RGB:
case TextureFormat::DXT1_RGBA:
case TextureFormat::DXT1_SRGB:
case TextureFormat::DXT1_SRGBA:
return 8;
case TextureFormat::DXT3_RGBA:
case TextureFormat::DXT3_SRGBA:
case TextureFormat::DXT5_RGBA:
case TextureFormat::DXT5_SRGBA:
return 16;
// The block size for ASTC compression is always 16 bytes.
@@ -175,8 +179,12 @@ size_t getBlockWidth(TextureFormat format) noexcept {
case TextureFormat::DXT1_RGB:
case TextureFormat::DXT1_RGBA:
case TextureFormat::DXT1_SRGB:
case TextureFormat::DXT1_SRGBA:
case TextureFormat::DXT3_RGBA:
case TextureFormat::DXT3_SRGBA:
case TextureFormat::DXT5_RGBA:
case TextureFormat::DXT5_SRGBA:
return 4;
case TextureFormat::RGBA_ASTC_4x4:

View File

@@ -363,9 +363,13 @@ io::ostream& operator<<(io::ostream& out, TextureFormat format) {
CASE(TextureFormat, ETC2_EAC_RGBA8)
CASE(TextureFormat, ETC2_EAC_SRGBA8)
CASE(TextureFormat, DXT1_RGB)
CASE(TextureFormat, DXT1_SRGB)
CASE(TextureFormat, DXT1_RGBA)
CASE(TextureFormat, DXT1_SRGBA)
CASE(TextureFormat, DXT3_RGBA)
CASE(TextureFormat, DXT3_SRGBA)
CASE(TextureFormat, DXT5_RGBA)
CASE(TextureFormat, DXT5_SRGBA)
CASE(TextureFormat, UNUSED)
CASE(TextureFormat, RGBA_ASTC_4x4)
CASE(TextureFormat, RGBA_ASTC_5x4)

View File

@@ -233,10 +233,14 @@ constexpr inline MTLPixelFormat getMetalFormat(TextureFormat format) noexcept {
// DXT (BC) formats are only available on macOS desktop.
// See https://en.wikipedia.org/wiki/S3_Texture_Compression#S3TC_format_comparison
case TextureFormat::DXT1_RGBA: return MTLPixelFormatBC1_RGBA;
case TextureFormat::DXT1_SRGBA: return MTLPixelFormatBC1_RGBA_sRGB;
case TextureFormat::DXT3_RGBA: return MTLPixelFormatBC2_RGBA;
case TextureFormat::DXT3_SRGBA: return MTLPixelFormatBC2_RGBA_sRGB;
case TextureFormat::DXT5_RGBA: return MTLPixelFormatBC3_RGBA;
case TextureFormat::DXT5_SRGBA: return MTLPixelFormatBC3_RGBA_sRGB;
case TextureFormat::DXT1_RGB: return MTLPixelFormatInvalid;
case TextureFormat::DXT1_SRGB: return MTLPixelFormatInvalid;
#endif
#if defined(IOS)

View File

@@ -390,6 +390,20 @@ constexpr /* inline */ GLenum getInternalFormat(backend::TextureFormat format) n
return 0;
#endif
#if defined(GL_EXT_texture_sRGB) || defined(GL_EXT_texture_compression_s3tc_srgb)
case TextureFormat::DXT1_SRGB: return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
case TextureFormat::DXT1_SRGBA: return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
case TextureFormat::DXT3_SRGBA: return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
case TextureFormat::DXT5_SRGBA: return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
#else
case TextureFormat::DXT1_SRGB:
case TextureFormat::DXT1_SRGBA:
case TextureFormat::DXT3_SRGBA:
case TextureFormat::DXT5_SRGBA:
// this should not happen
return 0;
#endif
#if defined(GL_KHR_texture_compression_astc_hdr)
case TextureFormat::RGBA_ASTC_4x4: return GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
case TextureFormat::RGBA_ASTC_5x4: return GL_COMPRESSED_RGBA_ASTC_5x4_KHR;

View File

@@ -189,6 +189,7 @@ void OpenGLContext::initExtensionsGLES(GLint major, GLint minor, ExtentionSet co
ext.texture_compression_s3tc = hasExtension(exts, "WEBGL_compressed_texture_s3tc");
ext.EXT_multisampled_render_to_texture = hasExtension(exts, "GL_EXT_multisampled_render_to_texture");
ext.KHR_debug = hasExtension(exts, "GL_KHR_debug");
ext.EXT_texture_compression_s3tc_srgb = hasExtension(exts, "GL_EXT_texture_compression_s3tc_srgb");
// ES 3.2 implies EXT_color_buffer_float
if (major >= 3 && minor >= 2) {
ext.EXT_color_buffer_float = true;
@@ -205,6 +206,7 @@ void OpenGLContext::initExtensionsGL(GLint major, GLint minor, ExtentionSet cons
ext.EXT_color_buffer_float = true; // Assumes core profile.
ext.APPLE_color_buffer_packed_float = true; // Assumes core profile.
ext.KHR_debug = major >= 4 && minor >= 3;
ext.EXT_texture_sRGB = hasExtension(exts, "GL_EXT_texture_sRGB");
}
void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept {

View File

@@ -122,6 +122,8 @@ public:
bool APPLE_color_buffer_packed_float = false;
bool EXT_multisampled_render_to_texture = false;
bool KHR_debug = false;
bool EXT_texture_sRGB = false;
bool EXT_texture_compression_s3tc_srgb = false;
} ext;
struct {

View File

@@ -1259,7 +1259,11 @@ bool OpenGLDriver::isTextureFormatSupported(TextureFormat format) {
return gl.ext.texture_compression_etc2;
}
if (isS3TCCompression(format)) {
return gl.ext.texture_compression_s3tc;
if (isS3TCSRGBCompression(format)) {
return gl.ext.texture_compression_s3tc && (gl.ext.EXT_texture_sRGB || gl.ext.EXT_texture_compression_s3tc_srgb);
} else {
return gl.ext.texture_compression_s3tc;
}
}
return getInternalFormat(format) != 0;
}

View File

@@ -173,9 +173,13 @@ VkFormat getVkFormat(TextureFormat format) {
// Compressed textures.
case TextureFormat::DXT1_RGB: return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case TextureFormat::DXT1_SRGB: return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
case TextureFormat::DXT1_RGBA: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case TextureFormat::DXT1_SRGBA: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
case TextureFormat::DXT3_RGBA: return VK_FORMAT_BC2_UNORM_BLOCK;
case TextureFormat::DXT3_SRGBA: return VK_FORMAT_BC2_SRGB_BLOCK;
case TextureFormat::DXT5_RGBA: return VK_FORMAT_BC3_UNORM_BLOCK;
case TextureFormat::DXT5_SRGBA: return VK_FORMAT_BC3_SRGB_BLOCK;
case TextureFormat::RGBA_ASTC_4x4: return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
case TextureFormat::RGBA_ASTC_5x4: return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;