Use a packed enum for buffer targets.

BUG=angleproject:2169

Change-Id: I4e08973d0e16404b7b8ee2f119e29ac502e28669
Reviewed-on: https://chromium-review.googlesource.com/723865
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/scripts/entry_point_packed_gl_enums.json b/scripts/entry_point_packed_gl_enums.json
index 28fcb6f..1b747d9 100644
--- a/scripts/entry_point_packed_gl_enums.json
+++ b/scripts/entry_point_packed_gl_enums.json
@@ -1,8 +1,70 @@
 {
+    "glBindBuffer": {
+        "target": "BufferBinding"
+    },
+    "glBindBufferBase": {
+        "target": "BufferBinding"
+    },
+    "glBindBufferRange": {
+        "target": "BufferBinding"
+    },
     "glBufferData": {
+        "target": "BufferBinding",
         "usage": "BufferUsage"
     },
+    "glBufferSubData": {
+        "target": "BufferBinding"
+    },
+    "glCopyBufferSubData": {
+        "readTarget": "BufferBinding",
+        "writeTarget": "BufferBinding"
+    },
     "glCullFace": {
         "mode": "CullFaceMode"
+    },
+    "glFlushMappedBufferRange": {
+        "target": "BufferBinding"
+    },
+    "glFlushMappedBufferRangeEXT": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferParameteriv": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferParameterivRobustANGLE": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferParameteri64v": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferParameteri64vRobustANGLE": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferPointerv": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferPointervOES": {
+        "target": "BufferBinding"
+    },
+    "glGetBufferPointervRobustANGLE": {
+        "target": "BufferBinding"
+    },
+    "glMapBuffer": {
+        "target": "BufferBinding"
+    },
+    "glMapBufferOES": {
+        "target": "BufferBinding"
+    },
+    "glMapBufferRange": {
+        "target": "BufferBinding"
+    },
+    "glMapBufferRangeEXT": {
+        "target": "BufferBinding"
+    },
+    "glUnmapBuffer": {
+        "target": "BufferBinding"
+    },
+    "glUnmapBufferOES": {
+        "target": "BufferBinding"
     }
 }
diff --git a/src/libANGLE/Buffer.cpp b/src/libANGLE/Buffer.cpp
index ca0528e..a1ebfc1 100644
--- a/src/libANGLE/Buffer.cpp
+++ b/src/libANGLE/Buffer.cpp
@@ -63,7 +63,7 @@
 }
 
 Error Buffer::bufferData(const Context *context,
-                         GLenum target,
+                         BufferBinding target,
                          const void *data,
                          GLsizeiptr size,
                          BufferUsage usage)
@@ -90,7 +90,7 @@
 }
 
 Error Buffer::bufferSubData(const Context *context,
-                            GLenum target,
+                            BufferBinding target,
                             const void *data,
                             GLsizeiptr size,
                             GLintptr offset)
diff --git a/src/libANGLE/Buffer.h b/src/libANGLE/Buffer.h
index da4a2da..86d4a9f 100644
--- a/src/libANGLE/Buffer.h
+++ b/src/libANGLE/Buffer.h
@@ -72,12 +72,12 @@
     const std::string &getLabel() const override;
 
     Error bufferData(const Context *context,
-                     GLenum target,
+                     BufferBinding target,
                      const void *data,
                      GLsizeiptr size,
                      BufferUsage usage);
     Error bufferSubData(const Context *context,
-                        GLenum target,
+                        BufferBinding target,
                         const void *data,
                         GLsizeiptr size,
                         GLintptr offset);
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 337cb9d..5604dbd 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -305,7 +305,7 @@
     mFenceNVHandleAllocator.setBaseHandle(0);
 
     // [OpenGL ES 2.0.24] section 3.7 page 83:
-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
     // and cube map texture state vectors respectively associated with them.
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
@@ -331,16 +331,14 @@
             new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
         mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
 
-        bindGenericAtomicCounterBuffer(0);
         for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
         {
-            bindIndexedAtomicCounterBuffer(0, i, 0, 0);
+            bindBufferRange(BufferBinding::AtomicCounter, 0, i, 0, 0);
         }
 
-        bindGenericShaderStorageBuffer(0);
         for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
         {
-            bindIndexedShaderStorageBuffer(0, i, 0, 0);
+            bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0);
         }
     }
 
@@ -362,22 +360,6 @@
     mGLState.initializeZeroTextures(this, mZeroTextures);
 
     bindVertexArray(0);
-    bindArrayBuffer(0);
-    bindDrawIndirectBuffer(0);
-    bindElementArrayBuffer(0);
-
-    bindRenderbuffer(GL_RENDERBUFFER, 0);
-
-    bindGenericUniformBuffer(0);
-    for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
-    {
-        bindIndexedUniformBuffer(0, i, 0, -1);
-    }
-
-    bindCopyReadBuffer(0);
-    bindCopyWriteBuffer(0);
-    bindPixelPackBuffer(0);
-    bindPixelUnpackBuffer(0);
 
     if (getClientVersion() >= Version(3, 0))
     {
@@ -388,6 +370,18 @@
         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
     }
 
+    for (auto type : angle::AllEnums<BufferBinding>())
+    {
+        bindBuffer(type, 0);
+    }
+
+    bindRenderbuffer(GL_RENDERBUFFER, 0);
+
+    for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
+    {
+        bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1);
+    }
+
     // Initialize dirty bit masks
     mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
     mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
@@ -936,24 +930,6 @@
     return mState.mSamplers->isSampler(samplerName);
 }
 
-void Context::bindArrayBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setArrayBufferBinding(this, buffer);
-}
-
-void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setDrawIndirectBufferBinding(this, buffer);
-}
-
-void Context::bindElementArrayBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setElementArrayBuffer(this, buffer);
-}
-
 void Context::bindTexture(GLenum target, GLuint handle)
 {
     Texture *texture = nullptr;
@@ -1020,90 +996,6 @@
     mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
 }
 
-void Context::bindGenericUniformBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericUniformBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
-                                       GLuint index,
-                                       GLintptr offset,
-                                       GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
-}
-
-void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
-                                                 GLuint index,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
-                                             GLuint index,
-                                             GLintptr offset,
-                                             GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setGenericShaderStorageBufferBinding(this, buffer);
-}
-
-void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
-                                             GLuint index,
-                                             GLintptr offset,
-                                             GLsizeiptr size)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
-}
-
-void Context::bindCopyReadBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setCopyReadBufferBinding(this, buffer);
-}
-
-void Context::bindCopyWriteBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setCopyWriteBufferBinding(this, buffer);
-}
-
-void Context::bindPixelPackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setPixelPackBufferBinding(this, buffer);
-}
-
-void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
-{
-    Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
-    mGLState.setPixelUnpackBufferBinding(this, buffer);
-}
-
 void Context::useProgram(GLuint program)
 {
     mGLState.setProgram(this, getProgram(program));
@@ -1724,7 +1616,7 @@
     }
 }
 
-void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteriv(buffer, pname, params);
@@ -3471,7 +3363,7 @@
     handleError(destTexture->copyCompressedTexture(this, sourceTexture));
 }
 
-void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
+void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
@@ -3479,7 +3371,7 @@
     QueryBufferPointerv(buffer, pname, params);
 }
 
-void *Context::mapBuffer(GLenum target, GLenum access)
+void *Context::mapBuffer(BufferBinding target, GLenum access)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
@@ -3494,7 +3386,7 @@
     return buffer->getMapPointer();
 }
 
-GLboolean Context::unmapBuffer(GLenum target)
+GLboolean Context::unmapBuffer(BufferBinding target)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
@@ -3510,7 +3402,10 @@
     return result;
 }
 
-void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+void *Context::mapBufferRange(BufferBinding target,
+                              GLintptr offset,
+                              GLsizeiptr length,
+                              GLbitfield access)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
@@ -3525,7 +3420,9 @@
     return buffer->getMapPointer();
 }
 
-void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
+void Context::flushMappedBufferRange(BufferBinding /*target*/,
+                                     GLintptr /*offset*/,
+                                     GLsizeiptr /*length*/)
 {
     // We do not currently support a non-trivial implementation of FlushMappedBufferRange
 }
@@ -3843,8 +3740,8 @@
                                   GLsizei stride,
                                   const void *ptr)
 {
-    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
-                                    type, normalized == GL_TRUE, false, stride, ptr);
+    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+                                    size, type, normalized == GL_TRUE, false, stride, ptr);
 }
 
 void Context::vertexAttribFormat(GLuint attribIndex,
@@ -3886,8 +3783,8 @@
                                    GLsizei stride,
                                    const void *pointer)
 {
-    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
-                                    type, false, true, stride, pointer);
+    mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
+                                    size, type, false, true, stride, pointer);
 }
 
 void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
@@ -4006,14 +3903,17 @@
     mGLState.getDebug().popGroup();
 }
 
-void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, BufferUsage usage)
+void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     ASSERT(buffer);
     handleError(buffer->bufferData(this, target, data, size, usage));
 }
 
-void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+void Context::bufferSubData(BufferBinding target,
+                            GLintptr offset,
+                            GLsizeiptr size,
+                            const void *data)
 {
     if (data == nullptr)
     {
@@ -4038,8 +3938,8 @@
     return mWorkarounds;
 }
 
-void Context::copyBufferSubData(GLenum readTarget,
-                                GLenum writeTarget,
+void Context::copyBufferSubData(BufferBinding readTarget,
+                                BufferBinding writeTarget,
                                 GLintptr readOffset,
                                 GLintptr writeOffset,
                                 GLsizeiptr size)
@@ -4065,90 +3965,25 @@
     programObject->bindAttributeLocation(index, name);
 }
 
-void Context::bindBuffer(GLenum target, GLuint buffer)
+void Context::bindBuffer(BufferBinding target, GLuint buffer)
 {
-    switch (target)
-    {
-        case GL_ARRAY_BUFFER:
-            bindArrayBuffer(buffer);
-            break;
-        case GL_ELEMENT_ARRAY_BUFFER:
-            bindElementArrayBuffer(buffer);
-            break;
-        case GL_COPY_READ_BUFFER:
-            bindCopyReadBuffer(buffer);
-            break;
-        case GL_COPY_WRITE_BUFFER:
-            bindCopyWriteBuffer(buffer);
-            break;
-        case GL_PIXEL_PACK_BUFFER:
-            bindPixelPackBuffer(buffer);
-            break;
-        case GL_PIXEL_UNPACK_BUFFER:
-            bindPixelUnpackBuffer(buffer);
-            break;
-        case GL_UNIFORM_BUFFER:
-            bindGenericUniformBuffer(buffer);
-            break;
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-            bindGenericTransformFeedbackBuffer(buffer);
-            break;
-        case GL_ATOMIC_COUNTER_BUFFER:
-            bindGenericAtomicCounterBuffer(buffer);
-            break;
-        case GL_SHADER_STORAGE_BUFFER:
-            bindGenericShaderStorageBuffer(buffer);
-            break;
-        case GL_DRAW_INDIRECT_BUFFER:
-            bindDrawIndirectBuffer(buffer);
-            break;
-        case GL_DISPATCH_INDIRECT_BUFFER:
-            if (buffer != 0)
-            {
-                // Binding buffers to this binding point is not implemented yet.
-                UNIMPLEMENTED();
-            }
-            break;
-
-        default:
-            UNREACHABLE();
-            break;
-    }
+    Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+    mGLState.setBufferBinding(this, target, bufferObject);
 }
 
-void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer)
 {
     bindBufferRange(target, index, buffer, 0, 0);
 }
 
-void Context::bindBufferRange(GLenum target,
+void Context::bindBufferRange(BufferBinding target,
                               GLuint index,
                               GLuint buffer,
                               GLintptr offset,
                               GLsizeiptr size)
 {
-    switch (target)
-    {
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-            bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
-            bindGenericTransformFeedbackBuffer(buffer);
-            break;
-        case GL_UNIFORM_BUFFER:
-            bindIndexedUniformBuffer(buffer, index, offset, size);
-            bindGenericUniformBuffer(buffer);
-            break;
-        case GL_ATOMIC_COUNTER_BUFFER:
-            bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
-            bindGenericAtomicCounterBuffer(buffer);
-            break;
-        case GL_SHADER_STORAGE_BUFFER:
-            bindIndexedShaderStorageBuffer(buffer, index, offset, size);
-            bindGenericShaderStorageBuffer(buffer);
-            break;
-        default:
-            UNREACHABLE();
-            break;
-    }
+    Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+    mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size);
 }
 
 void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
@@ -5299,7 +5134,7 @@
     }
 }
 
