Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/buffers.cpp
| Show All 13 Lines | |||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include "device/device.h" | #include "device/device.h" | ||||
| #include "render/buffers.h" | #include "render/buffers.h" | ||||
| #include "kernel/filter/filter_defines.h" | |||||
| #include "util/util_foreach.h" | #include "util/util_foreach.h" | ||||
| #include "util/util_hash.h" | #include "util/util_hash.h" | ||||
| #include "util/util_math.h" | #include "util/util_math.h" | ||||
| #include "util/util_opengl.h" | #include "util/util_opengl.h" | ||||
| #include "util/util_time.h" | #include "util/util_time.h" | ||||
| #include "util/util_types.h" | #include "util/util_types.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| Show All 20 Lines | |||||
| void BufferParams::get_offset_stride(int &offset, int &stride) | void BufferParams::get_offset_stride(int &offset, int &stride) | ||||
| { | { | ||||
| offset = -(full_x + full_y * width); | offset = -(full_x + full_y * width); | ||||
| stride = width; | stride = width; | ||||
| } | } | ||||
| bool BufferParams::modified(const BufferParams ¶ms) | bool BufferParams::modified(const BufferParams ¶ms) | ||||
| { | { | ||||
| return !(full_x == params.full_x && full_y == params.full_y && width == params.width && | return !(full_x == params.get_full_x() && full_y == params.get_full_y() && | ||||
| height == params.height && full_width == params.full_width && | width == params.get_width() && height == params.get_height() && | ||||
| full_height == params.full_height && Pass::equals(passes, params.passes) && | full_width == params.get_full_width() && full_height == params.get_full_height() && | ||||
| denoising_data_pass == params.denoising_data_pass && | Pass::equals(passes, params.get_passes()) && | ||||
| denoising_clean_pass == params.denoising_clean_pass && | denoising_data_pass == params.get_denoising_data_pass() && | ||||
| denoising_prefiltered_pass == params.denoising_prefiltered_pass); | denoising_clean_pass == params.get_denoising_clean_pass() && | ||||
| denoising_prefiltered_pass == params.get_denoising_prefiltered_pass()); | |||||
| } | } | ||||
| int BufferParams::get_passes_size() | int BufferParams::get_passes_size() | ||||
| { | { | ||||
| int size = 0; | int size = 0; | ||||
| for (size_t i = 0; i < passes.size(); i++) | for (size_t i = 0; i < passes.size(); i++) | ||||
| size += passes[i].components; | size += passes[i].get_components(); | ||||
| if (denoising_data_pass) { | if (denoising_data_pass) { | ||||
| size += DENOISING_PASS_SIZE_BASE; | size += DENOISING_PASS_SIZE_BASE; | ||||
| if (denoising_clean_pass) | if (denoising_clean_pass) | ||||
| size += DENOISING_PASS_SIZE_CLEAN; | size += DENOISING_PASS_SIZE_CLEAN; | ||||
| if (denoising_prefiltered_pass) | if (denoising_prefiltered_pass) | ||||
| size += DENOISING_PASS_SIZE_PREFILTERED; | size += DENOISING_PASS_SIZE_PREFILTERED; | ||||
| } | } | ||||
| return align_up(size, 4); | return align_up(size, 4); | ||||
| } | } | ||||
| int BufferParams::get_denoising_offset() | int BufferParams::get_denoising_offset() | ||||
| { | { | ||||
| int offset = 0; | int offset = 0; | ||||
| for (size_t i = 0; i < passes.size(); i++) | for (size_t i = 0; i < passes.size(); i++) | ||||
| offset += passes[i].components; | offset += passes[i].get_components(); | ||||
| return offset; | return offset; | ||||
| } | } | ||||
| int BufferParams::get_denoising_prefiltered_offset() | int BufferParams::get_denoising_prefiltered_offset() | ||||
| { | { | ||||
| assert(denoising_prefiltered_pass); | assert(denoising_prefiltered_pass); | ||||
| Show All 25 Lines | RenderTile::RenderTile() | ||||
| stride = 0; | stride = 0; | ||||
| buffer = 0; | buffer = 0; | ||||
| buffers = NULL; | buffers = NULL; | ||||
| stealing_state = NO_STEALING; | stealing_state = NO_STEALING; | ||||
| } | } | ||||
| WorkTile RenderTile::work_tile() const | |||||
| { | |||||
| WorkTile wtile; | |||||
| wtile.x = x; | |||||
| wtile.y = y; | |||||
| wtile.w = w; | |||||
| wtile.h = h; | |||||
| wtile.offset = offset; | |||||
| wtile.stride = stride; | |||||
| wtile.buffer = (float *)buffer; | |||||
| return wtile; | |||||
| } | |||||
| RenderTile RenderTile::from_device_task(const DeviceTask &task, bool set_sample) | |||||
| { | |||||
| RenderTile tile; | |||||
| tile.x = task.x; | |||||
| tile.y = task.y; | |||||
| tile.w = task.w; | |||||
| tile.h = task.h; | |||||
| tile.buffer = task.buffer; | |||||
| tile.num_samples = task.num_samples; | |||||
| tile.start_sample = task.sample; | |||||
| tile.offset = task.offset; | |||||
| tile.stride = task.stride; | |||||
| tile.buffers = task.buffers; | |||||
| /* sample is not set in OptiX denoising */ | |||||
| if (set_sample) { | |||||
| tile.sample = task.sample + task.num_samples; | |||||
| } | |||||
| return tile; | |||||
| } | |||||
| /* Render Buffers */ | /* Render Buffers */ | ||||
| RenderBuffers::RenderBuffers(Device *device) | RenderBuffers::RenderBuffers(Device *device) | ||||
| : buffer(device, "RenderBuffers", MEM_READ_WRITE), | : buffer(device, "RenderBuffers", MEM_READ_WRITE), | ||||
| map_neighbor_copied(false), | map_neighbor_copied(false), | ||||
| render_time(0.0f) | render_time(0.0f) | ||||
| { | { | ||||
| } | } | ||||
| RenderBuffers::~RenderBuffers() | RenderBuffers::~RenderBuffers() | ||||
| { | { | ||||
| buffer.free(); | buffer.free(); | ||||
| } | } | ||||
| void RenderBuffers::reset(BufferParams ¶ms_) | void RenderBuffers::reset(BufferParams ¶ms_) | ||||
| { | { | ||||
| params = params_; | params = params_; | ||||
| /* re-allocate buffer */ | /* re-allocate buffer */ | ||||
| buffer.alloc(params.width * params.get_passes_size(), params.height); | buffer.alloc(params.get_width() * params.get_passes_size(), params.get_height()); | ||||
| buffer.zero_to_device(); | buffer.zero_to_device(); | ||||
| } | } | ||||
| void RenderBuffers::zero() | void RenderBuffers::zero() | ||||
| { | { | ||||
| buffer.zero_to_device(); | buffer.zero_to_device(); | ||||
| } | } | ||||
| bool RenderBuffers::copy_from_device() | bool RenderBuffers::copy_from_device() | ||||
| { | { | ||||
| if (!buffer.device_pointer) | if (!buffer.device_pointer) | ||||
| return false; | return false; | ||||
| buffer.copy_from_device(0, params.width * params.get_passes_size(), params.height); | buffer.copy_from_device(0, params.get_width() * params.get_passes_size(), params.get_height()); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool RenderBuffers::get_denoising_pass_rect( | bool RenderBuffers::get_denoising_pass_rect( | ||||
| int type, float exposure, int sample, int components, float *pixels) | int type, float exposure, int sample, int components, float *pixels) | ||||
| { | { | ||||
| if (buffer.data() == NULL) { | if (buffer.data() == NULL) { | ||||
| Show All 11 Lines | bool RenderBuffers::get_denoising_pass_rect( | ||||
| } | } | ||||
| int offset; | int offset; | ||||
| if (type == DENOISING_PASS_CLEAN) { | if (type == DENOISING_PASS_CLEAN) { | ||||
| /* The clean pass isn't changed by prefiltering, so we use the original one there. */ | /* The clean pass isn't changed by prefiltering, so we use the original one there. */ | ||||
| offset = type + params.get_denoising_offset(); | offset = type + params.get_denoising_offset(); | ||||
| scale /= sample; | scale /= sample; | ||||
| } | } | ||||
| else if (params.denoising_prefiltered_pass) { | else if (params.get_denoising_prefiltered_pass()) { | ||||
| offset = type + params.get_denoising_prefiltered_offset(); | offset = type + params.get_denoising_prefiltered_offset(); | ||||
| } | } | ||||
| else { | else { | ||||
| switch (type) { | switch (type) { | ||||
| case DENOISING_PASS_PREFILTERED_DEPTH: | case DENOISING_PASS_PREFILTERED_DEPTH: | ||||
| offset = params.get_denoising_offset() + DENOISING_PASS_DEPTH; | offset = params.get_denoising_offset() + DENOISING_PASS_DEPTH; | ||||
| break; | break; | ||||
| case DENOISING_PASS_PREFILTERED_NORMAL: | case DENOISING_PASS_PREFILTERED_NORMAL: | ||||
| offset = params.get_denoising_offset() + DENOISING_PASS_NORMAL; | offset = params.get_denoising_offset() + DENOISING_PASS_NORMAL; | ||||
| break; | break; | ||||
| case DENOISING_PASS_PREFILTERED_ALBEDO: | case DENOISING_PASS_PREFILTERED_ALBEDO: | ||||
| offset = params.get_denoising_offset() + DENOISING_PASS_ALBEDO; | offset = params.get_denoising_offset() + DENOISING_PASS_ALBEDO; | ||||
| break; | break; | ||||
| case DENOISING_PASS_PREFILTERED_COLOR: | case DENOISING_PASS_PREFILTERED_COLOR: | ||||
| /* If we're not saving the prefiltering result, return the original noisy pass. */ | /* If we're not saving the prefiltering result, return the original noisy pass. */ | ||||
| offset = params.get_denoising_offset() + DENOISING_PASS_COLOR; | offset = params.get_denoising_offset() + DENOISING_PASS_COLOR; | ||||
| break; | break; | ||||
| default: | default: | ||||
| return false; | return false; | ||||
| } | } | ||||
| scale /= sample; | scale /= sample; | ||||
| } | } | ||||
| int pass_stride = params.get_passes_size(); | int pass_stride = params.get_passes_size(); | ||||
| int size = params.width * params.height; | int size = params.get_width() * params.get_height(); | ||||
| float *in = buffer.data() + offset; | float *in = buffer.data() + offset; | ||||
| if (components == 1) { | if (components == 1) { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | ||||
| pixels[0] = in[0] * scale; | pixels[0] = in[0] * scale; | ||||
| } | } | ||||
| } | } | ||||
| else if (components == 3) { | else if (components == 3) { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) { | for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) { | ||||
| pixels[0] = in[0] * scale; | pixels[0] = in[0] * scale; | ||||
| pixels[1] = in[1] * scale; | pixels[1] = in[1] * scale; | ||||
| pixels[2] = in[2] * scale; | pixels[2] = in[2] * scale; | ||||
| } | } | ||||
| } | } | ||||
| else if (components == 4) { | else if (components == 4) { | ||||
| /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */ | /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */ | ||||
| assert(params.passes[0].type == PASS_COMBINED); | assert(params.get_passes()[0].get_pass_type() == PASS_COMBINED); | ||||
| float *in_combined = buffer.data(); | float *in_combined = buffer.data(); | ||||
| for (int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) { | for (int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) { | ||||
| float3 val = make_float3(in[0], in[1], in[2]); | float3 val = make_float3(in[0], in[1], in[2]); | ||||
| if (type == DENOISING_PASS_PREFILTERED_COLOR && params.denoising_prefiltered_pass) { | if (type == DENOISING_PASS_PREFILTERED_COLOR && params.get_denoising_prefiltered_pass()) { | ||||
| /* Remove highlight compression from the image. */ | /* Remove highlight compression from the image. */ | ||||
| val = color_highlight_uncompress(val); | val = color_highlight_uncompress(val); | ||||
| } | } | ||||
| pixels[0] = val.x * scale; | pixels[0] = val.x * scale; | ||||
| pixels[1] = val.y * scale; | pixels[1] = val.y * scale; | ||||
| pixels[2] = val.z * scale; | pixels[2] = val.z * scale; | ||||
| pixels[3] = saturate(in_combined[3] * alpha_scale); | pixels[3] = saturate(in_combined[3] * alpha_scale); | ||||
| } | } | ||||
| Show All 10 Lines | |||||
| { | { | ||||
| if (buffer.data() == NULL) { | if (buffer.data() == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| float *sample_count = NULL; | float *sample_count = NULL; | ||||
| if (name == "Combined") { | if (name == "Combined") { | ||||
| int sample_offset = 0; | int sample_offset = 0; | ||||
| for (size_t j = 0; j < params.passes.size(); j++) { | for (size_t j = 0; j < params.get_passes().size(); j++) { | ||||
| Pass &pass = params.passes[j]; | Pass &pass = params.get_passes()[j]; | ||||
| if (pass.type != PASS_SAMPLE_COUNT) { | if (pass.get_pass_type() != PASS_SAMPLE_COUNT) { | ||||
| sample_offset += pass.components; | sample_offset += pass.get_components(); | ||||
| continue; | continue; | ||||
| } | } | ||||
| else { | else { | ||||
| sample_count = buffer.data() + sample_offset; | sample_count = buffer.data() + sample_offset; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| int pass_offset = 0; | int pass_offset = 0; | ||||
| for (size_t j = 0; j < params.passes.size(); j++) { | for (size_t j = 0; j < params.get_passes().size(); j++) { | ||||
| Pass &pass = params.passes[j]; | Pass &pass = params.get_passes()[j]; | ||||
| /* Pass is identified by both type and name, multiple of the same type | /* Pass is identified by both type and name, multiple of the same type | ||||
| * may exist with a different name. */ | * may exist with a different name. */ | ||||
| if (pass.name != name) { | if (pass.get_name() != name) { | ||||
| pass_offset += pass.components; | pass_offset += pass.get_components(); | ||||
| continue; | continue; | ||||
| } | } | ||||
| PassType type = pass.type; | PassType type = pass.get_pass_type(); | ||||
| float *in = buffer.data() + pass_offset; | float *in = buffer.data() + pass_offset; | ||||
| int pass_stride = params.get_passes_size(); | int pass_stride = params.get_passes_size(); | ||||
| float scale = (pass.filter) ? 1.0f / (float)sample : 1.0f; | float scale = (pass.get_filter()) ? 1.0f / (float)sample : 1.0f; | ||||
| float scale_exposure = (pass.exposure) ? scale * exposure : scale; | float scale_exposure = (pass.get_exposure()) ? scale * exposure : scale; | ||||
| int size = params.width * params.height; | int size = params.get_width() * params.get_height(); | ||||
| if (components == 1 && type == PASS_RENDER_TIME) { | if (components == 1 && type == PASS_RENDER_TIME) { | ||||
| /* Render time is not stored by kernel, but measured per tile. */ | /* Render time is not stored by kernel, but measured per tile. */ | ||||
| float val = (float)(1000.0 * render_time / (params.width * params.height * sample)); | float val = (float)(1000.0 * render_time / | ||||
| (params.get_width() * params.get_height() * sample)); | |||||
| for (int i = 0; i < size; i++, pixels++) { | for (int i = 0; i < size; i++, pixels++) { | ||||
| pixels[0] = val; | pixels[0] = val; | ||||
| } | } | ||||
| } | } | ||||
| else if (components == 1) { | else if (components == 1) { | ||||
| assert(pass.components == components); | assert(pass.get_components() == components); | ||||
| /* Scalar */ | /* Scalar */ | ||||
| if (type == PASS_DEPTH) { | if (type == PASS_DEPTH) { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | ||||
| float f = *in; | float f = *in; | ||||
| pixels[0] = (f == 0.0f) ? 1e10f : f * scale_exposure; | pixels[0] = (f == 0.0f) ? 1e10f : f * scale_exposure; | ||||
| } | } | ||||
| } | } | ||||
| Show All 15 Lines | #endif | ||||
| else { | else { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | for (int i = 0; i < size; i++, in += pass_stride, pixels++) { | ||||
| float f = *in; | float f = *in; | ||||
| pixels[0] = f * scale_exposure; | pixels[0] = f * scale_exposure; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (components == 3) { | else if (components == 3) { | ||||
| assert(pass.components == 4); | assert(pass.get_components() == 4); | ||||
| /* RGBA */ | /* RGBA */ | ||||
| if (type == PASS_SHADOW) { | if (type == PASS_SHADOW) { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) { | for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) { | ||||
| float4 f = make_float4(in[0], in[1], in[2], in[3]); | float4 f = make_float4(in[0], in[1], in[2], in[3]); | ||||
| float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f; | float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f; | ||||
| pixels[0] = f.x * invw; | pixels[0] = f.x * invw; | ||||
| pixels[1] = f.y * invw; | pixels[1] = f.y * invw; | ||||
| pixels[2] = f.z * invw; | pixels[2] = f.z * invw; | ||||
| } | } | ||||
| } | } | ||||
| else if (pass.divide_type != PASS_NONE) { | else if (pass.get_divide_type() != PASS_NONE) { | ||||
| /* RGB lighting passes that need to divide out color */ | /* RGB lighting passes that need to divide out color */ | ||||
| pass_offset = 0; | pass_offset = 0; | ||||
| for (size_t k = 0; k < params.passes.size(); k++) { | foreach (Pass &color_pass, params.get_passes()) { | ||||
| Pass &color_pass = params.passes[k]; | if (color_pass.get_pass_type() == pass.get_divide_type()) | ||||
| if (color_pass.type == pass.divide_type) | |||||
| break; | break; | ||||
| pass_offset += color_pass.components; | pass_offset += color_pass.get_components(); | ||||
| } | } | ||||
| float *in_divide = buffer.data() + pass_offset; | float *in_divide = buffer.data() + pass_offset; | ||||
| for (int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) { | for (int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) { | ||||
| float3 f = make_float3(in[0], in[1], in[2]); | float3 f = make_float3(in[0], in[1], in[2]); | ||||
| float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]); | float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]); | ||||
| Show All 11 Lines | else if (components == 3) { | ||||
| pixels[0] = f.x * scale_exposure; | pixels[0] = f.x * scale_exposure; | ||||
| pixels[1] = f.y * scale_exposure; | pixels[1] = f.y * scale_exposure; | ||||
| pixels[2] = f.z * scale_exposure; | pixels[2] = f.z * scale_exposure; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (components == 4) { | else if (components == 4) { | ||||
| assert(pass.components == components); | assert(pass.get_components() == components); | ||||
| /* RGBA */ | /* RGBA */ | ||||
| if (type == PASS_SHADOW) { | if (type == PASS_SHADOW) { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) { | for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) { | ||||
| float4 f = make_float4(in[0], in[1], in[2], in[3]); | float4 f = make_float4(in[0], in[1], in[2], in[3]); | ||||
| float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f; | float invw = (f.w > 0.0f) ? 1.0f / f.w : 1.0f; | ||||
| pixels[0] = f.x * invw; | pixels[0] = f.x * invw; | ||||
| pixels[1] = f.y * invw; | pixels[1] = f.y * invw; | ||||
| pixels[2] = f.z * invw; | pixels[2] = f.z * invw; | ||||
| pixels[3] = 1.0f; | pixels[3] = 1.0f; | ||||
| } | } | ||||
| } | } | ||||
| else if (type == PASS_MOTION) { | else if (type == PASS_MOTION) { | ||||
| /* need to normalize by number of samples accumulated for motion */ | /* need to normalize by number of samples accumulated for motion */ | ||||
| pass_offset = 0; | pass_offset = 0; | ||||
| for (size_t k = 0; k < params.passes.size(); k++) { | foreach (Pass &color_pass, params.get_passes()) { | ||||
| Pass &color_pass = params.passes[k]; | if (color_pass.get_pass_type() == PASS_MOTION_WEIGHT) | ||||
| if (color_pass.type == PASS_MOTION_WEIGHT) | |||||
| break; | break; | ||||
| pass_offset += color_pass.components; | pass_offset += color_pass.get_components(); | ||||
| } | } | ||||
| float *in_weight = buffer.data() + pass_offset; | float *in_weight = buffer.data() + pass_offset; | ||||
| for (int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) { | for (int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) { | ||||
| float4 f = make_float4(in[0], in[1], in[2], in[3]); | float4 f = make_float4(in[0], in[1], in[2], in[3]); | ||||
| float w = in_weight[0]; | float w = in_weight[0]; | ||||
| float invw = (w > 0.0f) ? 1.0f / w : 0.0f; | float invw = (w > 0.0f) ? 1.0f / w : 0.0f; | ||||
| Show All 13 Lines | else if (components == 4) { | ||||
| pixels[1] = f.y * scale; | pixels[1] = f.y * scale; | ||||
| pixels[2] = f.z; | pixels[2] = f.z; | ||||
| pixels[3] = f.w * scale; | pixels[3] = f.w * scale; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) { | for (int i = 0; i < size; i++, in += pass_stride, pixels += 4) { | ||||
| if (sample_count && sample_count[i * pass_stride] < 0.0f) { | if (sample_count && sample_count[i * pass_stride] < 0.0f) { | ||||
| scale = (pass.filter) ? -1.0f / (sample_count[i * pass_stride]) : 1.0f; | scale = (pass.get_filter()) ? -1.0f / (sample_count[i * pass_stride]) : 1.0f; | ||||
| scale_exposure = (pass.exposure) ? scale * exposure : scale; | scale_exposure = (pass.get_exposure()) ? scale * exposure : scale; | ||||
| } | } | ||||
| float4 f = make_float4(in[0], in[1], in[2], in[3]); | float4 f = make_float4(in[0], in[1], in[2], in[3]); | ||||
| pixels[0] = f.x * scale_exposure; | pixels[0] = f.x * scale_exposure; | ||||
| pixels[1] = f.y * scale_exposure; | pixels[1] = f.y * scale_exposure; | ||||
| pixels[2] = f.z * scale_exposure; | pixels[2] = f.z * scale_exposure; | ||||
| Show All 12 Lines | |||||
| bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels, int samples) | bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels, int samples) | ||||
| { | { | ||||
| if (buffer.data() == NULL) { | if (buffer.data() == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| int pass_offset = 0; | int pass_offset = 0; | ||||
| for (size_t j = 0; j < params.passes.size(); j++) { | foreach (Pass &pass, params.get_passes()) { | ||||
| Pass &pass = params.passes[j]; | if (pass.get_pass_type() != type) { | ||||
| pass_offset += pass.get_components(); | |||||
| if (pass.type != type) { | |||||
| pass_offset += pass.components; | |||||
| continue; | continue; | ||||
| } | } | ||||
| float *out = buffer.data() + pass_offset; | float *out = buffer.data() + pass_offset; | ||||
| int pass_stride = params.get_passes_size(); | int pass_stride = params.get_passes_size(); | ||||
| int size = params.width * params.height; | int size = params.get_width() * params.get_height(); | ||||
| assert(pass.components == components); | assert(pass.get_components() == components); | ||||
| for (int i = 0; i < size; i++, out += pass_stride, pixels += components) { | for (int i = 0; i < size; i++, out += pass_stride, pixels += components) { | ||||
| if (pass.filter) { | if (pass.get_filter()) { | ||||
| /* Scale by the number of samples, inverse of what we do in get_pass_rect. | /* Scale by the number of samples, inverse of what we do in get_pass_rect. | ||||
| * A better solution would be to remove the need for set_pass_rect entirely, | * A better solution would be to remove the need for set_pass_rect entirely, | ||||
| * and change baking to bake multiple objects in a tile at once. */ | * and change baking to bake multiple objects in a tile at once. */ | ||||
| for (int j = 0; j < components; j++) { | for (int j = 0; j < components; j++) { | ||||
| out[j] = pixels[j] * samples; | out[j] = pixels[j] * samples; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 30 Lines | |||||
| { | { | ||||
| draw_width = 0; | draw_width = 0; | ||||
| draw_height = 0; | draw_height = 0; | ||||
| params = params_; | params = params_; | ||||
| /* allocate display pixels */ | /* allocate display pixels */ | ||||
| if (half_float) { | if (half_float) { | ||||
| rgba_half.alloc_to_device(params.width, params.height); | rgba_half.alloc_to_device(params.get_width(), params.get_height()); | ||||
| } | } | ||||
| else { | else { | ||||
| rgba_byte.alloc_to_device(params.width, params.height); | rgba_byte.alloc_to_device(params.get_width(), params.get_height()); | ||||
| } | } | ||||
| } | } | ||||
| void DisplayBuffer::draw_set(int width, int height) | void DisplayBuffer::draw_set(int width, int height) | ||||
| { | { | ||||
| assert(width <= params.width && height <= params.height); | assert(width <= params.get_width() && height <= params.get_height()); | ||||
| draw_width = width; | draw_width = width; | ||||
| draw_height = height; | draw_height = height; | ||||
| } | } | ||||
| void DisplayBuffer::draw(Device *device, const DeviceDrawParams &draw_params) | void DisplayBuffer::draw(Device *device, const DeviceDrawParams &draw_params) | ||||
| { | { | ||||
| if (draw_width != 0 && draw_height != 0) { | if (draw_width != 0 && draw_height != 0) { | ||||
| device_memory &rgba = (half_float) ? (device_memory &)rgba_half : (device_memory &)rgba_byte; | device_memory &rgba = (half_float) ? (device_memory &)rgba_half : (device_memory &)rgba_byte; | ||||
| device->draw_pixels(rgba, | device->draw_pixels(rgba, | ||||
| 0, | 0, | ||||
| draw_width, | draw_width, | ||||
| draw_height, | draw_height, | ||||
| params.width, | params.get_width(), | ||||
| params.height, | params.get_height(), | ||||
| params.full_x, | params.get_full_x(), | ||||
| params.full_y, | params.get_full_y(), | ||||
| params.full_width, | params.get_full_width(), | ||||
| params.full_height, | params.get_full_height(), | ||||
| transparent, | transparent, | ||||
| draw_params); | draw_params); | ||||
| } | } | ||||
| } | } | ||||
| bool DisplayBuffer::draw_ready() | bool DisplayBuffer::draw_ready() | ||||
| { | { | ||||
| return (draw_width != 0 && draw_height != 0); | return (draw_width != 0 && draw_height != 0); | ||||
| } | } | ||||
| void RenderTileNeighbors::fill_tile_info(TileInfo *tile_info) | |||||
| { | |||||
| for (int i = 0; i < RenderTileNeighbors::SIZE; i++) { | |||||
| tile_info->offsets[i] = tiles[i].get_offset(); | |||||
| tile_info->strides[i] = tiles[i].get_stride(); | |||||
| tile_info->buffers[i] = tiles[i].get_buffer(); | |||||
| } | |||||
| tile_info->x[0] = tiles[3].get_x(); | |||||
| tile_info->x[1] = tiles[4].get_x(); | |||||
| tile_info->x[2] = tiles[5].get_x(); | |||||
| tile_info->x[3] = tiles[5].get_x() + tiles[5].get_w(); | |||||
| tile_info->y[0] = tiles[1].get_y(); | |||||
| tile_info->y[1] = tiles[4].get_y(); | |||||
| tile_info->y[2] = tiles[7].get_y(); | |||||
| tile_info->y[3] = tiles[7].get_y() + tiles[7].get_h(); | |||||
| } | |||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||