From c44d2805ba480fc7c2faf8ae07f2c1c9febf7e34 Mon Sep 17 00:00:00 2001 From: Aiden Gall Date: Sun, 4 Feb 2024 14:43:37 +0000 Subject: render with raylib --- src/util_cl.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 src/util_cl.c (limited to 'src/util_cl.c') diff --git a/src/util_cl.c b/src/util_cl.c new file mode 100644 index 0000000..5b571f5 --- /dev/null +++ b/src/util_cl.c @@ -0,0 +1,268 @@ +/* Copyright (C) 2024 Aiden Gall + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . */ + +#include "util.h" + +#include +#include +#include +#include +#include + +cl_platform_id *get_platforms(cl_uint *num_platforms); +cl_device_id *get_devices(cl_platform_id platform, cl_uint *num_devices); + +cl_program compile_spirv_program(cl_context context, cl_device_id device, + const void *spirv_start, size_t spirv_size); + +const char *cl_strerror(cl_int err); + +cl_platform_id * +get_platforms(cl_uint *const num_platforms) +{ + cl_int err; + + cl_platform_id *platforms; + cl_uint len; + + err = clGetPlatformIDs(0, NULL, &len); + if (err != CL_SUCCESS) + die("clGetPlatformIDs: %s\n", cl_strerror(err)); + warn("number of platforms = %d\n", len); + if (len < 1) + die("clGetPlatformIDs: No OpenCL platforms\n"); + + platforms = calloc(len, sizeof(*platforms)); + if (!platforms) + die("calloc: Out of memory\n"); + err = clGetPlatformIDs(len, platforms, NULL); + if (err != CL_SUCCESS) + die("clGetPlatformIDs: %s\n", cl_strerror(err)); + + *num_platforms = len; + return platforms; +} + +cl_device_id * +get_devices(const cl_platform_id platform, cl_uint *const num_devices) +{ + cl_int err; + + cl_device_id *devices; + cl_uint len; + + err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &len); + if (err != CL_SUCCESS) + die("clGetDeviceIDs: %s\n", cl_strerror(err)); + warn("number of devices in platform = %d\n", len); + if (len < 1) + die("clGetDeviceIDs: No OpenCL devices in platform\n"); + + devices = calloc(len, sizeof(*devices)); + if (!devices) + die("calloc: Out of memory\n"); + err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, len, devices, NULL); + if (err != CL_SUCCESS) + die("clGetDeviceIDs: %s\n", cl_strerror(err)); + + *num_devices = len; + return devices; +} + +cl_program +compile_spirv_program(const cl_context context, const cl_device_id device, + const void *const spirv_start, const size_t spirv_size) +{ + cl_int err, build_err; + cl_program program; + + program = clCreateProgramWithIL(context, spirv_start, spirv_size, &err); + if (err != CL_SUCCESS) + die("clCreateProgramWithIL: %s\n", cl_strerror(err)); + + build_err = clBuildProgram(program, 1, &device, NULL, NULL, NULL); + if (build_err != CL_SUCCESS) { + cl_char *log; + size_t buffer_size; + + err = clGetProgramBuildInfo(program, device, + CL_PROGRAM_BUILD_LOG, 0, NULL, + &buffer_size); + if (err != CL_SUCCESS) + die("clGetProgramBuildInfo: %s\n", cl_strerror(err)); + if (buffer_size < 1) + die("clGetProgramBuildInfo: " + "Build log buffer is empty\n"); + + log = calloc(buffer_size, sizeof(*log)); + if (!log) + die("calloc: Out of memory\n"); + err = clGetProgramBuildInfo( + program, device, CL_PROGRAM_BUILD_LOG, + sizeof(*log) * buffer_size, log, NULL); + if (err != CL_SUCCESS) + die("clGetProgramBuildInfo: %s\n", cl_strerror(err)); + + efwrite(log, sizeof(*log), buffer_size, stderr); + + free(log); + die("\nclBuildProgram: %s\n", cl_strerror(build_err)); + } + + return program; +} + +const char * +cl_strerror(const cl_int err) +{ + switch (err) { + case CL_SUCCESS: + return "CL_SUCCESS"; + case CL_DEVICE_NOT_FOUND: + return "CL_DEVICE_NOT_FOUND"; + case CL_DEVICE_NOT_AVAILABLE: + return "CL_DEVICE_NOT_AVAILABLE"; + case CL_COMPILER_NOT_AVAILABLE: + return "CL_COMPILER_NOT_AVAILABLE"; + case CL_MEM_OBJECT_ALLOCATION_FAILURE: + return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; + case CL_OUT_OF_RESOURCES: + return "CL_OUT_OF_RESOURCES"; + case CL_OUT_OF_HOST_MEMORY: + return "CL_OUT_OF_HOST_MEMORY"; + case CL_PROFILING_INFO_NOT_AVAILABLE: + return "CL_PROFILING_INFO_NOT_AVAILABLE"; + case CL_MEM_COPY_OVERLAP: + return "CL_MEM_COPY_OVERLAP"; + case CL_IMAGE_FORMAT_MISMATCH: + return "CL_IMAGE_FORMAT_MISMATCH"; + case CL_IMAGE_FORMAT_NOT_SUPPORTED: + return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; + case CL_BUILD_PROGRAM_FAILURE: + return "CL_BUILD_PROGRAM_FAILURE"; + case CL_MAP_FAILURE: + return "CL_MAP_FAILURE"; + case CL_INVALID_VALUE: + return "CL_INVALID_VALUE"; + case CL_INVALID_DEVICE_TYPE: + return "CL_INVALID_DEVICE_TYPE"; + case CL_INVALID_PLATFORM: + return "CL_INVALID_PLATFORM"; + case CL_INVALID_DEVICE: + return "CL_INVALID_DEVICE"; + case CL_INVALID_CONTEXT: + return "CL_INVALID_CONTEXT"; + case CL_INVALID_QUEUE_PROPERTIES: + return "CL_INVALID_QUEUE_PROPERTIES"; + case CL_INVALID_COMMAND_QUEUE: + return "CL_INVALID_COMMAND_QUEUE"; + case CL_INVALID_HOST_PTR: + return "CL_INVALID_HOST_PTR"; + case CL_INVALID_MEM_OBJECT: + return "CL_INVALID_MEM_OBJECT"; + case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: + return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; + case CL_INVALID_IMAGE_SIZE: + return "CL_INVALID_IMAGE_SIZE"; + case CL_INVALID_SAMPLER: + return "CL_INVALID_SAMPLER"; + case CL_INVALID_BINARY: + return "CL_INVALID_BINARY"; + case CL_INVALID_BUILD_OPTIONS: + return "CL_INVALID_BUILD_OPTIONS"; + case CL_INVALID_PROGRAM: + return "CL_INVALID_PROGRAM"; + case CL_INVALID_PROGRAM_EXECUTABLE: + return "CL_INVALID_PROGRAM_EXECUTABLE"; + case CL_INVALID_KERNEL_NAME: + return "CL_INVALID_KERNEL_NAME"; + case CL_INVALID_KERNEL_DEFINITION: + return "CL_INVALID_KERNEL_DEFINITION"; + case CL_INVALID_KERNEL: + return "CL_INVALID_KERNEL"; + case CL_INVALID_ARG_INDEX: + return "CL_INVALID_ARG_INDEX"; + case CL_INVALID_ARG_VALUE: + return "CL_INVALID_ARG_VALUE"; + case CL_INVALID_ARG_SIZE: + return "CL_INVALID_ARG_SIZE"; + case CL_INVALID_KERNEL_ARGS: + return "CL_INVALID_KERNEL_ARGS"; + case CL_INVALID_WORK_DIMENSION: + return "CL_INVALID_WORK_DIMENSION"; + case CL_INVALID_WORK_GROUP_SIZE: + return "CL_INVALID_WORK_GROUP_SIZE"; + case CL_INVALID_WORK_ITEM_SIZE: + return "CL_INVALID_WORK_ITEM_SIZE"; + case CL_INVALID_GLOBAL_OFFSET: + return "CL_INVALID_GLOBAL_OFFSET"; + case CL_INVALID_EVENT_WAIT_LIST: + return "CL_INVALID_EVENT_WAIT_LIST"; + case CL_INVALID_EVENT: + return "CL_INVALID_EVENT"; + case CL_INVALID_OPERATION: + return "CL_INVALID_OPERATION"; + case CL_INVALID_GL_OBJECT: + return "CL_INVALID_GL_OBJECT"; + case CL_INVALID_BUFFER_SIZE: + return "CL_INVALID_BUFFER_SIZE"; + case CL_INVALID_MIP_LEVEL: + return "CL_INVALID_MIP_LEVEL"; + case CL_INVALID_GLOBAL_WORK_SIZE: + return "CL_INVALID_GLOBAL_WORK_SIZE"; +#ifdef CL_VERSION_1_1 + case CL_MISALIGNED_SUB_BUFFER_OFFSET: + return "CL_MISALIGNED_SUB_BUFFER_OFFSET"; + case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: + return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; + case CL_INVALID_PROPERTY: + return "CL_INVALID_PROPERTY"; +#endif +#ifdef CL_VERSION_1_2 + case CL_COMPILE_PROGRAM_FAILURE: + return "CL_COMPILE_PROGRAM_FAILURE"; + case CL_LINKER_NOT_AVAILABLE: + return "CL_LINKER_NOT_AVAILABLE"; + case CL_LINK_PROGRAM_FAILURE: + return "CL_LINK_PROGRAM_FAILURE"; + case CL_DEVICE_PARTITION_FAILED: + return "CL_DEVICE_PARTITION_FAILED"; + case CL_KERNEL_ARG_INFO_NOT_AVAILABLE: + return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; + case CL_INVALID_IMAGE_DESCRIPTOR: + return "CL_INVALID_IMAGE_DESCRIPTOR"; + case CL_INVALID_COMPILER_OPTIONS: + return "CL_INVALID_COMPILER_OPTIONS"; + case CL_INVALID_LINKER_OPTIONS: + return "CL_INVALID_LINKER_OPTIONS"; + case CL_INVALID_DEVICE_PARTITION_COUNT: + return "CL_INVALID_DEVICE_PARTITION_COUNT"; +#endif +#ifdef CL_VERSION_2_0 + case CL_INVALID_PIPE_SIZE: + return "CL_INVALID_PIPE_SIZE"; + case CL_INVALID_DEVICE_QUEUE: + return "CL_INVALID_DEVICE_QUEUE"; +#endif +#ifdef CL_VERSION_2_2 + case CL_INVALID_SPEC_ID: + return "CL_INVALID_SPEC_ID"; + case CL_MAX_SIZE_RESTRICTION_EXCEEDED: + return "CL_MAX_SIZE_RESTRICTION_EXCEEDED"; +#endif + default: + return "OpenCL unknown error"; + } +} -- cgit v1.2.3