|
@@ -15,6 +15,12 @@
|
|
|
#include <curses.h>
|
|
#include <curses.h>
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#ifndef WIN32
|
|
|
|
|
+#include <dlfcn.h>
|
|
|
|
|
+#else
|
|
|
|
|
+#include <windows.h>
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
#include <stdbool.h>
|
|
#include <stdbool.h>
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
@@ -26,6 +32,8 @@
|
|
|
#endif
|
|
#endif
|
|
|
#include <ccan/opt/opt.h>
|
|
#include <ccan/opt/opt.h>
|
|
|
|
|
|
|
|
|
|
+#define OMIT_OPENCL_API
|
|
|
|
|
+
|
|
|
#include "compat.h"
|
|
#include "compat.h"
|
|
|
#include "miner.h"
|
|
#include "miner.h"
|
|
|
#include "driver-opencl.h"
|
|
#include "driver-opencl.h"
|
|
@@ -35,6 +43,213 @@
|
|
|
|
|
|
|
|
/* TODO: cleanup externals ********************/
|
|
/* TODO: cleanup externals ********************/
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+/* Platform API */
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetPlatformIDs)(cl_uint /* num_entries */,
|
|
|
|
|
+ cl_platform_id * /* platforms */,
|
|
|
|
|
+ cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetPlatformInfo)(cl_platform_id /* platform */,
|
|
|
|
|
+ cl_platform_info /* param_name */,
|
|
|
|
|
+ size_t /* param_value_size */,
|
|
|
|
|
+ void * /* param_value */,
|
|
|
|
|
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Device APIs */
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetDeviceIDs)(cl_platform_id /* platform */,
|
|
|
|
|
+ cl_device_type /* device_type */,
|
|
|
|
|
+ cl_uint /* num_entries */,
|
|
|
|
|
+ cl_device_id * /* devices */,
|
|
|
|
|
+ cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetDeviceInfo)(cl_device_id /* device */,
|
|
|
|
|
+ cl_device_info /* param_name */,
|
|
|
|
|
+ size_t /* param_value_size */,
|
|
|
|
|
+ void * /* param_value */,
|
|
|
|
|
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Context APIs */
|
|
|
|
|
+CL_API_ENTRY cl_context CL_API_CALL
|
|
|
|
|
+(*clCreateContextFromType)(const cl_context_properties * /* properties */,
|
|
|
|
|
+ cl_device_type /* device_type */,
|
|
|
|
|
+ void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *),
|
|
|
|
|
+ void * /* user_data */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clReleaseContext)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Command Queue APIs */
|
|
|
|
|
+CL_API_ENTRY cl_command_queue CL_API_CALL
|
|
|
|
|
+(*clCreateCommandQueue)(cl_context /* context */,
|
|
|
|
|
+ cl_device_id /* device */,
|
|
|
|
|
+ cl_command_queue_properties /* properties */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clReleaseCommandQueue)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Memory Object APIs */
|
|
|
|
|
+CL_API_ENTRY cl_mem CL_API_CALL
|
|
|
|
|
+(*clCreateBuffer)(cl_context /* context */,
|
|
|
|
|
+ cl_mem_flags /* flags */,
|
|
|
|
|
+ size_t /* size */,
|
|
|
|
|
+ void * /* host_ptr */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Program Object APIs */
|
|
|
|
|
+CL_API_ENTRY cl_program CL_API_CALL
|
|
|
|
|
+(*clCreateProgramWithSource)(cl_context /* context */,
|
|
|
|
|
+ cl_uint /* count */,
|
|
|
|
|
+ const char ** /* strings */,
|
|
|
|
|
+ const size_t * /* lengths */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_program CL_API_CALL
|
|
|
|
|
+(*clCreateProgramWithBinary)(cl_context /* context */,
|
|
|
|
|
+ cl_uint /* num_devices */,
|
|
|
|
|
+ const cl_device_id * /* device_list */,
|
|
|
|
|
+ const size_t * /* lengths */,
|
|
|
|
|
+ const unsigned char ** /* binaries */,
|
|
|
|
|
+ cl_int * /* binary_status */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clReleaseProgram)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clBuildProgram)(cl_program /* program */,
|
|
|
|
|
+ cl_uint /* num_devices */,
|
|
|
|
|
+ const cl_device_id * /* device_list */,
|
|
|
|
|
+ const char * /* options */,
|
|
|
|
|
+ void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */),
|
|
|
|
|
+ void * /* user_data */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetProgramInfo)(cl_program /* program */,
|
|
|
|
|
+ cl_program_info /* param_name */,
|
|
|
|
|
+ size_t /* param_value_size */,
|
|
|
|
|
+ void * /* param_value */,
|
|
|
|
|
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clGetProgramBuildInfo)(cl_program /* program */,
|
|
|
|
|
+ cl_device_id /* device */,
|
|
|
|
|
+ cl_program_build_info /* param_name */,
|
|
|
|
|
+ size_t /* param_value_size */,
|
|
|
|
|
+ void * /* param_value */,
|
|
|
|
|
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Kernel Object APIs */
|
|
|
|
|
+CL_API_ENTRY cl_kernel CL_API_CALL
|
|
|
|
|
+(*clCreateKernel)(cl_program /* program */,
|
|
|
|
|
+ const char * /* kernel_name */,
|
|
|
|
|
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clReleaseKernel)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clSetKernelArg)(cl_kernel /* kernel */,
|
|
|
|
|
+ cl_uint /* arg_index */,
|
|
|
|
|
+ size_t /* arg_size */,
|
|
|
|
|
+ const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Flush and Finish APIs */
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clFinish)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+/* Enqueued Commands APIs */
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clEnqueueReadBuffer)(cl_command_queue /* command_queue */,
|
|
|
|
|
+ cl_mem /* buffer */,
|
|
|
|
|
+ cl_bool /* blocking_read */,
|
|
|
|
|
+ size_t /* offset */,
|
|
|
|
|
+ size_t /* size */,
|
|
|
|
|
+ void * /* ptr */,
|
|
|
|
|
+ cl_uint /* num_events_in_wait_list */,
|
|
|
|
|
+ const cl_event * /* event_wait_list */,
|
|
|
|
|
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clEnqueueWriteBuffer)(cl_command_queue /* command_queue */,
|
|
|
|
|
+ cl_mem /* buffer */,
|
|
|
|
|
+ cl_bool /* blocking_write */,
|
|
|
|
|
+ size_t /* offset */,
|
|
|
|
|
+ size_t /* size */,
|
|
|
|
|
+ const void * /* ptr */,
|
|
|
|
|
+ cl_uint /* num_events_in_wait_list */,
|
|
|
|
|
+ const cl_event * /* event_wait_list */,
|
|
|
|
|
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+CL_API_ENTRY cl_int CL_API_CALL
|
|
|
|
|
+(*clEnqueueNDRangeKernel)(cl_command_queue /* command_queue */,
|
|
|
|
|
+ cl_kernel /* kernel */,
|
|
|
|
|
+ cl_uint /* work_dim */,
|
|
|
|
|
+ const size_t * /* global_work_offset */,
|
|
|
|
|
+ const size_t * /* global_work_size */,
|
|
|
|
|
+ const size_t * /* local_work_size */,
|
|
|
|
|
+ cl_uint /* num_events_in_wait_list */,
|
|
|
|
|
+ const cl_event * /* event_wait_list */,
|
|
|
|
|
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
|
|
|
+
|
|
|
|
|
+#ifdef WIN32
|
|
|
|
|
+#define dlsym (void*)GetProcAddress
|
|
|
|
|
+#define dlclose FreeLibrary
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#define LOAD_OCL_SYM(sym) do { \
|
|
|
|
|
+ if (!(sym = dlsym(cl, #sym))) { \
|
|
|
|
|
+ applog(LOG_ERR, "Failed to load OpenCL symbol " #sym ", no GPUs usable"); \
|
|
|
|
|
+ dlclose(cl); \
|
|
|
|
|
+ return false; \
|
|
|
|
|
+ } \
|
|
|
|
|
+} while(0)
|
|
|
|
|
+
|
|
|
|
|
+static bool
|
|
|
|
|
+load_opencl_symbols() {
|
|
|
|
|
+#ifndef WIN32
|
|
|
|
|
+ void *cl = dlopen("libOpenCL.so", RTLD_LAZY);
|
|
|
|
|
+#else
|
|
|
|
|
+ HMODULE cl = LoadLibrary("OpenCL.dll");
|
|
|
|
|
+#endif
|
|
|
|
|
+ if (!cl)
|
|
|
|
|
+ {
|
|
|
|
|
+ applog(LOG_ERR, "Failed to load OpenCL library, no GPUs usable");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LOAD_OCL_SYM(clGetPlatformIDs);
|
|
|
|
|
+ LOAD_OCL_SYM(clGetPlatformInfo);
|
|
|
|
|
+ LOAD_OCL_SYM(clGetDeviceIDs);
|
|
|
|
|
+ LOAD_OCL_SYM(clGetDeviceInfo);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateContextFromType);
|
|
|
|
|
+ LOAD_OCL_SYM(clReleaseContext);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateCommandQueue);
|
|
|
|
|
+ LOAD_OCL_SYM(clReleaseCommandQueue);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateBuffer);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateProgramWithSource);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateProgramWithBinary);
|
|
|
|
|
+ LOAD_OCL_SYM(clReleaseProgram);
|
|
|
|
|
+ LOAD_OCL_SYM(clBuildProgram);
|
|
|
|
|
+ LOAD_OCL_SYM(clGetProgramInfo);
|
|
|
|
|
+ LOAD_OCL_SYM(clGetProgramBuildInfo);
|
|
|
|
|
+ LOAD_OCL_SYM(clCreateKernel);
|
|
|
|
|
+ LOAD_OCL_SYM(clReleaseKernel);
|
|
|
|
|
+ LOAD_OCL_SYM(clSetKernelArg);
|
|
|
|
|
+ LOAD_OCL_SYM(clFinish);
|
|
|
|
|
+ LOAD_OCL_SYM(clEnqueueReadBuffer);
|
|
|
|
|
+ LOAD_OCL_SYM(clEnqueueWriteBuffer);
|
|
|
|
|
+ LOAD_OCL_SYM(clEnqueueNDRangeKernel);
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
#ifdef HAVE_CURSES
|
|
#ifdef HAVE_CURSES
|
|
|
extern WINDOW *mainwin, *statuswin, *logwin;
|
|
extern WINDOW *mainwin, *statuswin, *logwin;
|
|
|
extern void enable_curses(void);
|
|
extern void enable_curses(void);
|
|
@@ -1120,6 +1335,12 @@ struct device_api opencl_api;
|
|
|
|
|
|
|
|
static void opencl_detect()
|
|
static void opencl_detect()
|
|
|
{
|
|
{
|
|
|
|
|
+ if (!load_opencl_symbols()) {
|
|
|
|
|
+ nDevs = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
nDevs = clDevicesNum();
|
|
nDevs = clDevicesNum();
|