Cycles OSL minor optimizations: recycle shading context, don't do memory
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 15 Dec 2012 10:18:42 +0000 (10:18 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 15 Dec 2012 10:18:42 +0000 (10:18 +0000)
allocations for trace data, avoid some virtual function calls. Only helps
a few percentages.

21 files changed:
intern/cycles/kernel/CMakeLists.txt
intern/cycles/kernel/closure/bsdf.h
intern/cycles/kernel/closure/bsdf_util.h [new file with mode: 0644]
intern/cycles/kernel/closure/emissive.h
intern/cycles/kernel/closure/volume.h
intern/cycles/kernel/kernel_displace.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
intern/cycles/kernel/osl/emissive.cpp
intern/cycles/kernel/osl/osl_closures.cpp
intern/cycles/kernel/osl/osl_closures.h
intern/cycles/kernel/osl/osl_globals.h
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_services.h
intern/cycles/kernel/osl/osl_shader.cpp
intern/cycles/kernel/osl/osl_shader.h
intern/cycles/kernel/svm/svm_bsdf.h [deleted file]

index b7878e9b00f585ed53957fc695d976981eead058..b6e024dde17590e9b9a1219eee76d73d57cf1d4a 100644 (file)
@@ -56,6 +56,7 @@ set(SRC_CLOSURE_HEADERS
        closure/bsdf_reflection.h
        closure/bsdf_refraction.h
        closure/bsdf_transparent.h
+       closure/bsdf_util.h
        closure/bsdf_ward.h
        closure/bsdf_westin.h
        closure/emissive.h
@@ -64,7 +65,6 @@ set(SRC_CLOSURE_HEADERS
 set(SRC_SVM_HEADERS
        svm/svm.h
        svm/svm_attribute.h
-       svm/svm_bsdf.h
        svm/svm_camera.h
        svm/svm_closure.h
        svm/svm_convert.h
index cfb6321a91841cbebad59399bf936da89730ad45..f26aefe7fd34559c34925693b827981ca54fd401 100644 (file)
 /*
- * Adapted from Open Shading Language with this license:
+ * Copyright 2011, Blender Foundation.
  *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
  *
- * Modifications Copyright 2011, Blender Foundation.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * * Neither the name of Sony Pictures Imageworks nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#ifndef __OSL_BSDF_H__
-#define __OSL_BSDF_H__
+#include "../closure/bsdf_ashikhmin_velvet.h"
+#include "../closure/bsdf_diffuse.h"
+#include "../closure/bsdf_oren_nayar.h"
+#include "../closure/bsdf_phong_ramp.h"
+#include "../closure/bsdf_diffuse_ramp.h"
+#include "../closure/bsdf_microfacet.h"
+#include "../closure/bsdf_reflection.h"
+#include "../closure/bsdf_refraction.h"
+#include "../closure/bsdf_transparent.h"
+#ifdef __ANISOTROPIC__
+#include "../closure/bsdf_ward.h"
+#endif
+#include "../closure/bsdf_westin.h"
 
 CCL_NAMESPACE_BEGIN
 
-__device float fresnel_dielectric(float eta, const float3 N,
-               const float3 I, float3 *R, float3 *T,
-#ifdef __RAY_DIFFERENTIALS__
-               const float3 dIdx, const float3 dIdy,
-               float3 *dRdx, float3 *dRdy,
-               float3 *dTdx, float3 *dTdy, 
-#endif
-               bool *is_inside)
+__device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
 {
-       float cos = dot(N, I), neta;
-       float3 Nn;
-       // compute reflection
-       *R = (2 * cos)* N - I;
-#ifdef __RAY_DIFFERENTIALS__
-       *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
-       *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
+       int label;
+
+#ifdef __OSL__
+       if(kg->osl && sc->prim)
+               return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
 #endif
-       // check which side of the surface we are on
-       if(cos > 0) {
-               // we are on the outside of the surface, going in
-               neta = 1 / eta;
-               Nn   = N;
-               *is_inside = false;
-       }
-       else {
-               // we are inside the surface, 
-               cos  = -cos;
-               neta = eta;
-               Nn   = -N;
-               *is_inside = true;
-       }
-       *R = (2 * cos)* Nn - I;
-       float arg = 1 -(neta * neta *(1 -(cos * cos)));
-       if(arg < 0) {
-               *T = make_float3(0.0f, 0.0f, 0.0f);
-#ifdef __RAY_DIFFERENTIALS__
-               *dTdx = make_float3(0.0f, 0.0f, 0.0f);
-               *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+
+       switch(sc->type) {
+               case CLOSURE_BSDF_DIFFUSE_ID:
+                       label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+#ifdef __SVM__
+               case CLOSURE_BSDF_OREN_NAYAR_ID:
+                       label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+                       label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+                       label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;*/
+               case CLOSURE_BSDF_TRANSLUCENT_ID:
+                       label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_REFLECTION_ID:
+                       label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_REFRACTION_ID:
+                       label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_TRANSPARENT_ID:
+                       label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_MICROFACET_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+                       label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+               case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+                       label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+#ifdef __ANISOTROPIC__
+               case CLOSURE_BSDF_WARD_ID:
+                       label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
 #endif
-               return 1; // total internal reflection
-       }
-       else {
-               float dnp = sqrtf(arg);
-               float nK = (neta * cos)- dnp;
-               *T = -(neta * I)+(nK * Nn);
-#ifdef __RAY_DIFFERENTIALS__
-               *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
-               *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+               case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+                       label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+                       label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+                       label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
 #endif
-               // compute Fresnel terms
-               float cosTheta1 = cos; // N.R
-               float cosTheta2 = -dot(Nn, *T);
-               float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
-               float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
-               return 0.5f * (pPara * pPara + pPerp * pPerp);
+               default:
+                       label = LABEL_NONE;
+                       break;
        }
+
+       return label;
 }
 
-__device float fresnel_dielectric_cos(float cosi, float eta)
+__device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
 {
-       // compute fresnel reflectance without explicitly computing
-       // the refracted direction
-       float c = fabsf(cosi);
-       float g = eta * eta - 1 + c * c;
-       if(g > 0) {
-               g = sqrtf(g);
-               float A = (g - c)/(g + c);
-               float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
-               return 0.5f * A * A *(1 + B * B);
+       float3 eval;
+
+#ifdef __OSL__
+       if(kg->osl && sc->prim)
+               return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf);
+#endif
+
+       if(dot(sd->Ng, omega_in) >= 0.0f) {
+               switch(sc->type) {
+                       case CLOSURE_BSDF_DIFFUSE_ID:
+                               eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+#ifdef __SVM__
+                       case CLOSURE_BSDF_OREN_NAYAR_ID:
+                               eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+                               eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+                               eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;*/
+                       case CLOSURE_BSDF_TRANSLUCENT_ID:
+                               eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_REFLECTION_ID:
+                               eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_REFRACTION_ID:
+                               eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_TRANSPARENT_ID:
+                               eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_MICROFACET_GGX_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+                               eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+                       case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+                               eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+#ifdef __ANISOTROPIC__
+                       case CLOSURE_BSDF_WARD_ID:
+                               eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+#endif
+                       case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+                               eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+                               eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+                               eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+#endif
+                       default:
+                               eval = make_float3(0.0f, 0.0f, 0.0f);
+                               break;
+               }
+       }
+       else {
+               switch(sc->type) {
+                       case CLOSURE_BSDF_DIFFUSE_ID:
+                               eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#ifdef __SVM__
+                       case CLOSURE_BSDF_OREN_NAYAR_ID:
+                               eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_TRANSLUCENT_ID:
+                               eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_REFLECTION_ID:
+                               eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_REFRACTION_ID:
+                               eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_TRANSPARENT_ID:
+                               eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_MICROFACET_GGX_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+                               eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+                       case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+                               eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#ifdef __ANISOTROPIC__
+                       case CLOSURE_BSDF_WARD_ID:
+                               eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#endif
+                       case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+                               eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+                               eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+                               eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#endif
+                       default:
+                               eval = make_float3(0.0f, 0.0f, 0.0f);
+                               break;
+               }
        }
-       return 1.0f; // TIR(no refracted component)
-}
 
-__device float fresnel_conductor(float cosi, float eta, float k)
-{
-       float tmp_f = eta * eta + k * k;
-       float tmp = tmp_f * cosi * cosi;
-       float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/
-                      (tmp + (2.0f * eta * cosi) + 1);
-       float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/
-                      (tmp_f + (2.0f * eta * cosi) + cosi * cosi);
-       return(Rparl2 + Rperp2) * 0.5f;
+       return eval;
 }
 
-__device float smooth_step(float edge0, float edge1, float x)
+__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
 {
-       float result;
-       if(x < edge0) result = 0.0f;
-       else if(x >= edge1) result = 1.0f;
-       else {
-               float t = (x - edge0)/(edge1 - edge0);
-               result = (3.0f-2.0f*t)*(t*t);
+#ifdef __OSL__
+       if(kg->osl && sc->prim) {
+               OSLShader::bsdf_blur(sc, roughness);
+               return;
+       }
+#endif
+
+       switch(sc->type) {
+               case CLOSURE_BSDF_DIFFUSE_ID:
+                       bsdf_diffuse_blur(sc, roughness);
+                       break;
+#ifdef __SVM__
+               case CLOSURE_BSDF_OREN_NAYAR_ID:
+                       bsdf_oren_nayar_blur(sc, roughness);
+                       break;
+               /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+                       bsdf_phong_ramp_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+                       bsdf_diffuse_ramp_blur(sc, roughness);
+                       break;*/
+               case CLOSURE_BSDF_TRANSLUCENT_ID:
+                       bsdf_translucent_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_REFLECTION_ID:
+                       bsdf_reflection_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_REFRACTION_ID:
+                       bsdf_refraction_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_TRANSPARENT_ID:
+                       bsdf_transparent_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_MICROFACET_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+                       bsdf_microfacet_ggx_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+               case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+                       bsdf_microfacet_beckmann_blur(sc, roughness);
+                       break;
+#ifdef __ANISOTROPIC__
+               case CLOSURE_BSDF_WARD_ID:
+                       bsdf_ward_blur(sc, roughness);
+                       break;
+#endif
+               case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+                       bsdf_ashikhmin_velvet_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+                       bsdf_westin_backscatter_blur(sc, roughness);
+                       break;
+               case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+                       bsdf_westin_sheen_blur(sc, roughness);
+                       break;
+#endif
+               default:
+                       break;
        }
-       return result;
 }
 
 CCL_NAMESPACE_END
 
-#endif /* __OSL_BSDF_H__ */
-
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
new file mode 100644 (file)
index 0000000..cfb6321
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __OSL_BSDF_H__
+#define __OSL_BSDF_H__
+
+CCL_NAMESPACE_BEGIN
+
+__device float fresnel_dielectric(float eta, const float3 N,
+               const float3 I, float3 *R, float3 *T,
+#ifdef __RAY_DIFFERENTIALS__
+               const float3 dIdx, const float3 dIdy,
+               float3 *dRdx, float3 *dRdy,
+               float3 *dTdx, float3 *dTdy, 
+#endif
+               bool *is_inside)
+{
+       float cos = dot(N, I), neta;
+       float3 Nn;
+       // compute reflection
+       *R = (2 * cos)* N - I;
+#ifdef __RAY_DIFFERENTIALS__
+       *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
+       *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
+#endif
+       // check which side of the surface we are on
+       if(cos > 0) {
+               // we are on the outside of the surface, going in
+               neta = 1 / eta;
+               Nn   = N;
+               *is_inside = false;
+       }
+       else {
+               // we are inside the surface, 
+               cos  = -cos;
+               neta = eta;
+               Nn   = -N;
+               *is_inside = true;
+       }
+       *R = (2 * cos)* Nn - I;
+       float arg = 1 -(neta * neta *(1 -(cos * cos)));
+       if(arg < 0) {
+               *T = make_float3(0.0f, 0.0f, 0.0f);
+#ifdef __RAY_DIFFERENTIALS__
+               *dTdx = make_float3(0.0f, 0.0f, 0.0f);
+               *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+               return 1; // total internal reflection
+       }
+       else {
+               float dnp = sqrtf(arg);
+               float nK = (neta * cos)- dnp;
+               *T = -(neta * I)+(nK * Nn);
+#ifdef __RAY_DIFFERENTIALS__
+               *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
+               *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+#endif
+               // compute Fresnel terms
+               float cosTheta1 = cos; // N.R
+               float cosTheta2 = -dot(Nn, *T);
+               float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
+               float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
+               return 0.5f * (pPara * pPara + pPerp * pPerp);
+       }
+}
+
+__device float fresnel_dielectric_cos(float cosi, float eta)
+{
+       // compute fresnel reflectance without explicitly computing
+       // the refracted direction
+       float c = fabsf(cosi);
+       float g = eta * eta - 1 + c * c;
+       if(g > 0) {
+               g = sqrtf(g);
+               float A = (g - c)/(g + c);
+               float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
+               return 0.5f * A * A *(1 + B * B);
+       }
+       return 1.0f; // TIR(no refracted component)
+}
+
+__device float fresnel_conductor(float cosi, float eta, float k)
+{
+       float tmp_f = eta * eta + k * k;
+       float tmp = tmp_f * cosi * cosi;
+       float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/
+                      (tmp + (2.0f * eta * cosi) + 1);
+       float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/
+                      (tmp_f + (2.0f * eta * cosi) + cosi * cosi);
+       return(Rparl2 + Rperp2) * 0.5f;
+}
+
+__device float smooth_step(float edge0, float edge1, float x)
+{
+       float result;
+       if(x < edge0) result = 0.0f;
+       else if(x >= edge1) result = 1.0f;
+       else {
+               float t = (x - edge0)/(edge1 - edge0);
+               result = (3.0f-2.0f*t)*(t*t);
+       }
+       return result;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __OSL_BSDF_H__ */
+
index cbf9d9a4efb2c6aba55ea08e5a0ceea95bc75a15..33b1b695a9aa8135a10b8029bbee171f8143205d 100644 (file)
@@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv,
        /* todo: not implemented and used yet */
 }
 
-__device float3 emissive_eval(const float3 Ng, const float3 I)
+__device float3 emissive_simple_eval(const float3 Ng, const float3 I)
 {
        float res = emissive_pdf(Ng, I);
        
        return make_float3(res, res, res);
 }
 
-__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
-{
-       return emissive_eval(sd->Ng, sd->I);
-}
-
 CCL_NAMESPACE_END
 
index 734f9111ab69e905b31a6650d5a5a06475eb12e1..0b553f38a253f95e36d72c3d96529039415bc102 100644 (file)
@@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo
 
 /* VOLUME CLOSURE */
 
-__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
 {
+#ifdef __OSL__
+       if(kg->osl && sc->prim)
+               return OSLShader::volume_eval_phase(sc, omega_in, omega_out);
+#endif
+
        float3 eval;
 
        switch(sc->type) {
index a55f7a7fd7510d21df7778cc87a243dc3c2226b0..fc2be342e029d70287824794c382806b0c30fca7 100644 (file)
@@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
 
                /* evaluate */
                float3 P = sd.P;
-               shader_eval_displacement(kg, &sd);
+               shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
                out = sd.P - P;
        }
        else { // SHADER_EVAL_BACKGROUND
@@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
 
                /* evaluate */
                int flag = 0; /* we can't know which type of BSDF this is for */
-               out = shader_eval_background(kg, &sd, flag);
+               out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
        }
        
        shader_release(kg, &sd);
index 6d650a0158d8508d06adb0fe8d6eb1e27331bebe..e56633c93581de35a2019b77ff6c07dad772662c 100644 (file)
@@ -42,7 +42,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
                ray.time = time;
 #endif
                shader_setup_from_background(kg, &sd, &ray);
-               eval = shader_eval_background(kg, &sd, 0);
+               eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
        }
        else
 #endif
@@ -52,7 +52,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 
                /* no path flag, we're evaluating this for all closures. that's weak but
                 * we'd have to do multiple evaluations otherwise */
-               shader_eval_surface(kg, &sd, rando, 0);
+               shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
 
                /* evaluate emissive closure */
                if(sd.flag & SD_EMISSION)
@@ -170,7 +170,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
        /* evaluate background closure */
        ShaderData sd;
        shader_setup_from_background(kg, &sd, ray);
-       float3 L = shader_eval_background(kg, &sd, path_flag);
+       float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
        shader_release(kg, &sd);
 
 #ifdef __BACKGROUND_MIS__
index 3588b09c790e229b1c2bff85f8dbf881dae50bcc..8da21751cbedcbff6f70ee81e6eed8cf2cc9661a 100644 (file)
@@ -207,7 +207,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
 
                                ShaderData sd;
                                shader_setup_from_ray(kg, &sd, &isect, ray);
-                               shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
+                               shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
 
                                throughput *= shader_bsdf_transparency(kg, &sd);
 
@@ -272,7 +272,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
                ShaderData sd;
                shader_setup_from_ray(kg, &sd, &isect, &ray);
                float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
-               shader_eval_surface(kg, &sd, rbsdf, state.flag);
+               shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
 
                kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
 
@@ -478,7 +478,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
                ShaderData sd;
                shader_setup_from_ray(kg, &sd, &isect, &ray);
                float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
-               shader_eval_surface(kg, &sd, rbsdf, state.flag);
+               shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
                shader_merge_closures(kg, &sd);
 
                /* blurring of bsdf after bounces, for rays that have a small likelihood
@@ -666,7 +666,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
                ShaderData sd;
                shader_setup_from_ray(kg, &sd, &isect, &ray);
                float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
-               shader_eval_surface(kg, &sd, rbsdf, state.flag);
+               shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
                shader_merge_closures(kg, &sd);
 
                kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
index 98a7ec59d7b866e729e5839843db483612a12ea8..9bbfe6b0cc542d0a6f1bef1ea2fdcdb3a2e864c6 100644 (file)
  *
  */
 
+#include "closure/bsdf_util.h"
 #include "closure/bsdf.h"
 #include "closure/emissive.h"
 #include "closure/volume.h"
 
-#include "svm/svm_bsdf.h"
 #include "svm/svm.h"
 
 CCL_NAMESPACE_BEGIN
@@ -56,11 +56,6 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        const Intersection *isect, const Ray *ray)
 {
-#ifdef __OSL__
-       if (kg->osl)
-               OSLShader::init(kg, sd);
-#endif
-
        /* fetch triangle data */
        int prim = kernel_tex_fetch(__prim_index, isect->prim);
        float4 Ns = kernel_tex_fetch(__tri_normal, prim);
@@ -142,11 +137,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        const float3 P, const float3 Ng, const float3 I,
        int shader, int object, int prim, float u, float v, float t, float time)
 {
-#ifdef __OSL__
-       if (kg->osl)
-               OSLShader::init(kg, sd);
-#endif
-
        /* vectors */
        sd->P = P;
        sd->N = Ng;
@@ -273,11 +263,6 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
 
 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
 {
-#ifdef __OSL__
-       if (kg->osl)
-               OSLShader::init(kg, sd);
-#endif
-
        /* vectors */
        sd->P = ray->D;
        sd->N = -sd->P;
@@ -320,36 +305,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
 
 #ifdef __MULTI_CLOSURE__
 
-#ifdef __OSL__
-__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
-       int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
-{
-       for(int i = 0; i< sd->num_closure; i++) {
-               if(i == skip_bsdf)
-                       continue;
-
-               const ShaderClosure *sc = &sd->closure[i];
-
-               if(CLOSURE_IS_BSDF(sc->type)) {
-                       float bsdf_pdf = 0.0f;
-
-                       float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
-
-                       if(bsdf_pdf != 0.0f) {
-                               bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
-                               sum_pdf += bsdf_pdf*sc->sample_weight;
-                       }
-
-                       sum_sample_weight += sc->sample_weight;
-               }
-       }
-
-       *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
-}
-#endif
-
-__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
-       int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
+__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
+       int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
 {
        for(int i = 0; i< sd->num_closure; i++) {
                if(i == skip_bsdf)
@@ -359,11 +316,10 @@ __device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const flo
 
                if(CLOSURE_IS_BSDF(sc->type)) {
                        float bsdf_pdf = 0.0f;
-
-                       float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
+                       float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
 
                        if(bsdf_pdf != 0.0f) {
-                               bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
+                               bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
                                sum_pdf += bsdf_pdf*sc->sample_weight;
                        }
 
@@ -382,17 +338,12 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
 #ifdef __MULTI_CLOSURE__
        bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
 
-#ifdef __OSL__
-       if (kg->osl)
-               return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
-       else
-#endif
-               return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+       return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
 #else
        const ShaderClosure *sc = &sd->closure;
 
        *pdf = 0.0f;
-       *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
+       *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
 #endif
 }
 
@@ -439,24 +390,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
        float3 eval;
 
        *pdf = 0.0f;
-#ifdef __OSL__
-       if (kg->osl)
-               label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
-       else
-#endif
-               label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+       label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
 
        if(*pdf != 0.0f) {
                bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
 
                if(sd->num_closure > 1) {
                        float sweight = sc->sample_weight;
-#ifdef __OSL__
-                       if (kg->osl)
-                               _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
-                       else
-#endif
-                               _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
+                       _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
                }
        }
 
@@ -464,7 +405,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
 #else
        /* sample the single closure that we picked */
        *pdf = 0.0f;
-       int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
+       int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
        *bsdf_eval *= sd->closure.weight;
        return label;
 #endif
@@ -478,12 +419,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
        float3 eval;
 
        *pdf = 0.0f;
-#ifdef __OSL__
-       if (kg->osl)
-               label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
-       else
-#endif
-               label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+       label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
 
        if(*pdf != 0.0f)
                bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
@@ -497,17 +433,11 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes
        for(int i = 0; i< sd->num_closure; i++) {
                ShaderClosure *sc = &sd->closure[i];
 
-               if(CLOSURE_IS_BSDF(sc->type)) {
-#ifdef __OSL__
-                       if (kg->osl)
-                               OSLShader::bsdf_blur(sc, roughness);
-                       else
-#endif
-                               svm_bsdf_blur(sc, roughness);
-               }
+               if(CLOSURE_IS_BSDF(sc->type))
+                       bsdf_blur(kg, sc, roughness);
        }
 #else
-       svm_bsdf_blur(&sd->closure, roughness);
+       bsdf_blur(kg, &sd->closure, roughness);
 #endif
 }
 
@@ -635,6 +565,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
 
 /* Emission */
 
+__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
+{
+#ifdef __OSL__
+       if(kg->osl && sc->prim)
+               return OSLShader::emissive_eval(sd, sc);
+#endif
+
+       return emissive_simple_eval(sd->Ng, sd->I);
+}
+
 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
 {
        float3 eval;
@@ -644,18 +584,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
        for(int i = 0; i < sd->num_closure; i++) {
                ShaderClosure *sc = &sd->closure[i];
 
-               if(CLOSURE_IS_EMISSION(sc->type)) {
-#ifdef __OSL__
-                       if (kg->osl)
-                               eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
-                       else
-#endif
-                               eval += svm_emissive_eval(sd, sc)*sc->weight;
-
-               }
+               if(CLOSURE_IS_EMISSION(sc->type))
+                       eval += emissive_eval(kg, sd, sc)*sc->weight;
        }
 #else
-       eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
+       eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
 #endif
 
        return eval;
@@ -687,11 +620,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
 /* Surface Evaluation */
 
 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
-       float randb, int path_flag)
+       float randb, int path_flag, ShaderContext ctx)
 {
 #ifdef __OSL__
        if (kg->osl)
-               OSLShader::eval_surface(kg, sd, randb, path_flag);
+               OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
        else
 #endif
        {
@@ -706,11 +639,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
 
 /* Background Evaluation */
 
-__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
 {
 #ifdef __OSL__
        if (kg->osl)
-               return OSLShader::eval_background(kg, sd, path_flag);
+               return OSLShader::eval_background(kg, sd, path_flag, ctx);
        else
 #endif
 
@@ -753,31 +686,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
        for(int i = 0; i< sd->num_closure; i++) {
                const ShaderClosure *sc = &sd->closure[i];
 
-               if(CLOSURE_IS_VOLUME(sc->type)) {
-#ifdef __OSL__
-                       if (kg->osl)
-                               eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
-                       else
-#endif
-                               eval += volume_eval_phase(sc, omega_in, omega_out);
-               }
+               if(CLOSURE_IS_VOLUME(sc->type))
+                       eval += volume_eval_phase(kg, sc, omega_in, omega_out);
        }
 
        return eval;
 #else
-       return volume_eval_phase(&sd->closure, omega_in, omega_out);
+       return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
 #endif
 }
 
 /* Volume Evaluation */
 
 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
-       float randb, int path_flag)
+       float randb, int path_flag, ShaderContext ctx)
 {
 #ifdef __SVM__
 #ifdef __OSL__
        if (kg->osl)
-               OSLShader::eval_volume(kg, sd, randb, path_flag);
+               OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
        else
 #endif
                svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
@@ -786,13 +713,13 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
 
 /* Displacement Evaluation */
 
-__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
+__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
 {
        /* this will modify sd->P */
 #ifdef __SVM__
 #ifdef __OSL__
        if (kg->osl)
-               OSLShader::eval_displacement(kg, sd);
+               OSLShader::eval_displacement(kg, sd, ctx);
        else
 #endif
                svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
@@ -818,7 +745,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
 #ifdef __NON_PROGRESSIVE__
 __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
 {
-#ifndef __OSL__
        /* merge identical closures, better when we sample a single closure at a time */
        for(int i = 0; i < sd->num_closure; i++) {
                ShaderClosure *sci = &sd->closure[i];
@@ -826,7 +752,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
                for(int j = i + 1; j < sd->num_closure; j++) {
                        ShaderClosure *scj = &sd->closure[j];
 
-                       if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+                       if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
                                sci->weight += scj->weight;
                                sci->sample_weight += scj->sample_weight;
 
@@ -838,7 +764,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
                        }
                }
        }
-#endif
 }
 #endif
 
@@ -846,10 +771,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
 
 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
 {
-#ifdef __OSL__
-       if (kg->osl)
-               OSLShader::release(kg, sd);
-#endif
+       /* nothing to do currently */
 }
 
 CCL_NAMESPACE_END
index e3a766e56b10bc7203c1a91804201ea52c23841a..a0673f55681c1be7ea943befc2abc04928b7d07e 100644 (file)
@@ -379,6 +379,18 @@ typedef struct ShaderClosure {
 #endif
 } ShaderClosure;
 
+/* Shader Context
+ *
+ * For OSL we recycle a fixed number of contexts for speed */
+
+typedef enum ShaderContext {
+       SHADER_CONTEXT_MAIN = 0,
+       SHADER_CONTEXT_INDIRECT = 1,
+       SHADER_CONTEXT_EMISSION = 2,
+       SHADER_CONTEXT_SHADOW = 3,
+       SHADER_CONTEXT_NUM = 4
+} ShaderContext;
+
 /* Shader Data
  *
  * Main shader state at a point on the surface or in a volume. All coordinates
@@ -466,11 +478,6 @@ typedef struct ShaderData {
        /* Closure data, with a single sampled closure for low memory usage */
        ShaderClosure closure;
 #endif
-
-#ifdef __OSL__
-       /* OSL context */
-       void *osl_ctx;
-#endif
 } ShaderData;
 
 /* Constrant Kernel Data
index 7189f99a822aa4ca3330d358ae32caafaa3ff2c1..a320bea118a6a3143c26609400ec112666e48dbc 100644 (file)
@@ -55,7 +55,7 @@ public:
 
        void setup()
        {
-               sc.N = TO_FLOAT3(N);
+               sc.prim = this;
                m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc);
 
                for(int i = 0; i < 8; i++)
@@ -101,7 +101,7 @@ public:
 ClosureParam *closure_bsdf_diffuse_ramp_params()
 {
        static ClosureParam params[] = {
-               CLOSURE_VECTOR_PARAM(DiffuseRampClosure, N),
+               CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
                CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
                CLOSURE_STRING_KEYPARAM("label"),
            CLOSURE_FINISH_PARAM(DiffuseRampClosure)
index fb144be7e5074ff36a69fd810b48741aad57545c..ef656ee7d5f48700e05764aab7774fdec79ddeba 100644 (file)
@@ -54,7 +54,7 @@ public:
 
        void setup()
        {
-               sc.N = TO_FLOAT3(N);
+               sc.prim = this;
                m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
 
                for(int i = 0; i < 8; i++)
@@ -100,7 +100,7 @@ public:
 ClosureParam *closure_bsdf_phong_ramp_params()
 {
        static ClosureParam params[] = {
-               CLOSURE_VECTOR_PARAM(PhongRampClosure, N),
+               CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
                CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
                CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
                CLOSURE_STRING_KEYPARAM("label"),
index 37e3e37c00a9521477cd2759e224622199e633c6..7d9fa81dbdde20c09d6cf6b106fef98e5449e4f5 100644 (file)
@@ -65,7 +65,7 @@ public:
 
        Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
        {
-               float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
+               float3 result = emissive_simple_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
                return TO_COLOR3(result);
        }
 
index 1f71fde549efdd0d61b840aace86e834e17f5b18..fa9f770d6edfe029e8096ab1433b58ca0e230b89 100644 (file)
@@ -43,7 +43,7 @@
 #include "kernel_types.h"
 #include "kernel_montecarlo.h"
 
-#include "closure/bsdf.h"
+#include "closure/bsdf_util.h"
 #include "closure/bsdf_ashikhmin_velvet.h"
 #include "closure/bsdf_diffuse.h"
 #include "closure/bsdf_microfacet.h"
@@ -62,34 +62,34 @@ using namespace OSL;
 /* BSDF class definitions */
 
 BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE)
-       CLOSURE_VECTOR_PARAM(DiffuseClosure, N),
+       CLOSURE_FLOAT3_PARAM(DiffuseClosure, sc.N),
 BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
 
 BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE)
-       CLOSURE_VECTOR_PARAM(TranslucentClosure, N),
+       CLOSURE_FLOAT3_PARAM(TranslucentClosure, sc.N),
 BSDF_CLOSURE_CLASS_END(Translucent, translucent)
 
 BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE)
-       CLOSURE_VECTOR_PARAM(OrenNayarClosure, N),
+       CLOSURE_FLOAT3_PARAM(OrenNayarClosure, sc.N),
        CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
 
 BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR)
