blob: 87ebabd99f830f08944cd05be19ffa4a6e190436 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// RendererVk.cpp:
7// Implements the class methods for RendererVk.
8//
9
10#include "libANGLE/renderer/vulkan/RendererVk.h"
11
Jamie Madill4d0bf552016-12-28 15:45:24 -050012// Placing this first seems to solve an intellisense bug.
13#include "libANGLE/renderer/vulkan/renderervk_utils.h"
14
Jamie Madille09bd5d2016-11-29 16:20:35 -050015#include <EGL/eglext.h>
16
Jamie Madill9e54b5a2016-05-25 12:57:39 -040017#include "common/debug.h"
Jamie Madilla66779f2017-01-06 10:43:44 -050018#include "common/system_utils.h"
Jamie Madill4d0bf552016-12-28 15:45:24 -050019#include "libANGLE/renderer/driver_utils.h"
Jamie Madille09bd5d2016-11-29 16:20:35 -050020#include "libANGLE/renderer/vulkan/CompilerVk.h"
21#include "libANGLE/renderer/vulkan/FramebufferVk.h"
22#include "libANGLE/renderer/vulkan/TextureVk.h"
23#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
24#include "platform/Platform.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040025
26namespace rx
27{
28
Jamie Madille09bd5d2016-11-29 16:20:35 -050029namespace
30{
31
32VkResult VerifyExtensionsPresent(const std::vector<VkExtensionProperties> &extensionProps,
33 const std::vector<const char *> &enabledExtensionNames)
34{
35 // Compile the extensions names into a set.
36 std::set<std::string> extensionNames;
37 for (const auto &extensionProp : extensionProps)
38 {
39 extensionNames.insert(extensionProp.extensionName);
40 }
41
42 for (const auto &extensionName : enabledExtensionNames)
43 {
44 if (extensionNames.count(extensionName) == 0)
45 {
46 return VK_ERROR_EXTENSION_NOT_PRESENT;
47 }
48 }
49
50 return VK_SUCCESS;
51}
52
Jamie Madill0448ec82016-12-23 13:41:47 -050053VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
54 VkDebugReportObjectTypeEXT objectType,
55 uint64_t object,
56 size_t location,
57 int32_t messageCode,
58 const char *layerPrefix,
59 const char *message,
60 void *userData)
61{
62 if ((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0)
63 {
64 ANGLEPlatformCurrent()->logError(message);
65#if !defined(NDEBUG)
66 // Abort the call in Debug builds.
67 return VK_TRUE;
68#endif
69 }
70 else if ((flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0)
71 {
72 ANGLEPlatformCurrent()->logWarning(message);
73 }
74 else
75 {
76 ANGLEPlatformCurrent()->logInfo(message);
77 }
78
79 return VK_FALSE;
80}
81
Jamie Madille09bd5d2016-11-29 16:20:35 -050082} // anonymous namespace
83
Jamie Madill0448ec82016-12-23 13:41:47 -050084RendererVk::RendererVk()
85 : mCapsInitialized(false),
86 mInstance(VK_NULL_HANDLE),
87 mEnableValidationLayers(false),
Jamie Madill4d0bf552016-12-28 15:45:24 -050088 mDebugReportCallback(VK_NULL_HANDLE),
89 mPhysicalDevice(VK_NULL_HANDLE),
90 mQueue(VK_NULL_HANDLE),
91 mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
92 mDevice(VK_NULL_HANDLE),
93 mCommandPool(VK_NULL_HANDLE)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040094{
95}
96
97RendererVk::~RendererVk()
98{
Jamie Madill4d0bf552016-12-28 15:45:24 -050099 mCommandBuffer.reset(nullptr);
100
101 if (mCommandPool)
102 {
103 vkDestroyCommandPool(mDevice, mCommandPool, nullptr);
104 mCommandPool = VK_NULL_HANDLE;
105 }
106
107 if (mDevice)
108 {
109 vkDestroyDevice(mDevice, nullptr);
110 mDevice = VK_NULL_HANDLE;
111 }
112
Jamie Madill0448ec82016-12-23 13:41:47 -0500113 if (mDebugReportCallback)
114 {
115 ASSERT(mInstance);
116 auto destroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
117 vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT"));
118 ASSERT(destroyDebugReportCallback);
119 destroyDebugReportCallback(mInstance, mDebugReportCallback, nullptr);
120 }
121
Jamie Madill4d0bf552016-12-28 15:45:24 -0500122 if (mInstance)
123 {
124 vkDestroyInstance(mInstance, nullptr);
125 mInstance = VK_NULL_HANDLE;
126 }
127
128 mPhysicalDevice = VK_NULL_HANDLE;
Jamie Madill327ba852016-11-30 12:38:28 -0500129}
130
Jamie Madille09bd5d2016-11-29 16:20:35 -0500131vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
Jamie Madill327ba852016-11-30 12:38:28 -0500132{
Jamie Madilla66779f2017-01-06 10:43:44 -0500133#if !defined(NDEBUG)
134 // Validation layers enabled by default in Debug.
135 mEnableValidationLayers = true;
136#endif
137
138 // If specified in the attributes, override the default.
139 if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
140 {
141 mEnableValidationLayers =
142 (attribs.get(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE, EGL_FALSE) == EGL_TRUE);
143 }
144
145 // If we're loading the validation layers, we could be running from any random directory.
146 // Change to the executable directory so we can find the layers, then change back to the
147 // previous directory to be safe we don't disrupt the application.
148 std::string previousCWD;
149
150 if (mEnableValidationLayers)
151 {
152 const auto &cwd = angle::GetCWD();
153 if (!cwd.valid())
154 {
155 ANGLEPlatformCurrent()->logError("Error getting CWD for Vulkan layers init.");
156 mEnableValidationLayers = false;
157 }
158 else
159 {
160 previousCWD = cwd.value();
161 }
162 const char *exeDir = angle::GetExecutableDirectory();
163 angle::SetCWD(exeDir);
164 }
165
Jamie Madill0448ec82016-12-23 13:41:47 -0500166 // Gather global layer properties.
167 uint32_t instanceLayerCount = 0;
168 ANGLE_VK_TRY(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
169
170 std::vector<VkLayerProperties> instanceLayerProps(instanceLayerCount);
171 if (instanceLayerCount > 0)
172 {
173 ANGLE_VK_TRY(
174 vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayerProps.data()));
175 }
176
Jamie Madille09bd5d2016-11-29 16:20:35 -0500177 uint32_t instanceExtensionCount = 0;
178 ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, nullptr));
179
180 std::vector<VkExtensionProperties> instanceExtensionProps(instanceExtensionCount);
181 if (instanceExtensionCount > 0)
182 {
183 ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount,
184 instanceExtensionProps.data()));
185 }
186
Jamie Madill0448ec82016-12-23 13:41:47 -0500187 if (mEnableValidationLayers)
188 {
189 // Verify the standard validation layers are available.
190 if (!HasStandardValidationLayer(instanceLayerProps))
191 {
192 // Generate an error if the attribute was requested, warning otherwise.
193 if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
194 {
195 ANGLEPlatformCurrent()->logError("Vulkan standard validation layers are missing.");
196 }
197 else
198 {
199 ANGLEPlatformCurrent()->logWarning(
200 "Vulkan standard validation layers are missing.");
201 }
202 mEnableValidationLayers = false;
203 }
204 }
205
Jamie Madille09bd5d2016-11-29 16:20:35 -0500206 std::vector<const char *> enabledInstanceExtensions;
207 enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
208#if defined(ANGLE_PLATFORM_WINDOWS)
209 enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
210#else
211#error Unsupported Vulkan platform.
212#endif // defined(ANGLE_PLATFORM_WINDOWS)
213
Jamie Madill0448ec82016-12-23 13:41:47 -0500214 // TODO(jmadill): Should be able to continue initialization if debug report ext missing.
215 if (mEnableValidationLayers)
216 {
217 enabledInstanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
218 }
219
Jamie Madille09bd5d2016-11-29 16:20:35 -0500220 // Verify the required extensions are in the extension names set. Fail if not.
221 ANGLE_VK_TRY(VerifyExtensionsPresent(instanceExtensionProps, enabledInstanceExtensions));
222
Jamie Madill327ba852016-11-30 12:38:28 -0500223 VkApplicationInfo applicationInfo;
224 applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
225 applicationInfo.pNext = nullptr;
226 applicationInfo.pApplicationName = "ANGLE";
227 applicationInfo.applicationVersion = 1;
228 applicationInfo.pEngineName = "ANGLE";
229 applicationInfo.engineVersion = 1;
230 applicationInfo.apiVersion = VK_API_VERSION_1_0;
231
232 VkInstanceCreateInfo instanceInfo;
233 instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
234 instanceInfo.pNext = nullptr;
235 instanceInfo.flags = 0;
236 instanceInfo.pApplicationInfo = &applicationInfo;
237
Jamie Madille09bd5d2016-11-29 16:20:35 -0500238 // Enable requested layers and extensions.
239 instanceInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
240 instanceInfo.ppEnabledExtensionNames =
241 enabledInstanceExtensions.empty() ? nullptr : enabledInstanceExtensions.data();
Jamie Madill0448ec82016-12-23 13:41:47 -0500242 instanceInfo.enabledLayerCount = mEnableValidationLayers ? 1u : 0u;
243 instanceInfo.ppEnabledLayerNames =
244 mEnableValidationLayers ? &g_VkStdValidationLayerName : nullptr;
Jamie Madill327ba852016-11-30 12:38:28 -0500245
246 ANGLE_VK_TRY(vkCreateInstance(&instanceInfo, nullptr, &mInstance));
247
Jamie Madill0448ec82016-12-23 13:41:47 -0500248 if (mEnableValidationLayers)
249 {
Jamie Madilla66779f2017-01-06 10:43:44 -0500250 // Change back to the previous working directory now that we've loaded the instance -
251 // the validation layers should be loaded at this point.
252 angle::SetCWD(previousCWD.c_str());
253
Jamie Madill0448ec82016-12-23 13:41:47 -0500254 VkDebugReportCallbackCreateInfoEXT debugReportInfo;
255
256 debugReportInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
257 debugReportInfo.pNext = nullptr;
258 debugReportInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
259 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
260 VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
261 debugReportInfo.pfnCallback = &DebugReportCallback;
262 debugReportInfo.pUserData = this;
263
264 auto createDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
265 vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT"));
266 ASSERT(createDebugReportCallback);
267 ANGLE_VK_TRY(
268 createDebugReportCallback(mInstance, &debugReportInfo, nullptr, &mDebugReportCallback));
269 }
270
Jamie Madill4d0bf552016-12-28 15:45:24 -0500271 uint32_t physicalDeviceCount = 0;
272 ANGLE_VK_TRY(vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount, nullptr));
273 ANGLE_VK_CHECK(physicalDeviceCount > 0, VK_ERROR_INITIALIZATION_FAILED);
274
275 // TODO(jmadill): Handle multiple physical devices. For now, use the first device.
276 physicalDeviceCount = 1;
277 ANGLE_VK_TRY(vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount, &mPhysicalDevice));
278
279 vkGetPhysicalDeviceProperties(mPhysicalDevice, &mPhysicalDeviceProperties);
280
281 // Ensure we can find a graphics queue family.
282 uint32_t queueCount = 0;
283 vkGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr);
284
285 ANGLE_VK_CHECK(queueCount > 0, VK_ERROR_INITIALIZATION_FAILED);
286
287 mQueueFamilyProperties.resize(queueCount);
288 vkGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount,
289 mQueueFamilyProperties.data());
290
291 size_t graphicsQueueFamilyCount = false;
292 uint32_t firstGraphicsQueueFamily = 0;
293 for (uint32_t familyIndex = 0; familyIndex < queueCount; ++familyIndex)
294 {
295 const auto &queueInfo = mQueueFamilyProperties[familyIndex];
296 if ((queueInfo.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
297 {
298 ASSERT(queueInfo.queueCount > 0);
299 graphicsQueueFamilyCount++;
300 if (firstGraphicsQueueFamily == 0)
301 {
302 firstGraphicsQueueFamily = familyIndex;
303 }
304 break;
305 }
306 }
307
308 ANGLE_VK_CHECK(graphicsQueueFamilyCount > 0, VK_ERROR_INITIALIZATION_FAILED);
309
310 // If only one queue family, go ahead and initialize the device. If there is more than one
311 // queue, we'll have to wait until we see a WindowSurface to know which supports present.
312 if (graphicsQueueFamilyCount == 1)
313 {
314 ANGLE_TRY(initializeDevice(firstGraphicsQueueFamily));
315 }
316
Jamie Madill327ba852016-11-30 12:38:28 -0500317 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400318}
319
Jamie Madill4d0bf552016-12-28 15:45:24 -0500320vk::Error RendererVk::initializeDevice(uint32_t queueFamilyIndex)
321{
322 uint32_t deviceLayerCount = 0;
323 ANGLE_VK_TRY(vkEnumerateDeviceLayerProperties(mPhysicalDevice, &deviceLayerCount, nullptr));
324
325 std::vector<VkLayerProperties> deviceLayerProps(deviceLayerCount);
326 if (deviceLayerCount > 0)
327 {
328 ANGLE_VK_TRY(vkEnumerateDeviceLayerProperties(mPhysicalDevice, &deviceLayerCount,
329 deviceLayerProps.data()));
330 }
331
332 uint32_t deviceExtensionCount = 0;
333 ANGLE_VK_TRY(vkEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr,
334 &deviceExtensionCount, nullptr));
335
336 std::vector<VkExtensionProperties> deviceExtensionProps(deviceExtensionCount);
337 if (deviceExtensionCount > 0)
338 {
339 ANGLE_VK_TRY(vkEnumerateDeviceExtensionProperties(
340 mPhysicalDevice, nullptr, &deviceExtensionCount, deviceExtensionProps.data()));
341 }
342
343 if (mEnableValidationLayers)
344 {
345 if (!HasStandardValidationLayer(deviceLayerProps))
346 {
347 ANGLEPlatformCurrent()->logWarning("Vulkan standard validation layer is missing.");
348 mEnableValidationLayers = false;
349 }
350 }
351
352 std::vector<const char *> enabledDeviceExtensions;
353 enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
354
355 ANGLE_VK_TRY(VerifyExtensionsPresent(deviceExtensionProps, enabledDeviceExtensions));
356
357 VkDeviceQueueCreateInfo queueCreateInfo;
358
359 float zeroPriority = 0.0f;
360
361 queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
362 queueCreateInfo.pNext = nullptr;
363 queueCreateInfo.flags = 0;
364 queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
365 queueCreateInfo.queueCount = 1;
366 queueCreateInfo.pQueuePriorities = &zeroPriority;
367
368 // Initialize the device
369 VkDeviceCreateInfo createInfo;
370
371 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
372 createInfo.pNext = nullptr;
373 createInfo.flags = 0;
374 createInfo.queueCreateInfoCount = 1;
375 createInfo.pQueueCreateInfos = &queueCreateInfo;
376 createInfo.enabledLayerCount = mEnableValidationLayers ? 1u : 0u;
377 createInfo.ppEnabledLayerNames =
378 mEnableValidationLayers ? &g_VkStdValidationLayerName : nullptr;
379 createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledDeviceExtensions.size());
380 createInfo.ppEnabledExtensionNames =
381 enabledDeviceExtensions.empty() ? nullptr : enabledDeviceExtensions.data();
382 createInfo.pEnabledFeatures = nullptr; // TODO(jmadill): features
383
384 ANGLE_VK_TRY(vkCreateDevice(mPhysicalDevice, &createInfo, nullptr, &mDevice));
385
386 mCurrentQueueFamilyIndex = queueFamilyIndex;
387
388 vkGetDeviceQueue(mDevice, mCurrentQueueFamilyIndex, 0, &mQueue);
389
390 // Initialize the command pool now that we know the queue family index.
391 VkCommandPoolCreateInfo commandPoolInfo;
392 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
393 commandPoolInfo.pNext = nullptr;
394 // TODO(jmadill): Investigate transient command buffers.
395 commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
396 commandPoolInfo.queueFamilyIndex = mCurrentQueueFamilyIndex;
397
398 ANGLE_VK_TRY(vkCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool));
399
400 mCommandBuffer.reset(new vk::CommandBuffer(mDevice, mCommandPool));
401
402 return vk::NoError();
403}
404
405vk::ErrorOrResult<uint32_t> RendererVk::selectPresentQueueForSurface(VkSurfaceKHR surface)
406{
407 // We've already initialized a device, and can't re-create it unless it's never been used.
408 // TODO(jmadill): Handle the re-creation case if necessary.
409 if (mDevice != VK_NULL_HANDLE)
410 {
411 ASSERT(mCurrentQueueFamilyIndex != std::numeric_limits<uint32_t>::max());
412
413 // Check if the current device supports present on this surface.
414 VkBool32 supportsPresent = VK_FALSE;
415 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceSupportKHR(mPhysicalDevice, mCurrentQueueFamilyIndex,
416 surface, &supportsPresent));
417
418 return (supportsPresent == VK_TRUE);
419 }
420
421 // Find a graphics and present queue.
422 Optional<uint32_t> newPresentQueue;
423 uint32_t queueCount = static_cast<uint32_t>(mQueueFamilyProperties.size());
424 for (uint32_t queueIndex = 0; queueIndex < queueCount; ++queueIndex)
425 {
426 const auto &queueInfo = mQueueFamilyProperties[queueIndex];
427 if ((queueInfo.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
428 {
429 VkBool32 supportsPresent = VK_FALSE;
430 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceSupportKHR(mPhysicalDevice, queueIndex, surface,
431 &supportsPresent));
432
433 if (supportsPresent == VK_TRUE)
434 {
435 newPresentQueue = queueIndex;
436 break;
437 }
438 }
439 }
440
441 ANGLE_VK_CHECK(newPresentQueue.valid(), VK_ERROR_INITIALIZATION_FAILED);
442 ANGLE_TRY(initializeDevice(newPresentQueue.value()));
443
444 return newPresentQueue.value();
445}
446
447std::string RendererVk::getVendorString() const
448{
449 switch (mPhysicalDeviceProperties.vendorID)
450 {
451 case VENDOR_ID_AMD:
452 return "Advanced Micro Devices";
453 case VENDOR_ID_NVIDIA:
454 return "NVIDIA";
455 case VENDOR_ID_INTEL:
456 return "Intel";
457 default:
458 {
459 // TODO(jmadill): More vendor IDs.
460 std::stringstream strstr;
461 strstr << "Vendor ID: " << mPhysicalDeviceProperties.vendorID;
462 return strstr.str();
463 }
464 }
465}
466
Jamie Madille09bd5d2016-11-29 16:20:35 -0500467std::string RendererVk::getRendererDescription() const
468{
Jamie Madill4d0bf552016-12-28 15:45:24 -0500469 std::stringstream strstr;
470
471 uint32_t apiVersion = mPhysicalDeviceProperties.apiVersion;
472
473 strstr << "Vulkan ";
474 strstr << VK_VERSION_MAJOR(apiVersion) << ".";
475 strstr << VK_VERSION_MINOR(apiVersion) << ".";
476 strstr << VK_VERSION_PATCH(apiVersion);
477
478 strstr << "(" << mPhysicalDeviceProperties.deviceName << ")";
479
480 return strstr.str();
Jamie Madille09bd5d2016-11-29 16:20:35 -0500481}
482
Jamie Madillacccc6c2016-05-03 17:22:10 -0400483void RendererVk::ensureCapsInitialized() const
484{
485 if (!mCapsInitialized)
486 {
487 generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
488 mCapsInitialized = true;
489 }
490}
491
492void RendererVk::generateCaps(gl::Caps * /*outCaps*/,
493 gl::TextureCapsMap * /*outTextureCaps*/,
494 gl::Extensions * /*outExtensions*/,
495 gl::Limitations * /* outLimitations */) const
496{
Jamie Madill327ba852016-11-30 12:38:28 -0500497 // TODO(jmadill): Caps.
Jamie Madillacccc6c2016-05-03 17:22:10 -0400498}
499
500const gl::Caps &RendererVk::getNativeCaps() const
501{
502 ensureCapsInitialized();
503 return mNativeCaps;
504}
505
506const gl::TextureCapsMap &RendererVk::getNativeTextureCaps() const
507{
508 ensureCapsInitialized();
509 return mNativeTextureCaps;
510}
511
512const gl::Extensions &RendererVk::getNativeExtensions() const
513{
514 ensureCapsInitialized();
515 return mNativeExtensions;
516}
517
518const gl::Limitations &RendererVk::getNativeLimitations() const
519{
520 ensureCapsInitialized();
521 return mNativeLimitations;
522}
523
Jamie Madill4d0bf552016-12-28 15:45:24 -0500524vk::CommandBuffer *RendererVk::getCommandBuffer()
525{
526 return mCommandBuffer.get();
527}
528
529vk::Error RendererVk::submitAndFinishCommandBuffer(const vk::CommandBuffer &commandBuffer)
530{
531 VkFenceCreateInfo fenceInfo;
532 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
533 fenceInfo.pNext = nullptr;
534 fenceInfo.flags = 0;
535
536 VkCommandBuffer commandBufferHandle = commandBuffer.getHandle();
537
538 VkSubmitInfo submitInfo;
539 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
540 submitInfo.pNext = nullptr;
541 submitInfo.waitSemaphoreCount = 0;
542 submitInfo.pWaitSemaphores = nullptr;
543 submitInfo.pWaitDstStageMask = nullptr;
544 submitInfo.commandBufferCount = 1;
545 submitInfo.pCommandBuffers = &commandBufferHandle;
546 submitInfo.signalSemaphoreCount = 0;
547 submitInfo.pSignalSemaphores = nullptr;
548
549 // TODO(jmadill): Investigate how to properly submit command buffers.
550 ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, VK_NULL_HANDLE));
551
552 // Wait indefinitely for the queue to finish.
553 ANGLE_VK_TRY(vkQueueWaitIdle(mQueue));
554
555 return vk::NoError();
556}
557
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400558} // namespace rx