Commit e09bd5d3 by Jamie Madill Committed by Commit Bot

Vulkan: Add display creation, test and extension.

With this CL we have the ability to create Vulkan test configs and run basic tests, although the only thing that works is creating a Vulkan Renderer using the extension. BUG=angleproject:1319 Change-Id: I8ad17bba01241334be7da16e68fea38762ca6a20 Reviewed-on: https://chromium-review.googlesource.com/367750 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 4596a769
Name
ANGLE_platform_angle_vulkan
Name Strings
EGL_ANGLE_platform_angle_vulkan
Contributors
Jamie Madill, Google
Contacts
Jamie Madill, Google (jmadill 'at' google 'dot' com)
Status
Draft
Version
Version 1, 2016-11-17
Number
EGL Extension XXX
Extension Type
EGL client extension
Dependencies
Requires ANGLE_platform_angle.
Overview
This extension enables selection of Vulkan display types.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as values for the EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute:
EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE 0x3451
Additions to the EGL Specification
None.
New Behavior
To request a display that is backed by a Vulken driver, the value of
EGL_PLATFORM_ANGLE_TYPE_ANGLE should be
EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE.
If EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE is specified, it
controls enabling the standard Vulkan validation layers. EGL_TRUE enables
the validation and EGL_FALSE disables it. Any value other than these will
result in an error. If the flag is not specified, validation may default
to either enabled or disabled, depending on compile-time parameters in the
implementation.
If EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE and
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE are not specified, the
implementation will decide which version of Vulkan to instantiate. If they
are specified, it will choose a version that is lower or equal to the
specified major and minor versions. The only current values accepted for
major and minor version are 1 for major and 0 for minor.
Issues
1) Would it be better to specify validation layers individually?
RESOLVED: It would give more fined grained control, but the layers
are sensitive to ordering, and there may be new ones added or old ones
removed, this abstracts the logic into a simpler form. The validation
layers maintainers are also moving towards a single-layer model from
the current multiple layers approach.
2) Should the validation layers default to on, off, or no guarantee?
Defaulting to off offers some consistency. However, it's customary for
some applications like ANGLE to turn on debugging features by default
in Debug builds.
3) Should ANGLE always instantiate the highest available version of Vulkan?
RESOLVED: It's possible that in a future implementation of Vulkan there
may be driver issues present only on some version of Vulkan, and there's
no explicit guarantee higher versions will be more stable. Hence, we should
give ANGLE some flexiblity in this regard and leave this unspecified.
Revision History
Version 1, 2016-11-17 (Jamie Madill)
- Initial draft
...@@ -536,6 +536,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu ...@@ -536,6 +536,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE #define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
#endif /* EGL_ANGLE_platform_angle_null */ #endif /* EGL_ANGLE_platform_angle_null */
#ifndef EGL_ANGLE_platform_angle_vulkan
#define EGL_ANGLE_platform_angle_vulkan 1
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE 0x3451
#endif /* EGL_ANGLE_platform_angle_vulkan */
#ifndef EGL_ANGLE_window_fixed_size #ifndef EGL_ANGLE_window_fixed_size
#define EGL_ANGLE_window_fixed_size 1 #define EGL_ANGLE_window_fixed_size 1
#define EGL_FIXED_SIZE_ANGLE 0x3201 #define EGL_FIXED_SIZE_ANGLE 0x3201
......
...@@ -61,7 +61,10 @@ enum ShShaderOutput ...@@ -61,7 +61,10 @@ enum ShShaderOutput
// Prefer using these to specify HLSL output type: // Prefer using these to specify HLSL output type:
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9 SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11 SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3 SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A, // D3D 11 feature level 9_3
// Output specialized GLSL to be fed to glslang for Vulkan SPIR.
SH_GLSL_VULKAN_OUTPUT = 0x8B4B,
}; };
// Compile options. // Compile options.
......
...@@ -67,6 +67,11 @@ TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput ...@@ -67,6 +67,11 @@ TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput
return nullptr; return nullptr;
#endif // ANGLE_ENABLE_HLSL #endif // ANGLE_ENABLE_HLSL
case SH_GLSL_VULKAN_OUTPUT:
UNIMPLEMENTED();
// TODO(jmadill): Vulkan GLSL
return nullptr;
default: default:
// Unknown format. Return NULL per the sh::ConstructCompiler API. // Unknown format. Return NULL per the sh::ConstructCompiler API.
return nullptr; return nullptr;
......
...@@ -25,14 +25,13 @@ bool AttributeMap::contains(EGLAttrib key) const ...@@ -25,14 +25,13 @@ bool AttributeMap::contains(EGLAttrib key) const
EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
{ {
std::map<EGLAttrib, EGLAttrib>::const_iterator iter = mAttributes.find(key); auto iter = mAttributes.find(key);
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue; return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
} }
EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
{ {
return static_cast<EGLint>( return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
get(static_cast<EGLAttrib>(key), static_cast<EGLAttrib>(defaultValue)));
} }
bool AttributeMap::isEmpty() const bool AttributeMap::isEmpty() const
......
...@@ -1080,6 +1080,7 @@ ClientExtensions::ClientExtensions() ...@@ -1080,6 +1080,7 @@ ClientExtensions::ClientExtensions()
platformANGLE(false), platformANGLE(false),
platformANGLED3D(false), platformANGLED3D(false),
platformANGLEOpenGL(false), platformANGLEOpenGL(false),
platformANGLEVulkan(false),
deviceCreation(false), deviceCreation(false),
deviceCreationD3D11(false), deviceCreationD3D11(false),
x11Visual(false), x11Visual(false),
...@@ -1101,6 +1102,7 @@ std::vector<std::string> ClientExtensions::getStrings() const ...@@ -1101,6 +1102,7 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings);
InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings); InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings);
......
...@@ -672,6 +672,9 @@ struct ClientExtensions ...@@ -672,6 +672,9 @@ struct ClientExtensions
// EGL_ANGLE_platform_angle_null // EGL_ANGLE_platform_angle_null
bool platformANGLENULL; bool platformANGLENULL;
// EGL_ANGLE_platform_angle_vulkan
bool platformANGLEVulkan;
// EGL_ANGLE_device_creation // EGL_ANGLE_device_creation
bool deviceCreation; bool deviceCreation;
...@@ -688,6 +691,6 @@ struct ClientExtensions ...@@ -688,6 +691,6 @@ struct ClientExtensions
bool clientGetAllProcAddresses; bool clientGetAllProcAddresses;
}; };
} } // namespace egl
#endif // LIBANGLE_CAPS_H_ #endif // LIBANGLE_CAPS_H_
...@@ -55,7 +55,11 @@ ...@@ -55,7 +55,11 @@
#if defined(ANGLE_ENABLE_NULL) #if defined(ANGLE_ENABLE_NULL)
#include "libANGLE/renderer/null/DisplayNULL.h" #include "libANGLE/renderer/null/DisplayNULL.h"
#endif #endif // defined(ANGLE_ENABLE_NULL)
#if defined(ANGLE_ENABLE_VULKAN)
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#endif // defined(ANGLE_ENABLE_VULKAN)
namespace egl namespace egl
{ {
...@@ -146,88 +150,101 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) ...@@ -146,88 +150,101 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap)
attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
switch (displayType) switch (displayType)
{ {
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
// Default to D3D displays // Default to D3D displays
impl = new rx::DisplayD3D(); impl = new rx::DisplayD3D();
#elif defined(ANGLE_USE_X11) #elif defined(ANGLE_USE_X11)
impl = new rx::DisplayGLX(); impl = new rx::DisplayGLX();
#elif defined(ANGLE_PLATFORM_APPLE) #elif defined(ANGLE_PLATFORM_APPLE)
impl = new rx::DisplayCGL(); impl = new rx::DisplayCGL();
#elif defined(ANGLE_USE_OZONE) #elif defined(ANGLE_USE_OZONE)
impl = new rx::DisplayOzone(); impl = new rx::DisplayOzone();
#elif defined(ANGLE_PLATFORM_ANDROID) #elif defined(ANGLE_PLATFORM_ANDROID)
impl = new rx::DisplayAndroid(); impl = new rx::DisplayAndroid();
#else #else
// No display available // No display available
UNREACHABLE(); UNREACHABLE();
#endif #endif
break; break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
impl = new rx::DisplayD3D(); impl = new rx::DisplayD3D();
#else #else
// A D3D display was requested on a platform that doesn't support it // A D3D display was requested on a platform that doesn't support it
UNREACHABLE(); UNREACHABLE();
#endif #endif
break; break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
#if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_ENABLE_OPENGL)
#if defined(ANGLE_PLATFORM_WINDOWS) #if defined(ANGLE_PLATFORM_WINDOWS)
impl = new rx::DisplayWGL(); impl = new rx::DisplayWGL();
#elif defined(ANGLE_USE_X11) #elif defined(ANGLE_USE_X11)
impl = new rx::DisplayGLX(); impl = new rx::DisplayGLX();
#elif defined(ANGLE_PLATFORM_APPLE) #elif defined(ANGLE_PLATFORM_APPLE)
impl = new rx::DisplayCGL(); impl = new rx::DisplayCGL();
#elif defined(ANGLE_USE_OZONE) #elif defined(ANGLE_USE_OZONE)
// This might work but has never been tried, so disallow for now. // This might work but has never been tried, so disallow for now.
impl = nullptr; impl = nullptr;
#elif defined(ANGLE_PLATFORM_ANDROID) #elif defined(ANGLE_PLATFORM_ANDROID)
// No GL support on this platform, fail display creation. // No GL support on this platform, fail display creation.
impl = nullptr; impl = nullptr;
#else #else
#error Unsupported OpenGL platform. #error Unsupported OpenGL platform.
#endif #endif
#else #else
UNREACHABLE(); // No display available
#endif UNREACHABLE();
break; #endif // defined(ANGLE_ENABLE_OPENGL)
break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
#if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_ENABLE_OPENGL)
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
#if defined(ANGLE_PLATFORM_WINDOWS) #if defined(ANGLE_PLATFORM_WINDOWS)
impl = new rx::DisplayWGL(); impl = new rx::DisplayWGL();
#elif defined(ANGLE_USE_X11) #elif defined(ANGLE_USE_X11)
impl = new rx::DisplayGLX(); impl = new rx::DisplayGLX();
#elif defined(ANGLE_USE_OZONE) #elif defined(ANGLE_USE_OZONE)
impl = new rx::DisplayOzone(); impl = new rx::DisplayOzone();
#elif defined(ANGLE_PLATFORM_ANDROID) #elif defined(ANGLE_PLATFORM_ANDROID)
impl = new rx::DisplayAndroid(); impl = new rx::DisplayAndroid();
#else #else
// No GLES support on this platform, fail display creation. // No GLES support on this platform, fail display creation.
impl = nullptr; impl = nullptr;
#endif
break;
#endif #endif
#endif // defined(ANGLE_ENABLE_OPENGL)
break;
case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
#if defined(ANGLE_ENABLE_VULKAN)
impl = new rx::DisplayVk();
#else
// No display available
UNREACHABLE();
#endif // defined(ANGLE_ENABLE_VULKAN)
break;
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
#if defined(ANGLE_ENABLE_NULL) #if defined(ANGLE_ENABLE_NULL)
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: impl = new rx::DisplayNULL();
impl = new rx::DisplayNULL(); #else
break; // No display available
#endif UNREACHABLE();
#endif // defined(ANGLE_ENABLE_NULL)
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
return impl; return impl;
} }
} } // anonymous namespace
Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap) Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap)
{ {
...@@ -899,6 +916,10 @@ static ClientExtensions GenerateClientExtensions() ...@@ -899,6 +916,10 @@ static ClientExtensions GenerateClientExtensions()
extensions.experimentalPresentPath = true; extensions.experimentalPresentPath = true;
#endif #endif
#if defined(ANGLE_ENABLE_VULKAN)
extensions.platformANGLEVulkan = true;
#endif
#if defined(ANGLE_USE_X11) #if defined(ANGLE_USE_X11)
extensions.x11Visual = true; extensions.x11Visual = true;
#endif #endif
...@@ -1032,4 +1053,4 @@ gl::Version Display::getMaxSupportedESVersion() const ...@@ -1032,4 +1053,4 @@ gl::Version Display::getMaxSupportedESVersion() const
{ {
return mImplementation->getMaxSupportedESVersion(); return mImplementation->getMaxSupportedESVersion();
} }
} } // namespace egl
...@@ -24,14 +24,12 @@ CompilerVk::~CompilerVk() ...@@ -24,14 +24,12 @@ CompilerVk::~CompilerVk()
gl::Error CompilerVk::release() gl::Error CompilerVk::release()
{ {
UNIMPLEMENTED(); return gl::NoError();
return gl::Error(GL_INVALID_OPERATION);
} }
ShShaderOutput CompilerVk::getTranslatorOutputType() const ShShaderOutput CompilerVk::getTranslatorOutputType() const
{ {
UNIMPLEMENTED(); return SH_GLSL_VULKAN_OUTPUT;
return ShShaderOutput();
} }
} // namespace rx } // namespace rx
...@@ -42,8 +42,7 @@ ContextVk::~ContextVk() ...@@ -42,8 +42,7 @@ ContextVk::~ContextVk()
gl::Error ContextVk::initialize() gl::Error ContextVk::initialize()
{ {
UNIMPLEMENTED(); return gl::NoError();
return gl::Error(GL_INVALID_OPERATION);
} }
gl::Error ContextVk::flush() gl::Error ContextVk::flush()
...@@ -133,8 +132,7 @@ std::string ContextVk::getVendorString() const ...@@ -133,8 +132,7 @@ std::string ContextVk::getVendorString() const
std::string ContextVk::getRendererDescription() const std::string ContextVk::getRendererDescription() const
{ {
UNIMPLEMENTED(); return mRenderer->getRendererDescription();
return std::string();
} }
void ContextVk::insertEventMarker(GLsizei length, const char *marker) void ContextVk::insertEventMarker(GLsizei length, const char *marker)
...@@ -169,9 +167,8 @@ GLint64 ContextVk::getTimestamp() ...@@ -169,9 +167,8 @@ GLint64 ContextVk::getTimestamp()
return GLint64(); return GLint64();
} }
void ContextVk::onMakeCurrent(const gl::ContextState &data) void ContextVk::onMakeCurrent(const gl::ContextState & /*data*/)
{ {
UNIMPLEMENTED();
} }
const gl::Caps &ContextVk::getNativeCaps() const const gl::Caps &ContextVk::getNativeCaps() const
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
#include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/SurfaceVk.h"
namespace rx namespace rx
{ {
...@@ -25,33 +29,71 @@ DisplayVk::~DisplayVk() ...@@ -25,33 +29,71 @@ DisplayVk::~DisplayVk()
egl::Error DisplayVk::initialize(egl::Display *display) egl::Error DisplayVk::initialize(egl::Display *display)
{ {
UNIMPLEMENTED(); ASSERT(!mRenderer && display != nullptr);
return egl::Error(EGL_BAD_ACCESS); mRenderer.reset(new RendererVk());
return mRenderer->initialize(display->getAttributeMap()).toEGL(EGL_NOT_INITIALIZED);
} }
void DisplayVk::terminate() void DisplayVk::terminate()
{ {
UNIMPLEMENTED(); mRenderer.reset(nullptr);
} }
egl::Error DisplayVk::makeCurrent(egl::Surface *drawSurface, egl::Error DisplayVk::makeCurrent(egl::Surface * /*drawSurface*/,
egl::Surface *readSurface, egl::Surface * /*readSurface*/,
gl::Context *context) gl::Context * /*context*/)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
egl::ConfigSet DisplayVk::generateConfigs() egl::ConfigSet DisplayVk::generateConfigs()
{ {
UNIMPLEMENTED(); // TODO(jmadill): Multiple configs, pbuffers, and proper checking of config attribs.
return egl::ConfigSet(); egl::Config singleton;
singleton.renderTargetFormat = GL_RGBA8;
singleton.depthStencilFormat = GL_NONE;
singleton.bufferSize = 32;
singleton.redSize = 8;
singleton.greenSize = 8;
singleton.blueSize = 8;
singleton.alphaSize = 8;
singleton.alphaMaskSize = 0;
singleton.bindToTextureRGB = EGL_FALSE;
singleton.bindToTextureRGBA = EGL_FALSE;
singleton.colorBufferType = EGL_RGB_BUFFER;
singleton.configCaveat = EGL_NONE;
singleton.conformant = 0;
singleton.depthSize = 0;
singleton.stencilSize = 0;
singleton.level = 0;
singleton.matchNativePixmap = EGL_NONE;
singleton.maxPBufferWidth = 0;
singleton.maxPBufferHeight = 0;
singleton.maxPBufferPixels = 0;
singleton.maxSwapInterval = 1;
singleton.minSwapInterval = 1;
singleton.nativeRenderable = EGL_TRUE;
singleton.nativeVisualID = 0;
singleton.nativeVisualType = EGL_NONE;
singleton.renderableType = EGL_OPENGL_ES2_BIT;
singleton.sampleBuffers = 0;
singleton.samples = 0;
singleton.surfaceType = EGL_WINDOW_BIT;
singleton.optimalOrientation = 0;
singleton.transparentType = EGL_NONE;
singleton.transparentRedValue = 0;
singleton.transparentGreenValue = 0;
singleton.transparentBlueValue = 0;
egl::ConfigSet configSet;
configSet.add(singleton);
return configSet;
} }
bool DisplayVk::testDeviceLost() bool DisplayVk::testDeviceLost()
{ {
UNIMPLEMENTED(); // TODO(jmadill): Figure out how to do device lost in Vulkan.
return bool(); return false;
} }
egl::Error DisplayVk::restoreLostDevice() egl::Error DisplayVk::restoreLostDevice()
...@@ -62,20 +104,19 @@ egl::Error DisplayVk::restoreLostDevice() ...@@ -62,20 +104,19 @@ egl::Error DisplayVk::restoreLostDevice()
bool DisplayVk::isValidNativeWindow(EGLNativeWindowType window) const bool DisplayVk::isValidNativeWindow(EGLNativeWindowType window) const
{ {
UNIMPLEMENTED(); // TODO(jmadill): Cross-platform this.
return bool(); return (IsWindow(window) == TRUE);
} }
std::string DisplayVk::getVendorString() const std::string DisplayVk::getVendorString() const
{ {
UNIMPLEMENTED(); // TODO(jmadill): Determine GPU vendor from Renderer.
return std::string(); return std::string("Google Inc.");
} }
egl::Error DisplayVk::getDevice(DeviceImpl **device) egl::Error DisplayVk::getDevice(DeviceImpl **device)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
egl::Error DisplayVk::waitClient() const egl::Error DisplayVk::waitClient() const
...@@ -96,15 +137,18 @@ SurfaceImpl *DisplayVk::createWindowSurface(const egl::SurfaceState &state, ...@@ -96,15 +137,18 @@ SurfaceImpl *DisplayVk::createWindowSurface(const egl::SurfaceState &state,
EGLNativeWindowType window, EGLNativeWindowType window,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); return new WindowSurfaceVk(state, window);
return static_cast<SurfaceImpl *>(0);
} }
SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state, SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); ASSERT(mRenderer);
return static_cast<SurfaceImpl *>(0);
EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
return new OffscreenSurfaceVk(state, width, height);
} }
SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state,
...@@ -134,7 +178,7 @@ ImageImpl *DisplayVk::createImage(EGLenum target, ...@@ -134,7 +178,7 @@ ImageImpl *DisplayVk::createImage(EGLenum target,
ContextImpl *DisplayVk::createContext(const gl::ContextState &state) ContextImpl *DisplayVk::createContext(const gl::ContextState &state)
{ {
return new ContextVk(state, mRenderer); return new ContextVk(state, mRenderer.get());
} }
StreamProducerImpl *DisplayVk::createStreamProducerD3DTextureNV12( StreamProducerImpl *DisplayVk::createStreamProducerD3DTextureNV12(
...@@ -153,12 +197,11 @@ gl::Version DisplayVk::getMaxSupportedESVersion() const ...@@ -153,12 +197,11 @@ gl::Version DisplayVk::getMaxSupportedESVersion() const
void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
{ {
UNIMPLEMENTED();
} }
void DisplayVk::generateCaps(egl::Caps *outCaps) const void DisplayVk::generateCaps(egl::Caps *outCaps) const
{ {
UNIMPLEMENTED(); outCaps->textureNPOT = true;
} }
} // namespace rx } // namespace rx
...@@ -73,7 +73,7 @@ class DisplayVk : public DisplayImpl ...@@ -73,7 +73,7 @@ class DisplayVk : public DisplayImpl
void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override; void generateCaps(egl::Caps *outCaps) const override;
RendererVk *mRenderer; std::unique_ptr<RendererVk> mRenderer;
}; };
} // namespace rx } // namespace rx
......
...@@ -9,12 +9,45 @@ ...@@ -9,12 +9,45 @@
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include <EGL/eglext.h>
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/TextureVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "platform/Platform.h"
namespace rx namespace rx
{ {
RendererVk::RendererVk() : mCapsInitialized(false), mInstance(nullptr) namespace
{
VkResult VerifyExtensionsPresent(const std::vector<VkExtensionProperties> &extensionProps,
const std::vector<const char *> &enabledExtensionNames)
{
// Compile the extensions names into a set.
std::set<std::string> extensionNames;
for (const auto &extensionProp : extensionProps)
{
extensionNames.insert(extensionProp.extensionName);
}
for (const auto &extensionName : enabledExtensionNames)
{
if (extensionNames.count(extensionName) == 0)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
return VK_SUCCESS;
}
} // anonymous namespace
RendererVk::RendererVk() : mCapsInitialized(false), mInstance(VK_NULL_HANDLE)
{ {
} }
...@@ -23,8 +56,29 @@ RendererVk::~RendererVk() ...@@ -23,8 +56,29 @@ RendererVk::~RendererVk()
vkDestroyInstance(mInstance, nullptr); vkDestroyInstance(mInstance, nullptr);
} }
vk::Error RendererVk::initialize() vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
{ {
uint32_t instanceExtensionCount = 0;
ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, nullptr));
std::vector<VkExtensionProperties> instanceExtensionProps(instanceExtensionCount);
if (instanceExtensionCount > 0)
{
ANGLE_VK_TRY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount,
instanceExtensionProps.data()));
}
std::vector<const char *> enabledInstanceExtensions;
enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
#if defined(ANGLE_PLATFORM_WINDOWS)
enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#else
#error Unsupported Vulkan platform.
#endif // defined(ANGLE_PLATFORM_WINDOWS)
// Verify the required extensions are in the extension names set. Fail if not.
ANGLE_VK_TRY(VerifyExtensionsPresent(instanceExtensionProps, enabledInstanceExtensions));
VkApplicationInfo applicationInfo; VkApplicationInfo applicationInfo;
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pNext = nullptr; applicationInfo.pNext = nullptr;
...@@ -40,17 +94,24 @@ vk::Error RendererVk::initialize() ...@@ -40,17 +94,24 @@ vk::Error RendererVk::initialize()
instanceInfo.flags = 0; instanceInfo.flags = 0;
instanceInfo.pApplicationInfo = &applicationInfo; instanceInfo.pApplicationInfo = &applicationInfo;
// TODO(jmadill): Layers and extensions. // Enable requested layers and extensions.
instanceInfo.enabledExtensionCount = 0; instanceInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
instanceInfo.ppEnabledExtensionNames = nullptr; instanceInfo.ppEnabledExtensionNames =
instanceInfo.enabledLayerCount = 0; enabledInstanceExtensions.empty() ? nullptr : enabledInstanceExtensions.data();
instanceInfo.ppEnabledLayerNames = nullptr; instanceInfo.enabledLayerCount = 0u;
instanceInfo.ppEnabledLayerNames = nullptr;
ANGLE_VK_TRY(vkCreateInstance(&instanceInfo, nullptr, &mInstance)); ANGLE_VK_TRY(vkCreateInstance(&instanceInfo, nullptr, &mInstance));
return vk::NoError(); return vk::NoError();
} }
std::string RendererVk::getRendererDescription() const
{
// TODO(jmadill): Description.
return "Vulkan";
}
void RendererVk::ensureCapsInitialized() const void RendererVk::ensureCapsInitialized() const
{ {
if (!mCapsInitialized) if (!mCapsInitialized)
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/renderer/vulkan/renderervk_utils.h" #include "libANGLE/renderer/vulkan/renderervk_utils.h"
namespace egl
{
class AttributeMap;
}
namespace rx namespace rx
{ {
...@@ -25,13 +30,17 @@ class RendererVk : angle::NonCopyable ...@@ -25,13 +30,17 @@ class RendererVk : angle::NonCopyable
RendererVk(); RendererVk();
~RendererVk(); ~RendererVk();
vk::Error initialize(const egl::AttributeMap &attribs);
std::string getRendererDescription() const;
VkInstance getInstance() const { return mInstance; }
const gl::Caps &getNativeCaps() const; const gl::Caps &getNativeCaps() const;
const gl::TextureCapsMap &getNativeTextureCaps() const; const gl::TextureCapsMap &getNativeTextureCaps() const;
const gl::Extensions &getNativeExtensions() const; const gl::Extensions &getNativeExtensions() const;
const gl::Limitations &getNativeLimitations() const; const gl::Limitations &getNativeLimitations() const;
vk::Error initialize();
private: private:
void ensureCapsInitialized() const; void ensureCapsInitialized() const;
void generateCaps(gl::Caps *outCaps, void generateCaps(gl::Caps *outCaps,
......
...@@ -10,93 +10,175 @@ ...@@ -10,93 +10,175 @@
#include "libANGLE/renderer/vulkan/SurfaceVk.h" #include "libANGLE/renderer/vulkan/SurfaceVk.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx namespace rx
{ {
SurfaceVk::SurfaceVk(const egl::SurfaceState &surfaceState) : SurfaceImpl(surfaceState) OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
EGLint width,
EGLint height)
: SurfaceImpl(surfaceState), mWidth(width), mHeight(height)
{ {
} }
SurfaceVk::~SurfaceVk() OffscreenSurfaceVk::~OffscreenSurfaceVk()
{ {
} }
egl::Error SurfaceVk::initialize(const DisplayImpl *displayImpl) egl::Error OffscreenSurfaceVk::initialize(const DisplayImpl *displayImpl)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
FramebufferImpl *SurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state) FramebufferImpl *OffscreenSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
{ {
UNIMPLEMENTED(); return new FramebufferVk(state);
return static_cast<FramebufferImpl *>(0);
} }
egl::Error SurfaceVk::swap(const DisplayImpl *displayImpl) egl::Error OffscreenSurfaceVk::swap(const DisplayImpl *displayImpl)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
egl::Error SurfaceVk::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) egl::Error OffscreenSurfaceVk::postSubBuffer(EGLint /*x*/,
EGLint /*y*/,
EGLint /*width*/,
EGLint /*height*/)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
egl::Error SurfaceVk::querySurfacePointerANGLE(EGLint attribute, void **value) egl::Error OffscreenSurfaceVk::querySurfacePointerANGLE(EGLint /*attribute*/, void ** /*value*/)
{ {
UNIMPLEMENTED(); UNREACHABLE();
return egl::Error(EGL_BAD_ACCESS); return egl::Error(EGL_BAD_CURRENT_SURFACE);
} }
egl::Error SurfaceVk::bindTexImage(gl::Texture *texture, EGLint buffer) egl::Error OffscreenSurfaceVk::bindTexImage(gl::Texture * /*texture*/, EGLint /*buffer*/)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
egl::Error SurfaceVk::releaseTexImage(EGLint buffer) egl::Error OffscreenSurfaceVk::releaseTexImage(EGLint /*buffer*/)
{ {
UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS);
return egl::Error(EGL_BAD_ACCESS);
} }
void SurfaceVk::setSwapInterval(EGLint interval) void OffscreenSurfaceVk::setSwapInterval(EGLint /*interval*/)
{ {
UNIMPLEMENTED();
} }
EGLint SurfaceVk::getWidth() const EGLint OffscreenSurfaceVk::getWidth() const
{ {
UNIMPLEMENTED(); return mWidth;
return EGLint();
} }
EGLint SurfaceVk::getHeight() const EGLint OffscreenSurfaceVk::getHeight() const
{ {
UNIMPLEMENTED(); return mHeight;
return EGLint();
} }
EGLint SurfaceVk::isPostSubBufferSupported() const EGLint OffscreenSurfaceVk::isPostSubBufferSupported() const
{ {
UNIMPLEMENTED(); return EGL_FALSE;
return EGLint();
} }
EGLint SurfaceVk::getSwapBehavior() const EGLint OffscreenSurfaceVk::getSwapBehavior() const
{ {
UNIMPLEMENTED(); return EGL_BUFFER_PRESERVED;
return EGLint();
} }
gl::Error SurfaceVk::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, gl::Error OffscreenSurfaceVk::getAttachmentRenderTarget(
FramebufferAttachmentRenderTarget **rtOut) const gl::FramebufferAttachment::Target & /*target*/,
FramebufferAttachmentRenderTarget ** /*rtOut*/)
{ {
UNIMPLEMENTED(); UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState, EGLNativeWindowType window)
: SurfaceImpl(surfaceState)
{
}
WindowSurfaceVk::~WindowSurfaceVk()
{
}
egl::Error WindowSurfaceVk::initialize(const DisplayImpl *displayImpl)
{
// TODO(jmadill)
return egl::Error(EGL_SUCCESS);
}
FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
{
return new FramebufferVk(state);
}
egl::Error WindowSurfaceVk::swap(const DisplayImpl *displayImpl)
{
// TODO(jmadill)
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceVk::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
// TODO(jmadill)
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceVk::querySurfacePointerANGLE(EGLint attribute, void **value)
{
UNREACHABLE();
return egl::Error(EGL_BAD_CURRENT_SURFACE);
}
egl::Error WindowSurfaceVk::bindTexImage(gl::Texture *texture, EGLint buffer)
{
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceVk::releaseTexImage(EGLint buffer)
{
return egl::Error(EGL_SUCCESS);
}
void WindowSurfaceVk::setSwapInterval(EGLint interval)
{
}
EGLint WindowSurfaceVk::getWidth() const
{
// TODO(jmadill)
return 0;
}
EGLint WindowSurfaceVk::getHeight() const
{
// TODO(jmadill)
return 0;
}
EGLint WindowSurfaceVk::isPostSubBufferSupported() const
{
// TODO(jmadill)
return EGL_FALSE;
}
EGLint WindowSurfaceVk::getSwapBehavior() const
{
// TODO(jmadill)
return EGL_BUFFER_DESTROYED;
}
gl::Error WindowSurfaceVk::getAttachmentRenderTarget(
const gl::FramebufferAttachment::Target &target,
FramebufferAttachmentRenderTarget **rtOut)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
......
...@@ -14,12 +14,43 @@ ...@@ -14,12 +14,43 @@
namespace rx namespace rx
{ {
class RendererVk;
class SurfaceVk : public SurfaceImpl class OffscreenSurfaceVk : public SurfaceImpl
{ {
public: public:
SurfaceVk(const egl::SurfaceState &surfaceState); OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, EGLint width, EGLint height);
~SurfaceVk() override; ~OffscreenSurfaceVk() override;
egl::Error initialize(const DisplayImpl *displayImpl) override;
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
egl::Error swap(const DisplayImpl *displayImpl) override;
egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
egl::Error releaseTexImage(EGLint buffer) override;
void setSwapInterval(EGLint interval) override;
// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target,
FramebufferAttachmentRenderTarget **rtOut) override;
private:
EGLint mWidth;
EGLint mHeight;
};
class WindowSurfaceVk : public SurfaceImpl
{
public:
WindowSurfaceVk(const egl::SurfaceState &surfaceState, EGLNativeWindowType window);
~WindowSurfaceVk() override;
egl::Error initialize(const DisplayImpl *displayImpl) override; egl::Error initialize(const DisplayImpl *displayImpl) override;
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
......
...@@ -1613,4 +1613,51 @@ Error ValidateSwapBuffersWithDamageEXT(const Display *display, ...@@ -1613,4 +1613,51 @@ Error ValidateSwapBuffersWithDamageEXT(const Display *display,
return Error(EGL_SUCCESS); return Error(EGL_SUCCESS);
} }
} // namespace gl Error ValidatePlatformType(const ClientExtensions &clientExtensions, EGLint platformType)
{
switch (platformType)
{
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
if (!clientExtensions.platformANGLED3D)
{
return Error(EGL_BAD_ATTRIBUTE, "Direct3D platform is unsupported.");
}
break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
if (!clientExtensions.platformANGLEOpenGL)
{
return Error(EGL_BAD_ATTRIBUTE, "OpenGL platform is unsupported.");
}
break;
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
if (!clientExtensions.platformANGLENULL)
{
return Error(EGL_BAD_ATTRIBUTE,
"Display type "
"EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE "
"requires EGL_ANGLE_platform_angle_null.");
}
break;
case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
if (!clientExtensions.platformANGLEVulkan)
{
return Error(EGL_BAD_ATTRIBUTE, "Vulkan platform is unsupported.");
}
break;
default:
return Error(EGL_BAD_ATTRIBUTE, "Unknown platform type.");
}
return Error(EGL_SUCCESS);
}
} // namespace egl
...@@ -23,6 +23,7 @@ namespace egl ...@@ -23,6 +23,7 @@ namespace egl
{ {
class AttributeMap; class AttributeMap;
struct ClientExtensions;
struct Config; struct Config;
class Device; class Device;
class Display; class Display;
...@@ -106,6 +107,8 @@ Error ValidateCompatibleConfigs(const Display *display, ...@@ -106,6 +107,8 @@ Error ValidateCompatibleConfigs(const Display *display,
const Surface *surface, const Surface *surface,
const Config *config2, const Config *config2,
EGLint surfaceType); EGLint surfaceType);
}
Error ValidatePlatformType(const ClientExtensions &clientExtensions, EGLint platformType);
} // namespace gl
#endif // LIBANGLE_VALIDATIONEGL_H_ #endif // LIBANGLE_VALIDATIONEGL_H_
...@@ -165,12 +165,13 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -165,12 +165,13 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
{ {
EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
bool majorVersionSpecified = false;
bool minorVersionSpecified = false;
bool enableAutoTrimSpecified = false; bool enableAutoTrimSpecified = false;
bool deviceTypeSpecified = false; bool deviceTypeSpecified = false;
bool presentPathSpecified = false; bool presentPathSpecified = false;
Optional<EGLint> majorVersion;
Optional<EGLint> minorVersion;
if (attrib_list) if (attrib_list)
{ {
for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
...@@ -178,58 +179,28 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -178,58 +179,28 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
switch (curAttrib[0]) switch (curAttrib[0])
{ {
case EGL_PLATFORM_ANGLE_TYPE_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
switch (curAttrib[1])
{ {
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: egl::Error error = ValidatePlatformType(clientExtensions, curAttrib[1]);
break; if (error.isError())
{
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: thread->setError(error);
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
if (!clientExtensions.platformANGLED3D)
{
thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY;
}
break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
if (!clientExtensions.platformANGLEOpenGL)
{
thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY;
}
break;
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
if (!clientExtensions.platformANGLENULL)
{
thread->setError(Error(EGL_BAD_ATTRIBUTE,
"Display type "
"EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE "
"requires EGL_ANGLE_platform_angle_null."));
return EGL_NO_DISPLAY;
}
break;
default:
thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
}
platformType = curAttrib[1];
break;
} }
platformType = curAttrib[1];
break;
case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
if (curAttrib[1] != EGL_DONT_CARE) if (curAttrib[1] != EGL_DONT_CARE)
{ {
majorVersionSpecified = true; majorVersion = curAttrib[1];
} }
break; break;
case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
if (curAttrib[1] != EGL_DONT_CARE) if (curAttrib[1] != EGL_DONT_CARE)
{ {
minorVersionSpecified = true; minorVersion = curAttrib[1];
} }
break; break;
...@@ -292,13 +263,37 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -292,13 +263,37 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
deviceType = curAttrib[1]; deviceType = curAttrib[1];
break; break;
case EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE:
if (!clientExtensions.platformANGLEVulkan)
{
thread->setError(
Error(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_platform_angle_vulkan extension not active"));
return EGL_NO_DISPLAY;
}
if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
thread->setError(
Error(EGL_BAD_ATTRIBUTE,
"Validation can only be enabled for the Vulkan back-end."));
return EGL_NO_DISPLAY;
}
if (curAttrib[1] != EGL_TRUE && curAttrib[1] != EGL_FALSE)
{
thread->setError(
Error(EGL_BAD_ATTRIBUTE,
"Validation layer attribute must be EGL_TRUE or EGL_FALSE."));
return EGL_NO_DISPLAY;
}
break;
default: default:
break; break;
} }
} }
} }
if (!majorVersionSpecified && minorVersionSpecified) if (!majorVersion.valid() && minorVersion.valid())
{ {
thread->setError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
...@@ -341,6 +336,18 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -341,6 +336,18 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
if ((majorVersion.valid() && majorVersion.value() != 1) ||
(minorVersion.valid() && minorVersion.value() != 0))
{
thread->setError(Error(
EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently only supports Vulkan 1.0."));
return EGL_NO_DISPLAY;
}
}
thread->setError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return Display::GetDisplayFromAttribs(native_display, return Display::GetDisplayFromAttribs(native_display,
AttributeMap::CreateFromIntArray(attrib_list)); AttributeMap::CreateFromIntArray(attrib_list));
......
...@@ -106,6 +106,11 @@ TEST_P(RendererTest, RequestedRendererCreated) ...@@ -106,6 +106,11 @@ TEST_P(RendererTest, RequestedRendererCreated)
ASSERT_TRUE(IsNULL()); ASSERT_TRUE(IsNULL());
} }
if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
ASSERT_TRUE(IsVulkan());
}
EGLint glesMajorVersion = GetParam().majorVersion; EGLint glesMajorVersion = GetParam().majorVersion;
EGLint glesMinorVersion = GetParam().minorVersion; EGLint glesMinorVersion = GetParam().minorVersion;
...@@ -126,6 +131,9 @@ TEST_P(RendererTest, RequestedRendererCreated) ...@@ -126,6 +131,9 @@ TEST_P(RendererTest, RequestedRendererCreated)
{ {
FAIL() << "Unhandled GL ES client version."; FAIL() << "Unhandled GL ES client version.";
} }
ASSERT_GL_NO_ERROR();
ASSERT_EGL_SUCCESS();
} }
// Perform a simple operation (clear and read pixels) to verify the device is working // Perform a simple operation (clear and read pixels) to verify the device is working
...@@ -137,6 +145,13 @@ TEST_P(RendererTest, SimpleOperation) ...@@ -137,6 +145,13 @@ TEST_P(RendererTest, SimpleOperation)
return; return;
} }
// TODO(jmadil): Vulkan clear.
if (IsVulkan())
{
std::cout << "Vulkan clears not yet implemented" << std::endl;
return;
}
glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
...@@ -229,5 +244,9 @@ ANGLE_INSTANTIATE_TEST(RendererTest, ...@@ -229,5 +244,9 @@ ANGLE_INSTANTIATE_TEST(RendererTest,
// All ES version on top of the NULL backend // All ES version on top of the NULL backend
ES2_NULL(), ES2_NULL(),
ES3_NULL(), ES3_NULL(),
ES31_NULL()); ES31_NULL(),
}
// ES on top of Vulkan
ES2_VULKAN(),
ES3_VULKAN());
} // anonymous namespace
...@@ -795,6 +795,12 @@ bool IsAndroid() ...@@ -795,6 +795,12 @@ bool IsAndroid()
#endif #endif
} }
bool IsVulkan()
{
std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
return (rendererString.find("Vulkan") != std::string::npos);
}
bool IsLinux() bool IsLinux()
{ {
#if defined(ANGLE_PLATFORM_LINUX) #if defined(ANGLE_PLATFORM_LINUX)
......
...@@ -262,6 +262,7 @@ bool IsAndroid(); ...@@ -262,6 +262,7 @@ bool IsAndroid();
bool IsLinux(); bool IsLinux();
bool IsOSX(); bool IsOSX();
bool IsWindows(); bool IsWindows();
bool IsVulkan();
// Debug/Release // Debug/Release
bool IsDebug(); bool IsDebug();
......
...@@ -59,27 +59,30 @@ std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp) ...@@ -59,27 +59,30 @@ std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp)
switch (pp.eglParameters.renderer) switch (pp.eglParameters.renderer)
{ {
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
stream << "D3D9"; stream << "DEFAULT";
break; break;
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
stream << "D3D11"; stream << "D3D9";
break; break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
stream << "OPENGL"; stream << "D3D11";
break; break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
stream << "OPENGLES"; stream << "NULL";
break; break;
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
stream << "NULL"; stream << "OPENGL";
break; break;
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
stream << "DEFAULT"; stream << "OPENGLES";
break; break;
default: case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
stream << "UNDEFINED"; stream << "VULKAN";
break; break;
default:
stream << "UNDEFINED";
break;
} }
if (pp.eglParameters.majorVersion != EGL_DONT_CARE) if (pp.eglParameters.majorVersion != EGL_DONT_CARE)
...@@ -370,7 +373,12 @@ EGLPlatformParameters OPENGLES(EGLint major, EGLint minor) ...@@ -370,7 +373,12 @@ EGLPlatformParameters OPENGLES(EGLint major, EGLint minor)
EGL_DONT_CARE); EGL_DONT_CARE);
} }
} // namespace egl_platform EGLPlatformParameters VULKAN()
{
return EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
}
} // namespace egl_platform
// ANGLE tests platforms // ANGLE tests platforms
PlatformParameters ES2_D3D9() PlatformParameters ES2_D3D9()
...@@ -613,4 +621,14 @@ PlatformParameters ES31_NULL() ...@@ -613,4 +621,14 @@ PlatformParameters ES31_NULL()
return PlatformParameters(3, 1, EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE)); return PlatformParameters(3, 1, EGLPlatformParameters(EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE));
} }
} // namespace angle PlatformParameters ES2_VULKAN()
{
return PlatformParameters(2, 0, egl_platform::VULKAN());
}
PlatformParameters ES3_VULKAN()
{
return PlatformParameters(3, 0, egl_platform::VULKAN());
}
} // namespace angle
...@@ -82,7 +82,9 @@ EGLPlatformParameters OPENGL_NULL(); ...@@ -82,7 +82,9 @@ EGLPlatformParameters OPENGL_NULL();
EGLPlatformParameters OPENGLES(); EGLPlatformParameters OPENGLES();
EGLPlatformParameters OPENGLES(EGLint major, EGLint minor); EGLPlatformParameters OPENGLES(EGLint major, EGLint minor);
} // namespace egl_platform EGLPlatformParameters VULKAN();
} // namespace egl_platform
// ANGLE tests platforms // ANGLE tests platforms
PlatformParameters ES2_D3D9(); PlatformParameters ES2_D3D9();
...@@ -143,6 +145,9 @@ PlatformParameters ES2_NULL(); ...@@ -143,6 +145,9 @@ PlatformParameters ES2_NULL();
PlatformParameters ES3_NULL(); PlatformParameters ES3_NULL();
PlatformParameters ES31_NULL(); PlatformParameters ES31_NULL();
} // namespace angle PlatformParameters ES2_VULKAN();
PlatformParameters ES3_VULKAN();
} // namespace angle
#endif // ANGLE_TEST_CONFIGS_H_ #endif // ANGLE_TEST_CONFIGS_H_
...@@ -23,27 +23,37 @@ bool IsPlatformAvailable(const PlatformParameters &param) ...@@ -23,27 +23,37 @@ bool IsPlatformAvailable(const PlatformParameters &param)
{ {
switch (param.getRenderer()) switch (param.getRenderer())
{ {
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
break; break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
#if !defined(ANGLE_ENABLE_D3D9)
return false;
#else
break;
#endif
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
#ifndef ANGLE_ENABLE_D3D9 #if !defined(ANGLE_ENABLE_D3D11)
return false; return false;
#else
break;
#endif #endif
break;
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
#ifndef ANGLE_ENABLE_D3D11 case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
return false; #if !defined(ANGLE_ENABLE_OPENGL)
return false;
#else
break;
#endif #endif
break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: #if !defined(ANGLE_ENABLE_VULKAN)
#ifndef ANGLE_ENABLE_OPENGL return false;
return false; #else
break;
#endif #endif
break;
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
#ifndef ANGLE_ENABLE_NULL #ifndef ANGLE_ENABLE_NULL
...@@ -91,4 +101,4 @@ bool IsPlatformAvailable(const PlatformParameters &param) ...@@ -91,4 +101,4 @@ bool IsPlatformAvailable(const PlatformParameters &param)
} }
} }
} } // namespace angle
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