Browse Source

Fix some bugs in the image importer

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
84c73e5464
4 changed files with 70 additions and 23 deletions
  1. 1 0
      AnKi/Importer/Common.h
  2. 35 15
      AnKi/Importer/ImageImporter.cpp
  3. 20 5
      AnKi/Util/Logger.cpp
  4. 14 3
      AnKi/Util/Logger.h

+ 1 - 0
AnKi/Importer/Common.h

@@ -12,6 +12,7 @@ namespace anki
 /// @{
 
 #define ANKI_IMPORTER_LOGI(...) ANKI_LOG("IMPR", NORMAL, __VA_ARGS__)
+#define ANKI_IMPORTER_LOGV(...) ANKI_LOG("IMPR", VERBOSE, __VA_ARGS__)
 #define ANKI_IMPORTER_LOGE(...) ANKI_LOG("IMPR", ERROR, __VA_ARGS__)
 #define ANKI_IMPORTER_LOGW(...) ANKI_LOG("IMPR", WARNING, __VA_ARGS__)
 #define ANKI_IMPORTER_LOGF(...) ANKI_LOG("IMPR", FATAL, __VA_ARGS__)

+ 35 - 15
AnKi/Importer/ImageImporter.cpp

@@ -172,6 +172,13 @@ static ANKI_USE_RESULT Error checkConfig(const ImageImporterConfig& config)
 	ANKI_CFG_ASSERT(config.m_compressions == ImageBinaryDataCompression::RAW || config.m_type != ImageBinaryType::_3D,
 					"Can't compress 3D textures");
 
+	// ASTC
+	if(!!(config.m_compressions & ImageBinaryDataCompression::ASTC))
+	{
+		ANKI_CFG_ASSERT(config.m_astcBlockSize == UVec2(4u) || config.m_astcBlockSize == UVec2(8u),
+						"Incorrect ASTC block sizes");
+	}
+
 	// Mip size
 	ANKI_CFG_ASSERT(config.m_minMipmapDimension >= 4, "Mimpap min dimension can be less than 4");
 
@@ -335,15 +342,16 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 	ANKI_ASSERT(inWidth > 0 && isPowerOfTwo(inWidth) && inHeight > 0 && isPowerOfTwo(inHeight));
 	ANKI_ASSERT(outPixels.getSizeInBytes() == PtrSize((channelCount == 3) ? 8 : 16) * (inWidth / 4) * (inHeight / 4));
 
-	// Create a BMP image to feed to the compressor
-	StringAuto bmpFilename(alloc);
-	bmpFilename.sprintf("%s/AnKiImageImporter_%u.bmp", tempDirectory.cstr(), U32(std::rand()));
-	if(!stbi_write_bmp(bmpFilename.cstr(), inWidth, inHeight, channelCount, inPixels.getBegin()))
+	// Create a PNG image to feed to the compressor
+	StringAuto pngFilename(alloc);
+	pngFilename.sprintf("%s/AnKiImageImporter_%u.png", tempDirectory.cstr(), U32(std::rand()));
+	ANKI_IMPORTER_LOGV("Will store: %s", pngFilename.cstr());
+	if(!stbi_write_png(pngFilename.cstr(), inWidth, inHeight, channelCount, inPixels.getBegin(), 0))
 	{
-		ANKI_IMPORTER_LOGE("STB failed to create: %s", bmpFilename.cstr());
+		ANKI_IMPORTER_LOGE("STB failed to create: %s", pngFilename.cstr());
 		return Error::FUNCTION_FAILED;
 	}
-	CleanupFile bmpCleanup(alloc, bmpFilename);
+	CleanupFile pngCleanup(alloc, pngFilename);
 
 	// Invoke the compressor process
 	StringAuto ddsFilename(alloc);
@@ -354,9 +362,11 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 	args[argCount++] = "-nomipmap";
 	args[argCount++] = "-fd";
 	args[argCount++] = (channelCount == 3) ? "BC1" : "BC3";
-	args[argCount++] = bmpFilename;
+	args[argCount++] = pngFilename;
 	args[argCount++] = ddsFilename;
 
+	ANKI_IMPORTER_LOGV("Will invoke process: CompressonatorCLI %s %s %s %s %s", args[0].cstr(), args[1].cstr(),
+					   args[2].cstr(), args[3].cstr(), args[4].cstr());
 	ANKI_CHECK(proc.start("CompressonatorCLI", args,
 						  (compressonatorPath.isEmpty()) ? ConstWeakArray<CString>()
 														 : Array<CString, 2>{{"PATH", compressonatorPath}}));
