blob: ecbca1297e2c20c27a6ea04232ffadd769f2ab81 [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 Madille09bd5d2016-11-29 16:20:35 -050012#include <EGL/eglext.h>
13
Jamie Madill9e54b5a2016-05-25 12:57:39 -040014#include "common/debug.h"
Jamie Madille09bd5d2016-11-29 16:20:35 -050015#include "libANGLE/renderer/vulkan/CompilerVk.h"
16#include "libANGLE/renderer/vulkan/FramebufferVk.h"
17#include "libANGLE/renderer/vulkan/TextureVk.h"
18#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
19#include "platform/Platform.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040020
21namespace rx
22{
23
Jamie Madille09bd5d2016-11-29 16:20:35 -050024namespace
25{
26
27VkResult VerifyExtensionsPresent(const std::vector<VkExtensionProperties> &extensionProps,
28 const std::vector<const char *> &enabledExtensionNames)
29{
30 // Compile the extensions names into a set.
31 std::set<std::string> extensionNames;
32 for (const auto &extensionProp : extensionProps)
33 {
34 extensionNames.insert(extensionProp.extensionName);
35 }
36
37 for (const auto &extensionName : enabledExtensionNames)
38 {
39 if (extensionNames.count(extensionName) == 0)
40 {
41 return VK_ERROR_EXTENSION_NOT_PRESENT;
42 }
43 }
44
45 return VK_SUCCESS;
46}
47
Jamie Madill0448ec82016-12-23 13:41:47 -050048VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
49 VkDebugReportObjectTypeEXT objectType,
50 uint64_t object,
51 size_t location,
52 int32_t messageCode,
53 const char *layerPrefix,
54 const char *message,
55 void *userData)
56{
57 if ((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0)
58 {
59 ANGLEPlatformCurrent()->logError(message);
60#if !defined(NDEBUG)
61 // Abort the call in Debug builds.
62 return VK_TRUE;
63#endif
64 }
65 else if ((flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0)
66 {
67 ANGLEPlatformCurrent()->logWarning(message);
68 }
69 else
70 {
71 ANGLEPlatformCurrent()->logInfo(message);
72 }
73
74 return VK_FALSE;
75}
76
Jamie Madille09bd5d2016-11-29 16:20:35 -050077} // anonymous namespace
78
Jamie Madill0448ec82016-12-23 13:41:47 -050079RendererVk::RendererVk()
80 : mCapsInitialized(false),
81 mInstance(VK_NULL_HANDLE),
82 mEnableValidationLayers(false),
83 mDebugReportCallback(VK_NULL_HANDLE)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040084{
85}
86
87RendererVk::~RendererVk()
88{
Jamie Madill0448ec82016-12-23 13:41:47 -050089 if (mDebugReportCallback)
90 {
91 ASSERT(mInstance);
92 auto destroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
93 vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT"));
94 ASSERT(destroyDebugReportCallback);
95 destroyDebugReportCallback(mInstance, mDebugReportCallback, nullptr);
96 }
97
Jamie Madill327ba852016-11-30 12:38:28 -050098 vkDestroyInstance(mInstance, nullptr);
99}
100
Jamie Madille09bd5d2016-11-29 16:20:35 -0500101vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
Jamie Madill327ba852016-11-30 12:38:28 -0500102{
Jamie Madill0448ec82016-12-23 13:41:47 -0500103 // Gather global layer properties.
104 uint32_t instanceLayerCount = 0;
105 ANGLE_VK_TRY(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
106
107 std::vector<VkLayerProperties> instanceLayerProps(instanceLayerCount);
108 if (instanceLayerCount > 0)
109 {
110 ANGLE_VK_TRY(
111 vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayerProps.data()));
112 }
113
Jamie Madille09bd5d2016-11-29 16:20:35 -0500114 uint32_t instanceExtensionCount = 0;
115 ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, nullptr));
116
117 std::vector<VkExtensionProperties> instanceExtensionProps(instanceExtensionCount);
118 if (instanceExtensionCount > 0)
119 {
120 ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount,
121 instanceExtensionProps.data()));
122 }
123
Jamie Madill0448ec82016-12-23 13:41:47 -0500124#if !defined(NDEBUG)
125 // Validation layers enabled by default in Debug.
126 mEnableValidationLayers = true;
127#endif
128
129 // If specified in the attributes, override the default.
130 if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
131 {
132 mEnableValidationLayers =
133 (attribs.get(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE, EGL_FALSE) == EGL_TRUE);
134 }
135
136 if (mEnableValidationLayers)
137 {
138 // Verify the standard validation layers are available.
139 if (!HasStandardValidationLayer(instanceLayerProps))
140 {
141 // Generate an error if the attribute was requested, warning otherwise.
142 if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
143 {
144 ANGLEPlatformCurrent()->logError("Vulkan standard validation layers are missing.");
145 }
146 else
147 {
148 ANGLEPlatformCurrent()->logWarning(
149 "Vulkan standard validation layers are missing.");
150 }
151 mEnableValidationLayers = false;
152 }
153 }
154
Jamie Madille09bd5d2016-11-29 16:20:35 -0500155 std::vector<const char *> enabledInstanceExtensions;
156 enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
157#if defined(ANGLE_PLATFORM_WINDOWS)
158 enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
159#else
160#error Unsupported Vulkan platform.
161#endif // defined(ANGLE_PLATFORM_WINDOWS)
162
Jamie Madill0448ec82016-12-23 13:41:47 -0500163 // TODO(jmadill): Should be able to continue initialization if debug report ext missing.
164 if (mEnableValidationLayers)
165 {
166 enabledInstanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
167 }
168
Jamie Madille09bd5d2016-11-29 16:20:35 -0500169 // Verify the required extensions are in the extension names set. Fail if not.
170 ANGLE_VK_TRY(VerifyExtensionsPresent(instanceExtensionProps, enabledInstanceExtensions));
171
Jamie Madill327ba852016-11-30 12:38:28 -0500172 VkApplicationInfo applicationInfo;
173 applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
174 applicationInfo.pNext = nullptr;
175 applicationInfo.pApplicationName = "ANGLE";
176 applicationInfo.applicationVersion = 1;
177 applicationInfo.pEngineName = "ANGLE";
178 applicationInfo.engineVersion = 1;
179 applicationInfo.apiVersion = VK_API_VERSION_1_0;
180
181 VkInstanceCreateInfo instanceInfo;
182 instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
183 instanceInfo.pNext = nullptr;
184 instanceInfo.flags = 0;
185 instanceInfo.pApplicationInfo = &applicationInfo;
186
Jamie Madille09bd5d2016-11-29 16:20:35 -0500187 // Enable requested layers and extensions.
188 instanceInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
189 instanceInfo.ppEnabledExtensionNames =
190 enabledInstanceExtensions.empty() ? nullptr : enabledInstanceExtensions.data();
Jamie Madill0448ec82016-12-23 13:41:47 -0500191 instanceInfo.enabledLayerCount = mEnableValidationLayers ? 1u : 0u;
192 instanceInfo.ppEnabledLayerNames =
193 mEnableValidationLayers ? &g_VkStdValidationLayerName : nullptr;
Jamie Madill327ba852016-11-30 12:38:28 -0500194
195 ANGLE_VK_TRY(vkCreateInstance(&instanceInfo, nullptr, &mInstance));
196
Jamie Madill0448ec82016-12-23 13:41:47 -0500197 if (mEnableValidationLayers)
198 {
199 VkDebugReportCallbackCreateInfoEXT debugReportInfo;
200
201 debugReportInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
202 debugReportInfo.pNext = nullptr;
203 debugReportInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
204 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
205 VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
206 debugReportInfo.pfnCallback = &DebugReportCallback;
207 debugReportInfo.pUserData = this;
208
209 auto createDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
210 vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT"));
211 ASSERT(createDebugReportCallback);
212 ANGLE_VK_TRY(
213 createDebugReportCallback(mInstance, &debugReportInfo, nullptr, &mDebugReportCallback));
214 }
215
Jamie Madill327ba852016-11-30 12:38:28 -0500216 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400217}
218
Jamie Madille09bd5d2016-11-29 16:20:35 -0500219std::string RendererVk::getRendererDescription() const
220{
221 // TODO(jmadill): Description.
222 return "Vulkan";
223}
224
Jamie Madillacccc6c2016-05-03 17:22:10 -0400225void RendererVk::ensureCapsInitialized() const
226{
227 if (!mCapsInitialized)
228 {
229 generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
230 mCapsInitialized = true;
231 }
232}
233
234void RendererVk::generateCaps(gl::Caps * /*outCaps*/,
235 gl::TextureCapsMap * /*outTextureCaps*/,
236 gl::Extensions * /*outExtensions*/,
237 gl::Limitations * /* outLimitations */) const
238{
Jamie Madill327ba852016-11-30 12:38:28 -0500239 // TODO(jmadill): Caps.
Jamie Madillacccc6c2016-05-03 17:22:10 -0400240}
241
242const gl::Caps &RendererVk::getNativeCaps() const
243{
244 ensureCapsInitialized();
245 return mNativeCaps;
246}
247
248const gl::TextureCapsMap &RendererVk::getNativeTextureCaps() const
249{
250 ensureCapsInitialized();
251 return mNativeTextureCaps;
252}
253
254const gl::Extensions &RendererVk::getNativeExtensions() const
255{
256 ensureCapsInitialized();
257 return mNativeExtensions;
258}
259
260const gl::Limitations &RendererVk::getNativeLimitations() const
261{
262 ensureCapsInitialized();
263 return mNativeLimitations;
264}
265
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400266} // namespace rx