Browse Source

Removed support for BC7-compressed DDS images (only *very* modern systems support it right now); updated the ddsparse library

Alex Szpakowski 12 years ago
parent
commit
0a36c41ba0

+ 100 - 102
src/libraries/ddsparse/ddsparse.cpp

@@ -33,25 +33,106 @@ namespace dds
 using namespace dds::dxinfo;
 
 // Creates a packed uint representation of a FourCC code.
-static inline uint32_t FourCC(char a, char b, char c, char d)
+#define MakeFourCC(a, b, c, d) ((uint32_t) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)))
+
+// Translate the old DDS format to our own.
+static Format parseDDSFormat(const DDSPixelFormat &fmt)
 {
-	uint32_t fcc = ((uint32_t) a)
-	            | (((uint32_t) b) << 8)
-	            | (((uint32_t) c) << 16)
-	            | (((uint32_t) d) << 24);
+	if ((fmt.flags & DDPF_FOURCC) == 0)
+		return FORMAT_UNKNOWN;
+
+	Format f = FORMAT_UNKNOWN;
+
+	switch (fmt.fourCC)
+	{
+	case MakeFourCC('D','X','T','1'):
+		f = FORMAT_DXT1;
+		break;
+	case MakeFourCC('D','X','T','3'):
+		f = FORMAT_DXT3;
+		break;
+	case MakeFourCC('D','X','T','5'):
+		f = FORMAT_DXT5;
+		break;
+	case MakeFourCC('A','T','I','1'):
+	case MakeFourCC('B','C','4','U'):
+		f = FORMAT_BC4;
+		break;
+	case MakeFourCC('B','C','4','S'):
+		f = FORMAT_BC4s;
+		break;
+	case MakeFourCC('A','T','I','2'):
+	case MakeFourCC('B','C','5','U'):
+		f = FORMAT_BC5;
+		break;
+	case MakeFourCC('B','C','5','S'):
+		f = FORMAT_BC5s;
+		break;
+	default:
+		break;
+	}
 
-	return fcc;
+	return f;
 }
 
-Parser::Image::Image()
-	: width(0)
-	, height(0)
-	, dataSize(0)
-	, data(0)
+// Translate the new DX10 formats to our own.
+static Format parseDX10Format(DXGIFormat fmt)
 {
+	Format f = FORMAT_UNKNOWN;
+
+	switch (fmt)
+	{
+	case DXGI_FORMAT_BC1_TYPELESS:
+	case DXGI_FORMAT_BC1_UNORM:
+	case DXGI_FORMAT_BC1_UNORM_SRGB:
+		f = FORMAT_DXT1;
+		break;
+	case DXGI_FORMAT_BC2_TYPELESS:
+	case DXGI_FORMAT_BC2_UNORM:
+	case DXGI_FORMAT_BC2_UNORM_SRGB:
+		f = FORMAT_DXT3;
+		break;
+	case DXGI_FORMAT_BC3_TYPELESS:
+	case DXGI_FORMAT_BC3_UNORM:
+	case DXGI_FORMAT_BC3_UNORM_SRGB:
+		f = FORMAT_DXT5;
+		break;
+	case DXGI_FORMAT_BC4_TYPELESS:
+	case DXGI_FORMAT_BC4_UNORM:
+		f = FORMAT_BC4;
+		break;
+	case DXGI_FORMAT_BC4_SNORM:
+		f = FORMAT_BC4s;
+		break;
+	case DXGI_FORMAT_BC5_TYPELESS:
+	case DXGI_FORMAT_BC5_UNORM:
+		f = FORMAT_BC5;
+		break;
+	case DXGI_FORMAT_BC5_SNORM:
+		f = FORMAT_BC5s;
+		break;
+	case DXGI_FORMAT_BC6H_TYPELESS:
+	case DXGI_FORMAT_BC6H_UF16:
+		f = FORMAT_BC6H;
+		break;
+	case DXGI_FORMAT_BC6H_SF16:
+		f = FORAMT_BC6Hs;
+		break;
+	case DXGI_FORMAT_BC7_TYPELESS:
+	case DXGI_FORMAT_BC7_UNORM:
+		f = FORMAT_BC7;
+		break;
+	case DXGI_FORMAT_BC7_UNORM_SRGB:
+		f = FORMAT_BC7srgb;
+		break;
+	default:
+		break;
+	}
+	
+	return f;
 }
 
