/* cl_dynamic.h: OpenCL.dll loaded at run time (Windows). 4 October 2026. * * The one-click AMD worker (host.c cross-compiled with mingw, build-windows.sh) links no OpenCL import library: * every cl* entry point host.c calls is a function pointer filled from OpenCL.dll with LoadLibrary/GetProcAddress. * OpenCL.dll is the Khronos ICD loader that the AMD Adrenalin (and NVIDIA, Intel) driver installs in System32, so * nothing but the driver is needed on the PC. Included by host.c after when IGNEUM_CL_DYNAMIC is defined; * the macros below then rename the calls in the rest of the file. The Mac and Linux builds link the library as before. */ #ifndef IGNEUM_CL_DYNAMIC_H #define IGNEUM_CL_DYNAMIC_H #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #else #include #endif #include #define IG_CL_FUNCS(X) \ X(clGetPlatformIDs) X(clGetPlatformInfo) X(clGetDeviceIDs) X(clGetDeviceInfo) X(clCreateContext) \ X(clCreateCommandQueue) X(clCreateProgramWithSource) X(clBuildProgram) X(clGetProgramBuildInfo) X(clCreateKernel) \ X(clSetKernelArg) X(clEnqueueNDRangeKernel) X(clEnqueueReadBuffer) X(clEnqueueWriteBuffer) X(clCreateBuffer) \ X(clReleaseMemObject) X(clReleaseKernel) X(clReleaseProgram) X(clReleaseCommandQueue) X(clReleaseContext) \ X(clFinish) X(clWaitForEvents) X(clReleaseEvent) X(clGetEventInfo) X(clGetEventProfilingInfo) X(clGetKernelWorkGroupInfo) \ X(clGetExtensionFunctionAddressForPlatform) /* One pointer per entry point, typed from the header's declaration (so a signature drift is a compile error). */ #define IG_CL_DECL(f) static __typeof__(f)* ig_##f = NULL; IG_CL_FUNCS(IG_CL_DECL) #undef IG_CL_DECL static char ig_cl_error[512]; /* Returns 1 when OpenCL.dll and every entry point are there; else 0 with ig_cl_error set. */ static int ig_cl_load(void) { #ifdef _WIN32 HMODULE h = LoadLibraryA("OpenCL.dll"); if (!h) { snprintf(ig_cl_error, sizeof(ig_cl_error), "OpenCL.dll is not installed (the GPU driver provides it: AMD Adrenalin, or the NVIDIA or Intel driver); nothing else is needed"); return 0; } #define IG_CL_LOAD(f) ig_##f = (__typeof__(f)*)(void*)GetProcAddress(h, #f); if (!ig_##f) { snprintf(ig_cl_error, sizeof(ig_cl_error), "OpenCL.dll lacks %s", #f); return 0; } IG_CL_FUNCS(IG_CL_LOAD) #undef IG_CL_LOAD return 1; #else /* Linux (the HiveOS package, 4 October 2026): the ICD loader the GPU driver installs (ROCm, amdgpu-pro, NVIDIA, * Intel all register with it), opened at run time so the worker cross-compiles on the Mac with no OpenCL library. */ void* h = dlopen("libOpenCL.so.1", RTLD_NOW); if (!h) h = dlopen("libOpenCL.so", RTLD_NOW); if (!h) { snprintf(ig_cl_error, sizeof(ig_cl_error), "libOpenCL.so.1 is not installed (the GPU driver provides it: ROCm or amdgpu-pro for AMD, the NVIDIA or Intel driver); nothing else is needed"); return 0; } #define IG_CL_LOAD(f) ig_##f = (__typeof__(f)*)dlsym(h, #f); if (!ig_##f) { snprintf(ig_cl_error, sizeof(ig_cl_error), "libOpenCL.so.1 lacks %s", #f); return 0; } IG_CL_FUNCS(IG_CL_LOAD) #undef IG_CL_LOAD return 1; #endif } /* From here on, host.c's calls go through the pointers. */ #define IG_CL_RENAME(f) #define clGetPlatformIDs ig_clGetPlatformIDs #define clGetPlatformInfo ig_clGetPlatformInfo #define clGetDeviceIDs ig_clGetDeviceIDs #define clGetDeviceInfo ig_clGetDeviceInfo #define clCreateContext ig_clCreateContext #define clCreateCommandQueue ig_clCreateCommandQueue #define clCreateProgramWithSource ig_clCreateProgramWithSource #define clBuildProgram ig_clBuildProgram #define clGetProgramBuildInfo ig_clGetProgramBuildInfo #define clCreateKernel ig_clCreateKernel #define clSetKernelArg ig_clSetKernelArg #define clEnqueueNDRangeKernel ig_clEnqueueNDRangeKernel #define clEnqueueReadBuffer ig_clEnqueueReadBuffer #define clEnqueueWriteBuffer ig_clEnqueueWriteBuffer #define clCreateBuffer ig_clCreateBuffer #define clReleaseMemObject ig_clReleaseMemObject #define clReleaseKernel ig_clReleaseKernel #define clReleaseProgram ig_clReleaseProgram #define clReleaseCommandQueue ig_clReleaseCommandQueue #define clReleaseContext ig_clReleaseContext #define clFinish ig_clFinish #define clWaitForEvents ig_clWaitForEvents #define clReleaseEvent ig_clReleaseEvent #define clGetEventInfo ig_clGetEventInfo #define clGetEventProfilingInfo ig_clGetEventProfilingInfo #define clGetKernelWorkGroupInfo ig_clGetKernelWorkGroupInfo #define clGetExtensionFunctionAddressForPlatform ig_clGetExtensionFunctionAddressForPlatform #endif