-       CLOSURE_VECTOR_PARAM(ReflectionClosure, N),
+       CLOSURE_FLOAT3_PARAM(ReflectionClosure, sc.N),
 BSDF_CLOSURE_CLASS_END(Reflection, reflection)
 
 BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
-       CLOSURE_VECTOR_PARAM(RefractionClosure, N),
+       CLOSURE_FLOAT3_PARAM(RefractionClosure, sc.N),
        CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(Refraction, refraction)
 
 BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N),
+       CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N),
        CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
 
 BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
-       CLOSURE_VECTOR_PARAM(WestinSheenClosure, N),
+       CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N),
        CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
 
@@ -97,35 +97,35 @@ BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
 BSDF_CLOSURE_CLASS_END(Transparent, transparent)
 
 BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE)
-       CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N),
+       CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, sc.N),
        CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
 
 BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(WardClosure, N),
-       CLOSURE_VECTOR_PARAM(WardClosure, T),
+       CLOSURE_FLOAT3_PARAM(WardClosure, sc.N),
+       CLOSURE_FLOAT3_PARAM(WardClosure, sc.T),
        CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
        CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
 BSDF_CLOSURE_CLASS_END(Ward, ward)
 
 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N),
+       CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N),
        CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
 
 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N),
+       CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
        CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
 
 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N),