-void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
 {
     Buffer *buffer = mGLState.getTargetBuffer(target);
     QueryBufferParameteri64v(buffer, pname, params);
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index e29ab9b..40f554f 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -117,8 +117,6 @@
     GLuint createFenceNV();
     void deleteFenceNV(GLuint fence);
 
-    void bindArrayBuffer(GLuint bufferHandle);
-    void bindElementArrayBuffer(GLuint bufferHandle);
     void bindTexture(GLenum target, GLuint handle);
     void bindReadFramebuffer(GLuint framebufferHandle);
     void bindDrawFramebuffer(GLuint framebufferHandle);
@@ -135,33 +133,8 @@
                           GLint layer,
                           GLenum access,
                           GLenum format);
-    void bindGenericUniformBuffer(GLuint bufferHandle);
-    void bindIndexedUniformBuffer(GLuint bufferHandle,
-                                  GLuint index,
-                                  GLintptr offset,
-                                  GLsizeiptr size);
-    void bindGenericTransformFeedbackBuffer(GLuint bufferHandle);
-    void bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
-                                            GLuint index,
-                                            GLintptr offset,
-                                            GLsizeiptr size);
-    void bindGenericAtomicCounterBuffer(GLuint bufferHandle);
-    void bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
-                                        GLuint index,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
-    void bindGenericShaderStorageBuffer(GLuint bufferHandle);
-    void bindIndexedShaderStorageBuffer(GLuint bufferHandle,
-                                        GLuint index,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
-    void bindCopyReadBuffer(GLuint bufferHandle);
-    void bindCopyWriteBuffer(GLuint bufferHandle);
-    void bindPixelPackBuffer(GLuint bufferHandle);
-    void bindPixelUnpackBuffer(GLuint bufferHandle);
     void useProgram(GLuint program);
     void bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle);
-    void bindDrawIndirectBuffer(GLuint bufferHandle);
     void bindProgramPipeline(GLuint pipelineHandle);
 
     void beginQuery(GLenum target, GLuint query);
@@ -176,7 +149,7 @@
     void vertexAttribDivisor(GLuint index, GLuint divisor);
     void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
 
-    void getBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+    void getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params);
     void getFramebufferAttachmentParameteriv(GLenum target,
                                              GLenum attachment,
                                              GLenum pname,
@@ -577,11 +550,14 @@
     void flush();
     void finish();
 
-    void getBufferPointerv(GLenum target, GLenum pname, void **params);
-    void *mapBuffer(GLenum target, GLenum access);
-    GLboolean unmapBuffer(GLenum target);
-    void *mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
-    void flushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
+    void getBufferPointerv(BufferBinding target, GLenum pname, void **params);
+    void *mapBuffer(BufferBinding target, GLenum access);
+    GLboolean unmapBuffer(BufferBinding target);
+    void *mapBufferRange(BufferBinding target,
+                         GLintptr offset,
+                         GLsizeiptr length,
+                         GLbitfield access);
+    void flushMappedBufferRange(BufferBinding target, GLintptr offset, GLsizeiptr length);
 
     void beginTransformFeedback(GLenum primitiveMode);
 
@@ -668,13 +644,13 @@
                                      GLint components,
                                      const GLfloat *coeffs);
 
-    void bufferData(GLenum target, GLsizeiptr size, const void *data, BufferUsage usage);
-    void bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+    void bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage);
+    void bufferSubData(BufferBinding target, GLintptr offset, GLsizeiptr size, const void *data);
     void attachShader(GLuint program, GLuint shader);
     void bindAttribLocation(GLuint program, GLuint index, const GLchar *name);
-    void bindBuffer(GLenum target, GLuint buffer);
-    void bindBufferBase(GLenum target, GLuint index, GLuint buffer);
-    void bindBufferRange(GLenum target,
+    void bindBuffer(BufferBinding target, GLuint buffer);
+    void bindBufferBase(BufferBinding target, GLuint index, GLuint buffer);
+    void bindBufferRange(BufferBinding target,
                          GLuint index,
                          GLuint buffer,
                          GLintptr offset,
@@ -691,8 +667,8 @@
 
     void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
 
-    void copyBufferSubData(GLenum readTarget,
-                           GLenum writeTarget,
+    void copyBufferSubData(BufferBinding readTarget,
+                           BufferBinding writeTarget,
                            GLintptr readOffset,
                            GLintptr writeOffset,
                            GLsizeiptr size);
@@ -876,7 +852,7 @@
     void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
     void getInteger64v(GLenum pname, GLint64 *params);
 
-    void getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+    void getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params);
     void genSamplers(GLsizei count, GLuint *samplers);
     void deleteSamplers(GLsizei count, const GLuint *samplers);
     void getInternalformativ(GLenum target,
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 823f3d0..0ebaba9 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -1368,7 +1368,7 @@
     ANGLE_TRY(ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
     ANGLE_TRY(mImpl->readPixels(context, area, format, type, pixels));
 
-    Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    Buffer *unpackBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (unpackBuffer)
     {
         unpackBuffer->onPixelUnpack();
diff --git a/src/libANGLE/PackedGLEnums.h b/src/libANGLE/PackedGLEnums.h
index b02525b..70e3291 100644
--- a/src/libANGLE/PackedGLEnums.h
+++ b/src/libANGLE/PackedGLEnums.h
@@ -11,4 +11,101 @@
 
 #include "libANGLE/PackedGLEnums_autogen.h"
 
+#include <array>
+#include <cstddef>
+
+namespace angle
+{
+
+template <typename E>
+class EnumIterator final
+{
+  private:
+    using UnderlyingType = typename std::underlying_type<E>::type;
+
+  public:
+    EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {}
+    EnumIterator &operator++()
+    {
+        mValue++;
+        return *this;
+    }
+    bool operator==(const EnumIterator &other) const { return mValue == other.mValue; }
+    bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; }
+    E operator*() const { return static_cast<E>(mValue); }
+
+  private:
+    UnderlyingType mValue;
+};
+
+template <typename E>
+struct AllEnums
+{
+    EnumIterator<E> begin() const { return {static_cast<E>(0)}; }
+    EnumIterator<E> end() const { return {E::InvalidEnum}; }
+};
+
+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>;
+
+    Storage mData;
+
+  public:
+    // types:
+    using value_type      = T;
+    using pointer         = T *;
+    using const_pointer   = const T *;
+    using reference       = T &;
+    using const_reference = const T &;
+
+    using size_type       = size_t;
+    using difference_type = ptrdiff_t;
+
+    using iterator               = typename Storage::iterator;
+    using const_iterator         = typename Storage::const_iterator;
+    using reverse_iterator       = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+    // No explicit construct/copy/destroy for aggregate type
+    void fill(const T &u) { mData.fill(u); }
+    void swap(PackedEnumMap<E, T> &a) noexcept { mData.swap(a.mData); }
+
+    // iterators:
+    iterator begin() noexcept { return mData.begin(); }
+    const_iterator begin() const noexcept { return mData.begin(); }
+    iterator end() noexcept { return mData.end(); }
+    const_iterator end() const noexcept { return mData.end(); }
+
+    reverse_iterator rbegin() noexcept { return mData.rbegin(); }
+    const_reverse_iterator rbegin() const noexcept { return mData.rbegin(); }
+    reverse_iterator rend() noexcept { return mData.rend(); }
+    const_reverse_iterator rend() const noexcept { return mData.rend(); }
+
+    // capacity:
+    constexpr size_type size() const noexcept { return mData.size(); }
+    constexpr size_type max_size() const noexcept { return mData.max_size(); }
+    constexpr bool empty() const noexcept { return mData.empty(); }
+
+    // element access:
+    reference operator[](E n) { return mData[static_cast<UnderlyingType>(n)]; }
+    const_reference operator[](E n) const { return mData[static_cast<UnderlyingType>(n)]; }
+    const_reference at(E n) const { return mData.at(static_cast<UnderlyingType>(n)); }
+    reference at(E n) { return mData.at(static_cast<UnderlyingType>(n)); }
+
+    reference front() { return mData.front(); }
+    const_reference front() const { return mData.front(); }
+    reference back() { return mData.back(); }
+    const_reference back() const { return mData.back(); }
+
+    T *data() noexcept { return mData.data(); }
+    const T *data() const noexcept { return mData.data(); }
+};
+
+}  // namespace angle
+
 #endif  // LIBANGLE_PACKEDGLENUMS_H_
diff --git a/src/libANGLE/PackedGLEnums_autogen.cpp b/src/libANGLE/PackedGLEnums_autogen.cpp
index 257580b..9a58069 100644
--- a/src/libANGLE/PackedGLEnums_autogen.cpp
+++ b/src/libANGLE/PackedGLEnums_autogen.cpp
@@ -1,5 +1,5 @@
 // GENERATED FILE - DO NOT EDIT.
-// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+// 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
@@ -16,6 +16,74 @@
 {
 
 template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from)
+{
+    switch (from)
+    {
+        case GL_ARRAY_BUFFER:
+            return BufferBinding::Array;
+        case GL_ATOMIC_COUNTER_BUFFER:
+            return BufferBinding::AtomicCounter;
+        case GL_COPY_READ_BUFFER:
+            return BufferBinding::CopyRead;
+        case GL_COPY_WRITE_BUFFER:
+            return BufferBinding::CopyWrite;
+        case GL_DISPATCH_INDIRECT_BUFFER:
+            return BufferBinding::DispatchIndirect;
+        case GL_DRAW_INDIRECT_BUFFER:
+            return BufferBinding::DrawIndirect;
+        case GL_ELEMENT_ARRAY_BUFFER:
+            return BufferBinding::ElementArray;
+        case GL_PIXEL_PACK_BUFFER:
+            return BufferBinding::PixelPack;
+        case GL_PIXEL_UNPACK_BUFFER:
+            return BufferBinding::PixelUnpack;
+        case GL_SHADER_STORAGE_BUFFER:
+            return BufferBinding::ShaderStorage;
+        case GL_TRANSFORM_FEEDBACK_BUFFER:
+            return BufferBinding::TransformFeedback;
+        case GL_UNIFORM_BUFFER:
+            return BufferBinding::Uniform;
+        default:
+            return BufferBinding::InvalidEnum;
+    }
+}
+
+GLenum ToGLenum(BufferBinding from)
+{
+    switch (from)
+    {
+        case BufferBinding::Array:
+            return GL_ARRAY_BUFFER;
+        case BufferBinding::AtomicCounter:
+            return GL_ATOMIC_COUNTER_BUFFER;
+        case BufferBinding::CopyRead:
+            return GL_COPY_READ_BUFFER;
+        case BufferBinding::CopyWrite:
+            return GL_COPY_WRITE_BUFFER;
+        case BufferBinding::DispatchIndirect:
+            return GL_DISPATCH_INDIRECT_BUFFER;
+        case BufferBinding::DrawIndirect:
+            return GL_DRAW_INDIRECT_BUFFER;
+        case BufferBinding::ElementArray:
+            return GL_ELEMENT_ARRAY_BUFFER;
+        case BufferBinding::PixelPack:
+            return GL_PIXEL_PACK_BUFFER;
+        case BufferBinding::PixelUnpack:
+            return GL_PIXEL_UNPACK_BUFFER;
+        case BufferBinding::ShaderStorage:
+            return GL_SHADER_STORAGE_BUFFER;
+        case BufferBinding::TransformFeedback:
+            return GL_TRANSFORM_FEEDBACK_BUFFER;
+        case BufferBinding::Uniform:
+            return GL_UNIFORM_BUFFER;
+        default:
+            UNREACHABLE();
+            return GL_NONE;
+    }
+}
+
+template <>
 BufferUsage FromGLenum<BufferUsage>(GLenum from)
 {
     switch (from)
diff --git a/src/libANGLE/PackedGLEnums_autogen.h b/src/libANGLE/PackedGLEnums_autogen.h
index de2380f..fb4b337 100644
--- a/src/libANGLE/PackedGLEnums_autogen.h
+++ b/src/libANGLE/PackedGLEnums_autogen.h
@@ -1,5 +1,5 @@
 // GENERATED FILE - DO NOT EDIT.
-// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+// 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
@@ -12,9 +12,7 @@
 #ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
 #define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
+#include <angle_gl.h>
 
 #include <cstdint>
 
@@ -24,6 +22,29 @@
 template <typename Enum>
 Enum FromGLenum(GLenum from);
 
+enum class BufferBinding : uint8_t
+{
+    Array             = 0,
+    AtomicCounter     = 1,
+    CopyRead          = 2,
+    CopyWrite         = 3,
+    DispatchIndirect  = 4,
+    DrawIndirect      = 5,
+    ElementArray      = 6,
+    PixelPack         = 7,
+    PixelUnpack       = 8,
+    ShaderStorage     = 9,
+    TransformFeedback = 10,
+    Uniform           = 11,
+
+    InvalidEnum = 12,
+    EnumCount   = 12,
+};
+
+template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from);
+GLenum ToGLenum(BufferBinding from);
+
 enum class BufferUsage : uint8_t
 {
     DynamicCopy = 0,
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index a0c44ad..1ceed3f 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -234,10 +234,13 @@
         imageUnit.format  = GL_R32UI;
     }
 
-    mArrayBuffer.set(context, nullptr);
-    mDrawIndirectBuffer.set(context, nullptr);
     mRenderbuffer.set(context, nullptr);
 
+    for (auto type : angle::AllEnums<BufferBinding>())
+    {
+        mBoundBuffers[type].set(context, nullptr);
+    }
+
     if (mProgram)
     {
         mProgram->release(context);
@@ -253,25 +256,16 @@
         i->second.set(context, nullptr);
     }
 
-    mGenericUniformBuffer.set(context, nullptr);
-    for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
+    for (auto &buf : mUniformBuffers)
     {
-        bufItr->set(context, nullptr);
+        buf.set(context, nullptr);
     }
 
-    mCopyReadBuffer.set(context, nullptr);
-    mCopyWriteBuffer.set(context, nullptr);
-
-    mPixelPackBuffer.set(context, nullptr);
-    mPixelUnpackBuffer.set(context, nullptr);
-
-    mGenericAtomicCounterBuffer.set(context, nullptr);
     for (auto &buf : mAtomicCounterBuffers)
     {
         buf.set(context, nullptr);
     }
 
-    mGenericShaderStorageBuffer.set(context, nullptr);
     for (auto &buf : mShaderStorageBuffers)
     {
         buf.set(context, nullptr);
@@ -1098,12 +1092,6 @@
     return false;
 }
 
-void State::setElementArrayBuffer(const Context *context, Buffer *buffer)
-{
-    getVertexArray()->setElementArrayBuffer(context, buffer);
-    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
-}
-
 void State::bindVertexBuffer(const Context *context,
                              GLuint bindingIndex,
                              Buffer *boundBuffer,
@@ -1250,34 +1238,62 @@
     return it->second.get();
 }
 
-void State::setArrayBufferBinding(const Context *context, Buffer *buffer)
+void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
 {
-    mArrayBuffer.set(context, buffer);
-}
+    mBoundBuffers[target].set(context, buffer);
 
-GLuint State::getArrayBufferId() const
-{
-    return mArrayBuffer.id();
+    switch (target)
+    {
+        case BufferBinding::PixelPack:
+            mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
+            break;
+        case BufferBinding::PixelUnpack:
+            mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
+            break;
+        case BufferBinding::DrawIndirect:
+            mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
+            break;
+        case BufferBinding::TransformFeedback:
+            if (mTransformFeedback.get() != nullptr)
+            {
+                mTransformFeedback->bindGenericBuffer(context, buffer);
+            }
+            break;
+        case BufferBinding::ElementArray:
+            getVertexArray()->setElementArrayBuffer(context, buffer);
+            mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+            break;
+        default:
+            break;
+    }
 }
-
-void State::setDrawIndirectBufferBinding(const Context *context, Buffer *buffer)
+void State::setIndexedBufferBinding(const Context *context,
+                                    BufferBinding target,
+                                    GLuint index,
+                                    Buffer *buffer,
+                                    GLintptr offset,
+                                    GLsizeiptr size)
 {
-    mDrawIndirectBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
-}
+    setBufferBinding(context, target, buffer);
 
-void State::setGenericUniformBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericUniformBuffer.set(context, buffer);
-}
-
-void State::setIndexedUniformBufferBinding(const Context *context,
-                                           GLuint index,
-                                           Buffer *buffer,
-                                           GLintptr offset,
-                                           GLsizeiptr size)
-{
-    mUniformBuffers[index].set(context, buffer, offset, size);
+    switch (target)
+    {
+        case BufferBinding::TransformFeedback:
+            mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size);
+            break;
+        case BufferBinding::Uniform:
+            mUniformBuffers[index].set(context, buffer, offset, size);
+            break;
+        case BufferBinding::AtomicCounter:
+            mAtomicCounterBuffers[index].set(context, buffer, offset, size);
+            break;
+        case BufferBinding::ShaderStorage:
+            mShaderStorageBuffers[index].set(context, buffer, offset, size);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
 }
 
 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
@@ -1286,107 +1302,38 @@
     return mUniformBuffers[index];
 }
 
-void State::setGenericAtomicCounterBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericAtomicCounterBuffer.set(context, buffer);
-}
-
-void State::setIndexedAtomicCounterBufferBinding(const Context *context,
-                                                 GLuint index,
-                                                 Buffer *buffer,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
-    mAtomicCounterBuffers[index].set(context, buffer, offset, size);
-}
-
 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
 {
     ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
     return mAtomicCounterBuffers[index];
 }
 
