/** * Tests creation (using "full" constructor), getting info from and * destruction of sampler wrapper objects. * */ static void create_full_info_destroy_test() { /* Test variables. */ CCLContext* ctx = NULL; CCLSampler* s = NULL; const cl_sampler_properties sampler_properties[] = { CL_SAMPLER_NORMALIZED_COORDS, CL_FALSE, CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_CLAMP_TO_EDGE, CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST, 0}; GError* err = NULL; /* Get the test context with the pre-defined device. */ ctx = ccl_test_context_new(&err); g_assert_no_error(err); /* Create sampler using "full" constructor. */ s = ccl_sampler_new_full(ctx, sampler_properties, &err); g_assert_no_error(err); /* Get some info and check if the return value is as expected. */ cl_addressing_mode am; am = ccl_sampler_get_info_scalar( s, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode, &err); g_assert_no_error(err); g_assert_cmpuint(am, ==, CL_ADDRESS_CLAMP_TO_EDGE); cl_filter_mode fm; fm = ccl_sampler_get_info_scalar( s, CL_SAMPLER_FILTER_MODE, cl_filter_mode, &err); g_assert_no_error(err); g_assert_cmpuint(fm, ==, CL_FILTER_NEAREST); cl_bool nc; nc = ccl_sampler_get_info_scalar( s, CL_SAMPLER_NORMALIZED_COORDS, cl_bool, &err); g_assert_no_error(err); g_assert_cmpuint(nc, ==, CL_FALSE); cl_context context; context = ccl_sampler_get_info_scalar( s, CL_SAMPLER_CONTEXT, cl_context, &err); g_assert_no_error(err); g_assert_cmphex(GPOINTER_TO_UINT(context), ==, GPOINTER_TO_UINT(ccl_context_unwrap(ctx))); /* Destroy sampler. */ ccl_sampler_destroy(s); ccl_context_destroy(ctx); /* Confirm that memory allocated by wrappers has been properly * freed. */ g_assert(ccl_wrapper_memcheck()); }
/** * Tests creation (using "simple" constructor), getting info from and * destruction of sampler wrapper objects. * */ static void create_info_destroy_test() { /* Test variables. */ CCLContext* ctx = NULL; CCLSampler* s = NULL; cl_sampler sampler = NULL; GError* err = NULL; cl_int ocl_status; const cl_sampler_properties sampler_properties[] = { CL_SAMPLER_NORMALIZED_COORDS, CL_TRUE, CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_NONE, CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST, 0}; /* Get the test context with the pre-defined device. */ ctx = ccl_test_context_new(&err); g_assert_no_error(err); /* Test three ways to create a sampler. */ for (cl_uint i = 0; i < 3; ++i) { /* Create sampler wrapper. */ switch (i) { case 0: /* Create sampler using "simple" constructor. */ s = ccl_sampler_new(ctx, CL_TRUE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &err); g_assert_no_error(err); break; case 1: /* Using the "full" constructor. */ s = ccl_sampler_new_full(ctx, sampler_properties, &err); g_assert_no_error(err); break; case 2: /* Using the "wrap" constructor. */ CCL_BEGIN_IGNORE_DEPRECATIONS sampler = clCreateSampler(ccl_context_unwrap(ctx), CL_TRUE, CL_ADDRESS_NONE, CL_FILTER_NEAREST, &ocl_status); g_assert_cmpint(ocl_status, ==, CL_SUCCESS); CCL_END_IGNORE_DEPRECATIONS s = ccl_sampler_new_wrap(sampler); g_assert_cmphex(GPOINTER_TO_UINT(sampler), ==, GPOINTER_TO_UINT(ccl_sampler_unwrap(s))); break; } /* Get some info and check if the return value is as expected. */ cl_addressing_mode am; am = ccl_sampler_get_info_scalar( s, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode, &err); g_assert_no_error(err); g_assert_cmpuint(am, ==, CL_ADDRESS_NONE); cl_filter_mode fm; fm = ccl_sampler_get_info_scalar( s, CL_SAMPLER_FILTER_MODE, cl_filter_mode, &err); g_assert_no_error(err); g_assert_cmpuint(fm, ==, CL_FILTER_NEAREST); cl_bool nc; nc = ccl_sampler_get_info_scalar( s, CL_SAMPLER_NORMALIZED_COORDS, cl_bool, &err); g_assert_no_error(err); g_assert_cmpuint(nc, ==, CL_TRUE); cl_context context; context = ccl_sampler_get_info_scalar( s, CL_SAMPLER_CONTEXT, cl_context, &err); g_assert_no_error(err); g_assert_cmphex(GPOINTER_TO_UINT(context), ==, GPOINTER_TO_UINT(ccl_context_unwrap(ctx))); /* Destroy sampler. */ ccl_sampler_destroy(s); } /* Destroy context. */ ccl_context_destroy(ctx); /* Confirm that memory allocated by wrappers has been properly * freed. */ g_assert(ccl_wrapper_memcheck()); }
/** * Image filter main function. * */ int main(int argc, char * argv[]) { /* Wrappers for OpenCL objects. */ CCLContext * ctx; CCLDevice * dev; CCLImage * img_in; CCLImage * img_out; CCLQueue * queue; CCLProgram * prg; CCLKernel * krnl; CCLSampler * smplr; /* Device selected specified in the command line. */ int dev_idx = -1; /* Error handling object (must be initialized to NULL). */ CCLErr * err = NULL; /* Does selected device support images? */ cl_bool image_ok; /* Image data in host. */ unsigned char * input_image; unsigned char * output_image; /* Image properties. */ int width, height, n_channels; /* Image file write status. */ int file_write_status; /* Image parameters. */ cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT8 }; /* Origin and region of complete image. */ size_t origin[3] = { 0, 0, 0 }; size_t region[3]; /* Real worksize. */ size_t real_ws[2]; /* Global and local worksizes. */ size_t gws[2]; size_t lws[2]; /* Check arguments. */ if (argc < 2) { ERROR_MSG_AND_EXIT("Usage: image_filter <image_file> [device_index]"); } else if (argc >= 3) { /* Check if a device was specified in the command line. */ dev_idx = atoi(argv[2]); } /* Load image. */ input_image = stbi_load(argv[1], &width, &height, &n_channels, 4); if (!input_image) ERROR_MSG_AND_EXIT(stbi_failure_reason()); /* Real work size. */ real_ws[0] = width; real_ws[1] = height; /* Set image region. */ region[0] = width; region[1] = height; region[2] = 1; /* Create context using device selected from menu. */ ctx = ccl_context_new_from_menu_full(&dev_idx, &err); HANDLE_ERROR(err); /* Get first device in context. */ dev = ccl_context_get_device(ctx, 0, &err); HANDLE_ERROR(err); /* Ask device if it supports images. */ image_ok = ccl_device_get_info_scalar( dev, CL_DEVICE_IMAGE_SUPPORT, cl_bool, &err); HANDLE_ERROR(err); if (!image_ok) ERROR_MSG_AND_EXIT("Selected device doesn't support images."); /* Create a command queue. */ queue = ccl_queue_new(ctx, dev, 0, &err); HANDLE_ERROR(err); /* Create 2D input image using loaded image data. */ img_in = ccl_image_new(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &image_format, input_image, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) width, "image_height", (size_t) height, NULL); HANDLE_ERROR(err); /* Create 2D output image. */ img_out = ccl_image_new(ctx, CL_MEM_WRITE_ONLY, &image_format, NULL, &err, "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D, "image_width", (size_t) width, "image_height", (size_t) height, NULL); HANDLE_ERROR(err); /* Create program from kernel source and compile it. */ prg = ccl_program_new_from_source(ctx, FILTER_KERNEL, &err); HANDLE_ERROR(err); ccl_program_build(prg, NULL, &err); HANDLE_ERROR(err); /* Get kernel wrapper. */ krnl = ccl_program_get_kernel(prg, "do_filter", &err); HANDLE_ERROR(err); /* Determine nice local and global worksizes. */ ccl_kernel_suggest_worksizes(krnl, dev, 2, real_ws, gws, lws, &err); HANDLE_ERROR(err); /* Show information to user. */ printf("\n * Image size: %d x %d, %d channels\n", width, height, n_channels); printf(" * Global work-size: (%d, %d)\n", (int) gws[0], (int) gws[1]); printf(" * Local work-size: (%d, %d)\n", (int) lws[0], (int) lws[1]); /* Create sampler (this could also be created in-kernel). */ smplr = ccl_sampler_new(ctx, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); HANDLE_ERROR(err); /* Apply filter. */ ccl_kernel_set_args_and_enqueue_ndrange( krnl, queue, 2, NULL, gws, lws, NULL, &err, img_in, img_out, smplr, NULL); HANDLE_ERROR(err); /* Allocate space for output image. */ output_image = (unsigned char *) malloc(width * height * 4 * sizeof(unsigned char)); /* Read image data back to host. */ ccl_image_enqueue_read(img_out, queue, CL_TRUE, origin, region, 0, 0, output_image, NULL, &err); HANDLE_ERROR(err); /* Write image to file. */ file_write_status = stbi_write_png(IMAGE_FILE, width, height, 4, output_image, width * 4); /* Give feedback. */ if (file_write_status) { fprintf(stdout, "\nImage saved in file '" IMAGE_FILE "'\n"); } else { ERROR_MSG_AND_EXIT("Unable to save image in file."); } /* Release host images. */ free(output_image); stbi_image_free(input_image); /* Release wrappers. */ ccl_image_destroy(img_in); ccl_image_destroy(img_out); ccl_sampler_destroy(smplr); ccl_program_destroy(prg); ccl_queue_destroy(queue); ccl_context_destroy(ctx); /* Check all wrappers have been destroyed. */ assert(ccl_wrapper_memcheck()); /* Terminate. */ return EXIT_SUCCESS; }