Commit a3b220f3 by Tobin Ehlis Committed by Commit Bot

Vulkan: Adding null driver as device option

Bug: angleproject:2159 Plumbing to allow VK Mock ICD to be selected as the Vulkan driver. Adding new ANGLE env var "ANGLE_VK_ICD_JSON" to point to json file of mock ICD in angle and use this to override Vk loader ICD search path. At Vulkan renderer initialization time, enable the Mock ICD if device is EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE. Default physicalDevice is still the first detected device. If Mock ICD is requested but not available, fall back to the first device that was detected. Added a VULKAN_NULL() testing config that uses Vulkan as renderer but NULL as device. Turned on Vulkan NULL testing for DrawCallPerf. Change-Id: I04e15c14e998448f8c98f9fd72e796389f297993 Reviewed-on: https://chromium-review.googlesource.com/961494 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8a02d3b5
...@@ -28,6 +28,14 @@ ...@@ -28,6 +28,14 @@
#include "libANGLE/renderer/vulkan/vk_format_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "platform/Platform.h" #include "platform/Platform.h"
// Consts
namespace
{
const uint32_t kMockVendorID = 0xba5eba11;
const uint32_t kMockDeviceID = 0xf005ba11;
constexpr char kMockDeviceName[] = "Vulkan Mock Device";
} // anonymous namespace
namespace rx namespace rx
{ {
...@@ -125,7 +133,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -125,7 +133,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(g_VkLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR)) if (!angle::PrependPathToEnvironmentVar(g_VkLoaderLayersPathEnv, ANGLE_VK_DATA_DIR))
{ {
ERR() << "Error setting environment for Vulkan layers init."; ERR() << "Error setting environment for Vulkan layers init.";
mEnableValidationLayers = false; mEnableValidationLayers = false;
...@@ -251,11 +259,53 @@ RendererVk::~RendererVk() ...@@ -251,11 +259,53 @@ RendererVk::~RendererVk()
mPhysicalDevice = VK_NULL_HANDLE; mPhysicalDevice = VK_NULL_HANDLE;
} }
void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
bool preferMockICD,
VkPhysicalDevice *physicalDeviceOut,
VkPhysicalDeviceProperties *physicalDevicePropertiesOut)
{
ASSERT(!physicalDevices.empty());
if (preferMockICD)
{
for (const VkPhysicalDevice &physicalDevice : physicalDevices)
{
vkGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
if ((kMockVendorID == physicalDevicePropertiesOut->vendorID) &&
(kMockDeviceID == physicalDevicePropertiesOut->deviceID) &&
(strcmp(kMockDeviceName, physicalDevicePropertiesOut->deviceName) == 0))
{
*physicalDeviceOut = physicalDevice;
return;
}
}
WARN() << "Vulkan Mock Driver was requested but Mock Device was not found. Using default "
"physicalDevice instead.";
}
// Fall back to first device.
*physicalDeviceOut = physicalDevices[0];
vkGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
}
vk::Error RendererVk::initialize(const egl::AttributeMap &attribs, const char *wsiName) vk::Error RendererVk::initialize(const egl::AttributeMap &attribs, const char *wsiName)
{ {
ScopedVkLoaderEnvironment scopedEnvironment(ShouldUseDebugLayers(attribs)); ScopedVkLoaderEnvironment scopedEnvironment(ShouldUseDebugLayers(attribs));
mEnableValidationLayers = scopedEnvironment.canEnableValidationLayers(); mEnableValidationLayers = scopedEnvironment.canEnableValidationLayers();
bool enableNullDriver = false;
#if !defined(ANGLE_PLATFORM_ANDROID)
// Mock ICD does not currently run on Android
enableNullDriver = (attribs.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE) ==
EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
if (enableNullDriver)
{
// Override environment variable to use built Mock ICD
// ANGLE_VK_ICD_JSON gets set to the built mock ICD in BUILD.gn
ANGLE_VK_CHECK(angle::SetEnvironmentVar(g_VkICDPathEnv, ANGLE_VK_ICD_JSON),
VK_ERROR_INITIALIZATION_FAILED);
}
#endif // !defined(ANGLE_PLATFORM_ANDROID)
// Gather global layer properties. // Gather global layer properties.
uint32_t instanceLayerCount = 0; uint32_t instanceLayerCount = 0;
ANGLE_VK_TRY(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr)); ANGLE_VK_TRY(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
...@@ -348,10 +398,11 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs, const char *w ...@@ -348,10 +398,11 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs, const char *w
ANGLE_VK_CHECK(physicalDeviceCount > 0, VK_ERROR_INITIALIZATION_FAILED); ANGLE_VK_CHECK(physicalDeviceCount > 0, VK_ERROR_INITIALIZATION_FAILED);
// TODO(jmadill): Handle multiple physical devices. For now, use the first device. // TODO(jmadill): Handle multiple physical devices. For now, use the first device.
physicalDeviceCount = 1; std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
ANGLE_VK_TRY(vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount, &mPhysicalDevice)); ANGLE_VK_TRY(
vkEnumeratePhysicalDevices(mInstance, &physicalDeviceCount, physicalDevices.data()));
vkGetPhysicalDeviceProperties(mPhysicalDevice, &mPhysicalDeviceProperties); ChoosePhysicalDevice(physicalDevices, enableNullDriver, &mPhysicalDevice,
&mPhysicalDeviceProperties);
// Ensure we can find a graphics queue family. // Ensure we can find a graphics queue family.
uint32_t queueCount = 0; uint32_t queueCount = 0;
......
...@@ -198,6 +198,7 @@ vk::Error AllocateBufferOrImageMemory(RendererVk *renderer, ...@@ -198,6 +198,7 @@ vk::Error AllocateBufferOrImageMemory(RendererVk *renderer,
} // anonymous namespace } // anonymous namespace
const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH"; const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH";
const char *g_VkICDPathEnv = "VK_ICD_FILENAMES";
const char *VulkanResultString(VkResult result) const char *VulkanResultString(VkResult result)
{ {
......
...@@ -74,6 +74,7 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro ...@@ -74,6 +74,7 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro
uint32_t *enabledLayerCount); uint32_t *enabledLayerCount);
extern const char *g_VkLoaderLayersPathEnv; extern const char *g_VkLoaderLayersPathEnv;
extern const char *g_VkICDPathEnv;
enum class TextureDimension enum class TextureDimension
{ {
......
...@@ -190,7 +190,9 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark, ...@@ -190,7 +190,9 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
DrawArrays(DrawCallPerfOpenGLOrGLESParams(true, true), false), DrawArrays(DrawCallPerfOpenGLOrGLESParams(true, true), false),
DrawArrays(DrawCallPerfOpenGLOrGLESParams(true, false), true), DrawArrays(DrawCallPerfOpenGLOrGLESParams(true, false), true),
DrawArrays(DrawCallPerfValidationOnly(), false), DrawArrays(DrawCallPerfValidationOnly(), false),
DrawArrays(DrawCallPerfVulkanParams(false), false), DrawArrays(DrawCallPerfVulkanParams(true, false), true),
DrawArrays(DrawCallPerfVulkanParams(false), true)); DrawArrays(DrawCallPerfVulkanParams(true, false), false),
DrawArrays(DrawCallPerfVulkanParams(false, false), false),
DrawArrays(DrawCallPerfVulkanParams(false, false), true));
} // namespace } // namespace
...@@ -71,10 +71,10 @@ DrawCallPerfParams DrawCallPerfValidationOnly() ...@@ -71,10 +71,10 @@ DrawCallPerfParams DrawCallPerfValidationOnly()
return params; return params;
} }
DrawCallPerfParams DrawCallPerfVulkanParams(bool renderToTexture) DrawCallPerfParams DrawCallPerfVulkanParams(bool useNullDevice, bool renderToTexture)
{ {
DrawCallPerfParams params; DrawCallPerfParams params;
params.eglParameters = VULKAN(); params.eglParameters = useNullDevice ? VULKAN_NULL() : VULKAN();
params.useFBO = renderToTexture; params.useFBO = renderToTexture;
return params; return params;
} }
...@@ -38,6 +38,6 @@ DrawCallPerfParams DrawCallPerfD3D11Params(bool useNullDevice, bool renderToText ...@@ -38,6 +38,6 @@ DrawCallPerfParams DrawCallPerfD3D11Params(bool useNullDevice, bool renderToText
DrawCallPerfParams DrawCallPerfD3D9Params(bool useNullDevice, bool renderToTexture); DrawCallPerfParams DrawCallPerfD3D9Params(bool useNullDevice, bool renderToTexture);
DrawCallPerfParams DrawCallPerfOpenGLOrGLESParams(bool useNullDevice, bool renderToTexture); DrawCallPerfParams DrawCallPerfOpenGLOrGLESParams(bool useNullDevice, bool renderToTexture);
DrawCallPerfParams DrawCallPerfValidationOnly(); DrawCallPerfParams DrawCallPerfValidationOnly();
DrawCallPerfParams DrawCallPerfVulkanParams(bool renderToTexture); DrawCallPerfParams DrawCallPerfVulkanParams(bool useNullDevice, bool renderToTexture);
#endif // TESTS_PERF_TESTS_DRAW_CALL_PERF_PARAMS_H_ #endif // TESTS_PERF_TESTS_DRAW_CALL_PERF_PARAMS_H_
...@@ -398,6 +398,12 @@ EGLPlatformParameters VULKAN() ...@@ -398,6 +398,12 @@ EGLPlatformParameters VULKAN()
return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE); return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
} }
EGLPlatformParameters VULKAN_NULL()
{
return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, EGL_DONT_CARE, EGL_DONT_CARE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
}
} // namespace egl_platform } // namespace egl_platform
// ANGLE tests platforms // ANGLE tests platforms
...@@ -671,9 +677,19 @@ PlatformParameters ES1_VULKAN() ...@@ -671,9 +677,19 @@ PlatformParameters ES1_VULKAN()
return PlatformParameters(1, 0, egl_platform::VULKAN()); return PlatformParameters(1, 0, egl_platform::VULKAN());
} }
PlatformParameters ES1_VULKAN_NULL()
{
return PlatformParameters(1, 0, egl_platform::VULKAN_NULL());
}
PlatformParameters ES2_VULKAN() PlatformParameters ES2_VULKAN()
{ {
return PlatformParameters(2, 0, egl_platform::VULKAN()); return PlatformParameters(2, 0, egl_platform::VULKAN());
} }
PlatformParameters ES2_VULKAN_NULL()
{
return PlatformParameters(2, 0, egl_platform::VULKAN_NULL());
}
} // namespace angle } // namespace angle
...@@ -99,6 +99,7 @@ EGLPlatformParameters OPENGLES_NULL(); ...@@ -99,6 +99,7 @@ EGLPlatformParameters OPENGLES_NULL();
EGLPlatformParameters OPENGL_OR_GLES(bool useNullDevice); EGLPlatformParameters OPENGL_OR_GLES(bool useNullDevice);
EGLPlatformParameters VULKAN(); EGLPlatformParameters VULKAN();
EGLPlatformParameters VULKAN_NULL();
} // namespace egl_platform } // namespace egl_platform
...@@ -167,7 +168,9 @@ PlatformParameters ES3_NULL(); ...@@ -167,7 +168,9 @@ PlatformParameters ES3_NULL();
PlatformParameters ES31_NULL(); PlatformParameters ES31_NULL();
PlatformParameters ES1_VULKAN(); PlatformParameters ES1_VULKAN();
PlatformParameters ES1_VULKAN_NULL();
PlatformParameters ES2_VULKAN(); PlatformParameters ES2_VULKAN();
PlatformParameters ES2_VULKAN_NULL();
} // namespace angle } // namespace angle
......
...@@ -259,7 +259,8 @@ config("vulkan_loader_config") { ...@@ -259,7 +259,8 @@ config("vulkan_loader_config") {
"src/loader", "src/loader",
] ]
defines = [ defines = [
"ANGLE_VK_LAYERS_DIR=\"$data_dir\"", "ANGLE_VK_DATA_DIR=\"$data_dir\"",
"ANGLE_VK_ICD_JSON=\"$data_dir/VkICD_mock_icd.json\"",
"API_NAME=\"Vulkan\"", "API_NAME=\"Vulkan\"",
] ]
...@@ -524,12 +525,12 @@ if (!is_android) { ...@@ -524,12 +525,12 @@ if (!is_android) {
# The layer JSON files are part of the necessary data deps. # The layer JSON files are part of the necessary data deps.
outputs = [ outputs = [
"$root_out_dir/$data_dir/icd/VkICD_mock_icd.json", "$root_out_dir/$data_dir/VkICD_mock_icd.json",
] ]
data = [ data = [
"$root_out_dir/$data_dir/icd/VkICD_mock_icd.json", "$root_out_dir/$data_dir/VkICD_mock_icd.json",
] ]
args += [ rebase_path("$root_out_dir/$data_dir/icd", root_build_dir) ] args += [ rebase_path("$root_out_dir/$data_dir", root_build_dir) ]
} }
} }
......
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