Wrap some global vulkan methods which depend on env variables

ANGLE scoped sets some envion variables during initialization.
Those env variables will change some vulkan global methods behavior.
So to make sure those global methods have same behavior, this CL
wraps those global methods, and sets those envion variables before
call those vulkan methods.

Bug: chromium:1264439
Change-Id: Ie4e29884fcf5b67f4e53ddd3c90a9ade7b226a1f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3379209
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
This commit is contained in:
Peng Huang 2022-01-11 13:09:55 -05:00 коммит произвёл Angle LUCI CQ
Родитель 652e3db46b
Коммит 5adee91611
3 изменённых файлов: 150 добавлений и 11 удалений

Просмотреть файл

@ -12,16 +12,44 @@
#include <stdint.h>
#include "common/debug.h"
#include "common/vulkan/vulkan_icd.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx
{
namespace
{
DeviceVk *gDevice = nullptr;
class ScopedEnv : public angle::vk::ScopedVkLoaderEnvironment
{
public:
ScopedEnv()
: angle::vk::ScopedVkLoaderEnvironment(
gDevice ? gDevice->getRenderer()->getEnableValidationLayers() : false,
gDevice ? gDevice->getRenderer()->getEnabledICD() : angle::vk::ICD::Default)
{
if (!gDevice)
{
WARN() << "No DeviceVk instance.";
}
}
};
} // namespace
DeviceVk::DeviceVk() = default;
DeviceVk::~DeviceVk() = default;
DeviceVk::~DeviceVk()
{
if (gDevice == this)
{
gDevice = nullptr;
}
}
egl::Error DeviceVk::initialize()
{
@ -32,63 +60,67 @@ egl::Error DeviceVk::getAttribute(const egl::Display *display, EGLint attribute,
{
RendererVk *renderer =
static_cast<rx::DisplayVk *>(display->getImplementation())->getRenderer();
ASSERT(mRenderer == nullptr || mRenderer == renderer);
mRenderer = renderer;
switch (attribute)
{
case EGL_VULKAN_VERSION_ANGLE:
{
auto version = static_cast<intptr_t>(renderer->getApiVersion());
auto version = static_cast<intptr_t>(mRenderer->getApiVersion());
*outValue = reinterpret_cast<void *>(version);
return egl::NoError();
}
case EGL_VULKAN_INSTANCE_ANGLE:
{
*outValue = renderer->getInstance();
*outValue = mRenderer->getInstance();
return egl::NoError();
}
case EGL_VULKAN_DEVICE_ANGLE:
{
*outValue = renderer->getDevice();
*outValue = mRenderer->getDevice();
return egl::NoError();
}
case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE:
{
*outValue = renderer->getPhysicalDevice();
*outValue = mRenderer->getPhysicalDevice();
return egl::NoError();
}
case EGL_VULKAN_QUEUE_ANGLE:
{
// egl::ContextPriority::Medium is the default context priority.
*outValue = renderer->getQueue(egl::ContextPriority::Medium);
*outValue = mRenderer->getQueue(egl::ContextPriority::Medium);
return egl::NoError();
}
case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE:
{
intptr_t index = static_cast<intptr_t>(renderer->getQueueFamilyIndex());
intptr_t index = static_cast<intptr_t>(mRenderer->getQueueFamilyIndex());
*outValue = reinterpret_cast<void *>(index);
return egl::NoError();
}
case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE:
{
char **extensions = const_cast<char **>(renderer->getEnabledDeviceExtensions().data());
char **extensions = const_cast<char **>(mRenderer->getEnabledDeviceExtensions().data());
*outValue = reinterpret_cast<void *>(extensions);
return egl::NoError();
}
case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE:
{
char **extensions =
const_cast<char **>(renderer->getEnabledInstanceExtensions().data());
const_cast<char **>(mRenderer->getEnabledInstanceExtensions().data());
*outValue = reinterpret_cast<void *>(extensions);
return egl::NoError();
}
case EGL_VULKAN_FEATURES_ANGLE:
{
const auto *features = &renderer->getEnabledFeatures();
const auto *features = &mRenderer->getEnabledFeatures();
*outValue = const_cast<void *>(reinterpret_cast<const void *>(features));
return egl::NoError();
}
case EGL_VULKAN_GET_INSTANCE_PROC_ADDR:
{
*outValue = reinterpret_cast<void *>(vkGetInstanceProcAddr);
*outValue = reinterpret_cast<void *>(DeviceVk::WrappedGetInstanceProcAddr);
ASSERT(!gDevice || gDevice == this);
gDevice = this;
return egl::NoError();
}
default:
@ -106,4 +138,85 @@ void DeviceVk::generateExtensions(egl::DeviceExtensions *outExtensions) const
outExtensions->deviceVulkan = true;
}
// static
VKAPI_ATTR VkResult VKAPI_CALL
DeviceVk::WrappedCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance)
{
ScopedEnv scopedEnv;
return vkCreateInstance(pCreateInfo, pAllocator, pInstance);
}
// static
VKAPI_ATTR VkResult VKAPI_CALL
DeviceVk::WrappedEnumerateInstanceExtensionProperties(const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties)
{
ScopedEnv scopedEnv;
return vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
}
// static
VKAPI_ATTR VkResult VKAPI_CALL
DeviceVk::WrappedEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
VkLayerProperties *pProperties)
{
ScopedEnv scopedEnv;
return vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
}
// static
VKAPI_ATTR VkResult VKAPI_CALL DeviceVk::WrappedEnumerateInstanceVersion(uint32_t *pApiVersion)
{
ScopedEnv scopedEnv;
return vkEnumerateInstanceVersion(pApiVersion);
}
// static
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL DeviceVk::WrappedGetInstanceProcAddr(VkInstance instance,
const char *pName)
{
if (!pName || pName[0] != 'v' || pName[1] != 'k')
{
return nullptr;
}
if (instance != VK_NULL_HANDLE)
{
return vkGetInstanceProcAddr(instance, pName);
}
if (!strcmp(pName, "vkCreateInstance"))
{
return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedCreateInstance);
}
if (!strcmp(pName, "vkEnumerateInstanceExtensionProperties"))
{
return reinterpret_cast<PFN_vkVoidFunction>(
DeviceVk::WrappedEnumerateInstanceExtensionProperties);
}
if (!strcmp(pName, "vkEnumerateInstanceLayerProperties"))
{
return reinterpret_cast<PFN_vkVoidFunction>(
DeviceVk::WrappedEnumerateInstanceLayerProperties);
}
if (!strcmp(pName, "vkEnumerateInstanceVersion"))
{
if (!vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"))
{
// Vulkan 1.0 doesn't have vkEnumerateInstanceVersion.
return nullptr;
}
return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedEnumerateInstanceVersion);
}
if (!strcmp(pName, "vkGetInstanceProcAddr"))
{
return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedGetInstanceProcAddr);
}
return vkGetInstanceProcAddr(instance, pName);
}
} // namespace rx