-void State::setGenericShaderStorageBufferBinding(const Context *context, Buffer *buffer)
-{
-    mGenericShaderStorageBuffer.set(context, buffer);
-}
-
-void State::setIndexedShaderStorageBufferBinding(const Context *context,
-                                                 GLuint index,
-                                                 Buffer *buffer,
-                                                 GLintptr offset,
-                                                 GLsizeiptr size)
-{
-    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
-    mShaderStorageBuffers[index].set(context, buffer, offset, size);
-}
-
 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
 {
     ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
     return mShaderStorageBuffers[index];
 }
 
-void State::setCopyReadBufferBinding(const Context *context, Buffer *buffer)
-{
-    mCopyReadBuffer.set(context, buffer);
-}
-
-void State::setCopyWriteBufferBinding(const Context *context, Buffer *buffer)
-{
-    mCopyWriteBuffer.set(context, buffer);
-}
-
-void State::setPixelPackBufferBinding(const Context *context, Buffer *buffer)
-{
-    mPixelPackBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
-}
-
-void State::setPixelUnpackBufferBinding(const Context *context, Buffer *buffer)
-{
-    mPixelUnpackBuffer.set(context, buffer);
-    mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
-}
-
-Buffer *State::getTargetBuffer(GLenum target) const
+Buffer *State::getTargetBuffer(BufferBinding target) const
 {
     switch (target)
     {
-      case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
-      case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
-      case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
-      case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer().get();
-      case GL_PIXEL_PACK_BUFFER:
-          return mPixelPackBuffer.get();
-      case GL_PIXEL_UNPACK_BUFFER:
-          return mPixelUnpackBuffer.get();
-      case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
-      case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
-      case GL_ATOMIC_COUNTER_BUFFER:
-          return mGenericAtomicCounterBuffer.get();
-      case GL_SHADER_STORAGE_BUFFER:
-          return mGenericShaderStorageBuffer.get();
-      case GL_DRAW_INDIRECT_BUFFER:
-          return mDrawIndirectBuffer.get();
-      default:
-          UNREACHABLE();
-          return nullptr;
+        case BufferBinding::ElementArray:
+            return getVertexArray()->getElementArrayBuffer().get();
+        case BufferBinding::TransformFeedback:
+            return mTransformFeedback->getGenericBuffer().get();
+        default:
+            return mBoundBuffers[target].get();
     }
 }
 
 void State::detachBuffer(const Context *context, GLuint bufferName)
 {
-    BindingPointer<Buffer> *buffers[] = {
-        &mArrayBuffer,       &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
-        &mCopyWriteBuffer,   &mDrawIndirectBuffer,         &mPixelPackBuffer,
-        &mPixelUnpackBuffer, &mGenericUniformBuffer,       &mGenericShaderStorageBuffer};
-    for (auto buffer : buffers)
+    for (auto &buffer : mBoundBuffers)
     {
-        if (buffer->id() == bufferName)
+        if (buffer.id() == bufferName)
         {
-            buffer->set(context, nullptr);
+            buffer.set(context, nullptr);
         }
     }
 
@@ -1819,11 +1766,15 @@
     // State::getFloatv.
     switch (pname)
     {
-      case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
-      case GL_DRAW_INDIRECT_BUFFER_BINDING:
-          *params = mDrawIndirectBuffer.id();
-          break;
-      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBuffer().id(); break;
+        case GL_ARRAY_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::Array].id();
+            break;
+        case GL_DRAW_INDIRECT_BUFFER_BINDING:
+            *params = mBoundBuffers[BufferBinding::DrawIndirect].id();
+            break;
+        case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+            *params = getVertexArray()->getElementArrayBuffer().id();
+            break;
         //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
@@ -2031,25 +1982,26 @@
                                         GL_TEXTURE_EXTERNAL_OES);
           break;
       case GL_UNIFORM_BUFFER_BINDING:
-        *params = mGenericUniformBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::Uniform].id();
+          break;
       case GL_TRANSFORM_FEEDBACK_BINDING:
         *params = mTransformFeedback.id();
         break;
       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        *params = mTransformFeedback->getGenericBuffer().id();
-        break;
+          ASSERT(mTransformFeedback.get() != nullptr);
+          *params = mTransformFeedback->getGenericBuffer().id();
+          break;
       case GL_COPY_READ_BUFFER_BINDING:
-        *params = mCopyReadBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::CopyRead].id();
+          break;
       case GL_COPY_WRITE_BUFFER_BINDING:
-        *params = mCopyWriteBuffer.id();
-        break;
+          *params = mBoundBuffers[BufferBinding::CopyWrite].id();
+          break;
       case GL_PIXEL_PACK_BUFFER_BINDING:
-          *params = mPixelPackBuffer.id();
+          *params = mBoundBuffers[BufferBinding::PixelPack].id();
           break;
       case GL_PIXEL_UNPACK_BUFFER_BINDING:
-          *params = mPixelUnpackBuffer.id();
+          *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
           break;
       case GL_READ_BUFFER:
           *params = mReadFramebuffer->getReadBufferState();
@@ -2076,10 +2028,10 @@
           *params = static_cast<GLint>(mCoverageModulation);
           break;
       case GL_ATOMIC_COUNTER_BUFFER_BINDING:
-          *params = mGenericAtomicCounterBuffer.id();
+          *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
           break;
       case GL_SHADER_STORAGE_BUFFER_BINDING:
-          *params = mGenericShaderStorageBuffer.id();
+          *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
           break;
       default:
         UNREACHABLE();
@@ -2196,9 +2148,9 @@
     UNREACHABLE();
 }
 
-bool State::hasMappedBuffer(GLenum target) const
+bool State::hasMappedBuffer(BufferBinding target) const
 {
-    if (target == GL_ARRAY_BUFFER)
+    if (target == BufferBinding::Array)
     {
         const VertexArray *vao     = getVertexArray();
         const auto &vertexAttribs = vao->getVertexAttributes();
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index e3a5b1e..df4c25f 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -230,50 +230,19 @@
     void detachProgramPipeline(const Context *context, GLuint pipeline);
 
     //// Typed buffer binding point manipulation ////
-    // GL_ARRAY_BUFFER
-    void setArrayBufferBinding(const Context *context, Buffer *buffer);
-    GLuint getArrayBufferId() const;
+    void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer);
+    Buffer *getTargetBuffer(BufferBinding target) const;
+    void setIndexedBufferBinding(const Context *context,
+                                 BufferBinding target,
+                                 GLuint index,
+                                 Buffer *buffer,
+                                 GLintptr offset,
+                                 GLsizeiptr size);
 
-    void setDrawIndirectBufferBinding(const Context *context, Buffer *buffer);
-    Buffer *getDrawIndirectBuffer() const { return mDrawIndirectBuffer.get(); }
-
-    // GL_UNIFORM_BUFFER - Both indexed and generic targets
-    void setGenericUniformBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedUniformBufferBinding(const Context *context,
-                                        GLuint index,
-                                        Buffer *buffer,
-                                        GLintptr offset,
-                                        GLsizeiptr size);
     const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
-
-    // GL_ATOMIC_COUNTER_BUFFER - Both indexed and generic targets
-    void setGenericAtomicCounterBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedAtomicCounterBufferBinding(const Context *context,
-                                              GLuint index,
-                                              Buffer *buffer,
-                                              GLintptr offset,
-                                              GLsizeiptr size);
     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
-
-    // GL_SHADER_STORAGE_BUFFER - Both indexed and generic targets
-    void setGenericShaderStorageBufferBinding(const Context *context, Buffer *buffer);
-    void setIndexedShaderStorageBufferBinding(const Context *context,
-                                              GLuint index,
-                                              Buffer *buffer,
-                                              GLintptr offset,
-                                              GLsizeiptr size);
     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
 
-    // GL_COPY_[READ/WRITE]_BUFFER
-    void setCopyReadBufferBinding(const Context *context, Buffer *buffer);
-    void setCopyWriteBufferBinding(const Context *context, Buffer *buffer);
-
-    // GL_PIXEL[PACK/UNPACK]_BUFFER
-    void setPixelPackBufferBinding(const Context *context, Buffer *buffer);
-    void setPixelUnpackBufferBinding(const Context *context, Buffer *buffer);
-
-    // Retrieve typed buffer by target (non-indexed)
-    Buffer *getTargetBuffer(GLenum target) const;
     // Detach a buffer from all bindings
     void detachBuffer(const Context *context, GLuint bufferName);
 
@@ -369,7 +338,7 @@
     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data);
     void getBooleani_v(GLenum target, GLuint index, GLboolean *data);
 
