Commit c8c7d400 by Jamie Madill Committed by Commit Bot

Use a table for vertex attrib type validation.

No clearly sampled effect on performance but should require fewer instructions. May lead to future improvements. Bug: angleproject:3014 Change-Id: I64e155926ae2c553b059265780e72e91f91f097c Reviewed-on: https://chromium-review.googlesource.com/c/1393906 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 15214423
...@@ -8097,6 +8097,7 @@ void StateCache::initialize(Context *context) ...@@ -8097,6 +8097,7 @@ void StateCache::initialize(Context *context)
updateValidDrawElementsTypes(context); updateValidDrawElementsTypes(context);
updateBasicDrawStatesError(); updateBasicDrawStatesError();
updateBasicDrawElementsError(); updateBasicDrawElementsError();
updateVertexAttribTypesValidation(context);
} }
void StateCache::updateActiveAttribsMask(Context *context) void StateCache::updateActiveAttribsMask(Context *context)
...@@ -8388,4 +8389,44 @@ void StateCache::updateTransformFeedbackActiveUnpaused(Context *context) ...@@ -8388,4 +8389,44 @@ void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
TransformFeedback *xfb = context->getState().getCurrentTransformFeedback(); TransformFeedback *xfb = context->getState().getCurrentTransformFeedback();
mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused(); mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
} }
void StateCache::updateVertexAttribTypesValidation(Context *context)
{
if (context->getClientMajorVersion() <= 2)
{
mCachedVertexAttribTypesValidation = {{
{VertexAttribType::Byte, VertexAttribTypeCase::Valid},
{VertexAttribType::Short, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
{VertexAttribType::Float, VertexAttribTypeCase::Valid},
{VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
}};
}
else
{
mCachedVertexAttribTypesValidation = {{
{VertexAttribType::Byte, VertexAttribTypeCase::Valid},
{VertexAttribType::Short, VertexAttribTypeCase::Valid},
{VertexAttribType::Int, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
{VertexAttribType::Float, VertexAttribTypeCase::Valid},
{VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid},
{VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
{VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only},
{VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only},
}};
mCachedIntegerVertexAttribTypesValidation = {{
{VertexAttribType::Byte, VertexAttribTypeCase::Valid},
{VertexAttribType::Short, VertexAttribTypeCase::Valid},
{VertexAttribType::Int, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
{VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
}};
}
}
} // namespace gl } // namespace gl
...@@ -87,6 +87,13 @@ class ErrorSet : angle::NonCopyable ...@@ -87,6 +87,13 @@ class ErrorSet : angle::NonCopyable
std::set<GLenum> mErrors; std::set<GLenum> mErrors;
}; };
enum class VertexAttribTypeCase
{
Invalid = 0,
Valid = 1,
ValidSize4Only = 2,
};
// Helper class for managing cache variables and state changes. // Helper class for managing cache variables and state changes.
class StateCache final : angle::NonCopyable class StateCache final : angle::NonCopyable
{ {
...@@ -198,6 +205,17 @@ class StateCache final : angle::NonCopyable ...@@ -198,6 +205,17 @@ class StateCache final : angle::NonCopyable
return mCachedTransformFeedbackActiveUnpaused; return mCachedTransformFeedbackActiveUnpaused;
} }
// Cannot change except on Context/Extension init.
VertexAttribTypeCase getVertexAttribTypeValidation(VertexAttribType type) const
{
return mCachedVertexAttribTypesValidation[type];
}
VertexAttribTypeCase getIntegerVertexAttribTypeValidation(VertexAttribType type) const
{
return mCachedIntegerVertexAttribTypesValidation[type];
}
// State change notifications. // State change notifications.
void onVertexArrayBindingChange(Context *context); void onVertexArrayBindingChange(Context *context);
void onProgramExecutableChange(Context *context); void onProgramExecutableChange(Context *context);
...@@ -226,6 +244,7 @@ class StateCache final : angle::NonCopyable ...@@ -226,6 +244,7 @@ class StateCache final : angle::NonCopyable
void updateBasicDrawStatesError(); void updateBasicDrawStatesError();
void updateBasicDrawElementsError(); void updateBasicDrawElementsError();
void updateTransformFeedbackActiveUnpaused(Context *context); void updateTransformFeedbackActiveUnpaused(Context *context);
void updateVertexAttribTypesValidation(Context *context);
void setValidDrawModes(bool pointsOK, bool linesOK, bool trisOK, bool lineAdjOK, bool triAdjOK); void setValidDrawModes(bool pointsOK, bool linesOK, bool trisOK, bool lineAdjOK, bool triAdjOK);
...@@ -251,6 +270,14 @@ class StateCache final : angle::NonCopyable ...@@ -251,6 +270,14 @@ class StateCache final : angle::NonCopyable
mCachedValidBindTextureTypes; mCachedValidBindTextureTypes;
angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1> angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1>
mCachedValidDrawElementsTypes; mCachedValidDrawElementsTypes;
angle::PackedEnumMap<VertexAttribType,
VertexAttribTypeCase,
angle::EnumSize<VertexAttribType>() + 1>
mCachedVertexAttribTypesValidation;
angle::PackedEnumMap<VertexAttribType,
VertexAttribTypeCase,
angle::EnumSize<VertexAttribType>() + 1>
mCachedIntegerVertexAttribTypesValidation;
}; };
class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
......
...@@ -317,7 +317,6 @@ MSG kInvalidTransformation = "Invalid transformation."; ...@@ -317,7 +317,6 @@ MSG kInvalidTransformation = "Invalid transformation.";
MSG kInvalidTransformFeedbackAttribsCount = "Count exceeds MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."; MSG kInvalidTransformFeedbackAttribsCount = "Count exceeds MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.";
MSG kInvalidTransformFeedbackName = "name is not a valid transform feedback."; MSG kInvalidTransformFeedbackName = "name is not a valid transform feedback.";
MSG kInvalidType = "Invalid type."; MSG kInvalidType = "Invalid type.";
MSG kInvalidTypePureInt = "Invalid type = should be integer";
MSG kInvalidUniformCount = "Only array uniforms may have count > 1."; MSG kInvalidUniformCount = "Only array uniforms may have count > 1.";
MSG kInvalidUniformLocation = "Invalid uniform location"; MSG kInvalidUniformLocation = "Invalid uniform location";
MSG kInvalidUnpackAlignment = "Unpack alignment must be 1 = 2 = 4 = or 8."; MSG kInvalidUnpackAlignment = "Unpack alignment must be 1 = 2 = 4 = or 8.";
......
...@@ -4800,92 +4800,6 @@ bool ValidateGetInternalformativRobustANGLE(Context *context, ...@@ -4800,92 +4800,6 @@ bool ValidateGetInternalformativRobustANGLE(Context *context,
return true; return true;
} }
bool ValidateVertexFormatBase(Context *context,
GLuint attribIndex,
GLint size,
VertexAttribType type,
GLboolean pureInteger)
{
const Caps &caps = context->getCaps();
if (attribIndex >= caps.maxVertexAttributes)
{
context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
return false;
}
if (size < 1 || size > 4)
{
context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
return false;
}
// This validation could be improved using a table and better encapsulation.
switch (type)
{
case VertexAttribType::Byte:
case VertexAttribType::UnsignedByte:
case VertexAttribType::Short:
case VertexAttribType::UnsignedShort:
break;
case VertexAttribType::Int:
case VertexAttribType::UnsignedInt:
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
return false;
}
break;
case VertexAttribType::Fixed:
case VertexAttribType::Float:
if (pureInteger)
{
context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
return false;
}
break;
case VertexAttribType::HalfFloat:
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
return false;
}
if (pureInteger)
{
context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
return false;
}
break;
case VertexAttribType::Int2101010:
case VertexAttribType::UnsignedInt2101010:
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
return false;
}
if (pureInteger)
{
context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
return false;
}
if (size != 4)
{
context->validationError(GL_INVALID_OPERATION, kInvalidVertexAttribSize2101010);
return false;
}
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
return true;
}
// Perform validation from WebGL 2 section 5.10 "Invalid Clears": // Perform validation from WebGL 2 section 5.10 "Invalid Clears":
// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the // In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
// specified clear value and the type of a buffer that is being cleared generates an // specified clear value and the type of a buffer that is being cleared generates an
......
...@@ -488,11 +488,61 @@ bool ValidateGetVertexAttribBase(Context *context, ...@@ -488,11 +488,61 @@ bool ValidateGetVertexAttribBase(Context *context,
bool pointer, bool pointer,
bool pureIntegerEntryPoint); bool pureIntegerEntryPoint);
bool ValidateVertexFormatBase(Context *context, ANGLE_INLINE bool ValidateVertexFormat(Context *context,
GLuint attribIndex, GLuint index,
GLint size, GLint size,
VertexAttribType type, VertexAttribTypeCase validation)
GLboolean pureInteger); {
const Caps &caps = context->getCaps();
if (index >= caps.maxVertexAttributes)
{
context->validationError(GL_INVALID_VALUE, err::kIndexExceedsMaxVertexAttribute);
return false;
}
switch (validation)
{
case VertexAttribTypeCase::Invalid:
context->validationError(GL_INVALID_ENUM, err::kInvalidType);
return false;
case VertexAttribTypeCase::Valid:
if (size < 1 || size > 4)
{
context->validationError(GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
return false;
}
break;
case VertexAttribTypeCase::ValidSize4Only:
if (size != 4)
{
context->validationError(GL_INVALID_OPERATION,
err::kInvalidVertexAttribSize2101010);
return false;
}
break;
}
return true;
}
// Note: These byte, short, and int types are all converted to float for the shader.
ANGLE_INLINE bool ValidateFloatVertexFormat(Context *context,
GLuint index,
GLint size,
VertexAttribType type)
{
return ValidateVertexFormat(context, index, size,
context->getStateCache().getVertexAttribTypeValidation(type));
}
ANGLE_INLINE bool ValidateIntegerVertexFormat(Context *context,
GLuint index,
GLint size,
VertexAttribType type)
{
return ValidateVertexFormat(
context, index, size, context->getStateCache().getIntegerVertexAttribTypeValidation(type));
}
bool ValidateWebGLFramebufferAttachmentClearType(Context *context, bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
GLint drawbuffer, GLint drawbuffer,
......
...@@ -4683,7 +4683,7 @@ bool ValidateVertexAttribPointer(Context *context, ...@@ -4683,7 +4683,7 @@ bool ValidateVertexAttribPointer(Context *context,
GLsizei stride, GLsizei stride,
const void *ptr) const void *ptr)
{ {
if (!ValidateVertexFormatBase(context, index, size, type, false)) if (!ValidateFloatVertexFormat(context, index, size, type))
{ {
return false; return false;
} }
......
...@@ -2976,7 +2976,7 @@ bool ValidateVertexAttribIPointer(Context *context, ...@@ -2976,7 +2976,7 @@ bool ValidateVertexAttribIPointer(Context *context,
return false; return false;
} }
if (!ValidateVertexFormatBase(context, index, size, type, true)) if (!ValidateIntegerVertexFormat(context, index, size, type))
{ {
return false; return false;
} }
......
...@@ -335,12 +335,7 @@ bool ValidateProgramUniformMatrix(Context *context, ...@@ -335,12 +335,7 @@ bool ValidateProgramUniformMatrix(Context *context,
ValidateUniformMatrixValue(context, valueType, uniform->type); ValidateUniformMatrixValue(context, valueType, uniform->type);
} }
bool ValidateVertexAttribFormatCommon(Context *context, bool ValidateVertexAttribFormatCommon(Context *context, GLuint relativeOffset)
GLuint attribIndex,
GLint size,
VertexAttribType type,
GLuint relativeOffset,
GLboolean pureInteger)
{ {
if (context->getClientVersion() < ES_3_1) if (context->getClientVersion() < ES_3_1)
{ {
...@@ -363,7 +358,7 @@ bool ValidateVertexAttribFormatCommon(Context *context, ...@@ -363,7 +358,7 @@ bool ValidateVertexAttribFormatCommon(Context *context,
return false; return false;
} }
return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger); return true;
} }
} // anonymous namespace } // anonymous namespace
...@@ -1220,8 +1215,12 @@ bool ValidateVertexAttribFormat(Context *context, ...@@ -1220,8 +1215,12 @@ bool ValidateVertexAttribFormat(Context *context,
GLboolean normalized, GLboolean normalized,
GLuint relativeoffset) GLuint relativeoffset)
{ {
return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
false); {
return false;
}
return ValidateFloatVertexFormat(context, attribindex, size, type);
} }
bool ValidateVertexAttribIFormat(Context *context, bool ValidateVertexAttribIFormat(Context *context,
...@@ -1230,7 +1229,12 @@ bool ValidateVertexAttribIFormat(Context *context, ...@@ -1230,7 +1229,12 @@ bool ValidateVertexAttribIFormat(Context *context,
VertexAttribType type, VertexAttribType type,
GLuint relativeoffset) GLuint relativeoffset)
{ {
return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true); if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
{
return false;
}
return ValidateIntegerVertexFormat(context, attribindex, size, type);
} }
bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex) bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
......
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