static int dt_mipmap_cache_get_filename( gchar* mipmapfilename, size_t size) { int r = -1; char* abspath = NULL; // Directory char cachedir[DT_MAX_PATH_LEN]; dt_loc_get_user_cache_dir(cachedir, sizeof(cachedir)); // Build the mipmap filename const gchar *dbfilename = dt_database_get_path(darktable.db); if (!strcmp(dbfilename, ":memory:")) { snprintf(mipmapfilename, size, "%s", dbfilename); r = 0; goto exit; } abspath = malloc(PATH_MAX); if (!abspath) goto exit; if (!realpath(dbfilename, abspath)) snprintf(abspath, PATH_MAX, "%s", dbfilename); GChecksum* chk = g_checksum_new(G_CHECKSUM_SHA1); g_checksum_update(chk, (guchar*)abspath, strlen(abspath)); const gchar *filename = g_checksum_get_string(chk); if(!filename || filename[0] == '\0') snprintf(mipmapfilename, size, "%s/%s", cachedir, DT_MIPMAP_CACHE_DEFAULT_FILE_NAME); else snprintf(mipmapfilename, size, "%s/%s-%s", cachedir, DT_MIPMAP_CACHE_DEFAULT_FILE_NAME, filename); g_checksum_free(chk); r = 0; exit: free(abspath); return r; }
/* delete old mipmaps files */ static void _database_delete_mipmaps_files() { /* This migration is intended to be run only from 0.9.x to new cache in 1.0 */ // Directory char cachedir[DT_MAX_PATH_LEN], mipmapfilename[DT_MAX_PATH_LEN]; dt_loc_get_user_cache_dir(cachedir, sizeof(cachedir)); snprintf(mipmapfilename, DT_MAX_PATH_LEN, "%s/mipmaps", cachedir); if(access(mipmapfilename, F_OK) != -1) { fprintf(stderr, "[mipmap_cache] dropping old version file: %s\n", mipmapfilename); unlink(mipmapfilename); snprintf(mipmapfilename, DT_MAX_PATH_LEN, "%s/mipmaps.fallback", cachedir); if(access(mipmapfilename, F_OK) != -1) unlink(mipmapfilename); } }
int dt_lua_init_configuration(lua_State*L){ char tmp_path[PATH_MAX]; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L,"configuration"); // build the table containing the configuration info lua_pushstring(L,"tmp_dir"); dt_loc_get_tmp_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"config_dir"); dt_loc_get_user_config_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"cache_dir"); dt_loc_get_user_cache_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"version"); lua_pushstring(darktable.lua_state,PACKAGE_VERSION); lua_settable(L,-3); lua_pushstring(L,"verbose"); lua_pushboolean(L,darktable.unmuted & DT_DEBUG_LUA); lua_settable(L,-3); lua_pushstring(L,"has_gui"); lua_pushboolean(L,darktable.gui != NULL); lua_settable(L,-3); lua_pop(L,-1); //remove the configuration table from the stack return 0; }
int dt_lua_init_configuration(lua_State*L) { char tmp_path[PATH_MAX]; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L,"configuration"); // build the table containing the configuration info lua_pushstring(L,"tmp_dir"); dt_loc_get_tmp_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"config_dir"); dt_loc_get_user_config_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"cache_dir"); dt_loc_get_user_cache_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"version"); lua_pushstring(L,PACKAGE_VERSION); lua_settable(L,-3); lua_pushstring(L,"verbose"); lua_pushboolean(L,darktable.unmuted & DT_DEBUG_LUA); lua_settable(L,-3); lua_pushstring(L,"has_gui"); lua_pushboolean(L,darktable.gui != NULL); lua_settable(L,-3); lua_pushstring(L,"api_version_major"); lua_pushnumber(L,API_VERSION_MAJOR); lua_settable(L,-3); lua_pushstring(L,"api_version_minor"); lua_pushnumber(L,API_VERSION_MINOR); lua_settable(L,-3); lua_pushstring(L,"api_version_patch"); lua_pushnumber(L,API_VERSION_PATCH); lua_settable(L,-3); lua_pushstring(L,"api_version_suffix"); lua_pushstring(L,API_VERSION_SUFFIX); lua_settable(L,-3); lua_pushstring(L,"api_version_string"); if (strcmp(API_VERSION_SUFFIX, "") == 0) { lua_pushfstring(L,"%d.%d.%d",API_VERSION_MAJOR,API_VERSION_MINOR,API_VERSION_PATCH); } else { lua_pushfstring(L,"%d.%d.%d-%s",API_VERSION_MAJOR,API_VERSION_MINOR,API_VERSION_PATCH,API_VERSION_SUFFIX); } lua_settable(L,-3); lua_pop(L,1); //remove the configuration table from the stack return 0; }
int dt_lua_init_configuration(lua_State *L) { char tmp_path[PATH_MAX] = { 0 }; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L, "configuration"); // build the table containing the configuration info lua_pushstring(L, "tmp_dir"); dt_loc_get_tmp_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "config_dir"); dt_loc_get_user_config_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "cache_dir"); dt_loc_get_user_cache_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "version"); lua_pushstring(L, darktable_package_version); lua_settable(L, -3); lua_pushstring(L, "verbose"); lua_pushboolean(L, darktable.unmuted & DT_DEBUG_LUA); lua_settable(L, -3); lua_pushstring(L, "has_gui"); lua_pushboolean(L, darktable.gui != NULL); lua_settable(L, -3); lua_pushstring(L, "api_version_major"); lua_pushinteger(L, LUA_API_VERSION_MAJOR); lua_settable(L, -3); lua_pushstring(L, "api_version_minor"); lua_pushinteger(L, LUA_API_VERSION_MINOR); lua_settable(L, -3); lua_pushstring(L, "api_version_patch"); lua_pushinteger(L, LUA_API_VERSION_PATCH); lua_settable(L, -3); lua_pushstring(L, "api_version_suffix"); lua_pushstring(L, LUA_API_VERSION_SUFFIX); lua_settable(L, -3); lua_pushstring(L, "api_version_string"); if(LUA_API_VERSION_SUFFIX[0] == '\0') { lua_pushfstring(L, "%d.%d.%d", LUA_API_VERSION_MAJOR, LUA_API_VERSION_MINOR, LUA_API_VERSION_PATCH); } else { lua_pushfstring(L, "%d.%d.%d-%s", LUA_API_VERSION_MAJOR, LUA_API_VERSION_MINOR, LUA_API_VERSION_PATCH, LUA_API_VERSION_SUFFIX); } lua_settable(L, -3); lua_pushstring(L, "check_version"); lua_pushcfunction(L, check_version); lua_settable(L, -3); luaA_enum(L, lua_os_type); luaA_enum_value_name(L, lua_os_type, os_windows, "windows"); luaA_enum_value_name(L, lua_os_type, os_macos, "macos"); luaA_enum_value_name(L, lua_os_type, os_linux, "linux"); luaA_enum_value_name(L, lua_os_type, os_unix, "unix"); lua_pushstring(L, "running_os"); luaA_push(L, lua_os_type, &cur_os); lua_settable(L, -3); lua_pop(L, 1); // remove the configuration table from the stack return 0; }
void dt_opencl_init(dt_opencl_t *cl, const int argc, char *argv[]) { dt_pthread_mutex_init(&cl->lock, NULL); cl->inited = 0; cl->enabled = 0; cl->dlocl = NULL; int exclude_opencl = 0; // user selectable parameter defines minimum requirement on GPU memory // default is 768MB // values below 200 will be (re)set to 200 const int opencl_memory_requirement = max(200, dt_conf_get_int("opencl_memory_requirement")); dt_conf_set_int("opencl_memory_requirement", opencl_memory_requirement); for(int k=0; k<argc; k++) if(!strcmp(argv[k], "--disable-opencl")) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] do not try to find and use an opencl runtime library due to explicit user request\n"); exclude_opencl = 1; } if(exclude_opencl) goto finally; // look for explicit definition of opencl_runtime library in preferences const char *library = dt_conf_get_string("opencl_library"); dt_print(DT_DEBUG_OPENCL, "[opencl_init] trying to load opencl library: '%s'\n", library && strlen(library) != 0 ? library : "<system default>"); // dynamically load opencl runtime if(!dt_dlopencl_init(library, &cl->dlocl)) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] no working opencl library found. Continue with opencl disabled\n"); goto finally; } else { dt_print(DT_DEBUG_OPENCL, "[opencl_init] opencl library '%s' found on your system and loaded\n", cl->dlocl->library); } cl_int err; cl_platform_id all_platforms[DT_OPENCL_MAX_PLATFORMS]; cl_uint all_num_devices[DT_OPENCL_MAX_PLATFORMS]; cl_uint num_platforms = DT_OPENCL_MAX_PLATFORMS; err = (cl->dlocl->symbols->dt_clGetPlatformIDs) (DT_OPENCL_MAX_PLATFORMS, all_platforms, &num_platforms); if(err != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not get platforms: %d\n", err); goto finally; } if(num_platforms == 0) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] no opencl platform available\n"); goto finally; } dt_print(DT_DEBUG_OPENCL, "[opencl_init] found %d platform%s\n", num_platforms, num_platforms > 1 ? "s" : ""); for(int n=0; n < num_platforms; n++) { cl_platform_id platform = all_platforms[n]; // get the number of GPU devices available to the platforms // the other common option is CL_DEVICE_TYPE_GPU/CPU (but the latter doesn't work with the nvidia drivers) err = (cl->dlocl->symbols->dt_clGetDeviceIDs)(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &(all_num_devices[n])); if(err != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not get device id size: %d\n", err); } } cl_uint num_devices = 0; for(int n=0; n < num_platforms; n++) num_devices += all_num_devices[n]; // create the device list cl->dev = (dt_opencl_device_t *)malloc(sizeof(dt_opencl_device_t)*num_devices); cl_device_id *devices = (cl_device_id *)malloc(sizeof(cl_device_id)*num_devices); cl_device_id *devs = devices; for(int n=0; n < num_platforms; n++) { cl_platform_id platform = all_platforms[n]; err = (cl->dlocl->symbols->dt_clGetDeviceIDs)(platform, CL_DEVICE_TYPE_ALL, all_num_devices[n], devs, NULL); if(err != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not get devices list: %d\n", err); } devs += all_num_devices[n]; } dt_print(DT_DEBUG_OPENCL, "[opencl_init] found %d device%s\n", num_devices, num_devices > 1 ? "s" : ""); if(num_devices == 0) goto finally; int dev = 0; for(int k=0; k<num_devices; k++) { memset(cl->dev[dev].program_used, 0x0, sizeof(int)*DT_OPENCL_MAX_PROGRAMS); memset(cl->dev[dev].kernel_used, 0x0, sizeof(int)*DT_OPENCL_MAX_KERNELS); cl->dev[dev].eventlist = NULL; cl->dev[dev].eventtags = NULL; cl->dev[dev].numevents = 0; cl->dev[dev].eventsconsolidated = 0; cl->dev[dev].maxevents = 0; cl->dev[dev].lostevents = 0; cl->dev[dev].summary=CL_COMPLETE; cl->dev[dev].used_global_mem = 0; cl->dev[dev].nvidia_sm_20 = 0; cl_device_id devid = cl->dev[dev].devid = devices[k]; char infostr[1024]; char vendor[256]; size_t infoint; size_t infointtab[1024]; cl_device_type type; cl_bool image_support = 0; // test GPU memory and image support: (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_VENDOR, sizeof(vendor), &vendor, NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_NAME, sizeof(infostr), &infostr, NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_TYPE, sizeof(cl_device_type), &type, NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &image_support, NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &(cl->dev[dev].max_image_height), NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &(cl->dev[dev].max_image_width), NULL); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &(cl->dev[dev].max_mem_alloc), NULL); if(!strncasecmp(vendor, "NVIDIA", 6)) { // very lame attemt to detect support for atomic float add in global memory. // we need compute model sm_20, but let's try for all nvidia devices :( cl->dev[dev].nvidia_sm_20 = dt_nvidia_gpu_supports_sm_20(infostr); dt_print(DT_DEBUG_OPENCL, "[opencl_init] device %d `%s' %s sm_20 support.\n", k, infostr, cl->dev[dev].nvidia_sm_20 ? "has" : "doesn't have"); } if(type == CL_DEVICE_TYPE_CPU) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding CPU device %d `%s' as it will not deliver any performance gain.\n", k, infostr); continue; } if(!image_support) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding device %d `%s' due to missing image support.\n", k, infostr); continue; } (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &(cl->dev[dev].max_global_mem), NULL); if(cl->dev[dev].max_global_mem < opencl_memory_requirement*1024*1024) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding device %d `%s' due to insufficient global memory (%luMB).\n", k, infostr, cl->dev[dev].max_global_mem/1024/1024); continue; } dt_print(DT_DEBUG_OPENCL, "[opencl_init] device %d `%s' supports image sizes of %zd x %zd\n", k, infostr, cl->dev[dev].max_image_width, cl->dev[dev].max_image_height); dt_print(DT_DEBUG_OPENCL, "[opencl_init] device %d `%s' allows GPU memory allocations of up to %luMB\n", k, infostr, cl->dev[dev].max_mem_alloc/1024/1024); if(darktable.unmuted & DT_DEBUG_OPENCL) { printf("[opencl_init] device %d: %s \n", k, infostr); printf(" GLOBAL_MEM_SIZE: %.0fMB\n", (double)cl->dev[dev].max_global_mem/1024.0/1024.0); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(infoint), &infoint, NULL); printf(" MAX_WORK_GROUP_SIZE: %zd\n", infoint); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(infoint), &infoint, NULL); printf(" MAX_WORK_ITEM_DIMENSIONS: %zd\n", infoint); printf(" MAX_WORK_ITEM_SIZES: [ "); (cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(infointtab), infointtab, NULL); for (int i=0; i<infoint; i++) printf("%zd ", infointtab[i]); printf("]\n"); } dt_pthread_mutex_init(&cl->dev[dev].lock, NULL); cl->dev[dev].context = (cl->dlocl->symbols->dt_clCreateContext)(0, 1, &devid, NULL, NULL, &err); if(err != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not create context for device %d: %d\n", k, err); goto finally; } // create a command queue for first device the context reported cl->dev[dev].cmd_queue = (cl->dlocl->symbols->dt_clCreateCommandQueue)(cl->dev[dev].context, devid, (darktable.unmuted & DT_DEBUG_PERF) ? CL_QUEUE_PROFILING_ENABLE : 0, &err); if(err != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not create command queue for device %d: %d\n", k, err); goto finally; } char dtcache[DT_MAX_PATH_LEN]; char cachedir[DT_MAX_PATH_LEN]; char devname[1024]; double tstart, tend, tdiff; dt_loc_get_user_cache_dir(dtcache, DT_MAX_PATH_LEN); int len = strlen(infostr); int j=0; // remove non-alphanumeric chars from device name for (int i=0; i < len; i++) if (isalnum(infostr[i])) devname[j++]=infostr[i]; devname[j] = 0; snprintf(cachedir, DT_MAX_PATH_LEN, "%s/cached_kernels_for_%s", dtcache, devname); if (mkdir(cachedir, 0700) && (errno != EEXIST)) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] failed to create directory `%s'!\n", cachedir); goto finally; } char dtpath[DT_MAX_PATH_LEN]; char filename[DT_MAX_PATH_LEN]; char programname[DT_MAX_PATH_LEN]; char binname[DT_MAX_PATH_LEN]; dt_loc_get_datadir(dtpath, DT_MAX_PATH_LEN); snprintf(filename, DT_MAX_PATH_LEN, "%s/kernels/programs.conf", dtpath); // now load all darktable cl kernels. // TODO: compile as a job? tstart = dt_get_wtime(); FILE *f = fopen(filename, "rb"); if(f) { while(!feof(f)) { int rd = fscanf(f, "%[^\n]\n", programname); if(rd != 1) continue; // remove comments: for(int pos=0; pos<strlen(programname); pos++) if(programname[pos] == '#') { programname[pos] = '\0'; for(int l=pos-1; l>=0; l--) { if (programname[l] == ' ') programname[l] = '\0'; else break; } break; } if(programname[0] == '\0') continue; snprintf(filename, DT_MAX_PATH_LEN, "%s/kernels/%s", dtpath, programname); snprintf(binname, DT_MAX_PATH_LEN, "%s/%s.bin", cachedir, programname); dt_print(DT_DEBUG_OPENCL, "[opencl_init] compiling program `%s' ..\n", programname); int loaded_cached; char md5sum[33]; const int prog = dt_opencl_load_program(dev, filename, binname, cachedir, md5sum, &loaded_cached); if(dt_opencl_build_program(dev, prog, binname, cachedir, md5sum, loaded_cached) != CL_SUCCESS) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] failed to compile program `%s'!\n", programname); goto finally; } } fclose(f); tend = dt_get_wtime(); tdiff = tend - tstart; dt_print(DT_DEBUG_OPENCL, "[opencl_init] kernel loading time: %2.4lf \n", tdiff); } else { dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not open `%s'!\n", filename); goto finally; } ++dev; } free(devices); if(dev > 0) { dt_print(DT_DEBUG_OPENCL, "[opencl_init] successfully initialized.\n"); cl->num_devs = dev; cl->inited = 1; cl->enabled = dt_conf_get_bool("opencl"); } else { dt_print(DT_DEBUG_OPENCL, "[opencl_init] no suitable devices found.\n"); } finally: dt_print(DT_DEBUG_OPENCL, "[opencl_init] FINALLY: opencl is %sAVAILABLE on this system.\n", cl->inited ? "" : "NOT "); dt_print(DT_DEBUG_OPENCL, "[opencl_init] initial status of opencl enabled flag is %s.\n", cl->enabled ? "ON" : "OFF"); if(cl->inited) { dt_capabilities_add("opencl"); cl->bilateral = dt_bilateral_init_cl_global(); cl->gaussian = dt_gaussian_init_cl_global(); } return; }