// GENERATED FILE - DO NOT EDIT.
// Generated by generate_entry_points.py using data from cl.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_cl_autogen.cpp:
//   Defines the CL entry points.

#include "libGLESv2/entry_points_cl_autogen.h"

#include "libANGLE/capture/capture_cl_autogen.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/validationCL_autogen.h"
#include "libGLESv2/cl_stubs_autogen.h"
#include "libGLESv2/entry_points_cl_utils.h"

namespace cl
{

// CL 1.0
cl_int CL_API_CALL clGetPlatformIDs(cl_uint num_entries,
                                    cl_platform_id *platforms,
                                    cl_uint *num_platforms)
{
    InitBackEnds(false);

    ANGLE_UNSAFE_TODO(CL_EVENT(GetPlatformIDs,
                               "num_entries = %u, platforms = 0x%016" PRIxPTR
                               ", num_platforms = 0x%016" PRIxPTR "",
                               num_entries, (uintptr_t)platforms, (uintptr_t)num_platforms));

    ANGLE_CL_VALIDATE_ERROR(GetPlatformIDs, num_entries, platforms, num_platforms);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetPlatformIDs(num_entries, platforms, num_platforms);
    ANGLE_CAPTURE_CL(GetPlatformIDs, true, num_entries, platforms, num_platforms, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetPlatformInfo(cl_platform_id platform,
                                     cl_platform_info param_name,
                                     size_t param_value_size,
                                     void *param_value,
                                     size_t *param_value_size_ret)
{
    InitBackEnds(false);

    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetPlatformInfo,
                 "platform = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)platform, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    PlatformInfo param_namePacked = PackParam<PlatformInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetPlatformInfo, platform, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetPlatformInfo(platform, param_namePacked, param_value_size, param_value,
                                         param_value_size_ret);
    ANGLE_CAPTURE_CL(GetPlatformInfo, true, platform, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetDeviceIDs(cl_platform_id platform,
                                  cl_device_type device_type,
                                  cl_uint num_entries,
                                  cl_device_id *devices,
                                  cl_uint *num_devices)
{
    InitBackEnds(false);

    ANGLE_UNSAFE_TODO(CL_EVENT(GetDeviceIDs,
                               "platform = 0x%016" PRIxPTR
                               ", device_type = %llu, num_entries = %u, devices = 0x%016" PRIxPTR
                               ", num_devices = 0x%016" PRIxPTR "",
                               (uintptr_t)platform, static_cast<unsigned long long>(device_type),
                               num_entries, (uintptr_t)devices, (uintptr_t)num_devices));

    DeviceType device_typePacked = PackParam<DeviceType>(device_type);

    ANGLE_CL_VALIDATE_ERROR(GetDeviceIDs, platform, device_typePacked, num_entries, devices,
                            num_devices);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetDeviceIDs(platform, device_typePacked, num_entries, devices, num_devices);
    ANGLE_CAPTURE_CL(GetDeviceIDs, true, platform, device_typePacked, num_entries, devices,
                     num_devices, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetDeviceInfo(cl_device_id device,
                                   cl_device_info param_name,
                                   size_t param_value_size,
                                   void *param_value,
                                   size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetDeviceInfo,
                 "device = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)device, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    DeviceInfo param_namePacked = PackParam<DeviceInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetDeviceInfo, device, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetDeviceInfo(device, param_namePacked, param_value_size, param_value,
                                       param_value_size_ret);
    ANGLE_CAPTURE_CL(GetDeviceInfo, true, device, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_context CL_API_CALL clCreateContext(const cl_context_properties *properties,
                                       cl_uint num_devices,
                                       const cl_device_id *devices,
                                       void(CL_CALLBACK *pfn_notify)(const char *errinfo,
                                                                     const void *private_info,
                                                                     size_t cb,
                                                                     void *user_data),
                                       void *user_data,
                                       cl_int *errcode_ret)
{
    InitBackEnds(false);

    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateContext,
                 "properties = 0x%016" PRIxPTR ", num_devices = %u, devices = 0x%016" PRIxPTR
                 ", pfn_notify = 0x%016" PRIxPTR ", user_data = 0x%016" PRIxPTR
                 ", errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)properties, num_devices, (uintptr_t)devices, (uintptr_t)pfn_notify,
                 (uintptr_t)user_data, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateContext, properties, num_devices, devices, pfn_notify,
                                  user_data);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_context object = CreateContext(properties, num_devices, devices, pfn_notify, user_data);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateContext, true, properties, num_devices, devices, pfn_notify, user_data,
                     errcode_ret, object);
    return object;
}

cl_context CL_API_CALL
clCreateContextFromType(const cl_context_properties *properties,
                        cl_device_type device_type,
                        void(CL_CALLBACK *pfn_notify)(const char *errinfo,
                                                      const void *private_info,
                                                      size_t cb,
                                                      void *user_data),
                        void *user_data,
                        cl_int *errcode_ret)
{
    InitBackEnds(false);

    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateContextFromType,
                 "properties = 0x%016" PRIxPTR ", device_type = %llu, pfn_notify = 0x%016" PRIxPTR
                 ", user_data = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)properties, static_cast<unsigned long long>(device_type),
                 (uintptr_t)pfn_notify, (uintptr_t)user_data, (uintptr_t)errcode_ret));

    DeviceType device_typePacked = PackParam<DeviceType>(device_type);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateContextFromType, properties, device_typePacked, pfn_notify,
                                  user_data);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_context object = CreateContextFromType(properties, device_typePacked, pfn_notify, user_data);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateContextFromType, true, properties, device_typePacked, pfn_notify,
                     user_data, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clRetainContext(cl_context context)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainContext, "context = 0x%016" PRIxPTR "", (uintptr_t)context));

