blob: 597e6d8cb49a814635c80507fe01002b71995a67 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gl/gl_angle_util_vulkan.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_surface_egl.h"
namespace gl {
namespace {
EGLDeviceEXT GetEGLDeviceFromANGLE() {
EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay();
if (egl_display == EGL_NO_DISPLAY) {
LOG(ERROR) << "Failed to retrieve EGLDisplay";
return nullptr;
}
if (!gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) {
LOG(ERROR) << "EGL_EXT_device_query not supported";
return nullptr;
}
intptr_t egl_device = 0;
if (!eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device)) {
LOG(ERROR) << "eglQueryDisplayAttribEXT failed";
return nullptr;
}
if (!egl_device) {
LOG(ERROR) << "Failed to retrieve EGLDeviceEXT";
return nullptr;
}
return reinterpret_cast<EGLDeviceEXT>(egl_device);
}
gfx::ExtensionSet ToExtensionSet(const char* const* extensions) {
gfx::ExtensionSet extension_set;
for (const char* const* p = extensions; *p != nullptr; ++p)
extension_set.insert(*p);
return extension_set;
}
} // namespace
VkInstance QueryVkInstanceFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return VK_NULL_HANDLE;
intptr_t instance = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_INSTANCE_ANGLE,
&instance)) {
LOG(ERROR) << "Failed to retrieve VkInstance";
return VK_NULL_HANDLE;
}
return reinterpret_cast<VkInstance>(instance);
}
GL_EXPORT uint32_t QueryVkVersionFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return 0;
intptr_t version = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_VERSION_ANGLE,
&version)) {
LOG(ERROR) << "Failed to retrieve vulkan version";
return 0;
}
return static_cast<uint32_t>(version);
}
VkPhysicalDevice QueryVkPhysicalDeviceFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return VK_NULL_HANDLE;
intptr_t physical_device = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_PHYSICAL_DEVICE_ANGLE,
&physical_device)) {
LOG(ERROR) << "Failed to retrieve VkPhysicalDevice";
return VK_NULL_HANDLE;
}
return reinterpret_cast<VkPhysicalDevice>(physical_device);
}
VkDevice QueryVkDeviceFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return VK_NULL_HANDLE;
intptr_t device = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_DEVICE_ANGLE, &device)) {
LOG(ERROR) << "Failed to retrieve VkDevice";
return VK_NULL_HANDLE;
}
return reinterpret_cast<VkDevice>(device);
}
VkQueue QueryVkQueueFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return VK_NULL_HANDLE;
intptr_t queue = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_QUEUE_ANGLE, &queue)) {
LOG(ERROR) << "Failed to retrieve VkQueue";
return VK_NULL_HANDLE;
}
return reinterpret_cast<VkQueue>(queue);
}
int QueryVkQueueFramiliyIndexFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return -1;
intptr_t index = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE,
&index)) {
LOG(ERROR) << "Failed to retrieve queue familiy index";
return -1;
}
return index;
}
gfx::ExtensionSet QueryVkDeviceExtensionsFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return {};
intptr_t extensions = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE,
&extensions)) {
LOG(ERROR) << "Failed to retrieve vulkan enabled device extensions";
return {};
}
return ToExtensionSet(reinterpret_cast<const char* const*>(extensions));
}
gfx::ExtensionSet QueryVkInstanceExtensionsFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return {};
intptr_t extensions = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE,
&extensions)) {
LOG(ERROR) << "Failed to retrieve vulkan enabled instance extensions";
return {};
}
return ToExtensionSet(reinterpret_cast<const char* const*>(extensions));
}
const VkPhysicalDeviceFeatures2KHR* QueryVkEnabledDeviceFeaturesFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return nullptr;
intptr_t features = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_FEATURES_ANGLE,
&features)) {
LOG(ERROR) << "Failed to retrieve vulkan enabled device features";
return nullptr;
}
return reinterpret_cast<const VkPhysicalDeviceFeatures2KHR*>(features);
}
PFN_vkGetInstanceProcAddr QueryVkGetInstanceProcAddrFromANGLE() {
EGLDeviceEXT egl_device = GetEGLDeviceFromANGLE();
if (!egl_device)
return nullptr;
intptr_t proc = 0;
if (!eglQueryDeviceAttribEXT(egl_device, EGL_VULKAN_GET_INSTANCE_PROC_ADDR,
&proc)) {
LOG(ERROR) << "Failed to retrieve vkGetInstanceProcAddr";
return nullptr;
}
return reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc);
}
} // namespace gl