| Index: src/gpu/vk/GrVkBackendContext.cpp
|
| diff --git a/src/gpu/vk/GrVkBackendContext.cpp b/src/gpu/vk/GrVkBackendContext.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c169c620a133787fe022420ccdc788e8942d7bc0
|
| --- /dev/null
|
| +++ b/src/gpu/vk/GrVkBackendContext.cpp
|
| @@ -0,0 +1,252 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "vk/GrVkBackendContext.h"
|
| +#include "vk/GrVkInterface.h"
|
| +#include "vk/GrVkUtil.h"
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// Helper code to set up Vulkan context objects
|
| +
|
| +#ifdef ENABLE_VK_LAYERS
|
| +const char* kEnabledLayerNames[] = {
|
| + // elements of VK_LAYER_LUNARG_standard_validation
|
| + "VK_LAYER_LUNARG_threading",
|
| + "VK_LAYER_LUNARG_param_checker",
|
| + "VK_LAYER_LUNARG_device_limits",
|
| + "VK_LAYER_LUNARG_object_tracker",
|
| + "VK_LAYER_LUNARG_image",
|
| + "VK_LAYER_LUNARG_mem_tracker",
|
| + "VK_LAYER_LUNARG_draw_state",
|
| + "VK_LAYER_LUNARG_swapchain",
|
| + "VK_LAYER_GOOGLE_unique_objects",
|
| + // not included in standard_validation
|
| + //"VK_LAYER_LUNARG_api_dump",
|
| +};
|
| +const char* kEnabledInstanceExtensionNames[] = {
|
| + VK_EXT_DEBUG_REPORT_EXTENSION_NAME
|
| +};
|
| +
|
| +bool verify_instance_layers() {
|
| + // make sure we can actually use the extensions and layers above
|
| + uint32_t extensionCount;
|
| + VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
|
| + res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + int instanceExtensionsFound = 0;
|
| + for (uint32_t j = 0; j < ARRAYSIZE(kEnabledInstanceExtensionNames); ++j) {
|
| + for (uint32_t i = 0; i < extensionCount; ++i) {
|
| + if (!strncmp(extensions[i].extensionName, kEnabledInstanceExtensionNames[j],
|
| + strlen(kEnabledInstanceExtensionNames[j]))) {
|
| + ++instanceExtensionsFound;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + delete[] extensions;
|
| +
|
| + uint32_t layerCount;
|
| + res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + VkLayerProperties* layers = new VkLayerProperties[layerCount];
|
| + res = vkEnumerateInstanceLayerProperties(&layerCount, layers);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + int instanceLayersFound = 0;
|
| + for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) {
|
| + for (uint32_t i = 0; i < layerCount; ++i) {
|
| + if (!strncmp(layers[i].layerName, kEnabledLayerNames[j],
|
| + strlen(kEnabledLayerNames[j]))) {
|
| + ++instanceLayersFound;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + delete[] layers;
|
| +
|
| + return instanceExtensionsFound == ARRAYSIZE(kEnabledInstanceExtensionNames) &&
|
| + instanceLayersFound == ARRAYSIZE(kEnabledLayerNames);
|
| +}
|
| +
|
| +bool verify_device_layers(VkPhysicalDevice physDev) {
|
| + uint32_t layerCount;
|
| + VkResult res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + VkLayerProperties* layers = new VkLayerProperties[layerCount];
|
| + res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, layers);
|
| + if (VK_SUCCESS != res) {
|
| + return false;
|
| + }
|
| + int deviceLayersFound = 0;
|
| + for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) {
|
| + for (uint32_t i = 0; i < layerCount; ++i) {
|
| + if (!strncmp(layers[i].layerName, kEnabledLayerNames[j],
|
| + strlen(kEnabledLayerNames[j]))) {
|
| + ++deviceLayersFound;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + delete[] layers;
|
| +
|
| + return deviceLayersFound == ARRAYSIZE(kEnabledLayerNames);
|
| +}
|
| +#endif
|
| +
|
| +// Create the base Vulkan objects needed by the GrVkGpu object
|
| +const GrVkBackendContext* GrVkBackendContext::Create() {
|
| + VkPhysicalDevice physDev;
|
| + VkDevice device;
|
| + VkInstance inst;
|
| + VkResult err;
|
| +
|
| + const VkApplicationInfo app_info = {
|
| + VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
|
| + nullptr, // pNext
|
| + "vktest", // pApplicationName
|
| + 0, // applicationVersion
|
| + "vktest", // pEngineName
|
| + 0, // engineVerison
|
| + kGrVkMinimumVersion, // apiVersion
|
| + };
|
| +
|
| + const char** enabledLayerNames = nullptr;
|
| + int enabledLayerCount = 0;
|
| + const char** enabledInstanceExtensionNames = nullptr;
|
| + int enabledInstanceExtensionCount = 0;
|
| +#ifdef ENABLE_VK_LAYERS
|
| + if (verify_instance_layers()) {
|
| + enabledLayerNames = kEnabledLayerNames;
|
| + enabledLayerCount = ARRAYSIZE(kEnabledLayerNames);
|
| + enabledInstanceExtensionNames = kEnabledInstanceExtensionNames;
|
| + enabledInstanceExtensionCount = ARRAYSIZE(kEnabledInstanceExtensionNames);
|
| + }
|
| +#endif
|
| +
|
| + const VkInstanceCreateInfo instance_create = {
|
| + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
|
| + nullptr, // pNext
|
| + 0, // flags
|
| + &app_info, // pApplicationInfo
|
| + enabledLayerCount, // enabledLayerNameCount
|
| + enabledLayerNames, // ppEnabledLayerNames
|
| + enabledInstanceExtensionCount, // enabledExtensionNameCount
|
| + enabledInstanceExtensionNames, // ppEnabledExtensionNames
|
| + };
|
| +
|
| + err = vkCreateInstance(&instance_create, nullptr, &inst);
|
| + if (err < 0) {
|
| + SkDebugf("vkCreateInstance failed: %d\n", err);
|
| + SkFAIL("failing");
|
| + }
|
| +
|
| + uint32_t gpuCount;
|
| + err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
|
| + if (err) {
|
| + SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
|
| + SkFAIL("failing");
|
| + }
|
| + 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);
|
| + if (err) {
|
| + SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
|
| + SkFAIL("failing");
|
| + }
|
| +
|
| + // query to get the initial queue props size
|
| + uint32_t queueCount;
|
| + vkGetPhysicalDeviceQueueFamilyProperties(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);
|
| +
|
| + // iterate to find the graphics queue
|
| + uint32_t graphicsQueueIndex = -1;
|
| + for (uint32_t i = 0; i < queueCount; i++) {
|
| + if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
| + graphicsQueueIndex = i;
|
| + break;
|
| + }
|
| + }
|
| + SkASSERT(graphicsQueueIndex < queueCount);
|
| +
|
| +#ifdef ENABLE_VK_LAYERS
|
| + // unlikely that the device will have different layers than the instance, but good to check
|
| + if (!verify_device_layers(physDev)) {
|
| + enabledLayerNames = nullptr;
|
| + enabledLayerCount = 0;
|
| + }
|
| +#endif
|
| +
|
| + float queuePriorities[1] = { 0.0 };
|
| + // Here we assume no need for swapchain queue
|
| + // If one is needed, the client will need its own setup code
|
| + const VkDeviceQueueCreateInfo queueInfo = {
|
| + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
|
| + nullptr, // pNext
|
| + 0, // VkDeviceQueueCreateFlags
|
| + graphicsQueueIndex, // queueFamilyIndex
|
| + 1, // queueCount
|
| + queuePriorities, // pQueuePriorities
|
| + };
|
| + const VkDeviceCreateInfo deviceInfo = {
|
| + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
|
| + nullptr, // pNext
|
| + 0, // VkDeviceCreateFlags
|
| + 1, // queueCreateInfoCount
|
| + &queueInfo, // pQueueCreateInfos
|
| + enabledLayerCount, // layerCount
|
| + enabledLayerNames, // ppEnabledLayerNames
|
| + 0, // extensionCount
|
| + nullptr, // ppEnabledExtensionNames
|
| + nullptr // ppEnabledFeatures
|
| + };
|
| +
|
| + err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device);
|
| + if (err) {
|
| + SkDebugf("CreateDevice failed: %d\n", err);
|
| + return nullptr;
|
| + }
|
| +
|
| + VkQueue queue;
|
| + vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue);
|
| +
|
| + GrVkBackendContext* ctx = new GrVkBackendContext();
|
| + ctx->fInstance = inst;
|
| + ctx->fPhysicalDevice = physDev;
|
| + ctx->fDevice = device;
|
| + ctx->fQueue = queue;
|
| + ctx->fQueueFamilyIndex = graphicsQueueIndex;
|
| + ctx->fInterface.reset(GrVkCreateInterface(inst, physDev, device));
|
| +
|
| + return ctx;
|
| +}
|
| +
|
| +GrVkBackendContext::~GrVkBackendContext() {
|
| + vkDestroyDevice(fDevice, nullptr);
|
| + fDevice = VK_NULL_HANDLE;
|
| + vkDestroyInstance(fInstance, nullptr);
|
| + fInstance = VK_NULL_HANDLE;
|
| +}
|
|
|