+       CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
        CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
        CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
 BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
 
 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY)
-       CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N),
+       CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N),
        CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
        CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
index 5cd333c806e596145316b6afaf57bae47209c13d..fe37c974e953bfb52c051c0f39e12c9a47deb3cb 100644 (file)
@@ -70,8 +70,11 @@ void name(RendererServices *, int id, void *data) \
 
 #define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
 
-#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
-#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
+#define CLOSURE_FLOAT3_PARAM(st, fld) \
+    { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
+
+#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
+#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
 #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
 
 /* BSDF */
@@ -79,7 +82,6 @@ void name(RendererServices *, int id, void *data) \
 class CBSDFClosure : public OSL::ClosurePrimitive {
 public:
        ShaderClosure sc;
-       OSL::Vec3 N, T;
 
        CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
          m_scattering_label(scattering), m_shaderdata_flag(0) { }
@@ -87,7 +89,6 @@ public:
 
        int scattering() const { return m_scattering_label; }
        int shaderdata_flag() const { return m_shaderdata_flag; }
-       ClosureType shaderclosure_type() const { return sc.type; }
 
        virtual void blur(float roughness) = 0;
        virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
@@ -114,8 +115,7 @@ public: \
 \
        void setup() \
        { \
-               sc.N = TO_FLOAT3(N); \
-               sc.T = TO_FLOAT3(T); \
+               sc.prim = NULL; \
                m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
        } \
 \
index 1a2a210de88c65690e6fc830af957ff274b870bd..fb5691176988209aed0c13aae4916ab5a0ec2d11 100644 (file)
@@ -75,10 +75,21 @@ struct OSLGlobals {
        vector<ustring> object_names;
 };
 
+/* trace() call result */
+struct OSLTraceData {
+       Ray ray;
+       Intersection isect;
+       ShaderData sd;
+       bool setup;
+       bool init;
+};
+
 /* thread key for thread specific data lookup */
 struct OSLThreadData {
        OSL::ShaderGlobals globals;
        OSL::PerThreadInfo *thread_info;
+       OSLTraceData tracedata;
+       OSL::ShadingContext *context[SHADER_CONTEXT_NUM];
 };
 
 CCL_NAMESPACE_END
index b584a54b1b7ff32c0864b2da104493e54f8a7a3e..d6e52e28c62cd62d9ee7d456067099dca5af8817 100644 (file)
@@ -47,7 +47,7 @@ CCL_NAMESPACE_BEGIN
 
 /* RenderServices implementation */
 
-#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
+#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
 
 /* static ustrings */
 ustring OSLRenderServices::u_distance("distance");
@@ -121,7 +121,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
                        Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
 #endif
                        tfm = transform_transpose(tfm);
-                       result = TO_MATRIX44(tfm);
+                       COPY_MATRIX44(&result, &tfm);
 
                        return true;
                }
@@ -151,7 +151,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
                        Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
 #endif
                        itfm = transform_transpose(itfm);
-                       result = TO_MATRIX44(itfm);
+                       COPY_MATRIX44(&result, &itfm);
 
                        return true;
                }
