Commit ac43aaa2 by Jamie Madill Committed by Commit Bot

Refactor client check from ValidateDrawAttribs.

This moves out some shared logic into a more accessible place. We don't need to validate buffer overflows when using robust resource access but we do need to validate we are using client side data correctly. Bug: angleproject:1391 Change-Id: I7a3dca8409c5a1faf1ff7bc732d5ed1bd62eb3b1 Reviewed-on: https://chromium-review.googlesource.com/1148817 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 8c1508bc
...@@ -451,7 +451,7 @@ void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingI ...@@ -451,7 +451,7 @@ void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingI
mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict); mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict);
} }
bool VertexArray::hasTransformFeedbackBindingConflict(const AttributesMask &activeAttribues) const bool VertexArray::hasTransformFeedbackBindingConflict(const gl::Context *context) const
{ {
// Fast check first. // Fast check first.
if (!mCachedTransformFeedbackConflictedBindingsMask.any()) if (!mCachedTransformFeedbackConflictedBindingsMask.any())
...@@ -459,6 +459,8 @@ bool VertexArray::hasTransformFeedbackBindingConflict(const AttributesMask &acti ...@@ -459,6 +459,8 @@ bool VertexArray::hasTransformFeedbackBindingConflict(const AttributesMask &acti
return false; return false;
} }
const AttributesMask &activeAttribues = context->getStateCache().getActiveBufferedAttribsMask();
// Slow check. We must ensure that the conflicting attributes are enabled/active. // Slow check. We must ensure that the conflicting attributes are enabled/active.
for (size_t attribIndex : activeAttribues) for (size_t attribIndex : activeAttribues)
{ {
......
...@@ -249,7 +249,7 @@ class VertexArray final : public angle::ObserverInterface, public LabeledObject ...@@ -249,7 +249,7 @@ class VertexArray final : public angle::ObserverInterface, public LabeledObject
AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; } AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }
void onBindingChanged(const Context *context, bool bound); void onBindingChanged(const Context *context, bool bound);
bool hasTransformFeedbackBindingConflict(const AttributesMask &activeAttribues) const; bool hasTransformFeedbackBindingConflict(const gl::Context *context) const;
private: private:
~VertexArray() override; ~VertexArray() override;
......
...@@ -79,17 +79,14 @@ bool DifferenceCanOverflow(GLint a, GLint b) ...@@ -79,17 +79,14 @@ bool DifferenceCanOverflow(GLint a, GLint b)
return !checkedA.IsValid(); return !checkedA.IsValid();
} }
bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLint vertexCount) bool ValidateDrawClientAttribs(Context *context)
{ {
const gl::State &state = context->getGLState(); if (!context->getStateCache().hasAnyEnabledClientAttrib())
const gl::Program *program = state.getProgram(); return true;
const VertexArray *vao = state.getVertexArray();
bool webglCompatibility = context->getExtensions().webglCompatibility; const gl::State &state = context->getGLState();
if (context->getStateCache().hasAnyEnabledClientAttrib()) if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
{
if (webglCompatibility || !state.areClientArraysEnabled())
{ {
// [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
// If a vertex attribute is enabled as an array via enableVertexAttribArray but no // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
...@@ -98,13 +95,26 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi ...@@ -98,13 +95,26 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi
ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBuffer); ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBuffer);
return false; return false;
} }
else if (vao->hasEnabledNullPointerClientArray())
if (state.getVertexArray()->hasEnabledNullPointerClientArray())
{ {
// This is an application error that would normally result in a crash, but we catch it // This is an application error that would normally result in a crash, but we catch it
// and return an error // and return an error
ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBufferPointer); ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBufferPointer);
return false; return false;
} }
return true;
}
bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLint vertexCount)
{
const gl::State &state = context->getGLState();
const gl::Program *program = state.getProgram();
if (!ValidateDrawClientAttribs(context))
{
return false;
} }
// If we're drawing zero vertices, we have enough data. // If we're drawing zero vertices, we have enough data.
...@@ -113,6 +123,7 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi ...@@ -113,6 +123,7 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi
return true; return true;
} }
const VertexArray *vao = state.getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes(); const auto &vertexAttribs = vao->getVertexAttributes();
const auto &vertexBindings = vao->getVertexBindings(); const auto &vertexBindings = vao->getVertexBindings();
...@@ -170,12 +181,6 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi ...@@ -170,12 +181,6 @@ bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLi
} }
} }
if (webglCompatibility && vao->hasTransformFeedbackBindingConflict(activeAttribs))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexBufferBoundForTransformFeedback);
return false;
}
return true; return true;
} }
...@@ -2873,6 +2878,17 @@ bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count) ...@@ -2873,6 +2878,17 @@ bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
{ {
return false; return false;
} }
if (count > 0)
{
const VertexArray *vao = context->getGLState().getVertexArray();
if (vao->hasTransformFeedbackBindingConflict(context))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(),
VertexBufferBoundForTransformFeedback);
return false;
}
}
} }
} }
...@@ -3135,20 +3151,10 @@ bool ValidateDrawElementsCommon(Context *context, ...@@ -3135,20 +3151,10 @@ bool ValidateDrawElementsCommon(Context *context,
} }
} }
if (context->getExtensions().robustBufferAccessBehavior) if (context->getExtensions().robustBufferAccessBehavior || count == 0)
{
// Here we use maxVertex = 0 and vertexCount = 1 to avoid retrieving IndexRange when robust
// access is enabled.
if (!ValidateDrawAttribs(context, primcount, 0, 1))
{
return false;
}
}
else if (count == 0)
{ {
// ValidateDrawAttribs also does some extra validation that is independent of the vertex // Special checks are needed for client attribs. But we don't need to validate overflows.
// count. if (!ValidateDrawClientAttribs(context))
if (!ValidateDrawAttribs(context, 0, 0, 0))
{ {
return false; return false;
} }
......
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