-    bool hasMappedBuffer(GLenum target) const;
+    bool hasMappedBuffer(BufferBinding target) const;
     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
 
     // Sets the dirty bit for the program executable.
@@ -531,8 +500,6 @@
     float mNearZ;
     float mFarZ;
 
-    BindingPointer<Buffer> mArrayBuffer;
-    BindingPointer<Buffer> mDrawIndirectBuffer;
     Framebuffer *mReadFramebuffer;
     Framebuffer *mDrawFramebuffer;
     BindingPointer<Renderbuffer> mRenderbuffer;
@@ -579,20 +546,19 @@
     typedef std::map<GLenum, BindingPointer<Query>> ActiveQueryMap;
     ActiveQueryMap mActiveQueries;
 
-    BindingPointer<Buffer> mGenericUniformBuffer;
-    typedef std::vector<OffsetBindingPointer<Buffer>> BufferVector;
+    // Stores the currently bound buffer for each binding point. It has entries for the element
+    // array buffer and the transform feedback buffer but these should not be used. Instead these
+    // bind points are respectively owned by current the vertex array object and the current
+    // transform feedback object.
+    using BoundBufferMap = angle::PackedEnumMap<BufferBinding, BindingPointer<Buffer>>;
+    BoundBufferMap mBoundBuffers;
+
+    using BufferVector = std::vector<OffsetBindingPointer<Buffer>>;
     BufferVector mUniformBuffers;
-
-    BindingPointer<TransformFeedback> mTransformFeedback;
-
-    BindingPointer<Buffer> mGenericAtomicCounterBuffer;
     BufferVector mAtomicCounterBuffers;
-
-    BindingPointer<Buffer> mGenericShaderStorageBuffer;
     BufferVector mShaderStorageBuffers;
 
-    BindingPointer<Buffer> mCopyReadBuffer;
-    BindingPointer<Buffer> mCopyWriteBuffer;
+    BindingPointer<TransformFeedback> mTransformFeedback;
 
     BindingPointer<Buffer> mPixelUnpackBuffer;
     PixelUnpackState mUnpack;
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index 1684bc4..e8a1db3 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -57,7 +57,7 @@
         return InitState::Initialized;
 
     const auto &glState = context->getGLState();
-    return (pixels == nullptr && glState.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER) == nullptr)
+    return (pixels == nullptr && glState.getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
                ? InitState::MayNeedInit
                : InitState::Initialized;
 }
diff --git a/src/libANGLE/gen_packed_gl_enums.py b/src/libANGLE/gen_packed_gl_enums.py
index c9cb95d..562bf19 100644
--- a/src/libANGLE/gen_packed_gl_enums.py
+++ b/src/libANGLE/gen_packed_gl_enums.py
@@ -46,9 +46,7 @@
 #ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
 #define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
+#include <angle_gl.h>
 
 #include <cstdint>
 
diff --git a/src/libANGLE/packed_gl_enums.json b/src/libANGLE/packed_gl_enums.json
index 6de4f29..7e77de2 100644
--- a/src/libANGLE/packed_gl_enums.json
+++ b/src/libANGLE/packed_gl_enums.json
@@ -1,4 +1,19 @@
 {
+    "BufferBinding":
+    {
+        "Array": "GL_ARRAY_BUFFER",
+        "AtomicCounter": "GL_ATOMIC_COUNTER_BUFFER",
+        "CopyRead": "GL_COPY_READ_BUFFER",
+        "CopyWrite": "GL_COPY_WRITE_BUFFER",
+        "DispatchIndirect": "GL_DISPATCH_INDIRECT_BUFFER",
+        "DrawIndirect": "GL_DRAW_INDIRECT_BUFFER",
+        "ElementArray": "GL_ELEMENT_ARRAY_BUFFER",
+        "PixelPack": "GL_PIXEL_PACK_BUFFER",
+        "PixelUnpack": "GL_PIXEL_UNPACK_BUFFER",
+        "ShaderStorage": "GL_SHADER_STORAGE_BUFFER",
+        "TransformFeedback": "GL_TRANSFORM_FEEDBACK_BUFFER",
+        "Uniform": "GL_UNIFORM_BUFFER"
+    },
     "BufferUsage":
     {
         "DynamicCopy": "GL_DYNAMIC_COPY",
diff --git a/src/libANGLE/renderer/BufferImpl.h b/src/libANGLE/renderer/BufferImpl.h
index 581949d..f76fcdc 100644
--- a/src/libANGLE/renderer/BufferImpl.h
+++ b/src/libANGLE/renderer/BufferImpl.h
@@ -32,15 +32,15 @@
     virtual void destroy(const gl::Context *context) {}
 
     virtual gl::Error setData(const gl::Context *context,
-                              GLenum target,
+                              gl::BufferBinding target,
                               const void *data,
                               size_t size,
                               gl::BufferUsage usage)                                = 0;
     virtual gl::Error setSubData(const gl::Context *context,
-                                 GLenum target,
+                                 gl::BufferBinding target,
                                  const void *data,
                                  size_t size,
-                                 size_t offset) = 0;
+                                 size_t offset)                                     = 0;
     virtual gl::Error copySubData(const gl::Context *context,
                                   BufferImpl *source,
                                   GLintptr sourceOffset,
diff --git a/src/libANGLE/renderer/BufferImpl_mock.h b/src/libANGLE/renderer/BufferImpl_mock.h
index 9f18efc..5a4e210 100644
--- a/src/libANGLE/renderer/BufferImpl_mock.h
+++ b/src/libANGLE/renderer/BufferImpl_mock.h
@@ -22,9 +22,11 @@
     MockBufferImpl() : BufferImpl(mMockState) {}
     ~MockBufferImpl() { destructor(); }
 
-    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(
+        setData,
+        gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, gl::BufferUsage));
+    MOCK_METHOD5(setSubData,
+                 gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t));
     MOCK_METHOD5(
         copySubData,
         gl::Error(const gl::Context *contextImpl, BufferImpl *, GLintptr, GLintptr, GLsizeiptr));
diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 9ffcf7b..7611024 100644
--- a/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -216,7 +216,8 @@
                                    ptrdiff_t layerOffset)
 {
     ImageD3D *image = getImage(index);
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     ASSERT(image);
 
     // No-op
@@ -261,7 +262,8 @@
 {
     // CPU readback & copy where direct GPU copy is not supported
     const uint8_t *pixelData = nullptr;
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
@@ -299,7 +301,8 @@
     // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
     // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
     const uint8_t *pixelData = nullptr;
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
@@ -322,7 +325,8 @@
                                          ptrdiff_t layerOffset)
 {
     const uint8_t *pixelData = nullptr;
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
 
     if (pixelData != nullptr)
@@ -837,7 +841,8 @@
     gl::ImageIndex index = gl::ImageIndex::Make2D(level);
 
     // Attempt a fast gpu copy of the pixel data to the surface
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) &&
         isLevelComplete(level))
     {
@@ -878,7 +883,8 @@
     GLint level          = static_cast<GLint>(imageLevel);
     gl::ImageIndex index = gl::ImageIndex::Make2D(level);
 
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
     {
         RenderTargetD3D *renderTarget = nullptr;
@@ -2394,7 +2400,8 @@
     gl::ImageIndex index = gl::ImageIndex::Make3D(level);
 
     // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
         isLevelComplete(level))
     {
@@ -2436,7 +2443,8 @@
     gl::ImageIndex index = gl::ImageIndex::Make3D(level);
 
     // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
-    gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
     if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
     {
         RenderTargetD3D *destRenderTarget = nullptr;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index b748d2d..3765b27 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -318,7 +318,7 @@
 }
 
 gl::Error Buffer11::setData(const gl::Context *context,
-                            GLenum target,
+                            gl::BufferBinding target,
                             const void *data,
                             size_t size,
                             gl::BufferUsage usage)
@@ -348,7 +348,7 @@
 }
 
 gl::Error Buffer11::setSubData(const gl::Context *context,
-                               GLenum target,
+                               gl::BufferBinding target,
                                const void *data,
                                size_t size,
                                size_t offset)
@@ -360,7 +360,7 @@
         // Use system memory storage for dynamic buffers.
         // Try using a constant storage for constant buffers
         BufferStorage *writeBuffer = nullptr;
-        if (target == GL_UNIFORM_BUFFER)
+        if (target == gl::BufferBinding::Uniform)
         {
             // If we are a very large uniform buffer, keep system memory storage around so that we
             // aren't forced to read back from a constant buffer. We also check the workaround for
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index 27cf60b..d7a2d68 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -81,12 +81,12 @@
 
     // BufferImpl implementation
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index 2753fe7..63e47f2 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -284,7 +284,7 @@
     const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
     ASSERT(readAttachment);
 
-    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
     if (packBuffer != nullptr)
     {
         Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
diff --git a/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
index 71c5bc6..e9c8ca7 100644
--- a/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -153,7 +153,8 @@
            destArea.y >= 0 && destArea.y + destArea.height <= destSize.height &&
            destArea.z >= 0 && destArea.z + destArea.depth  <= destSize.depth  );
 
-    const gl::Buffer &sourceBuffer = *context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    const gl::Buffer &sourceBuffer =
+        *context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
 
     ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index b1427d2..6a235b2 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -1751,7 +1751,7 @@
         return gl::NoError();
     }
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
     uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
@@ -1802,7 +1802,7 @@
         return gl::NoError();
     }
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
     uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
@@ -3300,7 +3300,7 @@
     mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(),
                                           sourceSubResource, &srcBox);
 
-    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
     if (!invertTexture)
     {
         PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, packBuffer, 0);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
index d96c073..5160c38 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -23,7 +23,7 @@
 }
 
 gl::Error Buffer9::setData(const gl::Context *context,
-                           GLenum /*target*/,
+                           gl::BufferBinding /*target*/,
                            const void *data,
                            size_t size,
                            gl::BufferUsage usage)
@@ -56,7 +56,7 @@
 }
 
 gl::Error Buffer9::setSubData(const gl::Context *context,
-                              GLenum /*target*/,
+                              gl::BufferBinding /*target*/,
                               const void *data,
                               size_t size,
                               size_t offset)
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
index 2037e26..ceb537c 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -30,12 +30,12 @@
 
     // BufferImpl implementation
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
diff --git a/src/libANGLE/renderer/gl/BlitGL.cpp b/src/libANGLE/renderer/gl/BlitGL.cpp
index bfbdb79..b071822 100644
--- a/src/libANGLE/renderer/gl/BlitGL.cpp
+++ b/src/libANGLE/renderer/gl/BlitGL.cpp
@@ -179,7 +179,7 @@
     gl::PixelUnpackState unpack;
     mStateManager->setPixelUnpackState(unpack);
     mStateManager->setPixelUnpackBuffer(
-        context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER));
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack));
     mFunctions->texImage2D(target, static_cast<GLint>(level), internalFormat, sourceArea.width,
                            sourceArea.height, 0, format,
                            source->getImplementationColorReadType(context), nullptr);