-bool Parser::isDDS(const void *data, size_t dataSize)
+bool isDDS(const void *data, size_t dataSize)
 {
 	const uint8_t *readData = (const uint8_t *) data;
 	ptrdiff_t offset = 0;
@@ -61,7 +142,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
 		return false;
 
 	// All DDS files start with "DDS ".
-	if((*(uint32_t *) readData) != FourCC('D','D','S',' '))
+	if((*(uint32_t *) readData) != MakeFourCC('D','D','S',' '))
 		return false;
 
 	offset += sizeof(uint32_t);
@@ -76,7 +157,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
 	offset += sizeof(DDSHeader);
 
 	// Check for DX10 extension.
-	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
+	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
 	{
 		// Data must be big enough for both headers plus the magic value.
 		if (dataSize < (sizeof(uint32_t) + sizeof(DDSHeader) + sizeof(DDSHeader10)))
@@ -86,7 +167,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
 	return true;
 }
 
-bool Parser::isCompressedDDS(const void *data, size_t dataSize)
+bool isCompressedDDS(const void *data, size_t dataSize)
 {
 	if (!isDDS(data, dataSize))
 		return false;
@@ -98,7 +179,7 @@ bool Parser::isCompressedDDS(const void *data, size_t dataSize)
 	offset += sizeof(DDSHeader);
 
 	// Check for DX10 extension.
-	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
+	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
 	{
 		DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
 		return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN;
@@ -141,7 +222,7 @@ Format Parser::getFormat() const
 	return format;
 }
 
-const Parser::Image *Parser::getImageData(size_t miplevel) const
+const Image *Parser::getImageData(size_t miplevel) const
 {
 	if (miplevel >= texData.size())
 		return 0;
@@ -149,94 +230,11 @@ const Parser::Image *Parser::getImageData(size_t miplevel) const
 	return &texData[miplevel];
 }
 
-size_t Parser::getNumMipmaps() const
+size_t Parser::getMipmapCount() const
 {
 	return texData.size();
 }
 
-Format Parser::parseDDSFormat(const DDSPixelFormat &fmt)
-{
-	if (fmt.flags & DDPF_FOURCC)
-	{
-		if (fmt.fourCC == FourCC('D','X','T','1'))
-			return FORMAT_DXT1;
-		else if (fmt.fourCC == FourCC('D','X','T','3'))
-			return FORMAT_DXT3;
-		else if (fmt.fourCC == FourCC('D','X','T','5'))
-			return FORMAT_DXT5;
-		else if (fmt.fourCC == FourCC('A','T','I','1'))
-			return FORMAT_BC4;
-		else if (fmt.fourCC == FourCC('A','T','I','2'))
-			return FORMAT_BC5;
-		else if (fmt.fourCC == FourCC('B','C','4','U'))
-			return FORMAT_BC4;
-		else if (fmt.fourCC == FourCC('B','C','4','S'))
-			return FORMAT_BC4s;
-		else if (fmt.fourCC == FourCC('B','C','5','U'))
-			return FORMAT_BC5;
-		else if (fmt.fourCC == FourCC('B','C','5','S'))
-			return FORMAT_BC5s;
-	}
-
-	return FORMAT_UNKNOWN;
-}
-
-Format Parser::parseDX10Format(DXGIFormat fmt)
-{
-	Format f = FORMAT_UNKNOWN;
-
-	switch (fmt)
-	{
-	case DXGI_FORMAT_BC1_TYPELESS:
-	case DXGI_FORMAT_BC1_UNORM:
-	case DXGI_FORMAT_BC1_UNORM_SRGB:
-		f = FORMAT_DXT1;
-		break;
-	case DXGI_FORMAT_BC2_TYPELESS:
-	case DXGI_FORMAT_BC2_UNORM:
-	case DXGI_FORMAT_BC2_UNORM_SRGB:
-		f = FORMAT_DXT3;
-		break;
-	case DXGI_FORMAT_BC3_TYPELESS:
-	case DXGI_FORMAT_BC3_UNORM:
-	case DXGI_FORMAT_BC3_UNORM_SRGB:
-		f = FORMAT_DXT5;
-		break;
-	case DXGI_FORMAT_BC4_TYPELESS:
-	case DXGI_FORMAT_BC4_UNORM:
-		f = FORMAT_BC4;
-		break;
-	case DXGI_FORMAT_BC4_SNORM:
-		f = FORMAT_BC4s;
-		break;
-	case DXGI_FORMAT_BC5_TYPELESS:
-	case DXGI_FORMAT_BC5_UNORM:
-		f = FORMAT_BC5;
-		break;
-	case DXGI_FORMAT_BC5_SNORM:
-		f = FORMAT_BC5s;
-		break;
-	case DXGI_FORMAT_BC6H_TYPELESS:
-	case DXGI_FORMAT_BC6H_UF16:
-		f = FORMAT_BC6H;
-		break;
-	case DXGI_FORMAT_BC6H_SF16:
-		f = FORAMT_BC6Hs;
-		break;
-	case DXGI_FORMAT_BC7_TYPELESS:
-	case DXGI_FORMAT_BC7_UNORM:
-		f = FORMAT_BC7;
-		break;
-	case DXGI_FORMAT_BC7_UNORM_SRGB:
-		f = FORMAT_BC7srgb;
-		break;
-	default:
-		break;
-	}
-
-	return f;
-}
-
 size_t Parser::parseImageSize(Format fmt, int width, int height) const
 {
 	size_t size = 0;
@@ -318,7 +316,7 @@ bool Parser::parseData(const void *data, size_t dataSize)
 
 
 	// Check for DX10 extension.
-	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
+	if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
 	{
 		DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
 		offset += sizeof(DDSHeader10);

+ 29 - 36
src/libraries/ddsparse/ddsparse.h

@@ -25,13 +25,10 @@
 #ifndef DDS_PARSE_H
 #define DDS_PARSE_H
 
-#include "ddsinfo.h"
-
 #include <stddef.h>
 #include <stdint.h>
 
 #include <vector>
-#include <exception>
 
 namespace dds
 {
@@ -54,38 +51,39 @@ enum Format
 	FORMAT_UNKNOWN
 };
 
-class Parser
+// Represents a single mipmap level of a texture.
+struct Image
 {
-public:
+	int width;
+	int height;
+	size_t dataSize;
+	const uint8_t *data;
 
-	// Represents a single mipmap level of a texture.
-	struct Image
-	{
-		int width;
-		int height;
-		size_t dataSize;
-		const uint8_t *data;
+	Image() : width(0), height(0), dataSize(0), data(0)
+	{};
+};
 
-		Image();
-	};
+/**
+ * Determines whether the input byte data represents a valid DDS file.
+ * Does not take into account whether the texture format is supported.
+ *
+ * @param data     The byte data to parse.
+ * @param dataSize The size in bytes of the data.
+ **/
+bool isDDS(const void *data, size_t dataSize);
 
-	/**
-	 * Determines whether the input byte data represents a valid DDS file.
-	 * Does not take into account whether the texture format is supported.
-	 *
-	 * @param data     The byte data to parse.
-	 * @param dataSize The size in bytes of the data.
-	 **/
-	static bool isDDS(const void *data, size_t dataSize);
+/**
+ * Determines whether the input byte data represents a valid compressed DDS
+ * file. Takes into account texture format, but not type (3D textures, etc.)
+ *
+ * @param data     The byte data to parse.
+ * @param dataSize The size in bytes of the data.
+ **/
+bool isCompressedDDS(const void *data, size_t dataSize);
 
-	/**
-	 * Determines whether the input byte data represents a valid compressed DDS
-	 * file. Takes into account texture format, but not type (3D textures, etc.)
-	 *
-	 * @param data     The byte data to parse.
-	 * @param dataSize The size in bytes of the data.
-	 **/
-	static bool isCompressedDDS(const void *data, size_t dataSize);
+class Parser
+{
+public:
 
 	/**
 	 * Constructor.
@@ -121,17 +119,12 @@ public:
 	 * Gets the number of mipmap levels in this texture.
 	 * Includes the base mip level.
 	 **/
-	size_t getNumMipmaps() const;
+	size_t getMipmapCount() const;
 
 private:
 
-	static Format parseDDSFormat(const dxinfo::DDSPixelFormat &fmt);
-	static Format parseDX10Format(dxinfo::DXGIFormat fmt);
-
 	size_t parseImageSize(Format fmt, int width, int height) const;
-
 	bool parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips);
-
 	bool parseData(const void *data, size_t dataSize);
 
 	std::vector<Image> texData;

+ 0 - 1
src/modules/graphics/Graphics.cpp

@@ -178,7 +178,6 @@ StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::suppor
 	{ "mipmap", Graphics::SUPPORT_MIPMAP },
 	{ "dxt", Graphics::SUPPORT_DXT },
 	{ "bc5", Graphics::SUPPORT_BC5 },
-	{ "bc7", Graphics::SUPPORT_BC7 },
 };
 
 StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));

+ 0 - 1
src/modules/graphics/Graphics.h

@@ -97,7 +97,6 @@ public:
 		SUPPORT_MIPMAP,
 		SUPPORT_DXT,
 		SUPPORT_BC5,
-		SUPPORT_BC7,
 		SUPPORT_MAX_ENUM
 	};
 

