diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 5d6ac10dc40..5552e6ab7e2 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -76,6 +76,7 @@ protected: Device() {} bool background; + string error_msg; public: virtual ~Device() {} @@ -84,6 +85,7 @@ public: /* info */ virtual string description() = 0; + const string& error_message() { return error_msg; } /* regular memory */ virtual void mem_alloc(device_memory& mem, MemoryType type) = 0; diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 1158cc6c77c..e32cbfcc8a7 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -122,7 +122,10 @@ public: CUresult result = stmt; \ \ if(result != CUDA_SUCCESS) { \ - fprintf(stderr, "CUDA error: %s in %s\n", cuda_error_string(result), #stmt); \ + string message = string_printf("CUDA error: %s in %s", cuda_error_string(result), #stmt); \ + if(error_msg == "") \ + error_msg = message; \ + fprintf(stderr, "%s\n", message.c_str()); \ cuda_abort(); \ } \ } @@ -132,10 +135,20 @@ public: if(result == CUDA_SUCCESS) return false; - fprintf(stderr, "CUDA error: %s\n", cuda_error_string(result)); + string message = string_printf("CUDA error: %s", cuda_error_string(result)); + if(error_msg == "") + error_msg = message; + fprintf(stderr, "%s\n", message.c_str()); return true; } + void cuda_error(const string& message) + { + if(error_msg == "") + error_msg = message; + fprintf(stderr, "%s\n", message.c_str()); + } + void cuda_push_context() { cuda_assert(cuCtxSetCurrent(cuContext)) @@ -224,14 +237,14 @@ public: return cubin; #ifdef WITH_CUDA_BINARIES - fprintf(stderr, "CUDA binary kernel for this graphics card not found.\n"); + cuda_error("CUDA binary kernel for this graphics card not found."); return ""; #else /* if not, find CUDA compiler */ string nvcc = cuCompilerPath(); if(nvcc == "") { - fprintf(stderr, "CUDA nvcc compiler not found. Install CUDA toolkit in default location.\n"); + cuda_error("CUDA nvcc compiler not found. Install CUDA toolkit in default location."); return ""; } @@ -251,13 +264,13 @@ public: nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str()); if(system(command.c_str()) == -1) { - fprintf(stderr, "Failed to execute compilation command.\n"); + cuda_error("Failed to execute compilation command, see console for details."); return ""; } /* verify if compilation succeeded */ if(!path_exists(cubin)) { - fprintf(stderr, "CUDA kernel compilation failed.\n"); + cuda_error("CUDA kernel compilation failed, see console for details."); return ""; } @@ -284,7 +297,7 @@ public: CUresult result = cuModuleLoad(&cuModule, cubin.c_str()); if(cuda_error(result)) - fprintf(stderr, "Failed loading CUDA kernel %s.\n", cubin.c_str()); + cuda_error(string_printf("Failed loading CUDA kernel %s.", cubin.c_str())); cuda_pop_context(); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index e0b4f67da05..d783ae6c174 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -109,17 +109,30 @@ public: bool opencl_error(cl_int err) { if(err != CL_SUCCESS) { - fprintf(stderr, "OpenCL error (%d): %s\n", err, opencl_error_string(err)); + string message = string_printf("OpenCL error (%d): %s", err, opencl_error_string(err)); + if(error_msg == "") + error_msg = message; + fprintf(stderr, "%s\n", message.c_str()); return true; } return false; } + void opencl_error(const string& message) + { + if(error_msg == "") + error_msg = message; + fprintf(stderr, "%s\n", message.c_str()); + } + void opencl_assert(cl_int err) { if(err != CL_SUCCESS) { - fprintf(stderr, "OpenCL error (%d): %s\n", err, opencl_error_string(err)); + string message = string_printf("OpenCL error (%d): %s", err, opencl_error_string(err)); + if(error_msg == "") + error_msg = message; + fprintf(stderr, "%s\n", message.c_str()); #ifndef NDEBUG abort(); #endif @@ -147,7 +160,7 @@ public: return; if(num_platforms == 0) { - fprintf(stderr, "OpenCL: no platforms found.\n"); + opencl_error("OpenCL: no platforms found."); return; } @@ -183,24 +196,24 @@ public: clGetPlatformInfo(cpPlatform, CL_PLATFORM_VERSION, sizeof(version), &version, NULL); if(sscanf(version, "OpenCL %d.%d", &major, &minor) < 2) { - fprintf(stderr, "OpenCL: failed to parse platform version string (%s).", version); + opencl_error(string_printf("OpenCL: failed to parse platform version string (%s).", version)); return false; } if(!((major == req_major && minor >= req_minor) || (major > req_major))) { - fprintf(stderr, "OpenCL: platform version 1.1 or later required, found %d.%d\n", major, minor); + opencl_error(string_printf("OpenCL: platform version 1.1 or later required, found %d.%d", major, minor)); return false; } clGetDeviceInfo(cdDevice, CL_DEVICE_OPENCL_C_VERSION, sizeof(version), &version, NULL); if(sscanf(version, "OpenCL C %d.%d", &major, &minor) < 2) { - fprintf(stderr, "OpenCL: failed to parse OpenCL C version string (%s).", version); + opencl_error(string_printf("OpenCL: failed to parse OpenCL C version string (%s).", version)); return false; } if(!((major == req_major && minor >= req_minor) || (major > req_major))) { - fprintf(stderr, "OpenCL: C version 1.1 or later required, found %d.%d\n", major, minor); + opencl_error(string_printf("OpenCL: C version 1.1 or later required, found %d.%d", major, minor)); return false; } @@ -216,7 +229,7 @@ public: vector binary; if(!path_read_binary(clbin, binary)) { - fprintf(stderr, "OpenCL failed to read cached binary %s.\n", clbin.c_str()); + opencl_error(string_printf("OpenCL failed to read cached binary %s.", clbin.c_str())); return false; } @@ -229,7 +242,7 @@ public: &size, &bytes, &status, &ciErr); if(opencl_error(status) || opencl_error(ciErr)) { - fprintf(stderr, "OpenCL failed create program from cached binary %s.\n", clbin.c_str()); + opencl_error(string_printf("OpenCL failed create program from cached binary %s.", clbin.c_str())); return false; } @@ -253,7 +266,7 @@ public: clGetProgramInfo(cpProgram, CL_PROGRAM_BINARIES, sizeof(uint8_t*), &bytes, NULL); if(!path_write_binary(clbin, binary)) { - fprintf(stderr, "OpenCL failed to write cached binary %s.\n", clbin.c_str()); + opencl_error(string_printf("OpenCL failed to write cached binary %s.", clbin.c_str())); return false; } @@ -293,7 +306,8 @@ public: clGetProgramBuildInfo(cpProgram, cdDevice, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); build_log[ret_val_size] = '\0'; - fprintf(stderr, "OpenCL build failed:\n %s\n", build_log); + opencl_error("OpenCL build failed: errors in console"); + fprintf(stderr, "%s\n", build_log); delete[] build_log; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 2deb83674cc..73ac033623d 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -203,6 +203,10 @@ void Session::run_gpu() if(!no_tiles) { /* update scene */ update_scene(); + + if(device->error_message() != "") + progress.set_cancel(device->error_message()); + if(progress.get_cancel()) break; } @@ -222,6 +226,9 @@ void Session::run_gpu() device->task_wait(); + if(device->error_message() != "") + progress.set_cancel(device->error_message()); + if(progress.get_cancel()) break; } @@ -243,6 +250,9 @@ void Session::run_gpu() } } + if(device->error_message() != "") + progress.set_cancel(device->error_message()); + if(progress.get_cancel()) break; } @@ -345,6 +355,10 @@ void Session::run_cpu() /* update scene */ update_scene(); + + if(device->error_message() != "") + progress.set_cancel(device->error_message()); + if(progress.get_cancel()) break; @@ -360,6 +374,9 @@ void Session::run_cpu() if(!params.background) need_tonemap = true; + + if(device->error_message() != "") + progress.set_cancel(device->error_message()); } device->task_wait(); @@ -379,6 +396,9 @@ void Session::run_cpu() want to show the result of an incomplete sample*/ tonemap(); } + + if(device->error_message() != "") + progress.set_cancel(device->error_message()); } progress.set_update(); @@ -391,7 +411,11 @@ void Session::run() progress.set_status("Loading render kernels (may take a few minutes the first time)"); if(!device->load_kernels()) { - progress.set_status("Failed loading render kernel, see console for errors"); + string message = device->error_message(); + if(message == "") + message = "Failed loading render kernel, see console for errors"; + + progress.set_status("Error", message); progress.set_update(); return; } @@ -409,7 +433,7 @@ void Session::run() /* progress update */ if(progress.get_cancel()) - progress.set_status(progress.get_cancel_message()); + progress.set_status("Cancel", progress.get_cancel_message()); else progress.set_update(); }