Blender V2.61 - r43446

svm.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __SVM_H__
00020 #define __SVM_H__
00021 
00022 /* Shader Virtual Machine
00023  *
00024  * A shader is a list of nodes to be executed. These are simply read one after
00025  * the other and executed, using an node counter. Each node and it's associated
00026  * data is encoded as one or more uint4's in a 1D texture. If the data is larger
00027  * than an uint4, the node can increase the node counter to compensate for this.
00028  * Floats are encoded as int and then converted to float again.
00029  *
00030  * Nodes write their output into a stack. All stack data in the stack is
00031  * floats, since it's all factors, colors and vectors. The stack will be stored
00032  * in local memory on the GPU, as it would take too many register and indexes in
00033  * ways not known at compile time. This seems the only solution even though it
00034  * may be slow, with two positive factors. If the same shader is being executed,
00035  * memory access will be coalesced, and on fermi cards, memory will actually be
00036  * cached.
00037  *
00038  * The result of shader execution will be a single closure. This means the
00039  * closure type, associated label, data and weight. Sampling from multiple
00040  * closures is supported through the mix closure node, the logic for that is
00041  * mostly taken care of in the SVM compiler.
00042  */
00043 
00044 #include "svm_types.h"
00045 
00046 CCL_NAMESPACE_BEGIN
00047 
00048 /* Stack */
00049 
00050 __device_inline float3 stack_load_float3(float *stack, uint a)
00051 {
00052     kernel_assert(a+2 < SVM_STACK_SIZE);
00053 
00054     return make_float3(stack[a+0], stack[a+1], stack[a+2]);
00055 }
00056 
00057 __device_inline void stack_store_float3(float *stack, uint a, float3 f)
00058 {
00059     kernel_assert(a+2 < SVM_STACK_SIZE);
00060 
00061     stack[a+0] = f.x;
00062     stack[a+1] = f.y;
00063     stack[a+2] = f.z;
00064 }
00065 
00066 __device_inline float stack_load_float(float *stack, uint a)
00067 {
00068     kernel_assert(a < SVM_STACK_SIZE);
00069 
00070     return stack[a];
00071 }
00072 
00073 __device_inline float stack_load_float_default(float *stack, uint a, uint value)
00074 {
00075     return (a == (uint)SVM_STACK_INVALID)? __int_as_float(value): stack_load_float(stack, a);
00076 }
00077 
00078 __device_inline void stack_store_float(float *stack, uint a, float f)
00079 {
00080     kernel_assert(a < SVM_STACK_SIZE);
00081 
00082     stack[a] = f;
00083 }
00084 
00085 __device_inline bool stack_valid(uint a)
00086 {
00087     return a != (uint)SVM_STACK_INVALID;
00088 }
00089 
00090 /* Reading Nodes */
00091 
00092 __device_inline uint4 read_node(KernelGlobals *kg, int *offset)
00093 {
00094     uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
00095     (*offset)++;
00096     return node;
00097 }
00098 
00099 __device_inline float4 read_node_float(KernelGlobals *kg, int *offset)
00100 {
00101     uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
00102     float4 f = make_float4(__int_as_float(node.x), __int_as_float(node.y), __int_as_float(node.z), __int_as_float(node.w));
00103     (*offset)++;
00104     return f;
00105 }
00106 
00107 __device_inline void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
00108 {
00109     if(x) *x = (i & 0xFF);
00110     if(y) *y = ((i >> 8) & 0xFF);
00111     if(z) *z = ((i >> 16) & 0xFF);
00112     if(w) *w = ((i >> 24) & 0xFF);
00113 }
00114 
00115 CCL_NAMESPACE_END
00116 
00117 /* Nodes */
00118 
00119 #include "svm_noise.h"
00120 #include "svm_texture.h"
00121 
00122 #include "svm_attribute.h"
00123 #include "svm_gradient.h"
00124 #include "svm_closure.h"
00125 #include "svm_noisetex.h"
00126 #include "svm_convert.h"
00127 #include "svm_displace.h"
00128 #include "svm_fresnel.h"
00129 #include "svm_camera.h"
00130 #include "svm_geometry.h"
00131 #include "svm_hsv.h"
00132 #include "svm_image.h"
00133 #include "svm_gamma.h"
00134 #include "svm_invert.h"
00135 #include "svm_light_path.h"
00136 #include "svm_magic.h"
00137 #include "svm_mapping.h"
00138 #include "svm_normal.h"
00139 #include "svm_wave.h"
00140 #include "svm_math.h"
00141 #include "svm_mix.h"
00142 #include "svm_sepcomb_rgb.h"
00143 #include "svm_musgrave.h"
00144 #include "svm_sky.h"
00145 #include "svm_tex_coord.h"
00146 #include "svm_value.h"
00147 #include "svm_voronoi.h"
00148 #include "svm_checker.h"
00149 
00150 CCL_NAMESPACE_BEGIN
00151 
00152 /* Main Interpreter Loop */
00153 
00154 __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, float randb, int path_flag)
00155 {
00156     float stack[SVM_STACK_SIZE];
00157     float closure_weight = 1.0f;
00158     int offset = sd->shader & SHADER_MASK;
00159 
00160 #ifdef __MULTI_CLOSURE__
00161     sd->num_closure = 0;
00162     sd->randb_closure = randb;
00163 #else
00164     sd->closure.type = NBUILTIN_CLOSURES;
00165 #endif
00166 
00167     while(1) {
00168         uint4 node = read_node(kg, &offset);
00169 
00170         switch(node.x) {
00171             case NODE_SHADER_JUMP: {
00172                 if(type == SHADER_TYPE_SURFACE) offset = node.y;
00173                 else if(type == SHADER_TYPE_VOLUME) offset = node.z;
00174                 else if(type == SHADER_TYPE_DISPLACEMENT) offset = node.w;
00175                 else return;
00176                 break;
00177             }
00178             case NODE_CLOSURE_BSDF:
00179                 svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag);
00180                 break;
00181             case NODE_CLOSURE_EMISSION:
00182                 svm_node_closure_emission(sd, stack, node);
00183                 break;
00184             case NODE_CLOSURE_BACKGROUND:
00185                 svm_node_closure_background(sd, stack, node);
00186                 break;
00187             case NODE_CLOSURE_HOLDOUT:
00188                 svm_node_closure_holdout(sd, stack, node);
00189                 break;
00190             case NODE_CLOSURE_VOLUME:
00191                 svm_node_closure_volume(kg, sd, stack, node, path_flag);
00192                 break;
00193             case NODE_CLOSURE_SET_WEIGHT:
00194                 svm_node_closure_set_weight(sd, node.y, node.z, node.w);
00195                 break;
00196             case NODE_CLOSURE_WEIGHT:
00197                 svm_node_closure_weight(sd, stack, node.y);
00198                 break;
00199             case NODE_EMISSION_WEIGHT:
00200                 svm_node_emission_weight(kg, sd, stack, node);
00201                 break;
00202             case NODE_MIX_CLOSURE:
00203                 svm_node_mix_closure(sd, stack, node, &offset, &randb);
00204                 break;
00205             case NODE_ADD_CLOSURE:
00206                 svm_node_add_closure(sd, stack, node.y, node.z, &offset, &randb, &closure_weight);
00207                 break;
00208             case NODE_JUMP:
00209                 offset = node.y;
00210                 break;
00211 #ifdef __TEXTURES__
00212             case NODE_TEX_IMAGE:
00213                 svm_node_tex_image(kg, sd, stack, node);
00214                 break;
00215             case NODE_TEX_ENVIRONMENT:
00216                 svm_node_tex_environment(kg, sd, stack, node);
00217                 break;
00218             case NODE_TEX_SKY:
00219                 svm_node_tex_sky(kg, sd, stack, node.y, node.z);
00220                 break;
00221             case NODE_TEX_GRADIENT:
00222                 svm_node_tex_gradient(sd, stack, node);
00223                 break;
00224             case NODE_TEX_NOISE:
00225                 svm_node_tex_noise(kg, sd, stack, node, &offset);
00226                 break;
00227             case NODE_TEX_VORONOI:
00228                 svm_node_tex_voronoi(kg, sd, stack, node, &offset);
00229                 break;
00230             case NODE_TEX_MUSGRAVE:
00231                 svm_node_tex_musgrave(kg, sd, stack, node, &offset);
00232                 break;
00233             case NODE_TEX_WAVE:
00234                 svm_node_tex_wave(kg, sd, stack, node, &offset);
00235                 break;
00236             case NODE_TEX_MAGIC:
00237                 svm_node_tex_magic(kg, sd, stack, node, &offset);
00238                 break;
00239             case NODE_TEX_CHECKER:
00240                 svm_node_tex_checker(kg, sd, stack, node, &offset);
00241                 break;
00242 #endif
00243             case NODE_CAMERA:
00244                 svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
00245                 break;
00246             case NODE_GEOMETRY:
00247                 svm_node_geometry(sd, stack, node.y, node.z);
00248                 break;
00249             case NODE_GEOMETRY_BUMP_DX:
00250                 svm_node_geometry_bump_dx(sd, stack, node.y, node.z);
00251                 break;
00252             case NODE_GEOMETRY_BUMP_DY:
00253                 svm_node_geometry_bump_dy(sd, stack, node.y, node.z);
00254                 break;
00255             case NODE_LIGHT_PATH:
00256                 svm_node_light_path(sd, stack, node.y, node.z, path_flag);
00257                 break;
00258             case NODE_CONVERT:
00259                 svm_node_convert(sd, stack, node.y, node.z, node.w);
00260                 break;
00261             case NODE_VALUE_F:
00262                 svm_node_value_f(kg, sd, stack, node.y, node.z);
00263                 break;
00264             case NODE_VALUE_V:
00265                 svm_node_value_v(kg, sd, stack, node.y, &offset);
00266                 break;
00267             case NODE_INVERT:
00268                 svm_node_invert(sd, stack, node.y, node.z, node.w);
00269                 break;
00270             case NODE_GAMMA:
00271                 svm_node_gamma(sd, stack, node.y, node.z, node.w);
00272                 break;
00273             case NODE_MIX:
00274                 svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset);
00275                 break;
00276             case NODE_SEPARATE_RGB:
00277                 svm_node_separate_rgb(sd, stack, node.y, node.z, node.w);
00278                 break;
00279             case NODE_COMBINE_RGB:
00280                 svm_node_combine_rgb(sd, stack, node.y, node.z, node.w);
00281                 break;
00282             case NODE_HSV:
00283                 svm_node_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
00284                 break;
00285             case NODE_ATTR:
00286                 svm_node_attr(kg, sd, stack, node);
00287                 break;
00288             case NODE_ATTR_BUMP_DX:
00289                 svm_node_attr_bump_dx(kg, sd, stack, node);
00290                 break;
00291             case NODE_ATTR_BUMP_DY:
00292                 svm_node_attr_bump_dy(kg, sd, stack, node);
00293                 break;
00294             case NODE_FRESNEL:
00295                 svm_node_fresnel(sd, stack, node.y, node.z, node.w);
00296                 break;
00297             case NODE_LAYER_WEIGHT:
00298                 svm_node_layer_weight(sd, stack, node);
00299                 break;
00300             case NODE_SET_DISPLACEMENT:
00301                 svm_node_set_displacement(sd, stack, node.y);
00302                 break;
00303             case NODE_SET_BUMP:
00304                 svm_node_set_bump(sd, stack, node.y, node.z, node.w);
00305                 break;
00306             case NODE_MATH:
00307                 svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset);
00308                 break;
00309             case NODE_VECTOR_MATH:
00310                 svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset);
00311                 break;
00312             case NODE_NORMAL:
00313                 svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset);
00314                 break;
00315             case NODE_MAPPING:
00316                 svm_node_mapping(kg, sd, stack, node.y, node.z, &offset);
00317                 break;
00318             case NODE_TEX_COORD:
00319                 svm_node_tex_coord(kg, sd, stack, node.y, node.z);
00320                 break;
00321             case NODE_TEX_COORD_BUMP_DX:
00322                 svm_node_tex_coord_bump_dx(kg, sd, stack, node.y, node.z);
00323                 break;
00324             case NODE_TEX_COORD_BUMP_DY:
00325                 svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z);
00326                 break;
00327             case NODE_EMISSION_SET_WEIGHT_TOTAL:
00328                 svm_node_emission_set_weight_total(kg, sd, node.y, node.z, node.w);
00329                 break;
00330             case NODE_END:
00331             default:
00332 #ifndef __MULTI_CLOSURE__
00333                 sd->closure.weight *= closure_weight;
00334 #endif
00335                 return;
00336         }
00337     }
00338 }
00339 
00340 CCL_NAMESPACE_END
00341 
00342 #endif /* __SVM_H__ */
00343