@@ -646,7 +646,7 @@
     if (mVertexBuffer == 0)
     {
         mFunctions->genBuffers(1, &mVertexBuffer);
-        mStateManager->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
 
         // Use a single, large triangle, to avoid arithmetic precision issues where fragments
         // with the same Y coordinate don't get exactly the same interpolated texcoord Y.
@@ -662,7 +662,7 @@
         mFunctions->genVertexArrays(1, &mVAO);
 
         mStateManager->bindVertexArray(mVAO, 0);
-        mStateManager->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
 
         // Enable all attributes with the same buffer so that it doesn't matter what location the
         // texcoord attribute is assigned
diff --git a/src/libANGLE/renderer/gl/BufferGL.cpp b/src/libANGLE/renderer/gl/BufferGL.cpp
index 26795d9..50cc467 100644
--- a/src/libANGLE/renderer/gl/BufferGL.cpp
+++ b/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -23,11 +23,11 @@
 // GL_ELEMENT_ARRAY_BUFFER is supported on more versions but can modify the state of the currently
 // bound VAO.  Two simultaneous buffer bindings are only needed for glCopyBufferSubData which also
 // adds the GL_COPY_READ_BUFFER binding.
-static const GLenum SourceBufferOperationTarget = GL_COPY_READ_BUFFER;
+static constexpr gl::BufferBinding SourceBufferOperationTarget = gl::BufferBinding::CopyRead;
 
 // Use the GL_ELEMENT_ARRAY_BUFFER binding for most operations since it's available on all
 // supported GL versions and doesn't affect any current state when it changes.
-static const GLenum DestBufferOperationTarget = GL_ARRAY_BUFFER;
+static constexpr gl::BufferBinding DestBufferOperationTarget = gl::BufferBinding::Array;
 
 BufferGL::BufferGL(const gl::BufferState &state,
                    const FunctionsGL *functions,
@@ -56,13 +56,13 @@
 }
 
 gl::Error BufferGL::setData(const gl::Context * /*context*/,
-                            GLenum /*target*/,
+                            gl::BufferBinding /*target*/,
                             const void *data,
                             size_t size,
                             gl::BufferUsage usage)
 {
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-    mFunctions->bufferData(DestBufferOperationTarget, size, data, ToGLenum(usage));
+    mFunctions->bufferData(gl::ToGLenum(DestBufferOperationTarget), size, data, ToGLenum(usage));
 
     if (mShadowBufferData)
     {
@@ -83,13 +83,13 @@
 }
 
 gl::Error BufferGL::setSubData(const gl::Context * /*context*/,
-                               GLenum /*target*/,
+                               gl::BufferBinding /*target*/,
                                const void *data,
                                size_t size,
                                size_t offset)
 {
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-    mFunctions->bufferSubData(DestBufferOperationTarget, offset, size, data);
+    mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), offset, size, data);
 
     if (mShadowBufferData && size > 0)
     {
@@ -110,8 +110,9 @@
     mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
     mStateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID());
 
-    mFunctions->copyBufferSubData(SourceBufferOperationTarget, DestBufferOperationTarget,
-                                  sourceOffset, destOffset, size);
+    mFunctions->copyBufferSubData(gl::ToGLenum(SourceBufferOperationTarget),
+                                  gl::ToGLenum(DestBufferOperationTarget), sourceOffset, destOffset,
+                                  size);
 
     if (mShadowBufferData && size > 0)
     {
@@ -131,14 +132,14 @@
     else if (mFunctions->mapBuffer)
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access);
+        *mapPtr = mFunctions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access);
     }
     else
     {
         ASSERT(mFunctions->mapBufferRange && access == GL_WRITE_ONLY_OES);
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr =
-            mFunctions->mapBufferRange(DestBufferOperationTarget, 0, mBufferSize, GL_MAP_WRITE_BIT);
+        *mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), 0,
+                                             mBufferSize, GL_MAP_WRITE_BIT);
     }
 
     mIsMapped  = true;
@@ -161,7 +162,8 @@
     else
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access);
+        *mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), offset,
+                                             length, access);
     }
 
     mIsMapped  = true;
@@ -179,14 +181,14 @@
     if (mShadowBufferData)
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        mFunctions->bufferSubData(DestBufferOperationTarget, mMapOffset, mMapSize,
+        mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), mMapOffset, mMapSize,
                                   mShadowCopy.data() + mMapOffset);
         *result = GL_TRUE;
     }
     else
     {
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
-        *result = mFunctions->unmapBuffer(DestBufferOperationTarget);
+        *result = mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget));
     }
 
     mIsMapped = false;
@@ -212,10 +214,11 @@
         mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
 
         const gl::Type &typeInfo  = gl::GetTypeInfo(type);
-        const uint8_t *bufferData = MapBufferRangeWithFallback(
-            mFunctions, DestBufferOperationTarget, offset, count * typeInfo.bytes, GL_MAP_READ_BIT);
+        const uint8_t *bufferData =
+            MapBufferRangeWithFallback(mFunctions, gl::ToGLenum(DestBufferOperationTarget), offset,
+                                       count * typeInfo.bytes, GL_MAP_READ_BIT);
         *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled);
-        mFunctions->unmapBuffer(DestBufferOperationTarget);
+        mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget));
     }
 
     return gl::NoError();
diff --git a/src/libANGLE/renderer/gl/BufferGL.h b/src/libANGLE/renderer/gl/BufferGL.h
index 6acb090..fbac40c 100644
--- a/src/libANGLE/renderer/gl/BufferGL.h
+++ b/src/libANGLE/renderer/gl/BufferGL.h
@@ -27,12 +27,12 @@
     ~BufferGL() override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 620de74..b1065fa 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -430,7 +430,8 @@
     }
 
     PixelPackState packState     = context->getGLState().getPackState();
-    const gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    const gl::Buffer *packBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
 
     nativegl::ReadPixelsFormat readPixelsFormat =
         nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 8b317a5..98bf942 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -179,9 +179,11 @@
     mTextures[GL_TEXTURE_3D].resize(rendererCaps.maxCombinedTextureImageUnits);
     mTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(rendererCaps.maxCombinedTextureImageUnits);
 
-    mIndexedBuffers[GL_UNIFORM_BUFFER].resize(rendererCaps.maxUniformBufferBindings);
-    mIndexedBuffers[GL_ATOMIC_COUNTER_BUFFER].resize(rendererCaps.maxAtomicCounterBufferBindings);
-    mIndexedBuffers[GL_SHADER_STORAGE_BUFFER].resize(rendererCaps.maxShaderStorageBufferBindings);
+    mIndexedBuffers[gl::BufferBinding::Uniform].resize(rendererCaps.maxUniformBufferBindings);
+    mIndexedBuffers[gl::BufferBinding::AtomicCounter].resize(
+        rendererCaps.maxAtomicCounterBufferBindings);
+    mIndexedBuffers[gl::BufferBinding::ShaderStorage].resize(
+        rendererCaps.maxShaderStorageBufferBindings);
 
     mSampleMaskValues.fill(~GLbitfield(0));
 
@@ -283,29 +285,29 @@
 
 void StateManagerGL::deleteBuffer(GLuint buffer)
 {
-    if (buffer != 0)
+    if (buffer == 0)
     {
-        for (const auto &bufferTypeIter : mBuffers)
-        {
-            if (bufferTypeIter.second == buffer)
-            {
-                bindBuffer(bufferTypeIter.first, 0);
-            }
-        }
-
-        for (const auto &bufferTypeIter : mIndexedBuffers)
-        {
-            for (size_t bindIndex = 0; bindIndex < bufferTypeIter.second.size(); bindIndex++)
-            {
-                if (bufferTypeIter.second[bindIndex].buffer == buffer)
-                {
-                    bindBufferBase(bufferTypeIter.first, bindIndex, 0);
-                }
-            }
-        }
-
-        mFunctions->deleteBuffers(1, &buffer);
+        return;
     }
+
+    for (auto target : angle::AllEnums<gl::BufferBinding>())
+    {
+        if (mBuffers[target] == buffer)
+        {
+            bindBuffer(target, 0);
+        }
+
+        auto &indexedTarget = mIndexedBuffers[target];
+        for (size_t bindIndex = 0; bindIndex < indexedTarget.size(); ++bindIndex)
+        {
+            if (indexedTarget[bindIndex].buffer == buffer)
+            {
+                bindBufferBase(target, bindIndex, 0);
+            }
+        }
+    }
+
+    mFunctions->deleteBuffers(1, &buffer);
 }
 
 void StateManagerGL::deleteFramebuffer(GLuint fbo)
@@ -392,51 +394,51 @@
 {
     if (mVAO != vao)
     {
-        mVAO                              = vao;
-        mBuffers[GL_ELEMENT_ARRAY_BUFFER] = elementArrayBuffer;
+        mVAO                                      = vao;
+        mBuffers[gl::BufferBinding::ElementArray] = elementArrayBuffer;
         mFunctions->bindVertexArray(vao);
 
         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
     }
 }
 
-void StateManagerGL::bindBuffer(GLenum type, GLuint buffer)
+void StateManagerGL::bindBuffer(gl::BufferBinding target, GLuint buffer)
 {
-    if (mBuffers[type] != buffer)
+    if (mBuffers[target] != buffer)
     {
-        mBuffers[type] = buffer;
-        mFunctions->bindBuffer(type, buffer);
+        mBuffers[target] = buffer;
+        mFunctions->bindBuffer(gl::ToGLenum(target), buffer);
     }
 }
 
-void StateManagerGL::bindBufferBase(GLenum type, size_t index, GLuint buffer)
+void StateManagerGL::bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer)
 {
-    ASSERT(mIndexedBuffers.count(type) > 0);
-    ASSERT(index < mIndexedBuffers[type].size());
-    auto &binding = mIndexedBuffers[type][index];
+    ASSERT(index < mIndexedBuffers[target].size());
+    auto &binding = mIndexedBuffers[target][index];
     if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
         binding.size != static_cast<size_t>(-1))
     {
         binding.buffer = buffer;
         binding.offset = static_cast<size_t>(-1);
         binding.size   = static_cast<size_t>(-1);
-        mFunctions->bindBufferBase(type, static_cast<GLuint>(index), buffer);
+        mFunctions->bindBufferBase(gl::ToGLenum(target), static_cast<GLuint>(index), buffer);
     }
 }
 
-void StateManagerGL::bindBufferRange(GLenum type,
+void StateManagerGL::bindBufferRange(gl::BufferBinding target,
                                      size_t index,
                                      GLuint buffer,
                                      size_t offset,
                                      size_t size)
 {
-    auto &binding = mIndexedBuffers[type][index];
+    auto &binding = mIndexedBuffers[target][index];
     if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
     {
         binding.buffer = buffer;
         binding.offset = offset;
         binding.size   = size;
-        mFunctions->bindBufferRange(type, static_cast<GLuint>(index), buffer, offset, size);
+        mFunctions->bindBufferRange(gl::ToGLenum(target), static_cast<GLuint>(index), buffer,
+                                    offset, size);
     }
 }
 
@@ -549,7 +551,7 @@
     {
         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
     }
-    bindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferID);
+    bindBuffer(gl::BufferBinding::PixelUnpack, bufferID);
 }
 
 void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
@@ -594,7 +596,7 @@
     {
         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
     }
-    bindBuffer(GL_PIXEL_PACK_BUFFER, bufferID);
+    bindBuffer(gl::BufferBinding::PixelPack, bufferID);
 }
 
 void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
@@ -739,10 +741,10 @@
     }
     bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
 
-    gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     const BufferGL *bufferGL = GetImplAs<BufferGL>(drawIndirectBuffer);
-    bindBuffer(GL_DRAW_INDIRECT_BUFFER, bufferGL->getBufferID());
+    bindBuffer(gl::BufferBinding::DrawIndirect, bufferGL->getBufferID());
 
     return setGenericDrawState(context);
 }
@@ -858,11 +860,11 @@
 
             if (uniformBuffer.getSize() == 0)
             {
-                bindBufferBase(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
             }
         }
@@ -908,11 +910,11 @@
 
             if (buffer.getSize() == 0)
             {
-                bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_ATOMIC_COUNTER_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
                                 buffer.getOffset(), buffer.getSize());
             }
         }
@@ -982,11 +984,11 @@
 
             if (shaderStorageBuffer.getSize() == 0)
             {
-                bindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, bufferGL->getBufferID());
+                bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
             }
             else
             {
-                bindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, bufferGL->getBufferID(),
+                bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
             }
         }
@@ -1887,13 +1889,13 @@
                 setPixelUnpackState(state.getUnpackState());
                 break;
             case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
-                setPixelUnpackBuffer(state.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER));
+                setPixelUnpackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelUnpack));
                 break;
             case gl::State::DIRTY_BIT_PACK_STATE:
                 setPixelPackState(state.getPackState());
                 break;
             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
-                setPixelPackBuffer(state.getTargetBuffer(GL_PIXEL_PACK_BUFFER));
+                setPixelPackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelPack));
                 break;
             case gl::State::DIRTY_BIT_DITHER_ENABLED:
                 setDitherEnabled(state.isDitherEnabled());
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.h b/src/libANGLE/renderer/gl/StateManagerGL.h
index e8ac811..c3a3a5e 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -54,9 +54,13 @@
     void useProgram(GLuint program);
     void forceUseProgram(GLuint program);
     void bindVertexArray(GLuint vao, GLuint elementArrayBuffer);
-    void bindBuffer(GLenum type, GLuint buffer);
-    void bindBufferBase(GLenum type, size_t index, GLuint buffer);
-    void bindBufferRange(GLenum type, size_t index, GLuint buffer, size_t offset, size_t size);
+    void bindBuffer(gl::BufferBinding target, GLuint buffer);
+    void bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer);
+    void bindBufferRange(gl::BufferBinding target,
+                         size_t index,
+                         GLuint buffer,
+                         size_t offset,
+                         size_t size);
     void activeTexture(size_t unit);
     void bindTexture(GLenum type, GLuint texture);
     void bindSampler(size_t unit, GLuint sampler);
@@ -208,7 +212,7 @@
     GLuint mVAO;
     std::vector<gl::VertexAttribCurrentValueData> mVertexAttribCurrentValues;
 
