Merge changes from the witness.

Fix parallel cluster fit compressor.
Luma compression experiment.
pull/216/head
castano 12 years ago
parent b130487c2a
commit fa4ba97f6d

@ -111,8 +111,8 @@ void FastCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alpha
QuickCompress::compressDXT5(rgba, block);
}
#if 0
void NormalCompressorDXT1::compressBlock(ColorSet & set, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
#if 1
void CompressorDXT1::compressBlock(ColorSet & set, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
set.setUniformWeights();
set.createMinimalSet(false);
@ -146,7 +146,7 @@ void NormalCompressorDXT1::compressBlock(ColorSet & set, nvtt::AlphaMode alphaMo
}
}
#else
void NormalCompressorDXT1::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
void CompressorDXT1::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);
@ -165,7 +165,7 @@ void NormalCompressorDXT1::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
}
#endif
void NormalCompressorDXT1a::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
void CompressorDXT1a::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
uint alphaMask = 0;
for (uint i = 0; i < 16; i++)
@ -185,18 +185,24 @@ void NormalCompressorDXT1a::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alp
nvsquish::WeightedClusterFit fit;
fit.SetMetric(compressionOptions.colorWeight.x, compressionOptions.colorWeight.y, compressionOptions.colorWeight.z);
int flags = nvsquish::kDxt1;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
int flags = nvsquish::kDxt1;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
fit.SetColourSet(&colours, nvsquish::kDxt1);
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
fit.SetColourSet(&colours, nvsquish::kDxt1);
fit.Compress(output);
}
}
void CompressorDXT1_Luma::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
BlockDXT1 * block = new(output) BlockDXT1;
OptimalCompress::compressDXT1_Luma(rgba, block);
}
void NormalCompressorDXT3::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
void CompressorDXT3::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
BlockDXT3 * block = new(output) BlockDXT3;
@ -223,7 +229,7 @@ void NormalCompressorDXT3::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
}
void NormalCompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
void CompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
BlockDXT5 * block = new(output) BlockDXT5;
@ -247,17 +253,17 @@ void NormalCompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
nvsquish::WeightedClusterFit fit;
fit.SetMetric(compressionOptions.colorWeight.x, compressionOptions.colorWeight.y, compressionOptions.colorWeight.z);
int flags = 0;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
int flags = 0;
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
fit.SetColourSet(&colours, 0);
fit.Compress(&block->color);
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
fit.SetColourSet(&colours, 0);
fit.Compress(&block->color);
}
}
void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
void CompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
{
BlockDXT5 * block = new(output) BlockDXT5;

@ -64,39 +64,45 @@ namespace nv
// Normal CPU compressors.
#if 0
struct NormalCompressorDXT1 : public ColorSetCompressor
#if 1
struct CompressorDXT1 : public ColorSetCompressor
{
virtual void compressBlock(ColorSet & set, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; }
};
#else
struct NormalCompressorDXT1 : public FixedBlockCompressor
struct CompressorDXT1 : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; }
};
#endif
struct NormalCompressorDXT1a : public FixedBlockCompressor
struct CompressorDXT1a : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; }
};
struct NormalCompressorDXT3 : public FixedBlockCompressor
struct CompressorDXT1_Luma : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; }
};
struct CompressorDXT3 : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; }
};
struct NormalCompressorDXT5 : public FixedBlockCompressor
struct CompressorDXT5 : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; }
};
struct NormalCompressorDXT5n : public FixedBlockCompressor
struct CompressorDXT5n : public FixedBlockCompressor
{
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; }

