Commit 605af42e by Michael Spang Committed by Commit Bot

Vulkan: Move ICD overrides to a common place

We also need the bundled ICDs and selection logic for certain tests that create a vulkan instance. If we don't, the tests will use default vulkan even if ANGLE is using swiftshader-vulkan. Tests of driver specific handle types (e..g opaque fd) will fail in this case. Bug: angleproject:4092 Change-Id: Iff089c9341b8b533ee8634923d0177c5dbcd5cc8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2088659 Commit-Queue: Michael Spang <spang@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 3c2d329c
# Copyright 2020 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.
import("//build_overrides/swiftshader.gni")
import("../../../gni/angle.gni")
assert(angle_enable_vulkan)
angle_source_set("vulkan") {
sources = [
"vulkan_icd.cpp",
"vulkan_icd.h",
]
public_deps = [
"$angle_root:angle_common",
"$angle_root/src/libANGLE/renderer/vulkan:angle_vulkan_entry_points",
]
defines = [
"ANGLE_VK_LAYERS_DIR=\"$angle_data_dir\"",
"ANGLE_VK_MOCK_ICD_JSON=\"$angle_data_dir/VkICD_mock_icd.json\"",
]
deps = []
data_deps = []
if (!is_android && !is_fuchsia && !is_ggp) {
if (angle_shared_libvulkan) {
data_deps += [ "$angle_root/third_party/vulkan-loader/src:libvulkan" ]
} else {
deps += [ "$angle_root/third_party/vulkan-loader/src:libvulkan" ]
}
data_deps += [ "$angle_root/third_party/vulkan-tools/src:VkICD_mock_icd" ]
}
if (angle_enable_vulkan_validation_layers) {
defines += [ "ANGLE_ENABLE_VULKAN_VALIDATION_LAYERS_BY_DEFAULT" ]
if (is_fuchsia) {
data_deps += [ "//third_party/fuchsia-sdk:vulkan_validation" ]
} else {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers/src:vulkan_validation_layers" ]
if (!is_android) {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers/src:vulkan_gen_json_files" ]
}
}
}
if (angle_enable_swiftshader) {
import("$swiftshader_dir/src/Vulkan/vulkan.gni")
_sws_icd = "./$swiftshader_icd_file_name"
if (is_win) {
_sws_icd = ".\\\\$swiftshader_icd_file_name"
}
defines += [ "ANGLE_VK_SWIFTSHADER_ICD_JSON=\"${_sws_icd}\"" ]
data_deps += [
"$swiftshader_dir/src/Vulkan:icd_file",
"$swiftshader_dir/src/Vulkan:swiftshader_libvulkan",
]
}
}
//
// Copyright 2020 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.
//
// vulkan_icd.cpp : Helper for creating vulkan instances & selecting physical device.
#include "common/vulkan/vulkan_icd.h"
#include <functional>
#include <vector>
#include "common/bitset_utils.h"
#include "common/debug.h"
#include "common/system_utils.h"
namespace angle
{
namespace vk
{
namespace
{
// This function is unused on Android/Fuschia/GGP
#if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA) && \
!defined(ANGLE_PLATFORM_GGP)
const std::string WrapICDEnvironment(const char *icdEnvironment)
{
# if defined(ANGLE_PLATFORM_APPLE)
// On MacOS the libraries are bundled into the application directory
std::string ret = angle::GetHelperExecutableDir() + icdEnvironment;
return ret;
# endif // defined(ANGLE_PLATFORM_APPLE)
return icdEnvironment;
}
constexpr char kLoaderLayersPathEnv[] = "VK_LAYER_PATH";
#endif
constexpr char kLoaderICDFilenamesEnv[] = "VK_ICD_FILENAMES";
constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
constexpr uint32_t kMockVendorID = 0xba5eba11;
constexpr uint32_t kMockDeviceID = 0xf005ba11;
constexpr char kMockDeviceName[] = "Vulkan Mock Device";
constexpr uint32_t kGoogleVendorID = 0x1AE0;
constexpr uint32_t kSwiftShaderDeviceID = 0xC0DE;
constexpr char kSwiftShaderDeviceName[] = "SwiftShader Device";
using ICDFilterFunc = std::function<bool(const VkPhysicalDeviceProperties &)>;
ICDFilterFunc GetFilterForICD(vk::ICD preferredICD)
{
switch (preferredICD)
{
case vk::ICD::Mock:
return [](const VkPhysicalDeviceProperties &deviceProperties) {
return ((deviceProperties.vendorID == kMockVendorID) &&
(deviceProperties.deviceID == kMockDeviceID) &&
(strcmp(deviceProperties.deviceName, kMockDeviceName) == 0));
};
case vk::ICD::SwiftShader:
return [](const VkPhysicalDeviceProperties &deviceProperties) {
return ((deviceProperties.vendorID == kGoogleVendorID) &&
(deviceProperties.deviceID == kSwiftShaderDeviceID) &&
(strncmp(deviceProperties.deviceName, kSwiftShaderDeviceName,
strlen(kSwiftShaderDeviceName)) == 0));
};
default:
const std::string anglePreferredDevice =
angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
return [anglePreferredDevice](const VkPhysicalDeviceProperties &deviceProperties) {
return (anglePreferredDevice.empty() ||
anglePreferredDevice == deviceProperties.deviceName);
};
}
}
} // namespace
// 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.
ScopedVkLoaderEnvironment::ScopedVkLoaderEnvironment(bool enableValidationLayers, vk::ICD icd)
: mEnableValidationLayers(enableValidationLayers),
mICD(icd),
mChangedCWD(false),
mChangedICDEnv(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) && !defined(ANGLE_PLATFORM_FUCHSIA) && \
!defined(ANGLE_PLATFORM_GGP)
if (icd == vk::ICD::Mock)
{
if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_MOCK_ICD_JSON).c_str()))
{
ERR() << "Error setting environment for Mock/Null Driver.";
}
}
# if defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
else if (icd == vk::ICD::SwiftShader)
{
if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_SWIFTSHADER_ICD_JSON).c_str()))
{
ERR() << "Error setting environment for SwiftShader.";
}
}
# endif // defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
if (mEnableValidationLayers || icd != vk::ICD::Default)
{
const auto &cwd = angle::GetCWD();
if (!cwd.valid())
{
ERR() << "Error getting CWD for Vulkan layers init.";
mEnableValidationLayers = false;
mICD = vk::ICD::Default;
}
else
{
mPreviousCWD = cwd.value();
std::string exeDir = angle::GetExecutableDirectory();
mChangedCWD = angle::SetCWD(exeDir.c_str());
if (!mChangedCWD)
{
ERR() << "Error setting CWD for Vulkan layers init.";
mEnableValidationLayers = false;
mICD = vk::ICD::Default;
}
}
}
// Override environment variable to use the ANGLE layers.
if (mEnableValidationLayers)
{
if (!angle::PrependPathToEnvironmentVar(kLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
{
ERR() << "Error setting environment for Vulkan layers init.";
mEnableValidationLayers = false;
}
}
#endif // !defined(ANGLE_PLATFORM_ANDROID)
}
ScopedVkLoaderEnvironment::~ScopedVkLoaderEnvironment()
{
if (mChangedCWD)
{
#if !defined(ANGLE_PLATFORM_ANDROID)
ASSERT(mPreviousCWD.valid());
angle::SetCWD(mPreviousCWD.value().c_str());
#endif // !defined(ANGLE_PLATFORM_ANDROID)
}
if (mChangedICDEnv)
{
if (mPreviousICDEnv.value().empty())
{
angle::UnsetEnvironmentVar(kLoaderICDFilenamesEnv);
}
else
{
angle::SetEnvironmentVar(kLoaderICDFilenamesEnv, mPreviousICDEnv.value().c_str());
}
}
}
bool ScopedVkLoaderEnvironment::setICDEnvironment(const char *icd)
{
// Override environment variable to use built Mock ICD
// ANGLE_VK_ICD_JSON gets set to the built mock ICD in BUILD.gn
mPreviousICDEnv = angle::GetEnvironmentVar(kLoaderICDFilenamesEnv);
mChangedICDEnv = angle::SetEnvironmentVar(kLoaderICDFilenamesEnv, icd);
if (!mChangedICDEnv)
{
mICD = vk::ICD::Default;
}
return mChangedICDEnv;
}
void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
vk::ICD preferredICD,
VkPhysicalDevice *physicalDeviceOut,
VkPhysicalDeviceProperties *physicalDevicePropertiesOut)
{
ASSERT(!physicalDevices.empty());
ICDFilterFunc filter = GetFilterForICD(preferredICD);
for (const VkPhysicalDevice &physicalDevice : physicalDevices)
{
vkGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
if (filter(*physicalDevicePropertiesOut))
{
*physicalDeviceOut = physicalDevice;
return;
}
}
WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
// Fall back to first device.
*physicalDeviceOut = physicalDevices[0];
vkGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
}
} // namespace vk
} // namespace angle
//
// Copyright 2020 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.
//
// vulkan_icd.h : Helper for creating vulkan instances & selecting physical device.
#ifndef COMMON_VULKAN_VULKAN_ICD_H_
#define COMMON_VULKAN_VULKAN_ICD_H_
#include <string>
#include "common/Optional.h"
#include "common/angleutils.h"
#include "libANGLE/renderer/vulkan/vk_headers.h"
namespace angle
{
namespace vk
{
enum class ICD
{
Default,
Mock,
SwiftShader,
};
class ScopedVkLoaderEnvironment : angle::NonCopyable
{
public:
ScopedVkLoaderEnvironment(bool enableValidationLayers, vk::ICD icd);
~ScopedVkLoaderEnvironment();
bool canEnableValidationLayers() const { return mEnableValidationLayers; }
vk::ICD getEnabledICD() const { return mICD; }
private:
bool setICDEnvironment(const char *icd);
bool mEnableValidationLayers;
vk::ICD mICD;
bool mChangedCWD;
Optional<std::string> mPreviousCWD;
bool mChangedICDEnv;
Optional<std::string> mPreviousICDEnv;
};
void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
vk::ICD preferredICD,
VkPhysicalDevice *physicalDeviceOut,
VkPhysicalDeviceProperties *physicalDevicePropertiesOut);
} // namespace vk
} // namespace angle
#endif // COMMON_VULKAN_VULKAN_ICD_H_
...@@ -241,16 +241,12 @@ angle_source_set("angle_vulkan_backend") { ...@@ -241,16 +241,12 @@ angle_source_set("angle_vulkan_backend") {
public_deps = [ public_deps = [
"$angle_root:angle_glslang_wrapper", "$angle_root:angle_glslang_wrapper",
"$angle_root:libANGLE_headers", "$angle_root:libANGLE_headers",
"$angle_root/src/common/vulkan",
] ]
public_configs = [ ":angle_vulkan_backend_config" ] public_configs = [ ":angle_vulkan_backend_config" ]
data_deps = [] data_deps = []
defines = [
"ANGLE_VK_LAYERS_DIR=\"$angle_data_dir\"",
"ANGLE_VK_MOCK_ICD_JSON=\"$angle_data_dir/VkICD_mock_icd.json\"",
]
if (is_android) { if (is_android) {
libs += [ "vulkan" ] libs += [ "vulkan" ]
} }
...@@ -258,40 +254,4 @@ angle_source_set("angle_vulkan_backend") { ...@@ -258,40 +254,4 @@ angle_source_set("angle_vulkan_backend") {
# Include generated shaders. # Include generated shaders.
import("vk_internal_shaders_autogen.gni") import("vk_internal_shaders_autogen.gni")
sources += angle_vulkan_internal_shaders sources += angle_vulkan_internal_shaders
if (!is_android && !is_fuchsia && !is_ggp) {
if (angle_shared_libvulkan) {
data_deps += [ "$angle_root/third_party/vulkan-loader/src:libvulkan" ]
} else {
deps += [ "$angle_root/third_party/vulkan-loader/src:libvulkan" ]
}
data_deps += [ "$angle_root/third_party/vulkan-tools/src:VkICD_mock_icd" ]
}
if (angle_enable_vulkan_validation_layers) {
defines += [ "ANGLE_ENABLE_VULKAN_VALIDATION_LAYERS_BY_DEFAULT" ]
if (is_fuchsia) {
data_deps += [ "//third_party/fuchsia-sdk:vulkan_validation" ]
} else {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers/src:vulkan_validation_layers" ]
if (!is_android) {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers/src:vulkan_gen_json_files" ]
}
}
}
if (angle_enable_swiftshader) {
import("$swiftshader_dir/src/Vulkan/vulkan.gni")
_sws_icd = "./$swiftshader_icd_file_name"
if (is_win) {
_sws_icd = ".\\\\$swiftshader_icd_file_name"
}
defines += [ "ANGLE_VK_SWIFTSHADER_ICD_JSON=\"${_sws_icd}\"" ]
data_deps += [
"$swiftshader_dir/src/Vulkan:icd_file",
"$swiftshader_dir/src/Vulkan:swiftshader_libvulkan",
]
}
} }
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "common/PackedEnums.h" #include "common/PackedEnums.h"
#include "common/PoolAlloc.h" #include "common/PoolAlloc.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/vulkan/vulkan_icd.h"
#include "libANGLE/BlobCache.h" #include "libANGLE/BlobCache.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/renderer/vulkan/QueryVk.h" #include "libANGLE/renderer/vulkan/QueryVk.h"
...@@ -154,7 +155,7 @@ class RendererVk : angle::NonCopyable ...@@ -154,7 +155,7 @@ class RendererVk : angle::NonCopyable
return mMinImportedHostPointerAlignment; return mMinImportedHostPointerAlignment;
} }
bool isMockICDEnabled() const { return mEnabledICD == vk::ICD::Mock; } bool isMockICDEnabled() const { return mEnabledICD == angle::vk::ICD::Mock; }
// Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
// bufferFeatures). Looks through mandatory features first, and falls back to querying the // bufferFeatures). Looks through mandatory features first, and falls back to querying the
...@@ -281,7 +282,7 @@ class RendererVk : angle::NonCopyable ...@@ -281,7 +282,7 @@ class RendererVk : angle::NonCopyable
VkInstance mInstance; VkInstance mInstance;
bool mEnableValidationLayers; bool mEnableValidationLayers;
bool mEnableDebugUtils; bool mEnableDebugUtils;
vk::ICD mEnabledICD; angle::vk::ICD mEnabledICD;
VkDebugUtilsMessengerEXT mDebugUtilsMessenger; VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
VkDebugReportCallbackEXT mDebugReportCallback; VkDebugReportCallbackEXT mDebugReportCallback;
VkPhysicalDevice mPhysicalDevice; VkPhysicalDevice mPhysicalDevice;
......
...@@ -117,17 +117,6 @@ void AddToPNextChain(VulkanStruct1 *chainStart, VulkanStruct2 *ptr) ...@@ -117,17 +117,6 @@ void AddToPNextChain(VulkanStruct1 *chainStart, VulkanStruct2 *ptr)
localPtr->pNext = reinterpret_cast<VkBaseOutStructure *>(ptr); localPtr->pNext = reinterpret_cast<VkBaseOutStructure *>(ptr);
} }
extern const char *gLoaderLayersPathEnv;
extern const char *gLoaderICDFilenamesEnv;
extern const char *gANGLEPreferredDevice;
enum class ICD
{
Default,
Mock,
SwiftShader,
};
// Abstracts error handling. Implemented by both ContextVk for GL and DisplayVk for EGL errors. // Abstracts error handling. Implemented by both ContextVk for GL and DisplayVk for EGL errors.
class Context : angle::NonCopyable class Context : angle::NonCopyable
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment