Files
OpenCL-CTS/test_conformance/basic/test_imagereadwrite.c
Kevin Petit d8733efc0f Synchronise with Khronos-private Gitlab branch
The maintenance of the conformance tests is moving to Github.

This commit contains all the changes that have been done in
Gitlab since the first public release of the conformance tests.

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2019-03-05 16:23:49 +00:00

423 lines
13 KiB
C

//
// 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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#if !defined(_WIN32)
#include <stdbool.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
static unsigned char *
generate_rgba8_image(int w, int h, MTdata d)
{
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
int i;
for (i=0; i<w*h*4; i++)
ptr[i] = (unsigned char)genrand_int32(d);
return ptr;
}
static void
update_rgba8_image(unsigned char *p, int x, int y, int w, int h, int img_width, MTdata d)
{
int i, j, indx;
for (i=y; i<y+h; i++)
{
indx = (i * img_width + x) * 4;
for (j=x; j<x+w; j++,indx+=4)
{
p[indx+0] = (unsigned char)genrand_int32(d);
p[indx+1] = (unsigned char)genrand_int32(d);
p[indx+2] = (unsigned char)genrand_int32(d);
p[indx+3] = (unsigned char)genrand_int32(d);
}
}
}
static void
update_image_from_image(void *out, void *in, int x, int y, int w, int h, int img_width, int elem_size)
{
int i, j, k, out_indx, in_indx;
in_indx = 0;
for (i=y; i<y+h; i++)
{
out_indx = (i * img_width + x) * elem_size;
for (j=x; j<x+w; j++,out_indx+=elem_size)
{
for (k=0; k<elem_size; k++)
{
((char*)out)[out_indx + k] = ((char*)in)[in_indx];
in_indx++;
}
}
}
}
static int
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
{
int i;
for (i=0; i<w*h*4; i++)
{
if (outptr[i] != image[i])
{
log_error("i = %d. Expected (%d %d %d %d), got (%d %d %d %d)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
return -1;
}
}
return 0;
}
static unsigned short *
generate_rgba16_image(int w, int h, MTdata d)
{
unsigned short *ptr = (unsigned short*)malloc(w * h * 4 * sizeof(unsigned short));
int i;
for (i=0; i<w*h*4; i++)
ptr[i] = (unsigned short)genrand_int32(d);
return ptr;
}
static void
update_rgba16_image(unsigned short *p, int x, int y, int w, int h, int img_width, MTdata d)
{
int i, j, indx;
for (i=y; i<y+h; i++)
{
indx = (i * img_width + x) * 4;
for (j=x; j<x+w; j++,indx+=4)
{
p[indx+0] = (unsigned short)genrand_int32(d);
p[indx+1] = (unsigned short)genrand_int32(d);
p[indx+2] = (unsigned short)genrand_int32(d);
p[indx+3] = (unsigned short)genrand_int32(d);
}
}
}
static int
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
{
int i;
for (i=0; i<w*h*4; i++)
{
if (outptr[i] != image[i])
{
log_error("i = %d. Expected (%d %d %d %d), got (%d %d %d %d)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
return -1;
}
}
return 0;
}
static float *
generate_rgbafp_image(int w, int h, MTdata d)
{
float *ptr = (float*)malloc(w * h * 4 * sizeof(float));
int i;
for (i=0; i<w*h*4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
return ptr;
}
static void
update_rgbafp_image(float *p, int x, int y, int w, int h, int img_width, MTdata d)
{
int i, j, indx;
for (i=y; i<y+h; i++)
{
indx = (i * img_width + x) * 4;
for (j=x; j<x+w; j++,indx+=4)
{
p[indx+0] = get_random_float(-0x40000000, 0x40000000, d);
p[indx+1] = get_random_float(-0x40000000, 0x40000000, d);
p[indx+2] = get_random_float(-0x40000000, 0x40000000, d);
p[indx+3] = get_random_float(-0x40000000, 0x40000000, d);
}
}
}
static int
verify_rgbafp_image(float *image, float *outptr, int w, int h)
{
int i;
for (i=0; i<w*h*4; i++)
{
if (outptr[i] != image[i])
{
log_error("i = %d. Expected (%f %f %f %f), got (%f %f %f %f)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
return -1;
}
}
return 0;
}
int
test_imagereadwrite(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_image_format img_format;
unsigned char *rgba8_inptr, *rgba8_outptr;
unsigned short *rgba16_inptr, *rgba16_outptr;
float *rgbafp_inptr, *rgbafp_outptr;
clMemWrapper streams[3];
int img_width = 512;
int img_height = 512;
int num_tries = 200;
int i, j, err;
MTdata d;
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
d = init_genrand( gRandomSeed );
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, d);
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, d);
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, d);
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height);
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height);
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height);
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT8;
streams[0] = create_image_2d(context, (cl_mem_flags)(CL_MEM_READ_WRITE), &img_format, img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT16;
streams[1] = create_image_2d(context, (cl_mem_flags)(CL_MEM_READ_WRITE), &img_format, img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_FLOAT;
streams[2] = create_image_2d(context, (cl_mem_flags)(CL_MEM_READ_WRITE), &img_format, img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
for (i=0; i<3; i++)
{
void *p;
if (i == 0)
p = (void *)rgba8_inptr;
else if (i == 1)
p = (void *)rgba16_inptr;
else
p = (void *)rgbafp_inptr;
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, 1};
err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
origin, region, 0, 0,
p, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clWriteImage2D failed\n");
return -1;
}
}
for (i=0,j=0; i<num_tries*3; i++,j++)
{
int x = (int)get_random_float(0, img_width, d);
int y = (int)get_random_float(0, img_height, d);
int w = (int)get_random_float(1, (img_width - x), d);
int h = (int)get_random_float(1, (img_height - y), d);
size_t input_pitch;
int set_input_pitch = (int)(genrand_int32(d) & 0x01);
int packed_update = (int)(genrand_int32(d) & 0x01);
void *p, *outp;
int elem_size;
if (j == 3)
j = 0;
switch (j)
{
case 0:
//if ((w<=10) || (h<=10)) continue;
elem_size = 4;
if(packed_update)
{
p = generate_rgba8_image(w, h, d);
update_image_from_image(rgba8_inptr, p, x, y, w, h, img_width, elem_size);
}
else
{
update_rgba8_image(rgba8_inptr, x, y, w, h, img_width, d);
p = (void *)(rgba8_inptr + ((y * img_width + x) * 4));
}
outp = (void *)rgba8_outptr;
break;
case 1:
//if ((w<=8) || (h<=8)) continue;
elem_size = 2*4;
if(packed_update)
{
p = generate_rgba16_image(w, h, d);
update_image_from_image(rgba16_inptr, p, x, y, w, h, img_width, elem_size);
}
else
{
update_rgba16_image(rgba16_inptr, x, y, w, h, img_width, d);
p = (void *)(rgba16_inptr + ((y * img_width + x) * 4));
}
outp = (void *)rgba16_outptr;
break;
case 2:
//if ((w<=8) || (h<=8)) continue;
elem_size = 4*4;
if(packed_update)
{
p = generate_rgbafp_image(w, h, d);
update_image_from_image(rgbafp_inptr, p, x, y, w, h, img_width, elem_size);
}
else
{
update_rgbafp_image(rgbafp_inptr, x, y, w, h, img_width, d);
p = (void *)(rgbafp_inptr + ((y * img_width + x) * 4));
}
outp = (void *)rgbafp_outptr;
break;
}
const char* update_packed_pitch_name = "";
if(packed_update)
{
if(set_input_pitch)
{
// for packed updates the pitch does not need to be calculated here (but can be)
update_packed_pitch_name = "'packed with pitch'";
input_pitch = w*elem_size;
}
else
{
// for packed updates the pitch does not need to be calculated here
update_packed_pitch_name = "'packed without pitch'";
input_pitch = 0;
}
}
else
{
// for unpacked updates the pitch is required
update_packed_pitch_name = "'unpacked with pitch'";
input_pitch = img_width*elem_size;
}
size_t origin[3] = {x,y,0}, region[3] = {w, h, 1};
err = clEnqueueWriteImage(queue, streams[j], CL_TRUE,
origin, region, input_pitch, 0, p,
0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clWriteImage update failed for %s %s: %d\n",
(packed_update) ? "packed" : "unpacked",
(set_input_pitch) ? "set pitch" : "unset pitch", err);
free_mtdata(d);
return -1;
}
if(packed_update)
{
free(p);
p = NULL;
}
memset(outp, 0x7, img_width*img_height*elem_size);
origin[0]=0; origin[1]=0; origin[2]=0;
region[0]=img_width; region[1]=img_height; region[2]=1;
err = clEnqueueReadImage(queue, streams[j], CL_TRUE,
origin, region, 0,0,
outp, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clReadImage failed\n");
free_mtdata(d);
return -1;
}
switch (j)
{
case 0:
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
log_error("IMAGE RGBA8 read, write %s test failed\n", update_packed_pitch_name);
}
break;
case 1:
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
log_error("IMAGE RGBA16 read, write %s test failed\n", update_packed_pitch_name);
}
break;
case 2:
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
log_error("IMAGE RGBA FP read, write %s test failed\n", update_packed_pitch_name);
}
break;
}
if (err) break;
}
free_mtdata(d);
free(rgba8_inptr);
free(rgba16_inptr);
free(rgbafp_inptr);
free(rgba8_outptr);
free(rgba16_outptr);
free(rgbafp_outptr);
if (!err)
log_info("IMAGE read, write test passed\n");
return err;
}