//
// Copyright (c) 2017 The Khronos Group Inc.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "testBase.h"
#include "common.h"
#include <limits.h>

#if defined( __APPLE__ )
    #include <OpenGL/glu.h>
#else
    #include <GL/glu.h>
    #include <CL/cl_gl.h>
#endif

#pragma mark -
#pragma mark Write test kernels

static const char *kernelpattern_image_write_1D =
"__kernel void sample_test( __global %s4 *source, write_only image1d_t dest )\n"
"{\n"
"    uint index = get_global_id(0);\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, index, %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_1D_half =
"__kernel void sample_test( __global half4 *source, write_only image1d_t dest )\n"
"{\n"
"    uint index = get_global_id(0);\n"
"    write_imagef( dest, index, vload_half4(index, (__global half *)source));\n"
"}\n";

static const char *kernelpattern_image_write_1D_buffer =
"__kernel void sample_test( __global %s4 *source, write_only image1d_buffer_t dest )\n"
"{\n"
"    uint index = get_global_id(0);\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, index, %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_1D_buffer_half =
"__kernel void sample_test( __global half4 *source, write_only image1d_buffer_t dest )\n"
"{\n"
"    uint index = get_global_id(0);\n"
"    write_imagef( dest, index, vload_half4(index, (__global half *)source));\n"
"}\n";

static const char *kernelpattern_image_write_2D =
"__kernel void sample_test( __global %s4 *source, write_only image2d_t dest )\n"
"{\n"
"    int  tidX = get_global_id(0);\n"
"    int  tidY = get_global_id(1);\n"
"    uint index = tidY * get_image_width( dest ) + tidX;\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, (int2)( tidX, tidY ), %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_2D_half =
"__kernel void sample_test( __global half4 *source, write_only image2d_t dest )\n"
"{\n"
"    int  tidX = get_global_id(0);\n"
"    int  tidY = get_global_id(1);\n"
"    uint index = tidY * get_image_width( dest ) + tidX;\n"
"    write_imagef( dest, (int2)( tidX, tidY ), vload_half4(index, (__global half *)source));\n"
"}\n";

static const char *kernelpattern_image_write_1Darray =
"__kernel void sample_test( __global %s4 *source, write_only image1d_array_t dest )\n"
"{\n"
"    int  tidX = get_global_id(0);\n"
"    int  tidY = get_global_id(1);\n"
"    uint index = tidY * get_image_width( dest ) + tidX;\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, (int2)( tidX, tidY ), %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_1Darray_half =
"__kernel void sample_test( __global half4 *source, write_only image1d_array_t dest )\n"
"{\n"
"    int  tidX = get_global_id(0);\n"
"    int  tidY = get_global_id(1);\n"
"    uint index = tidY * get_image_width( dest ) + tidX;\n"
"    write_imagef( dest, (int2)( tidX, tidY ), vload_half4(index, (__global half *)source));\n"
"}\n";

static const char *kernelpattern_image_write_3D =
"#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable\n"
"__kernel void sample_test( __global %s4 *source, write_only image3d_t dest )\n"
"{\n"
"    int  tidX   = get_global_id(0);\n"
"    int  tidY   = get_global_id(1);\n"
"    int  tidZ   = get_global_id(2);\n"
"    int  width  = get_image_width( dest );\n"
"    int  height = get_image_height( dest );\n"
"    int  index = tidZ * width * height + tidY * width + tidX;\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_3D_half =
"#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable\n"
"__kernel void sample_test( __global half4 *source, write_only image3d_t dest )\n"
"{\n"
"    int  tidX   = get_global_id(0);\n"
"    int  tidY   = get_global_id(1);\n"
"    int  tidZ   = get_global_id(2);\n"
"    int  width  = get_image_width( dest );\n"
"    int  height = get_image_height( dest );\n"
"    int  index = tidZ * width * height + tidY * width + tidX;\n"
"    write_imagef( dest, (int4)( tidX, tidY, tidZ, 0 ), vload_half4(index, (__global half *)source));\n"
"}\n";

