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)
updateValidDrawElementsTypes(context);
updateBasicDrawStatesError();
updateBasicDrawElementsError();
updateVertexAttribTypesValidation(context);
}
void StateCache::updateActiveAttribsMask(Context *context)
......@@ -8388,4 +8389,44 @@ void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
TransformFeedback *xfb = context->getState().getCurrentTransformFeedback();
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
......@@ -87,6 +87,13 @@ class ErrorSet : angle::NonCopyable
std::set<GLenum> mErrors;
};
enum class VertexAttribTypeCase
{
Invalid = 0,
Valid = 1,
ValidSize4Only = 2,
};
// Helper class for managing cache variables and state changes.
class StateCache final : angle::NonCopyable
{
......@@ -198,6 +205,17 @@ class StateCache final : angle::NonCopyable
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.
void onVertexArrayBindingChange(Context *context);
void onProgramExecutableChange(Context *context);
......@@ -226,6 +244,7 @@ class StateCache final : angle::NonCopyable
void updateBasicDrawStatesError();
void updateBasicDrawElementsError();
void updateTransformFeedbackActiveUnpaused(Context *context);
void updateVertexAttribTypesValidation(Context *context);
void setValidDrawModes(bool pointsOK, bool linesOK, bool trisOK, bool lineAdjOK, bool triAdjOK);
......@@ -251,6 +270,14 @@ class StateCache final : angle::NonCopyable
mCachedValidBindTextureTypes;
angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1>
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
......
......@@ -317,7 +317,6 @@ MSG kInvalidTransformation = "Invalid transformation.";
MSG kInvalidTransformFeedbackAttribsCount = "Count exceeds MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.";
MSG kInvalidTransformFeedbackName = "name is not a valid transform feedback.";
MSG kInvalidType = "Invalid type.";
MSG kInvalidTypePureInt = "Invalid type = should be integer";
MSG kInvalidUniformCount = "Only array uniforms may have count > 1.";
MSG kInvalidUniformLocation = "Invalid uniform location";
MSG kInvalidUnpackAlignment = "Unpack alignment must be 1 = 2 = 4 = or 8.";
......
......@@ -4800,92 +4800,6 @@ bool ValidateGetInternalformativRobustANGLE(Context *context,
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":
// 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
......
......@@ -488,11 +488,61 @@ bool ValidateGetVertexAttribBase(Context *context,
bool pointer,
bool pureIntegerEntryPoint);
bool ValidateVertexFormatBase(Context *context,
GLuint attribIndex,
GLint size,
VertexAttribType type,
GLboolean pureInteger);
ANGLE_INLINE bool ValidateVertexFormat(Context *context,
GLuint index,
GLint size,
VertexAttribTypeCase validation)
{
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,
GLint drawbuffer,
......
......@@ -4683,7 +4683,7 @@ bool ValidateVertexAttribPointer(Context *context,
GLsizei stride,
const void *ptr)
{
if (!ValidateVertexFormatBase(context, index, size, type, false))
if (!ValidateFloatVertexFormat(context, index, size, type))
{
return false;
}
......
......@@ -2976,7 +2976,7 @@ bool ValidateVertexAttribIPointer(Context *context,
return false;
}
if (!ValidateVertexFormatBase(context, index, size, type, true))
if (!ValidateIntegerVertexFormat(context, index, size, type))
{
return false;
}
......
......@@ -335,12 +335,7 @@ bool ValidateProgramUniformMatrix(Context *context,
ValidateUniformMatrixValue(context, valueType, uniform->type);
}
bool ValidateVertexAttribFormatCommon(Context *context,
GLuint attribIndex,
GLint size,
VertexAttribType type,
GLuint relativeOffset,
GLboolean pureInteger)
bool ValidateVertexAttribFormatCommon(Context *context, GLuint relativeOffset)
{
if (context->getClientVersion() < ES_3_1)
{
......@@ -363,7 +358,7 @@ bool ValidateVertexAttribFormatCommon(Context *context,
return false;
}
return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
return true;
}
} // anonymous namespace
......@@ -1220,8 +1215,12 @@ bool ValidateVertexAttribFormat(Context *context,
GLboolean normalized,
GLuint relativeoffset)
{
return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
false);
if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
{
return false;
}
return ValidateFloatVertexFormat(context, attribindex, size, type);
}
bool ValidateVertexAttribIFormat(Context *context,
......@@ -1230,7 +1229,12 @@ bool ValidateVertexAttribIFormat(Context *context,
VertexAttribType type,
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)
......
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