diff options
Diffstat (limited to 'intern/cycles/device/device.cpp')
-rw-r--r-- | intern/cycles/device/device.cpp | 921 |
1 files changed, 463 insertions, 458 deletions
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index e74637472ef..16a68e8b855 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -44,572 +44,577 @@ uint Device::devices_initialized_mask = 0; /* Device Requested Features */ -std::ostream& operator <<(std::ostream &os, - const DeviceRequestedFeatures& requested_features) +std::ostream &operator<<(std::ostream &os, const DeviceRequestedFeatures &requested_features) { - os << "Experimental features: " - << (requested_features.experimental ? "On" : "Off") << std::endl; - os << "Max nodes group: " << requested_features.max_nodes_group << std::endl; - /* TODO(sergey): Decode bitflag into list of names. */ - os << "Nodes features: " << requested_features.nodes_features << std::endl; - os << "Use Hair: " - << string_from_bool(requested_features.use_hair) << std::endl; - os << "Use Object Motion: " - << string_from_bool(requested_features.use_object_motion) << std::endl; - os << "Use Camera Motion: " - << string_from_bool(requested_features.use_camera_motion) << std::endl; - os << "Use Baking: " - << string_from_bool(requested_features.use_baking) << std::endl; - os << "Use Subsurface: " - << string_from_bool(requested_features.use_subsurface) << std::endl; - os << "Use Volume: " - << string_from_bool(requested_features.use_volume) << std::endl; - os << "Use Branched Integrator: " - << string_from_bool(requested_features.use_integrator_branched) << std::endl; - os << "Use Patch Evaluation: " - << string_from_bool(requested_features.use_patch_evaluation) << std::endl; - os << "Use Transparent Shadows: " - << string_from_bool(requested_features.use_transparent) << std::endl; - os << "Use Principled BSDF: " - << string_from_bool(requested_features.use_principled) << std::endl; - os << "Use Denoising: " - << string_from_bool(requested_features.use_denoising) << std::endl; - os << "Use Displacement: " - << string_from_bool(requested_features.use_true_displacement) << std::endl; - os << "Use Background Light: " - << string_from_bool(requested_features.use_background_light) << std::endl; - return os; + os << "Experimental features: " << (requested_features.experimental ? "On" : "Off") << std::endl; + os << "Max nodes group: " << requested_features.max_nodes_group << std::endl; + /* TODO(sergey): Decode bitflag into list of names. */ + os << "Nodes features: " << requested_features.nodes_features << std::endl; + os << "Use Hair: " << string_from_bool(requested_features.use_hair) << std::endl; + os << "Use Object Motion: " << string_from_bool(requested_features.use_object_motion) + << std::endl; + os << "Use Camera Motion: " << string_from_bool(requested_features.use_camera_motion) + << std::endl; + os << "Use Baking: " << string_from_bool(requested_features.use_baking) << std::endl; + os << "Use Subsurface: " << string_from_bool(requested_features.use_subsurface) << std::endl; + os << "Use Volume: " << string_from_bool(requested_features.use_volume) << std::endl; + os << "Use Branched Integrator: " << string_from_bool(requested_features.use_integrator_branched) + << std::endl; + os << "Use Patch Evaluation: " << string_from_bool(requested_features.use_patch_evaluation) + << std::endl; + os << "Use Transparent Shadows: " << string_from_bool(requested_features.use_transparent) + << std::endl; + os << "Use Principled BSDF: " << string_from_bool(requested_features.use_principled) + << std::endl; + os << "Use Denoising: " << string_from_bool(requested_features.use_denoising) << std::endl; + os << "Use Displacement: " << string_from_bool(requested_features.use_true_displacement) + << std::endl; + os << "Use Background Light: " << string_from_bool(requested_features.use_background_light) + << std::endl; + return os; } /* Device */ Device::~Device() { - if(!background) { - if(vertex_buffer != 0) { - glDeleteBuffers(1, &vertex_buffer); - } - if(fallback_shader_program != 0) { - glDeleteProgram(fallback_shader_program); - } - } + if (!background) { + if (vertex_buffer != 0) { + glDeleteBuffers(1, &vertex_buffer); + } + if (fallback_shader_program != 0) { + glDeleteProgram(fallback_shader_program); + } + } } /* TODO move shaders to standalone .glsl file. */ const char *FALLBACK_VERTEX_SHADER = -"#version 330\n" -"uniform vec2 fullscreen;\n" -"in vec2 texCoord;\n" -"in vec2 pos;\n" -"out vec2 texCoord_interp;\n" -"\n" -"vec2 normalize_coordinates()\n" -"{\n" -" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n" -"}\n" -"\n" -"void main()\n" -"{\n" -" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n" -" texCoord_interp = texCoord;\n" -"}\n\0"; + "#version 330\n" + "uniform vec2 fullscreen;\n" + "in vec2 texCoord;\n" + "in vec2 pos;\n" + "out vec2 texCoord_interp;\n" + "\n" + "vec2 normalize_coordinates()\n" + "{\n" + " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n" + "}\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n" + " texCoord_interp = texCoord;\n" + "}\n\0"; const char *FALLBACK_FRAGMENT_SHADER = -"#version 330\n" -"uniform sampler2D image_texture;\n" -"in vec2 texCoord_interp;\n" -"out vec4 fragColor;\n" -"\n" -"void main()\n" -"{\n" -" fragColor = texture(image_texture, texCoord_interp);\n" -"}\n\0"; + "#version 330\n" + "uniform sampler2D image_texture;\n" + "in vec2 texCoord_interp;\n" + "out vec4 fragColor;\n" + "\n" + "void main()\n" + "{\n" + " fragColor = texture(image_texture, texCoord_interp);\n" + "}\n\0"; static void shader_print_errors(const char *task, const char *log, const char *code) { - LOG(ERROR) << "Shader: " << task << " error:"; - LOG(ERROR) << "===== shader string ===="; - - stringstream stream(code); - string partial; - - int line = 1; - while(getline(stream, partial, '\n')) { - if(line < 10) { - LOG(ERROR) << " " << line << " " << partial; - } - else { - LOG(ERROR) << line << " " << partial; - } - line++; - } - LOG(ERROR) << log; + LOG(ERROR) << "Shader: " << task << " error:"; + LOG(ERROR) << "===== shader string ===="; + + stringstream stream(code); + string partial; + + int line = 1; + while (getline(stream, partial, '\n')) { + if (line < 10) { + LOG(ERROR) << " " << line << " " << partial; + } + else { + LOG(ERROR) << line << " " << partial; + } + line++; + } + LOG(ERROR) << log; } static int bind_fallback_shader(void) { - GLint status; - GLchar log[5000]; - GLsizei length = 0; - GLuint program = 0; + GLint status; + GLchar log[5000]; + GLsizei length = 0; + GLuint program = 0; - struct Shader { - const char *source; - GLenum type; - } shaders[2] = { - {FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER}, - {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER} - }; + struct Shader { + const char *source; + GLenum type; + } shaders[2] = {{FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER}, + {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}}; - program = glCreateProgram(); + program = glCreateProgram(); - for(int i = 0; i < 2; i++) { - GLuint shader = glCreateShader(shaders[i].type); + for (int i = 0; i < 2; i++) { + GLuint shader = glCreateShader(shaders[i].type); - string source_str = shaders[i].source; - const char *c_str = source_str.c_str(); + string source_str = shaders[i].source; + const char *c_str = source_str.c_str(); - glShaderSource(shader, 1, &c_str, NULL); - glCompileShader(shader); + glShaderSource(shader, 1, &c_str, NULL); + glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) { - glGetShaderInfoLog(shader, sizeof(log), &length, log); - shader_print_errors("compile", log, c_str); - return 0; - } + if (!status) { + glGetShaderInfoLog(shader, sizeof(log), &length, log); + shader_print_errors("compile", log, c_str); + return 0; + } - glAttachShader(program, shader); - } + glAttachShader(program, shader); + } - /* Link output. */ - glBindFragDataLocation(program, 0, "fragColor"); + /* Link output. */ + glBindFragDataLocation(program, 0, "fragColor"); - /* Link and error check. */ - glLinkProgram(program); + /* Link and error check. */ + glLinkProgram(program); - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) { - glGetShaderInfoLog(program, sizeof(log), &length, log); - shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER); - shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER); - return 0; - } + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (!status) { + glGetShaderInfoLog(program, sizeof(log), &length, log); + shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER); + shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER); + return 0; + } - return program; + return program; } bool Device::bind_fallback_display_space_shader(const float width, const float height) { - if(fallback_status == FALLBACK_SHADER_STATUS_ERROR) { - return false; - } - - if(fallback_status == FALLBACK_SHADER_STATUS_NONE) { - fallback_shader_program = bind_fallback_shader(); - fallback_status = FALLBACK_SHADER_STATUS_ERROR; - - if(fallback_shader_program == 0) { - return false; - } - - glUseProgram(fallback_shader_program); - image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture"); - if(image_texture_location < 0) { - LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform."; - return false; - } - - fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen"); - if(fullscreen_location < 0) { - LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform."; - return false; - } - - fallback_status = FALLBACK_SHADER_STATUS_SUCCESS; - } - - /* Run this every time. */ - glUseProgram(fallback_shader_program); - glUniform1i(image_texture_location, 0); - glUniform2f(fullscreen_location, width, height); - return true; + if (fallback_status == FALLBACK_SHADER_STATUS_ERROR) { + return false; + } + + if (fallback_status == FALLBACK_SHADER_STATUS_NONE) { + fallback_shader_program = bind_fallback_shader(); + fallback_status = FALLBACK_SHADER_STATUS_ERROR; + + if (fallback_shader_program == 0) { + return false; + } + + glUseProgram(fallback_shader_program); + image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture"); + if (image_texture_location < 0) { + LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform."; + return false; + } + + fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen"); + if (fullscreen_location < 0) { + LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform."; + return false; + } + + fallback_status = FALLBACK_SHADER_STATUS_SUCCESS; + } + + /* Run this every time. */ + glUseProgram(fallback_shader_program); + glUniform1i(image_texture_location, 0); + glUniform2f(fullscreen_location, width, height); + return true; } -void Device::draw_pixels( - device_memory& rgba, int y, - int w, int h, int width, int height, - int dx, int dy, int dw, int dh, - bool transparent, const DeviceDrawParams &draw_params) +void Device::draw_pixels(device_memory &rgba, + int y, + int w, + int h, + int width, + int height, + int dx, + int dy, + int dw, + int dh, + bool transparent, + const DeviceDrawParams &draw_params) { - const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL); - - assert(rgba.type == MEM_PIXELS); - mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1)); - - GLuint texid; - glActiveTexture(GL_TEXTURE0); - glGenTextures(1, &texid); - glBindTexture(GL_TEXTURE_2D, texid); - - if(rgba.data_type == TYPE_HALF) { - GLhalf *data_pointer = (GLhalf*)rgba.host_pointer; - data_pointer += 4 * y * w; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer); - } - else { - uint8_t *data_pointer = (uint8_t*)rgba.host_pointer; - data_pointer += 4 * y * w; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - if(transparent) { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - GLint shader_program; - if(use_fallback_shader) { - if(!bind_fallback_display_space_shader(dw, dh)) { - return; - } - shader_program = fallback_shader_program; - } - else { - draw_params.bind_display_space_shader_cb(); - glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program); - } - - if(!vertex_buffer) { - glGenBuffers(1, &vertex_buffer); - } - - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); - /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */ - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW); - - float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - - if(vpointer) { - /* texture coordinate - vertex pair */ - vpointer[0] = 0.0f; - vpointer[1] = 0.0f; - vpointer[2] = dx; - vpointer[3] = dy; - - vpointer[4] = 1.0f; - vpointer[5] = 0.0f; - vpointer[6] = (float)width + dx; - vpointer[7] = dy; - - vpointer[8] = 1.0f; - vpointer[9] = 1.0f; - vpointer[10] = (float)width + dx; - vpointer[11] = (float)height + dy; - - vpointer[12] = 0.0f; - vpointer[13] = 1.0f; - vpointer[14] = dx; - vpointer[15] = (float)height + dy; - - if(vertex_buffer) { - glUnmapBuffer(GL_ARRAY_BUFFER); - } - } - - GLuint vertex_array_object; - GLuint position_attribute, texcoord_attribute; - - glGenVertexArrays(1, &vertex_array_object); - glBindVertexArray(vertex_array_object); - - texcoord_attribute = glGetAttribLocation(shader_program, "texCoord"); - position_attribute = glGetAttribLocation(shader_program, "pos"); - - glEnableVertexAttribArray(texcoord_attribute); - glEnableVertexAttribArray(position_attribute); - - glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0); - glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2)); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - if(vertex_buffer) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - - if(use_fallback_shader) { - glUseProgram(0); - } - else { - draw_params.unbind_display_space_shader_cb(); - } - - glDeleteVertexArrays(1, &vertex_array_object); - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &texid); - - if(transparent) { - glDisable(GL_BLEND); - } + const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL); + + assert(rgba.type == MEM_PIXELS); + mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1)); + + GLuint texid; + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &texid); + glBindTexture(GL_TEXTURE_2D, texid); + + if (rgba.data_type == TYPE_HALF) { + GLhalf *data_pointer = (GLhalf *)rgba.host_pointer; + data_pointer += 4 * y * w; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer); + } + else { + uint8_t *data_pointer = (uint8_t *)rgba.host_pointer; + data_pointer += 4 * y * w; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if (transparent) { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + + GLint shader_program; + if (use_fallback_shader) { + if (!bind_fallback_display_space_shader(dw, dh)) { + return; + } + shader_program = fallback_shader_program; + } + else { + draw_params.bind_display_space_shader_cb(); + glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program); + } + + if (!vertex_buffer) { + glGenBuffers(1, &vertex_buffer); + } + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */ + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW); + + float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + if (vpointer) { + /* texture coordinate - vertex pair */ + vpointer[0] = 0.0f; + vpointer[1] = 0.0f; + vpointer[2] = dx; + vpointer[3] = dy; + + vpointer[4] = 1.0f; + vpointer[5] = 0.0f; + vpointer[6] = (float)width + dx; + vpointer[7] = dy; + + vpointer[8] = 1.0f; + vpointer[9] = 1.0f; + vpointer[10] = (float)width + dx; + vpointer[11] = (float)height + dy; + + vpointer[12] = 0.0f; + vpointer[13] = 1.0f; + vpointer[14] = dx; + vpointer[15] = (float)height + dy; + + if (vertex_buffer) { + glUnmapBuffer(GL_ARRAY_BUFFER); + } + } + + GLuint vertex_array_object; + GLuint position_attribute, texcoord_attribute; + + glGenVertexArrays(1, &vertex_array_object); + glBindVertexArray(vertex_array_object); + + texcoord_attribute = glGetAttribLocation(shader_program, "texCoord"); + position_attribute = glGetAttribLocation(shader_program, "pos"); + + glEnableVertexAttribArray(texcoord_attribute); + glEnableVertexAttribArray(position_attribute); + + glVertexAttribPointer( + texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0); + glVertexAttribPointer(position_attribute, + 2, + GL_FLOAT, + GL_FALSE, + 4 * sizeof(float), + (const GLvoid *)(sizeof(float) * 2)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + if (vertex_buffer) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + if (use_fallback_shader) { + glUseProgram(0); + } + else { + draw_params.unbind_display_space_shader_cb(); + } + + glDeleteVertexArrays(1, &vertex_array_object); + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &texid); + + if (transparent) { + glDisable(GL_BLEND); + } } -Device *Device::create(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background) +Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background) { - Device *device; + Device *device; - switch(info.type) { - case DEVICE_CPU: - device = device_cpu_create(info, stats, profiler, background); - break; + switch (info.type) { + case DEVICE_CPU: + device = device_cpu_create(info, stats, profiler, background); + break; #ifdef WITH_CUDA - case DEVICE_CUDA: - if(device_cuda_init()) - device = device_cuda_create(info, stats, profiler, background); - else - device = NULL; - break; + case DEVICE_CUDA: + if (device_cuda_init()) + device = device_cuda_create(info, stats, profiler, background); + else + device = NULL; + break; #endif #ifdef WITH_MULTI - case DEVICE_MULTI: - device = device_multi_create(info, stats, profiler, background); - break; + case DEVICE_MULTI: + device = device_multi_create(info, stats, profiler, background); + break; #endif #ifdef WITH_NETWORK - case DEVICE_NETWORK: - device = device_network_create(info, stats, profiler, "127.0.0.1"); - break; + case DEVICE_NETWORK: + device = device_network_create(info, stats, profiler, "127.0.0.1"); + break; #endif #ifdef WITH_OPENCL - case DEVICE_OPENCL: - if(device_opencl_init()) - device = device_opencl_create(info, stats, profiler, background); - else - device = NULL; - break; + case DEVICE_OPENCL: + if (device_opencl_init()) + device = device_opencl_create(info, stats, profiler, background); + else + device = NULL; + break; #endif - default: - return NULL; - } + default: + return NULL; + } - return device; + return device; } DeviceType Device::type_from_string(const char *name) { - if(strcmp(name, "CPU") == 0) - return DEVICE_CPU; - else if(strcmp(name, "CUDA") == 0) - return DEVICE_CUDA; - else if(strcmp(name, "OPENCL") == 0) - return DEVICE_OPENCL; - else if(strcmp(name, "NETWORK") == 0) - return DEVICE_NETWORK; - else if(strcmp(name, "MULTI") == 0) - return DEVICE_MULTI; - - return DEVICE_NONE; + if (strcmp(name, "CPU") == 0) + return DEVICE_CPU; + else if (strcmp(name, "CUDA") == 0) + return DEVICE_CUDA; + else if (strcmp(name, "OPENCL") == 0) + return DEVICE_OPENCL; + else if (strcmp(name, "NETWORK") == 0) + return DEVICE_NETWORK; + else if (strcmp(name, "MULTI") == 0) + return DEVICE_MULTI; + + return DEVICE_NONE; } string Device::string_from_type(DeviceType type) { - if(type == DEVICE_CPU) - return "CPU"; - else if(type == DEVICE_CUDA) - return "CUDA"; - else if(type == DEVICE_OPENCL) - return "OPENCL"; - else if(type == DEVICE_NETWORK) - return "NETWORK"; - else if(type == DEVICE_MULTI) - return "MULTI"; - - return ""; + if (type == DEVICE_CPU) + return "CPU"; + else if (type == DEVICE_CUDA) + return "CUDA"; + else if (type == DEVICE_OPENCL) + return "OPENCL"; + else if (type == DEVICE_NETWORK) + return "NETWORK"; + else if (type == DEVICE_MULTI) + return "MULTI"; + + return ""; } vector<DeviceType> Device::available_types() { - vector<DeviceType> types; - types.push_back(DEVICE_CPU); + vector<DeviceType> types; + types.push_back(DEVICE_CPU); #ifdef WITH_CUDA - types.push_back(DEVICE_CUDA); + types.push_back(DEVICE_CUDA); #endif #ifdef WITH_OPENCL - types.push_back(DEVICE_OPENCL); + types.push_back(DEVICE_OPENCL); #endif #ifdef WITH_NETWORK - types.push_back(DEVICE_NETWORK); + types.push_back(DEVICE_NETWORK); #endif - return types; + return types; } vector<DeviceInfo> Device::available_devices(uint mask) { - /* Lazy initialize devices. On some platforms OpenCL or CUDA drivers can - * be broken and cause crashes when only trying to get device info, so - * we don't want to do any initialization until the user chooses to. */ - thread_scoped_lock lock(device_mutex); - vector<DeviceInfo> devices; + /* Lazy initialize devices. On some platforms OpenCL or CUDA drivers can + * be broken and cause crashes when only trying to get device info, so + * we don't want to do any initialization until the user chooses to. */ + thread_scoped_lock lock(device_mutex); + vector<DeviceInfo> devices; #ifdef WITH_OPENCL - if(mask & DEVICE_MASK_OPENCL) { - if(!(devices_initialized_mask & DEVICE_MASK_OPENCL)) { - if(device_opencl_init()) { - device_opencl_info(opencl_devices); - } - devices_initialized_mask |= DEVICE_MASK_OPENCL; - } - foreach(DeviceInfo& info, opencl_devices) { - devices.push_back(info); - } - } + if (mask & DEVICE_MASK_OPENCL) { + if (!(devices_initialized_mask & DEVICE_MASK_OPENCL)) { + if (device_opencl_init()) { + device_opencl_info(opencl_devices); + } + devices_initialized_mask |= DEVICE_MASK_OPENCL; + } + foreach (DeviceInfo &info, opencl_devices) { + devices.push_back(info); + } + } #endif #ifdef WITH_CUDA - if(mask & DEVICE_MASK_CUDA) { - if(!(devices_initialized_mask & DEVICE_MASK_CUDA)) { - if(device_cuda_init()) { - device_cuda_info(cuda_devices); - } - devices_initialized_mask |= DEVICE_MASK_CUDA; - } - foreach(DeviceInfo& info, cuda_devices) { - devices.push_back(info); - } - } + if (mask & DEVICE_MASK_CUDA) { + if (!(devices_initialized_mask & DEVICE_MASK_CUDA)) { + if (device_cuda_init()) { + device_cuda_info(cuda_devices); + } + devices_initialized_mask |= DEVICE_MASK_CUDA; + } + foreach (DeviceInfo &info, cuda_devices) { + devices.push_back(info); + } + } #endif - if(mask & DEVICE_MASK_CPU) { - if(!(devices_initialized_mask & DEVICE_MASK_CPU)) { - device_cpu_info(cpu_devices); - devices_initialized_mask |= DEVICE_MASK_CPU; - } - foreach(DeviceInfo& info, cpu_devices) { - devices.push_back(info); - } - } + if (mask & DEVICE_MASK_CPU) { + if (!(devices_initialized_mask & DEVICE_MASK_CPU)) { + device_cpu_info(cpu_devices); + devices_initialized_mask |= DEVICE_MASK_CPU; + } + foreach (DeviceInfo &info, cpu_devices) { + devices.push_back(info); + } + } #ifdef WITH_NETWORK - if(mask & DEVICE_MASK_NETWORK) { - if(!(devices_initialized_mask & DEVICE_MASK_NETWORK)) { - device_network_info(network_devices); - devices_initialized_mask |= DEVICE_MASK_NETWORK; - } - foreach(DeviceInfo& info, network_devices) { - devices.push_back(info); - } - } + if (mask & DEVICE_MASK_NETWORK) { + if (!(devices_initialized_mask & DEVICE_MASK_NETWORK)) { + device_network_info(network_devices); + devices_initialized_mask |= DEVICE_MASK_NETWORK; + } + foreach (DeviceInfo &info, network_devices) { + devices.push_back(info); + } + } #endif - return devices; + return devices; } string Device::device_capabilities(uint mask) { - thread_scoped_lock lock(device_mutex); - string capabilities = ""; + thread_scoped_lock lock(device_mutex); + string capabilities = ""; - if(mask & DEVICE_MASK_CPU) { - capabilities += "\nCPU device capabilities: "; - capabilities += device_cpu_capabilities() + "\n"; - } + if (mask & DEVICE_MASK_CPU) { + capabilities += "\nCPU device capabilities: "; + capabilities += device_cpu_capabilities() + "\n"; + } #ifdef WITH_OPENCL - if(mask & DEVICE_MASK_OPENCL) { - if(device_opencl_init()) { - capabilities += "\nOpenCL device capabilities:\n"; - capabilities += device_opencl_capabilities(); - } - } + if (mask & DEVICE_MASK_OPENCL) { + if (device_opencl_init()) { + capabilities += "\nOpenCL device capabilities:\n"; + capabilities += device_opencl_capabilities(); + } + } #endif #ifdef WITH_CUDA - if(mask & DEVICE_MASK_CUDA) { - if(device_cuda_init()) { - capabilities += "\nCUDA device capabilities:\n"; - capabilities += device_cuda_capabilities(); - } - } + if (mask & DEVICE_MASK_CUDA) { + if (device_cuda_init()) { + capabilities += "\nCUDA device capabilities:\n"; + capabilities += device_cuda_capabilities(); + } + } #endif - return capabilities; + return capabilities; } -DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int threads, bool background) +DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices, + int threads, + bool background) { - assert(subdevices.size() > 0); - - if(subdevices.size() == 1) { - /* No multi device needed. */ - return subdevices.front(); - } - - DeviceInfo info; - info.type = DEVICE_MULTI; - info.id = "MULTI"; - info.description = "Multi Device"; - info.num = 0; - - info.has_half_images = true; - info.has_volume_decoupled = true; - info.has_osl = true; - info.has_profiling = true; - - foreach(const DeviceInfo &device, subdevices) { - /* Ensure CPU device does not slow down GPU. */ - if(device.type == DEVICE_CPU && subdevices.size() > 1) { - if(background) { - int orig_cpu_threads = (threads)? threads: system_cpu_thread_count(); - int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0); - - VLOG(1) << "CPU render threads reduced from " - << orig_cpu_threads << " to " << cpu_threads - << ", to dedicate to GPU."; - - if(cpu_threads >= 1) { - DeviceInfo cpu_device = device; - cpu_device.cpu_threads = cpu_threads; - info.multi_devices.push_back(cpu_device); - } - else { - continue; - } - } - else { - VLOG(1) << "CPU render threads disabled for interactive render."; - continue; - } - } - else { - info.multi_devices.push_back(device); - } - - /* Accumulate device info. */ - info.has_half_images &= device.has_half_images; - info.has_volume_decoupled &= device.has_volume_decoupled; - info.has_osl &= device.has_osl; - info.has_profiling &= device.has_profiling; - } - - return info; + assert(subdevices.size() > 0); + + if (subdevices.size() == 1) { + /* No multi device needed. */ + return subdevices.front(); + } + + DeviceInfo info; + info.type = DEVICE_MULTI; + info.id = "MULTI"; + info.description = "Multi Device"; + info.num = 0; + + info.has_half_images = true; + info.has_volume_decoupled = true; + info.has_osl = true; + info.has_profiling = true; + + foreach (const DeviceInfo &device, subdevices) { + /* Ensure CPU device does not slow down GPU. */ + if (device.type == DEVICE_CPU && subdevices.size() > 1) { + if (background) { + int orig_cpu_threads = (threads) ? threads : system_cpu_thread_count(); + int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0); + + VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads + << ", to dedicate to GPU."; + + if (cpu_threads >= 1) { + DeviceInfo cpu_device = device; + cpu_device.cpu_threads = cpu_threads; + info.multi_devices.push_back(cpu_device); + } + else { + continue; + } + } + else { + VLOG(1) << "CPU render threads disabled for interactive render."; + continue; + } + } + else { + info.multi_devices.push_back(device); + } + + /* Accumulate device info. */ + info.has_half_images &= device.has_half_images; + info.has_volume_decoupled &= device.has_volume_decoupled; + info.has_osl &= device.has_osl; + info.has_profiling &= device.has_profiling; + } + + return info; } void Device::tag_update() { - free_memory(); + free_memory(); } void Device::free_memory() { - devices_initialized_mask = 0; - cuda_devices.free_memory(); - opencl_devices.free_memory(); - cpu_devices.free_memory(); - network_devices.free_memory(); + devices_initialized_mask = 0; + cuda_devices.free_memory(); + opencl_devices.free_memory(); + cpu_devices.free_memory(); + network_devices.free_memory(); } CCL_NAMESPACE_END |