Read an example of configuring vulkan backend for skia called VulkanBasic.cpp, just search skia Vulkan Backend cpp, and you should find it. It advised to not use skia_gpu_test when configuring Vulkan.
I know that the wrapper MakeVulkan is returning nullptr which explains why I am getting nullptr, but I should not for my variable context. This is my code so far:
uint32_t deviceCount = 0; uint32_t queueFamilyIndex = 0; skgpu::VulkanBackendContext vkBackendContext;
// Enable the Extension for Vulkan
std::vector<const char*> instance_extensions = {
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
};
std::unique_ptr<VkInstanceCreateInfo> instance_create_info = std::make_unique<VkInstanceCreateInfo>();
instance_create_info.get()->enabledExtensionCount = static_cast<uint32_t>(instance_extensions.size());
instance_create_info.get()->ppEnabledExtensionNames = instance_extensions.data();
vkCreateInstance(instance_create_info.get(), nullptr, &vkBackendContext.fInstance);
// Check and see if the device supports vulkan
if (&vkBackendContext.fInstance == nullptr) {
printf("Device does not support vulkan!\n");
return 1;
}
// Check to see if the vulkan device is compatible
if (vkEnumeratePhysicalDevices(vkBackendContext.fInstance, &deviceCount, nullptr) != VK_SUCCESS) {
printf("No Vulkan-compatible GPUs found!\n");
return 1;
}
std::vector<VkPhysicalDevice> devices(deviceCount);
// Get the vulkan devices and loop
if (vkEnumeratePhysicalDevices(vkBackendContext.fInstance, &deviceCount, devices.data()) != VK_SUCCESS) {
printf("Could not find Physical Device!\n");
return 1;
}
for (int i = 0; i < devices.size(); i++) {
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties(devices.at(i), &props);
// Prefer discrete GPUs
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
vkBackendContext.fPhysicalDevice = devices.at(i);
queueFamilyIndex = i;
break;
}
}
// Fallback to first device if no discrete GPU found
if (vkBackendContext.fPhysicalDevice == VK_NULL_HANDLE && !devices.empty()) {
vkBackendContext.fPhysicalDevice = devices.at(0);
queueFamilyIndex = 0;
}
else return 1; // TODO: Need a catch and except statement here
// Enable all the features physical device features two
std::unique_ptr<VkPhysicalDeviceShaderDrawParametersFeatures> ext_feature = std::make_unique<VkPhysicalDeviceShaderDrawParametersFeatures>();
ext_feature.get()->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
std::unique_ptr<VkPhysicalDeviceFeatures2> physical_features2 = std::make_unique<VkPhysicalDeviceFeatures2>();
physical_features2.get()->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
physical_features2.get()->pNext = ext_feature.get();
vkGetPhysicalDeviceFeatures2(vkBackendContext.fPhysicalDevice, physical_features2.get());
vkBackendContext.fDeviceFeatures2 = physical_features2.get();
// Logic if feature is not supported
//if (features.robustBufferAccess == VK_FALSE) { return 1;}
// Enable Device For Vulkan
std::unique_ptr< VkDeviceCreateInfo> device_create_info = std::make_unique<VkDeviceCreateInfo>();
std::vector<const char*> device_extensions = {
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME
};
float queuePriority = 1.0f;
std::unique_ptr<VkDeviceQueueCreateInfo> queue_create_info = std::make_unique<VkDeviceQueueCreateInfo>();
queue_create_info.get()->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info.get()->queueFamilyIndex = queueFamilyIndex;
queue_create_info.get()->queueCount = 1;
queue_create_info.get()->pQueuePriorities = &queuePriority;
device_create_info.get()->sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.get()->queueCreateInfoCount = 1;
device_create_info.get()->pQueueCreateInfos = queue_create_info.get();
device_create_info.get()->enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
device_create_info.get()->ppEnabledExtensionNames = device_extensions.data();
if (vkCreateDevice(vkBackendContext.fPhysicalDevice, device_create_info.get(), nullptr, &vkBackendContext.fDevice) != VK_SUCCESS) {
printf("Failed to create Vulkan device!\n");
return 1;
}
vkGetDeviceQueue(vkBackendContext.fDevice, queueFamilyIndex, 0, &vkBackendContext.fQueue);
vkBackendContext.fGraphicsQueueIndex = queueFamilyIndex;
vkBackendContext.fMaxAPIVersion = VK_API_VERSION_1_0; // For sure know that I have support for this
std::unique_ptr<skgpu::VulkanExtensions> fvk(new skgpu::VulkanExtensions());
// Enable skia support
//fvk.get()->init(vkBackendContext.fGetProc, vkBackendContext.fInstance, vkBackendContext.fPhysicalDevice, 0, instance_extensions.data(), 0, device_extensions.data());
//vkBackendContext.fVkExtensions = fvk.get();
sk_sp<GrDirectContext> context = GrDirectContexts::MakeVulkan(vkBackendContext);
if (!context) {
printf("context is null!\n");
return 1;
}` I couldn't figure out how to get Proc for my vkInstance. I have done it before using a lambda function, but the result for context was still nullptr. Can someone please explain to me why and how to fix this issue?