@@ -422,14 +432,15 @@ static ANKI_USE_RESULT Error compressAstc(GenericMemoryPoolAllocator<U8> alloc,
 	ANKI_ASSERT(outPixels.getSizeInBytes() == blockBytes * (inWidth / blockSize.x()) * (inHeight / blockSize.y()));
 
 	// Create a BMP image to feed to the astcebc
-	StringAuto bmpFilename(alloc);
-	bmpFilename.sprintf("%s/AnKiImageImporter_%u.bmp", tempDirectory.cstr(), U32(std::rand()));
-	if(!stbi_write_bmp(bmpFilename.cstr(), inWidth, inHeight, channelCount, inPixels.getBegin()))
+	StringAuto pngFilename(alloc);
+	pngFilename.sprintf("%s/AnKiImageImporter_%u.png", tempDirectory.cstr(), U32(std::rand()));
+	ANKI_IMPORTER_LOGV("Will store: %s", pngFilename.cstr());
+	if(!stbi_write_png(pngFilename.cstr(), inWidth, inHeight, channelCount, inPixels.getBegin(), 0))
 	{
-		ANKI_IMPORTER_LOGE("STB failed to create: %s", bmpFilename.cstr());
+		ANKI_IMPORTER_LOGE("STB failed to create: %s", pngFilename.cstr());
 		return Error::FUNCTION_FAILED;
 	}
-	CleanupFile bmpCleanup(alloc, bmpFilename);
+	CleanupFile pngCleanup(alloc, pngFilename);
 
 	// Invoke the compressor process
 	StringAuto astcFilename(alloc);
@@ -440,11 +451,13 @@ static ANKI_USE_RESULT Error compressAstc(GenericMemoryPoolAllocator<U8> alloc,
 	Array<CString, 5> args;
 	U32 argCount = 0;
 	args[argCount++] = "-cl";
-	args[argCount++] = bmpFilename;
+	args[argCount++] = pngFilename;
 	args[argCount++] = astcFilename;
 	args[argCount++] = blockStr;
 	args[argCount++] = "-fast";
 
+	ANKI_IMPORTER_LOGV("Will invoke process: astcenc-avx2 %s %s %s %s %s", args[0].cstr(), args[1].cstr(),
+					   args[2].cstr(), args[3].cstr(), args[4].cstr());
 	ANKI_CHECK(
 		proc.start("astcenc-avx2", args,
 				   (astcencPath.isEmpty()) ? ConstWeakArray<CString>() : Array<CString, 2>{{"PATH", astcencPath}}));
@@ -628,10 +641,17 @@ static ANKI_USE_RESULT Error importImageInternal(const ImageImporterConfig& conf
 	ANKI_CHECK(loadFirstMipmap(config, ctx));
 
 	// Generate mipmaps
+	U32 minMipDimension = max(config.m_minMipmapDimension, 4u);
+	if(!!(config.m_compressions & ImageBinaryDataCompression::ASTC))
+	{
+		minMipDimension = max(minMipDimension, config.m_astcBlockSize.x());
+		minMipDimension = max(minMipDimension, config.m_astcBlockSize.y());
+	}
+
 	const U32 mipCount =
 		min(config.m_mipmapCount, (config.m_type == ImageBinaryType::_3D)
-									  ? computeMaxMipmapCount3d(width, height, ctx.m_depth, config.m_minMipmapDimension)
-									  : computeMaxMipmapCount2d(width, height, config.m_minMipmapDimension));
+									  ? computeMaxMipmapCount3d(width, height, ctx.m_depth, minMipDimension)
+									  : computeMaxMipmapCount2d(width, height, minMipDimension));
 	for(U32 mip = 1; mip < mipCount; ++mip)
 	{
 		ctx.m_mipmaps.emplaceBack(alloc);

+ 20 - 5
AnKi/Util/Logger.cpp

@@ -20,11 +20,16 @@
 namespace anki
 {
 
-static const Array<const char*, static_cast<U>(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "E", "W", "F"};
+static const Array<const char*, static_cast<U>(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "V", "E", "W", "F"};
 
 Logger::Logger()
 {
 	addMessageHandler(this, &defaultSystemMessageHandler);
+
+	if(getenv("ANKI_LOGGER_VERBOSE") && getenv("ANKI_LOGGER_VERBOSE") == CString("1"))
+	{
+		m_verbosityEnabled = true;
+	}
 }
 
 Logger::~Logger()
@@ -63,10 +68,16 @@ void Logger::removeMessageHandler(void* data, LoggerMessageHandlerCallback callb
 void Logger::write(const char* file, int line, const char* func, const char* subsystem, LoggerMessageType type,
 				   ThreadId tid, const char* msg)
 {
-	m_mutex.lock();
+	// Note: m_verbosityEnabled is not accessed in a thread-safe way. It doesn't really matter though
+	if(type == LoggerMessageType::VERBOSE && !m_verbosityEnabled)
+	{
+		return;
+	}
 
 	LoggerMessageInfo inf = {file, line, func, type, msg, subsystem, tid};
 
+	m_mutex.lock();
+
 	U count = m_handlersCount;
 	while(count-- != 0)
 	{
@@ -128,6 +139,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 	switch(info.m_type)
 	{
 	case LoggerMessageType::NORMAL:
+	case LoggerMessageType::VERBOSE:
 		out = stdout;
 		terminalColor = "\033[0;32m";
 		terminalColorBg = "\033[1;42;37m";
@@ -168,6 +180,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 	switch(info.m_type)
 	{
 	case LoggerMessageType::NORMAL:
+	case LoggerMessageType::VERBOSE:
 		attribs |= FOREGROUND_GREEN;
 		out = stdout;
 		break;
@@ -213,6 +226,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 	switch(info.m_type)
 	{
 	case LoggerMessageType::NORMAL:
+	case LoggerMessageType::VERBOSE:
 		andMsgType = ANDROID_LOG_INFO;
 		break;
 	case LoggerMessageType::ERROR:
@@ -237,6 +251,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 	switch(info.m_type)
 	{
 	case LoggerMessageType::NORMAL:
+	case LoggerMessageType::VERBOSE:
 		out = stdout;
 		break;
 	case LoggerMessageType::ERROR:
@@ -252,7 +267,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 		ANKI_ASSERT(0);
 	}
 
-	fprintf(out, "[%s][%s][%" PRIx64 "] %s (%s:%d %s)\n", MSG_TEXT[static_cast<U>(info.m_type)],
+	fprintf(out, "[%s][%s][%" PRIx64 "] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)],
 			info.m_subsystem ? info.m_subsystem : "N/A ", info.m_tid, info.m_msg, info.m_file, info.m_line,
 			info.m_func);
 
@@ -264,8 +279,8 @@ void Logger::fileMessageHandler(void* pfile, const LoggerMessageInfo& info)
 {
 	File* file = reinterpret_cast<File*>(pfile);
 
-	Error err = file->writeText("[%s] %s (%s:%d %s)\n", MSG_TEXT[static_cast<U>(info.m_type)], info.m_msg, info.m_file,
-								info.m_line, info.m_func);
+	Error err = file->writeText("[%s] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)], info.m_msg, info.m_file, info.m_line,
+								info.m_func);
 
 	if(!err)
 	{

+ 14 - 3
AnKi/Util/Logger.h

@@ -23,6 +23,7 @@ class File;
 enum class LoggerMessageType : U8
 {
 	NORMAL,
+	VERBOSE,
 	ERROR,
 	WARNING,
 	FATAL,
@@ -59,7 +60,7 @@ public:
 
 	~Logger();
 
-	/// Add a new message handler
+	/// Add a new message handler.
 	void addMessageHandler(void* data, LoggerMessageHandlerCallback callback);
 
 	/// Remove a message handler.
@@ -68,15 +69,21 @@ public:
 	/// Add file message handler.
 	void addFileMessageHandler(File* file);
 
-	/// Send a message
+	/// Send a message.
 	void write(const char* file, int line, const char* func, const char* subsystem, LoggerMessageType type,
 			   ThreadId tid, const char* msg);
 
-	/// Send a formated message
+	/// Send a formated message.
 	ANKI_CHECK_FORMAT(7, 8)
 	void writeFormated(const char* file, int line, const char* func, const char* subsystem, LoggerMessageType type,
 					   ThreadId tid, const char* fmt, ...);
 
+	/// Enable or disable logger verbosity.
+	void enableVerbosity(Bool enable)
+	{
+		m_verbosityEnabled = enable;
+	}
+
 private:
 	class Handler
 	{
@@ -98,6 +105,7 @@ private:
 	Mutex m_mutex; ///< For thread safety
 	Array<Handler, 4> m_handlers;
 	U32 m_handlersCount = 0;
+	Bool m_verbosityEnabled = false;
 
 	static void defaultSystemMessageHandler(void*, const LoggerMessageInfo& info);
 	static void fileMessageHandler(void* file, const LoggerMessageInfo& info);
@@ -119,6 +127,9 @@ using LoggerSingleton = Singleton<Logger>;
 /// Log information message.
 #define ANKI_LOGI(...) ANKI_LOG(nullptr, NORMAL, __VA_ARGS__)
 
+/// Log verbose information message.
+#define ANKI_LOGV(...) ANKI_LOG(nullptr, VERBOSE, __VA_ARGS__)
+
 /// Log warning message.
 #define ANKI_LOGW(...) ANKI_LOG(nullptr, WARNING, __VA_ARGS__)