-    std::map<GLenum, GLuint> mBuffers;
+    angle::PackedEnumMap<gl::BufferBinding, GLuint> mBuffers;
 
     struct IndexedBufferBinding
     {
@@ -218,7 +222,7 @@
         size_t size;
         GLuint buffer;
     };
-    std::map<GLenum, std::vector<IndexedBufferBinding>> mIndexedBuffers;
+    angle::PackedEnumMap<gl::BufferBinding, std::vector<IndexedBufferBinding>> mIndexedBuffers;
 
     size_t mTextureUnitIndex;
     std::map<GLenum, std::vector<GLuint>> mTextures;
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index 5619076..0c152dc 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -172,7 +172,8 @@
                               const gl::PixelUnpackState &unpack,
                               const uint8_t *pixels)
 {
-    const gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    const gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
 
     if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
         unpack.rowLength != 0 && unpack.rowLength < size.width)
@@ -278,7 +279,8 @@
                                  const uint8_t *pixels)
 {
     ASSERT(CompatibleTextureTarget(getTarget(), target));
-    const gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    const gl::Buffer *unpackBuffer =
+        context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
 
     nativegl::TexSubImageFormat texSubImageFormat =
         nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
@@ -827,7 +829,7 @@
         else
         {
             // Make sure no pixel unpack buffer is bound
-            mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+            mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
 
             const gl::InternalFormat &internalFormatInfo =
                 gl::GetSizedInternalFormatInfo(internalFormat);
@@ -920,7 +922,7 @@
         else
         {
             // Make sure no pixel unpack buffer is bound
-            mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+            mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
 
             const gl::InternalFormat &internalFormatInfo =
                 gl::GetSizedInternalFormatInfo(internalFormat);
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index 2bac8a9..6dc1fe1 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -134,7 +134,7 @@
     if (elementArrayBuffer != mAppliedElementArrayBuffer.get())
     {
         const BufferGL *bufferGL = GetImplAs<BufferGL>(elementArrayBuffer);
-        mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID());
+        mStateManager->bindBuffer(gl::BufferBinding::ElementArray, bufferGL->getBufferID());
         mAppliedElementArrayBuffer.set(context, elementArrayBuffer);
     }
 
@@ -199,7 +199,7 @@
         if (elementArrayBuffer != mAppliedElementArrayBuffer.get())
         {
             const BufferGL *bufferGL = GetImplAs<BufferGL>(elementArrayBuffer);
-            mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID());
+            mStateManager->bindBuffer(gl::BufferBinding::ElementArray, bufferGL->getBufferID());
             mAppliedElementArrayBuffer.set(context, elementArrayBuffer);
         }
 
@@ -238,7 +238,7 @@
             mStreamingElementArrayBufferSize = 0;
         }
 
-        mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mStreamingElementArrayBuffer);
+        mStateManager->bindBuffer(gl::BufferBinding::ElementArray, mStreamingElementArrayBuffer);
         mAppliedElementArrayBuffer.set(context, nullptr);
 
         // Make sure the element array buffer is large enough
@@ -327,7 +327,7 @@
     const size_t bufferEmptySpace   = maxAttributeDataSize * indexRange.start;
     const size_t requiredBufferSize = streamingDataSize + bufferEmptySpace;
 
-    mStateManager->bindBuffer(GL_ARRAY_BUFFER, mStreamingArrayBuffer);
+    mStateManager->bindBuffer(gl::BufferBinding::Array, mStreamingArrayBuffer);
     if (requiredBufferSize > mStreamingArrayBufferSize)
     {
         mFunctions->bufferData(GL_ARRAY_BUFFER, requiredBufferSize, nullptr, GL_DYNAMIC_DRAW);
@@ -506,7 +506,7 @@
     // is not NULL.
 
     const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
-    mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
+    mStateManager->bindBuffer(gl::BufferBinding::Array, arrayBufferGL->getBufferID());
     callVertexAttribPointer(static_cast<GLuint>(attribIndex), attrib, binding.getStride(),
                             binding.getOffset());
 
diff --git a/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp b/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
index 655fbc9..b6c0ac9 100644
--- a/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
+++ b/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
@@ -684,21 +684,21 @@
         };
         // clang-format on
         gl->genBuffers(1, &mVertexBuffer);
-        sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+        sm->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
         gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
 
         // window border triangle strip
         const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0};
 
         gl->genBuffers(1, &mIndexBuffer);
-        sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+        sm->bindBuffer(gl::BufferBinding::ElementArray, mIndexBuffer);
         gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW);
     }
     else
     {
         sm->useProgram(mProgram);
-        sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
-        sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+        sm->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);
+        sm->bindBuffer(gl::BufferBinding::ElementArray, mIndexBuffer);
     }
 
     // convert from pixels to "-1 to 1" space
diff --git a/src/libANGLE/renderer/null/BufferNULL.cpp b/src/libANGLE/renderer/null/BufferNULL.cpp
index 4a72bb9..08a67d6 100644
--- a/src/libANGLE/renderer/null/BufferNULL.cpp
+++ b/src/libANGLE/renderer/null/BufferNULL.cpp
@@ -30,7 +30,7 @@
 }
 
 gl::Error BufferNULL::setData(const gl::Context *context,
-                              GLenum target,
+                              gl::BufferBinding target,
                               const void *data,
                               size_t size,
                               gl::BufferUsage usage)
@@ -49,7 +49,7 @@
 }
 
 gl::Error BufferNULL::setSubData(const gl::Context *context,
-                                 GLenum target,
+                                 gl::BufferBinding target,
                                  const void *data,
                                  size_t size,
                                  size_t offset)
diff --git a/src/libANGLE/renderer/null/BufferNULL.h b/src/libANGLE/renderer/null/BufferNULL.h
index acf6a62..1fa40e1 100644
--- a/src/libANGLE/renderer/null/BufferNULL.h
+++ b/src/libANGLE/renderer/null/BufferNULL.h
@@ -24,12 +24,12 @@
     ~BufferNULL() override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
diff --git a/src/libANGLE/renderer/null/FramebufferNULL.cpp b/src/libANGLE/renderer/null/FramebufferNULL.cpp
index bca9f8f..71d3cdc 100644
--- a/src/libANGLE/renderer/null/FramebufferNULL.cpp
+++ b/src/libANGLE/renderer/null/FramebufferNULL.cpp
@@ -119,7 +119,7 @@
                                       void *ptrOrOffset)
 {
     const gl::PixelPackState &packState = context->getGLState().getPackState();
-    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack);
 
     // Get the pointer to write to from the argument or the pack buffer
     GLubyte *pixels = nullptr;
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp
index 381b55b..9dd9e58 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp
@@ -41,7 +41,7 @@
 }
 
 gl::Error BufferVk::setData(const gl::Context *context,
-                            GLenum target,
+                            gl::BufferBinding target,
                             const void *data,
                             size_t size,
                             gl::BufferUsage usage)
@@ -80,7 +80,7 @@
 }
 
 gl::Error BufferVk::setSubData(const gl::Context *context,
-                               GLenum target,
+                               gl::BufferBinding target,
                                const void *data,
                                size_t size,
                                size_t offset)
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.h b/src/libANGLE/renderer/vulkan/BufferVk.h
index 8790297..d07a6ac 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.h
+++ b/src/libANGLE/renderer/vulkan/BufferVk.h
@@ -25,12 +25,12 @@
     void destroy(const gl::Context *context) override;
 
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage usage) override;
     gl::Error setSubData(const gl::Context *context,
-                         GLenum target,
+                         gl::BufferBinding target,
                          const void *data,
                          size_t size,
                          size_t offset) override;
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index cfa26a6..99530ec 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -327,7 +327,7 @@
     params.format      = format;
     params.type        = type;
     params.outputPitch = inputPitch;
-    params.packBuffer  = glState.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    params.packBuffer  = glState.getTargetBuffer(gl::BufferBinding::PixelPack);
     params.pack        = glState.getPackState();
 
     PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 615fac4..a4e1a3a 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -774,29 +774,29 @@
     }
 }
 
-bool ValidBufferTarget(const ValidationContext *context, GLenum target)
+bool ValidBufferType(const ValidationContext *context, BufferBinding target)
 {
     switch (target)
     {
-        case GL_ARRAY_BUFFER:
-        case GL_ELEMENT_ARRAY_BUFFER:
+        case BufferBinding::ElementArray:
+        case BufferBinding::Array:
             return true;
 
-        case GL_PIXEL_PACK_BUFFER:
-        case GL_PIXEL_UNPACK_BUFFER:
+        case BufferBinding::PixelPack:
+        case BufferBinding::PixelUnpack:
             return (context->getExtensions().pixelBufferObject ||
                     context->getClientMajorVersion() >= 3);
 
-        case GL_COPY_READ_BUFFER:
-        case GL_COPY_WRITE_BUFFER:
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
-        case GL_UNIFORM_BUFFER:
+        case BufferBinding::CopyRead:
+        case BufferBinding::CopyWrite:
+        case BufferBinding::TransformFeedback:
+        case BufferBinding::Uniform:
             return (context->getClientMajorVersion() >= 3);
 
-        case GL_ATOMIC_COUNTER_BUFFER:
-        case GL_SHADER_STORAGE_BUFFER:
-        case GL_DRAW_INDIRECT_BUFFER:
-        case GL_DISPATCH_INDIRECT_BUFFER:
+        case BufferBinding::AtomicCounter:
+        case BufferBinding::ShaderStorage:
+        case BufferBinding::DrawIndirect:
+        case BufferBinding::DispatchIndirect:
             return context->getClientVersion() >= Version(3, 1);
 
         default:
@@ -997,7 +997,8 @@
                         const void *pixels,
                         GLsizei imageSize)
 {
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer == nullptr && imageSize < 0)
     {
         // Checks are not required
@@ -2541,7 +2542,7 @@
     {
         // Check for mapped buffers
         // TODO(jmadill): Optimize this check for non - WebGL contexts.
-        if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
+        if (state.hasMappedBuffer(BufferBinding::Array))
         {
             context->handleError(InvalidOperation());
             return false;
@@ -2821,7 +2822,7 @@
     {
         // Check for mapped buffers
         // TODO(jmadill): Optimize this check for non - WebGL contexts.
-        if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
+        if (state.hasMappedBuffer(gl::BufferBinding::ElementArray))
         {
             context->handleError(InvalidOperation() << "Index buffer is mapped.");
             return false;
@@ -3527,7 +3528,7 @@
 }
 
 bool ValidateGetBufferPointervBase(Context *context,
-                                   GLenum target,
+                                   BufferBinding target,
                                    GLenum pname,
                                    GLsizei *length,
                                    void **params)
@@ -3545,10 +3546,9 @@
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
-        context->handleError(InvalidEnum() << "Buffer target not valid: 0x" << std::hex
-                                           << std::uppercase << target);
+        context->handleError(InvalidEnum() << "Buffer target not valid");
         return false;
     }
 
@@ -3580,9 +3580,9 @@
     return true;
 }
 
-bool ValidateUnmapBufferBase(Context *context, GLenum target)
+bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
 {
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -3600,12 +3600,12 @@
 }
 
 bool ValidateMapBufferRangeBase(Context *context,
-                                GLenum target,
+                                BufferBinding target,
                                 GLintptr offset,
                                 GLsizeiptr length,
                                 GLbitfield access)
 {
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -3696,7 +3696,7 @@
 }
 
 bool ValidateFlushMappedBufferRangeBase(Context *context,
-                                        GLenum target,
+                                        BufferBinding target,
                                         GLintptr offset,
                                         GLsizeiptr length)
 {
@@ -3712,7 +3712,7 @@
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -4071,7 +4071,7 @@
 }
 
 bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
-                                             GLenum target,
+                                             BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
@@ -4096,7 +4096,7 @@
 }
 
 bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
-                                               GLenum target,
+                                               BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
@@ -4724,7 +4724,8 @@
         return false;
     }
 
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer == nullptr)
     {
         if (dataSize < imageSize)
@@ -4736,7 +4737,7 @@
 }
 
 bool ValidateGetBufferParameterBase(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams)
@@ -4746,7 +4747,7 @@
         *numParams = 0;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -5223,7 +5224,7 @@
     }
 
     // Check for pixel pack buffer related API errors
-    gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
+    gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
     if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
     {
         // ...the buffer object's data store is currently mapped.
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index 9041f443..568d5eb 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -10,6 +10,7 @@
 #define LIBANGLE_VALIDATION_ES_H_
 
 #include "common/mathutil.h"
+#include "libANGLE/PackedGLEnums.h"
 
 #include <GLES2/gl2.h>
 #include <GLES3/gl3.h>
@@ -37,7 +38,7 @@
 bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target);
 bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target);
 bool ValidFramebufferTarget(GLenum target);
