summaryrefslogtreecommitdiff
path: root/src/util_cl.c
diff options
context:
space:
mode:
authorAiden Gall <aiden@aidengall.xyz>2024-02-04 14:43:37 +0000
committerAiden Gall <aiden@aidengall.xyz>2024-02-04 14:46:37 +0000
commitc44d2805ba480fc7c2faf8ae07f2c1c9febf7e34 (patch)
tree0171574e51da53dbe2664360949cc78259b2da0b /src/util_cl.c
parent5ff9d6184771970c14e682ecf55cbd9d27b2fada (diff)
render with raylib
Diffstat (limited to 'src/util_cl.c')
-rw-r--r--src/util_cl.c268
1 files changed, 268 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>. */
+
+#include "util.h"
+
+#include <CL/cl.h>
+#include <CL/cl_platform.h>
+#include <CL/cl_version.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+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";
+ }
+}