зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
652e3db46b
Коммит
5adee91611
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче