//
// 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 "common.h"
#include "testBase.h"

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

using namespace std;
void calc_1D_array_size_descriptors(sizevec_t* sizes, size_t nsizes)
{
  // Need to limit array size according to GL device properties
  GLint maxTextureLayers = 16, maxTextureSize = 4096;
  glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

  RandomSeed seed( gRandomSeed );

  // Generate some random sizes (within reasonable ranges)
  for (size_t i = 0; i < nsizes; i++) {
    sizes[i].width  = random_in_range( 2, min(maxTextureSize, 1<<(i+4)), seed );
    sizes[i].height = random_in_range( 2, min(maxTextureLayers, 1<<(i+4)), seed );
    sizes[i].depth  = 1;
  }
}

int test_images_read_1Darray( cl_device_id device, cl_context context,
  cl_command_queue queue, int )
{
  size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);

  GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
  size_t ntargets = sizeof(targets) / sizeof(targets[0]);

  const size_t nsizes = 8;
  sizevec_t sizes[nsizes];
  calc_1D_array_size_descriptors(sizes, nsizes);

  return test_images_read_common(device, context, queue, common_formats,
      nformats, targets, ntargets, sizes, nsizes);
}

int test_images_write_1Darray( cl_device_id device, cl_context context,
  cl_command_queue queue, int numElements )
{
  GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
  size_t ntargets = sizeof(targets) / sizeof(targets[0]);
  size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);

  const size_t nsizes = 8;
  sizevec_t sizes[nsizes];
  calc_1D_array_size_descriptors(sizes, nsizes);

  return test_images_write_common( device, context, queue, common_formats,
    nformats, targets, ntargets, sizes, nsizes );
}

int test_images_1Darray_getinfo( cl_device_id device, cl_context context,
  cl_command_queue queue, int )
{
  size_t nformats = sizeof(common_formats) / sizeof(common_formats[0]);

  GLenum targets[] = { GL_TEXTURE_1D_ARRAY };
  size_t ntargets = sizeof(targets) / sizeof(targets[0]);

  const size_t nsizes = 8;
  sizevec_t sizes[nsizes];
  calc_1D_array_size_descriptors(sizes, nsizes);

  return test_images_get_info_common(device, context, queue, common_formats,
      nformats, targets, ntargets, sizes, nsizes);
}