Commit db342276 by Jiawei Shao Committed by Commit Bot

ES31: Implement glSampleMaski on OpenGL

This patch intends to implement glSampleMaski on OpenGL backends. Refers to: https://chromium-review.googlesource.com/c/487603 BUG=angleproject:1592 TEST=dEQP-GLES31.functional.state_query.*.sample_mask* TEST=dEQP-GLES31.functional.texture.multisample.*.sample_mask* Change-Id: If5ddd6ab57259593919a482be80fbdbe29f6f54d Reviewed-on: https://chromium-review.googlesource.com/573727 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 49bb7e13
......@@ -19,6 +19,9 @@ const size_t kDefaultMaxProgramCacheMemoryBytes = 0;
enum
{
// Implementation upper limits, real maximums depend on the hardware
MAX_SAMPLE_MASK_WORDS = 2,
MAX_VERTEX_ATTRIBS = 16,
MAX_VERTEX_ATTRIB_BINDINGS = 16,
......
......@@ -2698,6 +2698,8 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
LimitCap(&mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
// WebGL compatibility
mExtensions.webglCompatibility = mWebGLContext;
for (const auto &extensionInfo : GetExtensionInfoMap())
......@@ -3721,6 +3723,11 @@ void Context::sampleCoverage(GLfloat value, GLboolean invert)
mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
}
void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
{
mGLState.setSampleMaskParams(maskNumber, mask);
}
void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
mGLState.setScissorParams(x, y, width, height);
......
......@@ -290,6 +290,7 @@ class Context final : public ValidationContext
void pixelStorei(GLenum pname, GLint param);
void polygonOffset(GLfloat factor, GLfloat units);
void sampleCoverage(GLfloat value, GLboolean invert);
void sampleMaski(GLuint maskNumber, GLbitfield mask);
void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
void stencilMaskSeparate(GLenum face, GLuint mask);
......
......@@ -683,6 +683,10 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign
*type = GL_INT_64_ANGLEX;
*numParams = 1;
return true;
case GL_SAMPLE_MASK:
*type = GL_BOOL;
*numParams = 1;
return true;
}
return false;
......@@ -732,6 +736,7 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target,
case GL_VERTEX_BINDING_DIVISOR:
case GL_VERTEX_BINDING_OFFSET:
case GL_VERTEX_BINDING_STRIDE:
case GL_SAMPLE_MASK_VALUE:
{
*type = GL_INT;
*numParams = 1;
......
......@@ -87,6 +87,8 @@ ERRMSG(InvalidRenderbufferTarget, "Invalid renderbuffer target.");
ERRMSG(InvalidRenderbufferTextureParameter, "Invalid parameter name for renderbuffer attachment.");
ERRMSG(InvalidRenderbufferWidthHeight,
"Renderbuffer width and height cannot be negative and cannot exceed maximum texture size.");
ERRMSG(InvalidSampleMaskNumber,
"MaskNumber cannot be greater than or equal to the value of MAX_SAMPLE_MASK_WORDS.");
ERRMSG(InvalidSampler, "Sampler is not valid");
ERRMSG(InvalidShaderName, "Shader object expected.");
ERRMSG(InvalidShaderType, "Invalid shader type.");
......
......@@ -45,6 +45,8 @@ State::State()
mSampleCoverage(false),
mSampleCoverageValue(0),
mSampleCoverageInvert(false),
mSampleMask(false),
mMaxSampleMaskWords(0),
mStencilRef(0),
mStencilBackRef(0),
mLineWidth(0),
......@@ -108,6 +110,11 @@ void State::initialize(const Context *context,
mSampleCoverage = false;
mSampleCoverageValue = 1.0f;
mSampleCoverageInvert = false;
mMaxSampleMaskWords = caps.maxSampleMaskWords;
mSampleMask = false;
mSampleMaskValues.fill(~GLbitfield(0));
mGenerateMipmapHint = GL_DONT_CARE;
mFragmentShaderDerivativeHint = GL_DONT_CARE;
......@@ -563,6 +570,35 @@ bool State::getSampleCoverageInvert() const
return mSampleCoverageInvert;
}
bool State::isSampleMaskEnabled() const
{
return mSampleMask;
}
void State::setSampleMaskEnabled(bool enabled)
{
mSampleMask = enabled;
mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
}
void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
{
ASSERT(maskNumber < mMaxSampleMaskWords);
mSampleMaskValues[maskNumber] = mask;
mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_WORD_0 + maskNumber);
}
GLbitfield State::getSampleMaskWord(GLuint maskNumber) const
{
ASSERT(maskNumber < mMaxSampleMaskWords);
return mSampleMaskValues[maskNumber];
}
GLuint State::getMaxSampleMaskWords() const
{
return mMaxSampleMaskWords;
}
void State::setSampleAlphaToOne(bool enabled)
{
mSampleAlphaToOne = enabled;
......@@ -650,11 +686,7 @@ void State::setEnableFeature(GLenum feature, bool enabled)
case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
case GL_SAMPLE_MASK:
if (enabled)
{
// Enabling this feature is not implemented yet.
UNIMPLEMENTED();
}
setSampleMaskEnabled(enabled);
break;
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
mDebug.setOutputSynchronous(enabled);
......@@ -687,8 +719,7 @@ bool State::getEnableFeature(GLenum feature) const
case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
case GL_SAMPLE_MASK:
UNIMPLEMENTED();
return false;
return isSampleMaskEnabled();
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
return mDebug.isOutputSynchronous();
case GL_DEBUG_OUTPUT:
......@@ -1669,6 +1700,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params)
case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
case GL_SAMPLE_MASK:
*params = mSampleMask;
break;
case GL_SCISSOR_TEST: *params = mScissorTest; break;
case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
......@@ -2085,6 +2119,10 @@ void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
*data = mVertexArray->getVertexBinding(index).getStride();
break;
case GL_SAMPLE_MASK_VALUE:
ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
*data = mSampleMaskValues[index];
break;
default:
UNREACHABLE();
break;
......
......@@ -124,10 +124,17 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
void setSampleAlphaToCoverage(bool enabled);
bool isSampleCoverageEnabled() const;
void setSampleCoverage(bool enabled);
void setSampleCoverageParams(GLfloat value, bool invert);
void setSampleCoverageParams(GLclampf value, bool invert);
GLfloat getSampleCoverageValue() const;
bool getSampleCoverageInvert() const;
// Multisample mask state manipulation.
bool isSampleMaskEnabled() const;
void setSampleMaskEnabled(bool enabled);
void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
GLbitfield getSampleMaskWord(GLuint maskNumber) const;
GLuint getMaxSampleMaskWords() const;
// Multisampling/alpha to one manipulation.
void setSampleAlphaToOne(bool enabled);
bool isSampleAlphaToOneEnabled() const;
......@@ -384,7 +391,10 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
DIRTY_BIT_SAMPLE_COVERAGE,
DIRTY_BIT_DEPTH_TEST_ENABLED,
DIRTY_BIT_SAMPLE_MASK_ENABLED,
DIRTY_BIT_SAMPLE_MASK_WORD_0,
DIRTY_BIT_SAMPLE_MASK_WORD_MAX = DIRTY_BIT_SAMPLE_MASK_WORD_0 + MAX_SAMPLE_MASK_WORDS,
DIRTY_BIT_DEPTH_TEST_ENABLED = DIRTY_BIT_SAMPLE_MASK_WORD_MAX,
DIRTY_BIT_DEPTH_FUNC,
DIRTY_BIT_DEPTH_MASK,
DIRTY_BIT_STENCIL_TEST_ENABLED,
......@@ -506,6 +516,9 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
bool mSampleCoverage;
GLfloat mSampleCoverageValue;
bool mSampleCoverageInvert;
bool mSampleMask;
GLuint mMaxSampleMaskWords;
std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
DepthStencilState mDepthStencil;
GLint mStencilRef;
......
......@@ -123,6 +123,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mSampleCoverageEnabled(false),
mSampleCoverageValue(1.0f),
mSampleCoverageInvert(false),
mSampleMaskEnabled(false),
mDepthTestEnabled(false),
mDepthFunc(GL_LESS),
mDepthMask(true),
......@@ -182,6 +183,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mIndexedBuffers[GL_ATOMIC_COUNTER_BUFFER].resize(rendererCaps.maxCombinedAtomicCounterBuffers);
mIndexedBuffers[GL_SHADER_STORAGE_BUFFER].resize(rendererCaps.maxCombinedShaderStorageBlocks);
mSampleMaskValues.fill(~GLbitfield(0));
for (GLenum queryType : QueryTypes)
{
mQueries[queryType] = 0;
......@@ -1333,6 +1336,36 @@ void StateManagerGL::setSampleCoverage(float value, bool invert)
}
}
void StateManagerGL::setSampleMaskEnabled(bool enabled)
{
if (mSampleMaskEnabled != enabled)
{
mSampleMaskEnabled = enabled;
if (mSampleMaskEnabled)
{
mFunctions->enable(GL_SAMPLE_MASK);
}
else
{
mFunctions->disable(GL_SAMPLE_MASK);
}
mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED);
}
}
void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
{
ASSERT(maskNumber < mSampleMaskValues.size());
if (mSampleMaskValues[maskNumber] != mask)
{
mSampleMaskValues[maskNumber] = mask;
mFunctions->sampleMaski(maskNumber, mask);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0 + maskNumber);
}
}
void StateManagerGL::setDepthTestEnabled(bool enabled)
{
if (mDepthTestEnabled != enabled)
......@@ -1985,16 +2018,37 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
context, state.getFramebufferSRGB(),
GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
break;
case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
setSampleMaskEnabled(state.isSampleMaskEnabled());
break;
default:
{
ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX);
if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX)
{
size_t attribIndex =
static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0;
setAttributeCurrentData(attribIndex,
state.getVertexAttribCurrentValue(attribIndex));
break;
}
else if (dirtyBit >= gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0 &&
dirtyBit < gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_MAX)
{
GLuint maskNumber =
static_cast<GLuint>(dirtyBit) - gl::State::DIRTY_BIT_SAMPLE_MASK_WORD_0;
// Only set the available sample mask values.
if (maskNumber < state.getMaxSampleMaskWords())
{
setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
}
break;
}
else
{
UNREACHABLE();
}
}
}
mLocalDirtyBits.reset();
......
......@@ -99,6 +99,8 @@ class StateManagerGL final : angle::NonCopyable
void setSampleAlphaToCoverageEnabled(bool enabled);
void setSampleCoverageEnabled(bool enabled);
void setSampleCoverage(float value, bool invert);
void setSampleMaskEnabled(bool enabled);
void setSampleMaski(GLuint maskNumber, GLbitfield mask);
void setDepthTestEnabled(bool enabled);
void setDepthFunc(GLenum depthFunc);
......@@ -295,6 +297,8 @@ class StateManagerGL final : angle::NonCopyable
bool mSampleCoverageEnabled;
float mSampleCoverageValue;
bool mSampleCoverageInvert;
bool mSampleMaskEnabled;
std::array<GLbitfield, gl::MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
bool mDepthTestEnabled;
GLenum mDepthFunc;
......
......@@ -2319,6 +2319,18 @@ bool ValidateIndexedStateQuery(ValidationContext *context,
return false;
}
break;
case GL_SAMPLE_MASK_VALUE:
if (context->getClientVersion() < ES_3_1)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
return false;
}
if (index >= caps.maxSampleMaskWords)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
return false;
}
break;
default:
context->handleError(InvalidEnum());
return false;
......
......@@ -1312,4 +1312,21 @@ bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
return true;
}
bool ValidateSampleMaski(Context *context, GLuint maskNumber)
{
if (context->getClientVersion() < ES_3_1)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
return false;
}
if (maskNumber >= context->getCaps().maxSampleMaskWords)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
return false;
}
return true;
}
} // namespace gl
......@@ -120,6 +120,9 @@ bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *pipelines);
bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *pipelines);
bool ValidateBindProgramPipeline(Context *context, GLuint pipeline);
bool ValidateIsProgramPipeline(Context *context, GLuint pipeline);
bool ValidateSampleMaski(Context *context, GLuint maskNumber);
} // namespace gl
#endif // LIBANGLE_VALIDATION_ES31_H_
......@@ -1073,11 +1073,11 @@ void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask)
Context *context = GetValidGlobalContext();
if (context)
{
if (mask != ~GLbitfield(0))
if (!context->skipValidation() && !ValidateSampleMaski(context, maskNumber))
{
// Setting a non-default sample mask is not implemented yet.
UNIMPLEMENTED();
return;
}
context->sampleMaski(maskNumber, mask);
}
}
......
......@@ -38,6 +38,7 @@
1442 D3D11 : dEQP-GLES31.functional.texture.gather.* = SKIP
// D3D11 Failing Tests
1442 D3D11 : dEQP-GLES31.functional.state_query.boolean.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_color_texture_samples_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_depth_texture_samples_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_integer_samples_* = FAIL
......@@ -63,9 +64,19 @@
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_uniform_buffer_bindings_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_combined_texture_image_units_* = FAIL
1729 D3D11 : dEQP-GLES31.functional.state_query.indexed.atomic_counter_buffer_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.sample_mask_value_* = FAIL
1951 D3D11 : dEQP-GLES31.functional.state_query.indexed.shader_storage_buffer_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples_64.sample_mask_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
......@@ -1225,10 +1236,8 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_draw = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.compare_mode_effect = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.base_level = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.boolean.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.dispatch_indirect_buffer_binding_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.program_pipeline_binding_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.indexed.sample_mask_value_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.indexed.image_binding* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d.depth_stencil_mode_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_cube_map.depth_stencil_mode_* = FAIL
......@@ -1314,12 +1323,3 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_64.sample_mask_* = FAIL
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