Add support for BC7 compression

This commit is contained in:
Atlante45 2017-05-18 13:11:41 -07:00
parent c2b140cc03
commit a8b1a29a4a
8 changed files with 32 additions and 5 deletions

View file

@ -18,11 +18,10 @@ bool GLTexelFormat::isCompressed() const {
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
return true; return true;
break;
default: default:
return false; return false;
break;
} }
} }
@ -238,6 +237,9 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) {
case gpu::COMPRESSED_BC5_XY: case gpu::COMPRESSED_BC5_XY:
result = GL_COMPRESSED_RG_RGTC2; result = GL_COMPRESSED_RG_RGTC2;
break; break;
case gpu::COMPRESSED_BC7_SRGBA:
result = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
break;
default: default:
qCWarning(gpugllogging) << "Unknown combination of texel format"; qCWarning(gpugllogging) << "Unknown combination of texel format";
@ -364,6 +366,9 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
case gpu::COMPRESSED_BC5_XY: case gpu::COMPRESSED_BC5_XY:
texel.internalFormat = GL_COMPRESSED_RG_RGTC2; texel.internalFormat = GL_COMPRESSED_RG_RGTC2;
break; break;
case gpu::COMPRESSED_BC7_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
break;
default: default:
qCWarning(gpugllogging) << "Unknown combination of texel format"; qCWarning(gpugllogging) << "Unknown combination of texel format";
@ -634,6 +639,10 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
case gpu::COMPRESSED_BC5_XY: case gpu::COMPRESSED_BC5_XY:
texel.internalFormat = GL_COMPRESSED_RG_RGTC2; texel.internalFormat = GL_COMPRESSED_RG_RGTC2;
break; break;
case gpu::COMPRESSED_BC7_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
break;
default: default:
qCWarning(gpugllogging) << "Unknown combination of texel format"; qCWarning(gpugllogging) << "Unknown combination of texel format";
} }

View file

@ -112,6 +112,7 @@ void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
glCompressedTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, internalFormat, glCompressedTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, internalFormat,
static_cast<GLsizei>(sourceSize), sourcePointer); static_cast<GLsizei>(sourceSize), sourcePointer);
break; break;
@ -128,6 +129,7 @@ void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
glCompressedTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, internalFormat, glCompressedTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, internalFormat,
static_cast<GLsizei>(sourceSize), sourcePointer); static_cast<GLsizei>(sourceSize), sourcePointer);
break; break;

View file

@ -142,6 +142,7 @@ void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
glCompressedTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, internalFormat, glCompressedTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, internalFormat,
static_cast<GLsizei>(sourceSize), sourcePointer); static_cast<GLsizei>(sourceSize), sourcePointer);
break; break;
@ -156,6 +157,7 @@ void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RED_RGTC1:
case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_RG_RGTC2:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
if (glCompressedTextureSubImage2DEXT) { if (glCompressedTextureSubImage2DEXT) {
auto target = GLTexture::CUBE_FACE_LAYOUT[face]; auto target = GLTexture::CUBE_FACE_LAYOUT[face];
glCompressedTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, internalFormat, glCompressedTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, internalFormat,

View file

@ -24,6 +24,7 @@ const Element Element::COLOR_COMPRESSED_SRGB{ VEC4, NUINT8, COMPRESSED_BC1_SRGB
const Element Element::COLOR_COMPRESSED_SRGBA_MASK{ VEC4, NUINT8, COMPRESSED_BC1_SRGBA }; const Element Element::COLOR_COMPRESSED_SRGBA_MASK{ VEC4, NUINT8, COMPRESSED_BC1_SRGBA };
const Element Element::COLOR_COMPRESSED_SRGBA{ VEC4, NUINT8, COMPRESSED_BC3_SRGBA }; const Element Element::COLOR_COMPRESSED_SRGBA{ VEC4, NUINT8, COMPRESSED_BC3_SRGBA };
const Element Element::COLOR_COMPRESSED_XY{ VEC4, NUINT8, COMPRESSED_BC5_XY }; const Element Element::COLOR_COMPRESSED_XY{ VEC4, NUINT8, COMPRESSED_BC5_XY };
const Element Element::COLOR_COMPRESSED_SRGBA_HIGH{ VEC4, NUINT8, COMPRESSED_BC7_SRGBA };
const Element Element::VEC2NU8_XY{ VEC2, NUINT8, XY }; const Element Element::VEC2NU8_XY{ VEC2, NUINT8, XY };

View file

@ -163,6 +163,7 @@ enum Semantic {
COMPRESSED_BC3_SRGBA, COMPRESSED_BC3_SRGBA,
COMPRESSED_BC4_RED, COMPRESSED_BC4_RED,
COMPRESSED_BC5_XY, COMPRESSED_BC5_XY,
COMPRESSED_BC7_SRGBA,
_LAST_COMPRESSED, _LAST_COMPRESSED,
@ -234,6 +235,7 @@ public:
static const Element COLOR_COMPRESSED_SRGBA_MASK; static const Element COLOR_COMPRESSED_SRGBA_MASK;
static const Element COLOR_COMPRESSED_SRGBA; static const Element COLOR_COMPRESSED_SRGBA;
static const Element COLOR_COMPRESSED_XY; static const Element COLOR_COMPRESSED_XY;
static const Element COLOR_COMPRESSED_SRGBA_HIGH;
static const Element VEC2NU8_XY; static const Element VEC2NU8_XY;
static const Element VEC4F_COLOR_RGBA; static const Element VEC4F_COLOR_RGBA;
static const Element VEC2F_UV; static const Element VEC2F_UV;

View file

@ -517,6 +517,8 @@ bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat
header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_RED_RGTC1, ktx::GLBaseInternalFormat::RED); header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_RED_RGTC1, ktx::GLBaseInternalFormat::RED);
} else if (texelFormat == Format::COLOR_COMPRESSED_XY && mipFormat == Format::COLOR_COMPRESSED_XY) { } else if (texelFormat == Format::COLOR_COMPRESSED_XY && mipFormat == Format::COLOR_COMPRESSED_XY) {
header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2, ktx::GLBaseInternalFormat::RG); header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2, ktx::GLBaseInternalFormat::RG);
} else if (texelFormat == Format::COLOR_COMPRESSED_SRGBA_HIGH && mipFormat == Format::COLOR_COMPRESSED_SRGBA_HIGH) {
header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM, ktx::GLBaseInternalFormat::RGBA);
} else { } else {
return false; return false;
} }
@ -575,6 +577,9 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E
} else if (header.getGLInternaFormat_Compressed() == ktx::GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2) { } else if (header.getGLInternaFormat_Compressed() == ktx::GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2) {
mipFormat = Format::COLOR_COMPRESSED_XY; mipFormat = Format::COLOR_COMPRESSED_XY;
texelFormat = Format::COLOR_COMPRESSED_XY; texelFormat = Format::COLOR_COMPRESSED_XY;
} else if (header.getGLInternaFormat_Compressed() == ktx::GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
mipFormat = Format::COLOR_COMPRESSED_SRGBA_HIGH;
texelFormat = Format::COLOR_COMPRESSED_SRGBA_HIGH;
} else { } else {
return false; return false;
} }

