diff options
Diffstat (limited to 'intern/cycles/kernel/util')
-rw-r--r-- | intern/cycles/kernel/util/util_color.h | 35 | ||||
-rw-r--r-- | intern/cycles/kernel/util/util_differential.h | 166 | ||||
-rw-r--r-- | intern/cycles/kernel/util/util_lookup_table.h | 56 | ||||
-rw-r--r-- | intern/cycles/kernel/util/util_profiling.h | 40 |
4 files changed, 297 insertions, 0 deletions
diff --git a/intern/cycles/kernel/util/util_color.h b/intern/cycles/kernel/util/util_color.h new file mode 100644 index 00000000000..0d7bfecd5f3 --- /dev/null +++ b/intern/cycles/kernel/util/util_color.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "util/util_color.h" + +CCL_NAMESPACE_BEGIN + +ccl_device float3 xyz_to_rgb(KernelGlobals kg, float3 xyz) +{ + return make_float3(dot(float4_to_float3(kernel_data.film.xyz_to_r), xyz), + dot(float4_to_float3(kernel_data.film.xyz_to_g), xyz), + dot(float4_to_float3(kernel_data.film.xyz_to_b), xyz)); +} + +ccl_device float linear_rgb_to_gray(KernelGlobals kg, float3 c) +{ + return dot(c, float4_to_float3(kernel_data.film.rgb_to_y)); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/util/util_differential.h b/intern/cycles/kernel/util/util_differential.h new file mode 100644 index 00000000000..17187083019 --- /dev/null +++ b/intern/cycles/kernel/util/util_differential.h @@ -0,0 +1,166 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +CCL_NAMESPACE_BEGIN + +/* See "Tracing Ray Differentials", Homan Igehy, 1999. */ + +ccl_device void differential_transfer(ccl_private differential3 *surface_dP, + const differential3 ray_dP, + float3 ray_D, + const differential3 ray_dD, + float3 surface_Ng, + float ray_t) +{ + /* ray differential transfer through homogeneous medium, to + * compute dPdx/dy at a shading point from the incoming ray */ + + float3 tmp = ray_D / dot(ray_D, surface_Ng); + float3 tmpx = ray_dP.dx + ray_t * ray_dD.dx; + float3 tmpy = ray_dP.dy + ray_t * ray_dD.dy; + + surface_dP->dx = tmpx - dot(tmpx, surface_Ng) * tmp; + surface_dP->dy = tmpy - dot(tmpy, surface_Ng) * tmp; +} + +ccl_device void differential_incoming(ccl_private differential3 *dI, const differential3 dD) +{ + /* compute dIdx/dy at a shading point, we just need to negate the + * differential of the ray direction */ + + dI->dx = -dD.dx; + dI->dy = -dD.dy; +} + +ccl_device void differential_dudv(ccl_private differential *du, + ccl_private differential *dv, + float3 dPdu, + float3 dPdv, + differential3 dP, + float3 Ng) +{ + /* now we have dPdx/dy from the ray differential transfer, and dPdu/dv + * from the primitive, we can compute dudx/dy and dvdx/dy. these are + * mainly used for differentials of arbitrary mesh attributes. */ + + /* find most stable axis to project to 2D */ + float xn = fabsf(Ng.x); + float yn = fabsf(Ng.y); + float zn = fabsf(Ng.z); + + if (zn < xn || zn < yn) { + if (yn < xn || yn < zn) { + dPdu.x = dPdu.y; + dPdv.x = dPdv.y; + dP.dx.x = dP.dx.y; + dP.dy.x = dP.dy.y; + } + + dPdu.y = dPdu.z; + dPdv.y = dPdv.z; + dP.dx.y = dP.dx.z; + dP.dy.y = dP.dy.z; + } + + /* using Cramer's rule, we solve for dudx and dvdx in a 2x2 linear system, + * and the same for dudy and dvdy. the denominator is the same for both + * solutions, so we compute it only once. + * + * dP.dx = dPdu * dudx + dPdv * dvdx; + * dP.dy = dPdu * dudy + dPdv * dvdy; */ + + float det = (dPdu.x * dPdv.y - dPdv.x * dPdu.y); + + if (det != 0.0f) + det = 1.0f / det; + + du->dx = (dP.dx.x * dPdv.y - dP.dx.y * dPdv.x) * det; + dv->dx = (dP.dx.y * dPdu.x - dP.dx.x * dPdu.y) * det; + + du->dy = (dP.dy.x * dPdv.y - dP.dy.y * dPdv.x) * det; + dv->dy = (dP.dy.y * dPdu.x - dP.dy.x * dPdu.y) * det; +} + +ccl_device differential differential_zero() +{ + differential d; + d.dx = 0.0f; + d.dy = 0.0f; + + return d; +} + +ccl_device differential3 differential3_zero() +{ + differential3 d; + d.dx = zero_float3(); + d.dy = zero_float3(); + + return d; +} + +/* Compact ray differentials that are just a scale to reduce memory usage and + * access cost in GPU. + * + * See above for more accurate reference implementations. + * + * TODO: also store the more compact version in ShaderData and recompute where + * needed? */ + +ccl_device_forceinline float differential_zero_compact() +{ + return 0.0f; +} + +ccl_device_forceinline float differential_make_compact(const differential3 D) +{ + return 0.5f * (len(D.dx) + len(D.dy)); +} + +ccl_device_forceinline void differential_transfer_compact(ccl_private differential3 *surface_dP, + const float ray_dP, + const float3 /* ray_D */, + const float ray_dD, + const float3 surface_Ng, + const float ray_t) +{ + /* ray differential transfer through homogeneous medium, to + * compute dPdx/dy at a shading point from the incoming ray */ + float scale = ray_dP + ray_t * ray_dD; + + float3 dx, dy; + make_orthonormals(surface_Ng, &dx, &dy); + surface_dP->dx = dx * scale; + surface_dP->dy = dy * scale; +} + +ccl_device_forceinline void differential_incoming_compact(ccl_private differential3 *dI, + const float3 D, + const float dD) +{ + /* compute dIdx/dy at a shading point, we just need to negate the + * differential of the ray direction */ + + float3 dx, dy; + make_orthonormals(D, &dx, &dy); + + dI->dx = dD * dx; + dI->dy = dD * dy; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/util/util_lookup_table.h b/intern/cycles/kernel/util/util_lookup_table.h new file mode 100644 index 00000000000..2c26e668d7b --- /dev/null +++ b/intern/cycles/kernel/util/util_lookup_table.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +CCL_NAMESPACE_BEGIN + +/* Interpolated lookup table access */ + +ccl_device float lookup_table_read(KernelGlobals kg, float x, int offset, int size) +{ + x = saturate(x) * (size - 1); + + int index = min(float_to_int(x), size - 1); + int nindex = min(index + 1, size - 1); + float t = x - index; + + float data0 = kernel_tex_fetch(__lookup_table, index + offset); + if (t == 0.0f) + return data0; + + float data1 = kernel_tex_fetch(__lookup_table, nindex + offset); + return (1.0f - t) * data0 + t * data1; +} + +ccl_device float lookup_table_read_2D( + KernelGlobals kg, float x, float y, int offset, int xsize, int ysize) +{ + y = saturate(y) * (ysize - 1); + + int index = min(float_to_int(y), ysize - 1); + int nindex = min(index + 1, ysize - 1); + float t = y - index; + + float data0 = lookup_table_read(kg, x, offset + xsize * index, xsize); + if (t == 0.0f) + return data0; + + float data1 = lookup_table_read(kg, x, offset + xsize * nindex, xsize); + return (1.0f - t) * data0 + t * data1; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/util/util_profiling.h b/intern/cycles/kernel/util/util_profiling.h new file mode 100644 index 00000000000..db8644005ea --- /dev/null +++ b/intern/cycles/kernel/util/util_profiling.h @@ -0,0 +1,40 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifdef __KERNEL_CPU__ +# include "util/util_profiling.h" +#endif + +CCL_NAMESPACE_BEGIN + +#ifdef __KERNEL_CPU__ +# define PROFILING_INIT(kg, event) \ + ProfilingHelper profiling_helper((ProfilingState *)&kg->profiler, event) +# define PROFILING_EVENT(event) profiling_helper.set_event(event) +# define PROFILING_INIT_FOR_SHADER(kg, event) \ + ProfilingWithShaderHelper profiling_helper((ProfilingState *)&kg->profiler, event) +# define PROFILING_SHADER(object, shader) \ + profiling_helper.set_shader(object, (shader)&SHADER_MASK); +#else +# define PROFILING_INIT(kg, event) +# define PROFILING_EVENT(event) +# define PROFILING_INIT_FOR_SHADER(kg, event) +# define PROFILING_SHADER(object, shader) +#endif /* __KERNEL_CPU__ */ + +CCL_NAMESPACE_END |