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 
29 namespace vk
30 {
31 
32 namespace
33 {
34 
shortDebugFlagsStr(VkDebugReportFlagsEXT flags)35 tcu::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 
getShortObjectTypeName(VkDebugReportObjectTypeEXT objectType)49 const 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 
shortObjectTypeStr(VkDebugReportObjectTypeEXT objectType)86 tcu::Format::Enum<VkDebugReportObjectTypeEXT> shortObjectTypeStr (VkDebugReportObjectTypeEXT objectType)
87 {
88 	return tcu::Format::Enum<VkDebugReportObjectTypeEXT>(getShortObjectTypeName, objectType);
89 }
90 
91 } // anonymous
92 
operator <<(std::ostream & str,const DebugReportMessage & message)93 std::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 
107 namespace
108 {
109 
debugReportCallback(VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objectType,deUint64 object,size_t location,deInt32 messageCode,const char * pLayerPrefix,const char * pMessage,void * pUserData)110 VKAPI_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 
createCallback(const InstanceInterface & vki,VkInstance instance,DebugReportRecorder::MessageList * messageList)128 Move<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 
DebugReportRecorder(const InstanceInterface & vki,VkInstance instance)152 DebugReportRecorder::DebugReportRecorder (const InstanceInterface& vki, VkInstance instance)
153 	: m_messages	(1024)
154 	, m_callback	(createCallback(vki, instance, &m_messages))
155 {
156 }
157 
~DebugReportRecorder(void)158 DebugReportRecorder::~DebugReportRecorder (void)
159 {
160 }
161 
isDebugReportSupported(const PlatformInterface & vkp)162 bool isDebugReportSupported (const PlatformInterface& vkp)
163 {
164 	return isExtensionSupported(enumerateInstanceExtensionProperties(vkp, DE_NULL),
165 								RequiredExtension("VK_EXT_debug_report"));
166 }
167 
168 } // vk
169