Esempio n. 1
0
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;
}
Esempio n. 2
0
/* 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);
  }
}
Esempio n. 3
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(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;
  
}
Esempio n. 4
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;

}
Esempio n. 5
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;
}
Esempio n. 6
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;
}