Merge pull request #236 from mpersano/master
Add support for compressing texture arrays.
This commit is contained in:
commit
875a78a124
@ -427,60 +427,85 @@ namespace
|
|||||||
{
|
{
|
||||||
struct FormatDescriptor
|
struct FormatDescriptor
|
||||||
{
|
{
|
||||||
uint format;
|
uint d3d9Format;
|
||||||
uint bitcount;
|
uint dxgiFormat;
|
||||||
uint rmask;
|
RGBAPixelFormat pixelFormat;
|
||||||
uint gmask;
|
|
||||||
uint bmask;
|
|
||||||
uint amask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FormatDescriptor s_d3d9Formats[] =
|
static const FormatDescriptor s_formats[] =
|
||||||
{
|
{
|
||||||
{ D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 },
|
{ D3DFMT_R8G8B8, DXGI_FORMAT_UNKNOWN, { 24, 0xFF0000, 0xFF00, 0xFF, 0 } },
|
||||||
{ D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM
|
{ D3DFMT_A8R8G8B8, DXGI_FORMAT_B8G8R8A8_UNORM, { 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 } },
|
||||||
{ D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM
|
{ D3DFMT_X8R8G8B8, DXGI_FORMAT_B8G8R8X8_UNORM, { 32, 0xFF0000, 0xFF00, 0xFF, 0 } },
|
||||||
{ D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM
|
{ D3DFMT_R5G6B5, DXGI_FORMAT_B5G6R5_UNORM, { 16, 0xF800, 0x7E0, 0x1F, 0 } },
|
||||||
{ D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 },
|
{ D3DFMT_X1R5G5B5, DXGI_FORMAT_UNKNOWN, { 16, 0x7C00, 0x3E0, 0x1F, 0 } },
|
||||||
{ D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM
|
{ D3DFMT_A1R5G5B5, DXGI_FORMAT_B5G5R5A1_UNORM, { 16, 0x7C00, 0x3E0, 0x1F, 0x8000 } },
|
||||||
{ D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 },
|
{ D3DFMT_A4R4G4B4, DXGI_FORMAT_UNKNOWN, { 16, 0xF00, 0xF0, 0xF, 0xF000 } },
|
||||||
{ D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 },
|
{ D3DFMT_R3G3B2, DXGI_FORMAT_UNKNOWN, { 8, 0xE0, 0x1C, 0x3, 0 } },
|
||||||
{ D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM
|
{ D3DFMT_A8, DXGI_FORMAT_A8_UNORM, { 8, 0, 0, 0, 8 } },
|
||||||
{ D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 },
|
{ D3DFMT_A8R3G3B2, DXGI_FORMAT_UNKNOWN, { 16, 0xE0, 0x1C, 0x3, 0xFF00 } },
|
||||||
{ D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 },
|
{ D3DFMT_X4R4G4B4, DXGI_FORMAT_UNKNOWN, { 16, 0xF00, 0xF0, 0xF, 0 } },
|
||||||
{ D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2
|
{ D3DFMT_A2B10G10R10, DXGI_FORMAT_R10G10B10A2_UNORM, { 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 } },
|
||||||
{ D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ D3DFMT_A8B8G8R8, DXGI_FORMAT_R8G8B8A8_UNORM, { 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 } },
|
||||||
{ D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 },
|
{ D3DFMT_X8B8G8R8, DXGI_FORMAT_UNKNOWN, { 32, 0xFF, 0xFF00, 0xFF0000, 0 } },
|
||||||
{ D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM
|
{ D3DFMT_G16R16, DXGI_FORMAT_R16G16_UNORM, { 32, 0xFFFF, 0xFFFF0000, 0, 0 } },
|
||||||
{ D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 },
|
{ D3DFMT_A2R10G10B10, DXGI_FORMAT_UNKNOWN, { 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 } },
|
||||||
{ D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 },
|
{ D3DFMT_A2B10G10R10, DXGI_FORMAT_UNKNOWN, { 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 } },
|
||||||
|
|
||||||
{ D3DFMT_L8, 8, 0xFF, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM
|
{ D3DFMT_L8, DXGI_FORMAT_R8_UNORM , { 8, 0xFF, 0, 0, 0 } },
|
||||||
{ D3DFMT_L16, 16, 0xFFFF, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM
|
{ D3DFMT_L16, DXGI_FORMAT_R16_UNORM, { 16, 0xFFFF, 0, 0, 0 } },
|
||||||
{ D3DFMT_A8L8, 16, 0xFF, 0, 0, 0xFF00 }, // DXGI_FORMAT_R8G8_UNORM?
|
{ D3DFMT_A8L8, DXGI_FORMAT_R8G8_UNORM, { 16, 0xFF, 0, 0, 0xFF00 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint s_d3d9FormatCount = NV_ARRAY_SIZE(s_d3d9Formats);
|
static const uint s_formatCount = NV_ARRAY_SIZE(s_formats);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
uint nv::findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
uint nv::findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < s_d3d9FormatCount; i++)
|
for (int i = 0; i < s_formatCount; i++)
|
||||||
{
|
{
|
||||||
if (s_d3d9Formats[i].bitcount == bitcount &&
|
if (s_formats[i].pixelFormat.bitcount == bitcount &&
|
||||||
s_d3d9Formats[i].rmask == rmask &&
|
s_formats[i].pixelFormat.rmask == rmask &&
|
||||||
s_d3d9Formats[i].gmask == gmask &&
|
s_formats[i].pixelFormat.gmask == gmask &&
|
||||||
s_d3d9Formats[i].bmask == bmask &&
|
s_formats[i].pixelFormat.bmask == bmask &&
|
||||||
s_d3d9Formats[i].amask == amask)
|
s_formats[i].pixelFormat.amask == amask)
|
||||||
{
|
{
|
||||||
return s_d3d9Formats[i].format;
|
return s_formats[i].d3d9Format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint nv::findDXGIFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < s_formatCount; i++)
|
||||||
|
{
|
||||||
|
if (s_formats[i].pixelFormat.bitcount == bitcount &&
|
||||||
|
s_formats[i].pixelFormat.rmask == rmask &&
|
||||||
|
s_formats[i].pixelFormat.gmask == gmask &&
|
||||||
|
s_formats[i].pixelFormat.bmask == bmask &&
|
||||||
|
s_formats[i].pixelFormat.amask == amask)
|
||||||
|
{
|
||||||
|
return s_formats[i].dxgiFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DXGI_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RGBAPixelFormat *nv::findDXGIPixelFormat(uint dxgiFormat)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < s_formatCount; i++)
|
||||||
|
{
|
||||||
|
if (s_formats[i].dxgiFormat == dxgiFormat) {
|
||||||
|
return &s_formats[i].pixelFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DDSHeader::DDSHeader()
|
DDSHeader::DDSHeader()
|
||||||
{
|
{
|
||||||
@ -964,8 +989,9 @@ bool DirectDrawSurface::isSupported() const
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return false;
|
return findDXGIPixelFormat(header.header10.dxgiFormat) != NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1072,6 +1098,13 @@ uint DirectDrawSurface::depth() const
|
|||||||
else return 1;
|
else return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint DirectDrawSurface::arraySize() const
|
||||||
|
{
|
||||||
|
nvDebugCheck(isValid());
|
||||||
|
if (header.hasDX10Header()) return header.header10.arraySize;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool DirectDrawSurface::isTexture1D() const
|
bool DirectDrawSurface::isTexture1D() const
|
||||||
{
|
{
|
||||||
nvDebugCheck(isValid());
|
nvDebugCheck(isValid());
|
||||||
@ -1087,7 +1120,7 @@ bool DirectDrawSurface::isTexture2D() const
|
|||||||
nvDebugCheck(isValid());
|
nvDebugCheck(isValid());
|
||||||
if (header.hasDX10Header())
|
if (header.hasDX10Header())
|
||||||
{
|
{
|
||||||
return header.header10.resourceDimension == DDS_DIMENSION_TEXTURE2D;
|
return header.header10.resourceDimension == DDS_DIMENSION_TEXTURE2D && header.header10.arraySize == 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1114,6 +1147,12 @@ bool DirectDrawSurface::isTextureCube() const
|
|||||||
return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
|
return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DirectDrawSurface::isTextureArray() const
|
||||||
|
{
|
||||||
|
nvDebugCheck(isValid());
|
||||||
|
return header.hasDX10Header() && header.header10.arraySize > 1;
|
||||||
|
}
|
||||||
|
|
||||||
void DirectDrawSurface::setNormalFlag(bool b)
|
void DirectDrawSurface::setNormalFlag(bool b)
|
||||||
{
|
{
|
||||||
nvDebugCheck(isValid());
|
nvDebugCheck(isValid());
|
||||||
@ -1163,14 +1202,18 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
|
|||||||
|
|
||||||
if (header.hasDX10Header())
|
if (header.hasDX10Header())
|
||||||
{
|
{
|
||||||
// So far only block formats supported.
|
if (const RGBAPixelFormat *format = findDXGIPixelFormat(header.header10.dxgiFormat)) {
|
||||||
readBlockImage(img);
|
readLinearImage(img, format->bitcount, format->rmask, format->gmask, format->bmask, format->amask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
readBlockImage(img);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (header.pf.flags & DDPF_RGB)
|
if (header.pf.flags & DDPF_RGB)
|
||||||
{
|
{
|
||||||
readLinearImage(img);
|
readLinearImage(img, header.pf.bitcount, header.pf.rmask, header.pf.gmask, header.pf.bmask, header.pf.amask);
|
||||||
}
|
}
|
||||||
else if (header.pf.flags & DDPF_FOURCC)
|
else if (header.pf.flags & DDPF_FOURCC)
|
||||||
{
|
{
|
||||||
@ -1248,7 +1291,7 @@ bool DirectDrawSurface::readSurface(uint face, uint mipmap, void * data, uint si
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DirectDrawSurface::readLinearImage(Image * img)
|
void DirectDrawSurface::readLinearImage(Image * img, uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||||
{
|
{
|
||||||
nvDebugCheck(stream != NULL);
|
nvDebugCheck(stream != NULL);
|
||||||
nvDebugCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
@ -1258,18 +1301,18 @@ void DirectDrawSurface::readLinearImage(Image * img)
|
|||||||
const uint d = img->depth();
|
const uint d = img->depth();
|
||||||
|
|
||||||
uint rshift, rsize;
|
uint rshift, rsize;
|
||||||
PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
|
PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
|
||||||
|
|
||||||
uint gshift, gsize;
|
uint gshift, gsize;
|
||||||
PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
|
PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
|
||||||
|
|
||||||
uint bshift, bsize;
|
uint bshift, bsize;
|
||||||
PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
|
PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
|
||||||
|
|
||||||
uint ashift, asize;
|
uint ashift, asize;
|
||||||
PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize);
|
PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
|
||||||
|
|
||||||
uint byteCount = (header.pf.bitcount + 7) / 8;
|
uint byteCount = (bitcount + 7) / 8;
|
||||||
|
|
||||||
#pragma NV_MESSAGE("TODO: Support floating point linear images and other FOURCC codes.")
|
#pragma NV_MESSAGE("TODO: Support floating point linear images and other FOURCC codes.")
|
||||||
|
|
||||||
@ -1284,10 +1327,10 @@ void DirectDrawSurface::readLinearImage(Image * img)
|
|||||||
stream->serialize(&c, byteCount);
|
stream->serialize(&c, byteCount);
|
||||||
|
|
||||||
Color32 pixel(0, 0, 0, 0xFF);
|
Color32 pixel(0, 0, 0, 0xFF);
|
||||||
pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
|
pixel.r = PixelFormat::convert((c & rmask) >> rshift, rsize, 8);
|
||||||
pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
|
pixel.g = PixelFormat::convert((c & gmask) >> gshift, gsize, 8);
|
||||||
pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
|
pixel.b = PixelFormat::convert((c & bmask) >> bshift, bsize, 8);
|
||||||
pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
|
pixel.a = PixelFormat::convert((c & amask) >> ashift, asize, 8);
|
||||||
|
|
||||||
img->pixel(x, y, z) = pixel;
|
img->pixel(x, y, z) = pixel;
|
||||||
}
|
}
|
||||||
|
@ -263,10 +263,21 @@ namespace nv
|
|||||||
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
|
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
|
extern uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
|
||||||
|
|
||||||
|
extern uint findDXGIFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
|
||||||
|
|
||||||
|
struct RGBAPixelFormat
|
||||||
|
{
|
||||||
|
uint bitcount;
|
||||||
|
uint rmask;
|
||||||
|
uint gmask;
|
||||||
|
uint bmask;
|
||||||
|
uint amask;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const RGBAPixelFormat *findDXGIPixelFormat(uint dxgiFormat);
|
||||||
|
|
||||||
struct NVIMAGE_CLASS DDSPixelFormat
|
struct NVIMAGE_CLASS DDSPixelFormat
|
||||||
{
|
{
|
||||||
uint size;
|
uint size;
|
||||||
@ -377,10 +388,12 @@ namespace nv
|
|||||||
uint width() const;
|
uint width() const;
|
||||||
uint height() const;
|
uint height() const;
|
||||||
uint depth() const;
|
uint depth() const;
|
||||||
|
uint arraySize() const;
|
||||||
bool isTexture1D() const;
|
bool isTexture1D() const;
|
||||||
bool isTexture2D() const;
|
bool isTexture2D() const;
|
||||||
bool isTexture3D() const;
|
bool isTexture3D() const;
|
||||||
bool isTextureCube() const;
|
bool isTextureCube() const;
|
||||||
|
bool isTextureArray() const;
|
||||||
|
|
||||||
void setNormalFlag(bool b);
|
void setNormalFlag(bool b);
|
||||||
void setHasAlphaFlag(bool b);
|
void setHasAlphaFlag(bool b);
|
||||||
@ -404,7 +417,7 @@ namespace nv
|
|||||||
uint faceSize() const;
|
uint faceSize() const;
|
||||||
uint offset(uint face, uint mipmap);
|
uint offset(uint face, uint mipmap);
|
||||||
|
|
||||||
void readLinearImage(Image * img);
|
void readLinearImage(Image * img, uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
|
||||||
void readBlockImage(Image * img);
|
void readBlockImage(Image * img);
|
||||||
void readBlock(ColorBlock * rgba);
|
void readBlock(ColorBlock * rgba);
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ int Compressor::estimateSize(const InputOptions & inputOptions, const Compressio
|
|||||||
// Surface API.
|
// Surface API.
|
||||||
bool Compressor::outputHeader(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::outputHeader(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.outputHeader(tex.type(), tex.width(), tex.height(), tex.depth(), mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
|
return m.outputHeader(tex.type(), tex.width(), tex.height(), tex.depth(), 1, mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::compress(const Surface & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::compress(const Surface & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
@ -154,7 +154,7 @@ int Compressor::estimateSize(const Surface & tex, int mipmapCount, const Compres
|
|||||||
|
|
||||||
bool Compressor::outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.outputHeader(TextureType_Cube, cube.edgeLength(), cube.edgeLength(), 1, mipmapCount, false, compressionOptions.m, outputOptions.m);
|
return m.outputHeader(TextureType_Cube, cube.edgeLength(), cube.edgeLength(), 1, 1, mipmapCount, false, compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
@ -174,9 +174,9 @@ int Compressor::estimateSize(const CubeSurface & cube, int mipmapCount, const Co
|
|||||||
|
|
||||||
|
|
||||||
// Raw API.
|
// Raw API.
|
||||||
bool Compressor::outputHeader(TextureType type, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::outputHeader(TextureType type, int w, int h, int d, int arraySize, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.outputHeader(type, w, h, d, mipmapCount, isNormalMap, compressionOptions.m, outputOptions.m);
|
return m.outputHeader(type, w, h, d, arraySize, mipmapCount, isNormalMap, compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
@ -231,6 +231,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
|||||||
int width = inputOptions.width;
|
int width = inputOptions.width;
|
||||||
int height = inputOptions.height;
|
int height = inputOptions.height;
|
||||||
int depth = inputOptions.depth;
|
int depth = inputOptions.depth;
|
||||||
|
int arraySize = inputOptions.textureType == TextureType_Array ? faceCount : 1;
|
||||||
|
|
||||||
nv::getTargetExtent(&width, &height, &depth, inputOptions.maxExtent, inputOptions.roundMode, inputOptions.textureType);
|
nv::getTargetExtent(&width, &height, &depth, inputOptions.maxExtent, inputOptions.roundMode, inputOptions.textureType);
|
||||||
|
|
||||||
@ -243,7 +244,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
|||||||
if (inputOptions.maxLevel > 0) mipmapCount = min(mipmapCount, inputOptions.maxLevel);
|
if (inputOptions.maxLevel > 0) mipmapCount = min(mipmapCount, inputOptions.maxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outputHeader(inputOptions.textureType, width, height, depth, mipmapCount, img.isNormalMap(), compressionOptions, outputOptions)) {
|
if (!outputHeader(inputOptions.textureType, width, height, depth, arraySize, mipmapCount, img.isNormalMap(), compressionOptions, outputOptions)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,10 +404,9 @@ void Compressor::Private::quantize(Surface & img, const CompressionOptions::Priv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int h, int d, int arraySize, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||||
bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
|
||||||
{
|
{
|
||||||
if (w <= 0 || h <= 0 || d <= 0 || mipmapCount <= 0)
|
if (w <= 0 || h <= 0 || d <= 0 || arraySize <= 0 || mipmapCount <= 0)
|
||||||
{
|
{
|
||||||
outputOptions.error(Error_InvalidInput);
|
outputOptions.error(Error_InvalidInput);
|
||||||
return false;
|
return false;
|
||||||
@ -425,15 +425,21 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int
|
|||||||
header.setUserVersion(outputOptions.version);
|
header.setUserVersion(outputOptions.version);
|
||||||
|
|
||||||
if (textureType == TextureType_2D) {
|
if (textureType == TextureType_2D) {
|
||||||
|
nvCheck(arraySize == 1);
|
||||||
header.setTexture2D();
|
header.setTexture2D();
|
||||||
}
|
}
|
||||||
else if (textureType == TextureType_Cube) {
|
else if (textureType == TextureType_Cube) {
|
||||||
|
nvCheck(arraySize == 1);
|
||||||
header.setTextureCube();
|
header.setTextureCube();
|
||||||
}
|
}
|
||||||
else if (textureType == TextureType_3D) {
|
else if (textureType == TextureType_3D) {
|
||||||
|
nvCheck(arraySize == 1);
|
||||||
header.setTexture3D();
|
header.setTexture3D();
|
||||||
header.setDepth(d);
|
header.setDepth(d);
|
||||||
}
|
}
|
||||||
|
else if (textureType == TextureType_Array) {
|
||||||
|
header.setTextureArray(arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
header.setWidth(w);
|
header.setWidth(w);
|
||||||
header.setHeight(h);
|
header.setHeight(h);
|
||||||
@ -459,25 +465,22 @@ bool Compressor::Private::outputHeader(nvtt::TextureType textureType, int w, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (bitcount == 16) {
|
if (bitcount == 16 && compressionOptions.rsize == 16) {
|
||||||
if (compressionOptions.rsize == 16) {
|
header.setDX10Format(DXGI_FORMAT_R16_UNORM);
|
||||||
header.setDX10Format(DXGI_FORMAT_R16_UNORM);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// B5G6R5_UNORM
|
|
||||||
// B5G5R5A1_UNORM
|
|
||||||
supported = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bitcount == 32) {
|
|
||||||
// B8G8R8A8_UNORM
|
|
||||||
// B8G8R8X8_UNORM
|
|
||||||
// R8G8B8A8_UNORM
|
|
||||||
// R10G10B10A2_UNORM
|
|
||||||
supported = false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
supported = false;
|
uint format = findDXGIFormat(compressionOptions.bitcount,
|
||||||
|
compressionOptions.rmask,
|
||||||
|
compressionOptions.gmask,
|
||||||
|
compressionOptions.bmask,
|
||||||
|
compressionOptions.amask);
|
||||||
|
|
||||||
|
if (format != DXGI_FORMAT_UNKNOWN) {
|
||||||
|
header.setDX10Format(format);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
supported = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ namespace nvtt
|
|||||||
|
|
||||||
void quantize(Surface & tex, const CompressionOptions::Private & compressionOptions) const;
|
void quantize(Surface & tex, const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
|
||||||
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int faceCount, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
||||||
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
@ -124,17 +124,19 @@ void InputOptions::reset()
|
|||||||
|
|
||||||
|
|
||||||
// Setup the input image.
|
// Setup the input image.
|
||||||
void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth /*= 1*/)
|
void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth /*= 1*/, int arraySize /*= 1*/)
|
||||||
{
|
{
|
||||||
// Validate arguments.
|
// Validate arguments.
|
||||||
nvCheck(width >= 0);
|
nvCheck(width >= 0);
|
||||||
nvCheck(height >= 0);
|
nvCheck(height >= 0);
|
||||||
nvCheck(depth >= 0);
|
nvCheck(depth >= 0);
|
||||||
|
nvCheck(arraySize >= 0);
|
||||||
|
|
||||||
// Correct arguments.
|
// Correct arguments.
|
||||||
if (width == 0) width = 1;
|
if (width == 0) width = 1;
|
||||||
if (height == 0) height = 1;
|
if (height == 0) height = 1;
|
||||||
if (depth == 0) depth = 1;
|
if (depth == 0) depth = 1;
|
||||||
|
if (arraySize == 0) arraySize = 1;
|
||||||
|
|
||||||
// Delete previous images.
|
// Delete previous images.
|
||||||
resetTextureLayout();
|
resetTextureLayout();
|
||||||
@ -145,7 +147,16 @@ void InputOptions::setTextureLayout(TextureType type, int width, int height, int
|
|||||||
m.depth = depth;
|
m.depth = depth;
|
||||||
|
|
||||||
// Allocate images.
|
// Allocate images.
|
||||||
m.faceCount = (type == TextureType_Cube) ? 6 : 1;
|
if (type == TextureType_Cube) {
|
||||||
|
nvCheck(arraySize == 1);
|
||||||
|
m.faceCount = 6;
|
||||||
|
}
|
||||||
|
else if (type == TextureType_Array) {
|
||||||
|
m.faceCount = arraySize;
|
||||||
|
} else {
|
||||||
|
nvCheck(arraySize == 1);
|
||||||
|
m.faceCount = 1;
|
||||||
|
}
|
||||||
m.mipmapCount = countMipmaps(width, height, depth);
|
m.mipmapCount = countMipmaps(width, height, depth);
|
||||||
m.imageCount = m.mipmapCount * m.faceCount;
|
m.imageCount = m.mipmapCount * m.faceCount;
|
||||||
m.images = new void *[m.imageCount];
|
m.images = new void *[m.imageCount];
|
||||||
|
@ -205,6 +205,7 @@ namespace nvtt
|
|||||||
TextureType_2D,
|
TextureType_2D,
|
||||||
TextureType_Cube,
|
TextureType_Cube,
|
||||||
TextureType_3D,
|
TextureType_3D,
|
||||||
|
TextureType_Array,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Input formats.
|
// Input formats.
|
||||||
@ -266,7 +267,7 @@ namespace nvtt
|
|||||||
NVTT_API void reset();
|
NVTT_API void reset();
|
||||||
|
|
||||||
// Setup input layout.
|
// Setup input layout.
|
||||||
NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1);
|
NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1, int arraySize = 1);
|
||||||
NVTT_API void resetTextureLayout();
|
NVTT_API void resetTextureLayout();
|
||||||
|
|
||||||
// Set mipmap data. Copies the data.
|
// Set mipmap data. Copies the data.
|
||||||
@ -412,7 +413,7 @@ namespace nvtt
|
|||||||
NVTT_API int estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
|
|
||||||
// Raw API. (New in NVTT 2.1)
|
// Raw API. (New in NVTT 2.1)
|
||||||
NVTT_API bool outputHeader(TextureType type, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool outputHeader(TextureType type, int w, int h, int d, int arraySize, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API bool compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool compress(int w, int h, int d, int face, int mipmap, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API int estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,7 @@ int main(int argc, char *argv[])
|
|||||||
float topPower = 64;
|
float topPower = 64;
|
||||||
|
|
||||||
// Output header.
|
// Output header.
|
||||||
context.outputHeader(nvtt::TextureType_Cube, topSize >> firstMipmap, topSize >> firstMipmap, 1, mipmapCount-firstMipmap, false, compressionOptions, outputOptions);
|
context.outputHeader(nvtt::TextureType_Cube, topSize >> firstMipmap, topSize >> firstMipmap, 1, 1, mipmapCount-firstMipmap, false, compressionOptions, outputOptions);
|
||||||
|
|
||||||
nv::Timer timer;
|
nv::Timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
@ -59,13 +59,13 @@ int main(int argc, char *argv[])
|
|||||||
assembleVolume = false;
|
assembleVolume = false;
|
||||||
assembleTextureArray = false;
|
assembleTextureArray = false;
|
||||||
}
|
}
|
||||||
if (strcmp("-volume", argv[i]) == 0)
|
else if (strcmp("-volume", argv[i]) == 0)
|
||||||
{
|
{
|
||||||
assembleCubeMap = false;
|
assembleCubeMap = false;
|
||||||
assembleVolume = true;
|
assembleVolume = true;
|
||||||
assembleTextureArray = false;
|
assembleTextureArray = false;
|
||||||
}
|
}
|
||||||
if (strcmp("-array", argv[i]) == 0)
|
else if (strcmp("-array", argv[i]) == 0)
|
||||||
{
|
{
|
||||||
assembleCubeMap = false;
|
assembleCubeMap = false;
|
||||||
assembleVolume = false;
|
assembleVolume = false;
|
||||||
|
@ -487,11 +487,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
nvDebugBreak();
|
nvDebugBreak();
|
||||||
}
|
}
|
||||||
else
|
else if (dds.isTextureCube()) {
|
||||||
{
|
|
||||||
nvDebugCheck(dds.isTextureCube());
|
|
||||||
inputOptions.setTextureLayout(nvtt::TextureType_Cube, dds.width(), dds.height());
|
inputOptions.setTextureLayout(nvtt::TextureType_Cube, dds.width(), dds.height());
|
||||||
faceCount = 6;
|
faceCount = 6;
|
||||||
|
} else {
|
||||||
|
nvDebugCheck(dds.isTextureArray());
|
||||||
|
inputOptions.setTextureLayout(nvtt::TextureType_Array, dds.width(), dds.height(), 1, dds.arraySize());
|
||||||
|
faceCount = dds.arraySize();
|
||||||
|
dds10 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint mipmapCount = dds.mipmapCount();
|
uint mipmapCount = dds.mipmapCount();
|
||||||
|
Loading…
Reference in New Issue
Block a user