Edit

kc3-lang/angle/src/libGLESv2/entry_points_cl_autogen.cpp

Branch :

  • Show log

    Commit

  • Author : John Plate
    Date : 2021-05-29 16:26:57
    Hash : baca10b7
    Message : CL: Remove object cache and fix multi-threading All CL front end objects used to be cached to be able to determine if an object has been created by the front end to check its validity. The validity is now checked with the existence of an intrinsic value (the dispatch table pointer), which is consistent with the patterns found in Mesa and clvk (though clvk uses a magic value). This allows the removal of all cached objects. The cached objects were stored with std::unique_ptr. These are now gone and all remaining pointers are now custom intrinsic reference count pointers. Also remove global lock which causes deadlocks, e.g. when CL API is called from a separate thread to unlock a blocking call with a user event. Most of the front end is constant and already thread-safe. The ref count is also thread-safe now (atomic). A few remaining locks will follow. Without the global lock it was now possible to make the API reentrant, and to remove the workaround with the Khronos ICD loader to skip ANGLE's OpenCL library. Bug: angleproject:6001 Change-Id: I7d3b52db9011a02cb7ea9ebdeb6e22c4c702ef5b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2927395 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com>

  • src/libGLESv2/entry_points_cl_autogen.cpp
  • // 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/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);
    
        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);
    
        return GetPlatformIDs(num_entries, platforms, num_platforms);
    }
    
    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);
    
        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);
    
        return GetPlatformInfo(platform, param_namePacked, param_value_size, param_value,
                               param_value_size_ret);
    }
    
    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);
    
        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);
    
        return GetDeviceIDs(platform, device_typePacked, num_entries, devices, num_devices);
    }
    
    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)
    {
        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);
    
        return GetDeviceInfo(device, param_namePacked, param_value_size, param_value,
                             param_value_size_ret);
    }
    
    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);
    
        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_int errorCode = CL_SUCCESS;
        cl_context object =
            CreateContext(properties, num_devices, devices, pfn_notify, user_data, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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);
    
        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_int errorCode = CL_SUCCESS;
        cl_context object =
            CreateContextFromType(properties, device_typePacked, pfn_notify, user_data, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clRetainContext(cl_context context)
    {
        CL_EVENT(RetainContext, "context = 0x%016" PRIxPTR "", (uintptr_t)context);
    
        ANGLE_CL_VALIDATE_ERROR(RetainContext, context);
    
        return RetainContext(context);
    }
    
    cl_int CL_API_CALL clReleaseContext(cl_context context)
    {
        CL_EVENT(ReleaseContext, "context = 0x%016" PRIxPTR "", (uintptr_t)context);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseContext, context);
    
        return ReleaseContext(context);
    }
    
    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)
    {
        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);
    
        return GetContextInfo(context, param_namePacked, param_value_size, param_value,
                              param_value_size_ret);
    }
    
    cl_int CL_API_CALL clRetainCommandQueue(cl_command_queue command_queue)
    {
        CL_EVENT(RetainCommandQueue, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue);
    
        ANGLE_CL_VALIDATE_ERROR(RetainCommandQueue, command_queue);
    
        return RetainCommandQueue(command_queue);
    }
    
    cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue command_queue)
    {
        CL_EVENT(ReleaseCommandQueue, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseCommandQueue, command_queue);
    
        return ReleaseCommandQueue(command_queue);
    }
    
    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)
    {
        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);
    
        return GetCommandQueueInfo(command_queue, param_namePacked, param_value_size, param_value,
                                   param_value_size_ret);
    }
    
    cl_mem CL_API_CALL clCreateBuffer(cl_context context,
                                      cl_mem_flags flags,
                                      size_t size,
                                      void *host_ptr,
                                      cl_int *errcode_ret)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object    = CreateBuffer(context, flagsPacked, size, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clRetainMemObject(cl_mem memobj)
    {
        CL_EVENT(RetainMemObject, "memobj = 0x%016" PRIxPTR "", (uintptr_t)memobj);
    
        ANGLE_CL_VALIDATE_ERROR(RetainMemObject, memobj);
    
        return RetainMemObject(memobj);
    }
    
    cl_int CL_API_CALL clReleaseMemObject(cl_mem memobj)
    {
        CL_EVENT(ReleaseMemObject, "memobj = 0x%016" PRIxPTR "", (uintptr_t)memobj);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseMemObject, memobj);
    
        return ReleaseMemObject(memobj);
    }
    
    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)
    {
        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);
    
        return GetSupportedImageFormats(context, flagsPacked, image_typePacked, num_entries,
                                        image_formats, num_image_formats);
    }
    
    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)
    {
        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);
    
        return GetMemObjectInfo(memobj, param_namePacked, param_value_size, param_value,
                                param_value_size_ret);
    }
    
    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)
    {
        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);
    
        return GetImageInfo(image, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);
    }
    
    cl_int CL_API_CALL clRetainSampler(cl_sampler sampler)
    {
        CL_EVENT(RetainSampler, "sampler = 0x%016" PRIxPTR "", (uintptr_t)sampler);
    
        ANGLE_CL_VALIDATE_ERROR(RetainSampler, sampler);
    
        return RetainSampler(sampler);
    }
    
    cl_int CL_API_CALL clReleaseSampler(cl_sampler sampler)
    {
        CL_EVENT(ReleaseSampler, "sampler = 0x%016" PRIxPTR "", (uintptr_t)sampler);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseSampler, sampler);
    
        return ReleaseSampler(sampler);
    }
    
    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)
    {
        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);
    
        return GetSamplerInfo(sampler, param_namePacked, param_value_size, param_value,
                              param_value_size_ret);
    }
    
    cl_program CL_API_CALL clCreateProgramWithSource(cl_context context,
                                                     cl_uint count,
                                                     const char **strings,
                                                     const size_t *lengths,
                                                     cl_int *errcode_ret)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_program object = CreateProgramWithSource(context, count, strings, lengths, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_program object = CreateProgramWithBinary(context, num_devices, device_list, lengths,
                                                    binaries, binary_status, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clRetainProgram(cl_program program)
    {
        CL_EVENT(RetainProgram, "program = 0x%016" PRIxPTR "", (uintptr_t)program);
    
        ANGLE_CL_VALIDATE_ERROR(RetainProgram, program);
    
        return RetainProgram(program);
    }
    
    cl_int CL_API_CALL clReleaseProgram(cl_program program)
    {
        CL_EVENT(ReleaseProgram, "program = 0x%016" PRIxPTR "", (uintptr_t)program);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseProgram, program);
    
        return ReleaseProgram(program);
    }
    
    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)
    {
        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);
    
        return BuildProgram(program, num_devices, device_list, options, pfn_notify, user_data);
    }
    
    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)
    {
        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);
    
        return GetProgramInfo(program, param_namePacked, param_value_size, param_value,
                              param_value_size_ret);
    }
    
    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)
    {
        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);
    
        return GetProgramBuildInfo(program, device, param_namePacked, param_value_size, param_value,
                                   param_value_size_ret);
    }
    
    cl_kernel CL_API_CALL clCreateKernel(cl_program program,
                                         const char *kernel_name,
                                         cl_int *errcode_ret)
    {
        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_int errorCode = CL_SUCCESS;
        cl_kernel object = CreateKernel(program, kernel_name, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clCreateKernelsInProgram(cl_program program,
                                                cl_uint num_kernels,
                                                cl_kernel *kernels,
                                                cl_uint *num_kernels_ret)
    {
        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);
    
        return CreateKernelsInProgram(program, num_kernels, kernels, num_kernels_ret);
    }
    
    cl_int CL_API_CALL clRetainKernel(cl_kernel kernel)
    {
        CL_EVENT(RetainKernel, "kernel = 0x%016" PRIxPTR "", (uintptr_t)kernel);
    
        ANGLE_CL_VALIDATE_ERROR(RetainKernel, kernel);
    
        return RetainKernel(kernel);
    }
    
    cl_int CL_API_CALL clReleaseKernel(cl_kernel kernel)
    {
        CL_EVENT(ReleaseKernel, "kernel = 0x%016" PRIxPTR "", (uintptr_t)kernel);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseKernel, kernel);
    
        return ReleaseKernel(kernel);
    }
    
    cl_int CL_API_CALL clSetKernelArg(cl_kernel kernel,
                                      cl_uint arg_index,
                                      size_t arg_size,
                                      const void *arg_value)
    {
        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);
    
        return SetKernelArg(kernel, arg_index, arg_size, arg_value);
    }
    
    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)
    {
        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);
    
        return GetKernelInfo(kernel, param_namePacked, param_value_size, param_value,
                             param_value_size_ret);
    }
    
    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)
    {
        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);
    
        return GetKernelWorkGroupInfo(kernel, device, param_namePacked, param_value_size, param_value,
                                      param_value_size_ret);
    }
    
    cl_int CL_API_CALL clWaitForEvents(cl_uint num_events, const cl_event *event_list)
    {
        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);
    
        return WaitForEvents(num_events, event_list);
    }
    
    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)
    {
        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);
    
        return GetEventInfo(event, param_namePacked, param_value_size, param_value,
                            param_value_size_ret);
    }
    
    cl_int CL_API_CALL clRetainEvent(cl_event event)
    {
        CL_EVENT(RetainEvent, "event = 0x%016" PRIxPTR "", (uintptr_t)event);
    
        ANGLE_CL_VALIDATE_ERROR(RetainEvent, event);
    
        return RetainEvent(event);
    }
    
    cl_int CL_API_CALL clReleaseEvent(cl_event event)
    {
        CL_EVENT(ReleaseEvent, "event = 0x%016" PRIxPTR "", (uintptr_t)event);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseEvent, event);
    
        return ReleaseEvent(event);
    }
    
    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)
    {
        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);
    
        return GetEventProfilingInfo(event, param_namePacked, param_value_size, param_value,
                                     param_value_size_ret);
    }
    
    cl_int CL_API_CALL clFlush(cl_command_queue command_queue)
    {
        CL_EVENT(Flush, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue);
    
        ANGLE_CL_VALIDATE_ERROR(Flush, command_queue);
    
        return Flush(command_queue);
    }
    
    cl_int CL_API_CALL clFinish(cl_command_queue command_queue)
    {
        CL_EVENT(Finish, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue);
    
        ANGLE_CL_VALIDATE_ERROR(Finish, command_queue);
    
        return Finish(command_queue);
    }
    
    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)
    {
        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);
    
        return EnqueueReadBuffer(command_queue, buffer, blocking_read, offset, size, ptr,
                                 num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueWriteBuffer(command_queue, buffer, blocking_write, offset, size, ptr,
                                  num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueCopyBuffer(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size,
                                 num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueReadImage(command_queue, image, blocking_read, origin, region, row_pitch,
                                slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return 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_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)
    {
        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);
    
        return EnqueueCopyImage(command_queue, src_image, dst_image, src_origin, dst_origin, region,
                                num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueCopyImageToBuffer(command_queue, src_image, dst_buffer, src_origin, region,
                                        dst_offset, num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueCopyBufferToImage(command_queue, src_buffer, dst_image, src_offset, dst_origin,
                                        region, num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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_int errorCode = CL_SUCCESS;
        void *object =
            EnqueueMapBuffer(command_queue, buffer, blocking_map, map_flagsPacked, offset, size,
                             num_events_in_wait_list, event_wait_list, event, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode = 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, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return EnqueueUnmapMemObject(command_queue, memobj, mapped_ptr, num_events_in_wait_list,
                                     event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return 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_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)
    {
        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);
    
        return 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_int CL_API_CALL clSetCommandQueueProperty(cl_command_queue command_queue,
                                                 cl_command_queue_properties properties,
                                                 cl_bool enable,
                                                 cl_command_queue_properties *old_properties)
    {
        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);
    
        return SetCommandQueueProperty(command_queue, propertiesPacked, enable, old_properties);
    }
    
    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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object    = CreateImage2D(context, flagsPacked, image_format, image_width, image_height,
                                      image_row_pitch, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object =
            CreateImage3D(context, flagsPacked, image_format, image_width, image_height, image_depth,
                          image_row_pitch, image_slice_pitch, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clEnqueueMarker(cl_command_queue command_queue, cl_event *event)
    {
        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);
    
        return EnqueueMarker(command_queue, event);
    }
    
    cl_int CL_API_CALL clEnqueueWaitForEvents(cl_command_queue command_queue,
                                              cl_uint num_events,
                                              const cl_event *event_list)
    {
        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);
    
        return EnqueueWaitForEvents(command_queue, num_events, event_list);
    }
    
    cl_int CL_API_CALL clEnqueueBarrier(cl_command_queue command_queue)
    {
        CL_EVENT(EnqueueBarrier, "command_queue = 0x%016" PRIxPTR "", (uintptr_t)command_queue);
    
        ANGLE_CL_VALIDATE_ERROR(EnqueueBarrier, command_queue);
    
        return EnqueueBarrier(command_queue);
    }
    
    cl_int CL_API_CALL clUnloadCompiler()
    {
        CL_EVENT(UnloadCompiler, "");
    
        ANGLE_CL_VALIDATE_ERROR(UnloadCompiler);
    
        return UnloadCompiler();
    }
    
    void *CL_API_CALL clGetExtensionFunctionAddress(const char *func_name)
    {
        CL_EVENT(GetExtensionFunctionAddress, "func_name = 0x%016" PRIxPTR "", (uintptr_t)func_name);
    
        ANGLE_CL_VALIDATE_POINTER(GetExtensionFunctionAddress, func_name);
    
        return GetExtensionFunctionAddress(func_name);
    }
    
    cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context,
                                                      cl_device_id device,
                                                      cl_command_queue_properties properties,
                                                      cl_int *errcode_ret)
    {
        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_int errorCode        = CL_SUCCESS;
        cl_command_queue object = CreateCommandQueue(context, device, propertiesPacked, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_sampler object = CreateSampler(context, normalized_coords, addressing_modePacked,
                                          filter_modePacked, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return EnqueueTask(command_queue, kernel, num_events_in_wait_list, event_wait_list, event);
    }
    
    // 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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object =
            CreateSubBuffer(buffer, flagsPacked, buffer_create_type, buffer_create_info, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return SetMemObjectDestructorCallback(memobj, pfn_notify, user_data);
    }
    
    cl_event CL_API_CALL clCreateUserEvent(cl_context context, cl_int *errcode_ret)
    {
        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_int errorCode = CL_SUCCESS;
        cl_event object  = CreateUserEvent(context, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clSetUserEventStatus(cl_event event, cl_int execution_status)
    {
        CL_EVENT(SetUserEventStatus, "event = 0x%016" PRIxPTR ", execution_status = %d",
                 (uintptr_t)event, execution_status);
    
        ANGLE_CL_VALIDATE_ERROR(SetUserEventStatus, event, execution_status);
    
        return SetUserEventStatus(event, execution_status);
    }
    
    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)
    {
        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);
    
        return SetEventCallback(event, command_exec_callback_type, pfn_notify, user_data);
    }
    
    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)
    {
        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);
    
        return 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_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)
    {
        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);
    
        return 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_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)
    {
        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);
    
        return 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 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)
    {
        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);
    
        return CreateSubDevices(in_device, properties, num_devices, out_devices, num_devices_ret);
    }
    
    cl_int CL_API_CALL clRetainDevice(cl_device_id device)
    {
        CL_EVENT(RetainDevice, "device = 0x%016" PRIxPTR "", (uintptr_t)device);
    
        ANGLE_CL_VALIDATE_ERROR(RetainDevice, device);
    
        return RetainDevice(device);
    }
    
    cl_int CL_API_CALL clReleaseDevice(cl_device_id device)
    {
        CL_EVENT(ReleaseDevice, "device = 0x%016" PRIxPTR "", (uintptr_t)device);
    
        ANGLE_CL_VALIDATE_ERROR(ReleaseDevice, device);
    
        return ReleaseDevice(device);
    }
    
    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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object =
            CreateImage(context, flagsPacked, image_format, image_desc, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_program object =
            CreateProgramWithBuiltInKernels(context, num_devices, device_list, kernel_names, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return CompileProgram(program, num_devices, device_list, options, num_input_headers,
                              input_headers, header_include_names, pfn_notify, user_data);
    }
    
    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)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_program object = LinkProgram(context, num_devices, device_list, options, num_input_programs,
                                        input_programs, pfn_notify, user_data, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clUnloadPlatformCompiler(cl_platform_id platform)
    {
        CL_EVENT(UnloadPlatformCompiler, "platform = 0x%016" PRIxPTR "", (uintptr_t)platform);
    
        ANGLE_CL_VALIDATE_ERROR(UnloadPlatformCompiler, platform);
    
        return UnloadPlatformCompiler(platform);
    }
    
    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)
    {
        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);
    
        return GetKernelArgInfo(kernel, arg_index, param_namePacked, param_value_size, param_value,
                                param_value_size_ret);
    }
    
    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)
    {
        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);
    
        return EnqueueFillBuffer(command_queue, buffer, pattern, pattern_size, offset, size,
                                 num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueFillImage(command_queue, image, fill_color, origin, region,
                                num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueMigrateMemObjects(command_queue, num_mem_objects, mem_objects, flagsPacked,
                                        num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueMarkerWithWaitList(command_queue, num_events_in_wait_list, event_wait_list,
                                         event);
    }
    
    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)
    {
        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);
    
        return EnqueueBarrierWithWaitList(command_queue, num_events_in_wait_list, event_wait_list,
                                          event);
    }
    
    void *CL_API_CALL clGetExtensionFunctionAddressForPlatform(cl_platform_id platform,
                                                               const char *func_name)
    {
        CL_EVENT(GetExtensionFunctionAddressForPlatform,
                 "platform = 0x%016" PRIxPTR ", func_name = 0x%016" PRIxPTR "", (uintptr_t)platform,
                 (uintptr_t)func_name);
    
        ANGLE_CL_VALIDATE_POINTER(GetExtensionFunctionAddressForPlatform, platform, func_name);
    
        return GetExtensionFunctionAddressForPlatform(platform, func_name);
    }
    
    // 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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_command_queue object =
            CreateCommandQueueWithProperties(context, device, properties, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object =
            CreatePipe(context, flagsPacked, pipe_packet_size, pipe_max_packets, properties, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return GetPipeInfo(pipe, param_namePacked, param_value_size, param_value, param_value_size_ret);
    }
    
    void *CL_API_CALL clSVMAlloc(cl_context context,
                                 cl_svm_mem_flags flags,
                                 size_t size,
                                 cl_uint alignment)
    {
        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);
    
        ANGLE_CL_VALIDATE_POINTER(SVMAlloc, context, flagsPacked, size, alignment);
    
        return SVMAlloc(context, flagsPacked, size, alignment);
    }
    
    void CL_API_CALL clSVMFree(cl_context context, void *svm_pointer)
    {
        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);
    
        SVMFree(context, svm_pointer);
    }
    
    cl_sampler CL_API_CALL
    clCreateSamplerWithProperties(cl_context context,
                                  const cl_sampler_properties *sampler_properties,
                                  cl_int *errcode_ret)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_sampler object = CreateSamplerWithProperties(context, sampler_properties, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel,
                                                cl_uint arg_index,
                                                const void *arg_value)
    {
        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);
    
        return SetKernelArgSVMPointer(kernel, arg_index, arg_value);
    }
    
    cl_int CL_API_CALL clSetKernelExecInfo(cl_kernel kernel,
                                           cl_kernel_exec_info param_name,
                                           size_t param_value_size,
                                           const void *param_value)
    {
        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);
    
        return SetKernelExecInfo(kernel, param_namePacked, param_value_size, param_value);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMFree(command_queue, num_svm_pointers, svm_pointers, pfn_free_func, user_data,
                              num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMMemcpy(command_queue, blocking_copy, dst_ptr, src_ptr, size,
                                num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMMemFill(command_queue, svm_ptr, pattern, pattern_size, size,
                                 num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMMap(command_queue, blocking_map, flagsPacked, svm_ptr, size,
                             num_events_in_wait_list, event_wait_list, event);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMUnmap(command_queue, svm_ptr, num_events_in_wait_list, event_wait_list, event);
    }
    
    // CL 2.1
    cl_int CL_API_CALL clSetDefaultDeviceCommandQueue(cl_context context,
                                                      cl_device_id device,
                                                      cl_command_queue command_queue)
    {
        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);
    
        return SetDefaultDeviceCommandQueue(context, device, command_queue);
    }
    
    cl_int CL_API_CALL clGetDeviceAndHostTimer(cl_device_id device,
                                               cl_ulong *device_timestamp,
                                               cl_ulong *host_timestamp)
    {
        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);
    
        return GetDeviceAndHostTimer(device, device_timestamp, host_timestamp);
    }
    
    cl_int CL_API_CALL clGetHostTimer(cl_device_id device, cl_ulong *host_timestamp)
    {
        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);
    
        return GetHostTimer(device, host_timestamp);
    }
    
    cl_program CL_API_CALL clCreateProgramWithIL(cl_context context,
                                                 const void *il,
                                                 size_t length,
                                                 cl_int *errcode_ret)
    {
        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_int errorCode  = CL_SUCCESS;
        cl_program object = CreateProgramWithIL(context, il, length, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    cl_kernel CL_API_CALL clCloneKernel(cl_kernel source_kernel, cl_int *errcode_ret)
    {
        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_int errorCode = CL_SUCCESS;
        cl_kernel object = CloneKernel(source_kernel, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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);
    
        return GetKernelSubGroupInfo(kernel, device, param_namePacked, input_value_size, input_value,
                                     param_value_size, param_value, param_value_size_ret);
    }
    
    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)
    {
        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);
    
        return EnqueueSVMMigrateMem(command_queue, num_svm_pointers, svm_pointers, sizes, flagsPacked,
                                    num_events_in_wait_list, event_wait_list, event);
    }
    
    // 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)
    {
        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);
    
        return SetProgramReleaseCallback(program, pfn_notify, user_data);
    }
    
    cl_int CL_API_CALL clSetProgramSpecializationConstant(cl_program program,
                                                          cl_uint spec_id,
                                                          size_t spec_size,
                                                          const void *spec_value)
    {
        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);
    
        return SetProgramSpecializationConstant(program, spec_id, spec_size, spec_value);
    }
    
    // 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)
    {
        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);
    
        return SetContextDestructorCallback(context, pfn_notify, user_data);
    }
    
    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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object =
            CreateBufferWithProperties(context, properties, flagsPacked, size, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        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)
    {
        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_int errorCode = CL_SUCCESS;
        cl_mem object    = CreateImageWithProperties(context, properties, flagsPacked, image_format,
                                                  image_desc, host_ptr, errorCode);
    
        ASSERT((errorCode == CL_SUCCESS) == (object != nullptr));
        if (errcode_ret != nullptr)
        {
            *errcode_ret = errorCode;
        }
        return object;
    }
    
    // cl_khr_icd
    cl_int CL_API_CALL clIcdGetPlatformIDsKHR(cl_uint num_entries,
                                              cl_platform_id *platforms,
                                              cl_uint *num_platforms)
    {
        InitBackEnds(true);
    
        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);
    
        return IcdGetPlatformIDsKHR(num_entries, platforms, num_platforms);
    }
    
    }  // namespace cl