aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk/GrVkBackendContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/vk/GrVkBackendContext.cpp')
-rw-r--r--src/gpu/vk/GrVkBackendContext.cpp83
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;
}