blob: f6dc561c5ee54bfb59098c9d5deccd1cca794f74 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_UI_LIB_ESCHER_TEST_VK_DEBUG_REPORT_COLLECTOR_H_
#define SRC_UI_LIB_ESCHER_TEST_VK_DEBUG_REPORT_COLLECTOR_H_
#include <string>
#include <vector>
#include <vulkan/vulkan.hpp>
namespace escher::test {
namespace impl {
// Collects Vulkan debug reports and provides functions used by validation debug report checking
// macros.
//
// A test fixture which has an instance of |VkDebugReportCallbackRegistry| and
// |VkDebugReportCollector| will be able to store all validation debug reports by setting
// |HandleDebugReport| with |pUserData| pointing to this instance, as its callback function.
//
// NOTE: Users may want to use the test fixture class |TestWithVkValidationLayer| directly if they
// only need the basic unit tests with Vulkan validation layer enabled.
//
class VkDebugReportCollector {
public:
// Debug report struct generated by Vulkan validation layer.
struct VkDebugReport {
vk::DebugReportFlagsEXT flags;
vk::DebugReportObjectTypeEXT object_type;
uint64_t object;
std::string layer_prefix;
int32_t message_code;
std::string message;
std::string ErrorMessage() const {
return "[" + vk::to_string(flags) + "] " + " [Object type] " + vk::to_string(object_type) +
" [Object id] " + std::to_string(object) + " [Layer] " + layer_prefix +
" [Message] # " + std::to_string(message_code) + " : " + message;
}
};
// Default constructor.
VkDebugReportCollector() = default;
// Default Validation layer debug handler which stores all debug reports to the
// std::vector<VkDebugReport> object which |pUserData|points to.
//
// The callback function is specified in
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/
// PFN_vkDebugReportCallbackEXT.html
// |flags| specifies the VkDebugReportFlagBitsEXT that triggered this callback.
// |object_type| specifyins the type of object being used or created at the time the event was
// triggered.
// |object| is the object where the issue was detected.
// |location| is a component (layer, driver, loader) defined value specifying the location
// of the trigger. This is an optional value.
// |message_code| is a layer-defined value indicating what test triggered this callback.
// |layer_prefix| is a null-terminated string that is an abbreviation of the name of
// the component making the callback.
// |message| is a null-terminated string detailing the trigger conditions.
// |user_data| is specified when user creates the debug callback object.
static uint32_t HandleDebugReport(VkFlags flags, VkDebugReportObjectTypeEXT object_type,
uint64_t object, size_t location, int32_t message_code,
const char* layer_prefix, const char* message, void* user_data);
// Helper function which prints out the debug reports if
// |predicate|(number of debug reports with |flags|, |num_threshold|) == false.
// |file| and |line| are passed by macros using __FILE__ and __LINE__ to print error position.
//
// Used only by |EXPECT/ASSERT_VULKAN_VALIDATION_LAYER_ERRORS_[PREDICATE]()| macros and should
// only be called within test scope.
bool PrintDebugReportsOnFalsePredicate(const vk::DebugReportFlagsEXT& flags, size_t num_threshold,
const std::function<bool(size_t, size_t)>& predicate,
const char* file, size_t line) const;
// Removes debug reports with certain debug report flag from |debug_reports_| list to suppress
// test failure.
// Used by SUPPRESS_VK_VALIDATION_[WARNINGS/ERRORS/PERFORMANCE_WARNINGS]() macros and should
// only be called within test scope..
void SuppressDebugReportsWithFlag(const vk::DebugReportFlagsEXT& flags);
// Removes all debug reports from |debug_reports_| list to suppress test failure.
// Used by SUPPRESS_VK_VALIDATION_DEBUG_REPORTS() macro and should only be called within test
// scope.
void SuppressAllDebugReports() { SuppressDebugReportsWithFlag(~vk::DebugReportFlagsEXT()); }
private:
// Helper function which outputs all debug reports with specific flag.
std::vector<VkDebugReport> DebugReportsWithFlag(const vk::DebugReportFlagsEXT& flags) const;
std::vector<VkDebugReport> debug_reports_ = {};
};
} // namespace impl
} // namespace escher::test
#endif // SRC_UI_LIB_ESCHER_TEST_VK_DEBUG_REPORT_COLLECTOR_H_