Просмотреть файл

@ -12,9 +12,13 @@
#include "libANGLE/renderer/DeviceImpl.h"
#include "common/vulkan/vk_headers.h"
namespace rx
{
class RendererVk;
class DeviceVk : public DeviceImpl
{
public:
@ -27,6 +31,27 @@ class DeviceVk : public DeviceImpl
void **outValue) override;
EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
RendererVk *getRenderer() const { return mRenderer; }
private:
// Wrappers for some global vulkan methods which need to read env variables.
// The wrappers will set those env variables before calling those global methods.
static VKAPI_ATTR VkResult VKAPI_CALL
WrappedCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance);
static VKAPI_ATTR VkResult VKAPI_CALL
WrappedEnumerateInstanceExtensionProperties(const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
static VKAPI_ATTR VkResult VKAPI_CALL
WrappedEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
VkLayerProperties *pProperties);
static VKAPI_ATTR VkResult VKAPI_CALL WrappedEnumerateInstanceVersion(uint32_t *pApiVersion);
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL WrappedGetInstanceProcAddr(VkInstance instance,
const char *pName);
RendererVk *mRenderer = nullptr;
};
} // namespace rx

Просмотреть файл

@ -238,6 +238,7 @@ class RendererVk : angle::NonCopyable
}
uint32_t getDefaultUniformBufferSize() const { return mDefaultUniformBufferSize; }
angle::vk::ICD getEnabledICD() const { return mEnabledICD; }
bool isMockICDEnabled() const { return mEnabledICD == angle::vk::ICD::Mock; }
// Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and