Vulkan: Enable on Android
Add Android DisplayVk and WindowSurfaceVk variants.
Build Vulkan backend and validation layers on Android
if toolchain uses required NDK API level.
Fix validation layers discovery to work on Android.
BUG=angleproject:2314
TEST=angle_end2end_tests builds and runs on Nexus 5X, 12 VULKAN tests pass
Change-Id: Iac2ec4ecd6470a7552f9f60c023ba1760aa090c5
Reviewed-on: https://chromium-review.googlesource.com/887797
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
index 3dea567..4328c2b 100644
--- a/src/libANGLE/renderer/vulkan/DisplayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
@@ -47,51 +47,6 @@
return egl::NoError();
}
-egl::ConfigSet DisplayVk::generateConfigs()
-{
- // TODO(jmadill): Multiple configs, pbuffers, and proper checking of config attribs.
- egl::Config singleton;
- singleton.renderTargetFormat = GL_BGRA8_EXT;
- singleton.depthStencilFormat = GL_NONE;
- singleton.bufferSize = 32;
- singleton.redSize = 8;
- singleton.greenSize = 8;
- singleton.blueSize = 8;
- singleton.alphaSize = 8;
- singleton.alphaMaskSize = 0;
- singleton.bindToTextureRGB = EGL_FALSE;
- singleton.bindToTextureRGBA = EGL_FALSE;
- singleton.colorBufferType = EGL_RGB_BUFFER;
- singleton.configCaveat = EGL_NONE;
- singleton.conformant = 0;
- singleton.depthSize = 0;
- singleton.stencilSize = 0;
- singleton.level = 0;
- singleton.matchNativePixmap = EGL_NONE;
- singleton.maxPBufferWidth = 0;
- singleton.maxPBufferHeight = 0;
- singleton.maxPBufferPixels = 0;
- singleton.maxSwapInterval = 1;
- singleton.minSwapInterval = 1;
- singleton.nativeRenderable = EGL_TRUE;
- singleton.nativeVisualID = 0;
- singleton.nativeVisualType = EGL_NONE;
- singleton.renderableType = EGL_OPENGL_ES2_BIT;
- singleton.sampleBuffers = 0;
- singleton.samples = 0;
- singleton.surfaceType = EGL_WINDOW_BIT;
- singleton.optimalOrientation = 0;
- singleton.transparentType = EGL_NONE;
- singleton.transparentRedValue = 0;
- singleton.transparentGreenValue = 0;
- singleton.transparentBlueValue = 0;
- singleton.colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
-
- egl::ConfigSet configSet;
- configSet.add(singleton);
- return configSet;
-}
-
bool DisplayVk::testDeviceLost()
{
// TODO(jmadill): Figure out how to do device lost in Vulkan.
diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.h b/src/libANGLE/renderer/vulkan/DisplayVk.h
index 475dc97..87c75ca 100644
--- a/src/libANGLE/renderer/vulkan/DisplayVk.h
+++ b/src/libANGLE/renderer/vulkan/DisplayVk.h
@@ -29,8 +29,6 @@
egl::Surface *readSurface,
gl::Context *context) override;
- egl::ConfigSet generateConfigs() override;
-
bool testDeviceLost() override;
egl::Error restoreLostDevice(const egl::Display *display) override;
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 71f2bef..1847f40 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -55,14 +55,14 @@
return VK_SUCCESS;
}
-VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
- VkDebugReportObjectTypeEXT objectType,
- uint64_t object,
- size_t location,
- int32_t messageCode,
- const char *layerPrefix,
- const char *message,
- void *userData)
+VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char *layerPrefix,
+ const char *message,
+ void *userData)
{
if ((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0)
{
@@ -85,6 +85,71 @@
return VK_FALSE;
}
+// If we're loading the validation layers, we could be running from any random directory.
+// Change to the executable directory so we can find the layers, then change back to the
+// previous directory to be safe we don't disrupt the application.
+class ScopedVkLoaderEnvironment : angle::NonCopyable
+{
+ public:
+ ScopedVkLoaderEnvironment(bool enableValidationLayers)
+ : mEnableValidationLayers(enableValidationLayers), mChangedCWD(false)
+ {
+// Changing CWD and setting environment variables makes no sense on Android,
+// since this code is a part of Java application there.
+// Android Vulkan loader doesn't need this either.
+#if !defined(ANGLE_PLATFORM_ANDROID)
+ if (mEnableValidationLayers)
+ {
+ const auto &cwd = angle::GetCWD();
+ if (!cwd.valid())
+ {
+ ERR() << "Error getting CWD for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ }
+ else
+ {
+ mPreviousCWD = cwd.value();
+ const char *exeDir = angle::GetExecutableDirectory();
+ mChangedCWD = angle::SetCWD(exeDir);
+ if (!mChangedCWD)
+ {
+ ERR() << "Error setting CWD for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ }
+ }
+ }
+
+ // Override environment variable to use the ANGLE layers.
+ if (mEnableValidationLayers)
+ {
+ if (!angle::SetEnvironmentVar(g_VkLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
+ {
+ ERR() << "Error setting environment for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ }
+ }
+#endif // !defined(ANGLE_PLATFORM_ANDROID)
+ }
+
+ ~ScopedVkLoaderEnvironment()
+ {
+ if (mChangedCWD)
+ {
+#if !defined(ANGLE_PLATFORM_ANDROID)
+ ASSERT(mPreviousCWD.valid());
+ angle::SetCWD(mPreviousCWD.value().c_str());
+#endif // !defined(ANGLE_PLATFORM_ANDROID)
+ }
+ }
+
+ bool canEnableValidationLayers() { return mEnableValidationLayers; }
+
+ private:
+ bool mEnableValidationLayers;
+ bool mChangedCWD;
+ Optional<std::string> mPreviousCWD;
+};
+
} // anonymous namespace
// CommandBatch implementation.
@@ -187,40 +252,8 @@
{
mEnableValidationLayers = ShouldUseDebugLayers(attribs);
- // If we're loading the validation layers, we could be running from any random directory.
- // Change to the executable directory so we can find the layers, then change back to the
- // previous directory to be safe we don't disrupt the application.
- std::string previousCWD;
-
- if (mEnableValidationLayers)
- {
- const auto &cwd = angle::GetCWD();
- if (!cwd.valid())
- {
- ERR() << "Error getting CWD for Vulkan layers init.";
- mEnableValidationLayers = false;
- }
- else
- {
- previousCWD = cwd.value();
- const char *exeDir = angle::GetExecutableDirectory();
- if (!angle::SetCWD(exeDir))
- {
- ERR() << "Error setting CWD for Vulkan layers init.";
- mEnableValidationLayers = false;
- }
- }
- }
-
- // Override environment variable to use the ANGLE layers.
- if (mEnableValidationLayers)
- {
- if (!angle::SetEnvironmentVar(g_VkLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
- {
- ERR() << "Error setting environment for Vulkan layers init.";
- mEnableValidationLayers = false;
- }
- }
+ ScopedVkLoaderEnvironment scopedEnvironment(mEnableValidationLayers);
+ mEnableValidationLayers = scopedEnvironment.canEnableValidationLayers();
// Gather global layer properties.
uint32_t instanceLayerCount = 0;
@@ -243,23 +276,14 @@
instanceExtensionProps.data()));
}
+ const char *const *enabledLayerNames = nullptr;
+ uint32_t enabledLayerCount = 0;
if (mEnableValidationLayers)
{
- // Verify the standard validation layers are available.
- if (!HasStandardValidationLayer(instanceLayerProps))
- {
- // Generate an error if the attribute was requested, warning otherwise.
- if (attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE) ==
- EGL_TRUE)
- {
- ERR() << "Vulkan standard validation layers are missing.";
- }
- else
- {
- WARN() << "Vulkan standard validation layers are missing.";
- }
- mEnableValidationLayers = false;
- }
+ bool layersRequested =
+ (attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE) == EGL_TRUE);
+ mEnableValidationLayers = GetAvailableValidationLayers(
+ instanceLayerProps, layersRequested, &enabledLayerNames, &enabledLayerCount);
}
std::vector<const char *> enabledInstanceExtensions;
@@ -294,18 +318,13 @@
instanceInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
instanceInfo.ppEnabledExtensionNames =
enabledInstanceExtensions.empty() ? nullptr : enabledInstanceExtensions.data();
- instanceInfo.enabledLayerCount = mEnableValidationLayers ? 1u : 0u;
- instanceInfo.ppEnabledLayerNames =
- mEnableValidationLayers ? &g_VkStdValidationLayerName : nullptr;
+ instanceInfo.enabledLayerCount = enabledLayerCount;
+ instanceInfo.ppEnabledLayerNames = enabledLayerNames;
ANGLE_VK_TRY(vkCreateInstance(&instanceInfo, nullptr, &mInstance));
if (mEnableValidationLayers)
{
- // Change back to the previous working directory now that we've loaded the instance -
- // the validation layers should be loaded at this point.
- angle::SetCWD(previousCWD.c_str());
-
VkDebugReportCallbackCreateInfoEXT debugReportInfo;
debugReportInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
@@ -406,13 +425,12 @@
mPhysicalDevice, nullptr, &deviceExtensionCount, deviceExtensionProps.data()));
}
+ const char *const *enabledLayerNames = nullptr;
+ uint32_t enabledLayerCount = 0;
if (mEnableValidationLayers)
{
- if (!HasStandardValidationLayer(deviceLayerProps))
- {
- WARN() << "Vulkan standard validation layer is missing.";
- mEnableValidationLayers = false;
- }
+ mEnableValidationLayers = GetAvailableValidationLayers(
+ deviceLayerProps, false, &enabledLayerNames, &enabledLayerCount);
}
std::vector<const char *> enabledDeviceExtensions;
@@ -439,9 +457,8 @@
createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1;
createInfo.pQueueCreateInfos = &queueCreateInfo;
- createInfo.enabledLayerCount = mEnableValidationLayers ? 1u : 0u;
- createInfo.ppEnabledLayerNames =
- mEnableValidationLayers ? &g_VkStdValidationLayerName : nullptr;
+ createInfo.enabledLayerCount = enabledLayerCount;
+ createInfo.ppEnabledLayerNames = enabledLayerNames;
createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledDeviceExtensions.size());
createInfo.ppEnabledExtensionNames =
enabledDeviceExtensions.empty() ? nullptr : enabledDeviceExtensions.data();
diff --git a/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.cpp b/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.cpp
new file mode 100644
index 0000000..a9473ef
--- /dev/null
+++ b/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.cpp
@@ -0,0 +1,87 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DisplayVkAndroid.cpp:
+// Implements the class methods for DisplayVkAndroid.
+//
+
+#include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
+
+#include <android/native_window.h>
+#include <vulkan/vulkan.h>
+
+#include "libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h"
+
+namespace rx
+{
+
+DisplayVkAndroid::DisplayVkAndroid(const egl::DisplayState &state) : DisplayVk(state)
+{
+}
+
+bool DisplayVkAndroid::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return (ANativeWindow_getFormat(window) >= 0);
+}
+
+SurfaceImpl *DisplayVkAndroid::createWindowSurfaceVk(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ EGLint width,
+ EGLint height)
+{
+ return new WindowSurfaceVkAndroid(state, window, width, height);
+}
+
+egl::ConfigSet DisplayVkAndroid::generateConfigs()
+{
+ // TODO(jmadill): Multiple configs, pbuffers, and proper checking of config attribs.
+ egl::Config singleton;
+ singleton.renderTargetFormat = GL_RGBA8;
+ singleton.depthStencilFormat = GL_NONE;
+ singleton.bufferSize = 32;
+ singleton.redSize = 8;
+ singleton.greenSize = 8;
+ singleton.blueSize = 8;
+ singleton.alphaSize = 8;
+ singleton.alphaMaskSize = 0;
+ singleton.bindToTextureRGB = EGL_FALSE;
+ singleton.bindToTextureRGBA = EGL_FALSE;
+ singleton.colorBufferType = EGL_RGB_BUFFER;
+ singleton.configCaveat = EGL_NONE;
+ singleton.conformant = 0;
+ singleton.depthSize = 0;
+ singleton.stencilSize = 0;
+ singleton.level = 0;
+ singleton.matchNativePixmap = EGL_NONE;
+ singleton.maxPBufferWidth = 0;
+ singleton.maxPBufferHeight = 0;
+ singleton.maxPBufferPixels = 0;
+ singleton.maxSwapInterval = 1;
+ singleton.minSwapInterval = 1;
+ singleton.nativeRenderable = EGL_TRUE;
+ singleton.nativeVisualID = 0;
+ singleton.nativeVisualType = EGL_NONE;
+ singleton.renderableType = EGL_OPENGL_ES2_BIT;
+ singleton.sampleBuffers = 0;
+ singleton.samples = 0;
+ singleton.surfaceType = EGL_WINDOW_BIT;
+ singleton.optimalOrientation = 0;
+ singleton.transparentType = EGL_NONE;
+ singleton.transparentRedValue = 0;
+ singleton.transparentGreenValue = 0;
+ singleton.transparentBlueValue = 0;
+ singleton.colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+
+ egl::ConfigSet configSet;
+ configSet.add(singleton);
+ return configSet;
+}
+
+const char *DisplayVkAndroid::getWSIName() const
+{
+ return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
+}
+
+} // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.h b/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.h
new file mode 100644
index 0000000..5a91f57
--- /dev/null
+++ b/src/libANGLE/renderer/vulkan/android/DisplayVkAndroid.h
@@ -0,0 +1,36 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DisplayVkAndroid.h:
+// Defines the class interface for DisplayVkAndroid, implementing DisplayVk for Android.
+//
+
+#ifndef LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_
+#define LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_
+
+#include "libANGLE/renderer/vulkan/DisplayVk.h"
+
+namespace rx
+{
+class DisplayVkAndroid : public DisplayVk
+{
+ public:
+ DisplayVkAndroid(const egl::DisplayState &state);
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ EGLint width,
+ EGLint height) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ const char *getWSIName() const override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_
diff --git a/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.cpp b/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.cpp
new file mode 100644
index 0000000..a9c9734
--- /dev/null
+++ b/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// WindowSurfaceVkAndroid.cpp:
+// Implements the class methods for WindowSurfaceVkAndroid.
+//
+
+#include "libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h"
+
+#include <android/native_window.h>
+
+#include "libANGLE/renderer/vulkan/RendererVk.h"
+
+namespace rx
+{
+
+WindowSurfaceVkAndroid::WindowSurfaceVkAndroid(const egl::SurfaceState &surfaceState,
+ EGLNativeWindowType window,
+ EGLint width,
+ EGLint height)
+ : WindowSurfaceVk(surfaceState, window, width, height)
+{
+}
+
+vk::ErrorOrResult<gl::Extents> WindowSurfaceVkAndroid::createSurfaceVk(RendererVk *renderer)
+{
+ VkAndroidSurfaceCreateInfoKHR createInfo;
+
+ createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = nullptr;
+ createInfo.flags = 0;
+ createInfo.window = mNativeWindowType;
+ ANGLE_VK_TRY(
+ vkCreateAndroidSurfaceKHR(renderer->getInstance(), &createInfo, nullptr, &mSurface));
+
+ int32_t width = ANativeWindow_getWidth(mNativeWindowType);
+ int32_t height = ANativeWindow_getHeight(mNativeWindowType);
+ ANGLE_VK_CHECK(width > 0 && height > 0, VK_ERROR_INITIALIZATION_FAILED);
+
+ return gl::Extents(width, height, 0);
+}
+
+} // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h b/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h
new file mode 100644
index 0000000..d2263f2
--- /dev/null
+++ b/src/libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// WindowSurfaceVkAndroid.h:
+// Defines the class interface for WindowSurfaceVkAndroid, implementing WindowSurfaceVk.
+//
+
+#ifndef LIBANGLE_RENDERER_VULKAN_ANDROID_WINDOWSURFACEVKANDROID_H_
+#define LIBANGLE_RENDERER_VULKAN_ANDROID_WINDOWSURFACEVKANDROID_H_
+
+#include "libANGLE/renderer/vulkan/SurfaceVk.h"
+
+namespace rx
+{
+
+class WindowSurfaceVkAndroid : public WindowSurfaceVk
+{
+ public:
+ WindowSurfaceVkAndroid(const egl::SurfaceState &surfaceState,
+ EGLNativeWindowType window,
+ EGLint width,
+ EGLint height);
+
+ private:
+ vk::ErrorOrResult<gl::Extents> createSurfaceVk(RendererVk *renderer) override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_VULKAN_ANDROID_WINDOWSURFACEVKANDROID_H_
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp
index 788ffbf..d9442b6 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp
@@ -107,11 +107,48 @@
}
}
+// Mirrors std_validation_str in loader.c
+const char *g_VkStdValidationLayerName = "VK_LAYER_LUNARG_standard_validation";
+const char *g_VkValidationLayerNames[] = {
+ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
+ "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
+ "VK_LAYER_GOOGLE_unique_objects"};
+const uint32_t g_VkNumValidationLayerNames =
+ sizeof(g_VkValidationLayerNames) / sizeof(g_VkValidationLayerNames[0]);
+
+bool HasValidationLayer(const std::vector<VkLayerProperties> &layerProps, const char *layerName)
+{
+ for (const auto &layerProp : layerProps)
+ {
+ if (std::string(layerProp.layerName) == layerName)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool HasStandardValidationLayer(const std::vector<VkLayerProperties> &layerProps)
+{
+ return HasValidationLayer(layerProps, g_VkStdValidationLayerName);
+}
+
+bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps)
+{
+ for (const auto &layerName : g_VkValidationLayerNames)
+ {
+ if (!HasValidationLayer(layerProps, layerName))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // anonymous namespace
-// Mirrors std_validation_str in loader.h
-// TODO(jmadill): Possibly wrap the loader into a safe source file. Can't be included trivially.
-const char *g_VkStdValidationLayerName = "VK_LAYER_LUNARG_standard_validation";
const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH";
const char *VulkanResultString(VkResult result)
@@ -175,17 +212,39 @@
}
}
-bool HasStandardValidationLayer(const std::vector<VkLayerProperties> &layerProps)
+bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerProps,
+ bool mustHaveLayers,
+ const char *const **enabledLayerNames,
+ uint32_t *enabledLayerCount)
{
- for (const auto &layerProp : layerProps)
+ if (HasStandardValidationLayer(layerProps))
{
- if (std::string(layerProp.layerName) == g_VkStdValidationLayerName)
+ *enabledLayerNames = &g_VkStdValidationLayerName;
+ *enabledLayerCount = 1;
+ }
+ else if (HasValidationLayers(layerProps))
+ {
+ *enabledLayerNames = g_VkValidationLayerNames;
+ *enabledLayerCount = g_VkNumValidationLayerNames;
+ }
+ else
+ {
+ // Generate an error if the layers were explicitly requested, warning otherwise.
+ if (mustHaveLayers)
{
- return true;
+ ERR() << "Vulkan validation layers are missing.";
}
+ else
+ {
+ WARN() << "Vulkan validation layers are missing.";
+ }
+
+ *enabledLayerNames = nullptr;
+ *enabledLayerCount = 0;
+ return false;
}
- return false;
+ return true;
}
namespace vk
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h
index 8ce2799..cb8b79d 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_utils.h
@@ -65,9 +65,12 @@
ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_VK_OBJECT);
const char *VulkanResultString(VkResult result);
-bool HasStandardValidationLayer(const std::vector<VkLayerProperties> &layerProps);
+// Verify that validation layers are available.
+bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerProps,
+ bool mustHaveLayers,
+ const char *const **enabledLayerNames,
+ uint32_t *enabledLayerCount);
-extern const char *g_VkStdValidationLayerName;
extern const char *g_VkLoaderLayersPathEnv;
enum class TextureDimension
diff --git a/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.cpp b/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.cpp
index 48a7bba..ca723e7 100644
--- a/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.cpp
+++ b/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.cpp
@@ -33,6 +33,51 @@
return new WindowSurfaceVkWin32(state, window, width, height);
}
+egl::ConfigSet DisplayVkWin32::generateConfigs()
+{
+ // TODO(jmadill): Multiple configs, pbuffers, and proper checking of config attribs.
+ egl::Config singleton;
+ singleton.renderTargetFormat = GL_BGRA8_EXT;
+ singleton.depthStencilFormat = GL_NONE;
+ singleton.bufferSize = 32;
+ singleton.redSize = 8;
+ singleton.greenSize = 8;
+ singleton.blueSize = 8;
+ singleton.alphaSize = 8;
+ singleton.alphaMaskSize = 0;
+ singleton.bindToTextureRGB = EGL_FALSE;
+ singleton.bindToTextureRGBA = EGL_FALSE;
+ singleton.colorBufferType = EGL_RGB_BUFFER;
+ singleton.configCaveat = EGL_NONE;
+ singleton.conformant = 0;
+ singleton.depthSize = 0;
+ singleton.stencilSize = 0;
+ singleton.level = 0;
+ singleton.matchNativePixmap = EGL_NONE;
+ singleton.maxPBufferWidth = 0;
+ singleton.maxPBufferHeight = 0;
+ singleton.maxPBufferPixels = 0;
+ singleton.maxSwapInterval = 1;
+ singleton.minSwapInterval = 1;
+ singleton.nativeRenderable = EGL_TRUE;
+ singleton.nativeVisualID = 0;
+ singleton.nativeVisualType = EGL_NONE;
+ singleton.renderableType = EGL_OPENGL_ES2_BIT;
+ singleton.sampleBuffers = 0;
+ singleton.samples = 0;
+ singleton.surfaceType = EGL_WINDOW_BIT;
+ singleton.optimalOrientation = 0;
+ singleton.transparentType = EGL_NONE;
+ singleton.transparentRedValue = 0;
+ singleton.transparentGreenValue = 0;
+ singleton.transparentBlueValue = 0;
+ singleton.colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+
+ egl::ConfigSet configSet;
+ configSet.add(singleton);
+ return configSet;
+}
+
const char *DisplayVkWin32::getWSIName() const
{
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
diff --git a/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.h b/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.h
index 5942155..ce04b6b 100644
--- a/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.h
+++ b/src/libANGLE/renderer/vulkan/win32/DisplayVkWin32.h
@@ -26,6 +26,8 @@
EGLint width,
EGLint height) override;
+ egl::ConfigSet generateConfigs() override;
+
const char *getWSIName() const override;
};
diff --git a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
index 68b1a09..346c1a9 100644
--- a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
+++ b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
@@ -61,6 +61,51 @@
return new WindowSurfaceVkXcb(state, window, width, height, mXcbConnection);
}
+egl::ConfigSet DisplayVkXcb::generateConfigs()
+{
+ // TODO(jmadill): Multiple configs, pbuffers, and proper checking of config attribs.
+ egl::Config singleton;
+ singleton.renderTargetFormat = GL_BGRA8_EXT;
+ singleton.depthStencilFormat = GL_NONE;
+ singleton.bufferSize = 32;
+ singleton.redSize = 8;
+ singleton.greenSize = 8;
+ singleton.blueSize = 8;
+ singleton.alphaSize = 8;
+ singleton.alphaMaskSize = 0;
+ singleton.bindToTextureRGB = EGL_FALSE;
+ singleton.bindToTextureRGBA = EGL_FALSE;
+ singleton.colorBufferType = EGL_RGB_BUFFER;
+ singleton.configCaveat = EGL_NONE;
+ singleton.conformant = 0;
+ singleton.depthSize = 0;
+ singleton.stencilSize = 0;
+ singleton.level = 0;
+ singleton.matchNativePixmap = EGL_NONE;
+ singleton.maxPBufferWidth = 0;
+ singleton.maxPBufferHeight = 0;
+ singleton.maxPBufferPixels = 0;
+ singleton.maxSwapInterval = 1;
+ singleton.minSwapInterval = 1;
+ singleton.nativeRenderable = EGL_TRUE;
+ singleton.nativeVisualID = 0;
+ singleton.nativeVisualType = EGL_NONE;
+ singleton.renderableType = EGL_OPENGL_ES2_BIT;
+ singleton.sampleBuffers = 0;
+ singleton.samples = 0;
+ singleton.surfaceType = EGL_WINDOW_BIT;
+ singleton.optimalOrientation = 0;
+ singleton.transparentType = EGL_NONE;
+ singleton.transparentRedValue = 0;
+ singleton.transparentGreenValue = 0;
+ singleton.transparentBlueValue = 0;
+ singleton.colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+
+ egl::ConfigSet configSet;
+ configSet.add(singleton);
+ return configSet;
+}
+
const char *DisplayVkXcb::getWSIName() const
{
return VK_KHR_XCB_SURFACE_EXTENSION_NAME;
diff --git a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
index eea95bb..2ecdaba 100644
--- a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
+++ b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
@@ -32,6 +32,8 @@
EGLint width,
EGLint height) override;
+ egl::ConfigSet generateConfigs() override;
+
const char *getWSIName() const override;
private: