diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2014-08-01 03:04:57 +0400 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2014-08-15 13:27:42 +0400 |
commit | 983cbafd1877f8dbaae60b064a14e27b5b640f18 (patch) | |
tree | 9cc7ba3db147c465f41d34b971f69c25e04a12be /intern | |
parent | 2c5b6859d91f086f3f7205f0cc15244882ca7ace (diff) |
Final Fix T41222 Blender gives weird ouput when baking (4096*4096) resolution on GPU
It now uses the tile size to split the job. For CPU this may add
overhead, but for GPU this is highly needed.
Reviewers: sergey
Differential Revision: https://developer.blender.org/D690
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/render/bake.cpp | 125 | ||||
-rw-r--r-- | intern/cycles/render/bake.h | 3 |
3 files changed, 79 insertions, 50 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 7e104d5bb41..3e84110c335 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -529,6 +529,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); + scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); scene->bake_manager->set_baking(true); /* set number of samples */ diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index d7da63dea8a..caf72089d68 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -95,6 +95,7 @@ BakeManager::BakeManager() m_bake_data = NULL; m_is_baking = false; need_update = true; + m_shader_limit = 512 * 512; } BakeManager::~BakeManager() @@ -119,74 +120,98 @@ BakeData *BakeManager::init(const int object, const size_t tri_offset, const siz return m_bake_data; } +void BakeManager::set_shader_limit(const size_t x, const size_t y) +{ + m_shader_limit = x * y; + m_shader_limit = pow(2, ceil(log(m_shader_limit)/log(2))); +} + bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]) { - size_t limit = bake_data->size(); + size_t num_pixels = bake_data->size(); - /* setup input for device task */ - device_vector<uint4> d_input; - uint4 *d_input_data = d_input.resize(limit * 2); - size_t d_input_size = 0; + progress.reset_sample(); + this->num_parts = 0; - for(size_t i = 0; i < limit; i++) { - d_input_data[d_input_size++] = bake_data->data(i); - d_input_data[d_input_size++] = bake_data->differentials(i); - } + /* calculate the total parts for the progress bar */ + for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) { + size_t shader_size = fminf(num_pixels - shader_offset, m_shader_limit); - if(d_input_size == 0) - return false; + DeviceTask task(DeviceTask::SHADER); + task.shader_w = shader_size; - /* run device task */ - device_vector<float4> d_output; - d_output.resize(limit); + this->num_parts += device->get_split_task_count(task); + } - /* needs to be up to data for attribute access */ - device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); + this->num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples : 1; - device->mem_alloc(d_input, MEM_READ_ONLY); - device->mem_copy_to(d_input); - device->mem_alloc(d_output, MEM_WRITE_ONLY); + for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) { + size_t shader_size = fminf(num_pixels - shader_offset, m_shader_limit); - DeviceTask task(DeviceTask::SHADER); - task.shader_input = d_input.device_pointer; - task.shader_output = d_output.device_pointer; - task.shader_eval_type = shader_type; - task.shader_x = 0; - task.shader_w = d_output.size(); - task.num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples: 1; - task.get_cancel = function_bind(&Progress::get_cancel, &progress); - task.update_progress_sample = function_bind(&Progress::increment_sample_update, &progress); + /* setup input for device task */ + device_vector<uint4> d_input; + uint4 *d_input_data = d_input.resize(shader_size * 2); + size_t d_input_size = 0; - this->num_parts = device->get_split_task_count(task); - this->num_samples = task.num_samples; + for(size_t i = shader_offset; i < (shader_offset + shader_size); i++) { + d_input_data[d_input_size++] = bake_data->data(i); + d_input_data[d_input_size++] = bake_data->differentials(i); + } - device->task_add(task); - device->task_wait(); + if(d_input_size == 0) { + m_is_baking = false; + return false; + } + + /* run device task */ + device_vector<float4> d_output; + d_output.resize(shader_size); + + /* needs to be up to data for attribute access */ + device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); + + device->mem_alloc(d_input, MEM_READ_ONLY); + device->mem_copy_to(d_input); + device->mem_alloc(d_output, MEM_WRITE_ONLY); + + DeviceTask task(DeviceTask::SHADER); + task.shader_input = d_input.device_pointer; + task.shader_output = d_output.device_pointer; + task.shader_eval_type = shader_type; + task.shader_x = 0; + task.shader_w = d_output.size(); + task.num_samples = this->num_samples; + task.get_cancel = function_bind(&Progress::get_cancel, &progress); + task.update_progress_sample = function_bind(&Progress::increment_sample_update, &progress); + + device->task_add(task); + device->task_wait(); + + if(progress.get_cancel()) { + device->mem_free(d_input); + device->mem_free(d_output); + m_is_baking = false; + return false; + } - if(progress.get_cancel()) { + device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); device->mem_free(d_input); device->mem_free(d_output); - m_is_baking = false; - return false; - } - - device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); - device->mem_free(d_input); - device->mem_free(d_output); - /* read result */ - int k = 0; + /* read result */ + int k = 0; - float4 *offset = (float4*)d_output.data_pointer; + float4 *offset = (float4*)d_output.data_pointer; - size_t depth = 4; - for(size_t i = 0; i < limit; i++) { - size_t index = i * depth; - float4 out = offset[k++]; + size_t depth = 4; + for(size_t i=shader_offset; i < (shader_offset + shader_size); i++) { + size_t index = i * depth; + float4 out = offset[k++]; - if(bake_data->is_valid(i)) { - for(size_t j=0; j < 4; j++) { - result[index + j] = out[j]; + if(bake_data->is_valid(i)) { + for(size_t j=0; j < 4; j++) { + result[index + j] = out[j]; + } } } } diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h index 652420c2e19..186fbbeea4d 100644 --- a/intern/cycles/render/bake.h +++ b/intern/cycles/render/bake.h @@ -60,6 +60,8 @@ public: BakeData *init(const int object, const size_t tri_offset, const size_t num_pixels); + void set_shader_limit(const size_t x, const size_t y); + bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]); void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); @@ -76,6 +78,7 @@ public: private: BakeData *m_bake_data; bool m_is_baking; + size_t m_shader_limit; }; CCL_NAMESPACE_END |