static const char *kernelpattern_image_write_2Darray =
"__kernel void sample_test( __global %s4 *source, write_only image2d_array_t dest )\n"
"{\n"
"    int  tidX   = get_global_id(0);\n"
"    int  tidY   = get_global_id(1);\n"
"    int  tidZ   = get_global_id(2);\n"
"    int  width  = get_image_width( dest );\n"
"    int  height = get_image_height( dest );\n"
"    int  index = tidZ * width * height + tidY * width + tidX;\n"
"    %s4 value = source[index];\n"
"    write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
"}\n";

static const char *kernelpattern_image_write_2Darray_half =
"__kernel void sample_test( __global half4 *source, write_only image2d_array_t dest )\n"
"{\n"
"    int  tidX   = get_global_id(0);\n"
"    int  tidY   = get_global_id(1);\n"
"    int  tidZ   = get_global_id(2);\n"
"    int  width  = get_image_width( dest );\n"
"    int  height = get_image_height( dest );\n"
"    int  index = tidZ * width * height + tidY * width + tidX;\n"
"    write_imagef( dest, (int4)( tidX, tidY, tidZ, 0 ), vload_half4(index, (__global half *)source));\n"
"}\n";

#ifdef GL_VERSION_3_2

static const char * kernelpattern_image_write_2D_depth =
"__kernel void sample_test( __global %s *source, write_only image2d_depth_t dest )\n"
"{\n"
"    int  tidX = get_global_id(0);\n"
"    int  tidY = get_global_id(1);\n"
"    uint index = tidY * get_image_width( dest ) + tidX;\n"
"    float value = source[index];\n"
"    write_imagef( dest, (int2)( tidX, tidY ), value);\n"
"}\n";

static const char * kernelpattern_image_write_2D_array_depth =
"__kernel void sample_test( __global %s *source, write_only image2d_array_depth_t dest )\n"
"{\n"
"    int  tidX   = get_global_id(0);\n"
"    int  tidY   = get_global_id(1);\n"
"    int  tidZ   = get_global_id(2);\n"
"    int  width  = get_image_width( dest );\n"
"    int  height = get_image_height( dest );\n"
"    int  index = tidZ * width * height + tidY * width + tidX;\n"
"    %s value = source[index];\n"
"    write_image%s( dest, (int4)( tidX, tidY, tidZ, 0 ), %s(value));\n"
"}\n";


#endif

#pragma mark -
#pragma mark Utility functions

