mirror of
https://github.com/bkaradzic/bimg.git
synced 2026-02-17 20:52:38 +01:00
Fixed BC7 encoder.
This commit is contained in:
41
3rdparty/nvtt/nvtt.cpp
vendored
41
3rdparty/nvtt/nvtt.cpp
vendored
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user