diff options
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 54 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 5 | ||||
-rw-r--r-- | tools/gpu/vk/VkTestContext.cpp | 17 | ||||
-rw-r--r-- | tools/gpu/vk/VkTestContext.h | 6 | ||||
-rw-r--r-- | tools/gpu/vk/VkTestUtils.cpp | 101 | ||||
-rw-r--r-- | tools/gpu/vk/VkTestUtils.h | 1 | ||||
-rw-r--r-- | tools/sk_app/VulkanWindowContext.cpp | 45 | ||||
-rw-r--r-- | tools/sk_app/VulkanWindowContext.h | 1 |
8 files changed, 101 insertions, 129 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 65225d919d..0b160a6ade 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -49,6 +49,30 @@ #define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) #define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) +#ifdef SK_ENABLE_VK_LAYERS +VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData) { + if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); + return VK_TRUE; // skip further layers + } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); + } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { + SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); + } else { + SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); + } + return VK_FALSE; +} +#endif + sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext, const GrContextOptions& options, GrContext* context) { if (backendContext.fInstance == VK_NULL_HANDLE || @@ -78,6 +102,27 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, , fResourceProvider(this) , fDisconnected(false) { SkASSERT(!backendContext.fOwnsInstanceAndDevice); +#ifdef SK_ENABLE_VK_LAYERS + fCallback = VK_NULL_HANDLE; + if (backendContext.fExtensions & kEXT_debug_report_GrVkExtensionFlag) { + // Setup callback creation information + VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; + callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + callbackCreateInfo.pNext = nullptr; + callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | + VK_DEBUG_REPORT_WARNING_BIT_EXT | + //VK_DEBUG_REPORT_INFORMATION_BIT_EXT | + //VK_DEBUG_REPORT_DEBUG_BIT_EXT | + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + callbackCreateInfo.pfnCallback = &DebugReportCallback; + callbackCreateInfo.pUserData = nullptr; + + // Register the callback + GR_VK_CALL_ERRCHECK(this->vkInterface(), + CreateDebugReportCallbackEXT(backendContext.fInstance, + &callbackCreateInfo, nullptr, &fCallback)); + } +#endif if (!fMemoryAllocator) { // We were not given a memory allocator at creation @@ -159,6 +204,12 @@ void GrVkGpu::destroyResources() { VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); } +#ifdef SK_ENABLE_VK_LAYERS + if (fCallback) { + VK_CALL(DestroyDebugReportCallbackEXT(fInstance, fCallback, nullptr)); + } +#endif + fMemoryAllocator.reset(); fQueue = VK_NULL_HANDLE; @@ -194,6 +245,9 @@ void GrVkGpu::disconnect(DisconnectType type) { } fSemaphoresToWaitOn.reset(); fSemaphoresToSignal.reset(); +#ifdef SK_ENABLE_VK_LAYERS + fCallback = VK_NULL_HANDLE; +#endif fCurrentCmdBuffer = nullptr; fCmdPool = VK_NULL_HANDLE; fDisconnected = true; diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 266c916cad..f506d28b0e 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -244,6 +244,11 @@ private: GrVkCopyManager fCopyManager; +#ifdef SK_ENABLE_VK_LAYERS + // For reporting validation layer errors + VkDebugReportCallbackEXT fCallback; +#endif + // compiler used for compiling sksl into spirv. We only want to create the compiler once since // there is significant overhead to the first compile of any compiler. SkSL::Compiler* fCompiler; diff --git a/tools/gpu/vk/VkTestContext.cpp b/tools/gpu/vk/VkTestContext.cpp index 32a1205107..592fb0f7b0 100644 --- a/tools/gpu/vk/VkTestContext.cpp +++ b/tools/gpu/vk/VkTestContext.cpp @@ -112,7 +112,6 @@ public: static VkTestContext* Create(VkTestContext* sharedContext) { GrVkBackendContext backendContext; bool ownsContext = true; - VkDebugReportCallbackEXT debugCallback = VK_NULL_HANDLE; if (sharedContext) { backendContext = sharedContext->getVkBackendContext(); // We always delete the parent context last so make sure the child does not think they @@ -124,12 +123,11 @@ public: if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) { return nullptr; } - if (!sk_gpu_test::CreateVkBackendContext(instProc, devProc, &backendContext, - &debugCallback)) { + if (!sk_gpu_test::CreateVkBackendContext(instProc, devProc, &backendContext)) { return nullptr; } } - return new VkTestContextImpl(backendContext, ownsContext, debugCallback); + return new VkTestContextImpl(backendContext, ownsContext); } ~VkTestContextImpl() override { this->teardown(); } @@ -152,20 +150,13 @@ protected: if (fOwnsContext) { GR_VK_CALL(this->vk(), DeviceWaitIdle(fVk.fDevice)); GR_VK_CALL(this->vk(), DestroyDevice(fVk.fDevice, nullptr)); -#ifdef SK_ENABLE_VK_LAYERS - if (fDebugCallback != VK_NULL_HANDLE) { - GR_VK_CALL(this->vk(), DestroyDebugReportCallbackEXT(fVk.fInstance, fDebugCallback, - nullptr)); - } -#endif GR_VK_CALL(this->vk(), DestroyInstance(fVk.fInstance, nullptr)); } } private: - VkTestContextImpl(const GrVkBackendContext& backendContext, bool ownsContext, - VkDebugReportCallbackEXT debugCallback) - : VkTestContext(backendContext, ownsContext, debugCallback) { + VkTestContextImpl(const GrVkBackendContext& backendContext, bool ownsContext) + : VkTestContext(backendContext, ownsContext) { fFenceSync.reset(new VkFenceSync(fVk.fInterface, fVk.fDevice, fVk.fQueue, fVk.fGraphicsQueueIndex)); } diff --git a/tools/gpu/vk/VkTestContext.h b/tools/gpu/vk/VkTestContext.h index 920f53534e..0e62cc0b8c 100644 --- a/tools/gpu/vk/VkTestContext.h +++ b/tools/gpu/vk/VkTestContext.h @@ -26,13 +26,11 @@ public: const GrVkInterface* vk() const { return fVk.fInterface.get(); } protected: - VkTestContext(const GrVkBackendContext& vk, bool ownsContext, - VkDebugReportCallbackEXT debugCallback) - : fVk(vk), fOwnsContext(ownsContext), fDebugCallback(debugCallback) {} + VkTestContext(const GrVkBackendContext& vk, bool ownsContext) + : fVk(vk), fOwnsContext(ownsContext) {} GrVkBackendContext fVk; bool fOwnsContext; - VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE; private: typedef TestContext INHERITED; diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp index e6ddda2fce..927f4fbe82 100644 --- a/tools/gpu/vk/VkTestUtils.cpp +++ b/tools/gpu/vk/VkTestUtils.cpp @@ -82,60 +82,12 @@ const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8); reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \ if (grVk##name == nullptr) { \ SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ - if (device != VK_NULL_HANDLE) { \ - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \ - } \ return false; \ } -#ifdef SK_ENABLE_VK_LAYERS -VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserData) { - if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); - return VK_TRUE; // skip further layers - } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); - } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); - } else { - SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); - } - return VK_FALSE; -} -#endif - -#define ACQUIRE_VK_PROC_LOCAL(name, instance, device) \ - PFN_vk##name grVk##name = \ - reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \ - if (grVk##name == nullptr) { \ - SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ - return; \ - } - -static void destroy_instance(GrVkInterface::GetProc getProc, VkInstance inst, - VkDebugReportCallbackEXT* debugCallback, - bool hasDebugExtension) { - if (hasDebugExtension && *debugCallback != VK_NULL_HANDLE) { - ACQUIRE_VK_PROC_LOCAL(DestroyDebugReportCallbackEXT, inst, VK_NULL_HANDLE); - grVkDestroyDebugReportCallbackEXT(inst, *debugCallback, nullptr); - *debugCallback = VK_NULL_HANDLE; - } - ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst, VK_NULL_HANDLE); - grVkDestroyInstance(inst, nullptr); -} - bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstanceProc, const GrVkInterface::GetDeviceProc& getDeviceProc, GrVkBackendContext* ctx, - VkDebugReportCallbackEXT* debugCallback, uint32_t* presentQueueIndexPtr, CanPresentFn canPresent) { auto getProc = [&getInstanceProc, &getDeviceProc](const char* proc_name, @@ -167,7 +119,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro SkTArray<const char*> instanceLayerNames; SkTArray<const char*> instanceExtensionNames; uint32_t extensionFlags = 0; - bool hasDebugExtension = false; #ifdef SK_ENABLE_VK_LAYERS for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { if (extensions.hasInstanceLayer(kDebugLayerNames[i])) { @@ -177,7 +128,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro if (extensions.hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); extensionFlags |= kEXT_debug_report_GrVkExtensionFlag; - hasDebugExtension = true; } #endif @@ -224,32 +174,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro return false; } -#ifdef SK_ENABLE_VK_LAYERS - *debugCallback = VK_NULL_HANDLE; - for (int i = 0; i < instanceExtensionNames.count() && !hasDebugExtension; ++i) { - if (!strcmp(instanceExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { - hasDebugExtension = true; - } - } - if (hasDebugExtension) { - // Setup callback creation information - VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; - callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; - callbackCreateInfo.pNext = nullptr; - callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | - VK_DEBUG_REPORT_WARNING_BIT_EXT | - // VK_DEBUG_REPORT_INFORMATION_BIT_EXT | - // VK_DEBUG_REPORT_DEBUG_BIT_EXT | - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; - callbackCreateInfo.pfnCallback = &DebugReportCallback; - callbackCreateInfo.pUserData = nullptr; - - ACQUIRE_VK_PROC(CreateDebugReportCallbackEXT, inst, VK_NULL_HANDLE); - // Register the callback - grVkCreateDebugReportCallbackEXT(inst, &callbackCreateInfo, nullptr, debugCallback); - } -#endif - ACQUIRE_VK_PROC(DestroyInstance, inst, VK_NULL_HANDLE); ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE); ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE); @@ -263,12 +187,12 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); if (err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } if (!gpuCount) { SkDebugf("vkEnumeratePhysicalDevices returned no supported devices.\n"); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } // Just returning the first physical device instead of getting the whole array. @@ -278,7 +202,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro // VK_INCOMPLETE is returned when the count we provide is less than the total device count. if (err && VK_INCOMPLETE != err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } @@ -287,7 +211,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); if (!queueCount) { SkDebugf("vkGetPhysicalDeviceQueueFamilyProperties returned no queues.\n"); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } @@ -307,7 +231,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro } if (graphicsQueueIndex == queueCount) { SkDebugf("Could not find any supported graphics queues.\n"); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } @@ -322,7 +246,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro } if (presentQueueIndex == queueCount) { SkDebugf("Could not find any supported present queues.\n"); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } *presentQueueIndexPtr = presentQueueIndex; @@ -336,6 +260,13 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro SkTArray<const char*> deviceLayerNames; SkTArray<const char*> deviceExtensionNames; +#ifdef SK_ENABLE_VK_LAYERS + for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { + if (extensions.hasDeviceLayer(kDebugLayerNames[i])) { + deviceLayerNames.push_back(kDebugLayerNames[i]); + } + } +#endif if (extensions.hasDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); extensionFlags |= kKHR_swapchain_GrVkExtensionFlag; @@ -402,7 +333,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro err = grVkCreateDevice(physDev, &deviceInfo, nullptr, &device); if (err) { SkDebugf("CreateDevice failed: %d\n", err); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } @@ -412,7 +343,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro SkDebugf("Vulkan interface validation failed\n"); grVkDeviceWaitIdle(device); grVkDestroyDevice(device, nullptr); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); + grVkDestroyInstance(inst, nullptr); return false; } @@ -431,6 +362,8 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro ctx->fOwnsInstanceAndDevice = false; return true; + + } } diff --git a/tools/gpu/vk/VkTestUtils.h b/tools/gpu/vk/VkTestUtils.h index 0046d6dba1..30471a78c0 100644 --- a/tools/gpu/vk/VkTestUtils.h +++ b/tools/gpu/vk/VkTestUtils.h @@ -26,7 +26,6 @@ namespace sk_gpu_test { bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstanceProc, const GrVkInterface::GetDeviceProc& getDeviceProc, GrVkBackendContext* ctx, - VkDebugReportCallbackEXT* debugCallback, uint32_t* presentQueueIndexPtr = nullptr, CanPresentFn canPresent = CanPresentFn()); } diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp index 8e0749ec1b..411f114e63 100644 --- a/tools/sk_app/VulkanWindowContext.cpp +++ b/tools/sk_app/VulkanWindowContext.cpp @@ -51,8 +51,7 @@ void VulkanWindowContext::initializeContext() { GrVkBackendContext backendContext; if (!sk_gpu_test::CreateVkBackendContext(fGetInstanceProcAddr, fGetDeviceProcAddr, - &backendContext, &fDebugCallback, - &fPresentQueueIndex, fCanPresentFn)) { + &backendContext, &fPresentQueueIndex, fCanPresentFn)) { return; } @@ -410,26 +409,28 @@ VulkanWindowContext::~VulkanWindowContext() { } void VulkanWindowContext::destroyContext() { - if (this->isValid()) { - fQueueWaitIdle(fPresentQueue); - fDeviceWaitIdle(fDevice); + if (!this->isValid()) { + return; + } - this->destroyBuffers(); + fQueueWaitIdle(fPresentQueue); + fDeviceWaitIdle(fDevice); - if (VK_NULL_HANDLE != fCommandPool) { - GR_VK_CALL(fInterface, DestroyCommandPool(fDevice, fCommandPool, nullptr)); - fCommandPool = VK_NULL_HANDLE; - } + this->destroyBuffers(); - if (VK_NULL_HANDLE != fSwapchain) { - fDestroySwapchainKHR(fDevice, fSwapchain, nullptr); - fSwapchain = VK_NULL_HANDLE; - } + if (VK_NULL_HANDLE != fCommandPool) { + GR_VK_CALL(fInterface, DestroyCommandPool(fDevice, fCommandPool, nullptr)); + fCommandPool = VK_NULL_HANDLE; + } - if (VK_NULL_HANDLE != fSurface) { - fDestroySurfaceKHR(fInstance, fSurface, nullptr); - fSurface = VK_NULL_HANDLE; - } + if (VK_NULL_HANDLE != fSwapchain) { + fDestroySwapchainKHR(fDevice, fSwapchain, nullptr); + fSwapchain = VK_NULL_HANDLE; + } + + if (VK_NULL_HANDLE != fSurface) { + fDestroySurfaceKHR(fInstance, fSurface, nullptr); + fSurface = VK_NULL_HANDLE; } fContext.reset(); @@ -439,14 +440,6 @@ void VulkanWindowContext::destroyContext() { fDestroyDevice(fDevice, nullptr); fDevice = VK_NULL_HANDLE; } - -#ifdef SK_ENABLE_VK_LAYERS - if (fDebugCallback != VK_NULL_HANDLE) { - GR_VK_CALL(fInterface, DestroyDebugReportCallbackEXT(fInstance, fDebugCallback, - nullptr)); - } -#endif - fPhysicalDevice = VK_NULL_HANDLE; if (VK_NULL_HANDLE != fInstance) { diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h index 3d9687b674..79298f6b38 100644 --- a/tools/sk_app/VulkanWindowContext.h +++ b/tools/sk_app/VulkanWindowContext.h @@ -68,7 +68,6 @@ private: VkInstance fInstance = VK_NULL_HANDLE; VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE; VkDevice fDevice = VK_NULL_HANDLE; - VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE; // simple wrapper class that exists only to initialize a pointer to NULL template <typename FNPTR_TYPE> class VkPtr { |