// GENERATED FILE - DO NOT EDIT.
// Generated by generate_entry_points.py using data from gl.xml.
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// entry_points_gles_3_1_autogen.cpp:
//   Defines the GLES 3.1 entry points.

#include "libGLESv2/entry_points_gles_3_1_autogen.h"

#include "common/entry_points_enum_autogen.h"
#include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/capture_gles_3_1_autogen.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/gl_enum_utils.h"
#include "libANGLE/validationES31.h"
#include "libGLESv2/global_state.h"

namespace gl
{
void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ActiveShaderProgram, "glActiveShaderProgram",
          "context = %d, pipeline = %u, program = %u", CID(context), pipeline, program);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateActiveShaderProgram(context, pipelinePacked, programPacked));
        if (isCallValid)
        {
            context->activeShaderProgram(pipelinePacked, programPacked);
        }
        ANGLE_CAPTURE(ActiveShaderProgram, isCallValid, context, pipelinePacked, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindImageTexture(GLuint unit,
                                  GLuint texture,
                                  GLint level,
                                  GLboolean layered,
                                  GLint layer,
                                  GLenum access,
                                  GLenum format)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindImageTexture, "glBindImageTexture",
          "context = %d, unit = %u, texture = %u, level = %d, layered = %s, layer = %d, access = "
          "%s, format = %s",
          CID(context), unit, texture, level, GLbooleanToString(layered), layer,
          GLenumToString(GLenumGroup::BufferAccessARB, access),
          GLenumToString(GLenumGroup::InternalFormat, format));

    if (context)
    {
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindImageTexture(context, unit, texturePacked, level, layered,
                                                     layer, access, format));
        if (isCallValid)
        {
            context->bindImageTexture(unit, texturePacked, level, layered, layer, access, format);
        }
        ANGLE_CAPTURE(BindImageTexture, isCallValid, context, unit, texturePacked, level, layered,
                      layer, access, format);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindProgramPipeline, "glBindProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            context->bindProgramPipeline(pipelinePacked);
        }
        ANGLE_CAPTURE(BindProgramPipeline, isCallValid, context, pipelinePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
                                  GLuint buffer,
                                  GLintptr offset,
                                  GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindVertexBuffer, "glBindVertexBuffer",
          "context = %d, bindingindex = %u, buffer = %u, offset = %llu, stride = %d", CID(context),
          bindingindex, buffer, static_cast<unsigned long long>(offset), stride);

    if (context)
    {
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindVertexBuffer(context, bindingindex, bufferPacked, offset, stride));
        if (isCallValid)
        {
            context->bindVertexBuffer(bindingindex, bufferPacked, offset, stride);
        }
        ANGLE_CAPTURE(BindVertexBuffer, isCallValid, context, bindingindex, bufferPacked, offset,
                      stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CreateShaderProgramv, "glCreateShaderProgramv",
          "context = %d, type = %s, count = %d, strings = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ShaderType, type), count, (uintptr_t)strings);

    GLuint returnValue;
    if (context)
    {
        ShaderType typePacked                                 = FromGL<ShaderType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCreateShaderProgramv(context, typePacked, count, strings));
        if (isCallValid)
        {
            returnValue = context->createShaderProgramv(typePacked, count, strings);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
        }
        ANGLE_CAPTURE(CreateShaderProgramv, isCallValid, context, typePacked, count, strings,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteProgramPipelines, "glDeleteProgramPipelines",
          "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)pipelines);

    if (context)
    {
        const ProgramPipelineID *pipelinesPacked = FromGL<const ProgramPipelineID *>(pipelines);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteProgramPipelines(context, n, pipelinesPacked));
        if (isCallValid)
        {
            context->deleteProgramPipelines(n, pipelinesPacked);
        }
        ANGLE_CAPTURE(DeleteProgramPipelines, isCallValid, context, n, pipelinesPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DispatchCompute, "glDispatchCompute",
          "context = %d, num_groups_x = %u, num_groups_y = %u, num_groups_z = %u", CID(context),
          num_groups_x, num_groups_y, num_groups_z);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDispatchCompute(context, num_groups_x, num_groups_y, num_groups_z));
        if (isCallValid)
        {
            context->dispatchCompute(num_groups_x, num_groups_y, num_groups_z);
        }
        ANGLE_CAPTURE(DispatchCompute, isCallValid, context, num_groups_x, num_groups_y,
                      num_groups_z);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DispatchComputeIndirect, "glDispatchComputeIndirect",
          "context = %d, indirect = %llu", CID(context), static_cast<unsigned long long>(indirect));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDispatchComputeIndirect(context, indirect));
        if (isCallValid)
        {
            context->dispatchComputeIndirect(indirect);
        }
        ANGLE_CAPTURE(DispatchComputeIndirect, isCallValid, context, indirect);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawArraysIndirect, "glDrawArraysIndirect",
          "context = %d, mode = %s, indirect = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)indirect);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawArraysIndirect(context, modePacked, indirect));
        if (isCallValid)
        {
            context->drawArraysIndirect(modePacked, indirect);
        }
        ANGLE_CAPTURE(DrawArraysIndirect, isCallValid, context, modePacked, indirect);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsIndirect, "glDrawElementsIndirect",
          "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode),
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indirect);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawElementsIndirect(context, modePacked, typePacked, indirect));
        if (isCallValid)
        {
            context->drawElementsIndirect(modePacked, typePacked, indirect);
        }
        ANGLE_CAPTURE(DrawElementsIndirect, isCallValid, context, modePacked, typePacked, indirect);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferParameteri, "glFramebufferParameteri",
          "context = %d, target = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferParameterName, pname), param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferParameteri(context, target, pname, param));
        if (isCallValid)
        {
            context->framebufferParameteri(target, pname, param);
        }
        ANGLE_CAPTURE(FramebufferParameteri, isCallValid, context, target, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenProgramPipelines, "glGenProgramPipelines",
          "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)pipelines);

    if (context)
    {
        ProgramPipelineID *pipelinesPacked = FromGL<ProgramPipelineID *>(pipelines);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenProgramPipelines(context, n, pipelinesPacked));
        if (isCallValid)
        {
            context->genProgramPipelines(n, pipelinesPacked);
        }
        ANGLE_CAPTURE(GenProgramPipelines, isCallValid, context, n, pipelinesPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBooleani_v, "glGetBooleani_v",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target), index, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetBooleani_v(context, target, index, data));
        if (isCallValid)
        {
            context->getBooleani_v(target, index, data);
        }
        ANGLE_CAPTURE(GetBooleani_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFramebufferParameteriv, "glGetFramebufferParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFramebufferParameteriv(context, target, pname, params));
        if (isCallValid)
        {
            context->getFramebufferParameteriv(target, pname, params);
        }
        ANGLE_CAPTURE(GetFramebufferParameteriv, isCallValid, context, target, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetMultisamplefv, "glGetMultisamplefv",
          "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), index, (uintptr_t)val);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetMultisamplefv(context, pname, index, val));
        if (isCallValid)
        {
            context->getMultisamplefv(pname, index, val);
        }
        ANGLE_CAPTURE(GetMultisamplefv, isCallValid, context, pname, index, val);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
                                       GLenum programInterface,
                                       GLenum pname,
                                       GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramInterfaceiv, "glGetProgramInterfaceiv",
          "context = %d, program = %u, programInterface = %s, pname = %s, params = 0x%016" PRIxPTR
          "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          GLenumToString(GLenumGroup::ProgramInterfacePName, pname), (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramInterfaceiv(context, programPacked, programInterface,
                                                          pname, params));
        if (isCallValid)
        {
            context->getProgramInterfaceiv(programPacked, programInterface, pname, params);
        }
        ANGLE_CAPTURE(GetProgramInterfaceiv, isCallValid, context, programPacked, programInterface,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLchar *infoLog)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog",
          "context = %d, pipeline = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", infoLog = 0x%016" PRIxPTR "",
          CID(context), pipeline, bufSize, (uintptr_t)length, (uintptr_t)infoLog);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramPipelineInfoLog(context, pipelinePacked, bufSize, length, infoLog));
        if (isCallValid)
        {
            context->getProgramPipelineInfoLog(pipelinePacked, bufSize, length, infoLog);
        }
        ANGLE_CAPTURE(GetProgramPipelineInfoLog, isCallValid, context, pipelinePacked, bufSize,
                      length, infoLog);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramPipelineiv, "glGetProgramPipelineiv",
          "context = %d, pipeline = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          pipeline, GLenumToString(GLenumGroup::PipelineParameterName, pname), (uintptr_t)params);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramPipelineiv(context, pipelinePacked, pname, params));
        if (isCallValid)
        {
            context->getProgramPipelineiv(pipelinePacked, pname, params);
        }
        ANGLE_CAPTURE(GetProgramPipelineiv, isCallValid, context, pipelinePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
                                           GLenum programInterface,
                                           const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramResourceIndex, "glGetProgramResourceIndex",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLuint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceIndex(context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue = context->getProgramResourceIndex(programPacked, programInterface, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceIndex, GLuint>();
        }
        ANGLE_CAPTURE(GetProgramResourceIndex, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceIndex, GLuint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
                                             GLenum programInterface,
                                             const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramResourceLocation, "glGetProgramResourceLocation",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceLocation(context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue =
                context->getProgramResourceLocation(programPacked, programInterface, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceLocation, GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocation, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceLocation, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetProgramResourceName(GLuint program,
                                        GLenum programInterface,
                                        GLuint index,
                                        GLsizei bufSize,
                                        GLsizei *length,
                                        GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramResourceName, "glGetProgramResourceName",
          "context = %d, program = %u, programInterface = %s, index = %u, bufSize = %d, length = "
          "0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          index, bufSize, (uintptr_t)length, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramResourceName(context, programPacked, programInterface,
                                                           index, bufSize, length, name));
        if (isCallValid)
        {
            context->getProgramResourceName(programPacked, programInterface, index, bufSize, length,
                                            name);
        }
        ANGLE_CAPTURE(GetProgramResourceName, isCallValid, context, programPacked, programInterface,
                      index, bufSize, length, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramResourceiv(GLuint program,
                                      GLenum programInterface,
                                      GLuint index,
                                      GLsizei propCount,
                                      const GLenum *props,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramResourceiv, "glGetProgramResourceiv",
          "context = %d, program = %u, programInterface = %s, index = %u, propCount = %d, props = "
          "0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          index, propCount, (uintptr_t)props, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceiv(context, programPacked, programInterface, index,
                                          propCount, props, bufSize, length, params));
        if (isCallValid)
        {
            context->getProgramResourceiv(programPacked, programInterface, index, propCount, props,
                                          bufSize, length, params);
        }
        ANGLE_CAPTURE(GetProgramResourceiv, isCallValid, context, programPacked, programInterface,
                      index, propCount, props, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfv, "glGetTexLevelParameterfv",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterfv(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfv, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameteriv, "glGetTexLevelParameteriv",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameteriv(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameteriv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameteriv, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsProgramPipeline, "glIsProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    GLboolean returnValue;
    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            returnValue = context->isProgramPipeline(pipelinePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsProgramPipeline, GLboolean>();
        }
        ANGLE_CAPTURE(IsProgramPipeline, isCallValid, context, pipelinePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsProgramPipeline, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY MemoryBarrier(GLbitfield barriers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MemoryBarrier, "glMemoryBarrier", "context = %d, barriers = %s",
          CID(context), GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMemoryBarrier(context, barriers));
        if (isCallValid)
        {
            context->memoryBarrier(barriers);
        }
        ANGLE_CAPTURE(MemoryBarrier, isCallValid, context, barriers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MemoryBarrierByRegion, "glMemoryBarrierByRegion",
          "context = %d, barriers = %s", CID(context),
          GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMemoryBarrierByRegion(context, barriers));
        if (isCallValid)
        {
            context->memoryBarrierByRegion(barriers);
        }
        ANGLE_CAPTURE(MemoryBarrierByRegion, isCallValid, context, barriers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1f, "glProgramUniform1f",
          "context = %d, program = %u, location = %d, v0 = %f", CID(context), program, location,
          v0);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1f(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1f(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1f, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1fv, "glProgramUniform1fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1i, "glProgramUniform1i",
          "context = %d, program = %u, location = %d, v0 = %d", CID(context), program, location,
          v0);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1i(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1i(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1i, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1iv, "glProgramUniform1iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1ui, "glProgramUniform1ui",
          "context = %d, program = %u, location = %d, v0 = %u", CID(context), program, location,
          v0);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1ui(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1ui(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1ui, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform1uiv, "glProgramUniform1uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2f, "glProgramUniform2f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2f(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2f(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2f, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2fv, "glProgramUniform2fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2i, "glProgramUniform2i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2i(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2i(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2i, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2iv, "glProgramUniform2iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2ui, "glProgramUniform2ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2ui(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2ui(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform2uiv, "glProgramUniform2uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3f, "glProgramUniform3f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3f(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3f(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3f, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3fv, "glProgramUniform3fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3i, "glProgramUniform3i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3i(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3i(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3i, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3iv, "glProgramUniform3iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3ui, "glProgramUniform3ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3ui(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3ui(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform3uiv, "glProgramUniform3uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4f, "glProgramUniform4f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
          CID(context), program, location, v0, v1, v2, v3);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4f(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4f(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4f, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4fv, "glProgramUniform4fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4i, "glProgramUniform4i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d",
          CID(context), program, location, v0, v1, v2, v3);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4i(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4i(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4i, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4iv, "glProgramUniform4iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4ui, "glProgramUniform4ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u",
          CID(context), program, location, v0, v1, v2, v3);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4ui(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4ui(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniform4uiv, "glProgramUniform4uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2fv, "glProgramUniformMatrix2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2x3fv, "glProgramUniformMatrix2x3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x3fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x3fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x3fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2x4fv, "glProgramUniformMatrix2x4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x4fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x4fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x4fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3fv, "glProgramUniformMatrix3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3x2fv, "glProgramUniformMatrix3x2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x2fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x2fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x2fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3x4fv, "glProgramUniformMatrix3x4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x4fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x4fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x4fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4fv, "glProgramUniformMatrix4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4x2fv, "glProgramUniformMatrix4x2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x2fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x2fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x2fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4x3fv, "glProgramUniformMatrix4x3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x3fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x3fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x3fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SampleMaski, "glSampleMaski",
          "context = %d, maskNumber = %u, mask = %s", CID(context), maskNumber,
          GLbitfieldToString(GLenumGroup::DefaultGroup, mask).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleMaski(context, maskNumber, mask));
        if (isCallValid)
        {
            context->sampleMaski(maskNumber, mask);
        }
        ANGLE_CAPTURE(SampleMaski, isCallValid, context, maskNumber, mask);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage2DMultisample(GLenum target,
                                         GLsizei samples,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage2DMultisample, "glTexStorage2DMultisample",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height,
          GLbooleanToString(fixedsamplelocations));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DMultisample(context, targetPacked, samples, internalformat, width,
                                             height, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
                                             fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage2DMultisample, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::UseProgramStages, "glUseProgramStages",
          "context = %d, pipeline = %u, stages = %s, program = %u", CID(context), pipeline,
          GLbitfieldToString(GLenumGroup::UseProgramStageMask, stages).c_str(), program);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUseProgramStages(context, pipelinePacked, stages, programPacked));
        if (isCallValid)
        {
            context->useProgramStages(pipelinePacked, stages, programPacked);
        }
        ANGLE_CAPTURE(UseProgramStages, isCallValid, context, pipelinePacked, stages,
                      programPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ValidateProgramPipeline, "glValidateProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    if (context)
    {
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateValidateProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            context->validateProgramPipeline(pipelinePacked);
        }
        ANGLE_CAPTURE(ValidateProgramPipeline, isCallValid, context, pipelinePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexAttribBinding, "glVertexAttribBinding",
          "context = %d, attribindex = %u, bindingindex = %u", CID(context), attribindex,
          bindingindex);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribBinding(context, attribindex, bindingindex));
        if (isCallValid)
        {
            context->vertexAttribBinding(attribindex, bindingindex);
        }
        ANGLE_CAPTURE(VertexAttribBinding, isCallValid, context, attribindex, bindingindex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
                                    GLint size,
                                    GLenum type,
                                    GLboolean normalized,
                                    GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexAttribFormat, "glVertexAttribFormat",
          "context = %d, attribindex = %u, size = %d, type = %s, normalized = %s, relativeoffset = "
          "%u",
          CID(context), attribindex, size, GLenumToString(GLenumGroup::DefaultGroup, type),
          GLbooleanToString(normalized), relativeoffset);

    if (context)
    {
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribFormat(context, attribindex, size, typePacked,
                                                       normalized, relativeoffset));
        if (isCallValid)
        {
            context->vertexAttribFormat(attribindex, size, typePacked, normalized, relativeoffset);
        }
        ANGLE_CAPTURE(VertexAttribFormat, isCallValid, context, attribindex, size, typePacked,
                      normalized, relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
                                     GLint size,
                                     GLenum type,
                                     GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexAttribIFormat, "glVertexAttribIFormat",
          "context = %d, attribindex = %u, size = %d, type = %s, relativeoffset = %u", CID(context),
          attribindex, size, GLenumToString(GLenumGroup::DefaultGroup, type), relativeoffset);

    if (context)
    {
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribIFormat(context, attribindex, size, typePacked, relativeoffset));
        if (isCallValid)
        {
            context->vertexAttribIFormat(attribindex, size, typePacked, relativeoffset);
        }
        ANGLE_CAPTURE(VertexAttribIFormat, isCallValid, context, attribindex, size, typePacked,
                      relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexBindingDivisor, "glVertexBindingDivisor",
          "context = %d, bindingindex = %u, divisor = %u", CID(context), bindingindex, divisor);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexBindingDivisor(context, bindingindex, divisor));
        if (isCallValid)
        {
            context->vertexBindingDivisor(bindingindex, divisor);
        }
        ANGLE_CAPTURE(VertexBindingDivisor, isCallValid, context, bindingindex, divisor);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}
}  // namespace gl
