* Compute MD5 hash to deal with nvidia opencl compiler cache not recognizing
  changes in #included files, makes it possible to do kernel compile only
  once and remember it for the next time blender is started.
* Kernel tweak to compile with ATI/linux. Enabling any more functionality than
  simple clay render still chokes the compiler though, without a specific error
  message ..
This commit is contained in:
2011-09-03 10:49:54 +00:00
parent 67030aaf84
commit db1664ed4c
10 changed files with 66 additions and 13 deletions

View File

@@ -25,9 +25,9 @@ def get_gpu_device():
if cuda and opencl:
gpu_string = "GPU"
elif cuda and not opencl:
gpu_string = "GPU (CUDA)"
gpu_string = "CUDA GPU"
else:
gpu_string = "GPU (OpenCL)"
gpu_string = "OpenCL GPU"
return gpu_string

View File

@@ -217,19 +217,19 @@ public:
if(!opencl_version_check())
return false;
/* nvidia opencl cache doesn't not work correct with includes, so force recompile */
static double recompile_trick = 0.0;
if(recompile_trick == 0.0)
recompile_trick = time_dt();
/* we compile kernels consisting of many files. unfortunately opencl
kernel caches do not seem to recognize changes in included files.
so we force recompile on changes by adding the md5 hash of all files */
string kernel_path = path_get("kernel");
string kernel_md5 = path_files_md5_hash(kernel_path);
/* compile source */
string source = string_printf("#include \"kernel.cl\" // %lf\n", recompile_trick);
string source = "#include \"kernel.cl\" // " + kernel_md5 + "\n";
size_t source_len = source.size();
const char *source_str = source.c_str();
string build_options = "";
build_options += "-I " + path_get("kernel") + " -I " + path_get("util"); /* todo: escape path */
build_options += "-I " + kernel_path + ""; /* todo: escape path */
build_options += " -Werror -cl-fast-relaxed-math -cl-strict-aliasing";
cpProgram = clCreateProgramWithSource(cxContext, 1, &source_str, &source_len, &ciErr);

View File

@@ -194,7 +194,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
L += throughput*shader_eval_background(kg, &sd, state.flag);
shader_release(kg, &sd);
#else
L += make_float3(0.8f, 0.8f, 0.8f);
L += throughput*make_float3(0.8f, 0.8f, 0.8f);
#endif
}

View File

@@ -32,12 +32,12 @@ CCL_NAMESPACE_BEGIN
#define __DPDU__
#define __UV__
#define __BACKGROUND__
#define __EMISSION__
#define __CAUSTICS_TRICKS__
#define __VISIBILITY_FLAG__
#ifndef __KERNEL_OPENCL__
#define __SVM__
#define __EMISSION__
#define __TEXTURES__
#define __HOLDOUT__
#endif

View File

@@ -37,6 +37,7 @@ __device int svm_bsdf_sample(const ShaderData *sd, float randu, float randv, flo
case CLOSURE_BSDF_DIFFUSE_ID:
label = bsdf_diffuse_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __SVM__
case CLOSURE_BSDF_TRANSLUCENT_ID:
label = bsdf_translucent_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
@@ -71,6 +72,7 @@ __device int svm_bsdf_sample(const ShaderData *sd, float randu, float randv, flo
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
label = bsdf_westin_sheen_sample(sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#endif
default:
label = LABEL_NONE;
break;

View File

@@ -35,7 +35,7 @@ Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.passes, params.tile_size, params.min_size)
{
device_use_gl = (params.device_type == DEVICE_CUDA && !params.background);
device_use_gl = ((params.device_type == DEVICE_CUDA || params.device_type == DEVICE_OPENCL) && !params.background);
device = Device::create(params.device_type, params.background, params.threads);
buffers = new RenderBuffers(device);
@@ -381,7 +381,7 @@ void Session::run_cpu()
void Session::run()
{
/* load kernels */
progress.set_status("Loading render kernels");
progress.set_status("Loading render kernels (may take a few minutes)");
if(!device->load_kernels()) {
progress.set_status("Failed loading render kernel, see console for errors");

View File

@@ -309,6 +309,29 @@ void MD5Hash::append(const uint8_t *data, int nbytes)
memcpy(buf, p, left);
}
bool MD5Hash::append_file(const string& filepath)
{
FILE *f = fopen(filepath.c_str(), "rb");
if(!f)
return false;
const size_t buffer_size = 1024;
uint8_t buffer[buffer_size];
size_t n;
do {
n = fread(buffer, 1, buffer_size, f);
append(buffer, n);
} while(n == buffer_size);
bool success = (ferror(f) == 0);
fclose(f);
return success;
}
void MD5Hash::finish(uint8_t digest[16])
{
static const uint8_t pad[64] = {

View File

@@ -41,6 +41,7 @@ public:
~MD5Hash();
void append(const uint8_t *data, int size);
bool append_file(const string& filepath);
string get_hex();
protected:

View File

@@ -17,6 +17,7 @@
*/
#include "util_debug.h"
#include "util_md5.h"
#include "util_path.h"
#include "util_string.h"
@@ -59,5 +60,29 @@ string path_join(const string& dir, const string& file)
return (boost::filesystem::path(dir) / boost::filesystem::path(file)).string();
}
string path_files_md5_hash(const string& dir)
{
/* computes md5 hash of all files in the directory */
MD5Hash hash;
if(boost::filesystem::exists(dir)) {
boost::filesystem::directory_iterator it(dir), it_end;
for(; it != it_end; it++) {
if(boost::filesystem::is_directory(it->status())) {
path_files_md5_hash(it->path().string());
}
else {
string filepath = it->path().string();
hash.append((const uint8_t*)filepath.c_str(), filepath.size());
hash.append_file(filepath);
}
}
}
return hash.get_hex();
}
CCL_NAMESPACE_END

View File

@@ -35,6 +35,8 @@ string path_filename(const string& path);
string path_dirname(const string& path);
string path_join(const string& dir, const string& file);
string path_files_md5_hash(const string& dir);
CCL_NAMESPACE_END
#endif