diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b66004bee58..4c8fe350b88 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -257,7 +257,7 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); /* feature set */ - bool experimental = (RNA_enum_get(&cscene, "feature_set") != 0); + params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0); /* device type */ params.device_type = DEVICE_CPU; @@ -266,14 +266,14 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background vector types = Device::available_types(); DeviceType dtype; - if(!experimental || RNA_enum_get(&cscene, "gpu_type") == 0) + if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0) dtype = DEVICE_CUDA; else dtype = DEVICE_OPENCL; if(device_type_available(types, dtype)) params.device_type = dtype; - else if(experimental && device_type_available(types, DEVICE_OPENCL)) + else if(params.experimental && device_type_available(types, DEVICE_OPENCL)) params.device_type = DEVICE_OPENCL; else if(device_type_available(types, DEVICE_CUDA)) params.device_type = DEVICE_CUDA; diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 5552e6ab7e2..5b87b11b6b8 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -112,7 +112,7 @@ public: virtual void *osl_memory() { return NULL; } /* load/compile kernels, must be called before adding tasks */ - virtual bool load_kernels() { return true; } + virtual bool load_kernels(bool experimental) { return true; } /* tasks */ virtual void task_add(DeviceTask& task) = 0; diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 83d3f79d96f..eb0e20db355 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -214,6 +214,21 @@ public: return string("CUDA ") + deviceName; } + bool support_device(bool experimental) + { + if(!experimental) { + int major, minor; + cuDeviceComputeCapability(&major, &minor, cuDevId); + + if(major <= 1 && minor <= 2) { + cuda_error(string_printf("CUDA device supported only with shader model 1.3 or up, found %d.%d.", major, minor)); + return false; + } + } + + return true; + } + string compile_kernel() { /* compute cubin name */ @@ -236,11 +251,11 @@ public: if(path_exists(cubin)) return cubin; -#ifdef WITH_CUDA_BINARIES +#if defined(WITH_CUDA_BINARIES) && defined(_WIN32) if(major <= 1 && minor <= 2) cuda_error(string_printf("CUDA device supported only with shader model 1.3 or up, found %d.%d.", major, minor)); else - cuda_error("CUDA binary kernel for this graphics card not found."); + cuda_error("CUDA binary kernel for this graphics card shader model (%d.%d) not found.", major, minor); return ""; #else /* if not, find CUDA compiler */ @@ -283,12 +298,15 @@ public: #endif } - bool load_kernels() + bool load_kernels(bool experimental) { /* check if cuda init succeeded */ if(cuContext == 0) return false; + if(!support_device(experimental)) + return false; + /* get kernel */ string cubin = compile_kernel(); diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 128c80ac396..fc5348ad168 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -132,10 +132,10 @@ public: return desc.str(); } - bool load_kernels() + bool load_kernels(bool experimental) { foreach(SubDevice& sub, devices) - if(!sub.device->load_kernels()) + if(!sub.device->load_kernels(experimental)) return false; return true; diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index d783ae6c174..8eaaebc6629 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -365,7 +365,7 @@ public: return md5.get_hex(); } - bool load_kernels() + bool load_kernels(bool experimental) { /* verify if device was initialized */ if(!device_initialized) { diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 73ac033623d..42b4a2bb7e4 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -410,7 +410,7 @@ void Session::run() /* load kernels */ progress.set_status("Loading render kernels (may take a few minutes the first time)"); - if(!device->load_kernels()) { + if(!device->load_kernels(params.experimental)) { string message = device->error_message(); if(message == "") message = "Failed loading render kernel, see console for errors"; diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 82c14227d03..ce7f420096a 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -43,6 +43,7 @@ public: string output_path; bool progressive; + bool experimental; int samples; int tile_size; int min_size; @@ -59,6 +60,7 @@ public: output_path = ""; progressive = false; + experimental = false; samples = INT_MAX; tile_size = 64; min_size = 64; @@ -75,6 +77,7 @@ public: && output_path == params.output_path /* && samples == params.samples */ && progressive == params.progressive + && experimental == params.experimental && tile_size == params.tile_size && min_size == params.min_size && threads == params.threads