diff --git a/3rdparty/nvtt/nvtt.cpp b/3rdparty/nvtt/nvtt.cpp index 51a2bce..157afea 100644 --- a/3rdparty/nvtt/nvtt.cpp +++ b/3rdparty/nvtt/nvtt.cpp @@ -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; } } } diff --git a/src/image_encode.cpp b/src/image_encode.cpp index ae1cec4..4f80d66 100644 --- a/src/image_encode.cpp +++ b/src/image_encode.cpp @@ -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; } } diff --git a/tools/texturec/texturec.cpp b/tools/texturec/texturec.cpp index bce1b6d..3ac699c 100644 --- a/tools/texturec/texturec.cpp +++ b/tools/texturec/texturec.cpp @@ -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