-bool ValidBufferTarget(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,
@@ -366,18 +367,18 @@
 bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs);
 
 bool ValidateGetBufferPointervBase(Context *context,
-                                   GLenum target,
+                                   BufferBinding target,
                                    GLenum pname,
                                    GLsizei *length,
                                    void **params);
-bool ValidateUnmapBufferBase(Context *context, GLenum target);
+bool ValidateUnmapBufferBase(Context *context, BufferBinding target);
 bool ValidateMapBufferRangeBase(Context *context,
-                                GLenum target,
+                                BufferBinding target,
                                 GLintptr offset,
                                 GLsizeiptr length,
                                 GLbitfield access);
 bool ValidateFlushMappedBufferRangeBase(Context *context,
-                                        GLenum target,
+                                        BufferBinding target,
                                         GLintptr offset,
                                         GLsizeiptr length);
 
@@ -399,19 +400,19 @@
                                                             GLsizei *numParams);
 
 bool ValidateGetBufferParameterBase(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     bool pointerVersion,
                                     GLsizei *numParams);
 bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
-                                             GLenum target,
+                                             BufferBinding target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params);
 
 bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
-                                               GLenum target,
+                                               BufferBinding target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 64cbb68..aa02c3d 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -1142,7 +1142,7 @@
         }
 
         if (width > 0 && height > 0 && pixels == nullptr &&
-            context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER) == nullptr)
+            context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
             return false;
@@ -2824,12 +2824,15 @@
     return true;
 }
 
-bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
+bool ValidateGetBufferPointervOES(Context *context,
+                                  BufferBinding target,
+                                  GLenum pname,
+                                  void **params)
 {
     return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
 }
 
-bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
+bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
 {
     if (!context->getExtensions().mapBuffer)
     {
@@ -2837,7 +2840,7 @@
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -2866,7 +2869,7 @@
     return ValidateMapBufferBase(context, target);
 }
 
-bool ValidateUnmapBufferOES(Context *context, GLenum target)
+bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
 {
     if (!context->getExtensions().mapBuffer)
     {
@@ -2878,7 +2881,7 @@
 }
 
 bool ValidateMapBufferRangeEXT(Context *context,
-                               GLenum target,
+                               BufferBinding target,
                                GLintptr offset,
                                GLsizeiptr length,
                                GLbitfield access)
@@ -2892,7 +2895,7 @@
     return ValidateMapBufferRangeBase(context, target, offset, length, access);
 }
 
-bool ValidateMapBufferBase(Context *context, GLenum target)
+bool ValidateMapBufferBase(Context *context, BufferBinding target)
 {
     Buffer *buffer = context->getGLState().getTargetBuffer(target);
     ASSERT(buffer != nullptr);
@@ -2917,7 +2920,7 @@
 }
 
 bool ValidateFlushMappedBufferRangeEXT(Context *context,
-                                       GLenum target,
+                                       BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length)
 {
@@ -4162,7 +4165,7 @@
 }
 
 bool ValidateBufferData(ValidationContext *context,
-                        GLenum target,
+                        BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
                         BufferUsage usage)
@@ -4198,7 +4201,7 @@
             return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -4216,7 +4219,7 @@
 }
 
 bool ValidateBufferSubData(ValidationContext *context,
-                           GLenum target,
+                           BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data)
@@ -4233,7 +4236,7 @@
         return false;
     }
 
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -4389,9 +4392,9 @@
     return GetValidProgram(context, program) != nullptr;
 }
 
-bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer)
+bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
 {
-    if (!ValidBufferTarget(context, target))
+    if (!ValidBufferType(context, target))
     {
         ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
         return false;
@@ -4702,7 +4705,8 @@
     // and the pointer argument is not NULL.
     bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
                              context->getGLState().getVertexArray()->id() == 0;
-    if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
+    if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
+        ptr != nullptr)
     {
         context
             ->handleError(InvalidOperation()
@@ -6169,7 +6173,7 @@
 }
 
 bool ValidateGetBufferParameteriv(ValidationContext *context,
-                                  GLenum target,
+                                  BufferBinding target,
                                   GLenum pname,
                                   GLint *params)
 {
diff --git a/src/libANGLE/validationES2.h b/src/libANGLE/validationES2.h
index 7cf1657..5dc0917 100644
--- a/src/libANGLE/validationES2.h
+++ b/src/libANGLE/validationES2.h
@@ -202,17 +202,20 @@
 
 bool ValidateBindTexture(Context *context, GLenum target, GLuint texture);
 
-bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params);
-bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access);
-bool ValidateUnmapBufferOES(Context *context, GLenum target);
+bool ValidateGetBufferPointervOES(Context *context,
+                                  BufferBinding target,
+                                  GLenum pname,
+                                  void **params);
+bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access);
+bool ValidateUnmapBufferOES(Context *context, BufferBinding target);
 bool ValidateMapBufferRangeEXT(Context *context,
-                               GLenum target,
+                               BufferBinding target,
                                GLintptr offset,
                                GLsizeiptr length,
                                GLbitfield access);
-bool ValidateMapBufferBase(Context *context, GLenum target);
+bool ValidateMapBufferBase(Context *context, BufferBinding target);
 bool ValidateFlushMappedBufferRangeEXT(Context *context,
-                                       GLenum target,
+                                       BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length);
 
@@ -347,12 +350,12 @@
 
 bool ValidateCreateShader(Context *context, GLenum type);
 bool ValidateBufferData(ValidationContext *context,
-                        GLenum target,
+                        BufferBinding target,
                         GLsizeiptr size,
                         const void *data,
                         BufferUsage usage);
 bool ValidateBufferSubData(ValidationContext *context,
-                           GLenum target,
+                           BufferBinding target,
                            GLintptr offset,
                            GLsizeiptr size,
                            const void *data);
@@ -365,7 +368,7 @@
                                 GLuint program,
                                 GLuint index,
                                 const GLchar *name);
-bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer);
+bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer);
 bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer);
 bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer);
 bool ValidateBlendColor(ValidationContext *context,
@@ -644,7 +647,7 @@
 bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *renderbuffers);
 bool ValidateGenTextures(Context *context, GLint n, GLuint *textures);
 bool ValidateGetBufferParameteriv(ValidationContext *context,
-                                  GLenum target,
+                                  BufferBinding target,
                                   GLenum pname,
                                   GLint *params);
 bool ValidateGetRenderbufferParameteriv(Context *context,
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 9e0433a..514b638 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -430,7 +430,7 @@
         }
 
         if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
-            context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER) == nullptr)
+            context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
         {
             ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
             return false;
@@ -445,7 +445,8 @@
     }
 
     // Check for pixel unpack buffer related API errors
-    gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
+    gl::Buffer *pixelUnpackBuffer =
+        context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
     if (pixelUnpackBuffer != nullptr)
     {
         // ...data is not evenly divisible into the number of bytes needed to store in memory a
@@ -1460,7 +1461,7 @@
 }
 
 static bool ValidateBindBufferCommon(Context *context,
-                                     GLenum target,
+                                     BufferBinding target,
                                      GLuint index,
                                      GLuint buffer,
                                      GLintptr offset,
@@ -1488,7 +1489,7 @@
     const Caps &caps = context->getCaps();
     switch (target)
     {
-        case GL_TRANSFORM_FEEDBACK_BUFFER:
+        case BufferBinding::TransformFeedback:
         {
             if (index >= caps.maxTransformFeedbackSeparateAttributes)
             {
@@ -1514,7 +1515,7 @@
             }
             break;
         }
-        case GL_UNIFORM_BUFFER:
+        case BufferBinding::Uniform:
         {
             if (index >= caps.maxUniformBufferBindings)
             {
@@ -1533,7 +1534,7 @@
             }
             break;
         }
-        case GL_ATOMIC_COUNTER_BUFFER:
+        case BufferBinding::AtomicCounter:
         {
             if (context->getClientVersion() < ES_3_1)
             {
@@ -1555,7 +1556,7 @@
             }
             break;
         }
-        case GL_SHADER_STORAGE_BUFFER:
+        case BufferBinding::ShaderStorage:
         {
             if (context->getClientVersion() < ES_3_1)
             {
@@ -1587,13 +1588,13 @@
     return true;
 }
 
-bool ValidateBindBufferBase(Context *context, GLenum target, GLuint index, GLuint buffer)
+bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer)
 {
     return ValidateBindBufferCommon(context, target, index, buffer, 0, 0);
 }
 
 bool ValidateBindBufferRange(Context *context,
-                             GLenum target,
+                             BufferBinding target,
                              GLuint index,
                              GLuint buffer,
                              GLintptr offset,
@@ -2170,13 +2171,13 @@
     return true;
 }
 
-bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, void **params)
+bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params)
 {
     return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
 }
 
 bool ValidateGetBufferPointervRobustANGLE(Context *context,
-                                          GLenum target,
+                                          BufferBinding target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
@@ -2200,7 +2201,7 @@
     return true;
 }
 
-bool ValidateUnmapBuffer(Context *context, GLenum target)
+bool ValidateUnmapBuffer(Context *context, BufferBinding target)
 {
     if (context->getClientMajorVersion() < 3)
     {
@@ -2212,7 +2213,7 @@
 }
 
 bool ValidateMapBufferRange(Context *context,
-                            GLenum target,
+                            BufferBinding target,
                             GLintptr offset,
                             GLsizeiptr length,
                             GLbitfield access)
@@ -2227,7 +2228,7 @@
 }
 
 bool ValidateFlushMappedBufferRange(Context *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLintptr offset,
                                     GLsizeiptr length)
 {
@@ -2455,8 +2456,8 @@
 }
 
 bool ValidateCopyBufferSubData(ValidationContext *context,
-                               GLenum readTarget,
-                               GLenum writeTarget,
+                               BufferBinding readTarget,
+                               BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size)
@@ -2467,7 +2468,7 @@
         return false;
     }
 
-    if (!ValidBufferTarget(context, readTarget) || !ValidBufferTarget(context, writeTarget))
+    if (!ValidBufferType(context, readTarget) || !ValidBufferType(context, writeTarget))
     {
         context->handleError(InvalidEnum() << "Invalid buffer target");
         return false;
@@ -2675,7 +2676,7 @@
     // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
     // and the pointer argument is not NULL.
     if (context->getGLState().getVertexArrayId() != 0 &&
-        context->getGLState().getArrayBufferId() == 0 && pointer != nullptr)
+        context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
     {
         context
             ->handleError(InvalidOperation()
@@ -3639,7 +3640,7 @@
 }
 
 bool ValidateGetBufferParameteri64v(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     GLint64 *params)
 {
diff --git a/src/libANGLE/validationES3.h b/src/libANGLE/validationES3.h
index 174f4c7..631b1ca 100644
--- a/src/libANGLE/validationES3.h
+++ b/src/libANGLE/validationES3.h
@@ -9,6 +9,8 @@
 #ifndef LIBANGLE_VALIDATION_ES3_H_
 #define LIBANGLE_VALIDATION_ES3_H_
 
+#include "libANGLE/PackedGLEnums.h"
+
 #include <GLES3/gl3.h>
 
 namespace gl
@@ -213,9 +215,9 @@
 bool ValidateBindVertexArray(Context *context, GLuint array);
 bool ValidateIsVertexArray(Context *context, GLuint array);
 
-bool ValidateBindBufferBase(Context *context, GLenum target, GLuint index, GLuint buffer);
+bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer);
 bool ValidateBindBufferRange(Context *context,
-                             GLenum target,
+                             BufferBinding target,
                              GLuint index,
                              GLuint buffer,
                              GLintptr offset,
@@ -357,21 +359,21 @@
 
 bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode);
 
-bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, void **params);
+bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params);
 bool ValidateGetBufferPointervRobustANGLE(Context *context,
-                                          GLenum target,
+                                          BufferBinding target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           void **params);
-bool ValidateUnmapBuffer(Context *context, GLenum target);
+bool ValidateUnmapBuffer(Context *context, BufferBinding target);
 bool ValidateMapBufferRange(Context *context,
-                            GLenum target,
+                            BufferBinding target,
                             GLintptr offset,
                             GLsizeiptr length,
                             GLbitfield access);
 bool ValidateFlushMappedBufferRange(Context *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLintptr offset,
                                     GLsizeiptr length);
 
@@ -398,8 +400,8 @@
                                         GLint64 *data);
 
 bool ValidateCopyBufferSubData(ValidationContext *context,
-                               GLenum readTarget,
-                               GLenum writeTarget,
+                               BufferBinding readTarget,
+                               BufferBinding writeTarget,
                                GLintptr readOffset,
                                GLintptr writeOffset,
                                GLsizeiptr size);
