mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-04-19 08:58:56 +00:00
BPTC modes for image_usePrecompressedTextures + image_useCompression
Both can now be set to 2 instead of just 0/1. For image_usePrecompressedTextures 1 now means "use .dds files no matter how they're compressed" and 2 means "only use .dds files if they are compressed with BPTC/BC7 or are uncompressed". For image_useCompression 1 means "compress textures with S3TC on upload" (just like before) and 2 means "compress with BPTC/BC7 if available" I wasn't sure whether this option makes sense for image_useCompression (over always using BPTC if available), but I can imagine that loading takes longer with BPTC (the driver has to compress the raw image data and compressing to S3TC might be faster than for BPTC)
This commit is contained in:
parent
f3cd3f31d0
commit
24cd2f1b4e
3 changed files with 59 additions and 17 deletions
|
@ -386,7 +386,7 @@ public:
|
|||
static idCVar image_roundDown; // round bad sizes down to nearest power of two
|
||||
static idCVar image_colorMipLevels; // development aid to see texture mip usage
|
||||
static idCVar image_downSize; // controls texture downsampling
|
||||
static idCVar image_useCompression; // 0 = force everything to high quality
|
||||
static idCVar image_useCompression; // 0 = force everything to high quality 1 = compress with S3TC (DXT) 2 = compress with BPTC if possible
|
||||
static idCVar image_filter; // changes texture filtering on mipmapped images
|
||||
static idCVar image_anisotropy; // set the maximum texture anisotropy if available
|
||||
static idCVar image_lodbias; // change lod bias on mipmapped images
|
||||
|
|
|
@ -53,10 +53,13 @@ idCVar idImageManager::image_forceDownSize( "image_forceDownSize", "0", CVAR_REN
|
|||
idCVar idImageManager::image_roundDown( "image_roundDown", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "round bad sizes down to nearest power of two" );
|
||||
idCVar idImageManager::image_colorMipLevels( "image_colorMipLevels", "0", CVAR_RENDERER | CVAR_BOOL, "development aid to see texture mip usage" );
|
||||
idCVar idImageManager::image_preload( "image_preload", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "if 0, dynamically load all images" );
|
||||
idCVar idImageManager::image_useCompression( "image_useCompression", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "0 = force everything to high quality" );
|
||||
idCVar idImageManager::image_useCompression( "image_useCompression", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER,
|
||||
"Compress textures on load so they use less VRAM. 1 = compress with S3TC/DXT when uploading 2 = compress with BPTC when uploading (if available) "
|
||||
"0 = upload uncompressed (unless image_usePrecompressedTextures is 1 and it's loaded from a precompressed .dds file)" );
|
||||
idCVar idImageManager::image_useAllFormats( "image_useAllFormats", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "allow alpha/intensity/luminance/luminance+alpha" );
|
||||
idCVar idImageManager::image_useNormalCompression( "image_useNormalCompression", "2", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "2 = use rxgb compression for normal maps, 1 = use 256 color compression for normal maps if available" );
|
||||
idCVar idImageManager::image_usePrecompressedTextures( "image_usePrecompressedTextures", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use .dds files if present" );
|
||||
idCVar idImageManager::image_usePrecompressedTextures( "image_usePrecompressedTextures", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER,
|
||||
"1 = use .dds files if present 2 = only use .dds files if they contain BPTC (BC7) textures (those have higher quality than S3TC/DXT) 0 = use uncompressed textures" );
|
||||
idCVar idImageManager::image_writePrecompressedTextures( "image_writePrecompressedTextures", "0", CVAR_RENDERER | CVAR_BOOL, "write .dds files if necessary" );
|
||||
idCVar idImageManager::image_writeNormalTGA( "image_writeNormalTGA", "0", CVAR_RENDERER | CVAR_BOOL, "write .tgas of the final normal maps for debugging" );
|
||||
idCVar idImageManager::image_writeNormalTGAPalletized( "image_writeNormalTGAPalletized", "0", CVAR_RENDERER | CVAR_BOOL, "write .tgas of the final palletized normal maps for debugging" );
|
||||
|
|
|
@ -215,6 +215,11 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
int rgbOr, rgbAnd, aOr, aAnd;
|
||||
int rgbDiffer, rgbaDiffer;
|
||||
|
||||
// TODO: or always use BC7 if available? do textures take longer to load then?
|
||||
// would look better at least...
|
||||
const bool useBC7compression = glConfig.bptcTextureCompressionAvailable
|
||||
&& globalImages->image_useCompression.GetInteger() == 2;
|
||||
|
||||
// determine if the rgb channels are all the same
|
||||
// and if either all rgb or all alpha are 255
|
||||
c = width*height;
|
||||
|
@ -262,12 +267,17 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
|
||||
// catch normal maps first
|
||||
if ( minimumDepth == TD_BUMP ) {
|
||||
if ( globalImages->image_useCompression.GetBool() && globalImages->image_useNormalCompression.GetInteger() == 1 && glConfig.sharedTexturePaletteAvailable ) {
|
||||
// DG: put the glConfig.sharedTexturePaletteAvailable check first because nowadays it's usually false
|
||||
if ( glConfig.sharedTexturePaletteAvailable && globalImages->image_useCompression.GetBool() && globalImages->image_useNormalCompression.GetInteger() == 1 ) {
|
||||
// image_useNormalCompression should only be set to 1 on nv_10 and nv_20 paths
|
||||
return GL_COLOR_INDEX8_EXT;
|
||||
} else if ( globalImages->image_useCompression.GetBool() && globalImages->image_useNormalCompression.GetInteger() && glConfig.textureCompressionAvailable ) {
|
||||
// image_useNormalCompression == 2 uses rxgb format which produces really good quality for medium settings
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
if ( useBC7compression ) {
|
||||
return GL_COMPRESSED_RGBA_BPTC_UNORM;
|
||||
} else {
|
||||
// image_useNormalCompression == 2 uses rxgb format which produces really good quality for medium settings
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
}
|
||||
} else {
|
||||
// we always need the alpha channel for bump maps for swizzling
|
||||
return GL_RGBA8;
|
||||
|
@ -282,7 +292,7 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
if ( minimumDepth == TD_SPECULAR ) {
|
||||
// we are assuming that any alpha channel is unintentional
|
||||
if ( glConfig.textureCompressionAvailable ) {
|
||||
return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
return useBC7compression ? GL_COMPRESSED_RGBA_BPTC_UNORM : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
} else {
|
||||
return GL_RGB5;
|
||||
}
|
||||
|
@ -290,6 +300,9 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
if ( minimumDepth == TD_DIFFUSE ) {
|
||||
// we might intentionally have an alpha channel for alpha tested textures
|
||||
if ( glConfig.textureCompressionAvailable ) {
|
||||
if ( useBC7compression ) {
|
||||
return GL_COMPRESSED_RGBA_BPTC_UNORM;
|
||||
}
|
||||
if ( !needAlpha ) {
|
||||
return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
} else {
|
||||
|
@ -319,7 +332,8 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
return GL_RGB8; // four bytes
|
||||
}
|
||||
if ( glConfig.textureCompressionAvailable ) {
|
||||
return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // half byte
|
||||
return useBC7compression ? GL_COMPRESSED_RGBA_BPTC_UNORM // 1byte/pixel
|
||||
: GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // half byte
|
||||
}
|
||||
return GL_RGB5; // two bytes
|
||||
}
|
||||
|
@ -327,7 +341,7 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
// cases with alpha
|
||||
if ( !rgbaDiffer ) {
|
||||
if ( minimumDepth != TD_HIGH_QUALITY && glConfig.textureCompressionAvailable ) {
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte
|
||||
return useBC7compression ? GL_COMPRESSED_RGBA_BPTC_UNORM : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte
|
||||
}
|
||||
return GL_INTENSITY8; // single byte for all channels
|
||||
}
|
||||
|
@ -346,7 +360,7 @@ GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, in
|
|||
return GL_RGBA8; // four bytes
|
||||
}
|
||||
if ( glConfig.textureCompressionAvailable ) {
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte
|
||||
return useBC7compression ? GL_COMPRESSED_RGBA_BPTC_UNORM : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte
|
||||
}
|
||||
if ( !rgbDiffer ) {
|
||||
return GL_LUMINANCE8_ALPHA8; // two bytes, max quality
|
||||
|
@ -1166,6 +1180,9 @@ void idImage::WritePrecompressedImage() {
|
|||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
header.ddspf.dwFourCC = DDS_MAKEFOURCC('D','X','T','5');
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_BPTC_UNORM:
|
||||
header.ddspf.dwFourCC = DDS_MAKEFOURCC('B','C','7','0');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
header.ddspf.dwFlags = ( internalFormat == GL_COLOR_INDEX8_EXT ) ? DDSF_RGB | DDSF_ID_INDEXCOLOR : DDSF_RGB;
|
||||
|
@ -1412,15 +1429,33 @@ bool idImage::CheckPrecompressedImage( bool fullLoad ) {
|
|||
|
||||
// DG: same if this is a BC7 (BPTC) texture but the GPU doesn't support that
|
||||
// or if it uses the additional DX10 header and is *not* a BC7 texture
|
||||
bool isBC7 = false;
|
||||
if ( ddspf_dwFourCC == DDS_MAKEFOURCC( 'D', 'X', '1', '0' ) ) {
|
||||
ddsDXT10addHeader_t *dx10Header = (ddsDXT10addHeader_t *)( data + 4 + sizeof(ddsFileHeader_t) );
|
||||
unsigned int dxgiFormat = LittleInt( dx10Header->dxgiFormat );
|
||||
if ( dxgiFormat != 98 // DXGI_FORMAT_BC7_UNORM
|
||||
|| !glConfig.bptcTextureCompressionAvailable ) {
|
||||
if (dxgiFormat != 98) {
|
||||
common->Warning( "Image file '%s' has unsupported dxgiFormat %d - dhewm3 only supports DXGI_FORMAT_BC7_UNORM (98)!",
|
||||
filename, dxgiFormat);
|
||||
}
|
||||
if ( dxgiFormat == 98 ) {
|
||||
isBC7 = true;
|
||||
} else {
|
||||
common->Warning( "Image file '%s' has unsupported dxgiFormat %d - dhewm3 only supports DXGI_FORMAT_BC7_UNORM (98)!",
|
||||
filename, dxgiFormat);
|
||||
R_StaticFree( data );
|
||||
return false;
|
||||
}
|
||||
} else if ( ddspf_dwFourCC == DDS_MAKEFOURCC( 'B', 'C', '7', '0' )
|
||||
|| ddspf_dwFourCC == DDS_MAKEFOURCC( 'B', 'C', '7', 'L' ) )
|
||||
{
|
||||
isBC7 = true;
|
||||
}
|
||||
if ( isBC7 && !glConfig.bptcTextureCompressionAvailable ) {
|
||||
R_StaticFree( data );
|
||||
return false;
|
||||
}
|
||||
if ( glConfig.bptcTextureCompressionAvailable
|
||||
&& globalImages->image_usePrecompressedTextures.GetInteger() == 2 )
|
||||
{
|
||||
// only high quality compressed textures, i.e. BC7 (BPTC), are welcome
|
||||
// or uncompressed ones (that have no FOURCC flag set)
|
||||
if ( !isBC7 && (ddspf_dwFlags & DDSF_FOURCC) != 0 ) {
|
||||
R_StaticFree( data );
|
||||
return false;
|
||||
}
|
||||
|
@ -1494,7 +1529,11 @@ void idImage::UploadPrecompressedImage( byte *data, int len ) {
|
|||
case DDS_MAKEFOURCC( 'R', 'X', 'G', 'B' ):
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
case DDS_MAKEFOURCC( 'D', 'X', '1', '0' ): // BC7 aka BPTC
|
||||
case DDS_MAKEFOURCC( 'B', 'C', '7', '0' ): // BC7 aka BPTC - inofficial FourCCs
|
||||
case DDS_MAKEFOURCC( 'B', 'C', '7', 'L' ):
|
||||
internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM;
|
||||
break;
|
||||
case DDS_MAKEFOURCC( 'D', 'X', '1', '0' ): // BC7 aka BPTC - the official dxgi way
|
||||
additionalHeaderOffset = 20;
|
||||
// Note: this is a bit hacky, but in CheckPrecompressedImage() we made sure
|
||||
// that only BC7 UNORM is accepted if the FourCC is 'DX10'
|
||||
|
|
Loading…
Reference in a new issue