Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2019-02-19 17:41:22 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2019-02-19 18:28:25 +0300
commite6f5632eb11b37a2398f80841a77674656243dcf (patch)
tree02f1b2459c9b0ce34680a0622f306d4f436028cd /intern/cycles/kernel/geom/geom_primitive.h
parent8138eb0dfefa3b6d05d197a9a701e964b8719328 (diff)
T61513: Refactored Cycles Attribute Retrieval
There is a generic function to retrieve float and float3 attributes `primitive_attribute_float` and primitive_attribute_float3`. Inside these functions an prioritised if-else construction checked where the attribute is stored and then retrieved from that location. Actually the calling function most of the time already knows where the data is stored. So we could simplify this by splitting these functions and remove the check logic. This patch splits the `primitive_attribute_float?` functions into `primitive_surface_attribute_float?` and `primitive_volume_attribute_float?`. What leads to less branching and more optimum kernels. The original function is still being used by OSL and `svm_node_attr`. This will reduce the compilation time and render time for kernels. Especially in production scenes there is a lot of benefit. Impact in compilation times job | scene_name | previous | new | percentage -------+-----------------+----------+-------+------------ t61513 | empty | 10.63 | 10.66 | 0% t61513 | bmw | 17.91 | 17.65 | 1% t61513 | fishycat | 19.57 | 17.68 | 10% t61513 | barbershop | 54.10 | 24.41 | 55% t61513 | classroom | 17.55 | 16.29 | 7% t61513 | koro | 18.92 | 18.05 | 5% t61513 | pavillion | 17.43 | 16.52 | 5% t61513 | splash279 | 16.48 | 14.91 | 10% t61513 | volume_emission | 36.22 | 21.60 | 40% Impact in render times job | scene_name | previous | new | percentage -------+-----------------+----------+--------+------------ 61513 | empty | 21.06 | 20.35 | 3% 61513 | bmw | 198.44 | 190.05 | 4% 61513 | fishycat | 394.20 | 401.25 | -2% 61513 | barbershop | 1188.16 | 912.39 | 23% 61513 | classroom | 341.08 | 340.38 | 0% 61513 | koro | 472.43 | 471.80 | 0% 61513 | pavillion | 905.77 | 899.80 | 1% 61513 | splash279 | 55.26 | 54.86 | 1% 61513 | volume_emission | 62.59 | 61.70 | 1% There is also a possitive impact when using CPU and CUDA, but they are small. I didn't split the hair logic from the surface logic due to: * Hair and surface use same attribute types. It was not clear if it could be splitted when looking at the code only. * Hair and surface are quick to compile and to read. So the benefit is quite small. Differential Revision: https://developer.blender.org/D4375
Diffstat (limited to 'intern/cycles/kernel/geom/geom_primitive.h')
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h95
1 files changed, 86 insertions, 9 deletions
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 6db8475d196..e3e2648e9ec 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -22,7 +22,6 @@
CCL_NAMESPACE_BEGIN
/* Generic primitive attribute reading functions */
-
ccl_device_inline float primitive_attribute_float(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
@@ -41,7 +40,9 @@ ccl_device_inline float primitive_attribute_float(KernelGlobals *kg,
#endif
#ifdef __VOLUME__
else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- return volume_attribute_float(kg, sd, desc, dx, dy);
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+ return volume_attribute_float(kg, sd, desc);
}
#endif
else {
@@ -51,6 +52,43 @@ ccl_device_inline float primitive_attribute_float(KernelGlobals *kg,
}
}
+ccl_device_inline float primitive_surface_attribute_float(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float *dx, float *dy)
+{
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if(subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
+ }
+#ifdef __HAIR__
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float(kg, sd, desc, dx, dy);
+ }
+#endif
+ else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+ return 0.0f;
+ }
+}
+
+#ifdef __VOLUME__
+ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc)
+{
+ if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float(kg, sd, desc);
+ }
+ else {
+ return 0.0f;
+ }
+}
+#endif
+
ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc,
@@ -69,7 +107,32 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
#endif
#ifdef __VOLUME__
else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
- return volume_attribute_float3(kg, sd, desc, dx, dy);
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return volume_attribute_float3(kg, sd, desc);
+ }
+#endif
+ else {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float3 *dx, float3 *dy)
+{
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ if(subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float3(kg, sd, desc, dx, dy);
+ else
+ return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
+ }
+#ifdef __HAIR__
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
+ return curve_attribute_float3(kg, sd, desc, dx, dy);
}
#endif
else {
@@ -79,6 +142,20 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
}
}
+#ifdef __VOLUME__
+ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc)
+{
+ if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float3(kg, sd, desc);
+ }
+ else {
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+#endif
+
/* Default UV coordinate */
ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
@@ -88,7 +165,7 @@ ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
if(desc.offset == ATTR_STD_NOT_FOUND)
return make_float3(0.0f, 0.0f, 0.0f);
- float3 uv = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
+ float3 uv = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
uv.z = 1.0f;
return uv;
}
@@ -104,8 +181,8 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in
if(desc_face_id.offset == ATTR_STD_NOT_FOUND || desc_uv.offset == ATTR_STD_NOT_FOUND)
return false;
- float3 uv3 = primitive_attribute_float3(kg, sd, desc_uv, NULL, NULL);
- float face_id_f = primitive_attribute_float(kg, sd, desc_face_id, NULL, NULL);
+ float3 uv3 = primitive_surface_attribute_float3(kg, sd, desc_uv, NULL, NULL);
+ float face_id_f = primitive_surface_attribute_float(kg, sd, desc_face_id, NULL, NULL);
*uv = make_float2(uv3.x, uv3.y);
*face_id = (int)face_id_f;
@@ -130,7 +207,7 @@ ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED);
if(desc.offset != ATTR_STD_NOT_FOUND) {
- float3 data = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
+ float3 data = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
object_normal_transform(kg, sd, &data);
return cross(sd->N, normalize(cross(data, sd->N)));
@@ -176,10 +253,10 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *
object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
/* lookup attributes */
- motion_pre = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
+ motion_pre = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
desc.offset += (sd->type & PRIMITIVE_ALL_TRIANGLE)? numverts: numkeys;
- motion_post = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
+ motion_post = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
#ifdef __HAIR__
if(is_curve_primitive && (sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {