Fixed BC7 encoder.

This commit is contained in:
Branimir Karadžić
2017-11-01 18:06:08 -07:00
parent 5baa2c36b8
commit 83093ef102
3 changed files with 63 additions and 48 deletions

View File

@@ -22,7 +22,7 @@ namespace nvtt
{
using namespace nv;
void compressBC6H(const void* _input, uint32_t _width, uint32_t _height, uint32_t _stride, void* _output)
void compressBC6H(const void* _input, uint32_t _width, uint32_t _height, uint32_t _srcStride, void* _output)
{
const uint8_t* src = (const uint8_t*)_input;
char* dst = (char*)_output;
@@ -31,35 +31,35 @@ namespace nvtt
{
for (uint32_t xx = 0; xx < _width; xx += 4)
{
const Vector4* rgba = (const Vector4*)&src[yy*_stride + xx*sizeof(float)*4];
const uint32_t bytesPerPixel = sizeof(float)*4;
const Vector4* srcRgba = (const Vector4*)&src[yy*_srcStride + xx*bytesPerPixel];
const uint32_t srcRgbaStride = _srcStride/bytesPerPixel;
ZOH::Utils::FORMAT = ZOH::UNSIGNED_F16;
ZOH::Utils::FORMAT = ZOH::SIGNED_F16;
ZOH::Tile zohTile(4, 4);
memset(zohTile.data, 0, sizeof(zohTile.data) );
memset(zohTile.importance_map, 0, sizeof(zohTile.importance_map) );
bx::memSet(zohTile.data, 0, sizeof(zohTile.data) );
bx::memSet(zohTile.importance_map, 0, sizeof(zohTile.importance_map) );
for (uint32_t blockY = 0; blockY < 4; ++blockY)
{
for (uint32_t blockX = 0; blockX < 4; ++blockX)
{
Vector4 color = rgba[blockY*4 + blockX];
uint16 rHalf = bx::halfFromFloat(color.x);
uint16 gHalf = bx::halfFromFloat(color.y);
uint16 bHalf = bx::halfFromFloat(color.z);
zohTile.data[blockY][blockX].x = ZOH::Tile::half2float(rHalf);
zohTile.data[blockY][blockX].y = ZOH::Tile::half2float(gHalf);
zohTile.data[blockY][blockX].z = ZOH::Tile::half2float(bHalf);
zohTile.importance_map[blockY][blockX] = 1.0f;
Vector4 color = srcRgba[blockY*srcRgbaStride + blockX];
zohTile.data[blockY][blockX].x = color.x;
zohTile.data[blockY][blockX].y = color.y;
zohTile.data[blockY][blockX].z = color.z;
}
}
ZOH::compress(zohTile, &dst[( (yy*_width) + xx)/4 * 16]);
zohTile.generate_importance_map();
ZOH::compress(zohTile, dst);
dst += ZOH::BLOCKSIZE;
}
}
}
void compressBC7(const void* _input, uint32_t _width, uint32_t _height, uint32_t _stride, void* _output)
void compressBC7(const void* _input, uint32_t _width, uint32_t _height, uint32_t _srcStride, void* _output)
{
const uint8_t* src = (const uint8_t*)_input;
char* dst = (char*)_output;
@@ -68,7 +68,9 @@ namespace nvtt
{
for (uint32_t xx = 0; xx < _width; xx += 4)
{
const Vector4* rgba = (const Vector4*)&src[yy*_stride + xx*sizeof(float)*4];
const uint32_t bytesPerPixel = sizeof(float) * 4;
const Vector4* srcRgba = (const Vector4*)&src[yy*_srcStride + xx*bytesPerPixel];
const uint32_t srcRgbaStride = _srcStride / bytesPerPixel;
AVPCL::mode_rgb = false;
AVPCL::flag_premult = false;
@@ -76,18 +78,19 @@ namespace nvtt
AVPCL::flag_nonuniform_ati = false;
AVPCL::Tile avpclTile(4, 4);
memset(avpclTile.data, 0, sizeof(avpclTile.data) );
bx::memSet(avpclTile.data, 0, sizeof(avpclTile.data) );
for (uint32_t blockY = 0; blockY < 4; ++blockY)
{
for (uint32_t blockX = 0; blockX < 4; ++blockX)
{
Vector4 color = rgba[blockY*4 + blockX];
Vector4 color = srcRgba[blockY*srcRgbaStride + blockX];
avpclTile.data[blockY][blockX] = color * 255.0f;
avpclTile.importance_map[blockY][blockX] = 1.0f;
}
}
AVPCL::compress(avpclTile, &dst[( (yy*_width) + xx)/4 * 16]);
AVPCL::compress(avpclTile, dst);
dst += AVPCL::BLOCKSIZE;
}
}
}

View File

@@ -66,11 +66,8 @@ namespace bimg
break;
case TextureFormat::BC6H:
nvtt::compressBC6H(src, _width, _height, 4, dst);
break;
case TextureFormat::BC7:
nvtt::compressBC7(src, _width, _height, 4, dst);
BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
break;
case TextureFormat::ETC1:
@@ -149,40 +146,53 @@ namespace bimg
const uint8_t* src = (const uint8_t*)_src;
if (!imageConvert(_dst, _dstFormat, _src, TextureFormat::RGBA32F, _width, _height, _depth) )
switch (_dstFormat)
{
uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*4);
if (imageConvert(temp, TextureFormat::RGBA8, _src, TextureFormat::RGBA32F, _width, _height, _depth) )
case TextureFormat::BC6H:
nvtt::compressBC6H(src, _width, _height, _width*16, _dst);
break;
case TextureFormat::BC7:
nvtt::compressBC7(src, _width, _height, _width*16, _dst);
break;
default:
if (!imageConvert(_dst, _dstFormat, _src, TextureFormat::RGBA32F, _width, _height, _depth) )
{
for (uint32_t zz = 0; zz < _depth; ++zz)
uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*4);
if (imageConvert(temp, TextureFormat::RGBA8, _src, TextureFormat::RGBA32F, _width, _height, _depth) )
{
const uint32_t zoffset = zz*_width*_height;
for (uint32_t yy = 0; yy < _height; ++yy)
for (uint32_t zz = 0; zz < _depth; ++zz)
{
const uint32_t yoffset = zoffset + yy*_width;
const uint32_t zoffset = zz*_width*_height;
for (uint32_t xx = 0; xx < _width; ++xx)
for (uint32_t yy = 0; yy < _height; ++yy)
{
const uint32_t offset = yoffset + xx;
const float* input = (const float*)&src[offset * 16];
uint8_t* output = &temp[offset * 4];
output[0] = uint8_t(bx::fsaturate(input[0])*255.0f + 0.5f);
output[1] = uint8_t(bx::fsaturate(input[1])*255.0f + 0.5f);
output[2] = uint8_t(bx::fsaturate(input[2])*255.0f + 0.5f);
output[3] = uint8_t(bx::fsaturate(input[3])*255.0f + 0.5f);
const uint32_t yoffset = zoffset + yy*_width;
for (uint32_t xx = 0; xx < _width; ++xx)
{
const uint32_t offset = yoffset + xx;
const float* input = (const float*)&src[offset * 16];
uint8_t* output = &temp[offset * 4];
output[0] = uint8_t(bx::fsaturate(input[0])*255.0f + 0.5f);
output[1] = uint8_t(bx::fsaturate(input[1])*255.0f + 0.5f);
output[2] = uint8_t(bx::fsaturate(input[2])*255.0f + 0.5f);
output[3] = uint8_t(bx::fsaturate(input[3])*255.0f + 0.5f);
}
}
}
imageEncodeFromRgba8(_dst, temp, _width, _height, _depth, _dstFormat, _quality, _err);
}
else
{
BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
}
imageEncodeFromRgba8(_dst, temp, _width, _height, _depth, _dstFormat, _quality, _err);
BX_FREE(_allocator, temp);
}
else
{
BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
}
BX_FREE(_allocator, temp);
break;
}
}

View File

@@ -315,8 +315,10 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
BX_FREE(_allocator, rgbaDst);
}
else if (!bimg::isCompressed(input->m_format)
&& 8 != inputBlockInfo.rBits)
else if ( (!bimg::isCompressed(input->m_format) && 8 != inputBlockInfo.rBits)
|| outputFormat == bimg::TextureFormat::BC6H
|| outputFormat == bimg::TextureFormat::BC7
)
{
uint32_t size = bimg::imageGetSize(
NULL