diff options
author | 2016-01-16 16:34:29 -0800 | |
---|---|---|
committer | 2016-01-25 13:49:31 -0800 | |
commit | 715b86ac7d0853131b375ff786c87d8d87a762a1 (patch) | |
tree | b1a2f6e8e09307f7b4b3b1dbc134c01465cad462 | |
parent | 6bd5dfa9b94d1f1b2d9b6bae52979502c44c2847 (diff) |
vulkan: Support VK_EXT_debug_report in loader and nulldrv
* Add extension to vulkan.api.
* Fix a few errors in upstream vk_ext_debug_report.h; bugs filed.
* Loader enumerates extension iff the driver supports it.
- TODO: Also enumerate if any layers that support it are implicitly
enabled.
- Note extension may still be enabled if any layer supports it.
* Add loader bottom procs for the extension functions. These will call
through to the driver version if the driver supports the extension.
* Add no-op support to nulldrv, mostly for testing the loader.
Change-Id: I092d2da56ee4c64498f8edae75e0d995478bb6f2
(cherry picked from commit a5ef7c27bc85e3628814532a32ffb9a5c33c4b73)
-rw-r--r-- | vulkan/api/vulkan.api | 108 | ||||
-rw-r--r-- | vulkan/include/vulkan/vk_debug_report_lunarg.h | 182 | ||||
-rw-r--r-- | vulkan/include/vulkan/vk_ext_debug_report.h | 11 | ||||
-rw-r--r-- | vulkan/libvulkan/Android.mk | 10 | ||||
-rw-r--r-- | vulkan/libvulkan/debug_report.cpp | 123 | ||||
-rw-r--r-- | vulkan/libvulkan/debug_report.h | 71 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch.tmpl | 15 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch_gen.cpp | 42 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch_gen.h | 7 | ||||
-rw-r--r-- | vulkan/libvulkan/layers_extensions.cpp | 2 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.cpp | 83 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.h | 4 | ||||
-rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 8 | ||||
-rw-r--r-- | vulkan/nulldrv/Android.mk | 7 | ||||
-rw-r--r-- | vulkan/nulldrv/null_driver.cpp | 93 | ||||
-rw-r--r-- | vulkan/nulldrv/null_driver.tmpl | 4 | ||||
-rw-r--r-- | vulkan/nulldrv/null_driver_gen.cpp | 3 | ||||
-rw-r--r-- | vulkan/nulldrv/null_driver_gen.h | 4 |
18 files changed, 510 insertions, 267 deletions
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 5d35ddf65b..d7358449e4 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -75,6 +75,9 @@ define NULL_HANDLE 0 @extension("VK_KHR_win32_surface") define VK_KHR_WIN32_SURFACE_SPEC_VERSION 5 @extension("VK_KHR_win32_surface") define VK_KHR_WIN32_SURFACE_NAME "VK_KHR_win32_surface" +@extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_SPEC_VERSION 2 +@extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_NAME "VK_EXT_debug_report" + ///////////// // Types // @@ -121,6 +124,8 @@ type u32 VkSampleMask @extension("VK_KHR_display") @nonDispatchHandle type u64 VkDisplayKHR @extension("VK_KHR_display") @nonDispatchHandle type u64 VkDisplayModeKHR +@extension("VK_EXT_debug_report") @nonDispatchHandle type u64 VkDebugReportCallbackEXT + ///////////// // Enums // @@ -722,6 +727,46 @@ enum VkColorSpaceKHR { VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0x00000000, } +@extension("VK_EXT_debug_report") +enum VkDebugReportObjectTypeEXT { + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, + VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, + VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, + VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, + VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, + VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, + VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, + VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, + VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, + VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, + VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = 28, +} + +@extension("VK_EXT_debug_report") +enum VkDebugReportErrorEXT { + VK_DEBUG_REPORT_ERROR_NONE_EXT = 0, + VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT = 1, +} + + ///////////////// // Bitfields // ///////////////// @@ -1249,6 +1294,17 @@ type VkFlags VkWin32SurfaceCreateFlagsKHR //bitfield VkWin32SurfaceCreateFlagBitsKHR { //} +@extension("VK_EXT_debug_report") +type VkFlags VkDebugReportFlagsEXT +@extension("VK_EXT_debug_report") +bitfield VkDebugReportFlagBitsEXT { + VK_DEBUG_REPORT_INFO_BIT_EXT = 0x00000001, + VK_DEBUG_REPORT_WARN_BIT_EXT = 0x00000002, + VK_DEBUG_REPORT_PERF_WARN_BIT_EXT = 0x00000004, + VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, +} + ////////////////// // Structures // @@ -2534,6 +2590,15 @@ class VkWin32SurfaceCreateInfoKHR { platform.HWND hwnd } +@extension("VK_EXT_debug_report") +class VkDebugReportCallbackCreateInfoEXT { + VkStructureType sType + const void* pNext + VkDebugReportFlagsEXT flags + PFN_vkDebugReportCallbackEXT pfnCallback + void* pUserData +} + //////////////// // Commands // @@ -5068,6 +5133,49 @@ cmd VkResult vkGetPhysicalDeviceWin32PresentationSupportKHR( return ? } +@extension("VK_EXT_debug_report") +@external type void* PFN_vkDebugReportCallbackEXT +@extension("VK_EXT_debug_report") +@pfn cmd VkBool32 vkDebugReportCallbackEXT( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + u64 object, + platform.size_t location, + s32 messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData) { + return ? +} + +@extension("VK_EXT_debug_report") +cmd VkResult vkCreateDebugReportCallbackEXT( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugReportCallbackEXT* pCallback) { + return ? +} + +@extension("VK_EXT_debug_report") +cmd void vkDestroyDebugReportCallbackEXT( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* pAllocator) { +} + +@extension("VK_EXT_debug_report") +cmd void vkDebugReportMessageEXT( + VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + u64 object, + platform.size_t location, + s32 messageCode, + const char* pLayerPrefix, + const char* pMessage) { +} + //////////////// // Validation // diff --git a/vulkan/include/vulkan/vk_debug_report_lunarg.h b/vulkan/include/vulkan/vk_debug_report_lunarg.h deleted file mode 100644 index 58939c90db..0000000000 --- a/vulkan/include/vulkan/vk_debug_report_lunarg.h +++ /dev/null @@ -1,182 +0,0 @@ -// -// File: vk_debug_report_lunarg.h -// -/* - * Vulkan - * - * Copyright (C) 2015 LunarG, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jon Ashburn <jon@lunarg.com> - * Courtney Goeltzenleuchter <courtney@lunarg.com> - */ - -#ifndef __VK_DEBUG_REPORT_LUNARG_H__ -#define __VK_DEBUG_REPORT_LUNARG_H__ - -#include "vulkan.h" - -#define VK_DEBUG_REPORT_EXTENSION_NUMBER 5 -#define VK_DEBUG_REPORT_EXTENSION_REVISION 1 -#ifdef __cplusplus -extern "C" -{ -#endif // __cplusplus - -/* -*************************************************************************************************** -* DebugReport Vulkan Extension API -*************************************************************************************************** -*/ -typedef enum { - VK_OBJECT_TYPE_INSTANCE = 0, - VK_OBJECT_TYPE_PHYSICAL_DEVICE = 1, - VK_OBJECT_TYPE_DEVICE = 2, - VK_OBJECT_TYPE_QUEUE = 3, - VK_OBJECT_TYPE_COMMAND_BUFFER = 4, - VK_OBJECT_TYPE_DEVICE_MEMORY = 5, - VK_OBJECT_TYPE_BUFFER = 6, - VK_OBJECT_TYPE_BUFFER_VIEW = 7, - VK_OBJECT_TYPE_IMAGE = 8, - VK_OBJECT_TYPE_IMAGE_VIEW = 9, - VK_OBJECT_TYPE_ATTACHMENT_VIEW = 10, - VK_OBJECT_TYPE_SHADER_MODULE = 12, - VK_OBJECT_TYPE_SHADER = 13, - VK_OBJECT_TYPE_PIPELINE = 14, - VK_OBJECT_TYPE_PIPELINE_LAYOUT = 15, - VK_OBJECT_TYPE_SAMPLER = 16, - VK_OBJECT_TYPE_DESCRIPTOR_SET = 17, - VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 18, - VK_OBJECT_TYPE_DESCRIPTOR_POOL = 19, - VK_OBJECT_TYPE_FENCE = 20, - VK_OBJECT_TYPE_SEMAPHORE = 21, - VK_OBJECT_TYPE_EVENT = 22, - VK_OBJECT_TYPE_QUERY_POOL = 23, - VK_OBJECT_TYPE_FRAMEBUFFER = 24, - VK_OBJECT_TYPE_RENDER_PASS = 25, - VK_OBJECT_TYPE_PIPELINE_CACHE = 26, - VK_OBJECT_TYPE_SWAPCHAIN_KHR = 27, - VK_OBJECT_TYPE_CMD_POOL = 28, - VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_INSTANCE, - VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_CMD_POOL, - VK_OBJECT_TYPE_NUM = (VK_OBJECT_TYPE_CMD_POOL - VK_OBJECT_TYPE_INSTANCE + 1), - VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDbgObjectType; - -#define VK_DEBUG_REPORT_EXTENSION_NAME "DEBUG_REPORT" - -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDbgMsgCallback) - -// ------------------------------------------------------------------------------------------------ -// Enumerations - -typedef enum VkDbgReportFlags_ -{ - VK_DBG_REPORT_INFO_BIT = 0x0001, - VK_DBG_REPORT_WARN_BIT = 0x0002, - VK_DBG_REPORT_PERF_WARN_BIT = 0x0004, - VK_DBG_REPORT_ERROR_BIT = 0x0008, - VK_DBG_REPORT_DEBUG_BIT = 0x0010, -} VkDbgReportFlags; - -// Debug Report ERROR codes -typedef enum _DEBUG_REPORT_ERROR -{ - DEBUG_REPORT_NONE, // Used for INFO & other non-error messages - DEBUG_REPORT_CALLBACK_REF, // Callbacks were not destroyed prior to calling DestroyInstance -} DEBUG_REPORT_ERROR; - -#define VK_DEBUG_REPORT_ENUM_EXTEND(type, id) ((type)(VK_DEBUG_REPORT_EXTENSION_NUMBER * -1000 + (id))) - -#define VK_OBJECT_TYPE_MSG_CALLBACK VK_DEBUG_REPORT_ENUM_EXTEND(VkDbgObjectType, 0) -#define VK_ERROR_VALIDATION_FAILED VK_DEBUG_REPORT_ENUM_EXTEND(VkResult, 0) - -// ------------------------------------------------------------------------------------------------ -// Vulkan function pointers - -typedef VkBool32 (VKAPI_PTR *PFN_vkDbgMsgCallback)( - VkFlags msgFlags, - VkDbgObjectType objType, - uint64_t srcObject, - size_t location, - int32_t msgCode, - const char* pLayerPrefix, - const char* pMsg, - void* pUserData); - -// ------------------------------------------------------------------------------------------------ -// API functions - -typedef VkResult (VKAPI_PTR *PFN_vkDbgCreateMsgCallback)(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, void* pUserData, VkDbgMsgCallback* pMsgCallback); -typedef VkResult (VKAPI_PTR *PFN_vkDbgDestroyMsgCallback)(VkInstance instance, VkDbgMsgCallback msgCallback); - -#ifdef VK_PROTOTYPES - -// DebugReport extension entrypoints -VKAPI_ATTR VkResult VKAPI_CALL vkDbgCreateMsgCallback( - VkInstance instance, - VkFlags msgFlags, - const PFN_vkDbgMsgCallback pfnMsgCallback, - void* pUserData, - VkDbgMsgCallback* pMsgCallback); - -VKAPI_ATTR VkResult VKAPI_CALL vkDbgDestroyMsgCallback( - VkInstance instance, - VkDbgMsgCallback msgCallback); - -// DebugReport utility callback functions -VKAPI_ATTR void VKAPI_CALL vkDbgStringCallback( - VkFlags msgFlags, - VkDbgObjectType objType, - uint64_t srcObject, - size_t location, - int32_t msgCode, - const char* pLayerPrefix, - const char* pMsg, - void* pUserData); - -VKAPI_ATTR void VKAPI_CALL vkDbgStdioCallback( - VkFlags msgFlags, - VkDbgObjectType objType, - uint64_t srcObject, - size_t location, - int32_t msgCode, - const char* pLayerPrefix, - const char* pMsg, - void* pUserData); - -VKAPI_ATTR void VKAPI_CALL vkDbgBreakCallback( - VkFlags msgFlags, - VkDbgObjectType objType, - uint64_t srcObject, - size_t location, - int32_t msgCode, - const char* pLayerPrefix, - const char* pMsg, - void* pUserData); - -#endif // VK_PROTOTYPES - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // __VK_DEBUG_REPORT_LUNARG_H__ diff --git a/vulkan/include/vulkan/vk_ext_debug_report.h b/vulkan/include/vulkan/vk_ext_debug_report.h index 40d0df3e16..c391033129 100644 --- a/vulkan/include/vulkan/vk_ext_debug_report.h +++ b/vulkan/include/vulkan/vk_ext_debug_report.h @@ -47,8 +47,7 @@ extern "C" #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) -#define VK_EXT_DEBUG_REPORT_REVISION 2 -#define VK_EXT_DEBUG_REPORT_EXTENSION_NUMBER 11 +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 2 #define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" @@ -85,8 +84,8 @@ typedef enum VkDebugReportObjectTypeEXT { } VkDebugReportObjectTypeEXT; typedef enum VkDebugReportErrorEXT { - VK_DEBUG_REPORT_ERROR_NONE = 0, - VK_DEBUG_REPORT_ERROR_CALLBACK_REF = 1, + VK_DEBUG_REPORT_ERROR_NONE_EXT = 0, + VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT = 1, } VkDebugReportErrorEXT; typedef enum VkDebugReportFlagBitsEXT { @@ -106,7 +105,7 @@ typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( int32_t messageCode, const char* pLayerPrefix, const char* pMessage, - const void* pUserData); + void* pUserData); typedef struct VkDebugReportCallbackCreateInfoEXT { @@ -114,7 +113,7 @@ typedef struct VkDebugReportCallbackCreateInfoEXT { const void* pNext; VkDebugReportFlagsEXT flags; PFN_vkDebugReportCallbackEXT pfnCallback; - const void* pUserData; + void* pUserData; } VkDebugReportCallbackCreateInfoEXT; typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk index 42417573f4..e643918381 100644 --- a/vulkan/libvulkan/Android.mk +++ b/vulkan/libvulkan/Android.mk @@ -16,9 +16,12 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CLANG := true -LOCAL_CFLAGS := -std=c99 -fvisibility=hidden -fstrict-aliasing -LOCAL_CFLAGS += -DLOG_TAG=\"vulkan\" -LOCAL_CFLAGS += -Weverything -Werror -Wno-padded -Wno-undef +LOCAL_CFLAGS := -DLOG_TAG=\"vulkan\" \ + -std=c99 -fvisibility=hidden -fstrict-aliasing \ + -Weverything -Werror \ + -Wno-padded \ + -Wno-undef +#LOCAL_CFLAGS += -DLOG_NDEBUG=0 LOCAL_CPPFLAGS := -std=c++14 \ -Wno-c++98-compat-pedantic \ -Wno-exit-time-destructors \ @@ -31,6 +34,7 @@ LOCAL_C_INCLUDES := \ system/core/libsync/include LOCAL_SRC_FILES := \ + debug_report.cpp \ dispatch_gen.cpp \ layers_extensions.cpp \ loader.cpp \ diff --git a/vulkan/libvulkan/debug_report.cpp b/vulkan/libvulkan/debug_report.cpp new file mode 100644 index 0000000000..fea9f18528 --- /dev/null +++ b/vulkan/libvulkan/debug_report.cpp @@ -0,0 +1,123 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "loader.h" + +namespace vulkan { + +VkResult DebugReportCallbackList::CreateCallback( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* create_info, + const VkAllocationCallbacks* allocator, + VkDebugReportCallbackEXT* callback) { + VkDebugReportCallbackEXT driver_callback; + VkResult result = GetDriverDispatch(instance).CreateDebugReportCallbackEXT( + GetDriverInstance(instance), create_info, allocator, &driver_callback); + if (result != VK_SUCCESS) + return result; + + const VkAllocationCallbacks* alloc = + allocator ? allocator : GetAllocator(instance); + void* mem = + alloc->pfnAllocation(alloc->pUserData, sizeof(Node), alignof(Node), + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!mem) { + GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( + GetDriverInstance(instance), driver_callback, allocator); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + std::lock_guard<decltype(rwmutex_)> lock(rwmutex_); + head_.next = + new (mem) Node{head_.next, create_info->flags, create_info->pfnCallback, + create_info->pUserData, driver_callback}; + *callback = + VkDebugReportCallbackEXT(reinterpret_cast<uintptr_t>(head_.next)); + return VK_SUCCESS; +} + +void DebugReportCallbackList::DestroyCallback( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* allocator) { + Node* node = reinterpret_cast<Node*>(uintptr_t(callback)); + std::unique_lock<decltype(rwmutex_)> lock(rwmutex_); + Node* prev = &head_; + while (prev && prev->next != node) + prev = prev->next; + prev->next = node->next; + lock.unlock(); + + GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( + GetDriverInstance(instance), node->driver_callback, allocator); + + const VkAllocationCallbacks* alloc = + allocator ? allocator : GetAllocator(instance); + alloc->pfnFree(alloc->pUserData, node); +} + +void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message) { + std::shared_lock<decltype(rwmutex_)> lock(rwmutex_); + Node* node = &head_; + while ((node = node->next)) { + if ((node->flags & flags) != 0) { + node->callback(flags, object_type, object, location, message_code, + layer_prefix, message, node->data); + } + } +} + +VkResult CreateDebugReportCallbackEXT_Bottom( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* create_info, + const VkAllocationCallbacks* allocator, + VkDebugReportCallbackEXT* callback) { + return GetDebugReportCallbacks(instance).CreateCallback( + instance, create_info, allocator, callback); +} + +void DestroyDebugReportCallbackEXT_Bottom( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* allocator) { + if (callback) + GetDebugReportCallbacks(instance).DestroyCallback(instance, callback, + allocator); +} + +void DebugReportMessageEXT_Bottom(VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message) { + GetDriverDispatch(instance).DebugReportMessageEXT( + GetDriverInstance(instance), flags, object_type, object, location, + message_code, layer_prefix, message); + GetDebugReportCallbacks(instance).Message(flags, object_type, object, + location, message_code, + layer_prefix, message); +} + +} // namespace vulkan diff --git a/vulkan/libvulkan/debug_report.h b/vulkan/libvulkan/debug_report.h new file mode 100644 index 0000000000..5bce24085f --- /dev/null +++ b/vulkan/libvulkan/debug_report.h @@ -0,0 +1,71 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBVULKAN_DEBUG_REPORT_H +#define LIBVULKAN_DEBUG_REPORT_H 1 + +#include <shared_mutex> +#include <vulkan/vk_ext_debug_report.h> + +namespace vulkan { + +// clang-format off +VKAPI_ATTR VkResult CreateDebugReportCallbackEXT_Bottom(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +VKAPI_ATTR void DestroyDebugReportCallbackEXT_Bottom(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +VKAPI_ATTR void DebugReportMessageEXT_Bottom(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); +// clang-format on + +class DebugReportCallbackList { + public: + DebugReportCallbackList() + : head_{nullptr, 0, nullptr, nullptr, VK_NULL_HANDLE} {} + DebugReportCallbackList(const DebugReportCallbackList&) = delete; + DebugReportCallbackList& operator=(const DebugReportCallbackList&) = delete; + ~DebugReportCallbackList() = default; + + VkResult CreateCallback( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* create_info, + const VkAllocationCallbacks* allocator, + VkDebugReportCallbackEXT* callback); + void DestroyCallback(VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* allocator); + void Message(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message); + + private: + struct Node { + Node* next; + VkDebugReportFlagsEXT flags; + PFN_vkDebugReportCallbackEXT callback; + void* data; + VkDebugReportCallbackEXT driver_callback; + }; + + // TODO(jessehall): replace with std::shared_mutex when available in libc++ + std::shared_timed_mutex rwmutex_; + Node head_; +}; + +} // namespace vulkan + +#endif // LIBVULKAN_DEBUG_REPORT_H diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl index 11ec697b0b..0f1194c12b 100644 --- a/vulkan/libvulkan/dispatch.tmpl +++ b/vulkan/libvulkan/dispatch.tmpl @@ -44,6 +44,7 @@ ¶ #define VK_USE_PLATFORM_ANDROID_KHR #include <vulkan/vk_android_native_buffer.h> +#include <vulkan/vk_ext_debug_report.h> #include <vulkan/vulkan.h> ¶ namespace vulkan { @@ -155,7 +156,7 @@ PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) { const NameProc kLoaderExportProcs[] = {« // clang-format off {{range $f := SortBy (AllCommands $) "FunctionName"}} - {{if (Macro "IsFunctionSupported" $f)}} + {{if (Macro "IsExported" $f)}} {"{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}})}, {{end}} {{end}} @@ -507,11 +508,13 @@ bool LoadDriverDispatchTable(VkInstance instance, {{define "IsExported"}} {{AssertType $ "Function"}} - {{$ext := GetAnnotation $ "extension"}} - {{if $ext}} - {{Macro "IsLoaderExtension" $ext}} - {{else}} - true + {{if (Macro "IsFunctionSupported" $)}} + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + {{Macro "IsLoaderExtension" $ext}} + {{else}} + true + {{end}} {{end}} {{end}} diff --git a/vulkan/libvulkan/dispatch_gen.cpp b/vulkan/libvulkan/dispatch_gen.cpp index ebdf0dacb1..60da7493f6 100644 --- a/vulkan/libvulkan/dispatch_gen.cpp +++ b/vulkan/libvulkan/dispatch_gen.cpp @@ -224,9 +224,12 @@ const NameProc kLoaderBottomProcs[] = { // clang-format off {"vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkAcquireNextImageKHR>(AcquireNextImageKHR_Bottom))}, {"vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateAndroidSurfaceKHR>(CreateAndroidSurfaceKHR_Bottom))}, + {"vkCreateDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDebugReportCallbackEXT>(CreateDebugReportCallbackEXT_Bottom))}, {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDevice>(CreateDevice_Bottom))}, {"vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateInstance>(CreateInstance_Bottom))}, {"vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateSwapchainKHR>(CreateSwapchainKHR_Bottom))}, + {"vkDebugReportMessageEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDebugReportMessageEXT>(DebugReportMessageEXT_Bottom))}, + {"vkDestroyDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDebugReportCallbackEXT>(DestroyDebugReportCallbackEXT_Bottom))}, {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyInstance>(DestroyInstance_Bottom))}, {"vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroySurfaceKHR>(DestroySurfaceKHR_Bottom))}, {"vkDestroySwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroySwapchainKHR>(DestroySwapchainKHR_Bottom))}, @@ -283,7 +286,10 @@ PFN_vkVoidFunction Lookup(const char* name, const NameOffset kInstanceDispatchOffsets[] = { // clang-format off {"vkCreateAndroidSurfaceKHR", offsetof(InstanceDispatchTable, CreateAndroidSurfaceKHR)}, + {"vkCreateDebugReportCallbackEXT", offsetof(InstanceDispatchTable, CreateDebugReportCallbackEXT)}, {"vkCreateDevice", offsetof(InstanceDispatchTable, CreateDevice)}, + {"vkDebugReportMessageEXT", offsetof(InstanceDispatchTable, DebugReportMessageEXT)}, + {"vkDestroyDebugReportCallbackEXT", offsetof(InstanceDispatchTable, DestroyDebugReportCallbackEXT)}, {"vkDestroyInstance", offsetof(InstanceDispatchTable, DestroyInstance)}, {"vkDestroySurfaceKHR", offsetof(InstanceDispatchTable, DestroySurfaceKHR)}, {"vkEnumerateDeviceExtensionProperties", offsetof(InstanceDispatchTable, EnumerateDeviceExtensionProperties)}, @@ -558,6 +564,21 @@ bool LoadInstanceDispatchTable(VkInstance instance, ALOGE("missing instance proc: %s", "vkCreateAndroidSurfaceKHR"); success = false; } + dispatch.CreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(get_proc_addr(instance, "vkCreateDebugReportCallbackEXT")); + if (UNLIKELY(!dispatch.CreateDebugReportCallbackEXT)) { + ALOGE("missing instance proc: %s", "vkCreateDebugReportCallbackEXT"); + success = false; + } + dispatch.DestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(get_proc_addr(instance, "vkDestroyDebugReportCallbackEXT")); + if (UNLIKELY(!dispatch.DestroyDebugReportCallbackEXT)) { + ALOGE("missing instance proc: %s", "vkDestroyDebugReportCallbackEXT"); + success = false; + } + dispatch.DebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(get_proc_addr(instance, "vkDebugReportMessageEXT")); + if (UNLIKELY(!dispatch.DebugReportMessageEXT)) { + ALOGE("missing instance proc: %s", "vkDebugReportMessageEXT"); + success = false; + } // clang-format on return success; } @@ -1262,6 +1283,27 @@ bool LoadDriverDispatchTable(VkInstance instance, ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceSparseImageFormatProperties"); success = false; } + if (extensions[kEXT_debug_report]) { + dispatch.CreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(get_proc_addr(instance, "vkCreateDebugReportCallbackEXT")); + if (UNLIKELY(!dispatch.CreateDebugReportCallbackEXT)) { + ALOGE("missing driver proc: %s", "vkCreateDebugReportCallbackEXT"); + success = false; + } + } + if (extensions[kEXT_debug_report]) { + dispatch.DestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(get_proc_addr(instance, "vkDestroyDebugReportCallbackEXT")); + if (UNLIKELY(!dispatch.DestroyDebugReportCallbackEXT)) { + ALOGE("missing driver proc: %s", "vkDestroyDebugReportCallbackEXT"); + success = false; + } + } + if (extensions[kEXT_debug_report]) { + dispatch.DebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(get_proc_addr(instance, "vkDebugReportMessageEXT")); + if (UNLIKELY(!dispatch.DebugReportMessageEXT)) { + ALOGE("missing driver proc: %s", "vkDebugReportMessageEXT"); + success = false; + } + } dispatch.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(instance, "vkGetDeviceProcAddr")); if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); diff --git a/vulkan/libvulkan/dispatch_gen.h b/vulkan/libvulkan/dispatch_gen.h index 877d8aabc0..14c5da8b19 100644 --- a/vulkan/libvulkan/dispatch_gen.h +++ b/vulkan/libvulkan/dispatch_gen.h @@ -16,6 +16,7 @@ #define VK_USE_PLATFORM_ANDROID_KHR #include <vulkan/vk_android_native_buffer.h> +#include <vulkan/vk_ext_debug_report.h> #include <vulkan/vulkan.h> namespace vulkan { @@ -40,6 +41,9 @@ struct InstanceDispatchTable { PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR; PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR; PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR; + PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; + PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; + PFN_vkDebugReportMessageEXT DebugReportMessageEXT; // clang-format on }; @@ -187,6 +191,9 @@ struct DriverDispatchTable { PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; + PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; + PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; + PFN_vkDebugReportMessageEXT DebugReportMessageEXT; PFN_vkGetDeviceProcAddr GetDeviceProcAddr; PFN_vkCreateImage CreateImage; PFN_vkDestroyImage DestroyImage; diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index f302307049..90a3827e4f 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -// #define LOG_NDEBUG 0 - #include "loader.h" #include <alloca.h> #include <dirent.h> diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 079352b604..618bd930cc 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -37,7 +37,6 @@ #include <cutils/properties.h> #include <hardware/hwvulkan.h> #include <log/log.h> -#include <vulkan/vk_debug_report_lunarg.h> #include <vulkan/vulkan_loader_data.h> using namespace vulkan; @@ -249,7 +248,6 @@ struct Instance { Instance(const VkAllocationCallbacks* alloc_callbacks) : dispatch_ptr(&dispatch), handle(reinterpret_cast<VkInstance>(&dispatch_ptr)), - get_instance_proc_addr(nullptr), alloc(alloc_callbacks), num_physical_devices(0), active_layers(CallbackAllocator<LayerRef>(alloc)), @@ -267,17 +265,13 @@ struct Instance { const VkInstance handle; InstanceDispatchTable dispatch; - // TODO(jessehall): Only needed by GetInstanceProcAddr_Top for - // vkDbg*MessageCallback. Points to the outermost layer's function. Remove - // once the DEBUG_CALLBACK is integrated into the API file. - PFN_vkGetInstanceProcAddr get_instance_proc_addr; - const VkAllocationCallbacks* alloc; uint32_t num_physical_devices; VkPhysicalDevice physical_devices[kMaxPhysicalDevices]; Vector<LayerRef> active_layers; - VkDbgMsgCallback message; + VkDebugReportCallbackEXT message; + DebugReportCallbackList debug_report_callbacks; struct { VkInstance instance; @@ -476,17 +470,17 @@ void FreeAllocatedCreateInfo(T& local_create_info, } VKAPI_ATTR -VkBool32 LogDebugMessageCallback(VkFlags message_flags, - VkDbgObjectType /*obj_type*/, - uint64_t /*src_object*/, +VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT /*objectType*/, + uint64_t /*object*/, size_t /*location*/, int32_t message_code, const char* layer_prefix, const char* message, void* /*user_data*/) { - if (message_flags & VK_DBG_REPORT_ERROR_BIT) { + if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message); - } else if (message_flags & VK_DBG_REPORT_WARN_BIT) { + } else if (flags & VK_DEBUG_REPORT_WARN_BIT_EXT) { ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message); } return false; @@ -517,8 +511,9 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, InstanceExtensionSet enabled_extensions; driver_create_info.enabledExtensionCount = 0; driver_create_info.ppEnabledExtensionNames = nullptr; - size_t max_names = std::min(create_info->enabledExtensionCount, - g_driver_instance_extensions.count()); + size_t max_names = + std::min(static_cast<size_t>(create_info->enabledExtensionCount), + g_driver_instance_extensions.count()); if (max_names > 0) { const char** names = static_cast<const char**>(alloca(max_names * sizeof(char*))); @@ -598,12 +593,6 @@ PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) { PFN_vkVoidFunction pfn; if ((pfn = GetLoaderBottomProcAddr(name))) return pfn; - // TODO: Possibly move this into the instance table - // TODO: Possibly register the callbacks in the loader - if (strcmp(name, "vkDbgCreateMsgCallback") == 0 || - strcmp(name, "vkDbgDestroyMsgCallback") == 0) { - return reinterpret_cast<PFN_vkVoidFunction>(Noop); - } return nullptr; } @@ -829,11 +818,12 @@ void DestroyInstance_Bottom(VkInstance vkinstance, instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator); } if (instance.message) { - PFN_vkDbgDestroyMsgCallback DebugDestroyMessageCallback; - DebugDestroyMessageCallback = - reinterpret_cast<PFN_vkDbgDestroyMsgCallback>( - vkGetInstanceProcAddr(vkinstance, "vkDbgDestroyMsgCallback")); - DebugDestroyMessageCallback(vkinstance, instance.message); + PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback; + destroy_debug_report_callback = + reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( + vkGetInstanceProcAddr(vkinstance, + "vkDestroyDebugReportCallbackEXT")); + destroy_debug_report_callback(vkinstance, instance.message, allocator); } instance.active_layers.clear(); const VkAllocationCallbacks* alloc = instance.alloc; @@ -975,7 +965,6 @@ VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info, next_element->get_proc_addr); } } - instance->get_instance_proc_addr = next_get_proc_addr; // This is the magic call that initializes all the layer instances and // allows them to create their instance_handle -> instance_data mapping. @@ -997,7 +986,7 @@ VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info, enable_logging = enable_callback; if (enable_callback) { enable_callback = AddExtensionToCreateInfo( - local_create_info, "DEBUG_REPORT", instance->alloc); + local_create_info, "VK_EXT_debug_report", instance->alloc); } } @@ -1024,13 +1013,18 @@ VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info, } if (enable_logging) { - PFN_vkDbgCreateMsgCallback dbg_create_msg_callback; - dbg_create_msg_callback = reinterpret_cast<PFN_vkDbgCreateMsgCallback>( - GetInstanceProcAddr_Top(instance->handle, - "vkDbgCreateMsgCallback")); - dbg_create_msg_callback( - instance->handle, VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT, - LogDebugMessageCallback, nullptr, &instance->message); + const VkDebugReportCallbackCreateInfoEXT callback_create_info = { + .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT, + .flags = + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARN_BIT_EXT, + .pfnCallback = LogDebugMessageCallback, + }; + PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback = + reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( + GetInstanceProcAddr_Top(instance->handle, + "vkCreateDebugReportCallbackEXT")); + create_debug_report_callback(instance->handle, &callback_create_info, + allocator, &instance->message); } return result; @@ -1050,13 +1044,6 @@ PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance, // Otherwise, look up the handler in the instance dispatch table if ((pfn = GetDispatchProcAddr(dispatch, name))) return pfn; - // TODO(jessehall): Generate these into the instance dispatch table, and - // add loader-bottom procs for them. - if (strcmp(name, "vkDbgCreateMsgCallback") == 0 || - strcmp(name, "vkDbgDestroyMsgCallback") == 0) { - return GetDispatchParent(vkinstance) - .get_instance_proc_addr(vkinstance, name); - } // Anything not handled already must be a device-dispatched function // without a loader-top. We must return a function that will dispatch based // on the dispatchable object parameter -- which is exactly what the @@ -1134,6 +1121,14 @@ const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) { return GetDispatchParent(vkdevice).instance->alloc; } +VkInstance GetDriverInstance(VkInstance instance) { + return GetDispatchParent(instance).drv.instance; +} + +const DriverDispatchTable& GetDriverDispatch(VkInstance instance) { + return GetDispatchParent(instance).drv.dispatch; +} + const DriverDispatchTable& GetDriverDispatch(VkDevice device) { return GetDispatchParent(device).instance->drv.dispatch; } @@ -1142,4 +1137,8 @@ const DriverDispatchTable& GetDriverDispatch(VkQueue queue) { return GetDispatchParent(queue).instance->drv.dispatch; } +DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) { + return GetDispatchParent(instance).debug_report_callbacks; +} + } // namespace vulkan diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index b7edb73c40..df43f74b59 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -19,6 +19,7 @@ #include <bitset> #include "dispatch_gen.h" +#include "debug_report.h" namespace vulkan { @@ -107,8 +108,11 @@ VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice, const const VkAllocationCallbacks* GetAllocator(VkInstance instance); const VkAllocationCallbacks* GetAllocator(VkDevice device); +VkInstance GetDriverInstance(VkInstance instance); +const DriverDispatchTable& GetDriverDispatch(VkInstance instance); const DriverDispatchTable& GetDriverDispatch(VkDevice device); const DriverDispatchTable& GetDriverDispatch(VkQueue queue); +DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance); // ----------------------------------------------------------------------------- // swapchain.cpp diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 5ee2abf679..da843f1bb0 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -// #define LOG_NDEBUG 0 - #include <algorithm> #include <memory> @@ -322,9 +320,9 @@ VkResult CreateSwapchainKHR_Bottom(VkDevice device, if (!allocator) allocator = GetAllocator(device); - ALOGV_IF(create_info->imageArraySize != 1, - "Swapchain imageArraySize (%u) != 1 not supported", - create_info->imageArraySize); + ALOGV_IF(create_info->imageArrayLayers != 1, + "Swapchain imageArrayLayers (%u) != 1 not supported", + create_info->imageArrayLayers); ALOGE_IF(create_info->imageFormat != VK_FORMAT_R8G8B8A8_UNORM, "swapchain formats other than R8G8B8A8_UNORM not yet implemented"); diff --git a/vulkan/nulldrv/Android.mk b/vulkan/nulldrv/Android.mk index 2db6138917..77d47467a5 100644 --- a/vulkan/nulldrv/Android.mk +++ b/vulkan/nulldrv/Android.mk @@ -16,12 +16,13 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CLANG := true -LOCAL_CFLAGS := -std=c99 -fvisibility=hidden -fstrict-aliasing -LOCAL_CFLAGS += -DLOG_TAG=\"vknulldrv\" -LOCAL_CFLAGS += -Weverything -Werror \ +LOCAL_CFLAGS := -std=c99 -fvisibility=hidden -fstrict-aliasing \ + -DLOG_TAG=\"vknulldrv\" \ + -Weverything -Werror \ -Wno-padded \ -Wno-undef \ -Wno-zero-length-array +#LOCAL_CFLAGS += -DLOG_NDEBUG=0 LOCAL_CPPFLAGS := -std=c++1y \ -Wno-c++98-compat-pedantic \ -Wno-c99-extensions diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp index 93168ba041..1b19d9a588 100644 --- a/vulkan/nulldrv/null_driver.cpp +++ b/vulkan/nulldrv/null_driver.cpp @@ -15,13 +15,13 @@ */ #include <hardware/hwvulkan.h> +#include <vulkan/vk_ext_debug_report.h> -#include <inttypes.h> -#include <string.h> #include <algorithm> #include <array> +#include <inttypes.h> +#include <string.h> -// #define LOG_NDEBUG 0 #include <log/log.h> #include <utils/Errors.h> @@ -37,6 +37,8 @@ struct VkInstance_T { hwvulkan_dispatch_t dispatch; VkAllocationCallbacks allocator; VkPhysicalDevice_T physical_device; + uint64_t next_callback_handle; + bool debug_report_enabled; }; struct VkQueue_T { @@ -67,6 +69,7 @@ namespace { namespace HandleType { enum Enum { kBufferView, + kDebugReportCallbackEXT, kDescriptorPool, kDescriptorSet, kDescriptorSetLayout, @@ -86,7 +89,6 @@ enum Enum { kNumTypes }; } // namespace HandleType -uint64_t AllocHandle(VkDevice device, HandleType::Enum type); const VkDeviceSize kMaxDeviceMemory = VkDeviceSize(INTPTR_MAX) + 1; @@ -164,14 +166,26 @@ VkInstance_T* GetInstanceFromPhysicalDevice( offsetof(VkInstance_T, physical_device)); } +uint64_t AllocHandle(uint64_t type, uint64_t* next_handle) { + const uint64_t kHandleMask = (UINT64_C(1) << 56) - 1; + ALOGE_IF(*next_handle == kHandleMask, + "non-dispatchable handles of type=%" PRIu64 + " are about to overflow", + type); + return (UINT64_C(1) << 63) | ((type & 0x7) << 56) | + ((*next_handle)++ & kHandleMask); +} + +template <class Handle> +Handle AllocHandle(VkInstance instance, HandleType::Enum type) { + return reinterpret_cast<Handle>( + AllocHandle(type, &instance->next_callback_handle)); +} + template <class Handle> Handle AllocHandle(VkDevice device, HandleType::Enum type) { - const uint64_t kHandleMask = (UINT64_C(1) << 56) - 1; - ALOGE_IF(device->next_handle[type] == kHandleMask, - "non-dispatchable handles of type=%u are about to overflow", type); return reinterpret_cast<Handle>( - (UINT64_C(1) << 63) | ((uint64_t(type) & 0x7) << 56) | - (device->next_handle[type]++ & kHandleMask)); + AllocHandle(type, &device->next_handle[type])); } } // namespace @@ -192,15 +206,33 @@ namespace null_driver { // Global VKAPI_ATTR -VkResult EnumerateInstanceExtensionProperties(const char*, - uint32_t* count, - VkExtensionProperties*) { - *count = 0; - return VK_SUCCESS; +VkResult EnumerateInstanceExtensionProperties( + const char* layer_name, + uint32_t* count, + VkExtensionProperties* properties) { + if (layer_name) { + ALOGW( + "Driver vkEnumerateInstanceExtensionProperties shouldn't be called " + "with a layer name ('%s')", + layer_name); + *count = 0; + return VK_SUCCESS; + } + + const VkExtensionProperties kExtensions[] = { + {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; + const uint32_t kExtensionsCount = + sizeof(kExtensions) / sizeof(kExtensions[0]); + + if (!properties || *count > kExtensionsCount) + *count = kExtensionsCount; + if (properties) + std::copy(kExtensions, kExtensions + *count, properties); + return *count < kExtensionsCount ? VK_INCOMPLETE : VK_SUCCESS; } VKAPI_ATTR -VkResult CreateInstance(const VkInstanceCreateInfo* /*create_info*/, +VkResult CreateInstance(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* out_instance) { // Assume the loader provided alloc callbacks even if the app didn't. @@ -218,6 +250,16 @@ VkResult CreateInstance(const VkInstanceCreateInfo* /*create_info*/, instance->dispatch.magic = HWVULKAN_DISPATCH_MAGIC; instance->allocator = *allocator; instance->physical_device.dispatch.magic = HWVULKAN_DISPATCH_MAGIC; + instance->next_callback_handle = 0; + instance->debug_report_enabled = false; + + for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { + if (strcmp(create_info->ppEnabledExtensionNames[i], + VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) { + ALOGV("Enabling " VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + instance->debug_report_enabled = true; + } + } *out_instance = instance; return VK_SUCCESS; @@ -269,13 +311,15 @@ void GetPhysicalDeviceQueueFamilyProperties( VkPhysicalDevice, uint32_t* count, VkQueueFamilyProperties* properties) { - if (properties) { + if (!properties || *count > 1) + *count = 1; + if (properties && *count == 1) { properties->queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; properties->queueCount = 1; properties->timestampValidBits = 64; + properties->minImageTransferGranularity = VkExtent3D{1, 1, 1}; } - *count = 1; } void GetPhysicalDeviceMemoryProperties( @@ -707,6 +751,15 @@ VkResult CreateShaderModule(VkDevice device, return VK_SUCCESS; } +VkResult CreateDebugReportCallbackEXT(VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT*, + const VkAllocationCallbacks*, + VkDebugReportCallbackEXT* callback) { + *callback = AllocHandle<VkDebugReportCallbackEXT>( + instance, HandleType::kDebugReportCallbackEXT); + return VK_SUCCESS; +} + VkResult GetSwapchainGrallocUsageANDROID(VkDevice, VkFormat, VkImageUsageFlags, @@ -1081,6 +1134,12 @@ void CmdEndRenderPass(VkCommandBuffer cmdBuffer) { void CmdExecuteCommands(VkCommandBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCommandBuffer* pCmdBuffers) { } +void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) { +} + +void DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage) { +} + #pragma clang diagnostic pop // clang-format on diff --git a/vulkan/nulldrv/null_driver.tmpl b/vulkan/nulldrv/null_driver.tmpl index 66dceb25cf..57e72d3deb 100644 --- a/vulkan/nulldrv/null_driver.tmpl +++ b/vulkan/nulldrv/null_driver.tmpl @@ -51,6 +51,7 @@ #define NULLDRV_NULL_DRIVER_H 1 ¶ #include <vulkan/vk_android_native_buffer.h> +#include <vulkan/vk_ext_debug_report.h> #include <vulkan/vulkan.h> ¶ namespace null_driver {« @@ -216,6 +217,7 @@ PFN_vkVoidFunction GetInstanceProcAddr(const char* name) {« */}} {{define "IsDriverExtension"}} {{$ext := index $.Arguments 0}} - {{if eq $ext "VK_ANDROID_native_buffer"}}true + {{ if eq $ext "VK_ANDROID_native_buffer"}}true + {{else if eq $ext "VK_EXT_debug_report"}}true {{end}} {{end}} diff --git a/vulkan/nulldrv/null_driver_gen.cpp b/vulkan/nulldrv/null_driver_gen.cpp index a96c2c4cdc..c5f42b0f6f 100644 --- a/vulkan/nulldrv/null_driver_gen.cpp +++ b/vulkan/nulldrv/null_driver_gen.cpp @@ -110,6 +110,7 @@ const NameProc kInstanceProcs[] = { {"vkCreateBufferView", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateBufferView>(CreateBufferView))}, {"vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateCommandPool>(CreateCommandPool))}, {"vkCreateComputePipelines", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateComputePipelines>(CreateComputePipelines))}, + {"vkCreateDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDebugReportCallbackEXT>(CreateDebugReportCallbackEXT))}, {"vkCreateDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDescriptorPool>(CreateDescriptorPool))}, {"vkCreateDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDescriptorSetLayout>(CreateDescriptorSetLayout))}, {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDevice>(CreateDevice))}, @@ -127,9 +128,11 @@ const NameProc kInstanceProcs[] = { {"vkCreateSampler", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateSampler>(CreateSampler))}, {"vkCreateSemaphore", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateSemaphore>(CreateSemaphore))}, {"vkCreateShaderModule", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateShaderModule>(CreateShaderModule))}, + {"vkDebugReportMessageEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDebugReportMessageEXT>(DebugReportMessageEXT))}, {"vkDestroyBuffer", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyBuffer>(DestroyBuffer))}, {"vkDestroyBufferView", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyBufferView>(DestroyBufferView))}, {"vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyCommandPool>(DestroyCommandPool))}, + {"vkDestroyDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDebugReportCallbackEXT>(DestroyDebugReportCallbackEXT))}, {"vkDestroyDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDescriptorPool>(DestroyDescriptorPool))}, {"vkDestroyDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDescriptorSetLayout>(DestroyDescriptorSetLayout))}, {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDevice>(DestroyDevice))}, diff --git a/vulkan/nulldrv/null_driver_gen.h b/vulkan/nulldrv/null_driver_gen.h index 62185a516c..ddf4afb5b2 100644 --- a/vulkan/nulldrv/null_driver_gen.h +++ b/vulkan/nulldrv/null_driver_gen.h @@ -22,6 +22,7 @@ #define NULLDRV_NULL_DRIVER_H 1 #include <vulkan/vk_android_native_buffer.h> +#include <vulkan/vk_ext_debug_report.h> #include <vulkan/vulkan.h> namespace null_driver { @@ -167,6 +168,9 @@ VKAPI_ATTR void CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRender VKAPI_ATTR void CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents); VKAPI_ATTR void CmdEndRenderPass(VkCommandBuffer commandBuffer); VKAPI_ATTR void CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +VKAPI_ATTR VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +VKAPI_ATTR void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +VKAPI_ATTR void DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage); VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence); VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd); |