فهرست منبع

Fixed BC7 encoder.

Branimir Karadžić 8 سال پیش
والد
کامیت
83093ef102
3فایلهای تغییر یافته به همراه63 افزوده شده و 48 حذف شده
  1. 22 19
      3rdparty/nvtt/nvtt.cpp
  2. 37 27
      src/image_encode.cpp
  3. 4 2
      tools/texturec/texturec.cpp

+ 22 - 19
3rdparty/nvtt/nvtt.cpp

@@ -22,7 +22,7 @@ namespace nvtt
 {
 {
 	using namespace nv;
 	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;
 		const uint8_t* src = (const uint8_t*)_input;
 		char* dst = (char*)_output;
 		char* dst = (char*)_output;
@@ -31,35 +31,35 @@ namespace nvtt
 		{
 		{
 			for (uint32_t xx = 0; xx < _width; xx += 4)
 			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);
 				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 blockY = 0; blockY < 4; ++blockY)
 				{
 				{
 					for (uint32_t blockX = 0; blockX < 4; ++blockX)
 					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;
 		const uint8_t* src = (const uint8_t*)_input;
 		char* dst = (char*)_output;
 		char* dst = (char*)_output;
@@ -68,7 +68,9 @@ namespace nvtt
 		{
 		{
 			for (uint32_t xx = 0; xx < _width; xx += 4)
 			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::mode_rgb     = false;
 				AVPCL::flag_premult = false;
 				AVPCL::flag_premult = false;
@@ -76,18 +78,19 @@ namespace nvtt
 				AVPCL::flag_nonuniform_ati = false;
 				AVPCL::flag_nonuniform_ati = false;
 
 
 				AVPCL::Tile avpclTile(4, 4);
 				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 blockY = 0; blockY < 4; ++blockY)
 				{
 				{
 					for (uint32_t blockX = 0; blockX < 4; ++blockX)
 					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.data[blockY][blockX] = color * 255.0f;
 						avpclTile.importance_map[blockY][blockX] = 1.0f;
 						avpclTile.importance_map[blockY][blockX] = 1.0f;
 					}
 					}
 				}
 				}
 
 
-				AVPCL::compress(avpclTile, &dst[( (yy*_width) + xx)/4 * 16]);
+				AVPCL::compress(avpclTile, dst);
+				dst += AVPCL::BLOCKSIZE;
 			}
 			}
 		}
 		}
 	}
 	}

+ 37 - 27
src/image_encode.cpp

@@ -66,11 +66,8 @@ namespace bimg
 				break;
 				break;
 
 
 			case TextureFormat::BC6H:
 			case TextureFormat::BC6H:
-				nvtt::compressBC6H(src, _width, _height, 4, dst);
-				break;
-
 			case TextureFormat::BC7:
 			case TextureFormat::BC7:
-				nvtt::compressBC7(src, _width, _height, 4, dst);
+				BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
 				break;
 				break;
 
 
 			case TextureFormat::ETC1:
 			case TextureFormat::ETC1:
@@ -149,40 +146,53 @@ namespace bimg
 
 
 		const uint8_t* src = (const uint8_t*)_src;
 		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);
-			}
-			else
-			{
-				BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				BX_FREE(_allocator, temp);
 			}
 			}
-
-			BX_FREE(_allocator, temp);
+			break;
 		}
 		}
 	}
 	}
 
 

+ 4 - 2
tools/texturec/texturec.cpp

@@ -315,8 +315,10 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 
 
 					BX_FREE(_allocator, rgbaDst);
 					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(
 					uint32_t size = bimg::imageGetSize(
 						  NULL
 						  NULL