Commit b0f917fa by Geoff Lang Committed by Commit Bot

Fix being unable to request some extensions implemented in the GL layer.

Some extensions are forced on in Context::initCaps even though the backend's native extensions do not mark the extension as supported. These extensions were not requestable because the Context::isExtensionRequestable only checks if the backend supports the extension. Make GL_OES_vertex_array_object requestable to cover the issue. BUG=angleproject:1523 Change-Id: Ie64df8e270924727ecf9cd3f993443abeb3ef658 Reviewed-on: https://chromium-review.googlesource.com/809197 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 025aafdf
......@@ -672,7 +672,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject);
map["GL_OES_vertex_array_object"] = enableableExtension(&Extensions::vertexArrayObject);
map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
// TODO(jmadill): Enable this when complete.
//map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError);
......
......@@ -350,15 +350,14 @@ Context::Context(rx::EGLImplFactory *implFactory,
}
}
const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
if (nativeExtensions.textureRectangle)
if (mSupportedExtensions.textureRectangle)
{
Texture *zeroTextureRectangle =
new Texture(mImplementation.get(), 0, TextureType::Rectangle);
mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
}
if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
if (mSupportedExtensions.eglImageExternal || mSupportedExtensions.eglStreamConsumerExternal)
{
Texture *zeroTextureExternal = new Texture(mImplementation.get(), 0, TextureType::External);
mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
......@@ -2871,14 +2870,12 @@ void Context::initExtensionStrings()
}
mExtensionString = mergeExtensionStrings(mExtensionStrings);
const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
mRequestableExtensionStrings.clear();
for (const auto &extensionInfo : GetExtensionInfoMap())
{
if (extensionInfo.second.Requestable &&
!(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
nativeExtensions.*(extensionInfo.second.ExtensionsMember))
mSupportedExtensions.*(extensionInfo.second.ExtensionsMember))
{
mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
}
......@@ -2940,9 +2937,8 @@ bool Context::isExtensionRequestable(const char *name)
const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
auto extension = extensionInfos.find(name);
const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
return extension != extensionInfos.end() && extension->second.Requestable &&
nativeExtensions.*(extension->second.ExtensionsMember);
mSupportedExtensions.*(extension->second.ExtensionsMember);
}
void Context::requestExtension(const char *name)
......@@ -2951,7 +2947,7 @@ void Context::requestExtension(const char *name)
ASSERT(extensionInfos.find(name) != extensionInfos.end());
const auto &extension = extensionInfos.at(name);
ASSERT(extension.Requestable);
ASSERT(mImplementation->getNativeExtensions().*(extension.ExtensionsMember));
ASSERT(isExtensionRequestable(name));
if (mExtensions.*(extension.ExtensionsMember))
{
......@@ -3006,83 +3002,95 @@ bool Context::hasActiveTransformFeedback(GLuint program) const
return false;
}
void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
Extensions Context::generateSupportedExtensions(const egl::DisplayExtensions &displayExtensions,
bool robustResourceInit) const
{
mCaps = mImplementation->getNativeCaps();
Extensions supportedExtensions = mImplementation->getNativeExtensions();
mExtensions = mImplementation->getNativeExtensions();
mLimitations = mImplementation->getNativeLimitations();
// GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
if (getClientVersion() < Version(2, 0))
if (getClientVersion() < ES_2_0)
{
mCaps.maxMultitextureUnits = 4;
mCaps.maxClipPlanes = 6;
mCaps.maxLights = 8;
mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
// Default extensions for GLES1
mExtensions.pointSizeArray = true;
supportedExtensions.pointSizeArray = true;
}
if (getClientVersion() < Version(3, 0))
if (getClientVersion() < ES_3_0)
{
// Disable ES3+ extensions
mExtensions.colorBufferFloat = false;
mExtensions.eglImageExternalEssl3 = false;
mExtensions.textureNorm16 = false;
mExtensions.multiview = false;
mExtensions.maxViews = 1u;
supportedExtensions.colorBufferFloat = false;
supportedExtensions.eglImageExternalEssl3 = false;
supportedExtensions.textureNorm16 = false;
supportedExtensions.multiview = false;
supportedExtensions.maxViews = 1u;
}
if (getClientVersion() < ES_3_1)
{
// Disable ES3.1+ extensions
mExtensions.geometryShader = false;
supportedExtensions.geometryShader = false;
}
if (getClientVersion() > Version(2, 0))
if (getClientVersion() > ES_2_0)
{
// FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
// mExtensions.sRGB = false;
// supportedExtensions.sRGB = false;
}
// Some extensions are always available because they are implemented in the GL layer.
mExtensions.bindUniformLocation = true;
mExtensions.vertexArrayObject = true;
mExtensions.bindGeneratesResource = true;
mExtensions.clientArrays = true;
mExtensions.requestExtension = true;
supportedExtensions.bindUniformLocation = true;
supportedExtensions.vertexArrayObject = true;
supportedExtensions.bindGeneratesResource = true;
supportedExtensions.clientArrays = true;
supportedExtensions.requestExtension = true;
// Enable the no error extension if the context was created with the flag.
mExtensions.noError = mSkipValidation;
supportedExtensions.noError = mSkipValidation;
// Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
supportedExtensions.surfacelessContext = displayExtensions.surfacelessContext;
// Explicitly enable GL_KHR_debug
mExtensions.debug = true;
mExtensions.maxDebugMessageLength = 1024;
mExtensions.maxDebugLoggedMessages = 1024;
mExtensions.maxDebugGroupStackDepth = 1024;
mExtensions.maxLabelLength = 1024;
supportedExtensions.debug = true;
supportedExtensions.maxDebugMessageLength = 1024;
supportedExtensions.maxDebugLoggedMessages = 1024;
supportedExtensions.maxDebugGroupStackDepth = 1024;
supportedExtensions.maxLabelLength = 1024;
// Explicitly enable GL_ANGLE_robust_client_memory
mExtensions.robustClientMemory = true;
supportedExtensions.robustClientMemory = true;
// Determine robust resource init availability from EGL.
mExtensions.robustResourceInitialization = robustResourceInit;
supportedExtensions.robustResourceInitialization = robustResourceInit;
// mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
// supports it.
mExtensions.robustBufferAccessBehavior =
mRobustAccess && mExtensions.robustBufferAccessBehavior;
supportedExtensions.robustBufferAccessBehavior =
mRobustAccess && supportedExtensions.robustBufferAccessBehavior;
// Enable the cache control query unconditionally.
mExtensions.programCacheControl = true;
supportedExtensions.programCacheControl = true;
return supportedExtensions;
}
void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
{
mCaps = mImplementation->getNativeCaps();
mSupportedExtensions = generateSupportedExtensions(displayExtensions, robustResourceInit);
mExtensions = mSupportedExtensions;
mLimitations = mImplementation->getNativeLimitations();
// GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
if (getClientVersion() < Version(2, 0))
{
mCaps.maxMultitextureUnits = 4;
mCaps.maxClipPlanes = 6;
mCaps.maxLights = 8;
mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
}
// Apply implementation limits
LimitCap(&mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
......@@ -3207,7 +3215,7 @@ void Context::updateCaps()
}
// If program binary is disabled, blank out the memory cache pointer.
if (!mImplementation->getNativeExtensions().getProgramBinary)
if (!mSupportedExtensions.getProgramBinary)
{
mMemoryProgramCache = nullptr;
}
......
......@@ -1490,6 +1490,8 @@ class Context final : angle::NonCopyable
void initVersionStrings();
void initExtensionStrings();
Extensions generateSupportedExtensions(const egl::DisplayExtensions &displayExtensions,
bool robustResourceInit) const;
void initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit);
void updateCaps();
void initWorkarounds();
......@@ -1517,6 +1519,10 @@ class Context final : angle::NonCopyable
Extensions mExtensions;
Limitations mLimitations;
// Extensions supported by the implementation plus extensions that are implemented entirely
// within the frontend.
Extensions mSupportedExtensions;
// Shader compiler. Lazily initialized hence the mutable value.
mutable BindingPointer<Compiler> mCompiler;
......
......@@ -1085,6 +1085,41 @@ TEST_P(WebGLCompatibilityTest, EnableProgramBinaryExtension)
}
}
// Test enabling the GL_OES_vertex_array_object extension
TEST_P(WebGLCompatibilityTest, EnableVertexArrayExtension)
{
EXPECT_FALSE(extensionEnabled("GL_OES_vertex_array_object"));
// This extensions become core in in ES3/WebGL2.
ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
GLint result = 0;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &result);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
// Expect that GL_OES_vertex_array_object is always available. It is implemented in the GL
// frontend.
EXPECT_TRUE(extensionRequestable("GL_OES_vertex_array_object"));
glRequestExtensionANGLE("GL_OES_vertex_array_object");
EXPECT_GL_NO_ERROR();
EXPECT_TRUE(extensionEnabled("GL_OES_vertex_array_object"));
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &result);
EXPECT_GL_NO_ERROR();
GLuint vao = 0;
glGenVertexArraysOES(0, &vao);
EXPECT_GL_NO_ERROR();
glBindVertexArrayOES(vao);
EXPECT_GL_NO_ERROR();
glDeleteVertexArraysOES(1, &vao);
EXPECT_GL_NO_ERROR();
}
// Verify that the context generates the correct error when the framebuffer attachments are
// different sizes
TEST_P(WebGLCompatibilityTest, FramebufferAttachmentSizeMismatch)
......
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