OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #include "vk/GrVkBackendContext.h" |
| 9 #include "vk/GrVkInterface.h" |
| 10 #include "vk/GrVkUtil.h" |
| 11 |
| 12 //////////////////////////////////////////////////////////////////////////////// |
| 13 // Helper code to set up Vulkan context objects |
| 14 |
| 15 #ifdef ENABLE_VK_LAYERS |
| 16 const char* kEnabledLayerNames[] = { |
| 17 // elements of VK_LAYER_LUNARG_standard_validation |
| 18 "VK_LAYER_LUNARG_threading", |
| 19 "VK_LAYER_LUNARG_param_checker", |
| 20 "VK_LAYER_LUNARG_device_limits", |
| 21 "VK_LAYER_LUNARG_object_tracker", |
| 22 "VK_LAYER_LUNARG_image", |
| 23 "VK_LAYER_LUNARG_mem_tracker", |
| 24 "VK_LAYER_LUNARG_draw_state", |
| 25 "VK_LAYER_LUNARG_swapchain", |
| 26 "VK_LAYER_GOOGLE_unique_objects", |
| 27 // not included in standard_validation |
| 28 //"VK_LAYER_LUNARG_api_dump", |
| 29 }; |
| 30 const char* kEnabledInstanceExtensionNames[] = { |
| 31 VK_EXT_DEBUG_REPORT_EXTENSION_NAME |
| 32 }; |
| 33 |
| 34 bool verify_instance_layers() { |
| 35 // make sure we can actually use the extensions and layers above |
| 36 uint32_t extensionCount; |
| 37 VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCou
nt, nullptr); |
| 38 if (VK_SUCCESS != res) { |
| 39 return false; |
| 40 } |
| 41 VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount
]; |
| 42 res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, exten
sions); |
| 43 if (VK_SUCCESS != res) { |
| 44 return false; |
| 45 } |
| 46 int instanceExtensionsFound = 0; |
| 47 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledInstanceExtensionNames); ++j) { |
| 48 for (uint32_t i = 0; i < extensionCount; ++i) { |
| 49 if (!strncmp(extensions[i].extensionName, kEnabledInstanceExtensionN
ames[j], |
| 50 strlen(kEnabledInstanceExtensionNames[j]))) { |
| 51 ++instanceExtensionsFound; |
| 52 break; |
| 53 } |
| 54 } |
| 55 } |
| 56 delete[] extensions; |
| 57 |
| 58 uint32_t layerCount; |
| 59 res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr); |
| 60 if (VK_SUCCESS != res) { |
| 61 return false; |
| 62 } |
| 63 VkLayerProperties* layers = new VkLayerProperties[layerCount]; |
| 64 res = vkEnumerateInstanceLayerProperties(&layerCount, layers); |
| 65 if (VK_SUCCESS != res) { |
| 66 return false; |
| 67 } |
| 68 int instanceLayersFound = 0; |
| 69 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) { |
| 70 for (uint32_t i = 0; i < layerCount; ++i) { |
| 71 if (!strncmp(layers[i].layerName, kEnabledLayerNames[j], |
| 72 strlen(kEnabledLayerNames[j]))) { |
| 73 ++instanceLayersFound; |
| 74 break; |
| 75 } |
| 76 } |
| 77 } |
| 78 delete[] layers; |
| 79 |
| 80 return instanceExtensionsFound == ARRAYSIZE(kEnabledInstanceExtensionNames)
&& |
| 81 instanceLayersFound == ARRAYSIZE(kEnabledLayerNames); |
| 82 } |
| 83 |
| 84 bool verify_device_layers(VkPhysicalDevice physDev) { |
| 85 uint32_t layerCount; |
| 86 VkResult res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, nullpt
r); |
| 87 if (VK_SUCCESS != res) { |
| 88 return false; |
| 89 } |
| 90 VkLayerProperties* layers = new VkLayerProperties[layerCount]; |
| 91 res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, layers); |
| 92 if (VK_SUCCESS != res) { |
| 93 return false; |
| 94 } |
| 95 int deviceLayersFound = 0; |
| 96 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) { |
| 97 for (uint32_t i = 0; i < layerCount; ++i) { |
| 98 if (!strncmp(layers[i].layerName, kEnabledLayerNames[j], |
| 99 strlen(kEnabledLayerNames[j]))) { |
| 100 ++deviceLayersFound; |
| 101 break; |
| 102 } |
| 103 } |
| 104 } |
| 105 delete[] layers; |
| 106 |
| 107 return deviceLayersFound == ARRAYSIZE(kEnabledLayerNames); |
| 108 } |
| 109 #endif |
| 110 |
| 111 // Create the base Vulkan objects needed by the GrVkGpu object |
| 112 const GrVkBackendContext* GrVkBackendContext::Create() { |
| 113 VkPhysicalDevice physDev; |
| 114 VkDevice device; |
| 115 VkInstance inst; |
| 116 VkResult err; |
| 117 |
| 118 const VkApplicationInfo app_info = { |
| 119 VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType |
| 120 nullptr, // pNext |
| 121 "vktest", // pApplicationName |
| 122 0, // applicationVersion |
| 123 "vktest", // pEngineName |
| 124 0, // engineVerison |
| 125 kGrVkMinimumVersion, // apiVersion |
| 126 }; |
| 127 |
| 128 const char** enabledLayerNames = nullptr; |
| 129 int enabledLayerCount = 0; |
| 130 const char** enabledInstanceExtensionNames = nullptr; |
| 131 int enabledInstanceExtensionCount = 0; |
| 132 #ifdef ENABLE_VK_LAYERS |
| 133 if (verify_instance_layers()) { |
| 134 enabledLayerNames = kEnabledLayerNames; |
| 135 enabledLayerCount = ARRAYSIZE(kEnabledLayerNames); |
| 136 enabledInstanceExtensionNames = kEnabledInstanceExtensionNames; |
| 137 enabledInstanceExtensionCount = ARRAYSIZE(kEnabledInstanceExtensionNames
); |
| 138 } |
| 139 #endif |
| 140 |
| 141 const VkInstanceCreateInfo instance_create = { |
| 142 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType |
| 143 nullptr, // pNext |
| 144 0, // flags |
| 145 &app_info, // pApplicationInfo |
| 146 enabledLayerCount, // enabledLayerNameCount |
| 147 enabledLayerNames, // ppEnabledLayerNames |
| 148 enabledInstanceExtensionCount, // enabledExtensionNameCount |
| 149 enabledInstanceExtensionNames, // ppEnabledExtensionNames |
| 150 }; |
| 151 |
| 152 err = vkCreateInstance(&instance_create, nullptr, &inst); |
| 153 if (err < 0) { |
| 154 SkDebugf("vkCreateInstance failed: %d\n", err); |
| 155 SkFAIL("failing"); |
| 156 } |
| 157 |
| 158 uint32_t gpuCount; |
| 159 err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); |
| 160 if (err) { |
| 161 SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); |
| 162 SkFAIL("failing"); |
| 163 } |
| 164 SkASSERT(gpuCount > 0); |
| 165 // Just returning the first physical device instead of getting the whole arr
ay. |
| 166 // TODO: find best match for our needs |
| 167 gpuCount = 1; |
| 168 err = vkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); |
| 169 if (err) { |
| 170 SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); |
| 171 SkFAIL("failing"); |
| 172 } |
| 173 |
| 174 // query to get the initial queue props size |
| 175 uint32_t queueCount; |
| 176 vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); |
| 177 SkASSERT(queueCount >= 1); |
| 178 |
| 179 SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties)); |
| 180 // now get the actual queue props |
| 181 VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAl
loc.get(); |
| 182 |
| 183 vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); |
| 184 |
| 185 // iterate to find the graphics queue |
| 186 uint32_t graphicsQueueIndex = -1; |
| 187 for (uint32_t i = 0; i < queueCount; i++) { |
| 188 if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { |
| 189 graphicsQueueIndex = i; |
| 190 break; |
| 191 } |
| 192 } |
| 193 SkASSERT(graphicsQueueIndex < queueCount); |
| 194 |
| 195 #ifdef ENABLE_VK_LAYERS |
| 196 // unlikely that the device will have different layers than the instance, bu
t good to check |
| 197 if (!verify_device_layers(physDev)) { |
| 198 enabledLayerNames = nullptr; |
| 199 enabledLayerCount = 0; |
| 200 } |
| 201 #endif |
| 202 |
| 203 float queuePriorities[1] = { 0.0 }; |
| 204 // Here we assume no need for swapchain queue |
| 205 // If one is needed, the client will need its own setup code |
| 206 const VkDeviceQueueCreateInfo queueInfo = { |
| 207 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType |
| 208 nullptr, // pNext |
| 209 0, // VkDeviceQueueCreateFlags |
| 210 graphicsQueueIndex, // queueFamilyIndex |
| 211 1, // queueCount |
| 212 queuePriorities, // pQueuePriorities |
| 213 }; |
| 214 const VkDeviceCreateInfo deviceInfo = { |
| 215 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType |
| 216 nullptr, // pNext |
| 217 0, // VkDeviceCreateFlags |
| 218 1, // queueCreateInfoCount |
| 219 &queueInfo, // pQueueCreateInfos |
| 220 enabledLayerCount, // layerCount |
| 221 enabledLayerNames, // ppEnabledLayerNames |
| 222 0, // extensionCount |
| 223 nullptr, // ppEnabledExtensionNames |
| 224 nullptr // ppEnabledFeatures |
| 225 }; |
| 226 |
| 227 err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); |
| 228 if (err) { |
| 229 SkDebugf("CreateDevice failed: %d\n", err); |
| 230 return nullptr; |
| 231 } |
| 232 |
| 233 VkQueue queue; |
| 234 vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); |
| 235 |
| 236 GrVkBackendContext* ctx = new GrVkBackendContext(); |
| 237 ctx->fInstance = inst; |
| 238 ctx->fPhysicalDevice = physDev; |
| 239 ctx->fDevice = device; |
| 240 ctx->fQueue = queue; |
| 241 ctx->fQueueFamilyIndex = graphicsQueueIndex; |
| 242 ctx->fInterface.reset(GrVkCreateInterface(inst, physDev, device)); |
| 243 |
| 244 return ctx; |
| 245 } |
| 246 |
| 247 GrVkBackendContext::~GrVkBackendContext() { |
| 248 vkDestroyDevice(fDevice, nullptr); |
| 249 fDevice = VK_NULL_HANDLE; |
| 250 vkDestroyInstance(fInstance, nullptr); |
| 251 fInstance = VK_NULL_HANDLE; |
| 252 } |
OLD | NEW |