Blender  V3.3
kernel/svm/attribute.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
7 
8 /* Attribute Node */
9 
12  uint4 node,
14  ccl_private uint *out_offset)
15 {
16  *out_offset = node.z;
18 
20 
21  if (sd->object != OBJECT_NONE) {
22  desc = find_attribute(kg, sd, node.y);
23  if (desc.offset == ATTR_STD_NOT_FOUND) {
24  desc = attribute_not_found();
25  desc.offset = 0;
26  desc.type = (NodeAttributeType)node.w;
27  }
28  }
29  else {
30  /* background */
31  desc = attribute_not_found();
32  desc.offset = 0;
33  desc.type = (NodeAttributeType)node.w;
34  }
35 
36  return desc;
37 }
38 
39 template<uint node_feature_mask>
42  ccl_private float *stack,
43  uint4 node)
44 {
46  uint out_offset = 0;
47  AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
48 
49 #ifdef __VOLUME__
51  {
52  /* Volumes
53  * NOTE: moving this into its own node type might help improve performance. */
54  if (primitive_is_volume_attribute(sd, desc)) {
55  const float4 value = volume_attribute_float4(kg, sd, desc);
56 
58  const float f = volume_attribute_value_to_float(value);
59  stack_store_float(stack, out_offset, f);
60  }
61  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
62  const float3 f = volume_attribute_value_to_float3(value);
63  stack_store_float3(stack, out_offset, f);
64  }
65  else {
66  const float f = volume_attribute_value_to_alpha(value);
67  stack_store_float(stack, out_offset, f);
68  }
69  return;
70  }
71  }
72 #endif
73 
74  if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
75  /* No generated attribute, fall back to object coordinates. */
76  float3 f = sd->P;
77  if (sd->object != OBJECT_NONE) {
79  }
81  stack_store_float(stack, out_offset, average(f));
82  }
83  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
84  stack_store_float3(stack, out_offset, f);
85  }
86  else {
87  stack_store_float(stack, out_offset, 1.0f);
88  }
89  return;
90  }
91 
92  /* Surface. */
93  if (desc.type == NODE_ATTR_FLOAT) {
94  float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL);
96  stack_store_float(stack, out_offset, f);
97  }
98  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
99  stack_store_float3(stack, out_offset, make_float3(f, f, f));
100  }
101  else {
102  stack_store_float(stack, out_offset, 1.0f);
103  }
104  }
105  else if (desc.type == NODE_ATTR_FLOAT2) {
107  if (type == NODE_ATTR_OUTPUT_FLOAT) {
108  stack_store_float(stack, out_offset, f.x);
109  }
110  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
111  stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
112  }
113  else {
114  stack_store_float(stack, out_offset, 1.0f);
115  }
116  }
117  else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
119  if (type == NODE_ATTR_OUTPUT_FLOAT) {
120  stack_store_float(stack, out_offset, average(float4_to_float3(f)));
121  }
122  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
123  stack_store_float3(stack, out_offset, float4_to_float3(f));
124  }
125  else {
126  stack_store_float(stack, out_offset, f.w);
127  }
128  }
129  else {
131  if (type == NODE_ATTR_OUTPUT_FLOAT) {
132  stack_store_float(stack, out_offset, average(f));
133  }
134  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
135  stack_store_float3(stack, out_offset, f);
136  }
137  else {
138  stack_store_float(stack, out_offset, 1.0f);
139  }
140  }
141 }
142 
145  ccl_private float *stack,
146  uint4 node)
147 {
149  uint out_offset = 0;
150  AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
151 
152 #ifdef __VOLUME__
153  /* Volume */
154  if (primitive_is_volume_attribute(sd, desc)) {
155  if (type == NODE_ATTR_OUTPUT_FLOAT) {
156  stack_store_float(stack, out_offset, 0.0f);
157  }
158  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
159  stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
160  }
161  else {
162  stack_store_float(stack, out_offset, 1.0f);
163  }
164  return;
165  }
166 #endif
167 
168  if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
169  /* No generated attribute, fall back to object coordinates. */
170  float3 f = sd->P + sd->dP.dx;
171  if (sd->object != OBJECT_NONE) {
173  }
174  if (type == NODE_ATTR_OUTPUT_FLOAT) {
175  stack_store_float(stack, out_offset, average(f));
176  }
177  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
178  stack_store_float3(stack, out_offset, f);
179  }
180  else {
181  stack_store_float(stack, out_offset, 1.0f);
182  }
183  return;
184  }
185 
186  /* Surface */
187  if (desc.type == NODE_ATTR_FLOAT) {
188  float dx;
189  float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
190  if (type == NODE_ATTR_OUTPUT_FLOAT) {
191  stack_store_float(stack, out_offset, f + dx);
192  }
193  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
194  stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
195  }
196  else {
197  stack_store_float(stack, out_offset, 1.0f);
198  }
199  }
200  else if (desc.type == NODE_ATTR_FLOAT2) {
201  float2 dx;
202  float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL);
203  if (type == NODE_ATTR_OUTPUT_FLOAT) {
204  stack_store_float(stack, out_offset, f.x + dx.x);
205  }
206  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
207  stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
208  }
209  else {
210  stack_store_float(stack, out_offset, 1.0f);
211  }
212  }
213  else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
214  float4 dx;
215  float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL);
216  if (type == NODE_ATTR_OUTPUT_FLOAT) {
217  stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
218  }
219  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
220  stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
221  }
222  else {
223  stack_store_float(stack, out_offset, f.w + dx.w);
224  }
225  }
226  else {
227  float3 dx;
228  float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
229  if (type == NODE_ATTR_OUTPUT_FLOAT) {
230  stack_store_float(stack, out_offset, average(f + dx));
231  }
232  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
233  stack_store_float3(stack, out_offset, f + dx);
234  }
235  else {
236  stack_store_float(stack, out_offset, 1.0f);
237  }
238  }
239 }
240 
243  ccl_private float *stack,
244  uint4 node)
245 {
247  uint out_offset = 0;
248  AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
249 
250 #ifdef __VOLUME__
251  /* Volume */
252  if (primitive_is_volume_attribute(sd, desc)) {
253  if (type == NODE_ATTR_OUTPUT_FLOAT) {
254  stack_store_float(stack, out_offset, 0.0f);
255  }
256  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
257  stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
258  }
259  else {
260  stack_store_float(stack, out_offset, 1.0f);
261  }
262  return;
263  }
264 #endif
265 
266  if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
267  /* No generated attribute, fall back to object coordinates. */
268  float3 f = sd->P + sd->dP.dy;
269  if (sd->object != OBJECT_NONE) {
271  }
272  if (type == NODE_ATTR_OUTPUT_FLOAT) {
273  stack_store_float(stack, out_offset, average(f));
274  }
275  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
276  stack_store_float3(stack, out_offset, f);
277  }
278  else {
279  stack_store_float(stack, out_offset, 1.0f);
280  }
281  return;
282  }
283 
284  /* Surface */
285  if (desc.type == NODE_ATTR_FLOAT) {
286  float dy;
287  float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
288  if (type == NODE_ATTR_OUTPUT_FLOAT) {
289  stack_store_float(stack, out_offset, f + dy);
290  }
291  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
292  stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
293  }
294  else {
295  stack_store_float(stack, out_offset, 1.0f);
296  }
297  }
298  else if (desc.type == NODE_ATTR_FLOAT2) {
299  float2 dy;
300  float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy);
301  if (type == NODE_ATTR_OUTPUT_FLOAT) {
302  stack_store_float(stack, out_offset, f.x + dy.x);
303  }
304  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
305  stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
306  }
307  else {
308  stack_store_float(stack, out_offset, 1.0f);
309  }
310  }
311  else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
312  float4 dy;
313  float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy);
314  if (type == NODE_ATTR_OUTPUT_FLOAT) {
315  stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
316  }
317  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
318  stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
319  }
320  else {
321  stack_store_float(stack, out_offset, f.w + dy.w);
322  }
323  }
324  else {
325  float3 dy;
326  float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
327  if (type == NODE_ATTR_OUTPUT_FLOAT) {
328  stack_store_float(stack, out_offset, average(f + dy));
329  }
330  else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
331  stack_store_float3(stack, out_offset, f + dy);
332  }
333  else {
334  stack_store_float(stack, out_offset, 1.0f);
335  }
336  }
337 }
338 
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
float float4[4]
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_noinline
Definition: cuda/compat.h:40
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_inline AttributeDescriptor attribute_not_found()
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg, ccl_private const ShaderData *sd, uint id)
ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
ccl_device_noinline void svm_node_attr(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
CCL_NAMESPACE_BEGIN ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals kg, ccl_private ShaderData *sd, uint4 node, ccl_private NodeAttributeOutputType *type, ccl_private uint *out_offset)
ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
NodeAttributeOutputType
@ NODE_ATTR_OUTPUT_FLOAT
@ NODE_ATTR_OUTPUT_FLOAT3
NodeAttributeType
@ NODE_ATTR_FLOAT
@ NODE_ATTR_RGBA
@ NODE_ATTR_FLOAT2
@ NODE_ATTR_FLOAT4
@ ATTR_STD_NOT_FOUND
Definition: kernel/types.h:647
@ ATTR_STD_GENERATED
Definition: kernel/types.h:620
#define IF_KERNEL_NODES_FEATURE(feature)
#define OBJECT_NONE
Definition: kernel/types.h:40
ShaderData
Definition: kernel/types.h:925
@ ATTR_ELEMENT_NONE
Definition: kernel/types.h:598
ccl_device_inline float average(const float2 &a)
Definition: math_float2.h:170
#define make_float3(x, y, z)
Definition: metal/compat.h:204
ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float3 *dx, ccl_private float3 *dy)
Definition: primitive.h:83
ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float2 *dx, ccl_private float2 *dy)
Definition: primitive.h:52
ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float4 *dx, ccl_private float4 *dy)
Definition: primitive.h:114
CCL_NAMESPACE_BEGIN ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
Definition: primitive.h:21
AttributeElement element
Definition: kernel/types.h:656
NodeAttributeType type
Definition: kernel/types.h:657
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util/math.h:500