runcl

A minimal OpenCL harness for rendering images
git clone git://pollux.codes/git/runcl.git
Log | Files | Refs | README | LICENSE

commit b13a64eea668fafb689305a3eae0c1c365c93216
parent 31633442aee54672e42f64bafd06bea5aba4c03b
Author: Pollux <pollux@pollux.codes>
Date:   Sun, 19 Jan 2025 10:42:37 -0600

refactor: pull arg parsing into separate function

Signed-off-by: Pollux <pollux@pollux.codes>

Diffstat:
Msrc/runcl.c | 143+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
1 file changed, 82 insertions(+), 61 deletions(-)

diff --git a/src/runcl.c b/src/runcl.c @@ -4,6 +4,9 @@ "usage: runcl -p <platform-index> -w <image-width> -h <image-height> " \ "input-opencl-file output-png-file" +#define DEF_WIDTH 640 +#define DEF_HEIGHT 480 + #define STR_LITERAL(x) #x #define STRINGIFY(x) STR_LITERAL(x) @@ -13,6 +16,12 @@ #include <stdio.h> #include <unistd.h> +struct Args { + int img_width; + int img_height; + int platform_index; +}; + void print_help() { printf(USAGE "\n"); } void print_version() { @@ -22,18 +31,52 @@ void print_version() { printf("LDFLAGS: " STRINGIFY(LDFLAGS) "\n"); } -int main(int argc, char **argv) { +int parse_args(int argc, char **argv, struct Args *out) { - char *source_file = NULL; - char *out_file = NULL; + int arg; + + out->img_width = DEF_WIDTH; + out->img_height = DEF_HEIGHT; + out->platform_index = 0; + + while ((arg = getopt(argc, argv, "p:w:h:Hv")) != -1) { + switch (arg) { + case 'p': + out->platform_index = atoi(optarg); + break; + case 'w': + out->img_width = atoi(optarg); + break; + case 'h': + out->img_height = atoi(optarg); + break; + case 'H': + print_help(); + return 255; + case 'v': + print_version(); + return 255; + case '?': + fprintf(stderr, "Error parsing command-line arguments...\n"); + return 1; + } + } + + if (argc < optind + 2) { + fprintf(stderr, "Error parsing command-line arguments...\n"); + return 1; + } + + return 0; +} - int img_width = 640; - int img_height = 480; - int platform_index = 0; +int main(int argc, char **argv) { - int c; + struct Args args; + int res; - opterr = 0; + char *source_file = NULL; + char *out_file = NULL; int data_size_out; float *data_out; @@ -57,8 +100,6 @@ int main(int argc, char **argv) { cl_uint platform_count = 256; cl_platform_id *platforms; - cl_int err; - size_t g_work_size, l_work_size; char name[100]; @@ -68,41 +109,20 @@ int main(int argc, char **argv) { png_infop info_ptr; png_bytep row; - while ((c = getopt(argc, argv, "p:w:h:Hv")) != -1) { - switch (c) { - case 'p': - platform_index = atoi(optarg); - break; - case 'w': - img_width = atoi(optarg); - break; - case 'h': - img_height = atoi(optarg); - break; - case 'H': - print_help(); - exit(0); - break; - case 'v': - print_version(); + res = parse_args(argc, argv, &args); + + if (res) { + if (res == 255) { exit(0); - break; - case '?': - fprintf(stderr, "Error parsing command-line arguments...\n"); - return 1; } + exit(res); } - data_size_out = sizeof(float) * img_width * img_height * 3; + data_size_out = sizeof(float) * args.img_width * args.img_height * 3; data_out = (float *)malloc(data_size_out); platforms = malloc(platform_count * sizeof(cl_platform_id)); - row = (png_bytep)malloc(3 * img_width * sizeof(png_byte)); - - if (argc < optind + 2) { - fprintf(stderr, "Error parsing command-line arguments...\n"); - return 1; - } + row = (png_bytep)malloc(3 * args.img_width * sizeof(png_byte)); source_file = argv[optind]; out_file = argv[optind + 1]; @@ -126,7 +146,7 @@ int main(int argc, char **argv) { clGetPlatformIDs(platform_count, platforms, NULL); - platform_id = platforms[platform_index]; + platform_id = platforms[args.platform_index]; clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); @@ -146,9 +166,9 @@ int main(int argc, char **argv) { program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, NULL); - err = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); + res = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); - if (err != CL_SUCCESS) { + if (res != CL_SUCCESS) { printf("Failed to build program!\n"); char build_log[16348]; clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, @@ -157,33 +177,34 @@ int main(int argc, char **argv) { goto error; } - kernel = clCreateKernel(program, "render", &err); + kernel = clCreateKernel(program, "render", &res); - if (err != CL_SUCCESS) { - printf("Error creating kernel: %d\n", (int)err); + if (res != CL_SUCCESS) { + printf("Error creating kernel: %d\n", res); goto error; } - clSetKernelArg(kernel, 0, sizeof(cl_int), (void *)&img_width); - clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&img_height); + clSetKernelArg(kernel, 0, sizeof(cl_int), (void *)&args.img_width); + clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&args.img_height); clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&out_buff); l_work_size = 128; - g_work_size = (img_width * img_height / l_work_size + 1) * l_work_size; + g_work_size = + (args.img_width * args.img_height / l_work_size + 1) * l_work_size; - err = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &g_work_size, + res = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &g_work_size, &l_work_size, 0, NULL, NULL); - if (err != CL_SUCCESS) { - printf("Error executing kernel: %d\n", (int)err); + if (res != CL_SUCCESS) { + printf("Error executing kernel: %d\n", (int)res); goto error; } - err = clEnqueueReadBuffer(command_queue, out_buff, CL_TRUE, 0, data_size_out, + res = clEnqueueReadBuffer(command_queue, out_buff, CL_TRUE, 0, data_size_out, (void *)data_out, 0, NULL, NULL); - if (err != CL_SUCCESS) { - printf("Error reading result: %d\n", (int)err); + if (res != CL_SUCCESS) { + printf("Error reading result: %d\n", (int)res); goto error; } @@ -201,18 +222,18 @@ int main(int argc, char **argv) { png_init_io(png_ptr, fp); - png_set_IHDR(png_ptr, info_ptr, img_width, img_height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, - PNG_FILTER_TYPE_BASE); + png_set_IHDR(png_ptr, info_ptr, args.img_width, args.img_height, 8, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); int x, y; - for (y = 0; y < img_height; y++) { - for (x = 0; x < img_width; x++) { - row[x * 3 + 0] = (int)(255 * data_out[3 * (y * img_width + x) + 0]); - row[x * 3 + 1] = (int)(255 * data_out[3 * (y * img_width + x) + 1]); - row[x * 3 + 2] = (int)(255 * data_out[3 * (y * img_width + x) + 2]); + for (y = 0; y < args.img_height; y++) { + for (x = 0; x < args.img_width; x++) { + row[x * 3 + 0] = (int)(255 * data_out[3 * (y * args.img_width + x) + 0]); + row[x * 3 + 1] = (int)(255 * data_out[3 * (y * args.img_width + x) + 1]); + row[x * 3 + 2] = (int)(255 * data_out[3 * (y * args.img_width + x) + 2]); } png_write_row(png_ptr, row); }