diff --git a/src/nvcore/Array.h b/src/nvcore/Array.h index f7fa5ce..f85caf6 100644 --- a/src/nvcore/Array.h +++ b/src/nvcore/Array.h @@ -446,6 +446,14 @@ namespace nv return *this; } + // Release ownership of allocated memory and returns pointer to it. + T * release() { + T * tmp = m_buffer; + m_buffer = NULL; + m_size = 0; + m_buffer_size = 0; + return tmp; + } /// Array serialization. friend Stream & operator<< ( Stream & s, Array & p ) diff --git a/src/nvcore/Debug.cpp b/src/nvcore/Debug.cpp index f9cb60c..8c9e622 100644 --- a/src/nvcore/Debug.cpp +++ b/src/nvcore/Debug.cpp @@ -199,65 +199,65 @@ namespace nvDebug( "\nDumping stacktrace:\n" ); - // Resolve PC to function names - for (int i = start; i < size; i++) - { - // Check for end of stack walk - DWORD64 ip = (DWORD64)trace[i]; - if (ip == NULL) - break; - - // Get function name - #define MAX_STRING_LEN (512) - unsigned char byBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_STRING_LEN] = { 0 }; - IMAGEHLP_SYMBOL64 * pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer; - pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - pSymbol->MaxNameLength = MAX_STRING_LEN; - - DWORD64 dwDisplacement; - - if (SymGetSymFromAddr64(hProcess, ip, &dwDisplacement, pSymbol)) - { - pSymbol->Name[MAX_STRING_LEN-1] = 0; - - /* - // Make the symbol readable for humans - UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, - UNDNAME_COMPLETE | - UNDNAME_NO_THISTYPE | - UNDNAME_NO_SPECIAL_SYMS | - UNDNAME_NO_MEMBER_TYPE | - UNDNAME_NO_MS_KEYWORDS | - UNDNAME_NO_ACCESS_SPECIFIERS ); - */ - - // pSymbol->Name - const char * pFunc = pSymbol->Name; - - // Get file/line number - IMAGEHLP_LINE64 theLine = { 0 }; - theLine.SizeOfStruct = sizeof(theLine); - - DWORD dwDisplacement; - if (!SymGetLineFromAddr64(hProcess, ip, &dwDisplacement, &theLine)) - { - nvDebug("unknown(%08X) : %s\n", (uint32)ip, pFunc); - } - else - { - /* - const char* pFile = strrchr(theLine.FileName, '\\'); - if ( pFile == NULL ) pFile = theLine.FileName; - else pFile++; - */ - const char * pFile = theLine.FileName; - - int line = theLine.LineNumber; - - nvDebug("%s(%d) : %s\n", pFile, line, pFunc); - } + // Resolve PC to function names + for (int i = start; i < size; i++) + { + // Check for end of stack walk + DWORD64 ip = (DWORD64)trace[i]; + if (ip == NULL) + break; + + // Get function name + #define MAX_STRING_LEN (512) + unsigned char byBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_STRING_LEN] = { 0 }; + IMAGEHLP_SYMBOL64 * pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer; + pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSymbol->MaxNameLength = MAX_STRING_LEN; + + DWORD64 dwDisplacement; + + if (SymGetSymFromAddr64(hProcess, ip, &dwDisplacement, pSymbol)) + { + pSymbol->Name[MAX_STRING_LEN-1] = 0; + + /* + // Make the symbol readable for humans + UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, + UNDNAME_COMPLETE | + UNDNAME_NO_THISTYPE | + UNDNAME_NO_SPECIAL_SYMS | + UNDNAME_NO_MEMBER_TYPE | + UNDNAME_NO_MS_KEYWORDS | + UNDNAME_NO_ACCESS_SPECIFIERS ); + */ + + // pSymbol->Name + const char * pFunc = pSymbol->Name; + + // Get file/line number + IMAGEHLP_LINE64 theLine = { 0 }; + theLine.SizeOfStruct = sizeof(theLine); + + DWORD dwDisplacement; + if (!SymGetLineFromAddr64(hProcess, ip, &dwDisplacement, &theLine)) + { + nvDebug("unknown(%08X) : %s\n", (uint32)ip, pFunc); + } + else + { + /* + const char* pFile = strrchr(theLine.FileName, '\\'); + if ( pFile == NULL ) pFile = theLine.FileName; + else pFile++; + */ + const char * pFile = theLine.FileName; + + int line = theLine.LineNumber; + + nvDebug("%s(%d) : %s\n", pFile, line, pFunc); + } + } } - } } diff --git a/src/nvcore/HashMap.h b/src/nvcore/HashMap.h index ddc8474..2cc124b 100644 --- a/src/nvcore/HashMap.h +++ b/src/nvcore/HashMap.h @@ -400,6 +400,66 @@ namespace nv } #endif + // These two functions are not tested: + + // By default we serialize the key-value pairs compactly. + friend Stream & operator<< (Stream & s, HashMap & map) + { + int entry_count = map.entry_count; + s << entry_count; + + if (s.isLoading()) { + map.clear(); + map.entry_count = entry_count; + map.size_mask = nextPowerOfTwo(entry_count) - 1; + map.table = malloc(map.size_mask + 1); + + for (int i = 0; i <= map.size_mask; i++) { + map.table[i].next_in_chain = -2; // mark empty + } + + T key; + U value; + for (int i = 0; i < entry_count; i++) { + s << key << value; + map.add(key, value); + } + } + else { + foreach(i, map) { + s << map[i].key << map[i].value; + } + } + + return s; + } + + // This requires more storage, but saves us from rehashing the elements. + friend Stream & rawSerialize(Stream & s, HashMap & map) + { + if (s.isLoading()) { + map.clear(); + } + + s << map.size_mask; + + if (map.size_mask != -1) { + s << map.entry_count; + + if (s.isLoading()) { + map.table = new Entry[map.size_mask+1]; + } + + for (int i = 0; i <= map.size_mask; i++) { + Entry & e = map.table[i]; + s << e.next_in_chain << e.hash_value; + s << e.key; + s << e.value; + } + } + + return s; + } private: diff --git a/src/nvcore/StdStream.h b/src/nvcore/StdStream.h index 7a8538d..e0a44f5 100644 --- a/src/nvcore/StdStream.h +++ b/src/nvcore/StdStream.h @@ -6,6 +6,7 @@ #include "nvcore.h" #include "Stream.h" +#include "Array.h" #include // fopen #include // memcpy @@ -308,6 +309,38 @@ namespace nv }; + /// Buffer output stream. + class NVCORE_CLASS BufferOutputStream : public Stream + { + NV_FORBID_COPY(BufferOutputStream); + public: + + BufferOutputStream(Array & buffer) : m_buffer(buffer) { } + + virtual uint serialize( void * data, uint len ) + { + nvDebugCheck(data != NULL); + m_buffer.append((uint8 *)data, len); + return len; + } + + virtual void seek( uint pos ) { /*Not implemented*/ } + virtual uint tell() const { return m_buffer.size(); } + virtual uint size() const { return m_buffer.size(); } + + virtual bool isError() const { return false; } + virtual void clearError() {} + + virtual bool isAtEnd() const { return true; } + virtual bool isSeekable() const { return false; } + virtual bool isLoading() const { return false; } + virtual bool isSaving() const { return true; } + + private: + Array & m_buffer; + }; + + /// Protected input stream. class NVCORE_CLASS ProtectedStream : public Stream { diff --git a/src/nvcore/Utils.h b/src/nvcore/Utils.h index 05e59c5..73ed5e8 100644 --- a/src/nvcore/Utils.h +++ b/src/nvcore/Utils.h @@ -95,21 +95,21 @@ namespace nv } - // Some hash functors: - template struct Hash + inline uint sdbmHash(const void * data_in, uint size, uint h = 5381) { - inline uint sdbm_hash(const void * data_in, uint size, uint h = 5381) const - { - const uint8 * data = (const uint8 *) data_in; - uint i = 0; - while (i < size) { - h = (h << 16) + (h << 6) - h + (uint) data[i++]; - } - return h; + const uint8 * data = (const uint8 *) data_in; + uint i = 0; + while (i < size) { + h = (h << 16) + (h << 6) - h + (uint) data[i++]; } + return h; + } + // Some hash functors: + template struct Hash + { uint operator()(const Key & k) const { - return sdbm_hash(&k, sizeof(Key)); + return sdbmHash(&k, sizeof(Key)); } }; template <> struct Hash diff --git a/src/nvcore/nvcore.h b/src/nvcore/nvcore.h index eb303ed..07050c4 100644 --- a/src/nvcore/nvcore.h +++ b/src/nvcore/nvcore.h @@ -153,6 +153,8 @@ typedef uint32 uint; #define NV_STRING2(x) #x #define NV_STRING(x) NV_STRING2(x) +#define NV_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + #if 1 #if NV_CC_MSVC #define NV_MESSAGE(x) message(__FILE__ "(" NV_STRING(__LINE__) ") : " x) diff --git a/src/nvimage/DirectDrawSurface.cpp b/src/nvimage/DirectDrawSurface.cpp index 83e9be3..f789f45 100644 --- a/src/nvimage/DirectDrawSurface.cpp +++ b/src/nvimage/DirectDrawSurface.cpp @@ -44,17 +44,19 @@ using namespace nv; const uint nv::FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T'); +const uint nv::FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); +const uint nv::FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); +const uint nv::FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); +const uint nv::FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); +const uint nv::FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); +const uint nv::FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); +const uint nv::FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); +const uint nv::FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); +const uint nv::FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); + + namespace { - static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); - static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); - static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); - static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); - static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); - static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); - static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); - static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); - static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y'); @@ -133,7 +135,10 @@ namespace static const uint DDPF_PALETTEINDEXED8 = 0x00000020U; static const uint DDPF_LUMINANCE = 0x00020000U; static const uint DDPF_ALPHAPREMULT = 0x00008000U; - static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. + + // Custom NVTT flags. + static const uint DDPF_NORMAL = 0x80000000U; + static const uint DDPF_SRGB = 0x40000000U; // DX10 formats. enum DXGI_FORMAT @@ -522,24 +527,26 @@ namespace static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]); - static uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) +} // namespace + +uint nv::findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) +{ + for (int i = 0; i < s_d3dFormatCount; i++) { - for (uint i = 0; i < s_d3dFormatCount; i++) + if (s_d3dFormats[i].bitcount == bitcount && + s_d3dFormats[i].rmask == rmask && + s_d3dFormats[i].gmask == gmask && + s_d3dFormats[i].bmask == bmask && + s_d3dFormats[i].amask == amask) { - if (s_d3dFormats[i].bitcount == bitcount && - s_d3dFormats[i].rmask == rmask && - s_d3dFormats[i].gmask == gmask && - s_d3dFormats[i].bmask == bmask && - s_d3dFormats[i].amask == amask) - { - return s_d3dFormats[i].format; - } + return s_d3dFormats[i].format; } - - return 0; } -} // namespace + return 0; +} + + DDSHeader::DDSHeader() { @@ -755,6 +762,12 @@ void DDSHeader::setNormalFlag(bool b) else this->pf.flags &= ~DDPF_NORMAL; } +void DDSHeader::setSrgbFlag(bool b) +{ + if (b) this->pf.flags |= DDPF_SRGB; + else this->pf.flags &= ~DDPF_SRGB; +} + void DDSHeader::setHasAlphaFlag(bool b) { if (b) this->pf.flags |= DDPF_ALPHAPIXELS; @@ -831,6 +844,11 @@ bool DDSHeader::isNormalMap() const return (pf.flags & DDPF_NORMAL) != 0; } +bool DDSHeader::isSrgb() const +{ + return (pf.flags & DDPF_SRGB) != 0; +} + bool DDSHeader::hasAlpha() const { return (pf.flags & DDPF_ALPHAPIXELS) != 0; @@ -1160,7 +1178,7 @@ void * DirectDrawSurface::readData(uint * sizePtr) void * data = new unsigned char [size]; size = stream->serialize(data, size); - nvDebugCheck(uint(size) == *sizePtr); + nvDebugCheck(size == *sizePtr); return data; } diff --git a/src/nvimage/DirectDrawSurface.h b/src/nvimage/DirectDrawSurface.h index 3b294c9..bf2de59 100644 --- a/src/nvimage/DirectDrawSurface.h +++ b/src/nvimage/DirectDrawSurface.h @@ -34,6 +34,17 @@ namespace nv struct ColorBlock; extern const uint FOURCC_NVTT; + extern const uint FOURCC_DDS; + extern const uint FOURCC_DXT1; + extern const uint FOURCC_DXT2; + extern const uint FOURCC_DXT3; + extern const uint FOURCC_DXT4; + extern const uint FOURCC_DXT5; + extern const uint FOURCC_RXGB; + extern const uint FOURCC_ATI1; + extern const uint FOURCC_ATI2; + + extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); struct NVIMAGE_CLASS DDSPixelFormat { @@ -101,6 +112,7 @@ namespace nv void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); void setDX10Format(uint format); void setNormalFlag(bool b); + void setSrgbFlag(bool b); void setHasAlphaFlag(bool b); void setUserVersion(int version); @@ -111,6 +123,7 @@ namespace nv uint toolVersion() const; uint userVersion() const; bool isNormalMap() const; + bool isSrgb() const; bool hasAlpha() const; uint d3d9Format() const; }; diff --git a/src/nvimage/PixelFormat.h b/src/nvimage/PixelFormat.h index 8ccf2c1..78c0a68 100644 --- a/src/nvimage/PixelFormat.h +++ b/src/nvimage/PixelFormat.h @@ -33,47 +33,47 @@ namespace nv namespace PixelFormat { - // Convert component @a c having @a inbits to the returned value having @a outbits. - inline uint convert(uint c, uint inbits, uint outbits) - { - if (inbits == 0) - { - return 0; - } - else if (inbits >= outbits) - { - // truncate - return c >> (inbits - outbits); - } - else - { - // bitexpand - return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); - } - } - - // Get pixel component shift and size given its mask. - inline void maskShiftAndSize(uint mask, uint * shift, uint * size) - { - if (!mask) - { - *shift = 0; - *size = 0; - return; - } - - *shift = 0; - while((mask & 1) == 0) { - ++(*shift); - mask >>= 1; - } + // Convert component @a c having @a inbits to the returned value having @a outbits. + inline uint convert(uint c, uint inbits, uint outbits) + { + if (inbits == 0) + { + return 0; + } + else if (inbits >= outbits) + { + // truncate + return c >> (inbits - outbits); + } + else + { + // bitexpand + return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); + } + } - *size = 0; - while((mask & 1) == 1) { - ++(*size); - mask >>= 1; - } - } + // Get pixel component shift and size given its mask. + inline void maskShiftAndSize(uint mask, uint * shift, uint * size) + { + if (!mask) + { + *shift = 0; + *size = 0; + return; + } + + *shift = 0; + while((mask & 1) == 0) { + ++(*shift); + mask >>= 1; + } + + *size = 0; + while((mask & 1) == 1) { + ++(*size); + mask >>= 1; + } + } inline float quantizeCeil(float f, int inbits, int outbits) { diff --git a/src/nvmath/Box.h b/src/nvmath/Box.h index 7a4c764..f9aa458 100644 --- a/src/nvmath/Box.h +++ b/src/nvmath/Box.h @@ -27,6 +27,9 @@ namespace nv /// Init ctor. Box(Vector3::Arg mins, Vector3::Arg maxs) : minCorner(mins), maxCorner(maxs) { } + // Assignment operator. + Box & operator=(const Box & b) { minCorner = b.minCorner; maxCorner = b.maxCorner; return *this; } + // Cast operators. operator const float * () const { return reinterpret_cast(this); } diff --git a/src/nvmath/Fitting.cpp b/src/nvmath/Fitting.cpp index de387d5..ba0e5e5 100644 --- a/src/nvmath/Fitting.cpp +++ b/src/nvmath/Fitting.cpp @@ -66,7 +66,7 @@ Vector3 nv::Fit::computeCentroid(int n, const Vector3 *__restrict points) Vector3 nv::Fit::computeCentroid(int n, const Vector3 *__restrict points, const float *__restrict weights, Vector3::Arg metric) { - Vector3 centroid(0.0f ); + Vector3 centroid(0.0f); float total = 0.0f; for (int i = 0; i < n; i++) diff --git a/src/nvmath/Half.cpp b/src/nvmath/Half.cpp index 5cd32d4..057bbaf 100644 --- a/src/nvmath/Half.cpp +++ b/src/nvmath/Half.cpp @@ -496,10 +496,12 @@ nv::fast_half_to_float( uint16 h ) const uint32 h_f_s_pos_offset = _uint32_li( 0x00000010 ); const uint32 h_f_e_pos_offset = _uint32_li( 0x0000000d ); const uint32 h_f_bias_offset = _uint32_li( 0x0001c000 ); + const uint32 f_e_mask = _uint32_li( 0x7f800000 ); const uint32 f_m_mask = _uint32_li( 0x007fffff ); const uint32 h_f_e_denorm_bias = _uint32_li( 0x0000007e ); const uint32 h_f_m_denorm_sa_bias = _uint32_li( 0x00000008 ); const uint32 f_e_pos = _uint32_li( 0x00000017 ); + const uint32 h_e_mask_minus_one = _uint32_li( 0x00007bff ); const uint32 h_e = _uint32_and( h, h_e_mask ); const uint32 h_m = _uint32_and( h, h_m_mask ); const uint32 h_s = _uint32_and( h, h_s_mask ); @@ -515,8 +517,10 @@ nv::fast_half_to_float( uint16 h ) const uint32 f_m_denorm = _uint32_and( h_f_m, f_m_mask ); const uint32 f_e_denorm = _uint32_sll( f_e_denorm_unpacked, f_e_pos ); const uint32 f_em_denorm = _uint32_or( f_e_denorm, f_m_denorm ); + const uint32 f_em_nan = _uint32_or( f_e_mask, f_m ); const uint32 is_e_eqz_msb = _uint32_dec( h_e ); const uint32 is_m_nez_msb = _uint32_neg( h_m ); + const uint32 is_e_flagged_msb = _uint32_sub( h_e_mask_minus_one, h_e ); const uint32 is_zero_msb = _uint32_andc( is_e_eqz_msb, is_m_nez_msb ); const uint32 is_denorm_msb = _uint32_and( is_m_nez_msb, is_e_eqz_msb ); const uint32 is_zero = _uint32_ext( is_zero_msb ); diff --git a/src/nvmath/Matrix.h b/src/nvmath/Matrix.h index adbefe1..1bf182d 100644 --- a/src/nvmath/Matrix.h +++ b/src/nvmath/Matrix.h @@ -33,6 +33,8 @@ namespace nv void operator+=(const Matrix3 & m); void operator-=(const Matrix3 & m); + float determinant() const; + private: scalar m_data[9]; }; @@ -179,6 +181,17 @@ namespace nv return mul(a, b); } + inline float Matrix3::determinant() const + { + return + get(0,0) * get(1,1) * get(2,2) + + get(0,1) * get(1,2) * get(2,0) + + get(0,2) * get(1,0) * get(2,1) - + get(0,2) * get(1,1) * get(2,0) - + get(0,1) * get(1,0) * get(2,2) - + get(0,0) * get(1,2) * get(2,1); + } + /// 4x4 transformation matrix. diff --git a/src/nvtt/CompressionOptions.cpp b/src/nvtt/CompressionOptions.cpp index e32d496..1b3ff10 100644 --- a/src/nvtt/CompressionOptions.cpp +++ b/src/nvtt/CompressionOptions.cpp @@ -24,6 +24,7 @@ #include "nvtt.h" #include "CompressionOptions.h" +#include "nvimage/DirectDrawSurface.h" using namespace nv; using namespace nvtt; @@ -92,10 +93,10 @@ void CompressionOptions::setQuality(Quality quality) /// perception more than a 7%. A better choice in my opinion is (3, 4, 2). void CompressionOptions::setColorWeights(float red, float green, float blue, float alpha/*=1.0f*/) { -// float total = red + green + blue; -// float x = red / total; -// float y = green / total; -// m.colorWeight.set(x, y, 1.0f - x - y); +// float total = red + green + blue; +// float x = red / total; +// float y = green / total; +// m.colorWeight.set(x, y, 1.0f - x - y); m.colorWeight.set(red, green, blue, alpha); } @@ -185,4 +186,64 @@ void CompressionOptions::setQuantization(bool colorDithering, bool alphaDitherin } +// Translate to and from D3D formats. +unsigned int CompressionOptions::d3d9Format() const +{ + if (m.format == Format_RGB) { + if (m.pixelType == PixelType_UnsignedNorm) { + + uint bitcount = m.bitcount; + uint rmask = m.rmask; + uint gmask = m.gmask; + uint bmask = m.bmask; + uint amask = m.amask; + + if (bitcount == 0) { + bitcount = m.rsize + m.gsize + m.bsize + m.asize; + rmask = ((1 << m.rsize) - 1) << (m.asize + m.bsize + m.gsize); + gmask = ((1 << m.gsize) - 1) << (m.asize + m.bsize); + bmask = ((1 << m.bsize) - 1) << m.asize; + amask = ((1 << m.asize) - 1) << 0; + } + + if (bitcount <= 32) { + return nv::findD3D9Format(bitcount, rmask, gmask, bmask, amask); + } + } + + return 0; + } + else { + uint d3d9_formats[] = { + 0, // Format_RGB, + FOURCC_DXT1, // Format_DXT1 + FOURCC_DXT1, // Format_DXT1a + FOURCC_DXT3, // Format_DXT3 + FOURCC_DXT5, // Format_DXT5 + FOURCC_DXT5, // Format_DXT5n + FOURCC_ATI1, // Format_BC4 + FOURCC_ATI2, // Format_BC5 + FOURCC_DXT1, // Format_DXT1n + 0, // Format_CTX1 + 0, // Format_BC6 + 0, // Format_BC7 + 0, // Format_RGBE + }; + + return d3d9_formats[m.format]; + } +} + +/* +bool CompressionOptions::setDirect3D9Format(unsigned int format) +{ +} + +unsigned int CompressionOptions::dxgiFormat() const +{ +} +bool CompressionOptions::setDXGIFormat(unsigned int format) +{ +} +*/ diff --git a/src/nvtt/CompressorDX9.cpp b/src/nvtt/CompressorDX9.cpp index 97136d6..60f19ae 100644 --- a/src/nvtt/CompressorDX9.cpp +++ b/src/nvtt/CompressorDX9.cpp @@ -144,23 +144,23 @@ void NormalCompressorDXT1::compressBlock(ColorSet & set, nvtt::AlphaMode alphaMo } } #else -void NormalCompressorDXT1::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) -{ - nvsquish::WeightedClusterFit fit; - fit.SetMetric(compressionOptions.colorWeight.x, compressionOptions.colorWeight.y, compressionOptions.colorWeight.z); - - if (rgba.isSingleColor()) - { - BlockDXT1 * block = new(output) BlockDXT1; - OptimalCompress::compressDXT1(rgba.color(0), block); - } - else - { - nvsquish::ColourSet colours((uint8 *)rgba.colors(), 0); - fit.SetColourSet(&colours, nvsquish::kDxt1); - fit.Compress(output); - } -} +void NormalCompressorDXT1::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) +{ + nvsquish::WeightedClusterFit fit; + fit.SetMetric(compressionOptions.colorWeight.x, compressionOptions.colorWeight.y, compressionOptions.colorWeight.z); + + if (rgba.isSingleColor()) + { + BlockDXT1 * block = new(output) BlockDXT1; + OptimalCompress::compressDXT1(rgba.color(0), block); + } + else + { + nvsquish::ColourSet colours((uint8 *)rgba.colors(), 0); + fit.SetColourSet(&colours, nvsquish::kDxt1); + fit.Compress(output); + } +} #endif void NormalCompressorDXT1a::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) diff --git a/src/nvtt/CompressorRGB.cpp b/src/nvtt/CompressorRGB.cpp index a5bb4f0..6433872 100644 --- a/src/nvtt/CompressorRGB.cpp +++ b/src/nvtt/CompressorRGB.cpp @@ -110,7 +110,10 @@ namespace { nvDebugCheck(alignment >= 1); flush(); - putBits(0, ((size_t)ptr % alignment) * 8); + int remainder = (size_t)ptr % alignment; + if (remainder != 0) { + putBits(0, (alignment - remainder) * 8); + } } uint8 * ptr; diff --git a/src/nvtt/Context.cpp b/src/nvtt/Context.cpp index 6950187..6819461 100644 --- a/src/nvtt/Context.cpp +++ b/src/nvtt/Context.cpp @@ -571,7 +571,7 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int header.setSwizzleCode('A', '2', 'X', 'Y'); } } - else if (compressionOptions.format == Format_BC6) { + else if (compressionOptions.format == Format_BC6) { // @@ This is not supported by D3DX. Always use DX10 header with BC6-7 formats. header.setFourCC('Z', 'O', 'H', ' '); } else if (compressionOptions.format == Format_BC7) { @@ -586,6 +586,8 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int supported = false; } } + + if (outputOptions.srgb) header.setSrgbFlag(true); } if (!supported) @@ -595,9 +597,6 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int return false; } - // Swap bytes if necessary. - header.swapBytes(); - uint headerSize = 128; if (header.hasDX10Header()) { @@ -605,6 +604,9 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int headerSize = 128 + 20; } + // Swap bytes if necessary. + header.swapBytes(); + bool writeSucceed = outputOptions.writeData(&header, headerSize); if (!writeSucceed) { @@ -796,37 +798,3 @@ CompressorInterface * Compressor::Private::chooseGpuCompressor(const Compression return NULL; } - -/* -int Compressor::Private::estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const -{ - const Format format = compressionOptions.format; - - const uint bitCount = compressionOptions.getBitCount(); - const uint pitchAlignment = compressionOptions.pitchAlignment; - - uint mipmapCount, width, height, depth; - inputOptions.computeExtents(&mipmapCount, &width, &height, &depth); - - int size = 0; - - for (uint f = 0; f < inputOptions.faceCount; f++) - { - uint w = inputOptions.targetWidth; - uint h = inputOptions.targetHeight; - uint d = inputOptions.targetDepth; - - for (uint m = 0; m < mipmapCount; m++) - { - size += computeImageSize(w, h, d, bitCount, pitchAlignment, format); - - // Compute extents of next mipmap: - w = max(1U, w / 2); - h = max(1U, h / 2); - d = max(1U, d / 2); - } - } - - return size; -} -*/ diff --git a/src/nvtt/OutputOptions.cpp b/src/nvtt/OutputOptions.cpp index 226bfcd..f5c9906 100644 --- a/src/nvtt/OutputOptions.cpp +++ b/src/nvtt/OutputOptions.cpp @@ -51,6 +51,7 @@ void OutputOptions::reset() m.outputHeader = true; m.container = Container_DDS; m.version = 0; + m.srgb = false; } @@ -108,6 +109,12 @@ void OutputOptions::setUserVersion(int version) m.version = version; } +/// Set SRGB flag. +void OutputOptions::setSrgbFlag(bool b) +{ + m.srgb = b; +} + bool OutputOptions::Private::hasValidOutputHandler() const { if (!fileName.isNull()) diff --git a/src/nvtt/OutputOptions.h b/src/nvtt/OutputOptions.h index e021d46..06dd2c2 100644 --- a/src/nvtt/OutputOptions.h +++ b/src/nvtt/OutputOptions.h @@ -66,6 +66,7 @@ namespace nvtt bool outputHeader; Container container; int version; + bool srgb; bool hasValidOutputHandler() const; diff --git a/src/nvtt/TexImage.cpp b/src/nvtt/TexImage.cpp index eb317f4..e198472 100644 --- a/src/nvtt/TexImage.cpp +++ b/src/nvtt/TexImage.cpp @@ -234,6 +234,11 @@ void TexImage::setNormalMap(bool isNormalMap) } } +bool TexImage::isNull() const +{ + return m->image == NULL; +} + int TexImage::width() const { if (m->image != NULL) return m->image->width(); diff --git a/src/nvtt/nvtt.h b/src/nvtt/nvtt.h index 2df502a..f47ef4f 100644 --- a/src/nvtt/nvtt.h +++ b/src/nvtt/nvtt.h @@ -147,6 +147,12 @@ namespace nvtt NVTT_API void setPitchAlignment(int pitchAlignment); NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127); + + // Translate to and from D3D formats. + NVTT_API unsigned int d3d9Format() const; + //NVTT_API bool setD3D9Format(unsigned int format); + //NVTT_API unsigned int dxgiFormat() const; + //NVTT_API bool setDxgiFormat(unsigned int format); }; /* @@ -329,6 +335,7 @@ namespace nvtt NVTT_API void setOutputHeader(bool outputHeader); NVTT_API void setContainer(Container container); NVTT_API void setUserVersion(int version); + NVTT_API void setSrgbFlag(bool b); }; typedef void Task(void * context, int id); @@ -392,6 +399,7 @@ namespace nvtt NVTT_API void setNormalMap(bool isNormalMap); // Queries. + NVTT_API bool isNull() const; NVTT_API int width() const; NVTT_API int height() const; NVTT_API int depth() const; diff --git a/src/nvtt/tools/compress.cpp b/src/nvtt/tools/compress.cpp index 9f4d003..abde2a1 100644 --- a/src/nvtt/tools/compress.cpp +++ b/src/nvtt/tools/compress.cpp @@ -451,7 +451,7 @@ int main(int argc, char *argv[]) } // Block compressed textures with mipmaps must be powers of two. - //if (!noMipmaps && format != nvtt::Format_RGB) + if (!noMipmaps && format != nvtt::Format_RGB) { inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo); }