Commit 74c2347e by Sami Väisänen Committed by Commit Bot

Support EXT_multisample_compatibility in the GL backend

BUG=angleproject:1377 Change-Id: Ie14aceca8e01f1cbc93fd5bd06d986336fb752b3 Reviewed-on: https://chromium-review.googlesource.com/343501Reviewed-by: 's avatarSami Väisänen <svaisanen@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Sami Väisänen <svaisanen@nvidia.com>
parent 87fc71c4
...@@ -160,7 +160,8 @@ Extensions::Extensions() ...@@ -160,7 +160,8 @@ Extensions::Extensions()
lossyETCDecode(false), lossyETCDecode(false),
bindUniformLocation(false), bindUniformLocation(false),
syncQuery(false), syncQuery(false),
colorBufferFloat(false) colorBufferFloat(false),
multisampleCompatibility(false)
{ {
} }
...@@ -234,6 +235,7 @@ std::vector<std::string> Extensions::getStrings() const ...@@ -234,6 +235,7 @@ std::vector<std::string> Extensions::getStrings() const
InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings); InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings);
InsertExtensionString("GL_CHROMIUM_bind_uniform_location", bindUniformLocation, &extensionStrings); InsertExtensionString("GL_CHROMIUM_bind_uniform_location", bindUniformLocation, &extensionStrings);
InsertExtensionString("GL_CHROMIUM_sync_query", syncQuery, &extensionStrings); InsertExtensionString("GL_CHROMIUM_sync_query", syncQuery, &extensionStrings);
InsertExtensionString("GL_EXT_multisample_compatibility", multisampleCompatibility, &extensionStrings);
// clang-format on // clang-format on
return extensionStrings; return extensionStrings;
......
...@@ -291,6 +291,10 @@ struct Extensions ...@@ -291,6 +291,10 @@ struct Extensions
// GL_EXT_color_buffer_float // GL_EXT_color_buffer_float
bool colorBufferFloat; bool colorBufferFloat;
// GL_EXT_multisample_compatibility.
// written against ES 3.1 but can apply to earlier versions.
bool multisampleCompatibility;
}; };
struct Limitations struct Limitations
......
...@@ -1405,6 +1405,18 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu ...@@ -1405,6 +1405,18 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
} }
} }
if (mExtensions.multisampleCompatibility)
{
switch (pname)
{
case GL_MULTISAMPLE_EXT:
case GL_SAMPLE_ALPHA_TO_ONE_EXT:
*type = GL_BOOL;
*numParams = 1;
return true;
}
}
// Check for ES3.0+ parameter names which are also exposed as ES2 extensions // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
switch (pname) switch (pname)
{ {
......
...@@ -42,7 +42,9 @@ State::State() ...@@ -42,7 +42,9 @@ State::State()
mProgram(nullptr), mProgram(nullptr),
mVertexArray(nullptr), mVertexArray(nullptr),
mActiveSampler(0), mActiveSampler(0),
mPrimitiveRestart(false) mPrimitiveRestart(false),
mMultiSampling(false),
mSampleAlphaToOne(false)
{ {
} }
...@@ -170,6 +172,12 @@ void State::initialize(const Caps &caps, ...@@ -170,6 +172,12 @@ void State::initialize(const Caps &caps,
mDebug.setOutputEnabled(debug); mDebug.setOutputEnabled(debug);
mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages); mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
if (extensions.framebufferMultisample)
{
mMultiSampling = true;
mSampleAlphaToOne = false;
}
} }
void State::reset() void State::reset()
...@@ -504,6 +512,28 @@ bool State::getSampleCoverageInvert() const ...@@ -504,6 +512,28 @@ bool State::getSampleCoverageInvert() const
return mSampleCoverageInvert; return mSampleCoverageInvert;
} }
void State::setSampleAlphaToOne(bool enabled)
{
mSampleAlphaToOne = enabled;
mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
}
bool State::isSampleAlphaToOneEnabled() const
{
return mSampleAlphaToOne;
}
void State::setMultisampling(bool enabled)
{
mMultiSampling = enabled;
mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
}
bool State::isMultisamplingEnabled() const
{
return mMultiSampling;
}
bool State::isScissorTestEnabled() const bool State::isScissorTestEnabled() const
{ {
return mScissorTest; return mScissorTest;
...@@ -555,6 +585,8 @@ void State::setEnableFeature(GLenum feature, bool enabled) ...@@ -555,6 +585,8 @@ void State::setEnableFeature(GLenum feature, bool enabled)
{ {
switch (feature) switch (feature)
{ {
case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
case GL_CULL_FACE: setCullFace(enabled); break; case GL_CULL_FACE: setCullFace(enabled); break;
case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break; case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break; case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
...@@ -580,6 +612,8 @@ bool State::getEnableFeature(GLenum feature) ...@@ -580,6 +612,8 @@ bool State::getEnableFeature(GLenum feature)
{ {
switch (feature) switch (feature)
{ {
case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
case GL_CULL_FACE: return isCullFaceEnabled(); case GL_CULL_FACE: return isCullFaceEnabled();
case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled(); case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled(); case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
...@@ -1360,6 +1394,12 @@ void State::getBooleanv(GLenum pname, GLboolean *params) ...@@ -1360,6 +1394,12 @@ void State::getBooleanv(GLenum pname, GLboolean *params)
case GL_DEBUG_OUTPUT: case GL_DEBUG_OUTPUT:
*params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE; *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
break; break;
case GL_MULTISAMPLE_EXT:
*params = mMultiSampling;
break;
case GL_SAMPLE_ALPHA_TO_ONE_EXT:
*params = mSampleAlphaToOne;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1395,6 +1435,12 @@ void State::getFloatv(GLenum pname, GLfloat *params) ...@@ -1395,6 +1435,12 @@ void State::getFloatv(GLenum pname, GLfloat *params)
params[2] = mBlendColor.blue; params[2] = mBlendColor.blue;
params[3] = mBlendColor.alpha; params[3] = mBlendColor.alpha;
break; break;
case GL_MULTISAMPLE_EXT:
*params = static_cast<GLfloat>(mMultiSampling);
break;
case GL_SAMPLE_ALPHA_TO_ONE_EXT:
*params = static_cast<GLfloat>(mSampleAlphaToOne);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1633,6 +1679,12 @@ void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params) ...@@ -1633,6 +1679,12 @@ void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params)
case GL_DEBUG_GROUP_STACK_DEPTH: case GL_DEBUG_GROUP_STACK_DEPTH:
*params = static_cast<GLint>(mDebug.getGroupStackDepth()); *params = static_cast<GLint>(mDebug.getGroupStackDepth());
break; break;
case GL_MULTISAMPLE_EXT:
*params = static_cast<GLint>(mMultiSampling);
break;
case GL_SAMPLE_ALPHA_TO_ONE_EXT:
*params = static_cast<GLint>(mSampleAlphaToOne);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -118,6 +118,12 @@ class State : angle::NonCopyable ...@@ -118,6 +118,12 @@ class State : angle::NonCopyable
GLclampf getSampleCoverageValue() const; GLclampf getSampleCoverageValue() const;
bool getSampleCoverageInvert() const; bool getSampleCoverageInvert() const;
// Multisampling/alpha to one manipulation.
void setSampleAlphaToOne(bool enabled);
bool isSampleAlphaToOneEnabled() const;
void setMultisampling(bool enabled);
bool isMultisamplingEnabled() const;
// Scissor test state toggle & query // Scissor test state toggle & query
bool isScissorTestEnabled() const; bool isScissorTestEnabled() const;
void setScissorTest(bool enabled); void setScissorTest(bool enabled);
...@@ -334,6 +340,8 @@ class State : angle::NonCopyable ...@@ -334,6 +340,8 @@ class State : angle::NonCopyable
DIRTY_BIT_RENDERBUFFER_BINDING, DIRTY_BIT_RENDERBUFFER_BINDING,
DIRTY_BIT_VERTEX_ARRAY_BINDING, DIRTY_BIT_VERTEX_ARRAY_BINDING,
DIRTY_BIT_PROGRAM_BINDING, DIRTY_BIT_PROGRAM_BINDING,
DIRTY_BIT_MULTISAMPLING,
DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
DIRTY_BIT_CURRENT_VALUE_0, DIRTY_BIT_CURRENT_VALUE_0,
DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS, DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS,
DIRTY_BIT_INVALID = DIRTY_BIT_CURRENT_VALUE_MAX, DIRTY_BIT_INVALID = DIRTY_BIT_CURRENT_VALUE_MAX,
...@@ -436,6 +444,9 @@ class State : angle::NonCopyable ...@@ -436,6 +444,9 @@ class State : angle::NonCopyable
Debug mDebug; Debug mDebug;
bool mMultiSampling;
bool mSampleAlphaToOne;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
DirtyObjects mDirtyObjects; DirtyObjects mDirtyObjects;
}; };
......
...@@ -113,6 +113,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren ...@@ -113,6 +113,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren
mClearStencil(0), mClearStencil(0),
mFramebufferSRGBEnabled(false), mFramebufferSRGBEnabled(false),
mTextureCubemapSeamlessEnabled(false), mTextureCubemapSeamlessEnabled(false),
mMultisamplingEnabled(true),
mSampleAlphaToOneEnabled(false),
mLocalDirtyBits() mLocalDirtyBits()
{ {
ASSERT(mFunctions); ASSERT(mFunctions);
...@@ -1513,6 +1515,12 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -1513,6 +1515,12 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit
case gl::State::DIRTY_BIT_PROGRAM_BINDING: case gl::State::DIRTY_BIT_PROGRAM_BINDING:
// TODO(jmadill): implement this // TODO(jmadill): implement this
break; break;
case gl::State::DIRTY_BIT_MULTISAMPLING:
setMultisamplingStateEnabled(state.isMultisamplingEnabled());
break;
case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
break;
default: default:
{ {
ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
...@@ -1545,6 +1553,40 @@ void StateManagerGL::setFramebufferSRGBEnabled(bool enabled) ...@@ -1545,6 +1553,40 @@ void StateManagerGL::setFramebufferSRGBEnabled(bool enabled)
} }
} }
void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
{
if (mMultisamplingEnabled != enabled)
{
mMultisamplingEnabled = enabled;
if (mMultisamplingEnabled)
{
mFunctions->enable(GL_MULTISAMPLE_EXT);
}
else
{
mFunctions->disable(GL_MULTISAMPLE_EXT);
}
mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
}
}
void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
{
if (mSampleAlphaToOneEnabled != enabled)
{
mSampleAlphaToOneEnabled = enabled;
if (mSampleAlphaToOneEnabled)
{
mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
}
else
{
mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
}
mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
}
}
void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled) void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
{ {
if (mTextureCubemapSeamlessEnabled != enabled) if (mTextureCubemapSeamlessEnabled != enabled)
......
...@@ -124,6 +124,9 @@ class StateManagerGL final : angle::NonCopyable ...@@ -124,6 +124,9 @@ class StateManagerGL final : angle::NonCopyable
void setFramebufferSRGBEnabled(bool enabled); void setFramebufferSRGBEnabled(bool enabled);
void setMultisamplingStateEnabled(bool enabled);
void setSampleAlphaToOneStateEnabled(bool enabled);
void onDeleteQueryObject(QueryGL *query); void onDeleteQueryObject(QueryGL *query);
gl::Error setDrawArraysState(const gl::ContextState &data, gl::Error setDrawArraysState(const gl::ContextState &data,
...@@ -254,6 +257,9 @@ class StateManagerGL final : angle::NonCopyable ...@@ -254,6 +257,9 @@ class StateManagerGL final : angle::NonCopyable
bool mFramebufferSRGBEnabled; bool mFramebufferSRGBEnabled;
bool mTextureCubemapSeamlessEnabled; bool mTextureCubemapSeamlessEnabled;
bool mMultisamplingEnabled;
bool mSampleAlphaToOneEnabled;
gl::State::DirtyBits mLocalDirtyBits; gl::State::DirtyBits mLocalDirtyBits;
}; };
......
...@@ -657,6 +657,12 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM ...@@ -657,6 +657,12 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS); QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
} }
// the EXT_multisample_compatibility is written against ES3.1 but can apply
// to earlier versions so therefore we're only checking for the extension string
// and not the specific GLES version.
extensions->multisampleCompatibility = functions->isAtLeastGL(gl::Version(1, 3)) ||
functions->hasGLESExtension("GL_EXT_multisample_compatibility");
// ANGLE emulates vertex array objects in its GL layer // ANGLE emulates vertex array objects in its GL layer
extensions->vertexArrayObject = true; extensions->vertexArrayObject = true;
......
...@@ -102,6 +102,11 @@ bool ValidCap(const Context *context, GLenum cap) ...@@ -102,6 +102,11 @@ bool ValidCap(const Context *context, GLenum cap)
{ {
switch (cap) switch (cap)
{ {
// EXT_multisample_compatibility
case GL_MULTISAMPLE_EXT:
case GL_SAMPLE_ALPHA_TO_ONE_EXT:
return context->getExtensions().multisampleCompatibility;
case GL_CULL_FACE: case GL_CULL_FACE:
case GL_POLYGON_OFFSET_FILL: case GL_POLYGON_OFFSET_FILL:
case GL_SAMPLE_ALPHA_TO_COVERAGE: case GL_SAMPLE_ALPHA_TO_COVERAGE:
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
{ {
'angle_end2end_tests_sources': 'angle_end2end_tests_sources':
[ [
'<(angle_path)/src/tests/gl_tests/MultisampleCompatibilityTest.cpp',
'<(angle_path)/src/tests/gl_tests/BindUniformLocationTest.cpp', '<(angle_path)/src/tests/gl_tests/BindUniformLocationTest.cpp',
'<(angle_path)/src/tests/gl_tests/BlendMinMaxTest.cpp', '<(angle_path)/src/tests/gl_tests/BlendMinMaxTest.cpp',
'<(angle_path)/src/tests/gl_tests/BlitFramebufferANGLETest.cpp', '<(angle_path)/src/tests/gl_tests/BlitFramebufferANGLETest.cpp',
......
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