From 36411219ff2b1c1c3a783b6577b812e0bc5f2293 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 5 Mar 2019 11:57:31 +0000 Subject: [PATCH] VkDebug: Update macros to address issues in b/127433389 Also add WARN() and ASSERT_MSG(). Bug: b/127433389 Change-Id: I2549e9a79b3168cfc419d6564f0c111f95246452 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26148 Reviewed-by: Nicolas Capens Reviewed-by: Chris Forbes Tested-by: Ben Clayton --- src/Pipeline/SpirvShader.cpp | 6 +-- src/Pipeline/SpirvShader.hpp | 4 +- src/Vulkan/VkDebug.cpp | 50 +++++++++++++++++--- src/Vulkan/VkDebug.hpp | 102 ++++++++++++++++++++++------------------ src/Vulkan/VkPhysicalDevice.cpp | 2 +- src/Vulkan/VkPipeline.cpp | 18 ++++--- src/Vulkan/libVulkan.cpp | 2 +- 7 files changed, 113 insertions(+), 71 deletions(-) diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp index 794f6716a..f83319d89 100644 --- a/src/Pipeline/SpirvShader.cpp +++ b/src/Pipeline/SpirvShader.cpp @@ -260,7 +260,7 @@ namespace sw mainBlockId = Block::ID(it.word(1)); break; default: - ERR("Unexpected opcode '%s' following OpFunction", OpcodeName(it.opcode()).c_str()); + WARN("Unexpected opcode '%s' following OpFunction", OpcodeName(it.opcode()).c_str()); } } ASSERT(mainBlockId.value() != 0); // Function's OpLabel not found @@ -399,7 +399,7 @@ namespace sw break; default: - UNIMPLEMENTED(OpcodeName(insn.opcode()).c_str()); + UNIMPLEMENTED("%s", OpcodeName(insn.opcode()).c_str()); } } } @@ -1190,7 +1190,7 @@ namespace sw break; default: - UNIMPLEMENTED(OpcodeName(insn.opcode()).c_str()); + UNIMPLEMENTED("opcode: %s", OpcodeName(insn.opcode()).c_str()); break; } } diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp index ecfa91ce1..007c04221 100644 --- a/src/Pipeline/SpirvShader.hpp +++ b/src/Pipeline/SpirvShader.hpp @@ -391,14 +391,14 @@ namespace sw Type const &getType(Type::ID id) const { auto it = types.find(id); - ASSERT(it != types.end()); + ASSERT_MSG(it != types.end(), "Unknown type %d", id.value()); return it->second; } Object const &getObject(Object::ID id) const { auto it = defs.find(id); - ASSERT(it != defs.end()); + ASSERT_MSG(it != defs.end(), "Unknown object %d", id.value()); return it->second; } diff --git a/src/Vulkan/VkDebug.cpp b/src/Vulkan/VkDebug.cpp index b82ef809e..262f70004 100644 --- a/src/Vulkan/VkDebug.cpp +++ b/src/Vulkan/VkDebug.cpp @@ -14,25 +14,61 @@ #include "VkDebug.hpp" +#include #include namespace vk { -void trace(const char *format, ...) + +void tracev(const char *format, va_list args) { +#ifndef SWIFTSHADER_DISABLE_TRACE if(false) { - FILE *file = fopen("debug.txt", "a"); + FILE *file = fopen(TRACE_OUTPUT_FILE, "a"); if(file) { - va_list vararg; - va_start(vararg, format); - vfprintf(file, format, vararg); - va_end(vararg); - + vfprintf(file, format, args); fclose(file); } } +#endif +} + +void trace(const char *format, ...) +{ + va_list vararg; + va_start(vararg, format); + tracev(format, vararg); + va_end(vararg); +} + +void warn(const char *format, ...) +{ + va_list vararg; + va_start(vararg, format); + tracev(format, vararg); + va_end(vararg); + + va_start(vararg, format); + vfprintf(stderr, format, vararg); + va_end(vararg); } + +void abort(const char *format, ...) +{ + va_list vararg; + + va_start(vararg, format); + tracev(format, vararg); + va_end(vararg); + + va_start(vararg, format); + vfprintf(stderr, format, vararg); + va_end(vararg); + + ::abort(); +} + } diff --git a/src/Vulkan/VkDebug.hpp b/src/Vulkan/VkDebug.hpp index 6bad986b7..c801d2721 100644 --- a/src/Vulkan/VkDebug.hpp +++ b/src/Vulkan/VkDebug.hpp @@ -27,77 +27,85 @@ namespace vk { -// Outputs text to the debugging log -void trace(const char *format, ...); -inline void trace() {} + // Outputs text to the debugging log + void trace(const char *format, ...); + inline void trace() {} + + // Outputs text to the debugging log and prints to stderr. + void warn(const char *format, ...); + inline void warn() {} + + // Outputs the message to the debugging log and stderr, and calls abort(). + void abort(const char *format, ...); } -// A macro to output a trace of a function call and its arguments to the debugging log +// A macro to output a trace of a function call and its arguments to the +// debugging log. Disabled if SWIFTSHADER_DISABLE_TRACE is defined. #if defined(SWIFTSHADER_DISABLE_TRACE) #define TRACE(message, ...) (void(0)) #else -#define TRACE(message, ...) vk::trace("trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define TRACE(message, ...) vk::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__) #endif -// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. -#if defined(SWIFTSHADER_DISABLE_TRACE) -#define FIXME(message, ...) (void(0)) -#else -#define FIXME(message, ...) do {vk::trace("fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false); abort();} while(false) -#endif +// A macro to print a warning message to the debugging log and stderr to denote +// an issue that needs fixing. +#define FIXME(message, ...) vk::warn("%s:%d FIXME: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__); -// A macro to output a function call and its arguments to the debugging log, in case of error. -#if defined(SWIFTSHADER_DISABLE_TRACE) -#define ERR(message, ...) (void(0)) +// A macro to print a warning message to the debugging log and stderr. +#define WARN(message, ...) vk::warn("%s:%d WARNING: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__); + +// A macro that prints the message to the debugging log and stderr and +// immediately aborts execution of the application. +// +// Note: This will terminate the application regardless of build flags! +// Use with extreme caution! +#undef ABORT +#define ABORT(message, ...) vk::abort("%s:%d ABORT: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__) + +// A macro that delegates to: +// ABORT() in debug builds (!NDEBUG || DCHECK_ALWAYS_ON) +// or +// WARN() in release builds (NDEBUG && !DCHECK_ALWAYS_ON) +#undef DABORT +#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) +#define DABORT(...) ABORT(__VA_ARGS__) #else -#define ERR(message, ...) do {vk::trace("err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false); abort();} while(false) +#define DABORT(...) WARN(__VA_ARGS__) #endif -// A macro asserting a condition and outputting failures to the debug log +// A macro asserting a condition. +// If the condition fails, the condition and message is passed to DABORT(). +#undef ASSERT_MSG +#define ASSERT_MSG(expression, format, ...) do { \ + if(!(expression)) { \ + DABORT("ASSERT(%s): " format "\n", #expression, ##__VA_ARGS__); \ + } } while(0) + +// A macro asserting a condition. +// If the condition fails, the condition is passed to DABORT(). #undef ASSERT -#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) #define ASSERT(expression) do { \ if(!(expression)) { \ - ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \ - assert(expression); \ - abort(); \ + DABORT("ASSERT(%s)\n", #expression); \ } } while(0) -#else -#define ASSERT(expression) (void(0)) -#endif -// A macro to indicate unimplemented functionality +// A macro to indicate unimplemented functionality. #undef UNIMPLEMENTED -#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) -#define UNIMPLEMENTED(...) do { \ - vk::trace("\t! Unimplemented: %s(%d): ", __FUNCTION__, __LINE__); \ - vk::trace(__VA_ARGS__); \ - vk::trace("\n"); \ - assert(false); \ - abort(); \ - } while(0) -#else - #define UNIMPLEMENTED(...) FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__) -#endif +#define UNIMPLEMENTED(...) DABORT("UNIMPLEMENTED! " __VA_ARGS__) -// A macro for code which is not expected to be reached under valid assumptions +// A macro for code which is not expected to be reached under valid assumptions. #undef UNREACHABLE -#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) -#define UNREACHABLE(value) do { \ - ERR("\t! Unreachable case reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \ - assert(false); \ - abort(); \ - } while(0) -#else - #define UNREACHABLE(value) ERR("\t! Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value) -#endif +#define UNREACHABLE(...) DABORT("UNREACHABLE! " __VA_ARGS__) -// A macro asserting a condition and outputting failures to the debug log, or return when in release mode. +// A macro asserting a condition and performing a return. #undef ASSERT_OR_RETURN +#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) +#define ASSERT_OR_RETURN(expression) ASSERT(expression) +#else #define ASSERT_OR_RETURN(expression) do { \ if(!(expression)) { \ - ASSERT(expression); \ return; \ } } while(0) +#endif #endif // VK_DEBUG_H_ diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp index 47757185d..08a7b9a4e 100644 --- a/src/Vulkan/VkPhysicalDevice.cpp +++ b/src/Vulkan/VkPhysicalDevice.cpp @@ -653,7 +653,7 @@ void PhysicalDevice::getImageFormatProperties(VkFormat format, VkImageType type, pImageFormatProperties->maxArrayLayers = 1; // no 3D + layers break; default: - UNREACHABLE(type); + UNREACHABLE("VkImageType: %d", int(type)); break; } diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp index 9d11b8503..ddb5ca493 100644 --- a/src/Vulkan/VkPipeline.cpp +++ b/src/Vulkan/VkPipeline.cpp @@ -192,19 +192,17 @@ std::vector preprocessSpirv( spvtools::Optimizer opt{SPV_ENV_VULKAN_1_1}; opt.SetMessageConsumer([](spv_message_level_t level, const char*, const spv_position_t& p, const char* m) { + const char* category = ""; switch (level) { - case SPV_MSG_FATAL: - case SPV_MSG_INTERNAL_ERROR: - case SPV_MSG_ERROR: - ERR("%d:%d %s", p.line, p.column, m); - break; - case SPV_MSG_WARNING: - case SPV_MSG_INFO: - case SPV_MSG_DEBUG: - TRACE("%d:%d %s", p.line, p.column, m); - break; + case SPV_MSG_FATAL: category = "FATAL"; break; + case SPV_MSG_INTERNAL_ERROR: category = "INTERNAL_ERROR"; break; + case SPV_MSG_ERROR: category = "ERROR"; break; + case SPV_MSG_WARNING: category = "WARNING"; break; + case SPV_MSG_INFO: category = "INFO"; break; + case SPV_MSG_DEBUG: category = "DEBUG"; break; } + vk::trace("%s: %d:%d %s", category, p.line, p.column, m); }); opt.RegisterPass(spvtools::CreateInlineExhaustivePass()); diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp index e6007776b..b9c57a182 100644 --- a/src/Vulkan/libVulkan.cpp +++ b/src/Vulkan/libVulkan.cpp @@ -1737,7 +1737,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(VkDevice device, u device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures); ASSERT(localDeviceIndex != remoteDeviceIndex); // "localDeviceIndex must not equal remoteDeviceIndex" - UNREACHABLE(remoteDeviceIndex); // Only one physical device is supported, and since the device indexes can't be equal, this should never be called. + UNREACHABLE("remoteDeviceIndex: %d", int(remoteDeviceIndex)); // Only one physical device is supported, and since the device indexes can't be equal, this should never be called. } VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) -- 2.11.0