@@ -166,22 +166,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
 
        if (from == u_ndc) {
                Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_raster) {
                Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_screen) {
                Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_camera) {
                Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
 
@@ -194,22 +194,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
 
        if (to == u_ndc) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_raster) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_screen) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_camera) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
 
@@ -232,7 +232,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
                        Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
 #endif
                        tfm = transform_transpose(tfm);
-                       result = TO_MATRIX44(tfm);
+                       COPY_MATRIX44(&result, &tfm);
 
                        return true;
                }
@@ -257,7 +257,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
                        Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
 #endif
                        tfm = transform_transpose(tfm);
-                       result = TO_MATRIX44(tfm);
+                       COPY_MATRIX44(&result, &tfm);
 
                        return true;
                }
@@ -272,22 +272,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
 
        if (from == u_ndc) {
                Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_raster) {
                Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_screen) {
                Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (from == u_camera) {
                Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
 
@@ -300,22 +300,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
        
        if (to == u_ndc) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_raster) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_screen) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        else if (to == u_camera) {
                Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
-               result = TO_MATRIX44(tfm);
+               COPY_MATRIX44(&result, &tfm);
                return true;
        }
        
@@ -815,13 +815,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
        ray.dD.dy = TO_FLOAT3(dRdy);
 
        /* allocate trace data */
-       TraceData *tracedata = new TraceData();
+       OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
        tracedata->ray = ray;
        tracedata->setup = false;
