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:
committed by
Romain Guy
parent
b351e709c1
commit
041f26a7c5
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user