static const char* get_appropriate_write_kernel(GLenum target,
  ExplicitType type, cl_channel_order channel_order)
{
  switch (get_base_gl_target(target)) {
    case GL_TEXTURE_1D:

      if (type == kHalf)
        return kernelpattern_image_write_1D_half;
      else
        return kernelpattern_image_write_1D;
      break;
    case GL_TEXTURE_BUFFER:
       if (type == kHalf)
        return kernelpattern_image_write_1D_buffer_half;
      else
        return kernelpattern_image_write_1D_buffer;
      break;
    case GL_TEXTURE_1D_ARRAY:
      if (type == kHalf)
        return kernelpattern_image_write_1Darray_half;
      else
        return kernelpattern_image_write_1Darray;
      break;
    case GL_COLOR_ATTACHMENT0:
    case GL_RENDERBUFFER:
    case GL_TEXTURE_RECTANGLE_EXT:
    case GL_TEXTURE_2D:
    case GL_TEXTURE_CUBE_MAP:
#ifdef GL_VERSION_3_2
      if (channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
        return kernelpattern_image_write_2D_depth;
#endif
      if (type == kHalf)
        return kernelpattern_image_write_2D_half;
      else
        return kernelpattern_image_write_2D;
      break;

    case GL_TEXTURE_2D_ARRAY:
#ifdef GL_VERSION_3_2
      if (channel_order == CL_DEPTH || channel_order == CL_DEPTH_STENCIL)
        return kernelpattern_image_write_2D_array_depth;
#endif
      if (type == kHalf)
        return kernelpattern_image_write_2Darray_half;
      else
        return kernelpattern_image_write_2Darray;
      break;

    case GL_TEXTURE_3D:
      if (type == kHalf)
        return kernelpattern_image_write_3D_half;
      else
        return kernelpattern_image_write_3D;
      break;

    default:
      log_error("Unsupported GL tex target (%s) passed to write test: "
        "%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
        __FILE__, __LINE__);
      return NULL;
  }
}

void set_dimensions_by_target(GLenum target, size_t *dims, size_t sizes[3],
  size_t width, size_t height, size_t depth)
{
  switch (get_base_gl_target(target)) {
    case GL_TEXTURE_1D:
      sizes[0] = width;
      *dims = 1;
      break;

    case GL_TEXTURE_BUFFER:
      sizes[0] = width;
      *dims = 1;
      break;

    case GL_TEXTURE_1D_ARRAY:
      sizes[0] = width;
      sizes[1] = height;
      *dims = 2;
      break;

    case GL_COLOR_ATTACHMENT0:
    case GL_RENDERBUFFER:
    case GL_TEXTURE_RECTANGLE_EXT:
    case GL_TEXTURE_2D:
    case GL_TEXTURE_CUBE_MAP:

      sizes[0] = width;
      sizes[1] = height;
      *dims = 2;
      break;

    case GL_TEXTURE_2D_ARRAY:
      sizes[0] = width;
      sizes[1] = height;
      sizes[2] = depth;
      *dims = 3;
      break;

    case GL_TEXTURE_3D:
      sizes[0] = width;
      sizes[1] = height;
      sizes[2] = depth;
      *dims = 3;
      break;

    default:
      log_error("Unsupported GL tex target (%s) passed to write test: "
        "%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
        __FILE__, __LINE__);
  }
}

int test_cl_image_write( cl_context context, cl_command_queue queue,
  GLenum target, cl_mem clImage, size_t width, size_t height, size_t depth,
  cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
  MTdata d, bool supports_half )
{
  size_t global_dims, global_sizes[3];
  clProgramWrapper program;
  clKernelWrapper kernel;
  clMemWrapper inStream;
  char* programPtr;
  int error;
  char kernelSource[2048];

  // What CL format did we get from the texture?

  error = clGetImageInfo(clImage, CL_IMAGE_FORMAT, sizeof(cl_image_format),
    outFormat, NULL);
  test_error(error, "Unable to get the CL image format");

  // Create the kernel source.  The target and the data type will influence
  // which particular kernel we choose.

  *outType = get_write_kernel_type( outFormat );
  size_t channelSize = get_explicit_type_size(*outType);

  const char* appropriateKernel = get_appropriate_write_kernel(target,
    *outType, outFormat->image_channel_order);
  if (*outType == kHalf && !supports_half) {
    log_info("cl_khr_fp16 isn't supported. Skip this test.\n");
    return 0;
  }

  const char* suffix = get_kernel_suffix( outFormat );
  const char* convert = get_write_conversion( outFormat, *outType );

  sprintf(kernelSource, appropriateKernel, get_explicit_type_name( *outType ),
    get_explicit_type_name( *outType ), suffix, convert);

  programPtr = kernelSource;
  if( create_single_kernel_helper_with_build_options( context, &program, &kernel, 1,
    (const char **)&programPtr, "sample_test", "" ) )
  {
      return -1;
  }

  // Create an appropriately-sized output buffer.

  // Check to see if the output buffer will fit on the device
  size_t bytes = channelSize * 4 * width * height * depth;
  cl_ulong alloc_size = 0;

  cl_device_id device = NULL;
  error = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE, sizeof(device), &device, NULL);
  test_error( error, "Unable to query command queue for device" );

  error = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(alloc_size), &alloc_size, NULL);
  test_error( error, "Unable to device for max mem alloc size" );

  if (bytes > alloc_size) {
    log_info("  Skipping: Buffer size (%lu) is greater than CL_DEVICE_MAX_MEM_ALLOC_SIZE (%lu)\n", bytes, alloc_size);
    *outSourceBuffer = NULL;
    return 0;
  }

  *outSourceBuffer = CreateRandomData(*outType, width * height * depth * 4, d);

  inStream = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR,
    channelSize * 4 * width * height * depth, *outSourceBuffer, &error );
  test_error( error, "Unable to create output buffer" );

  clSamplerWrapper sampler = clCreateSampler(context, CL_FALSE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &error);
  test_error( error, "Unable to create sampler" );

  error = clSetKernelArg( kernel, 0, sizeof( inStream ), &inStream );
  test_error( error, "Unable to set kernel arguments" );

  error = clSetKernelArg( kernel, 1, sizeof( clImage ), &clImage );
  test_error( error, "Unable to set kernel arguments" );

  // Flush and Acquire.

  glFinish();

  error = (*clEnqueueAcquireGLObjects_ptr)( queue, 1, &clImage, 0, NULL, NULL);
  test_error( error, "Unable to acquire GL obejcts");

  // Execute ( letting OpenCL choose the local size )

  // Setup the global dimensions and sizes based on the target type.
  set_dimensions_by_target(target, &global_dims, global_sizes,
    width, height, depth);

  error = clEnqueueNDRangeKernel( queue, kernel, global_dims, NULL,
    global_sizes, NULL, 0, NULL, NULL );
  test_error( error, "Unable to execute test kernel" );

  clEventWrapper event;
  error = (*clEnqueueReleaseGLObjects_ptr)( queue, 1, &clImage, 0, NULL, &event );
  test_error(error, "clEnqueueReleaseGLObjects failed");

  error = clWaitForEvents( 1, &event );
  test_error(error, "clWaitForEvents failed");

  return 0;
}