@@ -585,7 +587,7 @@
 bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params);
 bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params);
 bool ValidateGetBufferParameteri64v(ValidationContext *context,
-                                    GLenum target,
+                                    BufferBinding target,
                                     GLenum pname,
                                     GLint64 *params);
 bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param);
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index 7db0856..d44d17f 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -356,7 +356,7 @@
         return false;
     }
 
-    gl::Buffer *drawIndirectBuffer = state.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     if (!drawIndirectBuffer)
     {
         context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER");
@@ -405,7 +405,7 @@
     if (!ValidateDrawIndirectBase(context, mode, indirect))
         return false;
 
-    gl::Buffer *drawIndirectBuffer = state.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
     // which's size is 4 * sizeof(uint).
@@ -439,7 +439,7 @@
     if (!ValidateDrawIndirectBase(context, mode, indirect))
         return false;
 
-    gl::Buffer *drawIndirectBuffer = state.getDrawIndirectBuffer();
+    gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
     // which's size is 5 * sizeof(uint).
diff --git a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
index a249a9c..ae0e944 100644
--- a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -70,11 +70,12 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindBuffer>(target, buffer);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBuffer>(targetPacked, buffer);
 
-        if (context->skipValidation() || ValidateBindBuffer(context, target, buffer))
+        if (context->skipValidation() || ValidateBindBuffer(context, targetPacked, buffer))
         {
-            context->bindBuffer(target, buffer);
+            context->bindBuffer(targetPacked, buffer);
         }
     }
 }
@@ -226,13 +227,14 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
         BufferUsage usagePacked = FromGLenum<BufferUsage>(usage);
-        context->gatherParams<EntryPoint::BufferData>(target, size, data, usagePacked);
+        context->gatherParams<EntryPoint::BufferData>(targetPacked, size, data, usagePacked);
 
         if (context->skipValidation() ||
-            ValidateBufferData(context, target, size, data, usagePacked))
+            ValidateBufferData(context, targetPacked, size, data, usagePacked))
         {
-            context->bufferData(target, size, data, usagePacked);
+            context->bufferData(targetPacked, size, data, usagePacked);
         }
     }
 }
@@ -247,11 +249,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BufferSubData>(target, offset, size, data);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BufferSubData>(targetPacked, offset, size, data);
 
-        if (context->skipValidation() || ValidateBufferSubData(context, target, offset, size, data))
+        if (context->skipValidation() ||
+            ValidateBufferSubData(context, targetPacked, offset, size, data))
         {
-            context->bufferSubData(target, offset, size, data);
+            context->bufferSubData(targetPacked, offset, size, data);
         }
     }
 }
@@ -1101,12 +1105,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetBufferParameteriv>(target, pname, params);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferParameteriv>(targetPacked, pname, params);
 
         if (context->skipValidation() ||
-            ValidateGetBufferParameteriv(context, target, pname, params))
+            ValidateGetBufferParameteriv(context, targetPacked, pname, params))
         {
-            context->getBufferParameteriv(target, pname, params);
+            context->getBufferParameteriv(targetPacked, pname, params);
         }
     }
 }
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 00a1785..d4459ec 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -842,13 +842,15 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         if (!context->skipValidation() &&
-            !ValidateGetBufferPointervOES(context, target, pname, params))
+            !ValidateGetBufferPointervOES(context, targetPacked, pname, params))
         {
             return;
         }
 
-        context->getBufferPointerv(target, pname, params);
+        context->getBufferPointerv(targetPacked, pname, params);
     }
 }
 
@@ -859,12 +861,14 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateMapBufferOES(context, target, access))
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
+        if (!context->skipValidation() && !ValidateMapBufferOES(context, targetPacked, access))
         {
             return nullptr;
         }
 
-        return context->mapBuffer(target, access);
+        return context->mapBuffer(targetPacked, access);
     }
 
     return nullptr;
@@ -877,12 +881,14 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!context->skipValidation() && !ValidateUnmapBufferOES(context, target))
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
+        if (!context->skipValidation() && !ValidateUnmapBufferOES(context, targetPacked))
         {
             return GL_FALSE;
         }
 
-        return context->unmapBuffer(target);
+        return context->unmapBuffer(targetPacked);
     }
 
     return GL_FALSE;
@@ -901,13 +907,15 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         if (!context->skipValidation() &&
-            !ValidateMapBufferRangeEXT(context, target, offset, length, access))
+            !ValidateMapBufferRangeEXT(context, targetPacked, offset, length, access))
         {
             return nullptr;
         }
 
-        return context->mapBufferRange(target, offset, length, access);
+        return context->mapBufferRange(targetPacked, offset, length, access);
     }
 
     return nullptr;
@@ -921,13 +929,15 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         if (!context->skipValidation() &&
-            !ValidateFlushMappedBufferRangeEXT(context, target, offset, length))
+            !ValidateFlushMappedBufferRangeEXT(context, targetPacked, offset, length))
         {
             return;
         }
 
-        context->flushMappedBufferRange(target, offset, length);
+        context->flushMappedBufferRange(targetPacked, offset, length);
     }
 }
 
@@ -2018,14 +2028,16 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         GLsizei numParams = 0;
-        if (!ValidateGetBufferParameterivRobustANGLE(context, target, pname, bufSize, &numParams,
-                                                     params))
+        if (!ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname, bufSize,
+                                                     &numParams, params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(target);
+        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
         QueryBufferParameteriv(buffer, pname, params);
         SetRobustLengthParam(length, numParams);
     }
@@ -2783,14 +2795,16 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         GLsizei numParams = 0;
-        if (!ValidateGetBufferPointervRobustANGLE(context, target, pname, bufSize, &numParams,
+        if (!ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname, bufSize, &numParams,
                                                   params))
         {
             return;
         }
 
-        context->getBufferPointerv(target, pname, params);
+        context->getBufferPointerv(targetPacked, pname, params);
         SetRobustLengthParam(length, numParams);
     }
 }
@@ -3023,14 +3037,16 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+
         GLsizei numParams = 0;
-        if (!ValidateGetBufferParameteri64vRobustANGLE(context, target, pname, bufSize, &numParams,
-                                                       params))
+        if (!ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname, bufSize,
+                                                       &numParams, params))
         {
             return;
         }
 
-        Buffer *buffer = context->getGLState().getTargetBuffer(target);
+        Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked);
         QueryBufferParameteri64v(buffer, pname, params);
         SetRobustLengthParam(length, numParams);
     }
diff --git a/src/libGLESv2/entry_points_gles_3_0_autogen.cpp b/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
index 5f403a6..439f920 100644
--- a/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
+++ b/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
@@ -343,11 +343,12 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::UnmapBuffer>(target);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::UnmapBuffer>(targetPacked);
 
-        if (context->skipValidation() || ValidateUnmapBuffer(context, target))
+        if (context->skipValidation() || ValidateUnmapBuffer(context, targetPacked))
         {
-            return context->unmapBuffer(target);
+            return context->unmapBuffer(targetPacked);
         }
     }
 
@@ -362,11 +363,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetBufferPointerv>(target, pname, params);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferPointerv>(targetPacked, pname, params);
 
-        if (context->skipValidation() || ValidateGetBufferPointerv(context, target, pname, params))
+        if (context->skipValidation() ||
+            ValidateGetBufferPointerv(context, targetPacked, pname, params))
         {
-            context->getBufferPointerv(target, pname, params);
+            context->getBufferPointerv(targetPacked, pname, params);
         }
     }
 }
@@ -619,12 +622,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::MapBufferRange>(target, offset, length, access);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::MapBufferRange>(targetPacked, offset, length, access);
 
         if (context->skipValidation() ||
-            ValidateMapBufferRange(context, target, offset, length, access))
+            ValidateMapBufferRange(context, targetPacked, offset, length, access))
         {
-            return context->mapBufferRange(target, offset, length, access);
+            return context->mapBufferRange(targetPacked, offset, length, access);
         }
     }
 
@@ -639,12 +643,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::FlushMappedBufferRange>(target, offset, length);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::FlushMappedBufferRange>(targetPacked, offset, length);
 
         if (context->skipValidation() ||
-            ValidateFlushMappedBufferRange(context, target, offset, length))
+            ValidateFlushMappedBufferRange(context, targetPacked, offset, length))
         {
-            context->flushMappedBufferRange(target, offset, length);
+            context->flushMappedBufferRange(targetPacked, offset, length);
         }
     }
 }
@@ -774,12 +779,14 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindBufferRange>(target, index, buffer, offset, size);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBufferRange>(targetPacked, index, buffer, offset,
+                                                           size);
 
         if (context->skipValidation() ||
-            ValidateBindBufferRange(context, target, index, buffer, offset, size))
+            ValidateBindBufferRange(context, targetPacked, index, buffer, offset, size))
         {
-            context->bindBufferRange(target, index, buffer, offset, size);
+            context->bindBufferRange(targetPacked, index, buffer, offset, size);
         }
     }
 }
@@ -791,11 +798,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::BindBufferBase>(target, index, buffer);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::BindBufferBase>(targetPacked, index, buffer);
 
-        if (context->skipValidation() || ValidateBindBufferBase(context, target, index, buffer))
+        if (context->skipValidation() ||
+            ValidateBindBufferBase(context, targetPacked, index, buffer))
         {
-            context->bindBufferBase(target, index, buffer);
+            context->bindBufferBase(targetPacked, index, buffer);
         }
     }
 }
@@ -1243,13 +1252,17 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::CopyBufferSubData>(readTarget, writeTarget, readOffset,
-                                                             writeOffset, size);
+        BufferBinding readTargetPacked  = FromGLenum<BufferBinding>(readTarget);
+        BufferBinding writeTargetPacked = FromGLenum<BufferBinding>(writeTarget);
+        context->gatherParams<EntryPoint::CopyBufferSubData>(readTargetPacked, writeTargetPacked,
+                                                             readOffset, writeOffset, size);
 
-        if (context->skipValidation() || ValidateCopyBufferSubData(context, readTarget, writeTarget,
-                                                                   readOffset, writeOffset, size))
+        if (context->skipValidation() ||
+            ValidateCopyBufferSubData(context, readTargetPacked, writeTargetPacked, readOffset,
+                                      writeOffset, size))
         {
-            context->copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
+            context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset,
+                                       size);
         }
     }
 }
@@ -1588,12 +1601,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        context->gatherParams<EntryPoint::GetBufferParameteri64v>(target, pname, params);
+        BufferBinding targetPacked = FromGLenum<BufferBinding>(target);
+        context->gatherParams<EntryPoint::GetBufferParameteri64v>(targetPacked, pname, params);
 
         if (context->skipValidation() ||
-            ValidateGetBufferParameteri64v(context, target, pname, params))
+            ValidateGetBufferParameteri64v(context, targetPacked, pname, params))
         {
-            context->getBufferParameteri64v(target, pname, params);
+            context->getBufferParameteri64v(targetPacked, pname, params);
         }
     }
 }
diff --git a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
index f04d998..ad20579 100644
--- a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
+++ b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
@@ -37,7 +37,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,
+        gl::Error error    = mSourceBuffer->setData(nullptr, gl::BufferBinding::Array, testData,
                                                  sizeof(testData), gl::BufferUsage::StaticDraw);
         ASSERT_FALSE(error.isError());
 
diff --git a/src/tests/perf_tests/IndexDataManagerTest.cpp b/src/tests/perf_tests/IndexDataManagerTest.cpp
index 99ed580..13ace64 100644
--- a/src/tests/perf_tests/IndexDataManagerTest.cpp
+++ b/src/tests/perf_tests/IndexDataManagerTest.cpp
@@ -79,7 +79,7 @@
 
     // BufferImpl
     gl::Error setData(const gl::Context *context,
-                      GLenum target,
+                      gl::BufferBinding target,
                       const void *data,
                       size_t size,
                       gl::BufferUsage) override
@@ -92,7 +92,8 @@
         return gl::NoError();
     }
 
-    MOCK_METHOD5(setSubData, gl::Error(const gl::Context *, GLenum, const void *, size_t, size_t));
+    MOCK_METHOD5(setSubData,
+                 gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t));
     MOCK_METHOD5(copySubData,
                  gl::Error(const gl::Context *, BufferImpl *, GLintptr, GLintptr, GLsizeiptr));
     MOCK_METHOD3(map, gl::Error(const gl::Context *context, GLenum, void **));
@@ -167,7 +168,7 @@
         indexData[index] = static_cast<GLushort>(index);
     }
     EXPECT_FALSE(mIndexBuffer
-                     .bufferData(nullptr, GL_ARRAY_BUFFER, &indexData[0],
+                     .bufferData(nullptr, gl::BufferBinding::Array, &indexData[0],
                                  indexData.size() * sizeof(GLushort), gl::BufferUsage::StaticDraw)
                      .isError());
 }