Cycles: Implement proper texture derivatives evaluation for OSL
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 18 Dec 2015 16:42:04 +0000 (21:42 +0500)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 18 Dec 2015 16:50:30 +0000 (21:50 +0500)
This was an oldie TODO since initial work on newer OSL/OIIO support.
Now we should be ready for the libraries bump.

intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_services.h

index b0609ad..db53f2d 100644 (file)
@@ -840,14 +840,85 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, OSL::ShaderGlo
        return false; /* never called by OSL */
 }
 
-bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
+#if OSL_LIBRARY_VERSION_CODE < 10600
+bool OSLRenderServices::texture(ustring filename,
+                                TextureOpt &options,
                                 OSL::ShaderGlobals *sg,
-                                float s, float t, float dsdx, float dtdx,
-                                float dsdy, float dtdy, int nchannels, float *result)
+                                float s, float t,
+                                float dsdx, float dtdx,
+                                float dsdy, float dtdy,
+                                float *result)
 {
        OSL::TextureSystem *ts = osl_ts;
        ShaderData *sd = (ShaderData *)(sg->renderstate);
        KernelGlobals *kg = sd->osl_globals;
+       OSLThreadData *tdata = kg->osl_tdata;
+       OIIO::TextureSystem::Perthread *texture_thread_info =
+              tdata->oiio_thread_info;
+       OIIO::TextureSystem::TextureHandle *texture_handle =
+              ts->get_texture_handle(filename, texture_thread_info);
+       return texture(filename,
+                      texture_handle,
+                      texture_thread_info,
+                      options,
+                      sg,
+                      s, t,
+                      dsdx, dtdx, dsdy, dtdy,
+                      options.nchannels,
+                      result,
+                      NULL, NULL);
+}
+
+bool OSLRenderServices::texture3d(ustring filename,
+                                  TextureOpt &options,
+                                  OSL::ShaderGlobals *sg,
+                                  const OSL::Vec3 &P,
+                                  const OSL::Vec3 &dPdx,
+                                  const OSL::Vec3 &dPdy,
+                                  const OSL::Vec3 &dPdz,
+                                  float *result)
+{
+       OSL::TextureSystem *ts = osl_ts;
+       ShaderData *sd = (ShaderData *)(sg->renderstate);
+       KernelGlobals *kg = sd->osl_globals;
+       OSLThreadData *tdata = kg->osl_tdata;
+       OIIO::TextureSystem::Perthread *texture_thread_info =
+              tdata->oiio_thread_info;
+       OIIO::TextureSystem::TextureHandle *texture_handle =
+              ts->get_texture_handle(filename, texture_thread_info);
+       return texture3d(filename,
+                        texture_handle,
+                        texture_thread_info,
+                        options,
+                        sg,
+                        P,
+                        dPdx, dPdy, dPdz,
+                        options.nchannels,
+                        result,
+                        NULL, NULL, NULL);
+}
+#endif  /* OSL_LIBRARY_VERSION_CODE < 10600 */
+
+bool OSLRenderServices::texture(ustring filename,
+                                TextureHandle *texture_handle,
+                                TexturePerthread *texture_thread_info,
+                                TextureOpt &options,
+                                OSL::ShaderGlobals *sg,
+                                float s, float t,
+                                float dsdx, float dtdx, float dsdy, float dtdy,
+                                int nchannels,
+                                float *result,
+                                float *dresultds,
+                                float *dresultdt)
+{
+       OSL::TextureSystem *ts = osl_ts;
+       ShaderData *sd = (ShaderData *)(sg->renderstate);
+       KernelGlobals *kg = sd->osl_globals;
+
+       if(texture_thread_info == NULL) {
+               OSLThreadData *tdata = kg->osl_tdata;
+               texture_thread_info = tdata->oiio_thread_info;
+       }
 
 #ifdef WITH_PTEX
        /* todo: this is just a quick hack, only works with particular files and options */
@@ -902,19 +973,38 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
                status = true;
        }
        else {
-               OSLThreadData *tdata = kg->osl_tdata;
-               OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;
-
-               OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
-
 #if OIIO_VERSION < 10500
-               status = ts->texture(th, thread_info,
-                                    options, s, t, dsdx, dtdx, dsdy, dtdy,
+               (void) dresultds;  /* Ignored. */
+               (void) dresultdt;  /* Ignored. */
+               status = ts->texture(texture_handle,
+                                    texture_thread_info,
+                                    options,
+                                    s, t,
+                                    dsdx, dtdx,
+                                    dsdy, dtdy,
                                     result);
 #else
-               status = ts->texture(th, thread_info,
-                                    options, s, t, dsdx, dtdx, dsdy, dtdy,
-                                    nchannels, result);
+               if(texture_handle != NULL) {
+                       status = ts->texture(texture_handle,
+                                            texture_thread_info,
+                                            options,
+                                            s, t,
+                                            dsdx, dtdx,
+                                            dsdy, dtdy,
+                                            nchannels,
+                                            result,
+                                            dresultds, dresultdt);
+               }
+               else {
+                       status = ts->texture(filename,
+                                            options,
+                                            s, t,
+                                            dsdx, dtdx,
+                                            dsdy, dtdy,
+                                            nchannels,
+                                            result,
+                                            dresultds, dresultdt);
+               }
 #endif
        }
 
@@ -932,14 +1022,30 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
        return status;
 }
 
-bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
-                                  OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
-                                  const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
-                                  const OSL::Vec3 &dPdz, int nchannels, float *result)
+bool OSLRenderServices::texture3d(ustring filename,
+                                  TextureHandle *texture_handle,
+                                  TexturePerthread *texture_thread_info,
+                                  TextureOpt &options,
+                                  OSL::ShaderGlobals *sg,
+                                  const OSL::Vec3 &P,
+                                  const OSL::Vec3 &dPdx,
+                                  const OSL::Vec3 &dPdy,
+                                  const OSL::Vec3 &dPdz,
+                                  int nchannels,
+                                  float *result,
+                                  float *dresultds,
+                                  float *dresultdt,
+                                  float *dresultdr)
 {
        OSL::TextureSystem *ts = osl_ts;
        ShaderData *sd = (ShaderData *)(sg->renderstate);
        KernelGlobals *kg = sd->osl_globals;
+
+       if(texture_thread_info == NULL) {
+               OSLThreadData *tdata = kg->osl_tdata;
+               texture_thread_info = tdata->oiio_thread_info;
+       }
+
        bool status;
        if(filename[0] == '@') {
                int slot = atoi(filename.c_str() + 1);
@@ -955,16 +1061,36 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
                status = true;
        }
        else {
-               OSLThreadData *tdata = kg->osl_tdata;
-               OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;
-               OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
 #if OIIO_VERSION < 10500
-               status = ts->texture3d(th, thread_info,
-                                      options, P, dPdx, dPdy, dPdz, result);
+               (void) dresultds;  /* Ignored. */
+               (void) dresultdt;  /* Ignored. */
+               (void) dresultdr;  /* Ignored. */
+               status = ts->texture3d(texture_handle,
+                                      texture_thread_info,
+                                      options,
+                                      P,
+                                      dPdx, dPdy, dPdz,
+                                      result);
 #else
-               status = ts->texture3d(th, thread_info,
-                                      options, P, dPdx, dPdy, dPdz,
-                                      nchannels, result);
+               if(texture_handle != NULL) {
+                       status = ts->texture3d(texture_handle,
+                                              texture_thread_info,
+                                              options,
+                                              P,
+                                              dPdx, dPdy, dPdz,
+                                              nchannels,
+                                              result,
+                                              dresultds, dresultdt, dresultdr);
+               }
+               else {
+                       status = ts->texture3d(filename,
+                                              options,
+                                              P,
+                                              dPdx, dPdy, dPdz,
+                                              nchannels,
+                                              result,
+                                              dresultds, dresultdt, dresultdr);
+               }
 #endif
        }
 
index aa2befd..f35ddca 100644 (file)
@@ -40,7 +40,6 @@ class Shader;
 struct ShaderData;
 struct float3;
 struct KernelGlobals;
-
 class OSLRenderServices : public OSL::RendererServices
 {
 public:
@@ -94,42 +93,26 @@ public:
        bool getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
                        TypeDesc type, void *val, bool derivatives);
 
-       bool texture(ustring filename, TextureOpt &options,
-                    OSL::ShaderGlobals *sg,
-                    float s, float t, float dsdx, float dtdx,
-                    float dsdy, float dtdy, int nchannels, float *result);
-
-       bool texture3d(ustring filename, TextureOpt &options,
-                      OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
-                      const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
-                      const OSL::Vec3 &dPdz, int nchannels, float *result);
+#if OSL_LIBRARY_VERSION_CODE < 10600
+       typedef TextureSystem::TextureHandle TextureHandle;
+       typedef TextureSystem::Perthread TexturePerthread;
+#endif
 
-#if OSL_LIBRARY_VERSION_CODE >= 10600
        bool texture(ustring filename,
-                    TextureHandle * /*texture_handle*/,
-                    TexturePerthread * /*texture_thread_info*/,
+                    TextureSystem::TextureHandle *texture_handle,
+                    TexturePerthread *texture_thread_info,
                     TextureOpt &options,
                     OSL::ShaderGlobals *sg,
                     float s, float t,
                     float dsdx, float dtdx, float dsdy, float dtdy,
                     int nchannels,
                     float *result,
-                    float * /*dresultds*/,
-                    float * /*dresultdt*/)
-       {
-               /* TODO(sergey): Support derivatives. */
-               return texture(filename,
-                              options,
-                              sg,
-                              s, t,
-                              dsdx, dtdx, dsdy, dtdy,
-                              nchannels,
-                              result);
-       }
+                    float *dresultds,
+                    float *dresultdt);
 
        bool texture3d(ustring filename,
-                      TextureHandle * /*texture_handle*/,
-                      TexturePerthread * /*texture_thread_info*/,
+                      TextureHandle *texture_handle,
+                      TexturePerthread *texture_thread_info,
                       TextureOpt &options,
                       OSL::ShaderGlobals *sg,
                       const OSL::Vec3 &P,
@@ -138,20 +121,9 @@ public:
                       const OSL::Vec3 &dPdz,
                       int nchannels,
                       float *result,
-                      float * /*dresultds*/,
-                      float * /*dresultdt*/,
-                      float * /*dresultdr*/)
-       {
-               /* TODO(sergey): Support derivatives. */
-               return texture3d(filename,
-                                options,
-                                sg,
-                                P,
-                                dPdx, dPdy, dPdz,
-                                nchannels,
-                                result);
-       }
-#endif
+                      float *dresultds,
+                      float *dresultdt,
+                      float *dresultdr);
 
        bool environment(ustring filename, TextureOpt &options,
                         OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
@@ -212,23 +184,22 @@ public:
        /* Code to make OSL versions transition smooth. */
 
 #if OSL_LIBRARY_VERSION_CODE < 10600
-       inline bool texture(ustring filename, TextureOpt &options,
-                           OSL::ShaderGlobals *sg,
-                           float s, float t, float dsdx, float dtdx,
-                           float dsdy, float dtdy, float *result)
-       {
-               return texture(filename, options, sg, s, t, dsdx, dtdx, dsdy, dtdy,
-                              options.nchannels, result);
-       }
+       bool texture(ustring filename,
+                    TextureOpt &options,
+                    OSL::ShaderGlobals *sg,
+                    float s, float t,
+                    float dsdx, float dtdx,
+                    float dsdy, float dtdy,
+                    float *result);
 
-       inline bool texture3d(ustring filename, TextureOpt &options,
-                             OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
-                             const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
-                             const OSL::Vec3 &dPdz, float *result)
-       {
-               return texture3d(filename, options, sg, P, dPdx, dPdy, dPdz,
-                                options.nchannels, result);
-       }
+       bool texture3d(ustring filename,
+                      TextureOpt &options,
+                      OSL::ShaderGlobals *sg,
+                      const OSL::Vec3 &P,
+                      const OSL::Vec3 &dPdx,
+                      const OSL::Vec3 &dPdy,
+                      const OSL::Vec3 &dPdz,
+                      float *result);
 
        inline bool environment(ustring filename, TextureOpt &options,
                                OSL::ShaderGlobals *sg, const OSL::Vec3 &R,