HiresTextures: Support DXT10 extended header in DDS loader
This commit is contained in:
parent
8761c8244d
commit
a6a13f51c1
|
@ -196,7 +196,8 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DDS_HEADER header;
|
DDS_HEADER header;
|
||||||
if (!file.ReadBytes(&header, sizeof(header)) || header.dwSize < sizeof(header))
|
size_t header_size = sizeof(header);
|
||||||
|
if (!file.ReadBytes(&header, header_size) || header.dwSize < header_size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Required fields.
|
// Required fields.
|
||||||
|
@ -229,35 +230,59 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
|
||||||
info->mip_count = 1;
|
info->mip_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently, we only handle compressed textures here, and leave the rest to the SOIL loader.
|
// Handle fourcc formats vs uncompressed formats.
|
||||||
// In the future, this could be extended, but these isn't much benefit in doing so currently.
|
bool has_fourcc = (header.ddspf.dwFlags & DDS_FOURCC) != 0;
|
||||||
// TODO: DX10 extension header handling.
|
|
||||||
// TODO: Support RGBA8 and friends.
|
|
||||||
bool needs_s3tc = false;
|
bool needs_s3tc = false;
|
||||||
if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '1'))
|
if (has_fourcc)
|
||||||
{
|
{
|
||||||
info->format = HostTextureFormat::DXT1;
|
// Handle DX10 extension header.
|
||||||
info->block_size = 4;
|
u32 dxt10_format = 0;
|
||||||
info->bytes_per_block = 8;
|
if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'))
|
||||||
needs_s3tc = true;
|
{
|
||||||
}
|
DDS_HEADER_DXT10 dxt10_header;
|
||||||
else if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '3'))
|
if (!file.ReadBytes(&dxt10_header, sizeof(dxt10_header)))
|
||||||
{
|
return false;
|
||||||
info->format = HostTextureFormat::DXT3;
|
|
||||||
info->block_size = 4;
|
// Can't handle array textures here. Doesn't make sense to use them, anyway.
|
||||||
info->bytes_per_block = 16;
|
if (dxt10_header.resourceDimension != DDS_DIMENSION_TEXTURE2D || dxt10_header.arraySize != 1)
|
||||||
needs_s3tc = true;
|
return false;
|
||||||
}
|
|
||||||
else if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '5'))
|
header_size += sizeof(dxt10_header);
|
||||||
{
|
dxt10_format = dxt10_header.dxgiFormat;
|
||||||
info->format = HostTextureFormat::DXT5;
|
}
|
||||||
info->block_size = 4;
|
|
||||||
info->bytes_per_block = 16;
|
// Currently, we only handle compressed textures here, and leave the rest to the SOIL loader.
|
||||||
needs_s3tc = true;
|
// In the future, this could be extended, but these isn't much benefit in doing so currently.
|
||||||
|
if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '1') || dxt10_format == 71)
|
||||||
|
{
|
||||||
|
info->format = HostTextureFormat::DXT1;
|
||||||
|
info->block_size = 4;
|
||||||
|
info->bytes_per_block = 8;
|
||||||
|
needs_s3tc = true;
|
||||||
|
}
|
||||||
|
else if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '3') || dxt10_format == 74)
|
||||||
|
{
|
||||||
|
info->format = HostTextureFormat::DXT3;
|
||||||
|
info->block_size = 4;
|
||||||
|
info->bytes_per_block = 16;
|
||||||
|
needs_s3tc = true;
|
||||||
|
}
|
||||||
|
else if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', 'T', '5') || dxt10_format == 77)
|
||||||
|
{
|
||||||
|
info->format = HostTextureFormat::DXT5;
|
||||||
|
info->block_size = 4;
|
||||||
|
info->bytes_per_block = 16;
|
||||||
|
needs_s3tc = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Leave all remaining formats to SOIL.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Leave all remaining formats to SOIL.
|
// TODO: Support RGBA8 and friends.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +320,7 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for truncated or corrupted files.
|
// Check for truncated or corrupted files.
|
||||||
info->first_mip_offset = sizeof(magic) + sizeof(DDS_HEADER);
|
info->first_mip_offset = sizeof(magic) + header_size;
|
||||||
if (info->first_mip_offset >= file.GetSize())
|
if (info->first_mip_offset >= file.GetSize())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue