Cycles: Implement proper texture derivatives evaluation for OSL

This was an oldie TODO since initial work on newer OSL/OIIO support.
Now we should be ready for the libraries bump.
This commit is contained in:
Sergey Sharybin 2015-12-18 21:42:04 +05:00
parent 63015d3a09
commit 349affe370
2 changed files with 179 additions and 82 deletions

@ -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
}

@ -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);
#if OSL_LIBRARY_VERSION_CODE < 10600
typedef TextureSystem::TextureHandle TextureHandle;
typedef TextureSystem::Perthread TexturePerthread;
#endif
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
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,