+ 0 - 10
src/modules/graphics/opengl/Image.cpp

@@ -569,10 +569,6 @@ GLenum Image::getCompressedFormat(image::CompressedData::TextureType type) const
 		return GL_COMPRESSED_RG_RGTC2;
 	case image::CompressedData::TYPE_BC5s:
 		return GL_COMPRESSED_SIGNED_RG_RGTC2;
-	case image::CompressedData::TYPE_BC7:
-		return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
-	case image::CompressedData::TYPE_BC7srgb:
-		return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB;
 	default:
 		return GL_RGBA8;
 	}
@@ -614,15 +610,9 @@ bool Image::hasCompressedTextureSupport(image::CompressedData::TextureType type)
 	case image::CompressedData::TYPE_DXT3:
 	case image::CompressedData::TYPE_DXT5:
 		return GLEE_EXT_texture_compression_s3tc;
-
 	case image::CompressedData::TYPE_BC5:
 	case image::CompressedData::TYPE_BC5s:
 		return (GLEE_VERSION_3_0 || GLEE_ARB_texture_compression_rgtc || GLEE_EXT_texture_compression_rgtc);
-
-	case image::CompressedData::TYPE_BC7:
-	case image::CompressedData::TYPE_BC7srgb:
-		return (GLEE_VERSION_4_2 || GLEE_ARB_texture_compression_bptc);
-
 	default:
 		return false;
 

