Commit 752d220a by Jamie Madill Committed by Commit Bot

Use flat enum for PrimitiveMode.

The GLenum was already mostly packed. There were just a few missing values because of the exclusion of things like GL_QUADS and GL_POLYGON from GLES. Also update the PackedEnumMap initialization to take an intializer. The initializer is a list of key/values which is much more robust to changes in the packed map. Improves draw call speed slightly as there is no conversion needed any more for the mode enum. Bug: angleproject:2966 Change-Id: Icae658272c6234f29335f6a57a63cf341cf5b2a0 Reviewed-on: https://chromium-review.googlesource.com/c/1346529 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 11bfe6fa
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
"packed enum:src/common/packed_egl_enums.json": "packed enum:src/common/packed_egl_enums.json":
"5f591d220ee53b6e54a27d1523a3ab79", "5f591d220ee53b6e54a27d1523a3ab79",
"packed enum:src/common/packed_gl_enums.json": "packed enum:src/common/packed_gl_enums.json":
"7338a2a11c679aeb8efe2b415dbd4810", "b54346c106ab4a7b0acb69eb65123c1a",
"proc table:src/libGLESv2/gen_proc_table.py": "proc table:src/libGLESv2/gen_proc_table.py":
"027bfd5a8a8dffe91f492bf199029cde", "027bfd5a8a8dffe91f492bf199029cde",
"proc table:src/libGLESv2/proc_table_data.json": "proc table:src/libGLESv2/proc_table_data.json":
......
...@@ -74,6 +74,22 @@ class PackedEnumMap ...@@ -74,6 +74,22 @@ class PackedEnumMap
using Storage = std::array<T, MaxSize>; using Storage = std::array<T, MaxSize>;
public: public:
using InitPair = std::pair<E, T>;
constexpr PackedEnumMap() = default;
constexpr PackedEnumMap(std::initializer_list<InitPair> init) : mPrivateData{}
{
// We use a for loop instead of range-for to work around a limitation in MSVC.
for (const InitPair *it = init.begin(); it != init.end(); ++it)
{
// This horrible const_cast pattern is necessary to work around a constexpr limitation.
// See https://stackoverflow.com/q/34199774/ . Note that it should be fixed with C++17.
const_cast<T &>(const_cast<const Storage &>(
mPrivateData)[static_cast<UnderlyingType>(it->first)]) = it->second;
}
}
// types: // types:
using value_type = T; using value_type = T;
using pointer = T *; using pointer = T *;
...@@ -133,8 +149,8 @@ class PackedEnumMap ...@@ -133,8 +149,8 @@ class PackedEnumMap
T *data() noexcept { return mPrivateData.data(); } T *data() noexcept { return mPrivateData.data(); }
const T *data() const noexcept { return mPrivateData.data(); } const T *data() const noexcept { return mPrivateData.data(); }
// Do not access this variable directly. It unfortunately must be public to use aggregate init. private:
/* private: */ Storage mPrivateData; Storage mPrivateData;
}; };
// PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It // PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It
...@@ -199,6 +215,59 @@ TextureType SamplerTypeToTextureType(GLenum samplerType); ...@@ -199,6 +215,59 @@ TextureType SamplerTypeToTextureType(GLenum samplerType);
bool IsMultisampled(gl::TextureType type); bool IsMultisampled(gl::TextureType type);
enum class PrimitiveMode : uint8_t
{
Points = 0x0,
Lines = 0x1,
LineLoop = 0x2,
LineStrip = 0x3,
Triangles = 0x4,
TriangleStrip = 0x5,
TriangleFan = 0x6,
Unused1 = 0x7,
Unused2 = 0x8,
Unused3 = 0x9,
LinesAdjacency = 0xA,
LineStripAdjacency = 0xB,
TrianglesAdjacency = 0xC,
TriangleStripAdjacency = 0xD,
InvalidEnum = 0xE,
EnumCount = 0xE,
};
template <>
constexpr PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from)
{
if (from >= static_cast<GLenum>(PrimitiveMode::EnumCount))
{
return PrimitiveMode::InvalidEnum;
}
return static_cast<PrimitiveMode>(from);
}
constexpr GLenum ToGLenum(PrimitiveMode from)
{
return static_cast<GLenum>(from);
}
static_assert(ToGLenum(PrimitiveMode::Points) == GL_POINTS, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::Lines) == GL_LINES, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineLoop) == GL_LINE_LOOP, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineStrip) == GL_LINE_STRIP, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::Triangles) == GL_TRIANGLES, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleStrip) == GL_TRIANGLE_STRIP,
"PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleFan) == GL_TRIANGLE_FAN, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LinesAdjacency) == GL_LINES_ADJACENCY,
"PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineStripAdjacency) == GL_LINE_STRIP_ADJACENCY,
"PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TrianglesAdjacency) == GL_TRIANGLES_ADJACENCY,
"PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleStripAdjacency) == GL_TRIANGLE_STRIP_ADJACENCY,
"PrimitiveMode violation");
} // namespace gl } // namespace gl
namespace egl namespace egl
......
...@@ -628,70 +628,6 @@ GLenum ToGLenum(PointParameter from) ...@@ -628,70 +628,6 @@ GLenum ToGLenum(PointParameter from)
} }
template <> template <>
PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from)
{
switch (from)
{
case GL_POINTS:
return PrimitiveMode::Points;
case GL_LINES:
return PrimitiveMode::Lines;
case GL_LINE_LOOP:
return PrimitiveMode::LineLoop;
case GL_LINE_STRIP:
return PrimitiveMode::LineStrip;
case GL_TRIANGLES:
return PrimitiveMode::Triangles;
case GL_TRIANGLE_STRIP:
return PrimitiveMode::TriangleStrip;
case GL_TRIANGLE_FAN:
return PrimitiveMode::TriangleFan;
case GL_LINES_ADJACENCY_EXT:
return PrimitiveMode::LinesAdjacency;
case GL_LINE_STRIP_ADJACENCY_EXT:
return PrimitiveMode::LineStripAdjacency;
case GL_TRIANGLES_ADJACENCY_EXT:
return PrimitiveMode::TrianglesAdjacency;
case GL_TRIANGLE_STRIP_ADJACENCY_EXT:
return PrimitiveMode::TriangleStripAdjacency;
default:
return PrimitiveMode::InvalidEnum;
}
}
GLenum ToGLenum(PrimitiveMode from)
{
switch (from)
{
case PrimitiveMode::Points:
return GL_POINTS;
case PrimitiveMode::Lines:
return GL_LINES;
case PrimitiveMode::LineLoop:
return GL_LINE_LOOP;
case PrimitiveMode::LineStrip:
return GL_LINE_STRIP;
case PrimitiveMode::Triangles:
return GL_TRIANGLES;
case PrimitiveMode::TriangleStrip:
return GL_TRIANGLE_STRIP;
case PrimitiveMode::TriangleFan:
return GL_TRIANGLE_FAN;
case PrimitiveMode::LinesAdjacency:
return GL_LINES_ADJACENCY_EXT;
case PrimitiveMode::LineStripAdjacency:
return GL_LINE_STRIP_ADJACENCY_EXT;
case PrimitiveMode::TrianglesAdjacency:
return GL_TRIANGLES_ADJACENCY_EXT;
case PrimitiveMode::TriangleStripAdjacency:
return GL_TRIANGLE_STRIP_ADJACENCY_EXT;
default:
UNREACHABLE();
return 0;
}
}
template <>
QueryType FromGLenum<QueryType>(GLenum from) QueryType FromGLenum<QueryType>(GLenum from)
{ {
switch (from) switch (from)
......
...@@ -255,28 +255,6 @@ template <> ...@@ -255,28 +255,6 @@ template <>
PointParameter FromGLenum<PointParameter>(GLenum from); PointParameter FromGLenum<PointParameter>(GLenum from);
GLenum ToGLenum(PointParameter from); GLenum ToGLenum(PointParameter from);
enum class PrimitiveMode : uint8_t
{
Points = 0,
Lines = 1,
LineLoop = 2,
LineStrip = 3,
Triangles = 4,
TriangleStrip = 5,
TriangleFan = 6,
LinesAdjacency = 7,
LineStripAdjacency = 8,
TrianglesAdjacency = 9,
TriangleStripAdjacency = 10,
InvalidEnum = 11,
EnumCount = 11,
};
template <>
PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from);
GLenum ToGLenum(PrimitiveMode from);
enum class QueryType : uint8_t enum class QueryType : uint8_t
{ {
AnySamples = 0, AnySamples = 0,
......
...@@ -229,20 +229,6 @@ ...@@ -229,20 +229,6 @@
"SpotDirection": "GL_SPOT_DIRECTION", "SpotDirection": "GL_SPOT_DIRECTION",
"SpotExponent": "GL_SPOT_EXPONENT" "SpotExponent": "GL_SPOT_EXPONENT"
}, },
"PrimitiveMode":
{
"Points": "GL_POINTS",
"Lines": "GL_LINES",
"LineLoop": "GL_LINE_LOOP",
"LineStrip": "GL_LINE_STRIP",
"Triangles": "GL_TRIANGLES",
"TriangleStrip": "GL_TRIANGLE_STRIP",
"TriangleFan": "GL_TRIANGLE_FAN",
"LinesAdjacency": "GL_LINES_ADJACENCY_EXT",
"LineStripAdjacency": "GL_LINE_STRIP_ADJACENCY_EXT",
"TrianglesAdjacency": "GL_TRIANGLES_ADJACENCY_EXT",
"TriangleStripAdjacency": "GL_TRIANGLE_STRIP_ADJACENCY_EXT"
},
"PointParameter": "PointParameter":
{ {
"PointSizeMin" : "GL_POINT_SIZE_MIN", "PointSizeMin" : "GL_POINT_SIZE_MIN",
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/Format.h"
#include "libANGLE/validationES.h" #include "libANGLE/validationES.h"
namespace gl
{
namespace namespace
{ {
...@@ -56,12 +58,12 @@ namespace ...@@ -56,12 +58,12 @@ namespace
#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR); #define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
template <typename T> template <typename T>
std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager, std::vector<Path *> GatherPaths(PathManager &resourceManager,
GLsizei numPaths, GLsizei numPaths,
const void *paths, const void *paths,
GLuint pathBase) GLuint pathBase)
{ {
std::vector<gl::Path *> ret; std::vector<Path *> ret;
ret.reserve(numPaths); ret.reserve(numPaths);
const auto *nameArray = static_cast<const T *>(paths); const auto *nameArray = static_cast<const T *>(paths);
...@@ -76,11 +78,11 @@ std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager, ...@@ -76,11 +78,11 @@ std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
return ret; return ret;
} }
std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager, std::vector<Path *> GatherPaths(PathManager &resourceManager,
GLsizei numPaths, GLsizei numPaths,
GLenum pathNameType, GLenum pathNameType,
const void *paths, const void *paths,
GLuint pathBase) GLuint pathBase)
{ {
switch (pathNameType) switch (pathNameType)
{ {
...@@ -104,14 +106,11 @@ std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager, ...@@ -104,14 +106,11 @@ std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
} }
UNREACHABLE(); UNREACHABLE();
return std::vector<gl::Path *>(); return std::vector<Path *>();
} }
template <typename T> template <typename T>
angle::Result GetQueryObjectParameter(const gl::Context *context, angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
gl::Query *query,
GLenum pname,
T *params)
{ {
ASSERT(query != nullptr); ASSERT(query != nullptr);
...@@ -123,7 +122,7 @@ angle::Result GetQueryObjectParameter(const gl::Context *context, ...@@ -123,7 +122,7 @@ angle::Result GetQueryObjectParameter(const gl::Context *context,
{ {
bool available; bool available;
ANGLE_TRY(query->isResultAvailable(context, &available)); ANGLE_TRY(query->isResultAvailable(context, &available));
*params = gl::CastFromStateValue<T>(pname, static_cast<GLuint>(available)); *params = CastFromStateValue<T>(pname, static_cast<GLuint>(available));
return angle::Result::Continue(); return angle::Result::Continue();
} }
default: default:
...@@ -132,8 +131,8 @@ angle::Result GetQueryObjectParameter(const gl::Context *context, ...@@ -132,8 +131,8 @@ angle::Result GetQueryObjectParameter(const gl::Context *context,
} }
} }
ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const gl::Context *context, ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
gl::TransformFeedback *transformFeedback, TransformFeedback *transformFeedback,
GLsizei count, GLsizei count,
GLsizei instanceCount) GLsizei instanceCount)
{ {
...@@ -154,9 +153,9 @@ EGLint GetClientMinorVersion(const egl::AttributeMap &attribs) ...@@ -154,9 +153,9 @@ EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0)); return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
} }
gl::Version GetClientVersion(const egl::AttributeMap &attribs) Version GetClientVersion(const egl::AttributeMap &attribs)
{ {
return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs)); return Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
} }
GLenum GetResetStrategy(const egl::AttributeMap &attribs) GLenum GetResetStrategy(const egl::AttributeMap &attribs)
...@@ -256,45 +255,31 @@ void LimitCap(CapT *cap, MaxT maximum) ...@@ -256,45 +255,31 @@ void LimitCap(CapT *cap, MaxT maximum)
*cap = std::min(*cap, static_cast<CapT>(maximum)); *cap = std::min(*cap, static_cast<CapT>(maximum));
} }
constexpr angle::PackedEnumMap<gl::PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{ constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
1, /* Points */ {PrimitiveMode::Points, 1},
2, /* Lines */ {PrimitiveMode::Lines, 2},
2, /* LineLoop */ {PrimitiveMode::LineLoop, 2},
2, /* LineStrip */ {PrimitiveMode::LineStrip, 2},
3, /* Triangles */ {PrimitiveMode::Triangles, 3},
3, /* TriangleStrip */ {PrimitiveMode::TriangleStrip, 3},
3, /* TriangleFan */ {PrimitiveMode::TriangleFan, 3},
2, /* LinesAdjacency */ {PrimitiveMode::LinesAdjacency, 2},
2, /* LineStripAdjacency */ {PrimitiveMode::LineStripAdjacency, 2},
3, /* TrianglesAdjacency */ {PrimitiveMode::TrianglesAdjacency, 3},
3, /* TriangleStripAdjacency */ {PrimitiveMode::TriangleStripAdjacency, 3},
}}; }};
// Indices above are code-gen'd so make sure they don't change
// if any of these static asserts are hit, must update kMinimumPrimitiveCounts abouve // The rest default to false.
static_assert(static_cast<gl::PrimitiveMode>(0) == gl::PrimitiveMode::Points, constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); kValidBasicDrawModes = {{
static_assert(static_cast<gl::PrimitiveMode>(1) == gl::PrimitiveMode::Lines, {PrimitiveMode::Points, true},
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); {PrimitiveMode::Lines, true},
static_assert(static_cast<gl::PrimitiveMode>(2) == gl::PrimitiveMode::LineLoop, {PrimitiveMode::LineLoop, true},
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); {PrimitiveMode::LineStrip, true},
static_assert(static_cast<gl::PrimitiveMode>(3) == gl::PrimitiveMode::LineStrip, {PrimitiveMode::Triangles, true},
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); {PrimitiveMode::TriangleStrip, true},
static_assert(static_cast<gl::PrimitiveMode>(4) == gl::PrimitiveMode::Triangles, {PrimitiveMode::TriangleFan, true},
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); }};
static_assert(static_cast<gl::PrimitiveMode>(5) == gl::PrimitiveMode::TriangleStrip,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(6) == gl::PrimitiveMode::TriangleFan,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(7) == gl::PrimitiveMode::LinesAdjacency,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(8) == gl::PrimitiveMode::LineStripAdjacency,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(9) == gl::PrimitiveMode::TrianglesAdjacency,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(10) == gl::PrimitiveMode::TriangleStripAdjacency,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
static_assert(static_cast<gl::PrimitiveMode>(11) == gl::PrimitiveMode::EnumCount,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
enum SubjectIndexes : angle::SubjectIndex enum SubjectIndexes : angle::SubjectIndex
{ {
...@@ -311,9 +296,6 @@ enum SubjectIndexes : angle::SubjectIndex ...@@ -311,9 +296,6 @@ enum SubjectIndexes : angle::SubjectIndex
}; };
} // anonymous namespace } // anonymous namespace
namespace gl
{
Context::Context(rx::EGLImplFactory *implFactory, Context::Context(rx::EGLImplFactory *implFactory,
const egl::Config *config, const egl::Config *config,
const Context *shareContext, const Context *shareContext,
...@@ -8413,20 +8395,7 @@ void StateCache::updateValidDrawModes(Context *context) ...@@ -8413,20 +8395,7 @@ void StateCache::updateValidDrawModes(Context *context)
Program *program = context->getGLState().getProgram(); Program *program = context->getGLState().getProgram();
if (!program || !program->hasLinkedShaderStage(ShaderType::Geometry)) if (!program || !program->hasLinkedShaderStage(ShaderType::Geometry))
{ {
mCachedValidDrawModes = {{ mCachedValidDrawModes = kValidBasicDrawModes;
true, /* Points */
true, /* Lines */
true, /* LineLoop */
true, /* LineStrip */
true, /* Triangles */
true, /* TriangleStrip */
true, /* TriangleFan */
false, /* LinesAdjacency */
false, /* LineStripAdjacency */
false, /* TrianglesAdjacency */
false, /* TriangleStripAdjacency */
false, /* InvalidEnum */
}};
} }
else else
{ {
...@@ -8435,18 +8404,17 @@ void StateCache::updateValidDrawModes(Context *context) ...@@ -8435,18 +8404,17 @@ void StateCache::updateValidDrawModes(Context *context)
PrimitiveMode gsMode = program->getGeometryShaderInputPrimitiveType(); PrimitiveMode gsMode = program->getGeometryShaderInputPrimitiveType();
mCachedValidDrawModes = {{ mCachedValidDrawModes = {{
gsMode == PrimitiveMode::Points, /* Points */ {PrimitiveMode::Points, gsMode == PrimitiveMode::Points},
gsMode == PrimitiveMode::Lines, /* Lines */ {PrimitiveMode::Lines, gsMode == PrimitiveMode::Lines},
gsMode == PrimitiveMode::Lines, /* LineLoop */ {PrimitiveMode::LineLoop, gsMode == PrimitiveMode::Lines},
gsMode == PrimitiveMode::Lines, /* LineStrip */ {PrimitiveMode::LineStrip, gsMode == PrimitiveMode::Lines},
gsMode == PrimitiveMode::Triangles, /* Triangles */ {PrimitiveMode::Triangles, gsMode == PrimitiveMode::Triangles},
gsMode == PrimitiveMode::Triangles, /* TriangleStrip */ {PrimitiveMode::TriangleStrip, gsMode == PrimitiveMode::Triangles},
gsMode == PrimitiveMode::Triangles, /* TriangleFan */ {PrimitiveMode::TriangleFan, gsMode == PrimitiveMode::Triangles},
gsMode == PrimitiveMode::LinesAdjacency, /* LinesAdjacency */ {PrimitiveMode::LinesAdjacency, gsMode == PrimitiveMode::LinesAdjacency},
gsMode == PrimitiveMode::LinesAdjacency, /* LineStripAdjacency */ {PrimitiveMode::LineStripAdjacency, gsMode == PrimitiveMode::LinesAdjacency},
gsMode == PrimitiveMode::TrianglesAdjacency, /* TrianglesAdjacency */ {PrimitiveMode::TrianglesAdjacency, gsMode == PrimitiveMode::TrianglesAdjacency},
gsMode == PrimitiveMode::TrianglesAdjacency, /* TriangleStripAdjacency */ {PrimitiveMode::TriangleStripAdjacency, gsMode == PrimitiveMode::TrianglesAdjacency},
false, /* InvalidEnum */
}}; }};
} }
} }
...@@ -8458,16 +8426,14 @@ void StateCache::updateValidBindTextureTypes(Context *context) ...@@ -8458,16 +8426,14 @@ void StateCache::updateValidBindTextureTypes(Context *context)
bool isGLES31 = context->getClientVersion() >= Version(3, 1); bool isGLES31 = context->getClientVersion() >= Version(3, 1);
mCachedValidBindTextureTypes = {{ mCachedValidBindTextureTypes = {{
true, /* _2D */ {TextureType::_2D, true},
isGLES3, /* _2DArray */ {TextureType::_2DArray, isGLES3},
isGLES31 || exts.textureMultisample, /* _2DMultisample */ {TextureType::_2DMultisample, isGLES31 || exts.textureMultisample},
exts.textureStorageMultisample2DArray, /* _2DMultisampleArray */ {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2DArray},
isGLES3, /* _3D */ {TextureType::_3D, isGLES3},
exts.eglImageExternal || exts.eglStreamConsumerExternal, /* External */ {TextureType::External, exts.eglImageExternal || exts.eglStreamConsumerExternal},
exts.textureRectangle, /* Rectangle */ {TextureType::Rectangle, exts.textureRectangle},
true, /* CubeMap */ {TextureType::CubeMap, true},
false, /* InvalidEnum */
}}; }};
} }
} // namespace gl } // namespace gl
...@@ -50,26 +50,22 @@ bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType) ...@@ -50,26 +50,22 @@ bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
// Mapping from a buffer binding type to a dirty bit type. // Mapping from a buffer binding type to a dirty bit type.
constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{ constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{
0, /* Array */ {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING},
State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING, /* AtomicCounter */ {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING},
0, /* CopyRead */ {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING},
0, /* CopyWrite */ {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING},
State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING, /* DispatchIndirect */ {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING},
State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING, /* DrawIndirect */ {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING},
0, /* ElementArray */ {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS},
State::DIRTY_BIT_PACK_BUFFER_BINDING, /* PixelPack */
State::DIRTY_BIT_UNPACK_BUFFER_BINDING, /* PixelUnpack */
State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING, /* ShaderStorage */
0, /* TransformFeedback */
State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS, /* Uniform */
}}; }};
// Returns a buffer binding function depending on if a dirty bit is set. // Returns a buffer binding function depending on if a dirty bit is set.
template <BufferBinding Target> template <BufferBinding Target>
constexpr State::BufferBindingSetter GetBufferBindingSetter() constexpr std::pair<BufferBinding, State::BufferBindingSetter> GetBufferBindingSetter()
{ {
return kBufferBindingDirtyBits[Target] != 0 ? &State::setGenericBufferBindingWithBit<Target> return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0
: &State::setGenericBufferBinding<Target>; ? &State::setGenericBufferBindingWithBit<Target>
: &State::setGenericBufferBinding<Target>);
} }
} // namespace } // namespace
......
...@@ -1070,6 +1070,36 @@ TEST_P(SimpleOperationTest, RenderbufferAttachment) ...@@ -1070,6 +1070,36 @@ TEST_P(SimpleOperationTest, RenderbufferAttachment)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Tests that using desktop GL_QUADS/GL_POLYGONS enums generate the correct error.
TEST_P(SimpleOperationTest, PrimitiveModeNegativeTest)
{
// Draw a correct quad.
ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
glUseProgram(program);
GLint positionLocation = glGetAttribLocation(program, "position");
ASSERT_NE(-1, positionLocation);
setupQuadVertexBuffer(0.5f, 1.0f);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionLocation);
// Tests that TRIANGLES works.
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// Tests that specific invalid enums don't work.
glDrawArrays(static_cast<GLenum>(7), 0, 6);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glDrawArrays(static_cast<GLenum>(8), 0, 6);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glDrawArrays(static_cast<GLenum>(9), 0, 6);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(SimpleOperationTest, ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
......
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