Cycles: merge of changes from tomato branch.
Regular rendering now works tiled, and supports save buffers to save memory during render and cache render results. Brick texture node by Thomas. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Brick_Texture Image texture Blended Box Mapping. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Image_Texture http://mango.blender.org/production/blended_box/ Various bug fixes by Sergey and Campbell. * Fix for reading freed memory in some node setups. * Fix incorrect memory read when synchronizing mesh motion. * Fix crash appearing when direct light usage is different on different layers. * Fix for vector pass gives wrong result in some circumstances. * Fix for wrong resolution used for rendering Render Layer node. * Option to cancel rendering when doing initial synchronization. * No more texture limit when using CPU render. * Many fixes for new tiled rendering.
This commit is contained in:
@@ -19,14 +19,16 @@
|
||||
#include "tile.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
TileManager::TileManager(bool progressive_, int samples_, int tile_size_, int min_size_)
|
||||
TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int resolution_, int num_devices_)
|
||||
{
|
||||
progressive = progressive_;
|
||||
tile_size = tile_size_;
|
||||
min_size = min_size_;
|
||||
resolution = resolution_;
|
||||
num_devices = num_devices_;
|
||||
|
||||
BufferParams buffer_params;
|
||||
reset(buffer_params, 0);
|
||||
@@ -36,34 +38,24 @@ TileManager::~TileManager()
|
||||
{
|
||||
}
|
||||
|
||||
void TileManager::reset(BufferParams& params_, int samples_)
|
||||
void TileManager::reset(BufferParams& params_, int num_samples_)
|
||||
{
|
||||
params = params_;
|
||||
|
||||
start_resolution = 1;
|
||||
|
||||
int w = params.width, h = params.height;
|
||||
|
||||
if(min_size != INT_MAX) {
|
||||
while(w*h > min_size*min_size) {
|
||||
w = max(1, w/2);
|
||||
h = max(1, h/2);
|
||||
|
||||
start_resolution *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
samples = samples_;
|
||||
num_samples = num_samples_;
|
||||
|
||||
state.buffer = BufferParams();
|
||||
state.sample = -1;
|
||||
state.resolution = start_resolution;
|
||||
state.num_tiles = 0;
|
||||
state.num_rendered_tiles = 0;
|
||||
state.num_samples = 0;
|
||||
state.resolution = resolution;
|
||||
state.tiles.clear();
|
||||
}
|
||||
|
||||
void TileManager::set_samples(int samples_)
|
||||
void TileManager::set_samples(int num_samples_)
|
||||
{
|
||||
samples = samples_;
|
||||
num_samples = num_samples_;
|
||||
}
|
||||
|
||||
void TileManager::set_tiles()
|
||||
@@ -71,24 +63,34 @@ void TileManager::set_tiles()
|
||||
int resolution = state.resolution;
|
||||
int image_w = max(1, params.width/resolution);
|
||||
int image_h = max(1, params.height/resolution);
|
||||
int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size;
|
||||
int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size;
|
||||
int sub_w = image_w/tile_w;
|
||||
int sub_h = image_h/tile_h;
|
||||
|
||||
state.tiles.clear();
|
||||
|
||||
for(int tile_y = 0; tile_y < tile_h; tile_y++) {
|
||||
for(int tile_x = 0; tile_x < tile_w; tile_x++) {
|
||||
int x = tile_x * sub_w;
|
||||
int y = tile_y * sub_h;
|
||||
int w = (tile_x == tile_w-1)? image_w - x: sub_w;
|
||||
int h = (tile_y == tile_h-1)? image_h - y: sub_h;
|
||||
int num = min(image_h, num_devices);
|
||||
|
||||
state.tiles.push_back(Tile(x, y, w, h));
|
||||
for(int device = 0; device < num; device++) {
|
||||
int device_y = (image_h/num)*device;
|
||||
int device_h = (device == num-1)? image_h - device*(image_h/num): image_h/num;
|
||||
|
||||
int tile_w = (tile_size.x >= image_w)? 1: (image_w + tile_size.x - 1)/tile_size.x;
|
||||
int tile_h = (tile_size.y >= device_h)? 1: (device_h + tile_size.y - 1)/tile_size.y;
|
||||
int sub_w = (image_w + tile_w - 1)/tile_w;
|
||||
int sub_h = (device_h + tile_h - 1)/tile_h;
|
||||
|
||||
for(int tile_y = 0; tile_y < tile_h; tile_y++) {
|
||||
for(int tile_x = 0; tile_x < tile_w; tile_x++) {
|
||||
int x = tile_x * sub_w;
|
||||
int y = tile_y * sub_h;
|
||||
int w = (tile_x == tile_w-1)? image_w - x: sub_w;
|
||||
int h = (tile_y == tile_h-1)? device_h - y: sub_h;
|
||||
|
||||
state.tiles.push_back(Tile(x, y + device_y, w, h, device));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.num_tiles = state.tiles.size();
|
||||
|
||||
state.buffer.width = image_w;
|
||||
state.buffer.height = image_h;
|
||||
|
||||
@@ -98,9 +100,74 @@ void TileManager::set_tiles()
|
||||
state.buffer.full_height = max(1, params.full_height/resolution);
|
||||
}
|
||||
|
||||
list<Tile>::iterator TileManager::next_center_tile(int device)
|
||||
{
|
||||
list<Tile>::iterator iter, best = state.tiles.end();
|
||||
|
||||
int resolution = state.resolution;
|
||||
int image_w = max(1, params.width/resolution);
|
||||
int image_h = max(1, params.height/resolution);
|
||||
|
||||
int num = min(image_h, num_devices);
|
||||
|
||||
int device_y = (image_h / num) * device;
|
||||
int device_h = (device == num - 1) ? image_h - device * (image_h / num) : image_h / num;
|
||||
|
||||
int64_t centx = image_w / 2, centy = device_y + device_h / 2, tot = 1;
|
||||
int64_t mindist = (int64_t) image_w * (int64_t) device_h;
|
||||
|
||||
/* find center of rendering tiles, image center counts for 1 too */
|
||||
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
|
||||
if(iter->rendering) {
|
||||
Tile &cur_tile = *iter;
|
||||
centx += cur_tile.x + cur_tile.w / 2;
|
||||
centy += cur_tile.y + cur_tile.h / 2;
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
centx /= tot;
|
||||
centy /= tot;
|
||||
|
||||
/* closest of the non-rendering tiles */
|
||||
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
|
||||
if(iter->device == device && iter->rendering == false) {
|
||||
Tile &cur_tile = *iter;
|
||||
|
||||
int64_t distx = centx - (cur_tile.x + cur_tile.w / 2);
|
||||
int64_t disty = centy - (cur_tile.y + cur_tile.h / 2);
|
||||
distx = (int64_t) sqrt((double)distx * distx + disty * disty);
|
||||
|
||||
if(distx < mindist) {
|
||||
best = iter;
|
||||
mindist = distx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
bool TileManager::next_tile(Tile& tile, int device)
|
||||
{
|
||||
list<Tile>::iterator tile_it;
|
||||
|
||||
tile_it = next_center_tile(device);
|
||||
|
||||
if(tile_it != state.tiles.end()) {
|
||||
tile_it->rendering = true;
|
||||
tile = *tile_it;
|
||||
state.num_rendered_tiles++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TileManager::done()
|
||||
{
|
||||
return (state.sample+1 >= samples && state.resolution == 1);
|
||||
return (state.sample+state.num_samples >= num_samples && state.resolution == 1);
|
||||
}
|
||||
|
||||
bool TileManager::next()
|
||||
@@ -111,10 +178,17 @@ bool TileManager::next()
|
||||
if(progressive && state.resolution > 1) {
|
||||
state.sample = 0;
|
||||
state.resolution /= 2;
|
||||
state.num_samples = 1;
|
||||
set_tiles();
|
||||
}
|
||||
else {
|
||||
state.sample++;
|
||||
|
||||
if(progressive)
|
||||
state.num_samples = 1;
|
||||
else
|
||||
state.num_samples = num_samples;
|
||||
|
||||
state.resolution = 1;
|
||||
set_tiles();
|
||||
}
|
||||
|
Reference in New Issue
Block a user