diff options
Diffstat (limited to 'src/gpu/vk/GrVkBackendContext.cpp')
-rw-r--r-- | src/gpu/vk/GrVkBackendContext.cpp | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/src/gpu/vk/GrVkBackendContext.cpp b/src/gpu/vk/GrVkBackendContext.cpp index 5a9de04d39..3b53f83687 100644 --- a/src/gpu/vk/GrVkBackendContext.cpp +++ b/src/gpu/vk/GrVkBackendContext.cpp @@ -38,9 +38,32 @@ const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3); const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8); #endif +#define ACQUIRE_VK_PROC(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 nullptr; \ + } + // Create the base Vulkan objects needed by the GrVkGpu object const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndexPtr, - CanPresentFn canPresent) { + CanPresentFn canPresent, + GrVkInterface::GetProc getProc) { +#ifdef SK_LINK_WITH_VULKAN + if (getProc == nullptr) { + getProc = [](const char* proc_name, + VkInstance instance, VkDevice device) { + if (device != VK_NULL_HANDLE) { + return vkGetDeviceProcAddr(device, proc_name); + } + return vkGetInstanceProcAddr(instance, proc_name); + }; + } +#else + SkASSERT(getProc != nullptr); +#endif + VkPhysicalDevice physDev; VkDevice device; VkInstance inst; @@ -56,7 +79,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex kGrVkMinimumVersion, // apiVersion }; - GrVkExtensions extensions; + GrVkExtensions extensions(getProc); extensions.initInstance(kGrVkMinimumVersion); SkTArray<const char*> instanceLayerNames; @@ -92,7 +115,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex instanceExtensionNames.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); extensionFlags |= kKHR_android_surface_GrVkExtensionFlag; } -#elif defined(SK_BUILD_FOR_UNIX) +#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__) if (extensions.hasInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) { instanceExtensionNames.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); extensionFlags |= kKHR_xcb_surface_GrVkExtensionFlag; @@ -110,40 +133,50 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex instanceExtensionNames.begin(), // ppEnabledExtensionNames }; - err = vkCreateInstance(&instance_create, nullptr, &inst); + ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE); + err = grVkCreateInstance(&instance_create, nullptr, &inst); if (err < 0) { SkDebugf("vkCreateInstance failed: %d\n", err); return nullptr; } + ACQUIRE_VK_PROC(DestroyInstance, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(CreateDevice, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetDeviceQueue, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(DeviceWaitIdle, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(DestroyDevice, inst, VK_NULL_HANDLE); + uint32_t gpuCount; - err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); + err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); if (err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } SkASSERT(gpuCount > 0); // Just returning the first physical device instead of getting the whole array. // TODO: find best match for our needs gpuCount = 1; - err = vkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); + err = grVkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); if (err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } // query to get the initial queue props size uint32_t queueCount; - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); + grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); SkASSERT(queueCount >= 1); SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties)); // now get the actual queue props VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get(); - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); + grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); // iterate to find the graphics queue uint32_t graphicsQueueIndex = queueCount; @@ -190,7 +223,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex // query to get the physical device properties VkPhysicalDeviceFeatures deviceFeatures; - vkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); + grVkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); // this looks like it would slow things down, // and we can't depend on it on all platforms deviceFeatures.robustBufferAccess = VK_FALSE; @@ -242,15 +275,25 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex &deviceFeatures // ppEnabledFeatures }; - err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); + err = grVkCreateDevice(physDev, &deviceInfo, nullptr, &device); if (err) { SkDebugf("CreateDevice failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); + return nullptr; + } + + auto interface = + sk_make_sp<GrVkInterface>(getProc, inst, device, extensionFlags); + if (!interface->validate(extensionFlags)) { + SkDebugf("Vulkan interface validation failed\n"); + grVkDeviceWaitIdle(device); + grVkDestroyDevice(device, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } VkQueue queue; - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); + grVkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); GrVkBackendContext* ctx = new GrVkBackendContext(); ctx->fInstance = inst; @@ -261,15 +304,19 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex ctx->fMinAPIVersion = kGrVkMinimumVersion; ctx->fExtensions = extensionFlags; ctx->fFeatures = featureFlags; - ctx->fInterface.reset(GrVkCreateInterface(inst, device, extensionFlags)); + ctx->fInterface.reset(interface.release()); return ctx; } GrVkBackendContext::~GrVkBackendContext() { - vkDeviceWaitIdle(fDevice); - vkDestroyDevice(fDevice, nullptr); + if (fInterface == nullptr) { + return; + } + + fInterface->fFunctions.fDeviceWaitIdle(fDevice); + fInterface->fFunctions.fDestroyDevice(fDevice, nullptr); fDevice = VK_NULL_HANDLE; - vkDestroyInstance(fInstance, nullptr); + fInterface->fFunctions.fDestroyInstance(fInstance, nullptr); fInstance = VK_NULL_HANDLE; } |