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:
Diffstat (limited to 'intern/cycles/kernel/svm/attribute.h')
-rw-r--r--intern/cycles/kernel/svm/attribute.h346
1 files changed, 346 insertions, 0 deletions
diff --git a/intern/cycles/kernel/svm/attribute.h b/intern/cycles/kernel/svm/attribute.h
new file mode 100644
index 00000000000..e9de0164c7a
--- /dev/null
+++ b/intern/cycles/kernel/svm/attribute.h
@@ -0,0 +1,346 @@
+/*
+ * 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
+
+/* Attribute Node */
+
+ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ uint4 node,
+ ccl_private NodeAttributeOutputType *type,
+ ccl_private uint *out_offset)
+{
+ *out_offset = node.z;
+ *type = (NodeAttributeOutputType)node.w;
+
+ AttributeDescriptor desc;
+
+ if (sd->object != OBJECT_NONE) {
+ desc = find_attribute(kg, sd, node.y);
+ if (desc.offset == ATTR_STD_NOT_FOUND) {
+ desc = attribute_not_found();
+ desc.offset = 0;
+ desc.type = (NodeAttributeType)node.w;
+ }
+ }
+ else {
+ /* background */
+ desc = attribute_not_found();
+ desc.offset = 0;
+ desc.type = (NodeAttributeType)node.w;
+ }
+
+ return desc;
+}
+
+template<uint node_feature_mask>
+ccl_device_noinline void svm_node_attr(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ ccl_private float *stack,
+ uint4 node)
+{
+ NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
+ uint out_offset = 0;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+
+#ifdef __VOLUME__
+ IF_KERNEL_NODES_FEATURE(VOLUME)
+ {
+ /* Volumes
+ * NOTE: moving this into its own node type might help improve performance. */
+ if (primitive_is_volume_attribute(sd, desc)) {
+ const float4 value = volume_attribute_float4(kg, sd, desc);
+
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ const float f = volume_attribute_value_to_float(value);
+ stack_store_float(stack, out_offset, f);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ const float3 f = volume_attribute_value_to_float3(value);
+ stack_store_float3(stack, out_offset, f);
+ }
+ else {
+ const float f = volume_attribute_value_to_alpha(value);
+ stack_store_float(stack, out_offset, f);
+ }
+ return;
+ }
+ }
+#endif
+
+ if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
+ /* No generated attribute, fall back to object coordinates. */
+ float3 f = sd->P;
+ object_inverse_position_transform(kg, sd, &f);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ return;
+ }
+
+ /* Surface. */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f, f, f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f.x);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
+ float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f)));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, float4_to_float3(f));
+ }
+ else {
+ stack_store_float(stack, out_offset, f.w);
+ }
+ }
+ else {
+ float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+}
+
+ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ ccl_private float *stack,
+ uint4 node)
+{
+ NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
+ uint out_offset = 0;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+
+#ifdef __VOLUME__
+ /* Volume */
+ if (primitive_is_volume_attribute(sd, desc)) {
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, 0.0f);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ return;
+ }
+#endif
+
+ if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
+ /* No generated attribute, fall back to object coordinates. */
+ float3 f = sd->P + sd->dP.dx;
+ object_inverse_position_transform(kg, sd, &f);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ return;
+ }
+
+ /* Surface */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float dx;
+ float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f + dx);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 dx;
+ float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f.x + dx.x);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
+ float4 dx;
+ float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
+ }
+ else {
+ stack_store_float(stack, out_offset, f.w + dx.w);
+ }
+ }
+ else {
+ float3 dx;
+ float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f + dx));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f + dx);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+}
+
+ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ ccl_private float *stack,
+ uint4 node)
+{
+ NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
+ uint out_offset = 0;
+ AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
+
+#ifdef __VOLUME__
+ /* Volume */
+ if (primitive_is_volume_attribute(sd, desc)) {
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, 0.0f);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ return;
+ }
+#endif
+
+ if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
+ /* No generated attribute, fall back to object coordinates. */
+ float3 f = sd->P + sd->dP.dy;
+ object_inverse_position_transform(kg, sd, &f);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ return;
+ }
+
+ /* Surface */
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float dy;
+ float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f + dy);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 dy;
+ float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, f.x + dy.x);
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
+ float4 dy;
+ float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
+ }
+ else {
+ stack_store_float(stack, out_offset, f.w + dy.w);
+ }
+ }
+ else {
+ float3 dy;
+ float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_OUTPUT_FLOAT) {
+ stack_store_float(stack, out_offset, average(f + dy));
+ }
+ else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
+ stack_store_float3(stack, out_offset, f + dy);
+ }
+ else {
+ stack_store_float(stack, out_offset, 1.0f);
+ }
+ }
+}
+
+CCL_NAMESPACE_END