    ANGLE_CL_VALIDATE_ERROR(RetainContext, context);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainContext(context);
    ANGLE_CAPTURE_CL(RetainContext, true, context, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseContext(cl_context context)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseContext, "context = 0x%016" PRIxPTR "", (uintptr_t)context));

    ANGLE_CL_VALIDATE_ERROR(ReleaseContext, context);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseContext(context);
    ANGLE_CAPTURE_CL(ReleaseContext, true, context, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetContextInfo(cl_context context,
                                    cl_context_info param_name,
                                    size_t param_value_size,
                                    void *param_value,
                                    size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetContextInfo,
                 "context = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)context, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    ContextInfo param_namePacked = PackParam<ContextInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetContextInfo, context, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetContextInfo(context, param_namePacked, param_value_size, param_value,
                                        param_value_size_ret);
    ANGLE_CAPTURE_CL(GetContextInfo, true, context, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clRetainCommandQueue(cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainCommandQueue, "command_queue = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(RetainCommandQueue, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainCommandQueue(command_queue);
    ANGLE_CAPTURE_CL(RetainCommandQueue, true, command_queue, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseCommandQueue, "command_queue = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(ReleaseCommandQueue, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseCommandQueue(command_queue);
    ANGLE_CAPTURE_CL(ReleaseCommandQueue, true, command_queue, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetCommandQueueInfo(cl_command_queue command_queue,
                                         cl_command_queue_info param_name,
                                         size_t param_value_size,
                                         void *param_value,
                                         size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetCommandQueueInfo,
                 "command_queue = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    CommandQueueInfo param_namePacked = PackParam<CommandQueueInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetCommandQueueInfo, command_queue, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetCommandQueueInfo(command_queue, param_namePacked, param_value_size,
                                             param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetCommandQueueInfo, true, command_queue, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_mem CL_API_CALL clCreateBuffer(cl_context context,
                                  cl_mem_flags flags,
                                  size_t size,
                                  void *host_ptr,
                                  cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateBuffer,
                               "context = 0x%016" PRIxPTR
                               ", flags = %llu, size = %zu, host_ptr = 0x%016" PRIxPTR
                               ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, static_cast<unsigned long long>(flags), size,
                               (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateBuffer, context, flagsPacked, size, host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateBuffer(context, flagsPacked, size, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateBuffer, true, context, flagsPacked, size, host_ptr, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clRetainMemObject(cl_mem memobj)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainMemObject, "memobj = 0x%016" PRIxPTR "", (uintptr_t)memobj));

    ANGLE_CL_VALIDATE_ERROR(RetainMemObject, memobj);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainMemObject(memobj);
    ANGLE_CAPTURE_CL(RetainMemObject, true, memobj, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseMemObject(cl_mem memobj)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseMemObject, "memobj = 0x%016" PRIxPTR "", (uintptr_t)memobj));

    ANGLE_CL_VALIDATE_ERROR(ReleaseMemObject, memobj);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseMemObject(memobj);
    ANGLE_CAPTURE_CL(ReleaseMemObject, true, memobj, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetSupportedImageFormats(cl_context context,
                                              cl_mem_flags flags,
                                              cl_mem_object_type image_type,
                                              cl_uint num_entries,
                                              cl_image_format *image_formats,
                                              cl_uint *num_image_formats)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetSupportedImageFormats,
                 "context = 0x%016" PRIxPTR
                 ", flags = %llu, image_type = %u, num_entries = %u, image_formats = 0x%016" PRIxPTR
                 ", num_image_formats = 0x%016" PRIxPTR "",
                 (uintptr_t)context, static_cast<unsigned long long>(flags), image_type,
                 num_entries, (uintptr_t)image_formats, (uintptr_t)num_image_formats));

    MemFlags flagsPacked           = PackParam<MemFlags>(flags);
    MemObjectType image_typePacked = PackParam<MemObjectType>(image_type);

    ANGLE_CL_VALIDATE_ERROR(GetSupportedImageFormats, context, flagsPacked, image_typePacked,
                            num_entries, image_formats, num_image_formats);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetSupportedImageFormats(context, flagsPacked, image_typePacked,
                                                  num_entries, image_formats, num_image_formats);
    ANGLE_CAPTURE_CL(GetSupportedImageFormats, true, context, flagsPacked, image_typePacked,
                     num_entries, image_formats, num_image_formats, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetMemObjectInfo(cl_mem memobj,
                                      cl_mem_info param_name,
                                      size_t param_value_size,
                                      void *param_value,
                                      size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetMemObjectInfo,
                 "memobj = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)memobj, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    MemInfo param_namePacked = PackParam<MemInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetMemObjectInfo, memobj, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetMemObjectInfo(memobj, param_namePacked, param_value_size, param_value,
                                          param_value_size_ret);
    ANGLE_CAPTURE_CL(GetMemObjectInfo, true, memobj, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetImageInfo(cl_mem image,
                                  cl_image_info param_name,
                                  size_t param_value_size,
                                  void *param_value,
                                  size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetImageInfo,
                 "image = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)image, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    ImageInfo param_namePacked = PackParam<ImageInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetImageInfo, image, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetImageInfo(image, param_namePacked, param_value_size, param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetImageInfo, true, image, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clRetainSampler(cl_sampler sampler)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainSampler, "sampler = 0x%016" PRIxPTR "", (uintptr_t)sampler));

    ANGLE_CL_VALIDATE_ERROR(RetainSampler, sampler);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainSampler(sampler);
    ANGLE_CAPTURE_CL(RetainSampler, true, sampler, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseSampler(cl_sampler sampler)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseSampler, "sampler = 0x%016" PRIxPTR "", (uintptr_t)sampler));

    ANGLE_CL_VALIDATE_ERROR(ReleaseSampler, sampler);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseSampler(sampler);
    ANGLE_CAPTURE_CL(ReleaseSampler, true, sampler, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetSamplerInfo(cl_sampler sampler,
                                    cl_sampler_info param_name,
                                    size_t param_value_size,
                                    void *param_value,
                                    size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetSamplerInfo,
                 "sampler = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)sampler, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    SamplerInfo param_namePacked = PackParam<SamplerInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetSamplerInfo, sampler, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetSamplerInfo(sampler, param_namePacked, param_value_size, param_value,
                                        param_value_size_ret);
    ANGLE_CAPTURE_CL(GetSamplerInfo, true, sampler, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_program CL_API_CALL clCreateProgramWithSource(cl_context context,
                                                 cl_uint count,
                                                 const char **strings,
                                                 const size_t *lengths,
                                                 cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateProgramWithSource,
                               "context = 0x%016" PRIxPTR ", count = %u, strings = 0x%016" PRIxPTR
                               ", lengths = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, count, (uintptr_t)strings, (uintptr_t)lengths,
                               (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateProgramWithSource, context, count, strings, lengths);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_program object = CreateProgramWithSource(context, count, strings, lengths);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateProgramWithSource, true, context, count, strings, lengths, errcode_ret,
                     object);
    return object;
}

cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context,
                                                 cl_uint num_devices,
                                                 const cl_device_id *device_list,
                                                 const size_t *lengths,
                                                 const unsigned char **binaries,
                                                 cl_int *binary_status,
                                                 cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateProgramWithBinary,
                 "context = 0x%016" PRIxPTR ", num_devices = %u, device_list = 0x%016" PRIxPTR
                 ", lengths = 0x%016" PRIxPTR ", binaries = 0x%016" PRIxPTR
                 ", binary_status = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)context, num_devices, (uintptr_t)device_list, (uintptr_t)lengths,
                 (uintptr_t)binaries, (uintptr_t)binary_status, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateProgramWithBinary, context, num_devices, device_list,
                                  lengths, binaries, binary_status);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_program object = CreateProgramWithBinary(context, num_devices, device_list, lengths,
                                                binaries, binary_status);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateProgramWithBinary, true, context, num_devices, device_list, lengths,
                     binaries, binary_status, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clRetainProgram(cl_program program)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainProgram, "program = 0x%016" PRIxPTR "", (uintptr_t)program));

    ANGLE_CL_VALIDATE_ERROR(RetainProgram, program);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainProgram(program);
    ANGLE_CAPTURE_CL(RetainProgram, true, program, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseProgram(cl_program program)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseProgram, "program = 0x%016" PRIxPTR "", (uintptr_t)program));

    ANGLE_CL_VALIDATE_ERROR(ReleaseProgram, program);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseProgram(program);
    ANGLE_CAPTURE_CL(ReleaseProgram, true, program, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clBuildProgram(cl_program program,
                                  cl_uint num_devices,
                                  const cl_device_id *device_list,
                                  const char *options,
                                  void(CL_CALLBACK *pfn_notify)(cl_program program,
                                                                void *user_data),
                                  void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(BuildProgram,
                               "program = 0x%016" PRIxPTR
                               ", num_devices = %u, device_list = 0x%016" PRIxPTR
                               ", options = 0x%016" PRIxPTR ", pfn_notify = 0x%016" PRIxPTR
                               ", user_data = 0x%016" PRIxPTR "",
                               (uintptr_t)program, num_devices, (uintptr_t)device_list,
                               (uintptr_t)options, (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(BuildProgram, program, num_devices, device_list, options, pfn_notify,
                            user_data);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        BuildProgram(program, num_devices, device_list, options, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(BuildProgram, true, program, num_devices, device_list, options, pfn_notify,
                     user_data, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetProgramInfo(cl_program program,
                                    cl_program_info param_name,
                                    size_t param_value_size,
                                    void *param_value,
                                    size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetProgramInfo,
                 "program = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)program, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    ProgramInfo param_namePacked = PackParam<ProgramInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetProgramInfo, program, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetProgramInfo(program, param_namePacked, param_value_size, param_value,
                                        param_value_size_ret);
    ANGLE_CAPTURE_CL(GetProgramInfo, true, program, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetProgramBuildInfo(cl_program program,
                                         cl_device_id device,
                                         cl_program_build_info param_name,
                                         size_t param_value_size,
                                         void *param_value,
                                         size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetProgramBuildInfo,
                 "program = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)program, (uintptr_t)device, param_name, param_value_size,
                 (uintptr_t)param_value, (uintptr_t)param_value_size_ret));

    ProgramBuildInfo param_namePacked = PackParam<ProgramBuildInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetProgramBuildInfo, program, device, param_namePacked,
                            param_value_size, param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetProgramBuildInfo(program, device, param_namePacked, param_value_size,
                                             param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetProgramBuildInfo, true, program, device, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_kernel CL_API_CALL clCreateKernel(cl_program program,
                                     const char *kernel_name,
                                     cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateKernel,
                               "program = 0x%016" PRIxPTR ", kernel_name = 0x%016" PRIxPTR
                               ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)program, (uintptr_t)kernel_name, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateKernel, program, kernel_name);

    cl::gClErrorTls  = CL_SUCCESS;
    cl_kernel object = CreateKernel(program, kernel_name);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateKernel, true, program, kernel_name, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clCreateKernelsInProgram(cl_program program,
                                            cl_uint num_kernels,
                                            cl_kernel *kernels,
                                            cl_uint *num_kernels_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateKernelsInProgram,
                 "program = 0x%016" PRIxPTR ", num_kernels = %u, kernels = 0x%016" PRIxPTR
                 ", num_kernels_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)program, num_kernels, (uintptr_t)kernels, (uintptr_t)num_kernels_ret));

    ANGLE_CL_VALIDATE_ERROR(CreateKernelsInProgram, program, num_kernels, kernels, num_kernels_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = CreateKernelsInProgram(program, num_kernels, kernels, num_kernels_ret);
    ANGLE_CAPTURE_CL(CreateKernelsInProgram, true, program, num_kernels, kernels, num_kernels_ret,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clRetainKernel(cl_kernel kernel)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainKernel, "kernel = 0x%016" PRIxPTR "", (uintptr_t)kernel));

    ANGLE_CL_VALIDATE_ERROR(RetainKernel, kernel);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainKernel(kernel);
    ANGLE_CAPTURE_CL(RetainKernel, true, kernel, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseKernel(cl_kernel kernel)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseKernel, "kernel = 0x%016" PRIxPTR "", (uintptr_t)kernel));

    ANGLE_CL_VALIDATE_ERROR(ReleaseKernel, kernel);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseKernel(kernel);
    ANGLE_CAPTURE_CL(ReleaseKernel, true, kernel, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clSetKernelArg(cl_kernel kernel,
                                  cl_uint arg_index,
                                  size_t arg_size,
                                  const void *arg_value)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetKernelArg,
                               "kernel = 0x%016" PRIxPTR
                               ", arg_index = %u, arg_size = %zu, arg_value = 0x%016" PRIxPTR "",
                               (uintptr_t)kernel, arg_index, arg_size, (uintptr_t)arg_value));

    ANGLE_CL_VALIDATE_ERROR(SetKernelArg, kernel, arg_index, arg_size, arg_value);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetKernelArg(kernel, arg_index, arg_size, arg_value);
    ANGLE_CAPTURE_CL(SetKernelArg, true, kernel, arg_index, arg_size, arg_value, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetKernelInfo(cl_kernel kernel,
                                   cl_kernel_info param_name,
                                   size_t param_value_size,
                                   void *param_value,
                                   size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetKernelInfo,
                 "kernel = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)kernel, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    KernelInfo param_namePacked = PackParam<KernelInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetKernelInfo, kernel, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetKernelInfo(kernel, param_namePacked, param_value_size, param_value,
                                       param_value_size_ret);
    ANGLE_CAPTURE_CL(GetKernelInfo, true, kernel, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetKernelWorkGroupInfo(cl_kernel kernel,
                                            cl_device_id device,
                                            cl_kernel_work_group_info param_name,
                                            size_t param_value_size,
                                            void *param_value,
                                            size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetKernelWorkGroupInfo,
                 "kernel = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)kernel, (uintptr_t)device, param_name, param_value_size,
                 (uintptr_t)param_value, (uintptr_t)param_value_size_ret));

    KernelWorkGroupInfo param_namePacked = PackParam<KernelWorkGroupInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetKernelWorkGroupInfo, kernel, device, param_namePacked,
                            param_value_size, param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetKernelWorkGroupInfo(kernel, device, param_namePacked, param_value_size,
                                                param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetKernelWorkGroupInfo, true, kernel, device, param_namePacked,
                     param_value_size, param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clWaitForEvents(cl_uint num_events, const cl_event *event_list)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(WaitForEvents, "num_events = %u, event_list = 0x%016" PRIxPTR "",
                               num_events, (uintptr_t)event_list));

    ANGLE_CL_VALIDATE_ERROR(WaitForEvents, num_events, event_list);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = WaitForEvents(num_events, event_list);
    ANGLE_CAPTURE_CL(WaitForEvents, true, num_events, event_list, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetEventInfo(cl_event event,
                                  cl_event_info param_name,
                                  size_t param_value_size,
                                  void *param_value,
                                  size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetEventInfo,
                 "event = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)event, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    EventInfo param_namePacked = PackParam<EventInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetEventInfo, event, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetEventInfo(event, param_namePacked, param_value_size, param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetEventInfo, true, event, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clRetainEvent(cl_event event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainEvent, "event = 0x%016" PRIxPTR "", (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(RetainEvent, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainEvent(event);
    ANGLE_CAPTURE_CL(RetainEvent, true, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseEvent(cl_event event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseEvent, "event = 0x%016" PRIxPTR "", (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(ReleaseEvent, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseEvent(event);
    ANGLE_CAPTURE_CL(ReleaseEvent, true, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetEventProfilingInfo(cl_event event,
                                           cl_profiling_info param_name,
                                           size_t param_value_size,
                                           void *param_value,
                                           size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetEventProfilingInfo,
                 "event = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)event, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    ProfilingInfo param_namePacked = PackParam<ProfilingInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetEventProfilingInfo, event, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetEventProfilingInfo(event, param_namePacked, param_value_size,
                                               param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetEventProfilingInfo, true, event, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clFlush(cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(Flush, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(Flush, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = Flush(command_queue);
    ANGLE_CAPTURE_CL(Flush, true, command_queue, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clFinish(cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(Finish, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(Finish, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = Finish(command_queue);
    ANGLE_CAPTURE_CL(Finish, true, command_queue, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue,
                                       cl_mem buffer,
                                       cl_bool blocking_read,
                                       size_t offset,
                                       size_t size,
                                       void *ptr,
                                       cl_uint num_events_in_wait_list,
                                       const cl_event *event_wait_list,
                                       cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueReadBuffer,
        "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR
        ", blocking_read = %u, offset = %zu, size = %zu, ptr = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)buffer, blocking_read, offset, size, (uintptr_t)ptr,
        num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueReadBuffer, command_queue, buffer, blocking_read, offset, size,
                            ptr, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueReadBuffer(command_queue, buffer, blocking_read, offset, size, ptr,
                                           num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueReadBuffer, true, command_queue, buffer, blocking_read, offset, size,
                     ptr, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue,
                                        cl_mem buffer,
                                        cl_bool blocking_write,
                                        size_t offset,
                                        size_t size,
                                        const void *ptr,
                                        cl_uint num_events_in_wait_list,
                                        const cl_event *event_wait_list,
                                        cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueWriteBuffer,
        "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR
        ", blocking_write = %u, offset = %zu, size = %zu, ptr = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)buffer, blocking_write, offset, size, (uintptr_t)ptr,
        num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueWriteBuffer, command_queue, buffer, blocking_write, offset, size,
                            ptr, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueWriteBuffer(command_queue, buffer, blocking_write, offset, size,
                                            ptr, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueWriteBuffer, true, command_queue, buffer, blocking_write, offset, size,
                     ptr, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueCopyBuffer(cl_command_queue command_queue,
                                       cl_mem src_buffer,
                                       cl_mem dst_buffer,
                                       size_t src_offset,
                                       size_t dst_offset,
                                       size_t size,
                                       cl_uint num_events_in_wait_list,
                                       const cl_event *event_wait_list,
                                       cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueCopyBuffer,
        "command_queue = 0x%016" PRIxPTR ", src_buffer = 0x%016" PRIxPTR
        ", dst_buffer = 0x%016" PRIxPTR
        ", src_offset = %zu, dst_offset = %zu, size = %zu, num_events_in_wait_list = %u, "
        "event_wait_list = 0x%016" PRIxPTR ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)src_buffer, (uintptr_t)dst_buffer, src_offset,
        dst_offset, size, num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueCopyBuffer, command_queue, src_buffer, dst_buffer, src_offset,
                            dst_offset, size, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueCopyBuffer(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size,
                          num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueCopyBuffer, true, command_queue, src_buffer, dst_buffer, src_offset,
                     dst_offset, size, num_events_in_wait_list, event_wait_list, event,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueReadImage(cl_command_queue command_queue,
                                      cl_mem image,
                                      cl_bool blocking_read,
                                      const size_t *origin,
                                      const size_t *region,
                                      size_t row_pitch,
                                      size_t slice_pitch,
                                      void *ptr,
                                      cl_uint num_events_in_wait_list,
                                      const cl_event *event_wait_list,
                                      cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueReadImage,
                 "command_queue = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR
                 ", blocking_read = %u, origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
                 ", row_pitch = %zu, slice_pitch = %zu, ptr = 0x%016" PRIxPTR
                 ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, (uintptr_t)image, blocking_read, (uintptr_t)origin,
                 (uintptr_t)region, row_pitch, slice_pitch, (uintptr_t)ptr, num_events_in_wait_list,
                 (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueReadImage, command_queue, image, blocking_read, origin, region,
                            row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list,
                            event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueReadImage(command_queue, image, blocking_read, origin, region, row_pitch,
                         slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueReadImage, true, command_queue, image, blocking_read, origin, region,
                     row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueWriteImage(cl_command_queue command_queue,
                                       cl_mem image,
                                       cl_bool blocking_write,
                                       const size_t *origin,
                                       const size_t *region,
                                       size_t input_row_pitch,
                                       size_t input_slice_pitch,
                                       const void *ptr,
                                       cl_uint num_events_in_wait_list,
                                       const cl_event *event_wait_list,
                                       cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueWriteImage,
                 "command_queue = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR
                 ", blocking_write = %u, origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
                 ", input_row_pitch = %zu, input_slice_pitch = %zu, ptr = 0x%016" PRIxPTR
                 ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, (uintptr_t)image, blocking_write, (uintptr_t)origin,
                 (uintptr_t)region, input_row_pitch, input_slice_pitch, (uintptr_t)ptr,
                 num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueWriteImage, command_queue, image, blocking_write, origin, region,
                            input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueWriteImage(command_queue, image, blocking_write, origin, region, input_row_pitch,
                          input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueWriteImage, true, command_queue, image, blocking_write, origin, region,
                     input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueCopyImage(cl_command_queue command_queue,
                                      cl_mem src_image,
                                      cl_mem dst_image,
                                      const size_t *src_origin,
                                      const size_t *dst_origin,
                                      const size_t *region,
                                      cl_uint num_events_in_wait_list,
                                      const cl_event *event_wait_list,
                                      cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueCopyImage,
                               "command_queue = 0x%016" PRIxPTR ", src_image = 0x%016" PRIxPTR
                               ", dst_image = 0x%016" PRIxPTR ", src_origin = 0x%016" PRIxPTR
                               ", dst_origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)src_image, (uintptr_t)dst_image,
                               (uintptr_t)src_origin, (uintptr_t)dst_origin, (uintptr_t)region,
                               num_events_in_wait_list, (uintptr_t)event_wait_list,
                               (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueCopyImage, command_queue, src_image, dst_image, src_origin,
                            dst_origin, region, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueCopyImage(command_queue, src_image, dst_image, src_origin, dst_origin, region,
                         num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueCopyImage, true, command_queue, src_image, dst_image, src_origin,
                     dst_origin, region, num_events_in_wait_list, event_wait_list, event,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueCopyImageToBuffer(cl_command_queue command_queue,
                                              cl_mem src_image,
                                              cl_mem dst_buffer,
                                              const size_t *src_origin,
                                              const size_t *region,
                                              size_t dst_offset,
                                              cl_uint num_events_in_wait_list,
                                              const cl_event *event_wait_list,
                                              cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueCopyImageToBuffer,
        "command_queue = 0x%016" PRIxPTR ", src_image = 0x%016" PRIxPTR
        ", dst_buffer = 0x%016" PRIxPTR ", src_origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
        ", dst_offset = %zu, num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)src_image, (uintptr_t)dst_buffer,
        (uintptr_t)src_origin, (uintptr_t)region, dst_offset, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueCopyImageToBuffer, command_queue, src_image, dst_buffer,
                            src_origin, region, dst_offset, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueCopyImageToBuffer(command_queue, src_image, dst_buffer, src_origin, region,
                                 dst_offset, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueCopyImageToBuffer, true, command_queue, src_image, dst_buffer,
                     src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list,
                     event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueCopyBufferToImage(cl_command_queue command_queue,
                                              cl_mem src_buffer,
                                              cl_mem dst_image,
                                              size_t src_offset,
                                              const size_t *dst_origin,
                                              const size_t *region,
                                              cl_uint num_events_in_wait_list,
                                              const cl_event *event_wait_list,
                                              cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueCopyBufferToImage,
                 "command_queue = 0x%016" PRIxPTR ", src_buffer = 0x%016" PRIxPTR
                 ", dst_image = 0x%016" PRIxPTR ", src_offset = %zu, dst_origin = 0x%016" PRIxPTR
                 ", region = 0x%016" PRIxPTR
                 ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, (uintptr_t)src_buffer, (uintptr_t)dst_image, src_offset,
                 (uintptr_t)dst_origin, (uintptr_t)region, num_events_in_wait_list,
                 (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueCopyBufferToImage, command_queue, src_buffer, dst_image,
                            src_offset, dst_origin, region, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueCopyBufferToImage(command_queue, src_buffer, dst_image, src_offset, dst_origin,
                                 region, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueCopyBufferToImage, true, command_queue, src_buffer, dst_image,
                     src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list,
                     event, returnValue);
    return returnValue;
}

void *CL_API_CALL clEnqueueMapBuffer(cl_command_queue command_queue,
                                     cl_mem buffer,
                                     cl_bool blocking_map,
                                     cl_map_flags map_flags,
                                     size_t offset,
                                     size_t size,
                                     cl_uint num_events_in_wait_list,
                                     const cl_event *event_wait_list,
                                     cl_event *event,
                                     cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueMapBuffer,
                               "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR
                               ", blocking_map = %u, map_flags = %llu, offset = %zu, size = %zu, "
                               "num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)buffer, blocking_map,
                               static_cast<unsigned long long>(map_flags), offset, size,
                               num_events_in_wait_list, (uintptr_t)event_wait_list,
                               (uintptr_t)event, (uintptr_t)errcode_ret));

    MapFlags map_flagsPacked = PackParam<MapFlags>(map_flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(EnqueueMapBuffer, command_queue, buffer, blocking_map,
                                  map_flagsPacked, offset, size, num_events_in_wait_list,
                                  event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    void *object    = EnqueueMapBuffer(command_queue, buffer, blocking_map, map_flagsPacked, offset,
                                       size, num_events_in_wait_list, event_wait_list, event);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(EnqueueMapBuffer, true, command_queue, buffer, blocking_map, map_flagsPacked,
                     offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret,
                     object);
    return object;
}

void *CL_API_CALL clEnqueueMapImage(cl_command_queue command_queue,
                                    cl_mem image,
                                    cl_bool blocking_map,
                                    cl_map_flags map_flags,
                                    const size_t *origin,
                                    const size_t *region,
                                    size_t *image_row_pitch,
                                    size_t *image_slice_pitch,
                                    cl_uint num_events_in_wait_list,
                                    const cl_event *event_wait_list,
                                    cl_event *event,
                                    cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueMapImage,
        "command_queue = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR
        ", blocking_map = %u, map_flags = %llu, origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
        ", image_row_pitch = 0x%016" PRIxPTR ", image_slice_pitch = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)image, blocking_map,
        static_cast<unsigned long long>(map_flags), (uintptr_t)origin, (uintptr_t)region,
        (uintptr_t)image_row_pitch, (uintptr_t)image_slice_pitch, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event, (uintptr_t)errcode_ret));

    MapFlags map_flagsPacked = PackParam<MapFlags>(map_flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(
        EnqueueMapImage, command_queue, image, blocking_map, map_flagsPacked, origin, region,
        image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    void *object    = EnqueueMapImage(command_queue, image, blocking_map, map_flagsPacked, origin,
                                      region, image_row_pitch, image_slice_pitch,
                                      num_events_in_wait_list, event_wait_list, event);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(EnqueueMapImage, true, command_queue, image, blocking_map, map_flagsPacked,
                     origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list,
                     event_wait_list, event, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clEnqueueUnmapMemObject(cl_command_queue command_queue,
                                           cl_mem memobj,
                                           void *mapped_ptr,
                                           cl_uint num_events_in_wait_list,
                                           const cl_event *event_wait_list,
                                           cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueUnmapMemObject,
        "command_queue = 0x%016" PRIxPTR ", memobj = 0x%016" PRIxPTR ", mapped_ptr = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)memobj, (uintptr_t)mapped_ptr, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueUnmapMemObject, command_queue, memobj, mapped_ptr,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueUnmapMemObject(command_queue, memobj, mapped_ptr,
                                               num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueUnmapMemObject, true, command_queue, memobj, mapped_ptr,
                     num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue command_queue,
                                          cl_kernel kernel,
                                          cl_uint work_dim,
                                          const size_t *global_work_offset,
                                          const size_t *global_work_size,
                                          const size_t *local_work_size,
                                          cl_uint num_events_in_wait_list,
                                          const cl_event *event_wait_list,
                                          cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueNDRangeKernel,
        "command_queue = 0x%016" PRIxPTR ", kernel = 0x%016" PRIxPTR
        ", work_dim = %u, global_work_offset = 0x%016" PRIxPTR ", global_work_size = 0x%016" PRIxPTR
        ", local_work_size = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)kernel, work_dim, (uintptr_t)global_work_offset,
        (uintptr_t)global_work_size, (uintptr_t)local_work_size, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueNDRangeKernel, command_queue, kernel, work_dim,
                            global_work_offset, global_work_size, local_work_size,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueNDRangeKernel(command_queue, kernel, work_dim, global_work_offset, global_work_size,
                             local_work_size, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueNDRangeKernel, true, command_queue, kernel, work_dim,
                     global_work_offset, global_work_size, local_work_size, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueNativeKernel(cl_command_queue command_queue,
                                         void(CL_CALLBACK *user_func)(void *),
                                         void *args,
                                         size_t cb_args,
                                         cl_uint num_mem_objects,
                                         const cl_mem *mem_list,
                                         const void **args_mem_loc,
                                         cl_uint num_events_in_wait_list,
                                         const cl_event *event_wait_list,
                                         cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueNativeKernel,
        "command_queue = 0x%016" PRIxPTR ", user_func = 0x%016" PRIxPTR ", args = 0x%016" PRIxPTR
        ", cb_args = %zu, num_mem_objects = %u, mem_list = 0x%016" PRIxPTR
        ", args_mem_loc = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)user_func, (uintptr_t)args, cb_args, num_mem_objects,
        (uintptr_t)mem_list, (uintptr_t)args_mem_loc, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueNativeKernel, command_queue, user_func, args, cb_args,
                            num_mem_objects, mem_list, args_mem_loc, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueNativeKernel(command_queue, user_func, args, cb_args, num_mem_objects, mem_list,
                            args_mem_loc, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueNativeKernel, true, command_queue, user_func, args, cb_args,
                     num_mem_objects, mem_list, args_mem_loc, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clSetCommandQueueProperty(cl_command_queue command_queue,
                                             cl_command_queue_properties properties,
                                             cl_bool enable,
                                             cl_command_queue_properties *old_properties)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(SetCommandQueueProperty,
                 "command_queue = 0x%016" PRIxPTR
                 ", properties = %llu, enable = %u, old_properties = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, static_cast<unsigned long long>(properties), enable,
                 (uintptr_t)old_properties));

    CommandQueueProperties propertiesPacked = PackParam<CommandQueueProperties>(properties);

    ANGLE_CL_VALIDATE_ERROR(SetCommandQueueProperty, command_queue, propertiesPacked, enable,
                            old_properties);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        SetCommandQueueProperty(command_queue, propertiesPacked, enable, old_properties);
    ANGLE_CAPTURE_CL(SetCommandQueueProperty, true, command_queue, propertiesPacked, enable,
                     old_properties, returnValue);
    return returnValue;
}

cl_mem CL_API_CALL clCreateImage2D(cl_context context,
                                   cl_mem_flags flags,
                                   const cl_image_format *image_format,
                                   size_t image_width,
                                   size_t image_height,
                                   size_t image_row_pitch,
                                   void *host_ptr,
                                   cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CreateImage2D,
        "context = 0x%016" PRIxPTR ", flags = %llu, image_format = 0x%016" PRIxPTR
        ", image_width = %zu, image_height = %zu, image_row_pitch = %zu, host_ptr = 0x%016" PRIxPTR
        ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, static_cast<unsigned long long>(flags), (uintptr_t)image_format,
        image_width, image_height, image_row_pitch, (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateImage2D, context, flagsPacked, image_format, image_width,
                                  image_height, image_row_pitch, host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateImage2D(context, flagsPacked, image_format, image_width, image_height,
                                    image_row_pitch, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateImage2D, true, context, flagsPacked, image_format, image_width,
                     image_height, image_row_pitch, host_ptr, errcode_ret, object);
    return object;
}

cl_mem CL_API_CALL clCreateImage3D(cl_context context,
                                   cl_mem_flags flags,
                                   const cl_image_format *image_format,
                                   size_t image_width,
                                   size_t image_height,
                                   size_t image_depth,
                                   size_t image_row_pitch,
                                   size_t image_slice_pitch,
                                   void *host_ptr,
                                   cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CreateImage3D,
        "context = 0x%016" PRIxPTR ", flags = %llu, image_format = 0x%016" PRIxPTR
        ", image_width = %zu, image_height = %zu, image_depth = %zu, image_row_pitch = %zu, "
        "image_slice_pitch = %zu, host_ptr = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, static_cast<unsigned long long>(flags), (uintptr_t)image_format,
        image_width, image_height, image_depth, image_row_pitch, image_slice_pitch,
        (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateImage3D, context, flagsPacked, image_format, image_width,
                                  image_height, image_depth, image_row_pitch, image_slice_pitch,
                                  host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateImage3D(context, flagsPacked, image_format, image_width, image_height,
                                    image_depth, image_row_pitch, image_slice_pitch, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateImage3D, true, context, flagsPacked, image_format, image_width,
                     image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr,
                     errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clEnqueueMarker(cl_command_queue command_queue, cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueMarker,
                               "command_queue = 0x%016" PRIxPTR ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueMarker, command_queue, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueMarker(command_queue, event);
    ANGLE_CAPTURE_CL(EnqueueMarker, true, command_queue, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueWaitForEvents(cl_command_queue command_queue,
                                          cl_uint num_events,
                                          const cl_event *event_list)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueWaitForEvents,
                               "command_queue = 0x%016" PRIxPTR
                               ", num_events = %u, event_list = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, num_events, (uintptr_t)event_list));

    ANGLE_CL_VALIDATE_ERROR(EnqueueWaitForEvents, command_queue, num_events, event_list);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueWaitForEvents(command_queue, num_events, event_list);
    ANGLE_CAPTURE_CL(EnqueueWaitForEvents, true, command_queue, num_events, event_list,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueBarrier(cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueBarrier, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(EnqueueBarrier, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueBarrier(command_queue);
    ANGLE_CAPTURE_CL(EnqueueBarrier, true, command_queue, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clUnloadCompiler()
{
    ANGLE_UNSAFE_TODO(CL_EVENT(UnloadCompiler, ""));

    ANGLE_CL_VALIDATE_ERROR(UnloadCompiler);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = UnloadCompiler();
    ANGLE_CAPTURE_CL(UnloadCompiler, true, returnValue);
    return returnValue;
}

void *CL_API_CALL clGetExtensionFunctionAddress(const char *func_name)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(GetExtensionFunctionAddress, "func_name = 0x%016" PRIxPTR "",
                               (uintptr_t)func_name));

    cl::gClErrorTls = CL_SUCCESS;
    ANGLE_CL_VALIDATE_POINTER(GetExtensionFunctionAddress, func_name);

    void *returnValue = GetExtensionFunctionAddress(func_name);
    ANGLE_CAPTURE_CL(GetExtensionFunctionAddress, true, func_name, returnValue);
    return returnValue;
}

cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context,
                                                  cl_device_id device,
                                                  cl_command_queue_properties properties,
                                                  cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateCommandQueue,
                               "context = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
                               ", properties = %llu, errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)device,
                               static_cast<unsigned long long>(properties),
                               (uintptr_t)errcode_ret));

    CommandQueueProperties propertiesPacked = PackParam<CommandQueueProperties>(properties);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateCommandQueue, context, device, propertiesPacked);

    cl::gClErrorTls         = CL_SUCCESS;
    cl_command_queue object = CreateCommandQueue(context, device, propertiesPacked);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateCommandQueue, true, context, device, propertiesPacked, errcode_ret,
                     object);
    return object;
}

cl_sampler CL_API_CALL clCreateSampler(cl_context context,
                                       cl_bool normalized_coords,
                                       cl_addressing_mode addressing_mode,
                                       cl_filter_mode filter_mode,
                                       cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateSampler,
                               "context = 0x%016" PRIxPTR
                               ", normalized_coords = %u, addressing_mode = %u, filter_mode = %u, "
                               "errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, normalized_coords, addressing_mode, filter_mode,
                               (uintptr_t)errcode_ret));

    AddressingMode addressing_modePacked = PackParam<AddressingMode>(addressing_mode);
    FilterMode filter_modePacked         = PackParam<FilterMode>(filter_mode);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateSampler, context, normalized_coords, addressing_modePacked,
                                  filter_modePacked);

    cl::gClErrorTls = CL_SUCCESS;
    cl_sampler object =
        CreateSampler(context, normalized_coords, addressing_modePacked, filter_modePacked);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateSampler, true, context, normalized_coords, addressing_modePacked,
                     filter_modePacked, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clEnqueueTask(cl_command_queue command_queue,
                                 cl_kernel kernel,
                                 cl_uint num_events_in_wait_list,
                                 const cl_event *event_wait_list,
                                 cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueTask,
                               "command_queue = 0x%016" PRIxPTR ", kernel = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)kernel, num_events_in_wait_list,
                               (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueTask, command_queue, kernel, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueTask(command_queue, kernel, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueTask, true, command_queue, kernel, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

// CL 1.1
cl_mem CL_API_CALL clCreateSubBuffer(cl_mem buffer,
                                     cl_mem_flags flags,
                                     cl_buffer_create_type buffer_create_type,
                                     const void *buffer_create_info,
                                     cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateSubBuffer,
                 "buffer = 0x%016" PRIxPTR
                 ", flags = %llu, buffer_create_type = %u, buffer_create_info = 0x%016" PRIxPTR
                 ", errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)buffer, static_cast<unsigned long long>(flags), buffer_create_type,
                 (uintptr_t)buffer_create_info, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateSubBuffer, buffer, flagsPacked, buffer_create_type,
                                  buffer_create_info);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateSubBuffer(buffer, flagsPacked, buffer_create_type, buffer_create_info);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateSubBuffer, true, buffer, flagsPacked, buffer_create_type,
                     buffer_create_info, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clSetMemObjectDestructorCallback(cl_mem memobj,
                                                    void(CL_CALLBACK *pfn_notify)(cl_mem memobj,
                                                                                  void *user_data),
                                                    void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetMemObjectDestructorCallback,
                               "memobj = 0x%016" PRIxPTR ", pfn_notify = 0x%016" PRIxPTR
                               ", user_data = 0x%016" PRIxPTR "",
                               (uintptr_t)memobj, (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(SetMemObjectDestructorCallback, memobj, pfn_notify, user_data);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetMemObjectDestructorCallback(memobj, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(SetMemObjectDestructorCallback, true, memobj, pfn_notify, user_data,
                     returnValue);
    return returnValue;
}

cl_event CL_API_CALL clCreateUserEvent(cl_context context, cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateUserEvent,
                               "context = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateUserEvent, context);

    cl::gClErrorTls = CL_SUCCESS;
    cl_event object = CreateUserEvent(context);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateUserEvent, true, context, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clSetUserEventStatus(cl_event event, cl_int execution_status)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetUserEventStatus,
                               "event = 0x%016" PRIxPTR ", execution_status = %d", (uintptr_t)event,
                               execution_status));

    ANGLE_CL_VALIDATE_ERROR(SetUserEventStatus, event, execution_status);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetUserEventStatus(event, execution_status);
    ANGLE_CAPTURE_CL(SetUserEventStatus, true, event, execution_status, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clSetEventCallback(cl_event event,
                                      cl_int command_exec_callback_type,
                                      void(CL_CALLBACK *pfn_notify)(cl_event event,
                                                                    cl_int event_command_status,
                                                                    void *user_data),
                                      void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        SetEventCallback,
        "event = 0x%016" PRIxPTR ", command_exec_callback_type = %d, pfn_notify = 0x%016" PRIxPTR
        ", user_data = 0x%016" PRIxPTR "",
        (uintptr_t)event, command_exec_callback_type, (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(SetEventCallback, event, command_exec_callback_type, pfn_notify,
                            user_data);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetEventCallback(event, command_exec_callback_type, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(SetEventCallback, true, event, command_exec_callback_type, pfn_notify,
                     user_data, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueReadBufferRect(cl_command_queue command_queue,
                                           cl_mem buffer,
                                           cl_bool blocking_read,
                                           const size_t *buffer_origin,
                                           const size_t *host_origin,
                                           const size_t *region,
                                           size_t buffer_row_pitch,
                                           size_t buffer_slice_pitch,
                                           size_t host_row_pitch,
                                           size_t host_slice_pitch,
                                           void *ptr,
                                           cl_uint num_events_in_wait_list,
                                           const cl_event *event_wait_list,
                                           cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueReadBufferRect,
                               "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR
                               ", blocking_read = %u, buffer_origin = 0x%016" PRIxPTR
                               ", host_origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
                               ", buffer_row_pitch = %zu, buffer_slice_pitch = %zu, host_row_pitch "
                               "= %zu, host_slice_pitch = %zu, ptr = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)buffer, blocking_read,
                               (uintptr_t)buffer_origin, (uintptr_t)host_origin, (uintptr_t)region,
                               buffer_row_pitch, buffer_slice_pitch, host_row_pitch,
                               host_slice_pitch, (uintptr_t)ptr, num_events_in_wait_list,
                               (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueReadBufferRect, command_queue, buffer, blocking_read,
                            buffer_origin, host_origin, region, buffer_row_pitch,
                            buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueReadBufferRect(
        command_queue, buffer, blocking_read, buffer_origin, host_origin, region, buffer_row_pitch,
        buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
        event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueReadBufferRect, true, command_queue, buffer, blocking_read,
                     buffer_origin, host_origin, region, buffer_row_pitch, buffer_slice_pitch,
                     host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueWriteBufferRect(cl_command_queue command_queue,
                                            cl_mem buffer,
                                            cl_bool blocking_write,
                                            const size_t *buffer_origin,
                                            const size_t *host_origin,
                                            const size_t *region,
                                            size_t buffer_row_pitch,
                                            size_t buffer_slice_pitch,
                                            size_t host_row_pitch,
                                            size_t host_slice_pitch,
                                            const void *ptr,
                                            cl_uint num_events_in_wait_list,
                                            const cl_event *event_wait_list,
                                            cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueWriteBufferRect,
                               "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR
                               ", blocking_write = %u, buffer_origin = 0x%016" PRIxPTR
                               ", host_origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
                               ", buffer_row_pitch = %zu, buffer_slice_pitch = %zu, host_row_pitch "
                               "= %zu, host_slice_pitch = %zu, ptr = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)buffer, blocking_write,
                               (uintptr_t)buffer_origin, (uintptr_t)host_origin, (uintptr_t)region,
                               buffer_row_pitch, buffer_slice_pitch, host_row_pitch,
                               host_slice_pitch, (uintptr_t)ptr, num_events_in_wait_list,
                               (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueWriteBufferRect, command_queue, buffer, blocking_write,
                            buffer_origin, host_origin, region, buffer_row_pitch,
                            buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueWriteBufferRect(
        command_queue, buffer, blocking_write, buffer_origin, host_origin, region, buffer_row_pitch,
        buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
        event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueWriteBufferRect, true, command_queue, buffer, blocking_write,
                     buffer_origin, host_origin, region, buffer_row_pitch, buffer_slice_pitch,
                     host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueCopyBufferRect(cl_command_queue command_queue,
                                           cl_mem src_buffer,
                                           cl_mem dst_buffer,
                                           const size_t *src_origin,
                                           const size_t *dst_origin,
                                           const size_t *region,
                                           size_t src_row_pitch,
                                           size_t src_slice_pitch,
                                           size_t dst_row_pitch,
                                           size_t dst_slice_pitch,
                                           cl_uint num_events_in_wait_list,
                                           const cl_event *event_wait_list,
                                           cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueCopyBufferRect,
        "command_queue = 0x%016" PRIxPTR ", src_buffer = 0x%016" PRIxPTR
        ", dst_buffer = 0x%016" PRIxPTR ", src_origin = 0x%016" PRIxPTR
        ", dst_origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
        ", src_row_pitch = %zu, src_slice_pitch = %zu, dst_row_pitch = %zu, dst_slice_pitch = %zu, "
        "num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR ", event = 0x%016" PRIxPTR
        "",
        (uintptr_t)command_queue, (uintptr_t)src_buffer, (uintptr_t)dst_buffer,
        (uintptr_t)src_origin, (uintptr_t)dst_origin, (uintptr_t)region, src_row_pitch,
        src_slice_pitch, dst_row_pitch, dst_slice_pitch, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueCopyBufferRect, command_queue, src_buffer, dst_buffer,
                            src_origin, dst_origin, region, src_row_pitch, src_slice_pitch,
                            dst_row_pitch, dst_slice_pitch, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueCopyBufferRect(command_queue, src_buffer, dst_buffer, src_origin, dst_origin, region,
                              src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch,
                              num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueCopyBufferRect, true, command_queue, src_buffer, dst_buffer, src_origin,
                     dst_origin, region, src_row_pitch, src_slice_pitch, dst_row_pitch,
                     dst_slice_pitch, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

// CL 1.2
cl_int CL_API_CALL clCreateSubDevices(cl_device_id in_device,
                                      const cl_device_partition_property *properties,
                                      cl_uint num_devices,
                                      cl_device_id *out_devices,
                                      cl_uint *num_devices_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateSubDevices,
                               "in_device = 0x%016" PRIxPTR ", properties = 0x%016" PRIxPTR
                               ", num_devices = %u, out_devices = 0x%016" PRIxPTR
                               ", num_devices_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)in_device, (uintptr_t)properties, num_devices,
                               (uintptr_t)out_devices, (uintptr_t)num_devices_ret));

    ANGLE_CL_VALIDATE_ERROR(CreateSubDevices, in_device, properties, num_devices, out_devices,
                            num_devices_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        CreateSubDevices(in_device, properties, num_devices, out_devices, num_devices_ret);
    ANGLE_CAPTURE_CL(CreateSubDevices, true, in_device, properties, num_devices, out_devices,
                     num_devices_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clRetainDevice(cl_device_id device)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(RetainDevice, "device = 0x%016" PRIxPTR "", (uintptr_t)device));

    ANGLE_CL_VALIDATE_ERROR(RetainDevice, device);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = RetainDevice(device);
    ANGLE_CAPTURE_CL(RetainDevice, true, device, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clReleaseDevice(cl_device_id device)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(ReleaseDevice, "device = 0x%016" PRIxPTR "", (uintptr_t)device));

    ANGLE_CL_VALIDATE_ERROR(ReleaseDevice, device);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = ReleaseDevice(device);
    ANGLE_CAPTURE_CL(ReleaseDevice, true, device, returnValue);
    return returnValue;
}

cl_mem CL_API_CALL clCreateImage(cl_context context,
                                 cl_mem_flags flags,
                                 const cl_image_format *image_format,
                                 const cl_image_desc *image_desc,
                                 void *host_ptr,
                                 cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CreateImage,
        "context = 0x%016" PRIxPTR ", flags = %llu, image_format = 0x%016" PRIxPTR
        ", image_desc = 0x%016" PRIxPTR ", host_ptr = 0x%016" PRIxPTR
        ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, static_cast<unsigned long long>(flags), (uintptr_t)image_format,
        (uintptr_t)image_desc, (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateImage, context, flagsPacked, image_format, image_desc,
                                  host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateImage(context, flagsPacked, image_format, image_desc, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateImage, true, context, flagsPacked, image_format, image_desc, host_ptr,
                     errcode_ret, object);
    return object;
}

cl_program CL_API_CALL clCreateProgramWithBuiltInKernels(cl_context context,
                                                         cl_uint num_devices,
                                                         const cl_device_id *device_list,
                                                         const char *kernel_names,
                                                         cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(CreateProgramWithBuiltInKernels,
                 "context = 0x%016" PRIxPTR ", num_devices = %u, device_list = 0x%016" PRIxPTR
                 ", kernel_names = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)context, num_devices, (uintptr_t)device_list, (uintptr_t)kernel_names,
                 (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateProgramWithBuiltInKernels, context, num_devices,
                                  device_list, kernel_names);

    cl::gClErrorTls = CL_SUCCESS;
    cl_program object =
        CreateProgramWithBuiltInKernels(context, num_devices, device_list, kernel_names);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateProgramWithBuiltInKernels, true, context, num_devices, device_list,
                     kernel_names, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clCompileProgram(cl_program program,
                                    cl_uint num_devices,
                                    const cl_device_id *device_list,
                                    const char *options,
                                    cl_uint num_input_headers,
                                    const cl_program *input_headers,
                                    const char **header_include_names,
                                    void(CL_CALLBACK *pfn_notify)(cl_program program,
                                                                  void *user_data),
                                    void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CompileProgram,
        "program = 0x%016" PRIxPTR ", num_devices = %u, device_list = 0x%016" PRIxPTR
        ", options = 0x%016" PRIxPTR ", num_input_headers = %u, input_headers = 0x%016" PRIxPTR
        ", header_include_names = 0x%016" PRIxPTR ", pfn_notify = 0x%016" PRIxPTR
        ", user_data = 0x%016" PRIxPTR "",
        (uintptr_t)program, num_devices, (uintptr_t)device_list, (uintptr_t)options,
        num_input_headers, (uintptr_t)input_headers, (uintptr_t)header_include_names,
        (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(CompileProgram, program, num_devices, device_list, options,
                            num_input_headers, input_headers, header_include_names, pfn_notify,
                            user_data);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        CompileProgram(program, num_devices, device_list, options, num_input_headers, input_headers,
                       header_include_names, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(CompileProgram, true, program, num_devices, device_list, options,
                     num_input_headers, input_headers, header_include_names, pfn_notify, user_data,
                     returnValue);
    return returnValue;
}

cl_program CL_API_CALL clLinkProgram(cl_context context,
                                     cl_uint num_devices,
                                     const cl_device_id *device_list,
                                     const char *options,
                                     cl_uint num_input_programs,
                                     const cl_program *input_programs,
                                     void(CL_CALLBACK *pfn_notify)(cl_program program,
                                                                   void *user_data),
                                     void *user_data,
                                     cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        LinkProgram,
        "context = 0x%016" PRIxPTR ", num_devices = %u, device_list = 0x%016" PRIxPTR
        ", options = 0x%016" PRIxPTR ", num_input_programs = %u, input_programs = 0x%016" PRIxPTR
        ", pfn_notify = 0x%016" PRIxPTR ", user_data = 0x%016" PRIxPTR
        ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, num_devices, (uintptr_t)device_list, (uintptr_t)options,
        num_input_programs, (uintptr_t)input_programs, (uintptr_t)pfn_notify, (uintptr_t)user_data,
        (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(LinkProgram, context, num_devices, device_list, options,
                                  num_input_programs, input_programs, pfn_notify, user_data);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_program object = LinkProgram(context, num_devices, device_list, options, num_input_programs,
                                    input_programs, pfn_notify, user_data);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(LinkProgram, true, context, num_devices, device_list, options,
                     num_input_programs, input_programs, pfn_notify, user_data, errcode_ret,
                     object);
    return object;
}

cl_int CL_API_CALL clUnloadPlatformCompiler(cl_platform_id platform)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(UnloadPlatformCompiler, "platform = 0x%016" PRIxPTR "", (uintptr_t)platform));

    ANGLE_CL_VALIDATE_ERROR(UnloadPlatformCompiler, platform);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = UnloadPlatformCompiler(platform);
    ANGLE_CAPTURE_CL(UnloadPlatformCompiler, true, platform, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetKernelArgInfo(cl_kernel kernel,
                                      cl_uint arg_index,
                                      cl_kernel_arg_info param_name,
                                      size_t param_value_size,
                                      void *param_value,
                                      size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        GetKernelArgInfo,
        "kernel = 0x%016" PRIxPTR
        ", arg_index = %u, param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
        ", param_value_size_ret = 0x%016" PRIxPTR "",
        (uintptr_t)kernel, arg_index, param_name, param_value_size, (uintptr_t)param_value,
        (uintptr_t)param_value_size_ret));

    KernelArgInfo param_namePacked = PackParam<KernelArgInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetKernelArgInfo, kernel, arg_index, param_namePacked, param_value_size,
                            param_value, param_value_size_ret);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetKernelArgInfo(kernel, arg_index, param_namePacked, param_value_size,
                                          param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetKernelArgInfo, true, kernel, arg_index, param_namePacked, param_value_size,
                     param_value, param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueFillBuffer(cl_command_queue command_queue,
                                       cl_mem buffer,
                                       const void *pattern,
                                       size_t pattern_size,
                                       size_t offset,
                                       size_t size,
                                       cl_uint num_events_in_wait_list,
                                       const cl_event *event_wait_list,
                                       cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueFillBuffer,
        "command_queue = 0x%016" PRIxPTR ", buffer = 0x%016" PRIxPTR ", pattern = 0x%016" PRIxPTR
        ", pattern_size = %zu, offset = %zu, size = %zu, num_events_in_wait_list = %u, "
        "event_wait_list = 0x%016" PRIxPTR ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)buffer, (uintptr_t)pattern, pattern_size, offset, size,
        num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueFillBuffer, command_queue, buffer, pattern, pattern_size, offset,
                            size, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueFillBuffer(command_queue, buffer, pattern, pattern_size, offset,
                                           size, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueFillBuffer, true, command_queue, buffer, pattern, pattern_size, offset,
                     size, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueFillImage(cl_command_queue command_queue,
                                      cl_mem image,
                                      const void *fill_color,
                                      const size_t *origin,
                                      const size_t *region,
                                      cl_uint num_events_in_wait_list,
                                      const cl_event *event_wait_list,
                                      cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueFillImage,
        "command_queue = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR ", fill_color = 0x%016" PRIxPTR
        ", origin = 0x%016" PRIxPTR ", region = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)image, (uintptr_t)fill_color, (uintptr_t)origin,
        (uintptr_t)region, num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueFillImage, command_queue, image, fill_color, origin, region,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueFillImage(command_queue, image, fill_color, origin, region,
                                          num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueFillImage, true, command_queue, image, fill_color, origin, region,
                     num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueMigrateMemObjects(cl_command_queue command_queue,
                                              cl_uint num_mem_objects,
                                              const cl_mem *mem_objects,
                                              cl_mem_migration_flags flags,
                                              cl_uint num_events_in_wait_list,
                                              const cl_event *event_wait_list,
                                              cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueMigrateMemObjects,
        "command_queue = 0x%016" PRIxPTR ", num_mem_objects = %u, mem_objects = 0x%016" PRIxPTR
        ", flags = %llu, num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, num_mem_objects, (uintptr_t)mem_objects,
        static_cast<unsigned long long>(flags), num_events_in_wait_list, (uintptr_t)event_wait_list,
        (uintptr_t)event));

    MemMigrationFlags flagsPacked = PackParam<MemMigrationFlags>(flags);

    ANGLE_CL_VALIDATE_ERROR(EnqueueMigrateMemObjects, command_queue, num_mem_objects, mem_objects,
                            flagsPacked, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueMigrateMemObjects(command_queue, num_mem_objects, mem_objects, flagsPacked,
                                 num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueMigrateMemObjects, true, command_queue, num_mem_objects, mem_objects,
                     flagsPacked, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueMarkerWithWaitList(cl_command_queue command_queue,
                                               cl_uint num_events_in_wait_list,
                                               const cl_event *event_wait_list,
                                               cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueMarkerWithWaitList,
                               "command_queue = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, num_events_in_wait_list,
                               (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueMarkerWithWaitList, command_queue, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueMarkerWithWaitList(command_queue, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueMarkerWithWaitList, true, command_queue, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueBarrierWithWaitList(cl_command_queue command_queue,
                                                cl_uint num_events_in_wait_list,
                                                const cl_event *event_wait_list,
                                                cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueBarrierWithWaitList,
                               "command_queue = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, num_events_in_wait_list,
                               (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueBarrierWithWaitList, command_queue, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueBarrierWithWaitList(command_queue, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueBarrierWithWaitList, true, command_queue, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

void *CL_API_CALL clGetExtensionFunctionAddressForPlatform(cl_platform_id platform,
                                                           const char *func_name)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(GetExtensionFunctionAddressForPlatform,
                               "platform = 0x%016" PRIxPTR ", func_name = 0x%016" PRIxPTR "",
                               (uintptr_t)platform, (uintptr_t)func_name));

    cl::gClErrorTls = CL_SUCCESS;
    ANGLE_CL_VALIDATE_POINTER(GetExtensionFunctionAddressForPlatform, platform, func_name);

    void *returnValue = GetExtensionFunctionAddressForPlatform(platform, func_name);
    ANGLE_CAPTURE_CL(GetExtensionFunctionAddressForPlatform, true, platform, func_name,
                     returnValue);
    return returnValue;
}

// CL 2.0
cl_command_queue CL_API_CALL
clCreateCommandQueueWithProperties(cl_context context,
                                   cl_device_id device,
                                   const cl_queue_properties *properties,
                                   cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateCommandQueueWithProperties,
                               "context = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
                               ", properties = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)device, (uintptr_t)properties,
                               (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateCommandQueueWithProperties, context, device, properties);

    cl::gClErrorTls         = CL_SUCCESS;
    cl_command_queue object = CreateCommandQueueWithProperties(context, device, properties);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateCommandQueueWithProperties, true, context, device, properties,
                     errcode_ret, object);
    return object;
}

cl_mem CL_API_CALL clCreatePipe(cl_context context,
                                cl_mem_flags flags,
                                cl_uint pipe_packet_size,
                                cl_uint pipe_max_packets,
                                const cl_pipe_properties *properties,
                                cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CreatePipe,
        "context = 0x%016" PRIxPTR
        ", flags = %llu, pipe_packet_size = %u, pipe_max_packets = %u, properties = 0x%016" PRIxPTR
        ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, static_cast<unsigned long long>(flags), pipe_packet_size,
        pipe_max_packets, (uintptr_t)properties, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreatePipe, context, flagsPacked, pipe_packet_size,
                                  pipe_max_packets, properties);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object =
        CreatePipe(context, flagsPacked, pipe_packet_size, pipe_max_packets, properties);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreatePipe, true, context, flagsPacked, pipe_packet_size, pipe_max_packets,
                     properties, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clGetPipeInfo(cl_mem pipe,
                                 cl_pipe_info param_name,
                                 size_t param_value_size,
                                 void *param_value,
                                 size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetPipeInfo,
                 "pipe = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)pipe, param_name, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    PipeInfo param_namePacked = PackParam<PipeInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetPipeInfo, pipe, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetPipeInfo(pipe, param_namePacked, param_value_size, param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetPipeInfo, true, pipe, param_namePacked, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

void *CL_API_CALL clSVMAlloc(cl_context context,
                             cl_svm_mem_flags flags,
                             size_t size,
                             cl_uint alignment)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(SVMAlloc, "context = 0x%016" PRIxPTR ", flags = %llu, size = %zu, alignment = %u",
                 (uintptr_t)context, static_cast<unsigned long long>(flags), size, alignment));

    SVM_MemFlags flagsPacked = PackParam<SVM_MemFlags>(flags);

    cl::gClErrorTls = CL_SUCCESS;
    ANGLE_CL_VALIDATE_POINTER(SVMAlloc, context, flagsPacked, size, alignment);

    void *returnValue = SVMAlloc(context, flagsPacked, size, alignment);
    ANGLE_CAPTURE_CL(SVMAlloc, true, context, flagsPacked, size, alignment, returnValue);
    return returnValue;
}

void CL_API_CALL clSVMFree(cl_context context, void *svm_pointer)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SVMFree,
                               "context = 0x%016" PRIxPTR ", svm_pointer = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)svm_pointer));

    ANGLE_CL_VALIDATE_VOID(SVMFree, context, svm_pointer);

    cl::gClErrorTls = CL_SUCCESS;
    SVMFree(context, svm_pointer);
    ANGLE_CAPTURE_CL(SVMFree, true, context, svm_pointer);
}

cl_sampler CL_API_CALL
clCreateSamplerWithProperties(cl_context context,
                              const cl_sampler_properties *sampler_properties,
                              cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateSamplerWithProperties,
                               "context = 0x%016" PRIxPTR ", sampler_properties = 0x%016" PRIxPTR
                               ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)sampler_properties,
                               (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateSamplerWithProperties, context, sampler_properties);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_sampler object = CreateSamplerWithProperties(context, sampler_properties);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateSamplerWithProperties, true, context, sampler_properties, errcode_ret,
                     object);
    return object;
}

cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel,
                                            cl_uint arg_index,
                                            const void *arg_value)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetKernelArgSVMPointer,
                               "kernel = 0x%016" PRIxPTR
                               ", arg_index = %u, arg_value = 0x%016" PRIxPTR "",
                               (uintptr_t)kernel, arg_index, (uintptr_t)arg_value));

    ANGLE_CL_VALIDATE_ERROR(SetKernelArgSVMPointer, kernel, arg_index, arg_value);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetKernelArgSVMPointer(kernel, arg_index, arg_value);
    ANGLE_CAPTURE_CL(SetKernelArgSVMPointer, true, kernel, arg_index, arg_value, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clSetKernelExecInfo(cl_kernel kernel,
                                       cl_kernel_exec_info param_name,
                                       size_t param_value_size,
                                       const void *param_value)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(SetKernelExecInfo,
                 "kernel = 0x%016" PRIxPTR
                 ", param_name = %u, param_value_size = %zu, param_value = 0x%016" PRIxPTR "",
                 (uintptr_t)kernel, param_name, param_value_size, (uintptr_t)param_value));

    KernelExecInfo param_namePacked = PackParam<KernelExecInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(SetKernelExecInfo, kernel, param_namePacked, param_value_size,
                            param_value);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetKernelExecInfo(kernel, param_namePacked, param_value_size, param_value);
    ANGLE_CAPTURE_CL(SetKernelExecInfo, true, kernel, param_namePacked, param_value_size,
                     param_value, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMFree(cl_command_queue command_queue,
                                    cl_uint num_svm_pointers,
                                    void *svm_pointers[],
                                    void(CL_CALLBACK *pfn_free_func)(cl_command_queue queue,
                                                                     cl_uint num_svm_pointers,
                                                                     void *svm_pointers[],
                                                                     void *user_data),
                                    void *user_data,
                                    cl_uint num_events_in_wait_list,
                                    const cl_event *event_wait_list,
                                    cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueSVMFree,
        "command_queue = 0x%016" PRIxPTR ", num_svm_pointers = %u, svm_pointers = 0x%016" PRIxPTR
        ", pfn_free_func = 0x%016" PRIxPTR ", user_data = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, num_svm_pointers, (uintptr_t)svm_pointers,
        (uintptr_t)pfn_free_func, (uintptr_t)user_data, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMFree, command_queue, num_svm_pointers, svm_pointers,
                            pfn_free_func, user_data, num_events_in_wait_list, event_wait_list,
                            event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueSVMFree(command_queue, num_svm_pointers, svm_pointers, pfn_free_func, user_data,
                       num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMFree, true, command_queue, num_svm_pointers, svm_pointers,
                     pfn_free_func, user_data, num_events_in_wait_list, event_wait_list, event,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMMemcpy(cl_command_queue command_queue,
                                      cl_bool blocking_copy,
                                      void *dst_ptr,
                                      const void *src_ptr,
                                      size_t size,
                                      cl_uint num_events_in_wait_list,
                                      const cl_event *event_wait_list,
                                      cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueSVMMemcpy,
                 "command_queue = 0x%016" PRIxPTR ", blocking_copy = %u, dst_ptr = 0x%016" PRIxPTR
                 ", src_ptr = 0x%016" PRIxPTR
                 ", size = %zu, num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, blocking_copy, (uintptr_t)dst_ptr, (uintptr_t)src_ptr,
                 size, num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMMemcpy, command_queue, blocking_copy, dst_ptr, src_ptr, size,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueSVMMemcpy(command_queue, blocking_copy, dst_ptr, src_ptr, size,
                                          num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMMemcpy, true, command_queue, blocking_copy, dst_ptr, src_ptr, size,
                     num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMMemFill(cl_command_queue command_queue,
                                       void *svm_ptr,
                                       const void *pattern,
                                       size_t pattern_size,
                                       size_t size,
                                       cl_uint num_events_in_wait_list,
                                       const cl_event *event_wait_list,
                                       cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueSVMMemFill,
        "command_queue = 0x%016" PRIxPTR ", svm_ptr = 0x%016" PRIxPTR ", pattern = 0x%016" PRIxPTR
        ", pattern_size = %zu, size = %zu, num_events_in_wait_list = %u, event_wait_list = "
        "0x%016" PRIxPTR ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, (uintptr_t)svm_ptr, (uintptr_t)pattern, pattern_size, size,
        num_events_in_wait_list, (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMMemFill, command_queue, svm_ptr, pattern, pattern_size, size,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueSVMMemFill(command_queue, svm_ptr, pattern, pattern_size, size,
                                           num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMMemFill, true, command_queue, svm_ptr, pattern, pattern_size, size,
                     num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMMap(cl_command_queue command_queue,
                                   cl_bool blocking_map,
                                   cl_map_flags flags,
                                   void *svm_ptr,
                                   size_t size,
                                   cl_uint num_events_in_wait_list,
                                   const cl_event *event_wait_list,
                                   cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueSVMMap,
                 "command_queue = 0x%016" PRIxPTR
                 ", blocking_map = %u, flags = %llu, svm_ptr = 0x%016" PRIxPTR
                 ", size = %zu, num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, blocking_map, static_cast<unsigned long long>(flags),
                 (uintptr_t)svm_ptr, size, num_events_in_wait_list, (uintptr_t)event_wait_list,
                 (uintptr_t)event));

    MapFlags flagsPacked = PackParam<MapFlags>(flags);

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMMap, command_queue, blocking_map, flagsPacked, svm_ptr, size,
                            num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = EnqueueSVMMap(command_queue, blocking_map, flagsPacked, svm_ptr, size,
                                       num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMMap, true, command_queue, blocking_map, flagsPacked, svm_ptr, size,
                     num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMUnmap(cl_command_queue command_queue,
                                     void *svm_ptr,
                                     cl_uint num_events_in_wait_list,
                                     const cl_event *event_wait_list,
                                     cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(EnqueueSVMUnmap,
                               "command_queue = 0x%016" PRIxPTR ", svm_ptr = 0x%016" PRIxPTR
                               ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                               ", event = 0x%016" PRIxPTR "",
                               (uintptr_t)command_queue, (uintptr_t)svm_ptr,
                               num_events_in_wait_list, (uintptr_t)event_wait_list,
                               (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMUnmap, command_queue, svm_ptr, num_events_in_wait_list,
                            event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueSVMUnmap(command_queue, svm_ptr, num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMUnmap, true, command_queue, svm_ptr, num_events_in_wait_list,
                     event_wait_list, event, returnValue);
    return returnValue;
}

// CL 2.1
cl_int CL_API_CALL clSetDefaultDeviceCommandQueue(cl_context context,
                                                  cl_device_id device,
                                                  cl_command_queue command_queue)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetDefaultDeviceCommandQueue,
                               "context = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
                               ", command_queue = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)device, (uintptr_t)command_queue));

    ANGLE_CL_VALIDATE_ERROR(SetDefaultDeviceCommandQueue, context, device, command_queue);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetDefaultDeviceCommandQueue(context, device, command_queue);
    ANGLE_CAPTURE_CL(SetDefaultDeviceCommandQueue, true, context, device, command_queue,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetDeviceAndHostTimer(cl_device_id device,
                                           cl_ulong *device_timestamp,
                                           cl_ulong *host_timestamp)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(GetDeviceAndHostTimer,
                               "device = 0x%016" PRIxPTR ", device_timestamp = 0x%016" PRIxPTR
                               ", host_timestamp = 0x%016" PRIxPTR "",
                               (uintptr_t)device, (uintptr_t)device_timestamp,
                               (uintptr_t)host_timestamp));

    ANGLE_CL_VALIDATE_ERROR(GetDeviceAndHostTimer, device, device_timestamp, host_timestamp);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetDeviceAndHostTimer(device, device_timestamp, host_timestamp);
    ANGLE_CAPTURE_CL(GetDeviceAndHostTimer, true, device, device_timestamp, host_timestamp,
                     returnValue);
    return returnValue;
}

cl_int CL_API_CALL clGetHostTimer(cl_device_id device, cl_ulong *host_timestamp)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(GetHostTimer,
                               "device = 0x%016" PRIxPTR ", host_timestamp = 0x%016" PRIxPTR "",
                               (uintptr_t)device, (uintptr_t)host_timestamp));

    ANGLE_CL_VALIDATE_ERROR(GetHostTimer, device, host_timestamp);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = GetHostTimer(device, host_timestamp);
    ANGLE_CAPTURE_CL(GetHostTimer, true, device, host_timestamp, returnValue);
    return returnValue;
}

cl_program CL_API_CALL clCreateProgramWithIL(cl_context context,
                                             const void *il,
                                             size_t length,
                                             cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateProgramWithIL,
                               "context = 0x%016" PRIxPTR ", il = 0x%016" PRIxPTR
                               ", length = %zu, errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)il, length, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateProgramWithIL, context, il, length);

    cl::gClErrorTls   = CL_SUCCESS;
    cl_program object = CreateProgramWithIL(context, il, length);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateProgramWithIL, true, context, il, length, errcode_ret, object);
    return object;
}

cl_kernel CL_API_CALL clCloneKernel(cl_kernel source_kernel, cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CloneKernel,
                               "source_kernel = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)source_kernel, (uintptr_t)errcode_ret));

    ANGLE_CL_VALIDATE_ERRCODE_RET(CloneKernel, source_kernel);

    cl::gClErrorTls  = CL_SUCCESS;
    cl_kernel object = CloneKernel(source_kernel);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CloneKernel, true, source_kernel, errcode_ret, object);
    return object;
}

cl_int CL_API_CALL clGetKernelSubGroupInfo(cl_kernel kernel,
                                           cl_device_id device,
                                           cl_kernel_sub_group_info param_name,
                                           size_t input_value_size,
                                           const void *input_value,
                                           size_t param_value_size,
                                           void *param_value,
                                           size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        GetKernelSubGroupInfo,
        "kernel = 0x%016" PRIxPTR ", device = 0x%016" PRIxPTR
        ", param_name = %u, input_value_size = %zu, input_value = 0x%016" PRIxPTR
        ", param_value_size = %zu, param_value = 0x%016" PRIxPTR
        ", param_value_size_ret = 0x%016" PRIxPTR "",
        (uintptr_t)kernel, (uintptr_t)device, param_name, input_value_size, (uintptr_t)input_value,
        param_value_size, (uintptr_t)param_value, (uintptr_t)param_value_size_ret));

    KernelSubGroupInfo param_namePacked = PackParam<KernelSubGroupInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetKernelSubGroupInfo, kernel, device, param_namePacked,
                            input_value_size, input_value, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetKernelSubGroupInfo(kernel, device, param_namePacked, input_value_size, input_value,
                              param_value_size, param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetKernelSubGroupInfo, true, kernel, device, param_namePacked,
                     input_value_size, input_value, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueSVMMigrateMem(cl_command_queue command_queue,
                                          cl_uint num_svm_pointers,
                                          const void **svm_pointers,
                                          const size_t *sizes,
                                          cl_mem_migration_flags flags,
                                          cl_uint num_events_in_wait_list,
                                          const cl_event *event_wait_list,
                                          cl_event *event)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(EnqueueSVMMigrateMem,
                 "command_queue = 0x%016" PRIxPTR
                 ", num_svm_pointers = %u, svm_pointers = 0x%016" PRIxPTR ", sizes = 0x%016" PRIxPTR
                 ", flags = %llu, num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
                 ", event = 0x%016" PRIxPTR "",
                 (uintptr_t)command_queue, num_svm_pointers, (uintptr_t)svm_pointers,
                 (uintptr_t)sizes, static_cast<unsigned long long>(flags), num_events_in_wait_list,
                 (uintptr_t)event_wait_list, (uintptr_t)event));

    MemMigrationFlags flagsPacked = PackParam<MemMigrationFlags>(flags);

    ANGLE_CL_VALIDATE_ERROR(EnqueueSVMMigrateMem, command_queue, num_svm_pointers, svm_pointers,
                            sizes, flagsPacked, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueSVMMigrateMem(command_queue, num_svm_pointers, svm_pointers, sizes, flagsPacked,
                             num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueSVMMigrateMem, true, command_queue, num_svm_pointers, svm_pointers,
                     sizes, flagsPacked, num_events_in_wait_list, event_wait_list, event,
                     returnValue);
    return returnValue;
}

// CL 2.2
cl_int CL_API_CALL clSetProgramReleaseCallback(cl_program program,
                                               void(CL_CALLBACK *pfn_notify)(cl_program program,
                                                                             void *user_data),
                                               void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetProgramReleaseCallback,
                               "program = 0x%016" PRIxPTR ", pfn_notify = 0x%016" PRIxPTR
                               ", user_data = 0x%016" PRIxPTR "",
                               (uintptr_t)program, (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(SetProgramReleaseCallback, program, pfn_notify, user_data);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetProgramReleaseCallback(program, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(SetProgramReleaseCallback, true, program, pfn_notify, user_data, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clSetProgramSpecializationConstant(cl_program program,
                                                      cl_uint spec_id,
                                                      size_t spec_size,
                                                      const void *spec_value)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetProgramSpecializationConstant,
                               "program = 0x%016" PRIxPTR
                               ", spec_id = %u, spec_size = %zu, spec_value = 0x%016" PRIxPTR "",
                               (uintptr_t)program, spec_id, spec_size, (uintptr_t)spec_value));

    ANGLE_CL_VALIDATE_ERROR(SetProgramSpecializationConstant, program, spec_id, spec_size,
                            spec_value);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetProgramSpecializationConstant(program, spec_id, spec_size, spec_value);
    ANGLE_CAPTURE_CL(SetProgramSpecializationConstant, true, program, spec_id, spec_size,
                     spec_value, returnValue);
    return returnValue;
}

// CL 3.0
cl_int CL_API_CALL clSetContextDestructorCallback(cl_context context,
                                                  void(CL_CALLBACK *pfn_notify)(cl_context context,
                                                                                void *user_data),
                                                  void *user_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(SetContextDestructorCallback,
                               "context = 0x%016" PRIxPTR ", pfn_notify = 0x%016" PRIxPTR
                               ", user_data = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)pfn_notify, (uintptr_t)user_data));

    ANGLE_CL_VALIDATE_ERROR(SetContextDestructorCallback, context, pfn_notify, user_data);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = SetContextDestructorCallback(context, pfn_notify, user_data);
    ANGLE_CAPTURE_CL(SetContextDestructorCallback, true, context, pfn_notify, user_data,
                     returnValue);
    return returnValue;
}

cl_mem CL_API_CALL clCreateBufferWithProperties(cl_context context,
                                                const cl_mem_properties *properties,
                                                cl_mem_flags flags,
                                                size_t size,
                                                void *host_ptr,
                                                cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        CreateBufferWithProperties,
        "context = 0x%016" PRIxPTR ", properties = 0x%016" PRIxPTR
        ", flags = %llu, size = %zu, host_ptr = 0x%016" PRIxPTR ", errcode_ret = 0x%016" PRIxPTR "",
        (uintptr_t)context, (uintptr_t)properties, static_cast<unsigned long long>(flags), size,
        (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateBufferWithProperties, context, properties, flagsPacked,
                                  size, host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateBufferWithProperties(context, properties, flagsPacked, size, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateBufferWithProperties, true, context, properties, flagsPacked, size,
                     host_ptr, errcode_ret, object);
    return object;
}

cl_mem CL_API_CALL clCreateImageWithProperties(cl_context context,
                                               const cl_mem_properties *properties,
                                               cl_mem_flags flags,
                                               const cl_image_format *image_format,
                                               const cl_image_desc *image_desc,
                                               void *host_ptr,
                                               cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(CreateImageWithProperties,
                               "context = 0x%016" PRIxPTR ", properties = 0x%016" PRIxPTR
                               ", flags = %llu, image_format = 0x%016" PRIxPTR
                               ", image_desc = 0x%016" PRIxPTR ", host_ptr = 0x%016" PRIxPTR
                               ", errcode_ret = 0x%016" PRIxPTR "",
                               (uintptr_t)context, (uintptr_t)properties,
                               static_cast<unsigned long long>(flags), (uintptr_t)image_format,
                               (uintptr_t)image_desc, (uintptr_t)host_ptr, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(CreateImageWithProperties, context, properties, flagsPacked,
                                  image_format, image_desc, host_ptr);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = CreateImageWithProperties(context, properties, flagsPacked, image_format,
                                                image_desc, host_ptr);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(CreateImageWithProperties, true, context, properties, flagsPacked,
                     image_format, image_desc, host_ptr, errcode_ret, object);
    return object;
}

// cl_arm_import_memory
cl_mem CL_API_CALL clImportMemoryARM(cl_context context,
                                     cl_mem_flags flags,
                                     const cl_import_properties_arm *properties,
                                     void *memory,
                                     size_t size,
                                     cl_int *errcode_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(ImportMemoryARM,
                 "context = 0x%016" PRIxPTR ", flags = %llu, properties = 0x%016" PRIxPTR
                 ", memory = 0x%016" PRIxPTR ", size = %zu, errcode_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)context, static_cast<unsigned long long>(flags), (uintptr_t)properties,
                 (uintptr_t)memory, size, (uintptr_t)errcode_ret));

    MemFlags flagsPacked = PackParam<MemFlags>(flags);

    ANGLE_CL_VALIDATE_ERRCODE_RET(ImportMemoryARM, context, flagsPacked, properties, memory, size);

    cl::gClErrorTls = CL_SUCCESS;
    cl_mem object   = ImportMemoryARM(context, flagsPacked, properties, memory, size);

    ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr));
    if (errcode_ret != nullptr)
    {
        *errcode_ret = cl::gClErrorTls;
    }
    ANGLE_CAPTURE_CL(ImportMemoryARM, true, context, flagsPacked, properties, memory, size,
                     errcode_ret, object);
    return object;
}

// cl_khr_external_memory
cl_int CL_API_CALL clEnqueueAcquireExternalMemObjectsKHR(cl_command_queue command_queue,
                                                         cl_uint num_mem_objects,
                                                         const cl_mem *mem_objects,
                                                         cl_uint num_events_in_wait_list,
                                                         const cl_event *event_wait_list,
                                                         cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueAcquireExternalMemObjectsKHR,
        "command_queue = 0x%016" PRIxPTR ", num_mem_objects = %u, mem_objects = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, num_mem_objects, (uintptr_t)mem_objects, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueAcquireExternalMemObjectsKHR, command_queue, num_mem_objects,
                            mem_objects, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueAcquireExternalMemObjectsKHR(command_queue, num_mem_objects, mem_objects,
                                            num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueAcquireExternalMemObjectsKHR, true, command_queue, num_mem_objects,
                     mem_objects, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clEnqueueReleaseExternalMemObjectsKHR(cl_command_queue command_queue,
                                                         cl_uint num_mem_objects,
                                                         const cl_mem *mem_objects,
                                                         cl_uint num_events_in_wait_list,
                                                         const cl_event *event_wait_list,
                                                         cl_event *event)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(
        EnqueueReleaseExternalMemObjectsKHR,
        "command_queue = 0x%016" PRIxPTR ", num_mem_objects = %u, mem_objects = 0x%016" PRIxPTR
        ", num_events_in_wait_list = %u, event_wait_list = 0x%016" PRIxPTR
        ", event = 0x%016" PRIxPTR "",
        (uintptr_t)command_queue, num_mem_objects, (uintptr_t)mem_objects, num_events_in_wait_list,
        (uintptr_t)event_wait_list, (uintptr_t)event));

    ANGLE_CL_VALIDATE_ERROR(EnqueueReleaseExternalMemObjectsKHR, command_queue, num_mem_objects,
                            mem_objects, num_events_in_wait_list, event_wait_list, event);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        EnqueueReleaseExternalMemObjectsKHR(command_queue, num_mem_objects, mem_objects,
                                            num_events_in_wait_list, event_wait_list, event);
    ANGLE_CAPTURE_CL(EnqueueReleaseExternalMemObjectsKHR, true, command_queue, num_mem_objects,
                     mem_objects, num_events_in_wait_list, event_wait_list, event, returnValue);
    return returnValue;
}

// cl_khr_icd
cl_int CL_API_CALL clIcdGetPlatformIDsKHR(cl_uint num_entries,
                                          cl_platform_id *platforms,
                                          cl_uint *num_platforms)
{
    InitBackEnds(true);

    ANGLE_UNSAFE_TODO(CL_EVENT(IcdGetPlatformIDsKHR,
                               "num_entries = %u, platforms = 0x%016" PRIxPTR
                               ", num_platforms = 0x%016" PRIxPTR "",
                               num_entries, (uintptr_t)platforms, (uintptr_t)num_platforms));

    ANGLE_CL_VALIDATE_ERROR(IcdGetPlatformIDsKHR, num_entries, platforms, num_platforms);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = IcdGetPlatformIDsKHR(num_entries, platforms, num_platforms);
    ANGLE_CAPTURE_CL(IcdGetPlatformIDsKHR, true, num_entries, platforms, num_platforms,
                     returnValue);
    return returnValue;
}

void *CL_API_CALL clIcdGetFunctionAddressForPlatformKHR(cl_platform_id platform,
                                                        const char *func_name)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(IcdGetFunctionAddressForPlatformKHR,
                               "platform = 0x%016" PRIxPTR ", func_name = 0x%016" PRIxPTR "",
                               (uintptr_t)platform, (uintptr_t)func_name));

    cl::gClErrorTls = CL_SUCCESS;
    ANGLE_CL_VALIDATE_POINTER(IcdGetFunctionAddressForPlatformKHR, platform, func_name);

    void *returnValue = IcdGetFunctionAddressForPlatformKHR(platform, func_name);
    ANGLE_CAPTURE_CL(IcdGetFunctionAddressForPlatformKHR, true, platform, func_name, returnValue);
    return returnValue;
}

cl_int CL_API_CALL clIcdSetPlatformDispatchDataKHR(cl_platform_id platform, void *dispatch_data)
{
    ANGLE_UNSAFE_TODO(CL_EVENT(IcdSetPlatformDispatchDataKHR,
                               "platform = 0x%016" PRIxPTR ", dispatch_data = 0x%016" PRIxPTR "",
                               (uintptr_t)platform, (uintptr_t)dispatch_data));

    ANGLE_CL_VALIDATE_ERROR(IcdSetPlatformDispatchDataKHR, platform, dispatch_data);

    cl::gClErrorTls    = CL_SUCCESS;
    cl_int returnValue = IcdSetPlatformDispatchDataKHR(platform, dispatch_data);
    ANGLE_CAPTURE_CL(IcdSetPlatformDispatchDataKHR, true, platform, dispatch_data, returnValue);
    return returnValue;
}

// cl_khr_subgroups
cl_int CL_API_CALL clGetKernelSubGroupInfoKHR(cl_kernel in_kernel,
                                              cl_device_id in_device,
                                              cl_kernel_sub_group_info param_name,
                                              size_t input_value_size,
                                              const void *input_value,
                                              size_t param_value_size,
                                              void *param_value,
                                              size_t *param_value_size_ret)
{
    ANGLE_UNSAFE_TODO(
        CL_EVENT(GetKernelSubGroupInfoKHR,
                 "in_kernel = 0x%016" PRIxPTR ", in_device = 0x%016" PRIxPTR
                 ", param_name = %u, input_value_size = %zu, input_value = 0x%016" PRIxPTR
                 ", param_value_size = %zu, param_value = 0x%016" PRIxPTR
                 ", param_value_size_ret = 0x%016" PRIxPTR "",
                 (uintptr_t)in_kernel, (uintptr_t)in_device, param_name, input_value_size,
                 (uintptr_t)input_value, param_value_size, (uintptr_t)param_value,
                 (uintptr_t)param_value_size_ret));

    KernelSubGroupInfo param_namePacked = PackParam<KernelSubGroupInfo>(param_name);

    ANGLE_CL_VALIDATE_ERROR(GetKernelSubGroupInfoKHR, in_kernel, in_device, param_namePacked,
                            input_value_size, input_value, param_value_size, param_value,
                            param_value_size_ret);

    cl::gClErrorTls = CL_SUCCESS;
    cl_int returnValue =
        GetKernelSubGroupInfoKHR(in_kernel, in_device, param_namePacked, input_value_size,
                                 input_value, param_value_size, param_value, param_value_size_ret);
    ANGLE_CAPTURE_CL(GetKernelSubGroupInfoKHR, true, in_kernel, in_device, param_namePacked,
                     input_value_size, input_value, param_value_size, param_value,
                     param_value_size_ret, returnValue);
    return returnValue;
}

}  // namespace cl
