Add generator for packed GL enums.

For testing this also converts two unimportant GLenums, gl::BufferUsage
and gl::CullModeFace.

BUG=angleproject:2169

Change-Id: If1e86a97d0fed3fd567303aca6506ec579503076
Reviewed-on: https://chromium-review.googlesource.com/688000
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Buffer.cpp b/src/libANGLE/Buffer.cpp
index 198cb51..ca0528e 100644
--- a/src/libANGLE/Buffer.cpp
+++ b/src/libANGLE/Buffer.cpp
@@ -19,7 +19,7 @@
 
 BufferState::BufferState()
     : mLabel(),
-      mUsage(GL_STATIC_DRAW),
+      mUsage(BufferUsage::StaticDraw),
       mSize(0),
       mAccessFlags(0),
       mAccess(GL_WRITE_ONLY_OES),
@@ -66,7 +66,7 @@
                          GLenum target,
                          const void *data,
                          GLsizeiptr size,
-                         GLenum usage)
+                         BufferUsage usage)
 {
     const void *dataForImpl = data;
 
diff --git a/src/libANGLE/Buffer.h b/src/libANGLE/Buffer.h
index 35ed312..da4a2da 100644
--- a/src/libANGLE/Buffer.h
+++ b/src/libANGLE/Buffer.h
@@ -15,6 +15,7 @@
 #include "libANGLE/Debug.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/IndexRangeCache.h"
+#include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 
 namespace rx
@@ -36,7 +37,7 @@
 
     const std::string &getLabel();
 
-    GLenum getUsage() const { return mUsage; }
+    BufferUsage getUsage() const { return mUsage; }
     GLbitfield getAccessFlags() const { return mAccessFlags; }
     GLenum getAccess() const { return mAccess; }
     GLboolean isMapped() const { return mMapped; }
@@ -50,7 +51,7 @@
 
     std::string mLabel;
 
-    GLenum mUsage;
+    BufferUsage mUsage;
     GLint64 mSize;
     GLbitfield mAccessFlags;
     GLenum mAccess;
@@ -74,7 +75,7 @@
                      GLenum target,
                      const void *data,
                      GLsizeiptr size,
-                     GLenum usage);
+                     BufferUsage usage);
     Error bufferSubData(const Context *context,
                         GLenum target,
                         const void *data,
@@ -99,7 +100,7 @@
                         bool primitiveRestartEnabled,
                         IndexRange *outRange) const;
 
-    GLenum getUsage() const { return mState.mUsage; }
+    BufferUsage getUsage() const { return mState.mUsage; }
     GLbitfield getAccessFlags() const { return mState.mAccessFlags; }
     GLenum getAccess() const { return mState.mAccess; }
     GLboolean isMapped() const { return mState.mMapped; }
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 168d8a0..15274e4 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -3595,7 +3595,7 @@
     mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
 }
 
-void Context::cullFace(GLenum mode)
+void Context::cullFace(CullFaceMode mode)
 {
     mGLState.setCullMode(mode);
 }
@@ -4001,7 +4001,7 @@
     mGLState.getDebug().popGroup();
 }
 
-void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, BufferUsage usage)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 7a72dc3..a8c617b 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -21,6 +21,7 @@
 #include "libANGLE/ContextState.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/HandleAllocator.h"
+#include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 #include "libANGLE/ResourceMap.h"
 #include "libANGLE/VertexAttribute.h"
@@ -275,7 +276,7 @@
     void clearDepthf(GLfloat depth);
     void clearStencil(GLint s);
     void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-    void cullFace(GLenum mode);
+    void cullFace(CullFaceMode mode);
     void depthFunc(GLenum func);
     void depthMask(GLboolean flag);
     void depthRangef(GLfloat zNear, GLfloat zFar);
@@ -667,7 +668,7 @@
                                      GLint components,
                                      const GLfloat *coeffs);
 
-    void bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+    void bufferData(GLenum target, GLsizeiptr size, const void *data, BufferUsage usage);
     void bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
     void attachShader(GLuint program, GLuint shader);
     void bindAttribLocation(GLuint program, GLuint index, const GLchar *name);