@ -201,7 +201,7 @@ void ColorSetCompressorTask(void * data, int i)
//for (uint x = 0; x < d->bw; x++)
{
ColorSet set;
set.setColors(d->data, d->w, d->h, x, y);
set.setColors(d->data, d->w, d->h, x * 4, y * 4);
uint8 * ptr = d->mem + (y * d->bw + x) * d->bs;
d->compressor->compressBlock(set, d->alphaMode, *d->compressionOptions, ptr);

@ -690,7 +690,7 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression
return new FastCompressorDXT1;
}
return new NormalCompressorDXT1;
return new CompressorDXT1;
}
else if (compressionOptions.format == Format_DXT1a)
{
@ -699,7 +699,7 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression
return new FastCompressorDXT1a;
}
return new NormalCompressorDXT1a;
return new CompressorDXT1a;
}
else if (compressionOptions.format == Format_DXT1n)
{
@ -712,7 +712,7 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression
return new FastCompressorDXT3;
}
return new NormalCompressorDXT3;
return new CompressorDXT3;
}
else if (compressionOptions.format == Format_DXT5)
{
@ -726,7 +726,7 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression
return new FastCompressorDXT5;
}
return new NormalCompressorDXT5;
return new CompressorDXT5;
}
else if (compressionOptions.format == Format_DXT5n)
{
@ -735,7 +735,7 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression
return new FastCompressorDXT5n;
}
return new NormalCompressorDXT5n;
return new CompressorDXT5n;
}
else if (compressionOptions.format == Format_BC4)
{

@ -28,11 +28,9 @@
#include "nvmath/Vector.inl"
#include "nvcore/Array.h"
#include "nvcore/Array.inl"
#include "nvcore/StrLib.h"
#include <float.h> // FLT_MAX
using namespace nv;
using namespace nvtt;
@ -304,7 +302,7 @@ const Surface & CubeSurface::face(int f) const
bool CubeSurface::load(const char * fileName, int mipmap)
{
if (strcmp(Path::extension(fileName), ".dds") == 0) {
if (strEqual(Path::extension(fileName), ".dds")) {
nv::DirectDrawSurface dds(fileName);
if (!dds.isValid()/* || !dds.isSupported()*/) {
@ -412,7 +410,7 @@ void CubeSurface::range(int channel, float * minimum_ptr, float * maximum_ptr) c
const uint edgeLength = m->edgeLength;
m->allocateTexelTable();
float minimum = FLT_MAX;
float minimum = NV_FLOAT_MAX;
float maximum = 0.0f;
for (int f = 0; f < 6; f++) {

@ -379,6 +379,108 @@ void OptimalCompress::compressDXT1G(const ColorBlock & rgba, BlockDXT1 * block)
block->indices = computeGreenIndices(rgba, palette);
}
/*void OptimalCompress::initLumaTables() {
// For all possible color pairs:
for (int c0 = 0; c0 < 65536; c0++) {
for (int c1 = 0; c1 < 65536; c1++) {
// Compute
}
}
for (int r = 0; r < 1<<5; r++) {
for (int g = 0; g < 1<<6; g++) {
for (int b = 0; b < 1<<5; b++) {
}
}
}
}*/
// Brute force Luma compressor
void OptimalCompress::compressDXT1_Luma(const ColorBlock & rgba, BlockDXT1 * block)
{
nvDebugCheck(block != NULL);
// F_YR = 19595/65536.0f, F_YG = 38470/65536.0f, F_YB = 7471/65536.0f;
// 195841
//if (
/*
uint8 ming = 63;
uint8 maxg = 0;
bool isSingleColor = true;
uint8 singleColor = rgba.color(0).g;
// Get min/max green.
for (uint i = 0; i < 16; i++)
{
uint8 green = (rgba.color(i).g + 1) >> 2;
ming = min(ming, green);
maxg = max(maxg, green);
if (rgba.color(i).g != singleColor) isSingleColor = false;
}
if (isSingleColor)
{
compressDXT1G(singleColor, block);
return;
}
block->col0.r = 31;
block->col1.r = 31;
block->col0.g = maxg;
block->col1.g = ming;
block->col0.b = 0;
block->col1.b = 0;
int bestError = computeGreenError(rgba, block);
int bestg0 = maxg;
int bestg1 = ming;
// Expand search space a bit.
const int greenExpand = 4;
ming = (ming <= greenExpand) ? 0 : ming - greenExpand;
maxg = (maxg >= 63-greenExpand) ? 63 : maxg + greenExpand;
for (int g0 = ming+1; g0 <= maxg; g0++)
{
for (int g1 = ming; g1 < g0; g1++)
{
block->col0.g = g0;
block->col1.g = g1;
int error = computeGreenError(rgba, block, bestError);
if (error < bestError)
{
bestError = error;
bestg0 = g0;
bestg1 = g1;
}
}
}
block->col0.g = bestg0;
block->col1.g = bestg1;
nvDebugCheck(bestg0 == bestg1 || block->isFourColorMode());
*/
Color32 palette[4];
block->evaluatePalette(palette, false); // @@ Use target decoder.
block->indices = computeGreenIndices(rgba, palette);
}
void OptimalCompress::compressDXT3A(const ColorBlock & rgba, AlphaBlockDXT3 * dxtBlock)
{
dxtBlock->alpha0 = quantize4(rgba.color(0).a);

@ -47,6 +47,9 @@ namespace nv
void compressDXT1G(const ColorBlock & rgba, BlockDXT1 * block);
void compressDXT3A(const ColorBlock & rgba, AlphaBlockDXT3 * dxtBlock);
void compressDXT5A(const ColorBlock & rgba, AlphaBlockDXT5 * dxtBlock);
void compressDXT1_Luma(const ColorBlock & rgba, BlockDXT1 * block);
}
} // nv namespace

@ -38,6 +38,7 @@
#include "nvimage/ErrorMetric.h"
#include <float.h>
#include <string.h> // memset, memcpy
using namespace nv;
using namespace nvtt;
@ -451,8 +452,8 @@ static int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
#define CATCH __except (filter(GetExceptionCode(), GetExceptionInformation()))
#else
#define TRY
#define CATCH
#define TRY if (true)
#define CATCH else
#endif
@ -2421,6 +2422,37 @@ void Surface::flipZ()
m->image->flipZ();
}
Surface Surface::subImage(int x0, int x1, int y0, int y1, int z0, int z1) const
{
Surface s;
if (isNull()) return s;
if (x0 < 0 || x1 > width() || x0 > x1) return s;
if (y0 < 0 || y1 > height() || y0 > y1) return s;
if (z0 < 0 || z1 > depth() || z0 > z1) return s;
if (x1 >= width() || y1 >= height() || z1 >= depth()) return s;
FloatImage * img = s.m->image = new FloatImage;
int w = x1 - x0 + 1;
int h = y1 - y0 + 1;
int d = z1 - z0 + 1;
img->allocate(4, w, h, d);
for (int c = 0; c < 4; c++) {
for (int z = 0; z < d; z++) {
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
img->pixel(c, x, y, z) = m->image->pixel(c, x0+x, y0+y, z0+z);
}
}
}
}
return s;
}
bool Surface::copyChannel(const Surface & srcImage, int srcChannel)
{
return copyChannel(srcImage, srcChannel, srcChannel);

@ -103,6 +103,8 @@ namespace nvtt
Format_BC6, // Not supported yet.
Format_BC7, // Not supported yet.
Format_DXT1_Luma,
};
// 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.
@ -532,6 +534,7 @@ namespace nvtt
NVTT_API void flipX();
NVTT_API void flipY();
NVTT_API void flipZ();
NVTT_API Surface subImage(int x0, int x1, int y0, int y1, int z0, int z1) const;
// Copy image data.
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel);

