enum piglit_result
piglit_cl_test(const int argc,
	       const char **argv,
	       const struct piglit_cl_custom_test_config *config,
	       const struct piglit_cl_custom_test_env *env)
{
	piglit_cl_context piglit_cl_context = NULL;
	cl_command_queue queue = NULL;
	cl_mem buffer = NULL, sub_buffer = NULL;
	cl_program program = NULL;
	cl_kernel kernel = NULL;
	unsigned i;
	size_t global_size = 1, local_size = 1;
	cl_buffer_region region = {PAD_SIZE, SUB_BUFFER_SIZE };
	cl_int err;
	char *sub_data = malloc(BUFFER_SIZE);
	char *padding = malloc(PAD_SIZE);
	char data_byte = (char)DATA_BYTE;
	char pad_byte = 0xcd;
	char *out_data = malloc(BUFFER_SIZE);

	assert(SUB_BUFFER_SIZE % 4 == 0);
	memset(sub_data, data_byte, SUB_BUFFER_SIZE);
	memset(padding, pad_byte, PAD_SIZE);

	piglit_cl_context = piglit_cl_create_context(env->platform_id,
							&env->device_id, 1);
	queue = piglit_cl_context->command_queues[0];
	buffer = piglit_cl_create_buffer(piglit_cl_context, CL_MEM_READ_WRITE,
                                         BUFFER_SIZE);
	sub_buffer = clCreateSubBuffer(buffer, CL_MEM_READ_WRITE,
                                       CL_BUFFER_CREATE_TYPE_REGION,
                                       &region, &err);
	if (err != CL_SUCCESS) {
		fprintf(stderr, "clCreateSubBuffer() failed.");
		return PIGLIT_FAIL;
	}

	clEnqueueWriteBuffer(queue, buffer, CL_FALSE, 0, PAD_SIZE, padding,
                             0, NULL, NULL);
	clEnqueueWriteBuffer(queue, buffer, CL_FALSE, BUFFER_SIZE - PAD_SIZE,
                             PAD_SIZE, padding, 0, NULL, NULL);
	clFinish(queue);

	program = piglit_cl_build_program_with_source(piglit_cl_context, 1,
                                                      &source, "");
	kernel = piglit_cl_create_kernel(program, "test");

	if (!piglit_cl_set_kernel_arg(kernel, 0, sizeof(cl_mem), &sub_buffer)) {
		return PIGLIT_FAIL;
	}

	if (!piglit_cl_enqueue_ND_range_kernel(queue, kernel, 1, NULL,
	                                       &global_size, &local_size)) {
		return PIGLIT_FAIL;
	}
	clFinish(queue);

	clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, BUFFER_SIZE, out_data,
                            0, NULL, NULL);
	for (i = 0; i < PAD_SIZE; i++) {
		if (!piglit_cl_probe_integer(out_data[i], pad_byte, 0)) {
			fprintf(stderr, "Failed at offset %u\n", i);
			return PIGLIT_FAIL;
		}
	}

	for (i = BUFFER_SIZE - PAD_SIZE; i < BUFFER_SIZE; i++) {
		if (!piglit_cl_probe_integer(out_data[i], pad_byte, 0)) {
			fprintf(stderr, "Failed at offset %u\n", i);
			return PIGLIT_FAIL;
		}
	}

	for (i = PAD_SIZE; i < BUFFER_SIZE - PAD_SIZE; i++) {
		if (!piglit_cl_probe_integer(out_data[i], data_byte, 0)) {
			fprintf(stderr, "Failed at offset %u\n", i);
			return PIGLIT_FAIL;
		}
	}
	return PIGLIT_PASS;
}
Exemple #2
0
enum piglit_result
piglit_cl_test(const int argc,
               const char **argv,
               const struct piglit_cl_api_test_config* config,
               const struct piglit_cl_api_test_env* env)
{
#if defined(CL_VERSION_1_2)
	enum piglit_result result = PIGLIT_PASS;
	cl_int err;

#define IMG_WIDTH 4
#define IMG_HEIGHT 4
#define IMG_DATA_SIZE 4
#define IMG_BUFFER_SIZE IMG_WIDTH * IMG_HEIGHT * IMG_DATA_SIZE

	unsigned char img_buf[IMG_BUFFER_SIZE] = {0};
	unsigned char dst_buf[IMG_BUFFER_SIZE] = {0};
	unsigned char exp_buf[IMG_BUFFER_SIZE] = {0};
	int pattern[4] = {129, 33, 77, 255};
	size_t origin[3] = {0, 0, 0};
	size_t region[3] = {2, 2, 1};
	size_t tmp;
	cl_event event;
	cl_mem image;
	cl_image_format img_format;
	cl_image_desc img_desc = {0};
	cl_command_queue queue = env->context->command_queues[0];
	int i;

	cl_bool *image_support =
		piglit_cl_get_device_info(env->context->device_ids[0],
		                          CL_DEVICE_IMAGE_SUPPORT);

	if (!*image_support) {
		fprintf(stderr, "No image support\n");
		free(image_support);
		return PIGLIT_SKIP;
	}

	img_format.image_channel_order = CL_RGBA;
	img_format.image_channel_data_type = CL_UNSIGNED_INT8;
	img_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
	img_desc.image_width = IMG_WIDTH;
	img_desc.image_height = IMG_HEIGHT;
	img_desc.buffer = NULL;

/*** Normal usage ***/
	image = clCreateImage(env->context->cl_ctx,
	                      CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
	                      &img_format, &img_desc, &img_buf, &err);

	if(!piglit_cl_check_error(err, CL_SUCCESS)) {
		fprintf(stderr, "Failed (error code: %s): Creating an image\n",
		        piglit_cl_get_error_name(err));
		return PIGLIT_FAIL;
	}

	if (!test(queue, image, pattern, origin, region,
	          0, NULL, NULL,
	          CL_SUCCESS, &result, "Enqueuing the image to be filled")) {
		return PIGLIT_FAIL;
	}

	region[0] = IMG_WIDTH;
	region[1] = IMG_HEIGHT;
	err = clEnqueueReadImage(queue, image, 1, origin, region, 0, 0,
	                         dst_buf, 0, NULL, NULL);
	if(!piglit_cl_check_error(err, CL_SUCCESS)) {
		fprintf(stderr, "Failed (error code: %s): Reading image\n",
		        piglit_cl_get_error_name(err));
		return PIGLIT_FAIL;
	}

	/*
	 * fill the host buffer with the pattern
	 * for exemple : pattern == 1234
	 *
	 * 12341234abcdabcd
	 * 12341234abcdabcd
	 * abcdabcdabcdabcd
	 * abcdabcdabcdabcd
	 */
	exp_buf[0] = pattern[0];
	exp_buf[1] = pattern[1];
	exp_buf[2] = pattern[2];
	exp_buf[3] = pattern[3];
	memcpy(exp_buf + (IMG_DATA_SIZE * 1), exp_buf, IMG_DATA_SIZE);
	memcpy(exp_buf + (IMG_DATA_SIZE * 4), exp_buf, IMG_DATA_SIZE);
	memcpy(exp_buf + (IMG_DATA_SIZE * 5), exp_buf, IMG_DATA_SIZE);

	for (i = 0; i < sizeof(dst_buf) / sizeof(dst_buf[0]); ++i) {
		if (!piglit_cl_probe_integer(dst_buf[i], exp_buf[i], 0)) {
			fprintf(stderr, "Error at %d: got %d, expected %d\n",
			        i, dst_buf[i], exp_buf[i]);
			return PIGLIT_FAIL;
		}
	}

/*** Errors ***/

	/*
	 * CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue.
	 */
	test(NULL, image, pattern, origin, region,
		  0, NULL, NULL,
		  CL_INVALID_COMMAND_QUEUE, &result,
		  "CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue");

	/*
	 * CL_INVALID_CONTEXT if the context associated with command_queue and
	 * image are not the same or if the context associated with command_queue
	 * and events in event_wait_list are not the same.
	 */
	{
		piglit_cl_context context;
		cl_int err;
		context = piglit_cl_create_context(env->platform_id,
		                                   env->context->device_ids, 1);
		if (context) {
			event = clCreateUserEvent(context->cl_ctx, &err);
			if (err == CL_SUCCESS) {
				err = clSetUserEventStatus(event, CL_COMPLETE);
				if (err == CL_SUCCESS) {
					test(context->command_queues[0], image, pattern, origin, region,
					     0, NULL, NULL,
					     CL_INVALID_CONTEXT, &result,
					     "CL_INVALID_CONTEXT if the context associated with command_queue and image are not the same");

					test(queue, image, pattern, origin, region,
					     1, &event, NULL,
					     CL_INVALID_CONTEXT, &result,
					     "CL_INVALID_CONTEXT if the context associated with command_queue and events in event_wait_list are not the same");
				} else {
					fprintf(stderr, "Could not set event status.\n");
					piglit_merge_result(&result, PIGLIT_WARN);
				}
				clReleaseEvent(event);
			} else {
				fprintf(stderr, "Could not create user event.\n");
				piglit_merge_result(&result, PIGLIT_WARN);
			}

			piglit_cl_release_context(context);
		} else {
			fprintf(stderr, "Could not test triggering CL_INVALID_CONTEXT.\n");
			piglit_merge_result(&result, PIGLIT_WARN);
		}
	}

	/*
	 * CL_INVALID_MEM_OBJECT if image is not a valid buffer object.
	 */
	test(queue, NULL, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_MEM_OBJECT, &result,
	     "CL_INVALID_MEM_OBJECT if image is not a valid buffer object");

	/*
	 * CL_INVALID_VALUE if fill_color is NULL.
	 */
	test(queue, image, NULL, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if fill_color is NULL");

	/*
	 * CL_INVALID_VALUE if the region being written specified by origin and
	 * region is out of bounds or if ptr is a NULL value.
	 */
	tmp = origin[0];
	origin[0] = IMG_WIDTH + 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (origin)");
	origin[0] = tmp;

	tmp = region[0];
	region[0] = IMG_WIDTH + 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (region)");
	region[0] = tmp;

	test(queue, image, pattern, NULL, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if ptr is a NULL value (origin)");

	test(queue, image, pattern, origin, NULL,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if ptr is a NULL value (region)");

	/*
	 * CL_INVALID_VALUE if values in origin and region do not follow rules
	 * described in the argument description for origin and region.
	 */
	tmp = origin[2];
	origin[2] = 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if values in origin do not follow rules described in the argument description for origin");
	origin[2] = tmp;

	tmp = region[2];
	region[2] = 0;
	test(queue, image, pattern, origin, region,
		  0, NULL, NULL,
		CL_INVALID_VALUE, &result,
		"CL_INVALID_VALUE if values in region do not follow rules described in the argument description for region");
	region[2] = tmp;

	/*
	 * CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and
	 * num_events_in_wait_list > 0, or event_wait_list is not NULL and
	 * num_events_in_wait_list is 0, or if event objects in event_wait_list
	 * are not valid events.
	 */
	event = NULL;
	test(queue, image, pattern, origin, region,
	     1, NULL, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and num_events_in_wait_list > 0");

	test(queue, image, pattern, origin, region,
	     0, &event, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is not NULL and num_events_in_wait_list is 0");

	test(queue, image, pattern, origin, region,
	     1, &event, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event objects in event_wait_list are not valid events");

	/*
	 * CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified
	 * or compute row and/or slice pitch) for image are not supported by device
	 * associated with queue.
	 */
	/* This is a per device test, clCreateImage would have failed before */

	/*
	 * CL_INVALID_IMAGE_FORMAT if image format (image channel order and data type)
	 * for image are not supported by device associated with queue.
	 */
	/* This is a per device test, clCreateImage would have failed before */

	free(image_support);
	clReleaseMemObject(image);
	return result;
#else
	return PIGLIT_SKIP;
#endif
}