diff --git a/src/libANGLE/PackedGLEnums.h b/src/libANGLE/PackedGLEnums.h
new file mode 100644
index 0000000..b02525b
--- /dev/null
+++ b/src/libANGLE/PackedGLEnums.h
@@ -0,0 +1,14 @@
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackedGLEnums_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_H_
+#define LIBANGLE_PACKEDGLENUMS_H_
+
+#include "libANGLE/PackedGLEnums_autogen.h"
+
+#endif  // LIBANGLE_PACKEDGLENUMS_H_
diff --git a/src/libANGLE/PackedGLEnums_autogen.cpp b/src/libANGLE/PackedGLEnums_autogen.cpp
new file mode 100644
index 0000000..faf47df
--- /dev/null
+++ b/src/libANGLE/PackedGLEnums_autogen.cpp
@@ -0,0 +1,106 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by src/libANGLE/gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackedGLEnums_autogen.cpp:
+//   Implements ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#include "libANGLE/PackedGLEnums_autogen.h"
+#include "common/debug.h"
+
+namespace gl
+{
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_DYNAMIC_COPY:
+            return BufferUsage::DynamicCopy;
+        case GL_DYNAMIC_DRAW:
+            return BufferUsage::DynamicDraw;
+        case GL_DYNAMIC_READ:
+            return BufferUsage::DynamicRead;
+        case GL_STATIC_COPY:
+            return BufferUsage::StaticCopy;
+        case GL_STATIC_DRAW:
+            return BufferUsage::StaticDraw;
+        case GL_STATIC_READ:
+            return BufferUsage::StaticRead;
+        case GL_STREAM_COPY:
+            return BufferUsage::StreamCopy;
+        case GL_STREAM_DRAW:
+            return BufferUsage::StreamDraw;
+        case GL_STREAM_READ:
+            return BufferUsage::StreamRead;
+        default:
+            return BufferUsage::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(BufferUsage from)
+{
+    switch (from)
+    {
+        case BufferUsage::DynamicCopy:
+            return GL_DYNAMIC_COPY;
+        case BufferUsage::DynamicDraw:
+            return GL_DYNAMIC_DRAW;
+        case BufferUsage::DynamicRead:
+            return GL_DYNAMIC_READ;
+        case BufferUsage::StaticCopy:
+            return GL_STATIC_COPY;
+        case BufferUsage::StaticDraw:
+            return GL_STATIC_DRAW;
+        case BufferUsage::StaticRead:
+            return GL_STATIC_READ;
+        case BufferUsage::StreamCopy:
+            return GL_STREAM_COPY;
+        case BufferUsage::StreamDraw:
+            return GL_STREAM_DRAW;
+        case BufferUsage::StreamRead:
+            return GL_STREAM_READ;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_BACK:
+            return CullFaceMode::Back;
+        case GL_FRONT:
+            return CullFaceMode::Front;
+        case GL_FRONT_AND_BACK:
+            return CullFaceMode::FrontAndBack;
+        default:
+            return CullFaceMode::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(CullFaceMode from)
+{
+    switch (from)
+    {
+        case CullFaceMode::Back:
+            return GL_BACK;
+        case CullFaceMode::Front:
+            return GL_FRONT;
+        case CullFaceMode::FrontAndBack:
+            return GL_FRONT_AND_BACK;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+}  // namespace gl
diff --git a/src/libANGLE/PackedGLEnums_autogen.h b/src/libANGLE/PackedGLEnums_autogen.h
new file mode 100644
index 0000000..e86bef5
--- /dev/null
+++ b/src/libANGLE/PackedGLEnums_autogen.h
@@ -0,0 +1,63 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by src/libANGLE/gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackedGLEnums_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+#include <cstdint>
+
+namespace gl
+{
+
+template <typename Enum>
+Enum FromGLenum(GLenum from);
+
+enum class BufferUsage : uint8_t
+{
+    DynamicCopy = 0,
+    DynamicDraw = 1,
+    DynamicRead = 2,
+    StaticCopy  = 3,
+    StaticDraw  = 4,
+    StaticRead  = 5,
+    StreamCopy  = 6,
+    StreamDraw  = 7,
+    StreamRead  = 8,
+
+    InvalidEnum = 9,
+    EnumCount   = 9,
+};
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from);
+GLenum ToGLenum(BufferUsage from);
+
+enum class CullFaceMode : uint8_t
+{
+    Back         = 0,
+    Front        = 1,
+    FrontAndBack = 2,
+
+    InvalidEnum = 3,
+    EnumCount   = 3,
+};
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from);
+GLenum ToGLenum(CullFaceMode from);
+
+}  // namespace gl
+
+#endif  // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 1d041b4..c5d23db 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -358,7 +358,7 @@
     mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
 }
 
-void State::setCullMode(GLenum mode)
+void State::setCullMode(CullFaceMode mode)
 {
     mRasterizer.cullMode = mode;
     mDirtyBits.set(DIRTY_BIT_CULL_FACE);
@@ -1694,7 +1694,9 @@
         params[2] = mBlend.colorMaskBlue;
         params[3] = mBlend.colorMaskAlpha;
         break;
-      case GL_CULL_FACE:                 *params = mRasterizer.cullFace;          break;
+      case GL_CULL_FACE:
+          *params = mRasterizer.cullFace;
+          break;
       case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
       case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
@@ -1927,8 +1929,12 @@
         params[2] = mScissor.width;
         params[3] = mScissor.height;
         break;
-      case GL_CULL_FACE_MODE:                   *params = mRasterizer.cullMode;   break;
-      case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  break;
+      case GL_CULL_FACE_MODE:
+          *params = ToGLenum(mRasterizer.cullMode);
+          break;
+      case GL_FRONT_FACE:
+          *params = mRasterizer.frontFace;
+          break;
       case GL_RED_BITS:
       case GL_GREEN_BITS:
       case GL_BLUE_BITS:
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index a4d5e81..e476508 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -77,7 +77,7 @@
     // Face culling state manipulation
     bool isCullFaceEnabled() const;
     void setCullFace(bool enabled);
-    void setCullMode(GLenum mode);
+    void setCullMode(CullFaceMode mode);
     void setFrontFace(GLenum front);
 
     // Depth test state manipulation
diff --git a/src/libANGLE/angletypes.cpp b/src/libANGLE/angletypes.cpp
index d97b8d2..57f214f 100644
--- a/src/libANGLE/angletypes.cpp
+++ b/src/libANGLE/angletypes.cpp
@@ -45,7 +45,7 @@
 
     rasterizerDiscard   = false;
     cullFace            = false;
-    cullMode            = GL_BACK;
+    cullMode            = CullFaceMode::Back;
     frontFace           = GL_CCW;
     polygonOffsetFill   = false;
     polygonOffsetFactor = 0.0f;
diff --git a/src/libANGLE/angletypes.h b/src/libANGLE/angletypes.h
index d749213..03b810d 100644
--- a/src/libANGLE/angletypes.h
+++ b/src/libANGLE/angletypes.h
@@ -12,6 +12,7 @@
 #include "common/bitset_utils.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/PackedGLEnums.h"
 #include "libANGLE/RefCountObject.h"
 
 #include <stdint.h>
@@ -123,7 +124,7 @@
     RasterizerState();
 
     bool cullFace;
-    GLenum cullMode;
+    CullFaceMode cullMode;
     GLenum frontFace;
 
     bool polygonOffsetFill;
diff --git a/src/libANGLE/gen_format_map.py b/src/libANGLE/gen_format_map.py
index b67f427..e150fc0 100644
--- a/src/libANGLE/gen_format_map.py
+++ b/src/libANGLE/gen_format_map.py
@@ -184,4 +184,3 @@
         es3_type_cases = es3_type_cases,
         es3_combo_cases = es3_combo_cases)
     out_file.write(output_cpp)
-    out_file.close()
diff --git a/src/libANGLE/gen_packed_gl_enums.py b/src/libANGLE/gen_packed_gl_enums.py
new file mode 100644
index 0000000..c9cb95d
--- /dev/null
+++ b/src/libANGLE/gen_packed_gl_enums.py
@@ -0,0 +1,178 @@
+# Copyright 2016 The ANGLE Project Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# gen_packed_gl_enums.py:
+#  Code generation for the packed GL enums.
+
+import datetime, json, os, sys
+from collections import namedtuple
+
+Enum = namedtuple('Enum', ['name', 'values', 'max_value'])
+EnumValue = namedtuple('EnumValue', ['name', 'gl_name', 'value'])
+
+kJsonFileName = "packed_gl_enums.json"
+
+def load_enums(path):
+    with open(path) as map_file:
+        enums_dict = json.loads(map_file.read())
+
+    enums = []
+    for (enum_name, values_dict) in enums_dict.iteritems():
+
+        values = []
+        i = 0
+        for (value_name, value_gl_name) in sorted(values_dict.iteritems()):
+            values.append(EnumValue(value_name, value_gl_name, i))
+            i += 1
+
+        assert(i < 255) # This makes sure enums fit in the uint8_t
+        enums.append(Enum(enum_name, values, i))
+
+    enums.sort(key=lambda enum: enum.name)
+    return enums
+
+header_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name}.
+//
+// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackedGLEnums_autogen.h:
+//   Declares ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+#include <cstdint>
+
+namespace gl
+{{
+
+template<typename Enum>
+Enum FromGLenum(GLenum from);
+{content}
+}}  // namespace gl
+
+#endif // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
+"""
+
+enum_declaration_template = """
+enum class {enum_name} : uint8_t
+{{
+{value_declarations}
+
+    InvalidEnum = {max_value},
+    EnumCount = {max_value},
+}};
+
+template<>
+{enum_name} FromGLenum<{enum_name}>(GLenum from);
+GLenum ToGLenum({enum_name} from);
+"""
+
+def write_header(enums, path):
+    content = ['']
+
+    for enum in enums:
+        value_declarations = []
+        for value in enum.values:
+            value_declarations.append('    ' + value.name + ' = ' + str(value.value) + ',')
+
+        content.append(enum_declaration_template.format(
+            enum_name = enum.name,
+            max_value = str(enum.max_value),
+            value_declarations = '\n'.join(value_declarations)
+        ))
+
+    header = header_template.format(
+        content = ''.join(content),
+        copyright_year = datetime.date.today().year,
+        data_source_name = kJsonFileName,
+        script_name = sys.argv[0]
+    )
+
+    with (open(path, 'wt')) as f:
+        f.write(header)
+
+cpp_template = """// GENERATED FILE - DO NOT EDIT.
+// Generated by {script_name} using data from {data_source_name}.
+//
+// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackedGLEnums_autogen.cpp:
+//   Implements ANGLE-specific enums classes for GLEnum and functions operating
+//   on them.
+
+#include "common/debug.h"
+#include "libANGLE/PackedGLEnums_autogen.h"
+
+namespace gl
+{{
+{content}
+}}  // namespace gl
+"""
+
+enum_implementation_template = """
+template<>
+{enum_name} FromGLenum<{enum_name}>(GLenum from)
+{{
+    switch(from)
+    {{
+{from_glenum_cases}
+        default: return {enum_name}::InvalidEnum;
+    }}
+}}
+
+GLenum ToGLenum({enum_name} from)
+{{
+    switch(from)
+    {{
+{to_glenum_cases}
+        default: UNREACHABLE(); return GL_NONE;
+    }}
+}}
+"""
+
+def write_cpp(enums, path):
+    content = ['']
+
+    for enum in enums:
+        from_glenum_cases = []
+        to_glenum_cases = []
+        for value in enum.values:
+            qualified_name = enum.name + '::' + value.name
+            from_glenum_cases.append('        case ' + value.gl_name + ': return ' + qualified_name + ';')
+            to_glenum_cases.append('        case ' + qualified_name + ': return ' + value.gl_name + ';')
+
+        content.append(enum_implementation_template.format(
+            enum_name = enum.name,
+            from_glenum_cases = '\n'.join(from_glenum_cases),
+            max_value = str(enum.max_value),
+            to_glenum_cases = '\n'.join(to_glenum_cases)
+        ))
+
+    cpp = cpp_template.format(
+        content = ''.join(content),
+        copyright_year = datetime.date.today().year,
+        data_source_name = kJsonFileName,
+        script_name = sys.argv[0]
+    )
+
+    with (open(path, 'wt')) as f:
+        f.write(cpp)
+
+if __name__ == '__main__':
+    path_prefix = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
+    enums = load_enums(path_prefix + kJsonFileName)
+
+    write_header(enums, path_prefix + 'PackedGLEnums_autogen.h')
+    write_cpp(enums, path_prefix + 'PackedGLEnums_autogen.cpp')
diff --git a/src/libANGLE/packed_gl_enums.json b/src/libANGLE/packed_gl_enums.json
new file mode 100644
index 0000000..6de4f29
--- /dev/null
+++ b/src/libANGLE/packed_gl_enums.json
@@ -0,0 +1,20 @@
+{
+    "BufferUsage":
+    {
+        "DynamicCopy": "GL_DYNAMIC_COPY",
+        "DynamicDraw": "GL_DYNAMIC_DRAW",
+        "DynamicRead": "GL_DYNAMIC_READ",
+        "StaticCopy": "GL_STATIC_COPY",
+        "StaticDraw": "GL_STATIC_DRAW",
+        "StaticRead": "GL_STATIC_READ",
+        "StreamCopy": "GL_STREAM_COPY",
+        "StreamDraw": "GL_STREAM_DRAW",
+        "StreamRead": "GL_STREAM_READ"
+    },
+    "CullFaceMode":
+    {
+        "Back": "GL_BACK",
+        "Front": "GL_FRONT",
+        "FrontAndBack": "GL_FRONT_AND_BACK"
+    }
+}
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index d74cd7d..be2b654 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -410,7 +410,7 @@
     switch (pname)
     {
         case GL_BUFFER_USAGE:
-            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getUsage());
+            *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
             break;
         case GL_BUFFER_SIZE:
             *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
diff --git a/src/libANGLE/renderer/BufferImpl.h b/src/libANGLE/renderer/BufferImpl.h
index 7acf213..581949d 100644
--- a/src/libANGLE/renderer/BufferImpl.h
+++ b/src/libANGLE/renderer/BufferImpl.h
@@ -12,6 +12,7 @@
 #include "common/angleutils.h"
 #include "common/mathutil.h"
 #include "libANGLE/Error.h"
+#include "libANGLE/PackedGLEnums.h"
 
 #include <stdint.h>
 
@@ -34,7 +35,7 @@
                               GLenum target,
                               const void *data,
                               size_t size,
-                              GLenum usage) = 0;
+                              gl::BufferUsage usage)                                = 0;
     virtual gl::Error setSubData(const gl::Context *context,
                                  GLenum target,
                                  const void *data,
diff --git a/src/libANGLE/renderer/BufferImpl_mock.h b/src/libANGLE/renderer/BufferImpl_mock.h
index 6516e52..9f18efc 100644
--- a/src/libANGLE/renderer/BufferImpl_mock.h
+++ b/src/libANGLE/renderer/BufferImpl_mock.h
@@ -22,7 +22,8 @@
     MockBufferImpl() : BufferImpl(mMockState) {}
     ~MockBufferImpl() { destructor(); }
 
-    MOCK_METHOD5(setData, gl::Error(const gl::Context *, GLenum, const void *, size_t, GLenum));
+    MOCK_METHOD5(setData,
+                 gl::Error(const gl::Context *, GLenum, const void *, size_t, gl::BufferUsage));
     MOCK_METHOD5(setSubData, gl::Error(const gl::Context *, GLenum, const void *, size_t, size_t));
     MOCK_METHOD5(
         copySubData,
diff --git a/src/libANGLE/renderer/angle_format.py b/src/libANGLE/renderer/angle_format.py
index 43ca684..19d531c 100644
--- a/src/libANGLE/renderer/angle_format.py
+++ b/src/libANGLE/renderer/angle_format.py
@@ -21,9 +21,7 @@
 
 def load_json(path):
     with open(path) as map_file:
-        file_data = map_file.read()
-        map_file.close()
-        return json.loads(file_data, object_pairs_hook=reject_duplicate_keys)
+        return json.loads(map_file.read(), object_pairs_hook=reject_duplicate_keys)
 
 def load_forward_table(path):
     pairs = load_json(path)
diff --git a/src/libANGLE/renderer/d3d/BufferD3D.cpp b/src/libANGLE/renderer/d3d/BufferD3D.cpp
index fde642f..f75bd9e 100644
--- a/src/libANGLE/renderer/d3d/BufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -47,23 +47,23 @@
     mSerial = mNextSerial++;
 }
 
-void BufferD3D::updateD3DBufferUsage(const gl::Context *context, GLenum usage)
+void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage)
 {
     switch (usage)
     {
-        case GL_STATIC_DRAW:
-        case GL_STATIC_READ:
-        case GL_STATIC_COPY:
+        case gl::BufferUsage::StaticCopy:
+        case gl::BufferUsage::StaticDraw:
+        case gl::BufferUsage::StaticRead:
             mUsage = D3DBufferUsage::STATIC;
             initializeStaticData(context);
             break;
 
-        case GL_STREAM_DRAW:
-        case GL_STREAM_READ:
-        case GL_STREAM_COPY:
-        case GL_DYNAMIC_READ:
-        case GL_DYNAMIC_COPY:
-        case GL_DYNAMIC_DRAW:
+        case gl::BufferUsage::DynamicCopy:
+        case gl::BufferUsage::DynamicDraw:
+        case gl::BufferUsage::DynamicRead:
+        case gl::BufferUsage::StreamCopy:
+        case gl::BufferUsage::StreamDraw:
+        case gl::BufferUsage::StreamRead:
             mUsage = D3DBufferUsage::DYNAMIC;
             break;
         default:
@@ -168,7 +168,7 @@
 
         if (mUnmodifiedDataUse > 3 * getSize())
         {
-            updateD3DBufferUsage(context, GL_STATIC_DRAW);
+            updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw);
         }
     }
 }
diff --git a/src/libANGLE/renderer/d3d/BufferD3D.h b/src/libANGLE/renderer/d3d/BufferD3D.h
index 8483635..93c43b0 100644
--- a/src/libANGLE/renderer/d3d/BufferD3D.h
+++ b/src/libANGLE/renderer/d3d/BufferD3D.h
@@ -69,7 +69,7 @@
 
   protected:
     void updateSerial();
-    void updateD3DBufferUsage(const gl::Context *context, GLenum usage);
+    void updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage);
     void emptyStaticBufferCache();
 
     BufferFactoryD3D *mFactory;
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index 6195a65..2167200 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -73,7 +73,7 @@
     else if (gl::IsTriangleMode(drawMode))
     {
         if (glState.getRasterizerState().cullFace &&
-            glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack)
         {
             return true;
         }
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index 64ecf77..79e9037 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -321,7 +321,7 @@
                             GLenum target,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
     updateD3DBufferUsage(context, usage);
     ANGLE_TRY(setSubData(context, target, data, size, 0));
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index b758fb0..27cf60b 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -84,7 +84,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
                          GLenum target,
                          const void *data,
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 1304460..ba3abf7 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -446,7 +446,7 @@
 bool CullsEverything(const gl::State &glState)
 {
     return (glState.getRasterizerState().cullFace &&
-            glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK);
+            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
 }
 
 }  // anonymous namespace
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
index a24960b..443e4de 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -588,7 +588,7 @@
 
     mCurRasterState.rasterizerDiscard   = false;
     mCurRasterState.cullFace            = false;
-    mCurRasterState.cullMode            = GL_BACK;
+    mCurRasterState.cullMode            = gl::CullFaceMode::Back;
     mCurRasterState.frontFace           = GL_CCW;
     mCurRasterState.polygonOffsetFill   = false;
     mCurRasterState.polygonOffsetFactor = 0.0f;
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 61b1d84..8d1bf2e 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1603,7 +1603,7 @@
     return mask;
 }
 
-D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode)
 {
     D3D11_CULL_MODE cull = D3D11_CULL_NONE;
 
@@ -1611,13 +1611,13 @@
     {
         switch (cullMode)
         {
-            case GL_FRONT:
+            case gl::CullFaceMode::Front:
                 cull = D3D11_CULL_FRONT;
                 break;
-            case GL_BACK:
+            case gl::CullFaceMode::Back:
                 cull = D3D11_CULL_BACK;
                 break;
-            case GL_FRONT_AND_BACK:
+            case gl::CullFaceMode::FrontAndBack:
                 cull = D3D11_CULL_NONE;
                 break;
             default:
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
index 41e03be..a7549d4 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -43,7 +43,7 @@
 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
 UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
 
-D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode);
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode);
 
 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
index c9a46a5..d96c073 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -26,7 +26,7 @@
                            GLenum /*target*/,
                            const void *data,
                            size_t size,
-                           GLenum usage)
+                           gl::BufferUsage usage)
 {
     if (size > mMemory.size())
     {
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
index 143a502..2037e26 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -33,7 +33,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
                          GLenum target,
                          const void *data,
diff --git a/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
index 829fc41..a3bdc14 100644
--- a/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
@@ -890,7 +890,7 @@
     mCurSampleMask = sampleMask;
 }
 
-void StateManager9::setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace)
+void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace)
 {
     if (cullFace)
     {
diff --git a/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
index ea4f91c..63ce17c 100644
--- a/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
@@ -86,7 +86,7 @@
     void setSampleMask(unsigned int sampleMask);
 
     // Current raster state functions
-    void setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace);
+    void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace);
     void setDepthBias(bool polygonOffsetFill,
                       GLfloat polygonOffsetFactor,
                       GLfloat polygonOffsetUnits);
diff --git a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
index 3a569d6..fd451a6 100644
--- a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -135,21 +135,22 @@
     return d3dWrap;
 }
 
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace)
 {
     D3DCULL cull = D3DCULL_CCW;
     switch (cullFace)
     {
-      case GL_FRONT:
-        cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
-        break;
-      case GL_BACK:
-        cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
-        break;
-      case GL_FRONT_AND_BACK:
-        cull = D3DCULL_NONE; // culling will be handled during draw
-        break;
-      default: UNREACHABLE();
+        case gl::CullFaceMode::Front:
+            cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+            break;
+        case gl::CullFaceMode::Back:
+            cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+            break;
+        case gl::CullFaceMode::FrontAndBack:
+            cull = D3DCULL_NONE;  // culling will be handled during draw
+            break;
+        default:
+            UNREACHABLE();
     }
 
     return cull;
diff --git a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
index eaf3108..5b65b89 100644
--- a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
@@ -33,7 +33,7 @@
 D3DBLENDOP ConvertBlendOp(GLenum blendOp);
 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace);
 D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
diff --git a/src/libANGLE/renderer/gl/BufferGL.cpp b/src/libANGLE/renderer/gl/BufferGL.cpp
index c583942..26795d9 100644
--- a/src/libANGLE/renderer/gl/BufferGL.cpp
+++ b/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -59,10 +59,10 @@
                             GLenum /*target*/,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-    mFunctions->bufferData(DestBufferOperationTarget, size, data, usage);
+    mFunctions->bufferData(DestBufferOperationTarget, size, data, ToGLenum(usage));
 
     if (mShadowBufferData)
     {
diff --git a/src/libANGLE/renderer/gl/BufferGL.h b/src/libANGLE/renderer/gl/BufferGL.h
index d86f21c..6acb090 100644
--- a/src/libANGLE/renderer/gl/BufferGL.h
+++ b/src/libANGLE/renderer/gl/BufferGL.h
@@ -30,7 +30,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
                          GLenum target,
                          const void *data,
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 37108be..1f9d468 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -143,7 +143,7 @@
       mStencilBackStencilPassDepthPassOp(GL_KEEP),
       mStencilBackWritemask(static_cast<GLuint>(-1)),
       mCullFaceEnabled(false),
-      mCullFace(GL_BACK),
+      mCullFace(gl::CullFaceMode::Back),
       mFrontFace(GL_CCW),
       mPolygonOffsetFillEnabled(false),
       mPolygonOffsetFactor(0.0f),
@@ -1524,12 +1524,12 @@
     }
 }
 
-void StateManagerGL::setCullFace(GLenum cullFace)
+void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
 {
     if (mCullFace != cullFace)
     {
         mCullFace = cullFace;
-        mFunctions->cullFace(mCullFace);
+        mFunctions->cullFace(ToGLenum(mCullFace));
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
     }
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.h b/src/libANGLE/renderer/gl/StateManagerGL.h
index c88cbe3..d581505 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -114,7 +114,7 @@
     void setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass);
 
     void setCullFaceEnabled(bool enabled);
-    void setCullFace(GLenum cullFace);
+    void setCullFace(gl::CullFaceMode cullFace);
     void setFrontFace(GLenum frontFace);
     void setPolygonOffsetFillEnabled(bool enabled);
     void setPolygonOffset(float factor, float units);
@@ -320,7 +320,7 @@
     GLuint mStencilBackWritemask;
 
     bool mCullFaceEnabled;
-    GLenum mCullFace;
+    gl::CullFaceMode mCullFace;
     GLenum mFrontFace;
     bool mPolygonOffsetFillEnabled;
     GLfloat mPolygonOffsetFactor;
diff --git a/src/libANGLE/renderer/null/BufferNULL.cpp b/src/libANGLE/renderer/null/BufferNULL.cpp
index b1a7876..4a72bb9 100644
--- a/src/libANGLE/renderer/null/BufferNULL.cpp
+++ b/src/libANGLE/renderer/null/BufferNULL.cpp
@@ -33,7 +33,7 @@
                               GLenum target,
                               const void *data,
                               size_t size,
-                              GLenum usage)
+                              gl::BufferUsage usage)
 {
     if (!mAllocationTracker->updateMemoryAllocation(mData.size(), size))
     {
diff --git a/src/libANGLE/renderer/null/BufferNULL.h b/src/libANGLE/renderer/null/BufferNULL.h
index d4cc952..acf6a62 100644
--- a/src/libANGLE/renderer/null/BufferNULL.h
+++ b/src/libANGLE/renderer/null/BufferNULL.h
@@ -27,7 +27,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
                          GLenum target,
                          const void *data,
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp
index 32bda7a..12dbd62 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp
@@ -38,7 +38,7 @@
                             GLenum target,
                             const void *data,
                             size_t size,
-                            GLenum usage)
+                            gl::BufferUsage usage)
 {
     ContextVk *contextVk = GetImplAs<ContextVk>(context);
     auto device          = contextVk->getDevice();
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.h b/src/libANGLE/renderer/vulkan/BufferVk.h
index 7e00571..64ca3f4 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.h
+++ b/src/libANGLE/renderer/vulkan/BufferVk.h
@@ -27,7 +27,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum usage) override;
+                      gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
                          GLenum target,
                          const void *data,
diff --git a/src/libANGLE/renderer/vulkan/renderervk_utils.cpp b/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
index a5e7aa9..74faac6 100644
--- a/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/renderervk_utils.cpp
@@ -1001,11 +1001,11 @@
 
     switch (rasterState.cullMode)
     {
-        case GL_FRONT:
+        case gl::CullFaceMode::Front:
             return VK_CULL_MODE_FRONT_BIT;
-        case GL_BACK:
+        case gl::CullFaceMode::Back:
             return VK_CULL_MODE_BACK_BIT;
-        case GL_FRONT_AND_BACK:
+        case gl::CullFaceMode::FrontAndBack:
             return VK_CULL_MODE_FRONT_AND_BACK;
         default:
             UNREACHABLE();
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 84cbc2a..d073c69 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -4118,7 +4118,7 @@
                         GLenum target,
                         GLsizeiptr size,
                         const void *data,
-                        GLenum usage)
+                        BufferUsage usage)
 {
     if (size < 0)
     {
@@ -4128,17 +4128,17 @@
 
     switch (usage)
     {
-        case GL_STREAM_DRAW:
-        case GL_STATIC_DRAW:
-        case GL_DYNAMIC_DRAW:
+        case BufferUsage::StreamDraw:
+        case BufferUsage::StaticDraw:
+        case BufferUsage::DynamicDraw:
             break;
 
-        case GL_STREAM_READ:
-        case GL_STREAM_COPY:
-        case GL_STATIC_READ:
-        case GL_STATIC_COPY:
-        case GL_DYNAMIC_READ:
-        case GL_DYNAMIC_COPY:
+        case BufferUsage::StreamRead:
+        case BufferUsage::StaticRead:
+        case BufferUsage::DynamicRead:
+        case BufferUsage::StreamCopy:
+        case BufferUsage::StaticCopy:
+        case BufferUsage::DynamicCopy:
             if (context->getClientMajorVersion() < 3)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
@@ -4795,13 +4795,13 @@
     return true;
 }
 
-bool ValidateCullFace(ValidationContext *context, GLenum mode)
+bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
 {
     switch (mode)
     {
-        case GL_FRONT:
-        case GL_BACK:
-        case GL_FRONT_AND_BACK:
+        case CullFaceMode::Front:
+        case CullFaceMode::Back:
+        case CullFaceMode::FrontAndBack:
             break;
 
         default:
diff --git a/src/libANGLE/validationES2.h b/src/libANGLE/validationES2.h
index efb50c9..aa8dac9 100644
--- a/src/libANGLE/validationES2.h
+++ b/src/libANGLE/validationES2.h
@@ -9,6 +9,8 @@
 #ifndef LIBANGLE_VALIDATION_ES2_H_
 #define LIBANGLE_VALIDATION_ES2_H_
 
+#include "libANGLE/PackedGLEnums.h"
+
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
@@ -348,7 +350,7 @@
                         GLenum target,
                         GLsizeiptr size,
                         const void *data,
-                        GLenum usage);
+                        BufferUsage usage);
 bool ValidateBufferSubData(ValidationContext *context,
                            GLenum target,
                            GLintptr offset,
@@ -418,7 +420,7 @@
                        GLboolean alpha);
 bool ValidateCompileShader(ValidationContext *context, GLuint shader);
 bool ValidateCreateProgram(ValidationContext *context);
-bool ValidateCullFace(ValidationContext *context, GLenum mode);
+bool ValidateCullFace(ValidationContext *context, CullFaceMode mode);
 bool ValidateDeleteProgram(ValidationContext *context, GLuint program);
 bool ValidateDeleteShader(ValidationContext *context, GLuint shader);
 bool ValidateDepthFunc(ValidationContext *context, GLenum func);
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 8d3cdc8..055e5ef 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -169,6 +169,9 @@
             'libANGLE/LoggingAnnotator.h',
             'libANGLE/MemoryProgramCache.cpp',
             'libANGLE/MemoryProgramCache.h',
+            'libANGLE/PackedGLEnums.h',
+            'libANGLE/PackedGLEnums_autogen.cpp',
+            'libANGLE/PackedGLEnums_autogen.h',
             'libANGLE/Path.h',
             'libANGLE/Path.cpp',
             'libANGLE/Platform.cpp',
diff --git a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
index f4a7ec8..a249a9c 100644
--- a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -226,11 +226,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BufferData>(target, size, data, usage);
+        BufferUsage usagePacked = FromGLenum<BufferUsage>(usage);
+        context->gatherParams<EntryPoint::BufferData>(target, size, data, usagePacked);
 
-        if (context->skipValidation() || ValidateBufferData(context, target, size, data, usage))
+        if (context->skipValidation() ||
+            ValidateBufferData(context, target, size, data, usagePacked))
         {
-            context->bufferData(target, size, data, usage);
+            context->bufferData(target, size, data, usagePacked);
         }
     }
 }
@@ -533,11 +535,12 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CullFace>(mode);
+        CullFaceMode modePacked = FromGLenum<CullFaceMode>(mode);
+        context->gatherParams<EntryPoint::CullFace>(modePacked);
 
-        if (context->skipValidation() || ValidateCullFace(context, mode))
+        if (context->skipValidation() || ValidateCullFace(context, modePacked))
         {
-            context->cullFace(mode);
+            context->cullFace(modePacked);
         }
     }
 }
diff --git a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
index 8818cbc..f04d998 100644
--- a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
+++ b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
@@ -38,7 +38,7 @@
         mSourceBuffer      = new rx::Buffer11(mBufferState, mRenderer);
         GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
         gl::Error error    = mSourceBuffer->setData(nullptr, GL_ARRAY_BUFFER, testData,
-                                                 sizeof(testData), GL_STATIC_DRAW);
+                                                 sizeof(testData), gl::BufferUsage::StaticDraw);
         ASSERT_FALSE(error.isError());
 
         mTranslatedAttribute.baseOffset            = 0;
diff --git a/src/tests/perf_tests/IndexDataManagerTest.cpp b/src/tests/perf_tests/IndexDataManagerTest.cpp
index bd105d7..99ed580 100644
--- a/src/tests/perf_tests/IndexDataManagerTest.cpp
+++ b/src/tests/perf_tests/IndexDataManagerTest.cpp
@@ -82,7 +82,7 @@
                       GLenum target,
                       const void *data,
                       size_t size,
-                      GLenum) override
+                      gl::BufferUsage) override
     {
         mData.resize(size);
         if (data && size > 0)
@@ -168,7 +168,7 @@
     }
     EXPECT_FALSE(mIndexBuffer
                      .bufferData(nullptr, GL_ARRAY_BUFFER, &indexData[0],
-                                 indexData.size() * sizeof(GLushort), GL_STATIC_DRAW)
+                                 indexData.size() * sizeof(GLushort), gl::BufferUsage::StaticDraw)
                      .isError());
 }