-
-       if(sg->tracedata)
-               delete (TraceData*)sg->tracedata;
-       sg->tracedata = tracedata;
+       tracedata->init = true;
 
        /* raytrace */
        return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect);
@@ -831,9 +828,9 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
 bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
        TypeDesc type, void *val, bool derivatives)
 {
-       TraceData *tracedata = (TraceData*)sg->tracedata;
+       OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
 
-       if(source == u_trace && tracedata) {
+       if(source == u_trace && tracedata->init) {
                if(name == u_hit) {
                        return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
                }
index e687700b38317c1131a401ae277f17bae2555cad..cd4a4163209a5f900937b52beff1b12af83089f1 100644 (file)
@@ -106,13 +106,6 @@ public:
        static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
                        TypeDesc type, bool derivatives, void *val);
 
-       struct TraceData {
-               Ray ray;
-               Intersection isect;
-               ShaderData sd;
-               bool setup;
-       };
-
        static ustring u_distance;
        static ustring u_index;
        static ustring u_camera;
index 32712b25e9212806d77808c2a95e85b12452cb8f..f5c04b6755e650a7cbcaf7dbae09f414f2cbf1fa 100644 (file)
@@ -51,8 +51,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS
        OSLThreadData *tdata = new OSLThreadData();
 
        memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
+       tdata->globals.tracedata = &tdata->tracedata;
+       tdata->globals.flipHandedness = false;
        tdata->thread_info = ss->create_thread_info();
 
+       for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+               tdata->context[i] = ss->get_context(tdata->thread_info);
+
        kg->osl_ss = (OSLShadingSystem*)ss;
        kg->osl_tdata = tdata;
 }
@@ -65,6 +70,9 @@ void OSLShader::thread_free(KernelGlobals *kg)
        OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
        OSLThreadData *tdata = kg->osl_tdata;
 
+       for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+               ss->release_context(tdata->context[i]);
+
        ss->destroy_thread_info(tdata->thread_info);
 
        delete tdata;
@@ -77,8 +85,10 @@ void OSLShader::thread_free(KernelGlobals *kg)
 /* Globals */
 
 static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
-                                        int path_flag, OSL::ShaderGlobals *globals)
+                                        int path_flag, OSLThreadData *tdata)
 {
+       OSL::ShaderGlobals *globals = &tdata->globals;
+
        /* copy from shader data to shader globals */
        globals->P = TO_VEC3(sd->P);
        globals->dPdx = TO_VEC3(sd->dP.dx);
@@ -100,15 +110,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
        globals->time = sd->time;
 
        /* booleans */
-       globals->raytype = path_flag; /* todo: add our own ray types */
+       globals->raytype = path_flag;
        globals->backfacing = (sd->flag & SD_BACKFACING);
 
-       /* don't know yet if we need this */
-       globals->flipHandedness = false;
-       
        /* shader data to be used in services callbacks */
        globals->renderstate = sd; 
-       globals->tracedata = NULL;
 
        /* hacky, we leave it to services to fetch actual object matrix */
        globals->shader2common = sd;
@@ -116,6 +122,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
 
        /* must be set to NULL before execute */
        globals->Ci = NULL;
+
+       /* clear trace data */
+       tdata->tracedata.init = false;
 }
 
 /* Surface */
