1/*-------------------------------------------------------------------------
2 * Vulkan CTS Framework
3 * --------------------
4 *
5 * Copyright (c) 2016 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief VK_EXT_debug_report utilities
22 *//*--------------------------------------------------------------------*/
23
24#include "vkDebugReportUtil.hpp"
25#include "vkRefUtil.hpp"
26#include "vkQueryUtil.hpp"
27#include "deArrayUtil.hpp"
28
29namespace vk
30{
31
32namespace
33{
34
35tcu::Format::Bitfield<32> shortDebugFlagsStr (VkDebugReportFlagsEXT flags)
36{
37	static const tcu::Format::BitDesc	s_bits[] =
38	{
39		tcu::Format::BitDesc(VK_DEBUG_REPORT_INFORMATION_BIT_EXT,			"INFO"),
40		tcu::Format::BitDesc(VK_DEBUG_REPORT_WARNING_BIT_EXT,				"WARNING"),
41		tcu::Format::BitDesc(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,	"PERFORMANCE"),
42		tcu::Format::BitDesc(VK_DEBUG_REPORT_ERROR_BIT_EXT,					"ERROR"),
43		tcu::Format::BitDesc(VK_DEBUG_REPORT_DEBUG_BIT_EXT,					"DEBUG"),
44	};
45
46	return tcu::Format::Bitfield<32>(flags, DE_ARRAY_BEGIN(s_bits), DE_ARRAY_END(s_bits));
47}
48
49const char* getShortObjectTypeName (VkDebugReportObjectTypeEXT objectType)
50{
51	static const char* const s_names[] =
52	{
53		"Unknown",
54		"Instance",
55		"PhysicalDevice",
56		"Device",
57		"Queue",
58		"Semaphore",
59		"CommandBuffer",
60		"Fence",
61		"DeviceMemory",
62		"Buffer",
63		"Image",
64		"Event",
65		"QueryPool",
66		"BufferView",
67		"ImageView",
68		"ShaderModule",
69		"PipelineCache",
70		"PipelineLayout",
71		"RenderPass",
72		"Pipeline",
73		"DescriptorSetLayout",
74		"Sampler",
75		"DescriptorPool",
76		"DescriptorSet",
77		"Framebuffer",
78		"CommandPool",
79		"SurfaceKHR",
80		"SwapchainKHR",
81		"DebugReportCallbackEXT",
82	};
83	return de::getSizedArrayElement<VK_DEBUG_REPORT_OBJECT_TYPE_EXT_LAST>(s_names, objectType);
84}
85
86tcu::Format::Enum<VkDebugReportObjectTypeEXT> shortObjectTypeStr (VkDebugReportObjectTypeEXT objectType)
87{
88	return tcu::Format::Enum<VkDebugReportObjectTypeEXT>(getShortObjectTypeName, objectType);
89}
90
91} // anonymous
92
93std::ostream& operator<< (std::ostream& str, const DebugReportMessage& message)
94{
95	str << shortDebugFlagsStr(message.flags) << ": "
96		<< message.message
97		<< " (code " << tcu::toHex(message.messageCode);
98
99	if (!message.layerPrefix.empty())
100		str << " from " << message.layerPrefix;
101
102	str << " at " << shortObjectTypeStr(message.objectType) << ":" << message.location << ")";
103
104	return str;
105}
106
107namespace
108{
109
110VKAPI_ATTR VkBool32	VKAPI_CALL debugReportCallback (VkDebugReportFlagsEXT		flags,
111													VkDebugReportObjectTypeEXT	objectType,
112													deUint64					object,
113													size_t						location,
114													deInt32						messageCode,
115													const char*					pLayerPrefix,
116													const char*					pMessage,
117													void*						pUserData)
118{
119	DebugReportRecorder::MessageList* const	messageList	= reinterpret_cast<DebugReportRecorder::MessageList*>(pUserData);
120
121	messageList->append(DebugReportMessage(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage));
122
123	// Return false to indicate that the call should not return error and should
124	// continue execution normally.
125	return VK_FALSE;
126}
127
128Move<VkDebugReportCallbackEXT> createCallback (const InstanceInterface&				vki,
129											   VkInstance							instance,
130											   DebugReportRecorder::MessageList*	messageList)
131{
132	const VkDebugReportFlagsEXT					allFlags	= VK_DEBUG_REPORT_INFORMATION_BIT_EXT
133															| VK_DEBUG_REPORT_WARNING_BIT_EXT
134															| VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT
135															| VK_DEBUG_REPORT_ERROR_BIT_EXT
136															| VK_DEBUG_REPORT_DEBUG_BIT_EXT;
137
138	const VkDebugReportCallbackCreateInfoEXT	createInfo	=
139	{
140		VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
141		DE_NULL,
142		allFlags,
143		debugReportCallback,
144		messageList
145	};
146
147	return createDebugReportCallbackEXT(vki, instance, &createInfo);
148}
149
150} // anonymous
151
152DebugReportRecorder::DebugReportRecorder (const InstanceInterface& vki, VkInstance instance)
153	: m_messages	(1024)
154	, m_callback	(createCallback(vki, instance, &m_messages))
155{
156}
157
158DebugReportRecorder::~DebugReportRecorder (void)
159{
160}
161
162bool isDebugReportSupported (const PlatformInterface& vkp)
163{
164	return isExtensionSupported(enumerateInstanceExtensionProperties(vkp, DE_NULL),
165								RequiredExtension("VK_EXT_debug_report"));
166}
167
168} // vk
169