Add support for GBM platform by implementing a Display with no WSI
extension.

Bug: angleproject:7217
Change-Id: Ia9089131c5984dfdd926d2f85f1c218df1e84d9a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3596042
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Antonio Caggiano 2022-02-15 15:40:23 +01:00 коммит произвёл Angle LUCI CQ
Родитель 0b0744f3ef
Коммит 825d5b2c59
13 изменённых файлов: 536 добавлений и 367 удалений

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

@ -40,6 +40,7 @@ if (angle_has_build) {
}
declare_args() {
angle_use_gbm = ozone_platform_gbm && !is_ggp && is_linux && !is_chromecast
angle_use_x11 = ozone_platform_x11 && !is_ggp && is_linux && !is_chromecast
angle_use_wayland =
ozone_platform_wayland && !is_ggp && is_linux && !is_chromecast

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

@ -17,29 +17,6 @@
#include <array>
// Refer to:
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/drm_fourcc.h
// https://source.chromium.org/chromium/chromium/src/+/main:ui/gl/gl_image_native_pixmap.cc;l=24
#define FOURCC(a, b, c, d) \
((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
(static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
#define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ')
#define DRM_FORMAT_R16 FOURCC('R', '1', '6', ' ')
#define DRM_FORMAT_GR88 FOURCC('G', 'R', '8', '8')
#define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6')
#define DRM_FORMAT_RGB888 FOURCC('R', 'G', '2', '4')
#define DRM_FORMAT_BGR888 FOURCC('B', 'G', '2', '4')
#define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
#define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4')
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')
#define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4')
#define DRM_FORMAT_ABGR2101010 FOURCC('A', 'B', '3', '0')
#define DRM_FORMAT_ARGB2101010 FOURCC('A', 'R', '3', '0')
#define DRM_FORMAT_YVU420 FOURCC('Y', 'V', '1', '2')
#define DRM_FORMAT_NV12 FOURCC('N', 'V', '1', '2')
#define DRM_FORMAT_P010 FOURCC('P', '0', '1', '0')
namespace angle
{
GLenum DrmFourCCFormatToGLInternalFormat(int fourccFormat, bool *isYUV)

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

@ -16,6 +16,29 @@
# include <vector>
#endif
// Refer to:
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/drm_fourcc.h
// https://source.chromium.org/chromium/chromium/src/+/main:ui/gl/gl_image_native_pixmap.cc;l=24
#define FOURCC(a, b, c, d) \
((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
(static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
#define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ')
#define DRM_FORMAT_R16 FOURCC('R', '1', '6', ' ')
#define DRM_FORMAT_GR88 FOURCC('G', 'R', '8', '8')
#define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6')
#define DRM_FORMAT_RGB888 FOURCC('R', 'G', '2', '4')
#define DRM_FORMAT_BGR888 FOURCC('B', 'G', '2', '4')
#define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
#define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4')
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')
#define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4')
#define DRM_FORMAT_ABGR2101010 FOURCC('A', 'B', '3', '0')
#define DRM_FORMAT_ARGB2101010 FOURCC('A', 'R', '3', '0')
#define DRM_FORMAT_YVU420 FOURCC('Y', 'V', '1', '2')
#define DRM_FORMAT_NV12 FOURCC('N', 'V', '1', '2')
#define DRM_FORMAT_P010 FOURCC('P', '0', '1', '0')
namespace angle
{
GLenum DrmFourCCFormatToGLInternalFormat(int format, bool *isYUV);

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

@ -1338,6 +1338,7 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_EXT_device_query", deviceQueryEXT, &extensionStrings);
InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings);
InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings);
InsertExtensionString("EGL_KHR_platform_gbm", platformGbmKHR, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings);

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

@ -694,6 +694,9 @@ struct ClientExtensions
// EGL_EXT_platform_device
bool platformDevice = false;
// EGL_KHR_platform_gbm
bool platformGbmKHR = false;
// EGL_ANGLE_platform_angle
bool platformANGLE = false;

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

@ -427,6 +427,13 @@ rx::DisplayImpl *CreateDisplayFromAttribs(EGLAttrib displayType,
}
break;
# elif defined(ANGLE_PLATFORM_LINUX)
# if defined(ANGLE_USE_GBM)
if (platformType == EGL_PLATFORM_GBM_KHR)
{
impl = rx::CreateVulkanGbmDisplay(state);
break;
}
# endif
# if defined(ANGLE_USE_X11)
if (platformType == EGL_PLATFORM_X11_EXT && rx::IsVulkanXcbDisplayAvailable())
{
@ -877,6 +884,7 @@ Display::~Display()
switch (mPlatform)
{
case EGL_PLATFORM_ANGLE_ANGLE:
case EGL_PLATFORM_GBM_KHR:
{
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
ANGLEPlatformDisplayMap::iterator iter = displays->find(ANGLEPlatformDisplay(
@ -1913,6 +1921,10 @@ static ClientExtensions GenerateClientExtensions()
extensions.platformDevice = true;
#endif
#if defined(ANGLE_USE_GBM)
extensions.platformGbmKHR = true;
#endif
#if defined(ANGLE_ENABLE_D3D11)
# if defined(ANGLE_ENABLE_WINDOWS_UWP)
extensions.platformANGLED3D11ON12 = true;

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

@ -206,6 +206,13 @@ if (angle_use_wayland) {
]
}
if (angle_use_gbm) {
_vulkan_backend_sources += [
"linux/gbm/DisplayVkGbm.cpp",
"linux/gbm/DisplayVkGbm.h",
]
}
if (is_fuchsia) {
_vulkan_backend_sources += [
"fuchsia/DisplayVkFuchsia.cpp",
@ -316,6 +323,9 @@ angle_source_set("angle_vulkan_backend") {
if (is_linux || is_chromeos) {
deps += [ "$angle_root/src/common/linux:angle_dma_buf" ]
if (angle_use_gbm) {
deps += [ "//third_party/minigbm" ]
}
}
if (is_fuchsia) {

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

@ -27,6 +27,9 @@ DisplayImpl *CreateVulkanWin32Display(const egl::DisplayState &state);
bool IsVulkanWaylandDisplayAvailable();
DisplayImpl *CreateVulkanWaylandDisplay(const egl::DisplayState &state);
bool IsVulkanGbmDisplayAvailable();
DisplayImpl *CreateVulkanGbmDisplay(const egl::DisplayState &state);
bool IsVulkanXcbDisplayAvailable();
DisplayImpl *CreateVulkanXcbDisplay(const egl::DisplayState &state);

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

@ -0,0 +1,98 @@
//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayVkGbm.cpp:
// Implements the class methods for DisplayVkGbm.
//
#include "libANGLE/renderer/vulkan/linux/gbm/DisplayVkGbm.h"
#include <gbm.h>
#include "common/linux/dma_buf_utils.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
namespace rx
{
DisplayVkGbm::DisplayVkGbm(const egl::DisplayState &state)
: DisplayVkLinux(state), mGbmDevice(nullptr)
{}
egl::Error DisplayVkGbm::initialize(egl::Display *display)
{
mGbmDevice = reinterpret_cast<gbm_device *>(display->getNativeDisplayId());
if (!mGbmDevice)
{
ERR() << "Failed to retrieve GBM device";
return egl::EglNotInitialized();
}
return DisplayVk::initialize(display);
}
void DisplayVkGbm::terminate()
{
mGbmDevice = nullptr;
DisplayVk::terminate();
}
bool DisplayVkGbm::isValidNativeWindow(EGLNativeWindowType window) const
{
return (void *)window != nullptr;
}
SurfaceImpl *DisplayVkGbm::createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window)
{
return nullptr;
}
egl::ConfigSet DisplayVkGbm::generateConfigs()
{
const std::array<GLenum, 1> kColorFormats = {GL_BGRA8_EXT};
std::vector<GLenum> depthStencilFormats(
egl_vk::kConfigDepthStencilFormats,
egl_vk::kConfigDepthStencilFormats + ArraySize(egl_vk::kConfigDepthStencilFormats));
if (getCaps().stencil8)
{
depthStencilFormats.push_back(GL_STENCIL_INDEX8);
}
egl::ConfigSet cfgSet =
egl_vk::GenerateConfigs(kColorFormats.data(), kColorFormats.size(),
depthStencilFormats.data(), depthStencilFormats.size(), this);
cfgSet.begin()->second.nativeVisualID = DRM_FORMAT_XRGB8888;
return cfgSet;
}
void DisplayVkGbm::checkConfigSupport(egl::Config *config) {}
const char *DisplayVkGbm::getWSIExtension() const
{
return nullptr;
}
bool DisplayVkGbm::isUsingSwapchain() const
{
return true;
}
bool IsVulkanGbmDisplayAvailable()
{
return true;
}
DisplayImpl *CreateVulkanGbmDisplay(const egl::DisplayState &state)
{
return new DisplayVkGbm(state);
}
} // namespace rx

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

@ -0,0 +1,46 @@
//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayVkGbm.h:
// Defines the class interface for DisplayVkGbm, implementing DisplayVk for GBM.
//
#ifndef LIBANGLE_RENDERER_VULKAN_GBM_DISPLAYVKGBM_H_
#define LIBANGLE_RENDERER_VULKAN_GBM_DISPLAYVKGBM_H_
#include "libANGLE/renderer/vulkan/linux/DisplayVkLinux.h"
struct gbm_device;
namespace rx
{
class DisplayVkGbm : public DisplayVkLinux
{
public:
DisplayVkGbm(const egl::DisplayState &state);
egl::Error initialize(egl::Display *display) override;
void terminate() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override;
SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window) override;
egl::ConfigSet generateConfigs() override;
void checkConfigSupport(egl::Config *config) override;
const char *getWSIExtension() const override;
bool isUsingSwapchain() const override;
private:
gbm_device *mGbmDevice;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_GBM_DISPLAYVKGBM_H_

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

@ -551,6 +551,13 @@ bool ValidateGetPlatformDisplayCommon(const ValidationContext *val,
return false;
}
break;
case EGL_PLATFORM_GBM_KHR:
if (!clientExtensions.platformGbmKHR)
{
val->setError(EGL_BAD_PARAMETER, "Platform GBM extension is not active");
return false;
}
break;
default:
val->setError(EGL_BAD_CONFIG, "Bad platform type.");
return false;
@ -558,391 +565,377 @@ bool ValidateGetPlatformDisplayCommon(const ValidationContext *val,
attribMap.initializeWithoutValidation();
switch (platform)
if (platform != EGL_PLATFORM_DEVICE_EXT)
{
case EGL_PLATFORM_ANGLE_ANGLE:
EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
bool enableAutoTrimSpecified = false;
bool enableD3D11on12 = false;
bool presentPathSpecified = false;
bool luidSpecified = false;
bool deviceIdSpecified = false;
Optional<EGLAttrib> majorVersion;
Optional<EGLAttrib> minorVersion;
Optional<EGLAttrib> deviceType;
Optional<EGLAttrib> eglHandle;
for (const auto &curAttrib : attribMap)
{
EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
bool enableAutoTrimSpecified = false;
bool enableD3D11on12 = false;
bool presentPathSpecified = false;
bool luidSpecified = false;
bool deviceIdSpecified = false;
const EGLAttrib value = curAttrib.second;
Optional<EGLAttrib> majorVersion;
Optional<EGLAttrib> minorVersion;
Optional<EGLAttrib> deviceType;
Optional<EGLAttrib> eglHandle;
for (const auto &curAttrib : attribMap)
switch (curAttrib.first)
{
const EGLAttrib value = curAttrib.second;
switch (curAttrib.first)
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
{
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value));
platformType = value;
break;
}
case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
if (value != EGL_DONT_CARE)
{
ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value));
platformType = value;
break;
majorVersion = value;
}
break;
case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
if (value != EGL_DONT_CARE)
{
minorVersion = value;
}
break;
case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE:
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE, "Invalid automatic trim attribute");
return false;
}
enableAutoTrimSpecified = true;
break;
case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE:
if (!clientExtensions.platformANGLED3D ||
!clientExtensions.platformANGLED3D11ON12)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active.");
return false;
}
case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
if (value != EGL_DONT_CARE)
{
majorVersion = value;
}
break;
case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
if (value != EGL_DONT_CARE)
{
minorVersion = value;
}
break;
case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE:
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid automatic trim attribute");
return false;
}
enableAutoTrimSpecified = true;
break;
case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE:
if (!clientExtensions.platformANGLED3D ||
!clientExtensions.platformANGLED3D11ON12)
{
val->setError(
EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active.");
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute");
return false;
}
}
enableD3D11on12 = true;
break;
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute");
return false;
}
enableD3D11on12 = true;
break;
case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
if (!clientExtensions.experimentalPresentPath)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_experimental_present_path extension not active");
return false;
}
case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
if (!clientExtensions.experimentalPresentPath)
{
val->setError(
EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_experimental_present_path extension not active");
return false;
}
switch (value)
{
case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE:
case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE:
break;
default:
val->setError(
EGL_BAD_ATTRIBUTE,
"Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE");
return false;
}
presentPathSpecified = true;
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
switch (value)
{
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
if (!clientExtensions.platformANGLED3D)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_d3d is not supported");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE:
if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_device_type_"
"egl_angle is not supported");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
if (!clientExtensions.platformANGLEDeviceTypeSwiftShader)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_device_type_"
"swiftshader is not supported");
return false;
}
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
"attrib");
return false;
}
deviceType = value;
break;
case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE:
if (!clientExtensions.platformANGLE)
{
switch (value)
{
case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE:
case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle extension not active");
"Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE");
return false;
}
if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE "
"must be EGL_TRUE, EGL_FALSE, or "
"EGL_DONT_CARE.");
return false;
}
break;
}
presentPathSpecified = true;
break;
case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE:
if (value != EGL_DONT_CARE)
{
eglHandle = value;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
switch (value)
{
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
break;
case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE:
case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
luidSpecified = true;
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
if (!clientExtensions.platformANGLED3D)
{
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"EAGL_ANGLE attrib");
"EGL_ANGLE_platform_angle_d3d is not supported");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE:
if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"CGL_ANGLE attrib");
"EGL_ANGLE_platform_angle_device_type_"
"egl_angle is not supported");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE:
if (!clientExtensions.platformANGLEDeviceId)
{
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
if (!clientExtensions.platformANGLEDeviceTypeSwiftShader)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_device_type_"
"swiftshader is not supported");
return false;
}
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_device_id is not supported");
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
"attrib");
return false;
}
deviceIdSpecified = true;
break;
default:
break;
}
}
deviceType = value;
break;
case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE:
if (!clientExtensions.platformANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle extension not active");
return false;
}
if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE "
"must be EGL_TRUE, EGL_FALSE, or "
"EGL_DONT_CARE.");
return false;
}
break;
case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE:
if (value != EGL_DONT_CARE)
{
eglHandle = value;
}
break;
case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE:
case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
luidSpecified = true;
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"EAGL_ANGLE attrib");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
val->setError(EGL_BAD_ATTRIBUTE,
"Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"CGL_ANGLE attrib");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE:
if (!clientExtensions.platformANGLEDeviceId)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_device_id is not supported");
return false;
}
deviceIdSpecified = true;
break;
default:
break;
}
}
if (!majorVersion.valid() && minorVersion.valid())
if (!majorVersion.valid() && minorVersion.valid())
{
val->setError(EGL_BAD_ATTRIBUTE,
"Must specify major version if you specify a minor version.");
return false;
}
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE "
"requires a device type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (enableD3D11on12)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"Must specify major version if you specify a minor version.");
return false;
}
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE "
"requires a device type of "
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE "
"requires a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (enableD3D11on12)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE "
"requires a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (deviceType.valid() &&
deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE &&
deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device "
"type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE "
"or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE");
return false;
}
}
if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE &&
deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
"EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device "
"type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE "
"or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE");
return false;
}
if (luidSpecified)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and "
"EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE "
"require a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 &&
attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0)
{
val->setError(EGL_BAD_ATTRIBUTE,
"If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE "
"and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are "
"specified, at least one must non-zero.");
return false;
}
}
if (deviceIdSpecified)
{
if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 &&
attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0)
{
val->setError(EGL_BAD_ATTRIBUTE,
"If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE "
"and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are "
"specified, at least one must non-zero.");
return false;
}
}
if (deviceType.valid())
{
switch (deviceType.value())
{
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"This device type requires a "
"platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
"EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"This device type requires a "
"platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE.");
return false;
}
break;
default:
break;
}
}
if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
if ((majorVersion.valid() && majorVersion.value() != 1) ||
(minorVersion.valid() && minorVersion.value() != 0))
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently "
"only supports Vulkan 1.0.");
return false;
}
}
if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE.");
return false;
}
break;
}
case EGL_PLATFORM_DEVICE_EXT:
if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
const Device *eglDevice = static_cast<const Device *>(native_display);
if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice))
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (luidSpecified)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"native_display should be a valid EGL device if "
"platform equals EGL_PLATFORM_DEVICE_EXT");
"EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and "
"EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE "
"require a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
return false;
}
if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 &&
attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0)
{
val->setError(EGL_BAD_ATTRIBUTE,
"If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE "
"and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are "
"specified, at least one must non-zero.");
return false;
}
break;
}
default:
if (deviceIdSpecified)
{
UNREACHABLE();
if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 &&
attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0)
{
val->setError(EGL_BAD_ATTRIBUTE,
"If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE "
"and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are "
"specified, at least one must non-zero.");
return false;
}
}
if (deviceType.valid())
{
switch (deviceType.value())
{
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"This device type requires a "
"platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
"EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.");
return false;
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"This device type requires a "
"platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE.");
return false;
}
break;
default:
break;
}
}
if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
if ((majorVersion.valid() && majorVersion.value() != 1) ||
(minorVersion.valid() && minorVersion.value() != 0))
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently "
"only supports Vulkan 1.0.");
return false;
}
}
if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a "
"device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE.");
return false;
}
}
else
{
const Device *eglDevice = static_cast<const Device *>(native_display);
if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice))
{
val->setError(EGL_BAD_ATTRIBUTE,
"native_display should be a valid EGL device if "
"platform equals EGL_PLATFORM_DEVICE_EXT");
return false;
}
}

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

@ -202,6 +202,7 @@ EGLDisplay GetPlatformDisplayEXT(Thread *thread,
switch (platform)
{
case EGL_PLATFORM_ANGLE_ANGLE:
case EGL_PLATFORM_GBM_KHR:
{
return egl::Display::GetDisplayFromNativeDisplay(
platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);

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

@ -400,6 +400,7 @@ EGLDisplay GetPlatformDisplay(Thread *thread,
switch (platform)
{
case EGL_PLATFORM_ANGLE_ANGLE:
case EGL_PLATFORM_GBM_KHR:
{
return Display::GetDisplayFromNativeDisplay(
platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);