Commit e4477001 by Corentin Wallez Committed by Commit Bot

Add PackedEnumBitSet, use it for buffer binding validation

Includes angle::BitSetT changes from jmadill@chromium.org BUG=angleproject:2169 Change-Id: I9f896613f5c6cdc91281cb9a00134f67291870d9 Reviewed-on: https://chromium-review.googlesource.com/804177Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 4fba4a97
......@@ -2780,6 +2780,33 @@ void Context::updateCaps()
{
mMemoryProgramCache = nullptr;
}
// Compute which buffer types are allowed
mValidBufferBindings.reset();
mValidBufferBindings.set(BufferBinding::ElementArray);
mValidBufferBindings.set(BufferBinding::Array);
if (mExtensions.pixelBufferObject || getClientVersion() >= ES_3_0)
{
mValidBufferBindings.set(BufferBinding::PixelPack);
mValidBufferBindings.set(BufferBinding::PixelUnpack);
}
if (getClientVersion() >= ES_3_0)
{
mValidBufferBindings.set(BufferBinding::CopyRead);
mValidBufferBindings.set(BufferBinding::CopyWrite);
mValidBufferBindings.set(BufferBinding::TransformFeedback);
mValidBufferBindings.set(BufferBinding::Uniform);
}
if (getClientVersion() >= ES_3_1)
{
mValidBufferBindings.set(BufferBinding::AtomicCounter);
mValidBufferBindings.set(BufferBinding::ShaderStorage);
mValidBufferBindings.set(BufferBinding::DrawIndirect);
mValidBufferBindings.set(BufferBinding::DispatchIndirect);
}
}
void Context::initWorkarounds()
......
......@@ -140,11 +140,16 @@ class ValidationContext : angle::NonCopyable
template <typename T>
const T &getParams() const;
bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; }
protected:
ContextState mState;
bool mSkipValidation;
bool mDisplayTextureShareGroup;
// Stores for each buffer binding type whether is it allowed to be used in this context.
angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings;
// Caches entry point parameters and values re-used between layers.
mutable const ParamTypeInfo *mSavedArgsType;
static constexpr size_t kParamsBufferSize = 64u;
......
......@@ -12,11 +12,28 @@
#include "libANGLE/PackedGLEnums_autogen.h"
#include <array>
#include <bitset>
#include <cstddef>
#include "common/bitset_utils.h"
namespace angle
{
// Return the number of elements of a packed enum, including the InvalidEnum element.
template <typename E>
constexpr size_t EnumSize()
{
using UnderlyingType = typename std::underlying_type<E>::type;
return static_cast<UnderlyingType>(E::EnumCount);
}
// Implementation of AllEnums which allows iterating over all the possible values for a packed enums
// like so:
// for (auto value : AllEnums<MyPackedEnum>()) {
// // Do something with the enum.
// }
template <typename E>
class EnumIterator final
{
......@@ -45,13 +62,14 @@ struct AllEnums
EnumIterator<E> end() const { return {E::InvalidEnum}; }
};
// PackedEnumMap<E, T> is like an std::array<T, E::EnumCount> but is indexed with enum values. It
// implements all of the std::array interface except with enum values instead of indices.
template <typename E, typename T>
class PackedEnumMap
{
private:
using UnderlyingType = typename std::underlying_type<E>::type;
static constexpr size_t kSize = static_cast<UnderlyingType>(E::EnumCount);
using Storage = std::array<T, kSize>;
using Storage = std::array<T, EnumSize<E>()>;
Storage mData;
......@@ -106,6 +124,11 @@ class PackedEnumMap
const T *data() const noexcept { return mData.data(); }
};
// PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It
// implements the std::bitset interface except with enum values instead of indices.
template <typename E>
using PackedEnumBitSet = BitSetT<EnumSize<E>(), uint32_t, E>;
} // namespace angle
#endif // LIBANGLE_PACKEDGLENUMS_H_
......@@ -649,36 +649,6 @@ bool ValidFramebufferTarget(const ValidationContext *context, GLenum target)
}
}
bool ValidBufferType(const ValidationContext *context, BufferBinding target)
{
switch (target)
{
case BufferBinding::ElementArray:
case BufferBinding::Array:
return true;
case BufferBinding::PixelPack:
case BufferBinding::PixelUnpack:
return (context->getExtensions().pixelBufferObject ||
context->getClientMajorVersion() >= 3);
case BufferBinding::CopyRead:
case BufferBinding::CopyWrite:
case BufferBinding::TransformFeedback:
case BufferBinding::Uniform:
return (context->getClientMajorVersion() >= 3);
case BufferBinding::AtomicCounter:
case BufferBinding::ShaderStorage:
case BufferBinding::DrawIndirect:
case BufferBinding::DispatchIndirect:
return context->getClientVersion() >= Version(3, 1);
default:
return false;
}
}
bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
{
const auto &caps = context->getCaps();
......@@ -3497,7 +3467,7 @@ bool ValidateGetBufferPointervBase(Context *context,
return false;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
context->handleError(InvalidEnum() << "Buffer target not valid");
return false;
......@@ -3533,7 +3503,7 @@ bool ValidateGetBufferPointervBase(Context *context,
bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
{
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -3556,7 +3526,7 @@ bool ValidateMapBufferRangeBase(Context *context,
GLsizeiptr length,
GLbitfield access)
{
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -3663,7 +3633,7 @@ bool ValidateFlushMappedBufferRangeBase(Context *context,
return false;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -4704,7 +4674,7 @@ bool ValidateGetBufferParameterBase(ValidationContext *context,
*numParams = 0;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......
......@@ -39,7 +39,6 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta
bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target);
bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target);
bool ValidFramebufferTarget(const ValidationContext *context, GLenum target);
bool ValidBufferType(const ValidationContext *context, BufferBinding target);
bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams);
bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level);
bool ValidImageSizeParameters(ValidationContext *context,
......
......@@ -2838,7 +2838,7 @@ bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
return false;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -4206,7 +4206,7 @@ bool ValidateBufferData(ValidationContext *context,
return false;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -4241,7 +4241,7 @@ bool ValidateBufferSubData(ValidationContext *context,
return false;
}
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......@@ -4408,7 +4408,7 @@ bool ValidateBindAttribLocation(ValidationContext *context,
bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
{
if (!ValidBufferType(context, target))
if (!context->isValidBufferBinding(target))
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
return false;
......
......@@ -2466,7 +2466,7 @@ bool ValidateCopyBufferSubData(ValidationContext *context,
return false;
}
if (!ValidBufferType(context, readTarget) || !ValidBufferType(context, writeTarget))
if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
{
context->handleError(InvalidEnum() << "Invalid buffer target");
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