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)
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 93168ba..1b19d9a 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 @@
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 HandleType {
enum Enum {
kBufferView,
+ kDebugReportCallbackEXT,
kDescriptorPool,
kDescriptorSet,
kDescriptorSetLayout,
@@ -86,7 +89,6 @@
kNumTypes
};
} // namespace HandleType
-uint64_t AllocHandle(VkDevice device, HandleType::Enum type);
const VkDeviceSize kMaxDeviceMemory = VkDeviceSize(INTPTR_MAX) + 1;
@@ -164,14 +166,26 @@
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 @@
// 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 @@
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 @@
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 @@
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 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