@@ -132,14 +141,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
 
                if (prim) {
                        ShaderClosure sc;
-                       sc.prim = prim;
                        sc.weight = weight;
 
                        switch (prim->category()) {
                                case OSL::ClosurePrimitive::BSDF: {
-                                       if (sd->num_closure == MAX_CLOSURE)
-                                               return;
-
                                        CBSDFClosure *bsdf = (CBSDFClosure *)prim;
                                        int scattering = bsdf->scattering();
 
@@ -151,8 +156,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
                                        float sample_weight = fabsf(average(weight));
 
                                        sc.sample_weight = sample_weight;
-                                       sc.type = bsdf->shaderclosure_type();
-                                       sc.N = bsdf->sc.N; /* needed for AO */
+
+                                       sc.type = bsdf->sc.type;
+                                       sc.N = bsdf->sc.N;
+                                       sc.T = bsdf->sc.T;
+                                       sc.data0 = bsdf->sc.data0;
+                                       sc.data1 = bsdf->sc.data1;
+                                       sc.prim = bsdf->sc.prim;
 
                                        /* add */
                                        if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
@@ -170,6 +180,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
 
                                        sc.sample_weight = sample_weight;
                                        sc.type = CLOSURE_EMISSION_ID;
+                                       sc.prim = NULL;
 
                                        /* flag */
                                        if(sd->num_closure < MAX_CLOSURE) {
@@ -179,14 +190,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
                                        break;
                                }
                                case AmbientOcclusion: {
-                                       if (sd->num_closure == MAX_CLOSURE)
-                                               return;
-
                                        /* sample weight */
                                        float sample_weight = fabsf(average(weight));
 
                                        sc.sample_weight = sample_weight;
                                        sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
+                                       sc.prim = NULL;
 
                                        if(sd->num_closure < MAX_CLOSURE) {
                                                sd->closure[sd->num_closure++] = sc;
@@ -195,11 +204,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
                                        break;
                                }
                                case OSL::ClosurePrimitive::Holdout:
-                                       if (sd->num_closure == MAX_CLOSURE)
-                                               return;
-
                                        sc.sample_weight = 0.0f;
                                        sc.type = CLOSURE_HOLDOUT_ID;
+                                       sc.prim = NULL;
 
                                        if(sd->num_closure < MAX_CLOSURE) {
                                                sd->closure[sd->num_closure++] = sc;
@@ -226,26 +233,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
        }
 }
 
-void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
 {
-       /* gather pointers */
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       OSLThreadData *tdata = kg->osl_tdata;
-       OSL::ShaderGlobals *globals = &tdata->globals;
-       OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
        /* setup shader globals from shader data */
-       shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+       OSLThreadData *tdata = kg->osl_tdata;
+       shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
 
        /* execute shader for this point */
+       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+       OSL::ShaderGlobals *globals = &tdata->globals;
+       OSL::ShadingContext *octx = tdata->context[(int)ctx];
        int shader = sd->shader & SHADER_MASK;
 
        if (kg->osl->surface_state[shader])
-               ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals);
-
-       /* free trace data */
-       if(globals->tracedata)
-               delete (OSLRenderServices::TraceData*)globals->tracedata;
+               ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
 
        /* flatten closure tree */
        sd->num_closure = 0;
@@ -287,24 +288,19 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
        return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
 {
-       /* gather pointers */
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       OSLThreadData *tdata = kg->osl_tdata;
-       OSL::ShaderGlobals *globals = &tdata->globals;
-       OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
        /* setup shader globals from shader data */
-       shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+       OSLThreadData *tdata = kg->osl_tdata;
+       shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
 
        /* execute shader for this point */
-       if (kg->osl->background_state)
-               ss->execute(*ctx, *(kg->osl->background_state), *globals);
+       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+       OSL::ShaderGlobals *globals = &tdata->globals;
+       OSL::ShadingContext *octx = tdata->context[(int)ctx];
 
-       /* free trace data */
-       if(globals->tracedata)
-               delete (OSLRenderServices::TraceData*)globals->tracedata;
+       if (kg->osl->background_state)
+               ss->execute(*octx, *(kg->osl->background_state), *globals);
 
        /* return background color immediately */
        if (globals->Ci)
@@ -327,19 +323,16 @@ static void flatten_volume_closure_tree(ShaderData *sd,
 
                if (prim) {
                        ShaderClosure sc;
-                       sc.prim = prim;
                        sc.weight = weight;
 
                        switch (prim->category()) {
                                case OSL::ClosurePrimitive::Volume: {
-                                       if (sd->num_closure == MAX_CLOSURE)
-                                               return;
-
                                        /* sample weight */
                                        float sample_weight = fabsf(average(weight));
 
                                        sc.sample_weight = sample_weight;
                                        sc.type = CLOSURE_VOLUME_ID;
+                                       sc.prim = NULL;
 
                                        /* add */
                                        if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
@@ -368,26 +361,20 @@ static void flatten_volume_closure_tree(ShaderData *sd,
        }
 }
 
-void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
 {
-       /* gather pointers */
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       OSLThreadData *tdata = kg->osl_tdata;
-       OSL::ShaderGlobals *globals = &tdata->globals;
-       OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
        /* setup shader globals from shader data */
-       shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+       OSLThreadData *tdata = kg->osl_tdata;
+       shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
 
        /* execute shader */
+       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+       OSL::ShaderGlobals *globals = &tdata->globals;
+       OSL::ShadingContext *octx = tdata->context[(int)ctx];
        int shader = sd->shader & SHADER_MASK;
 
        if (kg->osl->volume_state[shader])
-               ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals);
-
-       /* free trace data */
-       if(globals->tracedata)
-               delete (OSLRenderServices::TraceData*)globals->tracedata;
+               ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
 
        if (globals->Ci)
                flatten_volume_closure_tree(sd, globals->Ci);
@@ -395,46 +382,25 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
 
 /* Displacement */
 
-void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
+void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
 {
-       /* gather pointers */
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       OSLThreadData *tdata = kg->osl_tdata;
-       OSL::ShaderGlobals *globals = &tdata->globals;
-       OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
        /* setup shader globals from shader data */
-       shaderdata_to_shaderglobals(kg, sd, 0, globals);
+       OSLThreadData *tdata = kg->osl_tdata;
+       shaderdata_to_shaderglobals(kg, sd, 0, tdata);
 
        /* execute shader */
+       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+       OSL::ShaderGlobals *globals = &tdata->globals;
+       OSL::ShadingContext *octx = tdata->context[(int)ctx];
        int shader = sd->shader & SHADER_MASK;
 
        if (kg->osl->displacement_state[shader])
-               ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals);
-
-       /* free trace data */
-       if(globals->tracedata)
-               delete (OSLRenderServices::TraceData*)globals->tracedata;
+               ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
 
        /* get back position */
        sd->P = TO_FLOAT3(globals->P);
 }
 
-void OSLShader::init(KernelGlobals *kg, ShaderData *sd)
-{
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       OSLThreadData *tdata = kg->osl_tdata;
-       
-       sd->osl_ctx = ss->get_context(tdata->thread_info);
-}
-
-void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
-{
-       OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-       
-       ss->release_context((OSL::ShadingContext *)sd->osl_ctx);
-}
-
 /* BSDF Closure */
 
 int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
index e614f240dc1d55e6961b92031095815450581c4d..2e46a2de42cf8705409b5cbfb7660fe547941688 100644 (file)
@@ -55,10 +55,10 @@ public:
        static void thread_free(KernelGlobals *kg);
 
        /* eval */
-       static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
-       static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag);
-       static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
-       static void eval_displacement(KernelGlobals *kg, ShaderData *sd);
+       static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+       static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx);
+       static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+       static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx);
 
        /* sample & eval */
        static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc,
@@ -73,10 +73,6 @@ public:
        static float3 volume_eval_phase(const ShaderClosure *sc,
                                        const float3 omega_in, const float3 omega_out);
 
-       /* release */
-       static void init(KernelGlobals *kg, ShaderData *sd);
-       static void release(KernelGlobals *kg, ShaderData *sd);
-
        /* attributes */
        static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
 };
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
deleted file mode 100644 (file)
index a9524f3..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "../closure/bsdf_ashikhmin_velvet.h"
-#include "../closure/bsdf_diffuse.h"
-#include "../closure/bsdf_oren_nayar.h"
-#include "../closure/bsdf_phong_ramp.h"
-#include "../closure/bsdf_diffuse_ramp.h"
-#include "../closure/bsdf_microfacet.h"
-#include "../closure/bsdf_reflection.h"
-#include "../closure/bsdf_refraction.h"
-#include "../closure/bsdf_transparent.h"
-#ifdef __ANISOTROPIC__
-#include "../closure/bsdf_ward.h"
-#endif
-#include "../closure/bsdf_westin.h"
-
-CCL_NAMESPACE_BEGIN
-
-__device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
-{
-       int label;
-
-       switch(sc->type) {
-               case CLOSURE_BSDF_DIFFUSE_ID:
-                       label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-#ifdef __SVM__
-               case CLOSURE_BSDF_OREN_NAYAR_ID:
-                       label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               /*case CLOSURE_BSDF_PHONG_RAMP_ID:
-                       label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
-                       label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;*/
-               case CLOSURE_BSDF_TRANSLUCENT_ID:
-                       label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_REFLECTION_ID:
-                       label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_REFRACTION_ID:
-                       label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_TRANSPARENT_ID:
-                       label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_MICROFACET_GGX_ID:
-               case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                       label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
-               case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                       label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-#ifdef __ANISOTROPIC__
-               case CLOSURE_BSDF_WARD_ID:
-                       label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-#endif
-               case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                       label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
-                       label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-               case CLOSURE_BSDF_WESTIN_SHEEN_ID:
-                       label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
-                       break;
-#endif
-               default:
-                       label = LABEL_NONE;
-                       break;
-       }
-
-       return label;
-}
-
-__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
-{
-       float3 eval;
-
-       if(dot(sd->Ng, omega_in) >= 0.0f) {
-               switch(sc->type) {
-                       case CLOSURE_BSDF_DIFFUSE_ID:
-                               eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-#ifdef __SVM__
-                       case CLOSURE_BSDF_OREN_NAYAR_ID:
-                               eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       /*case CLOSURE_BSDF_PHONG_RAMP_ID:
-                               eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
-                               eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;*/
-                       case CLOSURE_BSDF_TRANSLUCENT_ID:
-                               eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_REFLECTION_ID:
-                               eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_REFRACTION_ID:
-                               eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_TRANSPARENT_ID:
-                               eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_MICROFACET_GGX_ID:
-                       case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                               eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
-                       case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                               eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-#ifdef __ANISOTROPIC__
-                       case CLOSURE_BSDF_WARD_ID:
-                               eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-#endif
-                       case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                               eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
-                               eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_WESTIN_SHEEN_ID:
-                               eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
-                               break;
-#endif
-                       default:
-                               eval = make_float3(0.0f, 0.0f, 0.0f);
-                               break;
-               }
-       }
-       else {
-               switch(sc->type) {
-                       case CLOSURE_BSDF_DIFFUSE_ID:
-                               eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-#ifdef __SVM__
-                       case CLOSURE_BSDF_OREN_NAYAR_ID:
-                               eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_TRANSLUCENT_ID:
-                               eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_REFLECTION_ID:
-                               eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_REFRACTION_ID:
-                               eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_TRANSPARENT_ID:
-                               eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_MICROFACET_GGX_ID:
-                       case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                               eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
-                       case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                               eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-#ifdef __ANISOTROPIC__
-                       case CLOSURE_BSDF_WARD_ID:
-                               eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-#endif
-                       case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                               eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
-                               eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-                       case CLOSURE_BSDF_WESTIN_SHEEN_ID:
-                               eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
-                               break;
-#endif
-                       default:
-                               eval = make_float3(0.0f, 0.0f, 0.0f);
-                               break;
-               }
-       }
-
-       return eval;
-}
-
-__device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
-{
-       switch(sc->type) {
-               case CLOSURE_BSDF_DIFFUSE_ID:
-                       bsdf_diffuse_blur(sc, roughness);
-                       break;
-#ifdef __SVM__
-               case CLOSURE_BSDF_OREN_NAYAR_ID:
-                       bsdf_oren_nayar_blur(sc, roughness);
-                       break;
-               /*case CLOSURE_BSDF_PHONG_RAMP_ID:
-                       bsdf_phong_ramp_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
-                       bsdf_diffuse_ramp_blur(sc, roughness);
-                       break;*/
-               case CLOSURE_BSDF_TRANSLUCENT_ID:
-                       bsdf_translucent_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_REFLECTION_ID:
-                       bsdf_reflection_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_REFRACTION_ID:
-                       bsdf_refraction_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_TRANSPARENT_ID:
-                       bsdf_transparent_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_MICROFACET_GGX_ID:
-               case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                       bsdf_microfacet_ggx_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
-               case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                       bsdf_microfacet_beckmann_blur(sc, roughness);
-                       break;
-#ifdef __ANISOTROPIC__
-               case CLOSURE_BSDF_WARD_ID:
-                       bsdf_ward_blur(sc, roughness);
-                       break;
-#endif
-               case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                       bsdf_ashikhmin_velvet_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
-                       bsdf_westin_backscatter_blur(sc, roughness);
-                       break;
-               case CLOSURE_BSDF_WESTIN_SHEEN_ID:
-                       bsdf_westin_sheen_blur(sc, roughness);
-                       break;
-#endif
-               default:
-                       break;
-       }
-}
-
-CCL_NAMESPACE_END
-