igneum/proto-opencl/cl_dynamic.h
igneum-labs d69d70c3fc Windows exes carry the coin icon and a version block (the project lead's rule, 4 Oct 2026)
Every Windows executable now ships with the coin icon Explorer shows and the version block Properties shows
(CompanyName Igneum, ProductName Igneum Miner, FileDescription per exe, 0.3.0, LegalCopyright Igneum contributors),
like the Mac app and DMG already do.

- igneumd.exe, igneum-miner.exe: packaging/windows/embed-resources.sh now takes the worktree and target dir
  (defaults vendor/igneum-node-v4 and vendor/igneum-node/target-integration) and relinks with a linker shim first in
  PATH instead of `cargo rustc -- -C link-arg`: cargo rustc takes one package and unifies features differently from
  the two-package cross-build (300 crates differ), and a configured linker is fingerprinted and rebuilds everything;
  the PATH shim changes neither. .rc files moved to 0.3.0.
- igneum-worker-cuda.exe, igneum-worker-opencl.exe: proto-cuda/nvrtc/build-windows.sh compiles the two new .rc
  files with windres and links the objects; the icon is made with make-icons.py if missing.
- igneum-app.exe: app/igneum-app/build.rs runs windres on resources/igneum-app.rc for Windows targets and links it
  (cargo:rustc-link-arg-bins, no crate dependency); it fails the build if the .rc version drifts from Cargo.toml.
- packaging/windows/resources/verify-exe.py: small PE parser that checks the .rsrc section, icon group and version
  strings on the Mac; both build scripts call it, and it checks every exe inside the packages.
- proto-opencl/cl_dynamic.h: clGetEventInfo added to the run-time loader table (4714b51 added the call in host.c
  without it, so the one-click OpenCL worker no longer linked under IGNEUM_CL_DYNAMIC).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 10:44:20 +00:00

79 lines
3.8 KiB
C

/* 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 <CL/cl.h> 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 <windows.h>
#endif
#include <stdio.h>
#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
snprintf(ig_cl_error, sizeof(ig_cl_error), "IGNEUM_CL_DYNAMIC is for the Windows build");
return 0;
#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