| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "vk/GrVkBackendContext.h" | 8 #include "vk/GrVkBackendContext.h" |
| 9 #include "vk/GrVkExtensions.h" |
| 9 #include "vk/GrVkInterface.h" | 10 #include "vk/GrVkInterface.h" |
| 10 #include "vk/GrVkUtil.h" | 11 #include "vk/GrVkUtil.h" |
| 11 | 12 |
| 12 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
| 13 // Helper code to set up Vulkan context objects | 14 // Helper code to set up Vulkan context objects |
| 14 | 15 |
| 15 #ifdef ENABLE_VK_LAYERS | 16 #ifdef ENABLE_VK_LAYERS |
| 16 const char* kEnabledLayerNames[] = { | 17 const char* kDebugLayerNames[] = { |
| 17 // elements of VK_LAYER_LUNARG_standard_validation | 18 // elements of VK_LAYER_LUNARG_standard_validation |
| 18 "VK_LAYER_LUNARG_threading", | 19 "VK_LAYER_LUNARG_threading", |
| 19 "VK_LAYER_LUNARG_param_checker", | 20 "VK_LAYER_LUNARG_param_checker", |
| 20 "VK_LAYER_LUNARG_device_limits", | 21 "VK_LAYER_LUNARG_device_limits", |
| 21 "VK_LAYER_LUNARG_object_tracker", | 22 "VK_LAYER_LUNARG_object_tracker", |
| 22 "VK_LAYER_LUNARG_image", | 23 "VK_LAYER_LUNARG_image", |
| 23 "VK_LAYER_LUNARG_mem_tracker", | 24 "VK_LAYER_LUNARG_mem_tracker", |
| 24 "VK_LAYER_LUNARG_draw_state", | 25 "VK_LAYER_LUNARG_draw_state", |
| 25 "VK_LAYER_LUNARG_swapchain", | 26 "VK_LAYER_LUNARG_swapchain", |
| 26 "VK_LAYER_GOOGLE_unique_objects", | 27 "VK_LAYER_GOOGLE_unique_objects", |
| 27 // not included in standard_validation | 28 // not included in standard_validation |
| 28 //"VK_LAYER_LUNARG_api_dump", | 29 //"VK_LAYER_LUNARG_api_dump", |
| 30 //"VK_LAYER_LUNARG_vktrace", |
| 31 //"VK_LAYER_LUNARG_screenshot", |
| 29 }; | 32 }; |
| 30 const char* kEnabledInstanceExtensionNames[] = { | 33 #endif |
| 31 VK_EXT_DEBUG_REPORT_EXTENSION_NAME | |
| 32 }; | |
| 33 | 34 |
| 34 bool verify_instance_layers() { | 35 // the minimum version of Vulkan supported |
| 35 // make sure we can actually use the extensions and layers above | 36 const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3); |
| 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 | 37 |
| 111 // Create the base Vulkan objects needed by the GrVkGpu object | 38 // Create the base Vulkan objects needed by the GrVkGpu object |
| 112 const GrVkBackendContext* GrVkBackendContext::Create() { | 39 const GrVkBackendContext* GrVkBackendContext::Create() { |
| 113 VkPhysicalDevice physDev; | 40 VkPhysicalDevice physDev; |
| 114 VkDevice device; | 41 VkDevice device; |
| 115 VkInstance inst; | 42 VkInstance inst; |
| 116 VkResult err; | 43 VkResult err; |
| 117 | 44 |
| 118 const VkApplicationInfo app_info = { | 45 const VkApplicationInfo app_info = { |
| 119 VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType | 46 VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType |
| 120 nullptr, // pNext | 47 nullptr, // pNext |
| 121 "vktest", // pApplicationName | 48 "vktest", // pApplicationName |
| 122 0, // applicationVersion | 49 0, // applicationVersion |
| 123 "vktest", // pEngineName | 50 "vktest", // pEngineName |
| 124 0, // engineVerison | 51 0, // engineVerison |
| 125 kGrVkMinimumVersion, // apiVersion | 52 kGrVkMinimumVersion, // apiVersion |
| 126 }; | 53 }; |
| 127 | 54 |
| 128 const char** enabledLayerNames = nullptr; | 55 GrVkExtensions extensions; |
| 129 int enabledLayerCount = 0; | 56 extensions.initInstance(kGrVkMinimumVersion); |
| 130 const char** enabledInstanceExtensionNames = nullptr; | 57 |
| 131 int enabledInstanceExtensionCount = 0; | 58 SkTArray<const char*> instanceLayerNames; |
| 59 SkTArray<const char*> instanceExtensionNames; |
| 60 uint32_t extensionFlags = 0; |
| 132 #ifdef ENABLE_VK_LAYERS | 61 #ifdef ENABLE_VK_LAYERS |
| 133 if (verify_instance_layers()) { | 62 for (int i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { |
| 134 enabledLayerNames = kEnabledLayerNames; | 63 if (extensions.hasInstanceLayer(kDebugLayerNames[i])) { |
| 135 enabledLayerCount = ARRAYSIZE(kEnabledLayerNames); | 64 instanceLayerNames.push_back(kDebugLayerNames[i]); |
| 136 enabledInstanceExtensionNames = kEnabledInstanceExtensionNames; | 65 } |
| 137 enabledInstanceExtensionCount = ARRAYSIZE(kEnabledInstanceExtensionNames
); | 66 } |
| 67 if (extensions.hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { |
| 68 instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); |
| 69 extensionFlags |= kEXT_debug_report_GrVkExtensionFlag; |
| 138 } | 70 } |
| 139 #endif | 71 #endif |
| 140 | 72 |
| 141 const VkInstanceCreateInfo instance_create = { | 73 const VkInstanceCreateInfo instance_create = { |
| 142 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType | 74 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType |
| 143 nullptr, // pNext | 75 nullptr, // pNext |
| 144 0, // flags | 76 0, // flags |
| 145 &app_info, // pApplicationInfo | 77 &app_info, // pApplicationInfo |
| 146 enabledLayerCount, // enabledLayerNameCount | 78 instanceLayerNames.count(), // enabledLayerNameCount |
| 147 enabledLayerNames, // ppEnabledLayerNames | 79 instanceLayerNames.begin(), // ppEnabledLayerNames |
| 148 enabledInstanceExtensionCount, // enabledExtensionNameCount | 80 instanceExtensionNames.count(), // enabledExtensionNameCount |
| 149 enabledInstanceExtensionNames, // ppEnabledExtensionNames | 81 instanceExtensionNames.begin(), // ppEnabledExtensionNames |
| 150 }; | 82 }; |
| 151 | 83 |
| 152 err = vkCreateInstance(&instance_create, nullptr, &inst); | 84 err = vkCreateInstance(&instance_create, nullptr, &inst); |
| 153 if (err < 0) { | 85 if (err < 0) { |
| 154 SkDebugf("vkCreateInstance failed: %d\n", err); | 86 SkDebugf("vkCreateInstance failed: %d\n", err); |
| 155 SkFAIL("failing"); | 87 SkFAIL("failing"); |
| 156 } | 88 } |
| 157 | 89 |
| 158 uint32_t gpuCount; | 90 uint32_t gpuCount; |
| 159 err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); | 91 err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 185 // iterate to find the graphics queue | 117 // iterate to find the graphics queue |
| 186 uint32_t graphicsQueueIndex = -1; | 118 uint32_t graphicsQueueIndex = -1; |
| 187 for (uint32_t i = 0; i < queueCount; i++) { | 119 for (uint32_t i = 0; i < queueCount; i++) { |
| 188 if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { | 120 if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { |
| 189 graphicsQueueIndex = i; | 121 graphicsQueueIndex = i; |
| 190 break; | 122 break; |
| 191 } | 123 } |
| 192 } | 124 } |
| 193 SkASSERT(graphicsQueueIndex < queueCount); | 125 SkASSERT(graphicsQueueIndex < queueCount); |
| 194 | 126 |
| 127 extensions.initDevice(kGrVkMinimumVersion, inst, physDev); |
| 128 |
| 129 SkTArray<const char*> deviceLayerNames; |
| 130 SkTArray<const char*> deviceExtensionNames; |
| 195 #ifdef ENABLE_VK_LAYERS | 131 #ifdef ENABLE_VK_LAYERS |
| 196 // unlikely that the device will have different layers than the instance, bu
t good to check | 132 for (int i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { |
| 197 if (!verify_device_layers(physDev)) { | 133 if (extensions.hasDeviceLayer(kDebugLayerNames[i])) { |
| 198 enabledLayerNames = nullptr; | 134 deviceLayerNames.push_back(kDebugLayerNames[i]); |
| 199 enabledLayerCount = 0; | 135 } |
| 200 } | 136 } |
| 201 #endif | 137 #endif |
| 138 if (extensions.hasDeviceExtension("VK_NV_glsl_shader")) { |
| 139 deviceExtensionNames.push_back("VK_NV_glsl_shader"); |
| 140 extensionFlags |= kNV_glsl_shader_GrVkExtensionFlag; |
| 141 } |
| 142 |
| 143 // query to get the physical device properties |
| 144 VkPhysicalDeviceFeatures deviceFeatures; |
| 145 vkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); |
| 146 // this looks like it would slow things down, |
| 147 // and we can't depend on it on all platforms |
| 148 deviceFeatures.robustBufferAccess = VK_FALSE; |
| 149 |
| 150 uint32_t featureFlags = 0; |
| 151 if (deviceFeatures.geometryShader) { |
| 152 featureFlags |= kGeometryShader_GrVkFeatureFlag; |
| 153 } |
| 154 if (deviceFeatures.dualSrcBlend) { |
| 155 featureFlags |= kDualSrcBlend_GrVkFeatureFlag; |
| 156 } |
| 157 if (deviceFeatures.sampleRateShading) { |
| 158 featureFlags |= kSampleRateShading_GrVkFeatureFlag; |
| 159 } |
| 202 | 160 |
| 203 float queuePriorities[1] = { 0.0 }; | 161 float queuePriorities[1] = { 0.0 }; |
| 204 // Here we assume no need for swapchain queue | 162 // Here we assume no need for swapchain queue |
| 205 // If one is needed, the client will need its own setup code | 163 // If one is needed, the client will need its own setup code |
| 206 const VkDeviceQueueCreateInfo queueInfo = { | 164 const VkDeviceQueueCreateInfo queueInfo = { |
| 207 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType | 165 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType |
| 208 nullptr, // pNext | 166 nullptr, // pNext |
| 209 0, // VkDeviceQueueCreateFlags | 167 0, // VkDeviceQueueCreateFlags |
| 210 graphicsQueueIndex, // queueFamilyIndex | 168 graphicsQueueIndex, // queueFamilyIndex |
| 211 1, // queueCount | 169 1, // queueCount |
| 212 queuePriorities, // pQueuePriorities | 170 queuePriorities, // pQueuePriorities |
| 213 }; | 171 }; |
| 214 const VkDeviceCreateInfo deviceInfo = { | 172 const VkDeviceCreateInfo deviceInfo = { |
| 215 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType | 173 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType |
| 216 nullptr, // pNext | 174 nullptr, // pNext |
| 217 0, // VkDeviceCreateFlags | 175 0, // VkDeviceCreateFlags |
| 218 1, // queueCreateInfoCount | 176 1, // queueCreateInfoCount |
| 219 &queueInfo, // pQueueCreateInfos | 177 &queueInfo, // pQueueCreateInfos |
| 220 enabledLayerCount, // layerCount | 178 deviceLayerNames.count(), // layerCount |
| 221 enabledLayerNames, // ppEnabledLayerNames | 179 deviceLayerNames.begin(), // ppEnabledLayerNames |
| 222 0, // extensionCount | 180 deviceExtensionNames.count(), // extensionCount |
| 223 nullptr, // ppEnabledExtensionNames | 181 deviceExtensionNames.begin(), // ppEnabledExtensionNames |
| 224 nullptr // ppEnabledFeatures | 182 &deviceFeatures // ppEnabledFeatures |
| 225 }; | 183 }; |
| 226 | 184 |
| 227 err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); | 185 err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); |
| 228 if (err) { | 186 if (err) { |
| 229 SkDebugf("CreateDevice failed: %d\n", err); | 187 SkDebugf("CreateDevice failed: %d\n", err); |
| 230 return nullptr; | 188 return nullptr; |
| 231 } | 189 } |
| 232 | 190 |
| 233 VkQueue queue; | 191 VkQueue queue; |
| 234 vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); | 192 vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); |
| 235 | 193 |
| 236 GrVkBackendContext* ctx = new GrVkBackendContext(); | 194 GrVkBackendContext* ctx = new GrVkBackendContext(); |
| 237 ctx->fInstance = inst; | 195 ctx->fInstance = inst; |
| 238 ctx->fPhysicalDevice = physDev; | 196 ctx->fPhysicalDevice = physDev; |
| 239 ctx->fDevice = device; | 197 ctx->fDevice = device; |
| 240 ctx->fQueue = queue; | 198 ctx->fQueue = queue; |
| 241 ctx->fQueueFamilyIndex = graphicsQueueIndex; | 199 ctx->fQueueFamilyIndex = graphicsQueueIndex; |
| 242 ctx->fInterface.reset(GrVkCreateInterface(inst, physDev, device)); | 200 ctx->fMinAPIVersion = kGrVkMinimumVersion; |
| 201 ctx->fExtensions = extensionFlags; |
| 202 ctx->fFeatures = featureFlags; |
| 203 ctx->fInterface.reset(GrVkCreateInterface(inst, device, extensionFlags)); |
| 243 | 204 |
| 244 return ctx; | 205 return ctx; |
| 245 } | 206 } |
| 246 | 207 |
| 247 GrVkBackendContext::~GrVkBackendContext() { | 208 GrVkBackendContext::~GrVkBackendContext() { |
| 248 vkDestroyDevice(fDevice, nullptr); | 209 vkDestroyDevice(fDevice, nullptr); |
| 249 fDevice = VK_NULL_HANDLE; | 210 fDevice = VK_NULL_HANDLE; |
| 250 vkDestroyInstance(fInstance, nullptr); | 211 vkDestroyInstance(fInstance, nullptr); |
| 251 fInstance = VK_NULL_HANDLE; | 212 fInstance = VK_NULL_HANDLE; |
| 252 } | 213 } |
| OLD | NEW |