@ -21,16 +21,17 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#include <nvcore/StrLib.h>
#include <nvcore/StdStream.h>
#include "cmdline.h"
#include <nvmath/Color.h>
#include "nvimage/Image.h"
#include "nvimage/ImageIO.h"
#include "nvimage/DirectDrawSurface.h"
#include <nvimage/Image.h>
#include <nvimage/ImageIO.h>
#include <nvimage/DirectDrawSurface.h>
#include "nvmath/Color.h"
#include "cmdline.h"
#include "nvcore/Array.inl"
#include "nvcore/StrLib.h"
#include "nvcore/StdStream.h"
// @@ Add decent error messages.
// @@ Add option to resize images.

@ -92,6 +92,7 @@ struct Error
{
printf(" Mean absolute error: %f\n", mabse);
printf(" Max absolute error: %f\n", maxabse);
printf(" Mean squared error: %f\n", mse);
printf(" Root mean squared error: %f\n", rmse);
printf(" Peak signal to noise ratio in dB: %f\n", psnr);
}
@ -153,6 +154,13 @@ struct NormalError
float psnr;
};
static float luma(const nv::Color32 & c) {
return 0.299f * float(c.r) + 0.587f * float(c.g) + 0.114f * float(c.b);
//return 0.25f * float(c.r) + 0.5f * float(c.g) + 0.25f * float(c.b);
//return 0.333f * float(c.r) + 0.334f * float(c.g) + 0.333f * float(c.b);
//return 0.1f * float(c.r) + 0.8f * float(c.g) + 0.1f * float(c.g);
}
int main(int argc, char *argv[])
{
@ -220,6 +228,7 @@ int main(int argc, char *argv[])
Error error_g;
Error error_b;
Error error_a;
Error error_luma;
Error error_total;
NormalError error_normal;
@ -234,15 +243,16 @@ int main(int argc, char *argv[])
double g = float(c0.g - c1.g);
double b = float(c0.b - c1.b);
double a = float(c0.a - c1.a);
error_r.addSample(r);
error_g.addSample(g);
error_b.addSample(b);
error_a.addSample(a);
if (compareNormal) {
error_normal.addSample(c0, c1);
}
double l0 = luma(c0);
double l1 = luma(c1);
error_luma.addSample(l0 - l1);
double d = sqrt(r*r + g*g + b*b);
@ -251,6 +261,10 @@ int main(int argc, char *argv[])
}
error_total.addSample(d);
if (compareNormal) {
error_normal.addSample(c0, c1);
}
}
}
@ -258,6 +272,7 @@ int main(int argc, char *argv[])
error_g.done();
error_b.done();
error_a.done();
error_luma.done();
error_total.done();
error_normal.done();
@ -271,6 +286,9 @@ int main(int argc, char *argv[])
printf("Color:\n");
error_total.print();
printf("Luma:\n");
error_luma.print();
if (compareNormal)
{
printf("Normal:\n");

Loading…
Cancel
Save