static int test_image_write( cl_context context, cl_command_queue queue,
  GLenum glTarget, GLuint glTexture, size_t width, size_t height, size_t depth,
  cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
  MTdata d, bool supports_half )
{
  int error;

  // Create a CL image from the supplied GL texture
  clMemWrapper image = (*clCreateFromGLTexture_ptr)( context, CL_MEM_WRITE_ONLY,
    glTarget, 0, glTexture, &error );

  if ( error != CL_SUCCESS ) {
    print_error( error, "Unable to create CL image from GL texture" );
    GLint fmt;
    glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt );
    log_error( "    Supplied GL texture was base format %s and internal "
      "format %s\n", GetGLBaseFormatName( fmt ), GetGLFormatName( fmt ) );
    return error;
  }

  return test_cl_image_write( context, queue, glTarget, image,
    width, height, depth, outFormat, outType, outSourceBuffer, d, supports_half );
}

int supportsHalf(cl_context context, bool* supports_half)
{
  int error;
  size_t  size;
  cl_uint numDev;

  error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");

  cl_device_id* devices = new cl_device_id[numDev];
  error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");

  *supports_half = is_extension_available(devices[0], "cl_khr_fp16");
  delete [] devices;

  return error;
}

int supportsMsaa(cl_context context, bool* supports_msaa)
{
  int error;
  size_t  size;
  cl_uint numDev;

  error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");

  cl_device_id* devices = new cl_device_id[numDev];
  error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");

  *supports_msaa = is_extension_available(devices[0], "cl_khr_gl_msaa_sharing");
  delete [] devices;

  return error;
}

int supportsDepth(cl_context context, bool* supports_depth)
{
  int error;
  size_t  size;
  cl_uint numDev;

  error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDev, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_NUM_DEVICES failed");

  cl_device_id* devices = new cl_device_id[numDev];
  error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDev * sizeof(cl_device_id), devices, NULL);
  test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");

  *supports_depth = is_extension_available(devices[0], "cl_khr_gl_depth_images");
  delete [] devices;

  return error;
}

