Commit d2766ce7 by Jamie Madill Committed by Commit Bot

Vulkan: Generalize ICD decision for loader.

This will allow a more flexible introduction of other ICDs like SwiftShader. Refactoring change only. Bug: angleproject:3876 Change-Id: I6883225645e0f961f699366368bebccd9812aaec Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1775463 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0b1fbcff
...@@ -58,16 +58,26 @@ constexpr uint64_t kMaxFenceWaitTimeNs = 10'000'000'000llu; ...@@ -58,16 +58,26 @@ constexpr uint64_t kMaxFenceWaitTimeNs = 10'000'000'000llu;
// version of Vulkan. // version of Vulkan.
constexpr uint32_t kPreferredVulkanAPIVersion = VK_API_VERSION_1_1; constexpr uint32_t kPreferredVulkanAPIVersion = VK_API_VERSION_1_1;
bool ShouldEnableMockICD(const egl::AttributeMap &attribs) vk::ICD ChooseICDFromAttribs(const egl::AttributeMap &attribs)
{ {
#if !defined(ANGLE_PLATFORM_ANDROID) #if !defined(ANGLE_PLATFORM_ANDROID)
// Mock ICD does not currently run on Android // Mock ICD does not currently run on Android
return (attribs.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGLAttrib deviceType = attribs.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE) == EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
#else switch (deviceType)
return false; {
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
return vk::ICD::Mock;
default:
UNREACHABLE();
break;
}
#endif // !defined(ANGLE_PLATFORM_ANDROID) #endif // !defined(ANGLE_PLATFORM_ANDROID)
return vk::ICD::Default;
} }
bool StrLess(const char *a, const char *b) bool StrLess(const char *a, const char *b)
...@@ -335,9 +345,9 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags, ...@@ -335,9 +345,9 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
class ScopedVkLoaderEnvironment : angle::NonCopyable class ScopedVkLoaderEnvironment : angle::NonCopyable
{ {
public: public:
ScopedVkLoaderEnvironment(bool enableValidationLayers, bool enableMockICD) ScopedVkLoaderEnvironment(bool enableValidationLayers, vk::ICD icd)
: mEnableValidationLayers(enableValidationLayers), : mEnableValidationLayers(enableValidationLayers),
mEnableMockICD(enableMockICD), mICD(icd),
mChangedCWD(false), mChangedCWD(false),
mChangedICDEnv(false) mChangedICDEnv(false)
{ {
...@@ -345,27 +355,21 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -345,27 +355,21 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
// since this code is a part of Java application there. // since this code is a part of Java application there.
// Android Vulkan loader doesn't need this either. // Android Vulkan loader doesn't need this either.
#if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA) #if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA)
if (enableMockICD) if (icd == vk::ICD::Mock)
{ {
// Override environment variable to use built Mock ICD if (!setICDEnvironment(ANGLE_VK_MOCK_ICD_JSON))
// ANGLE_VK_ICD_JSON gets set to the built mock ICD in BUILD.gn
mPreviousICDEnv = angle::GetEnvironmentVar(gVkLoaderICDFilenamesEnv);
mChangedICDEnv =
angle::SetEnvironmentVar(gVkLoaderICDFilenamesEnv, ANGLE_VK_MOCK_ICD_JSON);
if (!mChangedICDEnv)
{ {
ERR() << "Error setting Path for Mock/Null Driver."; ERR() << "Error setting environment for Mock/Null Driver.";
mEnableMockICD = false;
} }
} }
if (mEnableValidationLayers || mEnableMockICD) if (mEnableValidationLayers || icd != vk::ICD::Default)
{ {
const auto &cwd = angle::GetCWD(); const auto &cwd = angle::GetCWD();
if (!cwd.valid()) if (!cwd.valid())
{ {
ERR() << "Error getting CWD for Vulkan layers init."; ERR() << "Error getting CWD for Vulkan layers init.";
mEnableValidationLayers = false; mEnableValidationLayers = false;
mEnableMockICD = false; mICD = vk::ICD::Default;
} }
else else
{ {
...@@ -376,7 +380,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -376,7 +380,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
{ {
ERR() << "Error setting CWD for Vulkan layers init."; ERR() << "Error setting CWD for Vulkan layers init.";
mEnableValidationLayers = false; mEnableValidationLayers = false;
mEnableMockICD = false; mICD = vk::ICD::Default;
} }
} }
} }
...@@ -384,7 +388,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -384,7 +388,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
// Override environment variable to use the ANGLE layers. // Override environment variable to use the ANGLE layers.
if (mEnableValidationLayers) if (mEnableValidationLayers)
{ {
if (!angle::PrependPathToEnvironmentVar(gVkLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR)) if (!angle::PrependPathToEnvironmentVar(vk::gLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
{ {
ERR() << "Error setting environment for Vulkan layers init."; ERR() << "Error setting environment for Vulkan layers init.";
mEnableValidationLayers = false; mEnableValidationLayers = false;
...@@ -406,22 +410,36 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -406,22 +410,36 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
{ {
if (mPreviousICDEnv.value().empty()) if (mPreviousICDEnv.value().empty())
{ {
angle::UnsetEnvironmentVar(gVkLoaderICDFilenamesEnv); angle::UnsetEnvironmentVar(vk::gLoaderICDFilenamesEnv);
} }
else else
{ {
angle::SetEnvironmentVar(gVkLoaderICDFilenamesEnv, mPreviousICDEnv.value().c_str()); angle::SetEnvironmentVar(vk::gLoaderICDFilenamesEnv,
mPreviousICDEnv.value().c_str());
} }
} }
} }
bool canEnableValidationLayers() const { return mEnableValidationLayers; } bool canEnableValidationLayers() const { return mEnableValidationLayers; }
vk::ICD getEnabledICD() const { return mICD; }
bool canEnableMockICD() const { return mEnableMockICD; }
private: private:
bool 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(vk::gLoaderICDFilenamesEnv);
mChangedICDEnv = angle::SetEnvironmentVar(vk::gLoaderICDFilenamesEnv, icd);
if (!mChangedICDEnv)
{
mICD = vk::ICD::Default;
}
return mChangedICDEnv;
}
bool mEnableValidationLayers; bool mEnableValidationLayers;
bool mEnableMockICD; vk::ICD mICD;
bool mChangedCWD; bool mChangedCWD;
Optional<std::string> mPreviousCWD; Optional<std::string> mPreviousCWD;
bool mChangedICDEnv; bool mChangedICDEnv;
...@@ -429,12 +447,12 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -429,12 +447,12 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
}; };
void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices, void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
bool preferMockICD, vk::ICD preferredICD,
VkPhysicalDevice *physicalDeviceOut, VkPhysicalDevice *physicalDeviceOut,
VkPhysicalDeviceProperties *physicalDevicePropertiesOut) VkPhysicalDeviceProperties *physicalDevicePropertiesOut)
{ {
ASSERT(!physicalDevices.empty()); ASSERT(!physicalDevices.empty());
if (preferMockICD) if (preferredICD == vk::ICD::Mock)
{ {
for (const VkPhysicalDevice &physicalDevice : physicalDevices) for (const VkPhysicalDevice &physicalDevice : physicalDevices)
{ {
...@@ -489,7 +507,7 @@ RendererVk::RendererVk() ...@@ -489,7 +507,7 @@ RendererVk::RendererVk()
mFeaturesInitialized(false), mFeaturesInitialized(false),
mInstance(VK_NULL_HANDLE), mInstance(VK_NULL_HANDLE),
mEnableValidationLayers(false), mEnableValidationLayers(false),
mEnableMockICD(false), mEnabledICD(vk::ICD::Default),
mDebugUtilsMessenger(VK_NULL_HANDLE), mDebugUtilsMessenger(VK_NULL_HANDLE),
mDebugReportCallback(VK_NULL_HANDLE), mDebugReportCallback(VK_NULL_HANDLE),
mPhysicalDevice(VK_NULL_HANDLE), mPhysicalDevice(VK_NULL_HANDLE),
...@@ -573,9 +591,9 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk, ...@@ -573,9 +591,9 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
mDisplay = display; mDisplay = display;
const egl::AttributeMap &attribs = mDisplay->getAttributeMap(); const egl::AttributeMap &attribs = mDisplay->getAttributeMap();
ScopedVkLoaderEnvironment scopedEnvironment(ShouldUseDebugLayers(attribs), ScopedVkLoaderEnvironment scopedEnvironment(ShouldUseDebugLayers(attribs),
ShouldEnableMockICD(attribs)); ChooseICDFromAttribs(attribs));
mEnableValidationLayers = scopedEnvironment.canEnableValidationLayers(); mEnableValidationLayers = scopedEnvironment.canEnableValidationLayers();
mEnableMockICD = scopedEnvironment.canEnableMockICD(); mEnabledICD = scopedEnvironment.getEnabledICD();
// Gather global layer properties. // Gather global layer properties.
uint32_t instanceLayerCount = 0; uint32_t instanceLayerCount = 0;
...@@ -772,7 +790,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk, ...@@ -772,7 +790,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount); std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
ANGLE_VK_TRY(displayVk, vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount, ANGLE_VK_TRY(displayVk, vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount,
physicalDevices.data())); physicalDevices.data()));
ChoosePhysicalDevice(physicalDevices, mEnableMockICD, &mPhysicalDevice, ChoosePhysicalDevice(physicalDevices, mEnabledICD, &mPhysicalDevice,
&mPhysicalDeviceProperties); &mPhysicalDeviceProperties);
vkGetPhysicalDeviceFeatures(mPhysicalDevice, &mPhysicalDeviceFeatures); vkGetPhysicalDeviceFeatures(mPhysicalDevice, &mPhysicalDeviceFeatures);
......
...@@ -126,7 +126,7 @@ class RendererVk : angle::NonCopyable ...@@ -126,7 +126,7 @@ class RendererVk : angle::NonCopyable
return mFeatures; return mFeatures;
} }
bool isMockICDEnabled() const { return mEnableMockICD; } bool isMockICDEnabled() const { return mEnabledICD == 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
...@@ -192,7 +192,7 @@ class RendererVk : angle::NonCopyable ...@@ -192,7 +192,7 @@ class RendererVk : angle::NonCopyable
VkInstance mInstance; VkInstance mInstance;
bool mEnableValidationLayers; bool mEnableValidationLayers;
bool mEnableMockICD; vk::ICD mEnabledICD;
VkDebugUtilsMessengerEXT mDebugUtilsMessenger; VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
VkDebugReportCallbackEXT mDebugReportCallback; VkDebugReportCallbackEXT mDebugReportCallback;
VkPhysicalDevice mPhysicalDevice; VkPhysicalDevice mPhysicalDevice;
......
...@@ -150,9 +150,6 @@ angle::Result AllocateBufferOrImageMemory(vk::Context *context, ...@@ -150,9 +150,6 @@ angle::Result AllocateBufferOrImageMemory(vk::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
const char *gVkLoaderLayersPathEnv = "VK_LAYER_PATH";
const char *gVkLoaderICDFilenamesEnv = "VK_ICD_FILENAMES";
const char *VulkanResultString(VkResult result) const char *VulkanResultString(VkResult result)
{ {
switch (result) switch (result)
...@@ -249,6 +246,9 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro ...@@ -249,6 +246,9 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro
namespace vk namespace vk
{ {
const char *gLoaderLayersPathEnv = "VK_LAYER_PATH";
const char *gLoaderICDFilenamesEnv = "VK_ICD_FILENAMES";
VkImageAspectFlags GetDepthStencilAspectFlags(const angle::Format &format) VkImageAspectFlags GetDepthStencilAspectFlags(const angle::Format &format)
{ {
return (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) | return (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
......
...@@ -87,9 +87,6 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro ...@@ -87,9 +87,6 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro
bool mustHaveLayers, bool mustHaveLayers,
VulkanLayerVector *enabledLayerNames); VulkanLayerVector *enabledLayerNames);
extern const char *gVkLoaderLayersPathEnv;
extern const char *gVkLoaderICDFilenamesEnv;
enum class TextureDimension enum class TextureDimension
{ {
TEX_2D, TEX_2D,
...@@ -102,6 +99,15 @@ namespace vk ...@@ -102,6 +99,15 @@ namespace vk
{ {
struct Format; struct Format;
extern const char *gLoaderLayersPathEnv;
extern const char *gLoaderICDFilenamesEnv;
enum class ICD
{
Default,
Mock,
};
// 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