Add support for float10 and float11 formats. Not tested.
This commit is contained in:
parent
676a0b2908
commit
dc13d9e9d2
@ -40,22 +40,123 @@ using namespace nvtt;
|
||||
|
||||
namespace
|
||||
{
|
||||
inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
|
||||
{
|
||||
memcpy(dst, src, 4 * w);
|
||||
/* 11 and 10 bit floating point numbers according to the OpenGL packed float extension:
|
||||
http://www.opengl.org/registry/specs/EXT/packed_float.txt
|
||||
|
||||
2.1.A Unsigned 11-Bit Floating-Point Numbers
|
||||
|
||||
An unsigned 11-bit floating-point number has no sign bit, a 5-bit
|
||||
exponent (E), and a 6-bit mantissa (M). The value of an unsigned
|
||||
11-bit floating-point number (represented as an 11-bit unsigned
|
||||
integer N) is determined by the following:
|
||||
|
||||
0.0, if E == 0 and M == 0,
|
||||
2^-14 * (M / 64), if E == 0 and M != 0,
|
||||
2^(E-15) * (1 + M/64), if 0 < E < 31,
|
||||
INF, if E == 31 and M == 0, or
|
||||
NaN, if E == 31 and M != 0,
|
||||
|
||||
where
|
||||
|
||||
E = floor(N / 64), and
|
||||
M = N mod 64.
|
||||
|
||||
Implementations are also allowed to use any of the following
|
||||
alternative encodings:
|
||||
|
||||
0.0, if E == 0 and M != 0
|
||||
2^(E-15) * (1 + M/64) if E == 31 and M == 0
|
||||
2^(E-15) * (1 + M/64) if E == 31 and M != 0
|
||||
|
||||
When a floating-point value is converted to an unsigned 11-bit
|
||||
floating-point representation, finite values are rounded to the closet
|
||||
representable finite value. While less accurate, implementations
|
||||
are allowed to always round in the direction of zero. This means
|
||||
negative values are converted to zero. Likewise, finite positive
|
||||
values greater than 65024 (the maximum finite representable unsigned
|
||||
11-bit floating-point value) are converted to 65024. Additionally:
|
||||
negative infinity is converted to zero; positive infinity is converted
|
||||
to positive infinity; and both positive and negative NaN are converted
|
||||
to positive NaN.
|
||||
|
||||
Any representable unsigned 11-bit floating-point value is legal
|
||||
as input to a GL command that accepts 11-bit floating-point data.
|
||||
The result of providing a value that is not a floating-point number
|
||||
(such as infinity or NaN) to such a command is unspecified, but must
|
||||
not lead to GL interruption or termination. Providing a denormalized
|
||||
number or negative zero to GL must yield predictable results.
|
||||
|
||||
2.1.B Unsigned 10-Bit Floating-Point Numbers
|
||||
|
||||
An unsigned 10-bit floating-point number has no sign bit, a 5-bit
|
||||
exponent (E), and a 5-bit mantissa (M). The value of an unsigned
|
||||
10-bit floating-point number (represented as an 10-bit unsigned
|
||||
integer N) is determined by the following:
|
||||
|
||||
0.0, if E == 0 and M == 0,
|
||||
2^-14 * (M / 32), if E == 0 and M != 0,
|
||||
2^(E-15) * (1 + M/32), if 0 < E < 31,
|
||||
INF, if E == 31 and M == 0, or
|
||||
NaN, if E == 31 and M != 0,
|
||||
|
||||
where
|
||||
|
||||
E = floor(N / 32), and
|
||||
M = N mod 32.
|
||||
|
||||
When a floating-point value is converted to an unsigned 10-bit
|
||||
floating-point representation, finite values are rounded to the closet
|
||||
representable finite value. While less accurate, implementations
|
||||
are allowed to always round in the direction of zero. This means
|
||||
negative values are converted to zero. Likewise, finite positive
|
||||
values greater than 64512 (the maximum finite representable unsigned
|
||||
10-bit floating-point value) are converted to 64512. Additionally:
|
||||
negative infinity is converted to zero; positive infinity is converted
|
||||
to positive infinity; and both positive and negative NaN are converted
|
||||
to positive NaN.
|
||||
|
||||
Any representable unsigned 10-bit floating-point value is legal
|
||||
as input to a GL command that accepts 10-bit floating-point data.
|
||||
The result of providing a value that is not a floating-point number
|
||||
(such as infinity or NaN) to such a command is unspecified, but must
|
||||
not lead to GL interruption or termination. Providing a denormalized
|
||||
number or negative zero to GL must yield predictable results.
|
||||
*/
|
||||
|
||||
// @@ Is this correct? Not tested!
|
||||
// 6 bits of mantissa, 5 bits of exponent.
|
||||
static uint toFloat11(float f) {
|
||||
if (f < 0) f = 0; // Flush to 0 or to epsilon?
|
||||
if (f > 65024) f = 65024; // Flush to infinity or max?
|
||||
|
||||
Float754 F;
|
||||
F.value = f;
|
||||
|
||||
uint E = F.field.biasedexponent - 127 + 15;
|
||||
nvDebugCheck(E < 32);
|
||||
|
||||
uint M = F.field.mantissa >> (23 - 6);
|
||||
|
||||
return (E << 6) | M;
|
||||
}
|
||||
|
||||
inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)
|
||||
{
|
||||
memcpy(dst, src, 4 * w);
|
||||
// @@ Is this correct? Not tested!
|
||||
// 5 bits of mantissa, 5 bits of exponent.
|
||||
static uint toFloat10(float f) {
|
||||
if (f < 0) f = 0; // Flush to 0 or to epsilon?
|
||||
if (f > 64512) f = 64512; // Flush to infinity or max?
|
||||
|
||||
Float754 F;
|
||||
F.value = f;
|
||||
|
||||
uint E = F.field.biasedexponent - 127 + 15;
|
||||
nvDebugCheck(E < 32);
|
||||
|
||||
uint M = F.field.mantissa >> (23 - 5);
|
||||
|
||||
return (E << 5) | M;
|
||||
}
|
||||
|
||||
static uint16 to_half(float f)
|
||||
{
|
||||
union { float f; uint32 u; } c;
|
||||
c.f = f;
|
||||
return half_from_float(c.u);
|
||||
}
|
||||
|
||||
struct BitStream
|
||||
{
|
||||
@ -84,18 +185,28 @@ namespace
|
||||
|
||||
void putFloat(float f)
|
||||
{
|
||||
nvDebugCheck(bits == 0);
|
||||
nvDebugCheck(bits == 0); // @@ Do not require alignment.
|
||||
*((float *)ptr) = f;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
void putHalf(float f)
|
||||
{
|
||||
nvDebugCheck(bits == 0);
|
||||
nvDebugCheck(bits == 0); // @@ Do not require alignment.
|
||||
*((uint16 *)ptr) = to_half(f);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
void putFloat11(float f)
|
||||
{
|
||||
putBits(toFloat11(f), 11);
|
||||
}
|
||||
|
||||
void putFloat10(float f)
|
||||
{
|
||||
putBits(toFloat10(f), 10);
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
nvDebugCheck(bits < 8);
|
||||
@ -142,10 +253,11 @@ void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint
|
||||
bsize = compressionOptions.bsize;
|
||||
asize = compressionOptions.asize;
|
||||
|
||||
nvCheck(rsize == 0 || rsize == 16 || rsize == 32);
|
||||
nvCheck(gsize == 0 || gsize == 16 || gsize == 32);
|
||||
nvCheck(bsize == 0 || bsize == 16 || bsize == 32);
|
||||
nvCheck(asize == 0 || asize == 16 || asize == 32);
|
||||
// Other float sizes are not supported and will be zero-padded.
|
||||
nvDebugCheck(rsize == 0 || rsize == 10 || rsize == 11 || rsize == 16 || rsize == 32);
|
||||
nvDebugCheck(gsize == 0 || gsize == 10 || gsize == 11 || gsize == 16 || gsize == 32);
|
||||
nvDebugCheck(bsize == 0 || bsize == 10 || bsize == 11 || bsize == 16 || bsize == 32);
|
||||
nvDebugCheck(asize == 0 || asize == 10 || asize == 11 || asize == 16 || asize == 32);
|
||||
|
||||
bitCount = rsize + gsize + bsize + asize;
|
||||
}
|
||||
@ -213,15 +325,27 @@ void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint
|
||||
{
|
||||
if (rsize == 32) stream.putFloat(r);
|
||||
else if (rsize == 16) stream.putHalf(r);
|
||||
else if (rsize == 11) stream.putFloat11(r);
|
||||
else if (rsize == 10) stream.putFloat10(r);
|
||||
else stream.putBits(0, rsize);
|
||||
|
||||
if (gsize == 32) stream.putFloat(g);
|
||||
else if (gsize == 16) stream.putHalf(g);
|
||||
else if (gsize == 11) stream.putFloat11(g);
|
||||
else if (gsize == 10) stream.putFloat10(g);
|
||||
else stream.putBits(0, gsize);
|
||||
|
||||
if (bsize == 32) stream.putFloat(b);
|
||||
else if (bsize == 16) stream.putHalf(b);
|
||||
else if (bsize == 11) stream.putFloat11(b);
|
||||
else if (bsize == 10) stream.putFloat10(b);
|
||||
else stream.putBits(0, bsize);
|
||||
|
||||
if (asize == 32) stream.putFloat(a);
|
||||
else if (asize == 16) stream.putHalf(a);
|
||||
else if (asize == 11) stream.putFloat11(a);
|
||||
else if (asize == 10) stream.putFloat10(a);
|
||||
else stream.putBits(0, asize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -71,11 +71,11 @@ namespace nvtt
|
||||
struct CubeSurface;
|
||||
|
||||
|
||||
// Supported compression formats.
|
||||
// @@ I wish I had distinguished between "formats" and compressors.
|
||||
// That is, 'DXT1' is a format 'DXT1a' and 'DXT1n' are DXT1 compressors.
|
||||
// That is, 'DXT3' is a format 'DXT3n' is a DXT3 compressor.
|
||||
// Having multiple enums for the same ids only creates confusion. Clean this up.
|
||||
/// Supported compression formats.
|
||||
enum Format
|
||||
{
|
||||
// No compression.
|
||||
@ -105,7 +105,7 @@ namespace nvtt
|
||||
Format_BC7, // Not supported yet.
|
||||
};
|
||||
|
||||
/// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input.
|
||||
// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input. They are only relevant in RGBA mode.
|
||||
enum PixelType
|
||||
{
|
||||
PixelType_UnsignedNorm = 0,
|
||||
@ -116,7 +116,7 @@ namespace nvtt
|
||||
PixelType_UnsignedFloat = 5,
|
||||
};
|
||||
|
||||
/// Quality modes.
|
||||
// Quality modes.
|
||||
enum Quality
|
||||
{
|
||||
Quality_Fastest,
|
||||
@ -125,16 +125,17 @@ namespace nvtt
|
||||
Quality_Highest,
|
||||
};
|
||||
|
||||
/// DXT decoder.
|
||||
// DXT decoder.
|
||||
enum Decoder
|
||||
{
|
||||
Decoder_D3D10,
|
||||
Decoder_D3D9,
|
||||
Decoder_NV5x,
|
||||
//Decoder_RSX, // To take advantage of DXT5 bug.
|
||||
};
|
||||
|
||||
|
||||
/// Compression options. This class describes the desired compression format and other compression settings.
|
||||
// Compression options. This class describes the desired compression format and other compression settings.
|
||||
struct CompressionOptions
|
||||
{
|
||||
NVTT_FORBID_COPY(CompressionOptions);
|
||||
@ -159,6 +160,7 @@ namespace nvtt
|
||||
|
||||
NVTT_API void setPitchAlignment(int pitchAlignment);
|
||||
|
||||
// @@ I wish this wasn't part of the compression options. Quantization is applied before compression. We don't have compressors with error diffusion.
|
||||
NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
|
||||
|
||||
NVTT_API void setTargetDecoder(Decoder decoder);
|
||||
@ -181,7 +183,7 @@ namespace nvtt
|
||||
*/
|
||||
|
||||
|
||||
/// Wrap modes.
|
||||
// Wrap modes.
|
||||
enum WrapMode
|
||||
{
|
||||
WrapMode_Clamp,
|
||||
@ -189,7 +191,7 @@ namespace nvtt
|
||||
WrapMode_Mirror,
|
||||
};
|
||||
|
||||
/// Texture types.
|
||||
// Texture types.
|
||||
enum TextureType
|
||||
{
|
||||
TextureType_2D,
|
||||
@ -197,23 +199,23 @@ namespace nvtt
|
||||
TextureType_3D,
|
||||
};
|
||||
|
||||
/// Input formats.
|
||||
// Input formats.
|
||||
enum InputFormat
|
||||
{
|
||||
InputFormat_BGRA_8UB, // Normalized [0, 1] 8 bit fixed point.
|
||||
InputFormat_RGBA_16F, // 16 bit floating point.
|
||||
InputFormat_RGBA_32F, // 32 bit floating point.
|
||||
InputFormat_BGRA_8UB, // Normalized [0, 1] 8 bit fixed point.
|
||||
InputFormat_RGBA_16F, // 16 bit floating point.
|
||||
InputFormat_RGBA_32F, // 32 bit floating point.
|
||||
};
|
||||
|
||||
/// Mipmap downsampling filters.
|
||||
// Mipmap downsampling filters.
|
||||
enum MipmapFilter
|
||||
{
|
||||
MipmapFilter_Box, ///< Box filter is quite good and very fast.
|
||||
MipmapFilter_Triangle, ///< Triangle filter blurs the results too much, but that might be what you want.
|
||||
MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter.
|
||||
MipmapFilter_Box, // Box filter is quite good and very fast.
|
||||
MipmapFilter_Triangle, // Triangle filter blurs the results too much, but that might be what you want.
|
||||
MipmapFilter_Kaiser, // Kaiser-windowed Sinc filter is the best downsampling filter.
|
||||
};
|
||||
|
||||
/// Texture resize filters.
|
||||
// Texture resize filters.
|
||||
enum ResizeFilter
|
||||
{
|
||||
ResizeFilter_Box,
|
||||
@ -222,7 +224,7 @@ namespace nvtt
|
||||
ResizeFilter_Mitchell,
|
||||
};
|
||||
|
||||
/// Extents rounding mode.
|
||||
// Extents rounding mode.
|
||||
enum RoundMode
|
||||
{
|
||||
RoundMode_None,
|
||||
@ -231,7 +233,7 @@ namespace nvtt
|
||||
RoundMode_ToPreviousPowerOfTwo,
|
||||
};
|
||||
|
||||
/// Alpha mode.
|
||||
// Alpha mode.
|
||||
enum AlphaMode
|
||||
{
|
||||
AlphaMode_None,
|
||||
@ -239,7 +241,7 @@ namespace nvtt
|
||||
AlphaMode_Premultiplied,
|
||||
};
|
||||
|
||||
/// Input options. Specify format and layout of the input texture.
|
||||
// Input options. Specify format and layout of the input texture.
|
||||
struct InputOptions
|
||||
{
|
||||
NVTT_FORBID_COPY(InputOptions);
|
||||
@ -288,22 +290,22 @@ namespace nvtt
|
||||
};
|
||||
|
||||
|
||||
/// Output handler.
|
||||
// Output handler.
|
||||
struct OutputHandler
|
||||
{
|
||||
virtual ~OutputHandler() {}
|
||||
|
||||
/// Indicate the start of a new compressed image that's part of the final texture.
|
||||
// Indicate the start of a new compressed image that's part of the final texture.
|
||||
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) = 0;
|
||||
|
||||
/// Output data. Compressed data is output as soon as it's generated to minimize memory allocations.
|
||||
// Output data. Compressed data is output as soon as it's generated to minimize memory allocations.
|
||||
virtual bool writeData(const void * data, int size) = 0;
|
||||
|
||||
/// Indicate the end of a the compressed image.
|
||||
// Indicate the end of a the compressed image.
|
||||
virtual void endImage() = 0;
|
||||
};
|
||||
|
||||
/// Error codes.
|
||||
// Error codes.
|
||||
enum Error
|
||||
{
|
||||
Error_Unknown,
|
||||
@ -315,7 +317,7 @@ namespace nvtt
|
||||
Error_UnsupportedOutputFormat,
|
||||
};
|
||||
|
||||
/// Error handler.
|
||||
// Error handler.
|
||||
struct ErrorHandler
|
||||
{
|
||||
virtual ~ErrorHandler() {}
|
||||
@ -324,16 +326,18 @@ namespace nvtt
|
||||
virtual void error(Error e) = 0;
|
||||
};
|
||||
|
||||
/// Container.
|
||||
// Container.
|
||||
enum Container
|
||||
{
|
||||
Container_DDS,
|
||||
Container_DDS10,
|
||||
// Container_KTX, // Khronos Texture: http://www.khronos.org/opengles/sdk/tools/KTX/
|
||||
// Container_VTF, // Valve Texture Format: http://developer.valvesoftware.com/wiki/Valve_Texture_Format
|
||||
};
|
||||
|
||||
|
||||
/// Output Options. This class holds pointers to the interfaces that are used to report the output of
|
||||
/// the compressor to the user.
|
||||
// Output Options. This class holds pointers to the interfaces that are used to report the output of
|
||||
// the compressor to the user.
|
||||
struct OutputOptions
|
||||
{
|
||||
NVTT_FORBID_COPY(OutputOptions);
|
||||
@ -363,7 +367,7 @@ namespace nvtt
|
||||
virtual void dispatch(Task * task, void * context, int count) = 0;
|
||||
};
|
||||
|
||||
/// Context.
|
||||
// Context.
|
||||
struct Compressor
|
||||
{
|
||||
NVTT_FORBID_COPY(Compressor);
|
||||
@ -404,12 +408,13 @@ namespace nvtt
|
||||
NormalTransform_Orthographic,
|
||||
NormalTransform_Stereographic,
|
||||
NormalTransform_Paraboloid,
|
||||
NormalTransform_Quartic,
|
||||
NormalTransform_Quartic
|
||||
//NormalTransform_DualParaboloid,
|
||||
};
|
||||
|
||||
|
||||
/// A surface is a texture mipmap. Can be 2D or 3D.
|
||||
// A surface is one level of a 2D or 3D texture.
|
||||
// @@ It would be nice to add support for texture borders for correct resizing of tiled textures and constrained DXT compression.
|
||||
struct Surface
|
||||
{
|
||||
NVTT_API Surface();
|
||||
@ -519,15 +524,16 @@ namespace nvtt
|
||||
};
|
||||
|
||||
|
||||
// Cube layout formats.
|
||||
enum CubeLayout {
|
||||
CubeLayout_VerticalCross,
|
||||
CubeLayout_HorizontalCross,
|
||||
CubeLayout_Column,
|
||||
CubeLayout_Row,
|
||||
CubeLayout_LatitudeLongitude,
|
||||
CubeLayout_LatitudeLongitude
|
||||
};
|
||||
|
||||
/// A cubemap mipmap. CubeSurface?
|
||||
// A CubeSurface is one level of a cube map texture.
|
||||
struct CubeSurface
|
||||
{
|
||||
NVTT_API CubeSurface();
|
||||
@ -548,7 +554,7 @@ namespace nvtt
|
||||
Surface & face(int face);
|
||||
const Surface & face(int face) const;
|
||||
|
||||
// Layout conversion.
|
||||
// Layout conversion. @@ Not implemented.
|
||||
void fold(const Surface & img, CubeLayout layout);
|
||||
Surface unfold(CubeLayout layout) const;
|
||||
|
||||
@ -556,11 +562,12 @@ namespace nvtt
|
||||
|
||||
// @@ Add resizing methods.
|
||||
|
||||
// @@ Add edge fixup methods.
|
||||
|
||||
// Filtering.
|
||||
CubeSurface irradianceFilter(int size) const;
|
||||
CubeSurface cosinePowerFilter(int size, float cosinePower) const;
|
||||
|
||||
|
||||
/*
|
||||
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
||||
NVTT_API void resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user