View file

@ -344,7 +344,7 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) {
nvtt::TextureType textureType = nvtt::TextureType_2D; nvtt::TextureType textureType = nvtt::TextureType_2D;
nvtt::InputFormat inputFormat = nvtt::InputFormat_BGRA_8UB; nvtt::InputFormat inputFormat = nvtt::InputFormat_BGRA_8UB;
nvtt::WrapMode wrapMode = nvtt::WrapMode_Repeat; nvtt::WrapMode wrapMode = nvtt::WrapMode_Mirror;
nvtt::RoundMode roundMode = nvtt::RoundMode_None; nvtt::RoundMode roundMode = nvtt::RoundMode_None;
nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None; nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None;
@ -380,6 +380,9 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) {
compressionOptions.setFormat(nvtt::Format_BC4); compressionOptions.setFormat(nvtt::Format_BC4);
} else if (mipFormat == gpu::Element::COLOR_COMPRESSED_XY) { } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_XY) {
compressionOptions.setFormat(nvtt::Format_BC5); compressionOptions.setFormat(nvtt::Format_BC5);
} else if (mipFormat == gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH) {
alphaMode = nvtt::AlphaMode_Transparency;
compressionOptions.setFormat(nvtt::Format_BC7);
} else if (mipFormat == gpu::Element::COLOR_RGBA_32) { } else if (mipFormat == gpu::Element::COLOR_RGBA_32) {
compressionOptions.setFormat(nvtt::Format_RGBA); compressionOptions.setFormat(nvtt::Format_RGBA);
compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm);
@ -934,8 +937,8 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage&
gpu::Element formatMip; gpu::Element formatMip;
gpu::Element formatGPU; gpu::Element formatGPU;
if (isCubeTexturesCompressionEnabled()) { if (isCubeTexturesCompressionEnabled()) {
formatMip = gpu::Element::COLOR_COMPRESSED_SRGBA; formatMip = gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH;
formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA; formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH;
} else { } else {
formatMip = gpu::Element::COLOR_SRGBA_32; formatMip = gpu::Element::COLOR_SRGBA_32;
formatGPU = gpu::Element::COLOR_SRGBA_32; formatGPU = gpu::Element::COLOR_SRGBA_32;

View file

@ -56,6 +56,7 @@ uint32_t Header::evalPixelOrBlockHeight(uint32_t level) const {
case GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: // BC3 case GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: // BC3
case GLInternalFormat_Compressed::COMPRESSED_RED_RGTC1: // BC4 case GLInternalFormat_Compressed::COMPRESSED_RED_RGTC1: // BC4
case GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2: // BC5 case GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2: // BC5
case GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM: // BC7
return (pixelWidth + 3) / 4; return (pixelWidth + 3) / 4;
default: default:
throw std::runtime_error("Unknown format"); throw std::runtime_error("Unknown format");
@ -81,6 +82,8 @@ size_t Header::evalPixelOrBlockSize() const {
return 8; return 8;
} else if (format == GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2) { } else if (format == GLInternalFormat_Compressed::COMPRESSED_RG_RGTC2) {
return 16; return 16;
} else if (format == GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
return 16;
} }
} else { } else {
auto baseFormat = getGLBaseInternalFormat(); auto baseFormat = getGLBaseInternalFormat();