static int test_image_format_write( cl_context context, cl_command_queue queue,
  size_t width, size_t height, size_t depth, GLenum target, GLenum format,
  GLenum internalFormat,  GLenum glType, ExplicitType type, MTdata d )
{
  int error;
  int samples = 8;
  // If we're testing a half float format, then we need to determine the
  // rounding mode of this machine.  Punt if we fail to do so.

  if( type == kHalf )
    if( DetectFloatToHalfRoundingMode(queue) )
      return 1;

  // Create an appropriate GL texture or renderbuffer, given the target.

  glTextureWrapper glTexture;
  glBufferWrapper glBuf;
  glFramebufferWrapper glFramebuffer;
  glRenderbufferWrapper glRenderbuffer;
  switch (get_base_gl_target(target)) {
    case GL_TEXTURE_1D:
      CreateGLTexture1D( width, target, format, internalFormat, glType,
        type, &glTexture, &error, false, d );
      break;
    case GL_TEXTURE_BUFFER:
      CreateGLTextureBuffer( width, target, format, internalFormat, glType,
        type, &glTexture, &glBuf, &error, false, d );
      break;
    case GL_TEXTURE_1D_ARRAY:
      CreateGLTexture1DArray( width, height, target, format, internalFormat,
        glType, type, &glTexture, &error, false, d );
      break;
    case GL_TEXTURE_RECTANGLE_EXT:
    case GL_TEXTURE_2D:
    case GL_TEXTURE_CUBE_MAP:
      CreateGLTexture2D( width, height, target, format, internalFormat, glType,
        type, &glTexture, &error, false, d );
      break;
    case GL_COLOR_ATTACHMENT0:
    case GL_RENDERBUFFER:
      CreateGLRenderbuffer(width, height, target, format, internalFormat,
        glType, type, &glFramebuffer, &glRenderbuffer, &error, d, false);
    case GL_TEXTURE_2D_ARRAY:
      CreateGLTexture2DArray( width, height, depth, target, format,
        internalFormat, glType, type, &glTexture, &error, false, d );
      break;
    case GL_TEXTURE_3D:
      CreateGLTexture3D( width, height, depth, target, format,
        internalFormat, glType, type, &glTexture, &error, d, false );
      break;

    default:
      log_error("Unsupported GL tex target (%s) passed to write test: "
        "%s (%s):%d", GetGLTargetName(target), __FUNCTION__,
        __FILE__, __LINE__);
  }

  // If there was a problem during creation, make sure it isn't a known
  // cause, and then complain.
  if ( error == -2 ) {
    log_info("OpenGL texture couldn't be created, because a texture is too big. Skipping test.\n");
    return 0;
  }

  if ( error != 0 ) {
    if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport())){
      log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. "
        "Skipping test.\n");
      return 0;
    } else {
      return error;
    }
  }

  // Run and get the results
  cl_image_format clFormat;
  ExplicitType sourceType;
  ExplicitType validationType;
  void *outSourceBuffer = NULL;

  GLenum globj = glTexture;
  if (target == GL_RENDERBUFFER || target == GL_COLOR_ATTACHMENT0) {
    globj = glRenderbuffer;
  }

  bool supports_half = false;
  error = supportsHalf(context, &supports_half);
  if( error != 0 )
    return error;

  error = test_image_write( context, queue, target, globj, width, height,
    depth, &clFormat, &sourceType, (void **)&outSourceBuffer, d, supports_half );

  if( error != 0 || ((sourceType == kHalf ) && !supports_half)) {
    if (outSourceBuffer)
      free(outSourceBuffer);
    return error;
  }

  if (!outSourceBuffer)
    return 0;

  // If actual source type was half, convert to float for validation.

  if ( sourceType == kHalf )
    validationType = kFloat;
  else
    validationType = sourceType;

  BufferOwningPtr<char> validationSource;

  if ( clFormat.image_channel_data_type == CL_UNORM_INT_101010 )
  {
    validationSource.reset( outSourceBuffer );
  }
  else
  {
    validationSource.reset( convert_to_expected( outSourceBuffer,
      width * height * depth, sourceType, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
    free(outSourceBuffer);
  }

  log_info( "- Write for %s [%4ld x %4ld x %4ld] : GL Texture : %s : %s : %s =>"
    " CL Image : %s : %s \n",
    GetGLTargetName(target),
    width, height, depth,
    GetGLFormatName( format ),
    GetGLFormatName( internalFormat ),
    GetGLTypeName( glType),
    GetChannelOrderName( clFormat.image_channel_order ),
    GetChannelTypeName( clFormat.image_channel_data_type ));

  // Read the results from the GL texture.

  ExplicitType readType = type;
  BufferOwningPtr<char> glResults( ReadGLTexture(
    target, glTexture, glBuf, width, format,
    internalFormat, glType, readType, /* unused */ 1, 1 ) );
  if( glResults == NULL )
    return -1;

  // We have to convert our input buffer to the returned type, so we can validate.
  BufferOwningPtr<char> convertedGLResults;
  if ( clFormat.image_channel_data_type != CL_UNORM_INT_101010 )
  {
    convertedGLResults.reset( convert_to_expected(
      glResults, width * height * depth, readType, validationType, get_channel_order_channel_count(clFormat.image_channel_order), glType ));
  }

  // Validate.

  int valid = 0;
  if (convertedGLResults) {
    if( sourceType == kFloat || sourceType == kHalf )
    {
      if ( clFormat.image_channel_data_type == CL_UNORM_INT_101010 )
      {
        valid = validate_float_results_rgb_101010( validationSource, glResults, width, height, depth, 1 );
      }
      else
      {
        valid = validate_float_results( validationSource, convertedGLResults,
          width, height, depth, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
      }
    }
    else
    {
      valid = validate_integer_results( validationSource, convertedGLResults,
        width, height, depth, 1, get_explicit_type_size( readType ) );
    }
  }

  return valid;
}

#pragma mark -
#pragma mark Write test common entry point

// This is the main loop for all of the write tests.  It iterates over the
// given formats & targets, testing a variety of sizes against each
// combination.

int test_images_write_common(cl_device_id device, cl_context context,
  cl_command_queue queue, struct format* formats, size_t nformats,
  GLenum *targets, size_t ntargets, sizevec_t* sizes, size_t nsizes )
{
  int err = 0;
  int error = 0;
  RandomSeed seed(gRandomSeed);

  // First, ensure this device supports images.

  if (checkForImageSupport(device)) {
    log_info("Device does not support images.  Skipping test.\n");
    return 0;
  }

  // Get the value of CL_DEVICE_MAX_MEM_ALLOC_SIZE
  cl_ulong max_individual_allocation_size = 0;
  err = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
                        sizeof(max_individual_allocation_size),
                        &max_individual_allocation_size, NULL);
  if (err) {
    log_error("ERROR: clGetDeviceInfo failed for CL_DEVICE_MAX_MEM_ALLOC_SIZE.\n");
    error++;
    return error;
  }

  size_t total_allocation_size;
  size_t fidx, tidx, sidx;

  for ( fidx = 0; fidx < nformats; fidx++ ) {
    for ( tidx = 0; tidx < ntargets; tidx++ ) {

      // Texture buffer only takes an internal format, so the level data passed
      // by the test and used for verification must match the internal format
      if ((targets[tidx] == GL_TEXTURE_BUFFER) && (GetGLFormat(formats[ fidx ].internal) != formats[fidx].formattype))
        continue;

      if ( formats[ fidx ].datatype == GL_UNSIGNED_INT_2_10_10_10_REV )
      {
        // Check if the RGB 101010 format is supported
        if ( is_rgb_101010_supported( context, targets[ tidx ] ) == 0 )
          continue; // skip
      }

      if (formats[ fidx ].datatype == GL_UNSIGNED_INT_24_8)
      {
        //check if a implementation supports writing to the depth stencil formats
        cl_image_format imageFormat = { CL_DEPTH_STENCIL, CL_UNORM_INT24 };
        if (!is_image_format_supported(context, CL_MEM_WRITE_ONLY, (targets[tidx] == GL_TEXTURE_2D || targets[tidx] == GL_TEXTURE_RECTANGLE) ? CL_MEM_OBJECT_IMAGE2D: CL_MEM_OBJECT_IMAGE2D_ARRAY, &imageFormat))
          continue;
      }

      if (formats[ fidx ].datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
      {
        //check if a implementation supports writing to the depth stencil formats
        cl_image_format imageFormat = { CL_DEPTH_STENCIL, CL_FLOAT};
        if (!is_image_format_supported(context, CL_MEM_WRITE_ONLY, (targets[tidx] == GL_TEXTURE_2D || targets[tidx] == GL_TEXTURE_RECTANGLE) ? CL_MEM_OBJECT_IMAGE2D: CL_MEM_OBJECT_IMAGE2D_ARRAY, &imageFormat))
          continue;
      }

      if (targets[tidx] != GL_TEXTURE_BUFFER)
        log_info( "Testing image write for GL format %s : %s : %s : %s\n",
                 GetGLTargetName( targets[ tidx ] ),
                 GetGLFormatName( formats[ fidx ].internal ),
                 GetGLBaseFormatName( formats[ fidx ].formattype ),
                 GetGLTypeName( formats[ fidx ].datatype ) );
      else
        log_info( "Testing image write for GL format %s : %s\n",
                 GetGLTargetName( targets[ tidx ] ),
                 GetGLFormatName( formats[ fidx ].internal ));


      for (sidx = 0; sidx < nsizes; sidx++) {

        // All tested formats are 4-channel formats
        total_allocation_size =
           sizes[sidx].width * sizes[sidx].height * sizes[sidx].depth *
           4 * get_explicit_type_size( formats[ fidx ].type );

        if (total_allocation_size > max_individual_allocation_size) {
          log_info( "The requested allocation size (%gMB) is larger than the "
                    "maximum individual allocation size (%gMB)\n",
                    total_allocation_size/(1024.0*1024.0),
                    max_individual_allocation_size/(1024.0*1024.0));
          log_info( "Skipping write test for %s : %s : %s : %s "
                    " and size (%ld, %ld, %ld)\n",
                    GetGLTargetName( targets[ tidx ] ),
                    GetGLFormatName( formats[ fidx ].internal ),
                    GetGLBaseFormatName( formats[ fidx ].formattype ),
                    GetGLTypeName( formats[ fidx ].datatype ),
                    sizes[sidx].width,
                    sizes[sidx].height,
                    sizes[sidx].depth);
          continue;
        }
#ifdef GL_VERSION_3_2
        if (get_base_gl_target(targets[ tidx ]) == GL_TEXTURE_2D_MULTISAMPLE ||
            get_base_gl_target(targets[ tidx ]) == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
        {
            bool supports_msaa;
            int errorInGetInfo = supportsMsaa(context, &supports_msaa);
            if (errorInGetInfo != 0) return errorInGetInfo;
            if (!supports_msaa) return 0;
        }
        if (formats[ fidx ].formattype == GL_DEPTH_COMPONENT ||
            formats[ fidx ].formattype == GL_DEPTH_STENCIL)
        {
            bool supports_depth;
            int errorInGetInfo = supportsDepth(context, &supports_depth);
            if (errorInGetInfo != 0) return errorInGetInfo;
            if (!supports_depth) return 0;
        }
#endif

        if( test_image_format_write( context, queue,
                                     sizes[sidx].width,
                                     sizes[sidx].height,
                                     sizes[sidx].depth,
                                     targets[ tidx ],
                                     formats[ fidx ].formattype,
                                     formats[ fidx ].internal,
                                     formats[ fidx ].datatype,
                                     formats[ fidx ].type, seed ) )
        {
          log_error( "ERROR: Image write test failed for %s : %s : %s : %s "
            " and size (%ld, %ld, %ld)\n\n",
            GetGLTargetName( targets[ tidx ] ),
            GetGLFormatName( formats[ fidx ].internal ),
            GetGLBaseFormatName( formats[ fidx ].formattype ),
            GetGLTypeName( formats[ fidx ].datatype ),
            sizes[sidx].width,
            sizes[sidx].height,
            sizes[sidx].depth);

          error++;
          break;    // Skip other sizes for this combination
        }
      }

      // If we passed all sizes (check versus size loop count):

      if (sidx == nsizes) {
        log_info( "passed: Image write for GL format  %s : %s : %s : %s\n\n",
          GetGLTargetName( targets[ tidx ] ),
          GetGLFormatName( formats[ fidx ].internal ),
          GetGLBaseFormatName( formats[ fidx ].formattype ),
          GetGLTypeName( formats[ fidx ].datatype ) );
      }
    }
  }

  return error;
}