+ 0 - 4
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -1068,10 +1068,6 @@ int w_isSupported(lua_State *L)
 			if (!Image::hasCompressedTextureSupport(image::CompressedData::TYPE_BC5))
 				supported = false;
 			break;
-		case Graphics::SUPPORT_BC7:
-			if (!Image::hasCompressedTextureSupport(image::CompressedData::TYPE_BC7))
-				supported = false;
-			break;
 		default:
 			supported = false;
 		}

+ 0 - 2
src/modules/image/CompressedData.cpp

@@ -117,8 +117,6 @@ StringMap<CompressedData::TextureType, CompressedData::TYPE_MAX_ENUM>::Entry Com
 	{"dxt5", CompressedData::TYPE_DXT5},
 	{"bc5", CompressedData::TYPE_BC5},
 	{"bc5s", CompressedData::TYPE_BC5s},
-	{"bc7", CompressedData::TYPE_BC7},
-	{"bc7srgb", CompressedData::TYPE_BC7srgb},
 };
 
 StringMap<CompressedData::TextureType, CompressedData::TYPE_MAX_ENUM> CompressedData::types(CompressedData::typeEntries, sizeof(CompressedData::typeEntries));

+ 5 - 6
src/modules/image/CompressedData.h

@@ -36,10 +36,11 @@ namespace love
 namespace image
 {
 
-// CompressedData represents image data which is designed to be uploaded to the
-// GPU and rendered in its compressed form, without being un-compressed.
-// http://renderingpipeline.com/2012/07/texture-compression/
-
+/**
+ * CompressedData represents image data which is designed to be uploaded to the
+ * GPU and rendered in its compressed form, without being un-compressed.
+ * http://renderingpipeline.com/2012/07/texture-compression/
+ **/
 class CompressedData : public Data
 {
 public:
@@ -53,8 +54,6 @@ public:
 		TYPE_DXT5,
 		TYPE_BC5,
 		TYPE_BC5s,
-		TYPE_BC7,
-		TYPE_BC7srgb,
 		TYPE_MAX_ENUM
 	};
 

+ 5 - 9
src/modules/image/magpie/ddsHandler.cpp

@@ -32,12 +32,12 @@ bool ddsHandler::canParse(const filesystem::FileData *data)
 	if (data->getExtension().compare("dds") != 0)
 		return false;
 
-	return dds::Parser::isCompressedDDS(data->getData(), data->getSize());
+	return dds::isCompressedDDS(data->getData(), data->getSize());
 }
 
 CompressedData::TextureType ddsHandler::parse(filesystem::FileData *data, std::vector<CompressedData::SubImage> &images)
 {
-	if (!dds::Parser::isDDS(data->getData(), data->getSize()))
+	if (!dds::isDDS(data->getData(), data->getSize()))
 		throw love::Exception("Could not decode compressed data (not a DDS file?)");
 
 	CompressedData::TextureType textype = CompressedData::TYPE_UNKNOWN;
@@ -51,12 +51,12 @@ CompressedData::TextureType ddsHandler::parse(filesystem::FileData *data, std::v
 		if (textype == CompressedData::TYPE_UNKNOWN)
 			throw love::Exception("Could not parse compressed data: Unsupported format.");
 
-		if (parser.getNumMipmaps() == 0)
+		if (parser.getMipmapCount() == 0)
 			throw love::Exception("Could not parse compressed data: No readable texture data.");
 
-		for (size_t i = 0; i < parser.getNumMipmaps(); i++)
+		for (size_t i = 0; i < parser.getMipmapCount(); i++)
 		{
-			const dds::Parser::Image *img = parser.getImageData(i);
+			const dds::Image *img = parser.getImageData(i);
 
 			CompressedData::SubImage mip;
 
@@ -90,10 +90,6 @@ CompressedData::TextureType ddsHandler::convertFormat(dds::Format ddsformat)
 		return CompressedData::TYPE_BC5;
 	case dds::FORMAT_BC5s:
 		return CompressedData::TYPE_BC5s;
-	case dds::FORMAT_BC7:
-		return CompressedData::TYPE_BC7;
-	case dds::FORMAT_BC7srgb:
-		return CompressedData::TYPE_BC7srgb;
 	default:
 		return CompressedData::TYPE_UNKNOWN;
 	}

+ 1 - 0
src/modules/image/magpie/ddsHandler.h

@@ -22,6 +22,7 @@
 #define LOVE_IMAGE_MAGPIE_DDS_HANDLER_H
 
 // LOVE
+#include "common/EnumMap.h"
 #include "filesystem/FileData.h"
 #include "image/CompressedData.h"