Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/osl')
-rw-r--r--intern/cycles/kernel/osl/background.cpp4
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp2
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp2
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp63
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h10
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h33
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp105
-rw-r--r--intern/cycles/kernel/osl/osl_services.h52
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp42
11 files changed, 151 insertions, 166 deletions
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 03fa88f40ad..b395227845d 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -52,7 +52,7 @@ using namespace OSL;
///
class GenericBackgroundClosure : public CClosurePrimitive {
public:
- void setup(const KernelGlobals *, ShaderData *sd, int /* path_flag */, float3 weight)
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
{
background_setup(sd, weight);
}
@@ -67,7 +67,7 @@ class GenericBackgroundClosure : public CClosurePrimitive {
///
class HoldoutClosure : CClosurePrimitive {
public:
- void setup(const KernelGlobals *, ShaderData *sd, int /* path_flag */, float3 weight)
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
{
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, weight);
sd->flag |= SD_HOLDOUT;
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
index 419837ab8d6..c5edc7c9be3 100644
--- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -51,7 +51,7 @@ class DiffuseRampClosure : public CBSDFClosure {
DiffuseRampBsdf params;
Color3 colors[8];
- void setup(const KernelGlobals *, ShaderData *sd, int /* path_flag */, float3 weight)
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
{
DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
sd, sizeof(DiffuseRampBsdf), weight, &params);
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index 6bf39934235..4b7e59ff932 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -50,7 +50,7 @@ class PhongRampClosure : public CBSDFClosure {
PhongRampBsdf params;
Color3 colors[8];
- void setup(const KernelGlobals *, ShaderData *sd, int /* path_flag */, float3 weight)
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
{
PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
sd, sizeof(PhongRampBsdf), weight, &params);
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 894727a5c7b..c29ddb13e2e 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -54,7 +54,7 @@ using namespace OSL;
///
class GenericEmissiveClosure : public CClosurePrimitive {
public:
- void setup(const KernelGlobals *, ShaderData *sd, int /* path_flag */, float3 weight)
+ void setup(ShaderData *sd, int /* path_flag */, float3 weight)
{
emission_setup(sd, weight);
}
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index b487aef09a1..dd52c33071c 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -67,7 +67,7 @@ class CBSSRDFClosure : public CClosurePrimitive {
params.roughness = 0.0f;
}
- void setup(const KernelGlobals *, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
if (method == u_cubic) {
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_CUBIC_ID);
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 7152a56bd70..27205df3732 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -227,9 +227,9 @@ CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
return bsdf;
}
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- if (!skip(kg, sd, path_flag, LABEL_GLOSSY)) {
+ if (!skip(sd, path_flag, LABEL_GLOSSY)) {
PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@@ -287,7 +287,7 @@ class PrincipledClearcoatClosure : public CBSDFClosure {
return bsdf;
}
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
@@ -471,13 +471,12 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
/* BSDF Closure */
-bool CBSDFClosure::skip(const KernelGlobals *kg,
- const ShaderData *sd,
- int path_flag,
- int scattering)
+bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
{
/* caustic options */
if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
+ KernelGlobals *kg = sd->osl_globals;
+
if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
(!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
return true;
@@ -495,12 +494,12 @@ class MicrofacetFresnelClosure : public CBSDFClosure {
float3 color;
float3 cspec0;
- MicrofacetBsdf *alloc(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
{
/* Technically, the MultiGGX Glass closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
- if (skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return NULL;
}
@@ -525,9 +524,9 @@ class MicrofacetFresnelClosure : public CBSDFClosure {
class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -554,9 +553,9 @@ CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresn
class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -589,12 +588,12 @@ class MicrofacetMultiClosure : public CBSDFClosure {
MicrofacetBsdf params;
float3 color;
- MicrofacetBsdf *alloc(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
- if (skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return NULL;
}
@@ -619,9 +618,9 @@ class MicrofacetMultiClosure : public CBSDFClosure {
class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -647,9 +646,9 @@ CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXCl
class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -679,9 +678,9 @@ class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
{
}
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -713,12 +712,12 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure {
float3 color;
float3 cspec0;
- MicrofacetBsdf *alloc(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
- if (skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return NULL;
}
@@ -743,9 +742,9 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure {
class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -773,9 +772,9 @@ CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare,
class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -807,9 +806,9 @@ class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosu
{
}
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- MicrofacetBsdf *bsdf = alloc(kg, sd, path_flag, weight);
+ MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
}
@@ -842,7 +841,7 @@ class TransparentClosure : public CBSDFClosure {
ShaderClosure params;
float3 unused;
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
bsdf_transparent_setup(sd, weight, path_flag);
}
@@ -861,7 +860,7 @@ CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
class VolumeAbsorptionClosure : public CBSDFClosure {
public:
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
volume_extinction_setup(sd, weight);
}
@@ -880,7 +879,7 @@ class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
public:
HenyeyGreensteinVolume params;
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight)
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
volume_extinction_setup(sd, weight);
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 9de1e036194..d3db6b71f5c 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -42,8 +42,6 @@
CCL_NAMESPACE_BEGIN
-struct KernelGlobals;
-
OSL::ClosureParam *closure_emission_params();
OSL::ClosureParam *closure_background_params();
OSL::ClosureParam *closure_holdout_params();
@@ -113,7 +111,7 @@ void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void
class CClosurePrimitive {
public:
- virtual void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight) = 0;
+ virtual void setup(ShaderData *sd, int path_flag, float3 weight) = 0;
OSL::ustring label;
};
@@ -122,7 +120,7 @@ class CClosurePrimitive {
class CBSDFClosure : public CClosurePrimitive {
public:
- bool skip(const KernelGlobals *kg, const ShaderData *sd, int path_flag, int scattering);
+ bool skip(const ShaderData *sd, int path_flag, int scattering);
};
#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \
@@ -132,9 +130,9 @@ class CBSDFClosure : public CClosurePrimitive {
structname params; \
float3 unused; \
\
- void setup(const KernelGlobals *kg, ShaderData *sd, int path_flag, float3 weight) \
+ void setup(ShaderData *sd, int path_flag, float3 weight) \
{ \
- if (!skip(kg, sd, path_flag, TYPE)) { \
+ if (!skip(sd, path_flag, TYPE)) { \
structname *bsdf = (structname *)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
} \
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 51bc5cf81a9..0e6c8d21534 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -39,36 +39,6 @@ CCL_NAMESPACE_BEGIN
class OSLRenderServices;
class ColorSpaceProcessor;
-/* OSL Texture Handle
- *
- * OSL texture lookups are string based. If those strings are known at compile
- * time, the OSL compiler can cache a texture handle to use instead of a string.
- *
- * By default it uses TextureSystem::TextureHandle. But since we want to support
- * different kinds of textures and color space conversions, this is our own handle
- * with additional data.
- *
- * These are stored in a concurrent hash map, because OSL can compile multiple
- * shaders in parallel. */
-
-struct OSLTextureHandle : public OIIO::RefCnt {
- enum Type { OIIO, SVM, IES, BEVEL, AO };
-
- OSLTextureHandle(Type type = OIIO, int svm_slot = -1)
- : type(type), svm_slot(svm_slot), oiio_handle(NULL), processor(NULL)
- {
- }
-
- Type type;
- int svm_slot;
- OSL::TextureSystem::TextureHandle *oiio_handle;
- ColorSpaceProcessor *processor;
-};
-
-typedef OIIO::intrusive_ptr<OSLTextureHandle> OSLTextureHandleRef;
-typedef OIIO::unordered_map_concurrent<ustring, OSLTextureHandleRef, ustringHash>
- OSLTextureHandleMap;
-
/* OSL Globals
*
* Data needed by OSL render services, that is global to a rendering session.
@@ -111,9 +81,6 @@ struct OSLGlobals {
vector<AttributeMap> attribute_map;
ObjectNameMap object_name_map;
vector<ustring> object_names;
-
- /* textures */
- OSLTextureHandleMap textures;
};
/* trace() call result */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 8215f6522db..08821ffa099 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -56,10 +56,6 @@
#include "kernel/kernel_accumulate.h"
#include "kernel/kernel_shader.h"
-#ifdef WITH_PTEX
-# include <Ptexture.h>
-#endif
-
CCL_NAMESPACE_BEGIN
/* RenderServices implementation */
@@ -126,35 +122,16 @@ ustring OSLRenderServices::u_u("u");
ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
-OSLRenderServices::OSLRenderServices()
+OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system)
+ : texture_system(texture_system)
{
- kernel_globals = NULL;
- osl_globals = NULL;
- osl_ts = NULL;
-
-#ifdef WITH_PTEX
- size_t maxmem = 16384 * 1024;
- ptex_cache = PtexCache::create(0, maxmem);
-#endif
}
OSLRenderServices::~OSLRenderServices()
{
- if (osl_ts) {
- VLOG(2) << "OSL texture system stats:\n" << osl_ts->getstats();
+ if (texture_system) {
+ VLOG(2) << "OSL texture system stats:\n" << texture_system->getstats();
}
-#ifdef WITH_PTEX
- ptex_cache->release();
-#endif
-}
-
-void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_,
- OSLGlobals *osl_globals_,
- OSL::TextureSystem *osl_ts_)
-{
- kernel_globals = kernel_globals_;
- osl_globals = osl_globals_;
- osl_ts = osl_ts_;
}
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
@@ -166,6 +143,7 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
* a concept of shader space, so we just use object space for both. */
if (xform) {
const ShaderData *sd = (const ShaderData *)xform;
+ KernelGlobals *kg = sd->osl_globals;
int object = sd->object;
if (object != OBJECT_NONE) {
@@ -175,9 +153,9 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
if (time == sd->time)
tfm = sd->ob_tfm;
else
- tfm = object_fetch_transform_motion_test(kernel_globals, object, time, NULL);
+ tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
#else
- Transform tfm = object_fetch_transform(kernel_globals, object, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
copy_matrix(result, tfm);
@@ -202,6 +180,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
* a concept of shader space, so we just use object space for both. */
if (xform) {
const ShaderData *sd = (const ShaderData *)xform;
+ KernelGlobals *kg = sd->osl_globals;
int object = sd->object;
if (object != OBJECT_NONE) {
@@ -211,9 +190,9 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
if (time == sd->time)
itfm = sd->ob_itfm;
else
- object_fetch_transform_motion_test(kernel_globals, object, time, &itfm);
+ object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
- Transform itfm = object_fetch_transform(kernel_globals, object, OBJECT_INVERSE_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
copy_matrix(result, itfm);
@@ -234,7 +213,8 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
ustring from,
float time)
{
- KernelGlobals *kg = kernel_globals;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
if (from == u_ndc) {
copy_matrix(result, kernel_data.cam.ndctoworld);
@@ -265,7 +245,8 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
ustring to,
float time)
{
- KernelGlobals *kg = kernel_globals;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
if (to == u_ndc) {
copy_matrix(result, kernel_data.cam.worldtondc);
@@ -305,7 +286,8 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_tfm;
#else
- Transform tfm = object_fetch_transform(kernel_globals, object, OBJECT_TRANSFORM);
+ KernelGlobals *kg = sd->osl_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
copy_matrix(result, tfm);
@@ -335,7 +317,8 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
#else
- Transform tfm = object_fetch_transform(kernel_globals, object, OBJECT_INVERSE_TRANSFORM);
+ KernelGlobals *kg = sd->osl_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
copy_matrix(result, tfm);
@@ -353,7 +336,8 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from)
{
- KernelGlobals *kg = kernel_globals;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
if (from == u_ndc) {
copy_matrix(result, kernel_data.cam.ndctoworld);
@@ -379,7 +363,8 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
ustring to)
{
- KernelGlobals *kg = kernel_globals;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kg = sd->osl_globals;
if (to == u_ndc) {
copy_matrix(result, kernel_data.cam.worldtondc);
@@ -891,15 +876,15 @@ bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
bool OSLRenderServices::get_attribute(
ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
{
- KernelGlobals *kg = kernel_globals;
+ KernelGlobals *kg = sd->osl_globals;
int prim_type = 0;
int object;
/* lookup of attribute on another object */
if (object_name != u_empty) {
- OSLGlobals::ObjectNameMap::iterator it = osl_globals->object_name_map.find(object_name);
+ OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
- if (it == osl_globals->object_name_map.end())
+ if (it == kg->osl->object_name_map.end())
return false;
object = it->second;
@@ -914,7 +899,7 @@ bool OSLRenderServices::get_attribute(
/* find attribute on object */
object = object * ATTR_PRIM_TYPES + prim_type;
- OSLGlobals::AttributeMap &attribute_map = osl_globals->attribute_map[object];
+ OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
if (it != attribute_map.end()) {
@@ -955,26 +940,26 @@ bool OSLRenderServices::get_userdata(
TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename)
{
- OSLTextureHandleMap::iterator it = osl_globals->textures.find(filename);
+ OSLTextureHandleMap::iterator it = textures.find(filename);
/* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
- if (it != osl_globals->textures.end()) {
+ if (it != textures.end()) {
if (it->second->type != OSLTextureHandle::OIIO) {
return (TextureSystem::TextureHandle *)it->second.get();
}
}
/* Get handle from OpenImageIO. */
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
if (handle == NULL) {
return NULL;
}
/* Insert new OSLTextureHandle if needed. */
- if (it == osl_globals->textures.end()) {
- osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
- it = osl_globals->textures.find(filename);
+ if (it == textures.end()) {
+ textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
+ it = textures.find(filename);
}
/* Assign OIIO texture handle and return. */
@@ -987,7 +972,7 @@ bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
if (handle->oiio_handle) {
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
return ts->good(handle->oiio_handle);
}
else {
@@ -1014,13 +999,14 @@ bool OSLRenderServices::texture(ustring filename,
{
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kernel_globals = sd->osl_globals;
bool status = false;
switch (texture_type) {
case OSLTextureHandle::BEVEL: {
/* Bevel shader hack. */
if (nchannels >= 3) {
- ShaderData *sd = (ShaderData *)(sg->renderstate);
PathState *state = sd->osl_path_state;
int num_samples = (int)s;
float radius = t;
@@ -1034,7 +1020,6 @@ bool OSLRenderServices::texture(ustring filename,
}
case OSLTextureHandle::AO: {
/* AO shader hack. */
- ShaderData *sd = (ShaderData *)(sg->renderstate);
PathState *state = sd->osl_path_state;
int num_samples = (int)s;
float radius = t;
@@ -1075,7 +1060,7 @@ bool OSLRenderServices::texture(ustring filename,
}
case OSLTextureHandle::OIIO: {
/* OpenImageIO texture cache. */
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
if (handle && handle->oiio_handle) {
if (texture_thread_info == NULL) {
@@ -1161,6 +1146,8 @@ bool OSLRenderServices::texture3d(ustring filename,
switch (texture_type) {
case OSLTextureHandle::SVM: {
/* Packed texture. */
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kernel_globals = sd->osl_globals;
int slot = handle->svm_slot;
float4 rgba = kernel_tex_image_interp_3d(
kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
@@ -1177,10 +1164,12 @@ bool OSLRenderServices::texture3d(ustring filename,
}
case OSLTextureHandle::OIIO: {
/* OpenImageIO texture cache. */
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
if (handle && handle->oiio_handle) {
if (texture_thread_info == NULL) {
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kernel_globals = sd->osl_globals;
OSLThreadData *tdata = kernel_globals->osl_tdata;
texture_thread_info = tdata->oiio_thread_info;
}
@@ -1259,11 +1248,13 @@ bool OSLRenderServices::environment(ustring filename,
ustring *errormessage)
{
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
bool status = false;
if (handle && handle->oiio_handle) {
if (thread_info == NULL) {
+ ShaderData *sd = (ShaderData *)(sg->renderstate);
+ KernelGlobals *kernel_globals = sd->osl_globals;
OSLThreadData *tdata = kernel_globals->osl_tdata;
thread_info = tdata->oiio_thread_info;
}
@@ -1317,7 +1308,7 @@ bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
}
/* Get texture info from OpenImageIO. */
- OSL::TextureSystem *ts = osl_ts;
+ OSL::TextureSystem *ts = texture_system;
return ts->get_texture_info(filename, subimage, dataname, datatype, data);
}
@@ -1399,10 +1390,11 @@ bool OSLRenderServices::trace(TraceOpt &options,
tracedata->ray = ray;
tracedata->setup = false;
tracedata->init = true;
+ tracedata->sd.osl_globals = sd->osl_globals;
/* Raytrace, leaving out shadow opaque to avoid early exit. */
uint visibility = PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE;
- return scene_intersect(kernel_globals, ray, visibility, &tracedata->isect);
+ return scene_intersect(sd->osl_globals, ray, visibility, &tracedata->isect);
}
bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
@@ -1425,10 +1417,11 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
}
else {
ShaderData *sd = &tracedata->sd;
+ KernelGlobals *kg = sd->osl_globals;
if (!tracedata->setup) {
/* lazy shader data setup */
- shader_setup_from_ray(kernel_globals, sd, &tracedata->isect, &tracedata->ray);
+ shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray);
tracedata->setup = true;
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index e881e528fc5..024ef656be1 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -40,13 +40,46 @@ class Shader;
struct ShaderData;
struct float3;
struct KernelGlobals;
+
+/* OSL Texture Handle
+ *
+ * OSL texture lookups are string based. If those strings are known at compile
+ * time, the OSL compiler can cache a texture handle to use instead of a string.
+ *
+ * By default it uses TextureSystem::TextureHandle. But since we want to support
+ * different kinds of textures and color space conversions, this is our own handle
+ * with additional data.
+ *
+ * These are stored in a concurrent hash map, because OSL can compile multiple
+ * shaders in parallel. */
+
+struct OSLTextureHandle : public OIIO::RefCnt {
+ enum Type { OIIO, SVM, IES, BEVEL, AO };
+
+ OSLTextureHandle(Type type = OIIO, int svm_slot = -1)
+ : type(type), svm_slot(svm_slot), oiio_handle(NULL), processor(NULL)
+ {
+ }
+
+ Type type;
+ int svm_slot;
+ OSL::TextureSystem::TextureHandle *oiio_handle;
+ ColorSpaceProcessor *processor;
+};
+
+typedef OIIO::intrusive_ptr<OSLTextureHandle> OSLTextureHandleRef;
+typedef OIIO::unordered_map_concurrent<ustring, OSLTextureHandleRef, ustringHash>
+ OSLTextureHandleMap;
+
+/* OSL Render Services
+ *
+ * Interface for OSL to access attributes, textures and other scene data. */
+
class OSLRenderServices : public OSL::RendererServices {
public:
- OSLRenderServices();
+ OSLRenderServices(OSL::TextureSystem *texture_system);
~OSLRenderServices();
- void thread_init(KernelGlobals *kernel_globals, OSLGlobals *osl_globals, OSL::TextureSystem *ts);
-
bool get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform,
@@ -255,13 +288,12 @@ class OSLRenderServices : public OSL::RendererServices {
static ustring u_at_bevel;
static ustring u_at_ao;
- private:
- KernelGlobals *kernel_globals;
- OSLGlobals *osl_globals;
- OSL::TextureSystem *osl_ts;
-#ifdef WITH_PTEX
- PtexCache *ptex_cache;
-#endif
+ /* Texture system and texture handle map are part of the services instead of
+ * globals to be shared between different render sessions. This saves memory,
+ * and is required because texture handles are cached as part of the shared
+ * shading system. */
+ OSL::TextureSystem *texture_system;
+ OSLTextureHandleMap textures;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 69599825bc0..db5ad06d3fc 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -49,7 +49,6 @@ void OSLShader::thread_init(KernelGlobals *kg,
/* per thread kernel data init*/
kg->osl = osl_globals;
- kg->osl->services->thread_init(kernel_globals, osl_globals, osl_globals->ts);
OSL::ShadingSystem *ss = kg->osl->ss;
OSLThreadData *tdata = new OSLThreadData();
@@ -129,13 +128,13 @@ static void shaderdata_to_shaderglobals(
tdata->tracedata.init = false;
/* used by renderservices */
+ sd->osl_globals = kg;
sd->osl_path_state = state;
}
/* Surface */
-static void flatten_surface_closure_tree(KernelGlobals *kg,
- ShaderData *sd,
+static void flatten_surface_closure_tree(ShaderData *sd,
int path_flag,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
@@ -146,14 +145,13 @@ static void flatten_surface_closure_tree(KernelGlobals *kg,
switch (closure->id) {
case OSL::ClosureColor::MUL: {
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_surface_closure_tree(
- kg, sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
break;
}
case OSL::ClosureColor::ADD: {
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_surface_closure_tree(kg, sd, path_flag, add->closureA, weight);
- flatten_surface_closure_tree(kg, sd, path_flag, add->closureB, weight);
+ flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
+ flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
break;
}
default: {
@@ -164,7 +162,7 @@ static void flatten_surface_closure_tree(KernelGlobals *kg,
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(kg, sd, path_flag, weight);
+ prim->setup(sd, path_flag, weight);
}
break;
}
@@ -235,13 +233,12 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state
/* flatten closure tree */
if (globals->Ci)
- flatten_surface_closure_tree(kg, sd, path_flag, globals->Ci);
+ flatten_surface_closure_tree(sd, path_flag, globals->Ci);
}
/* Background */
-static void flatten_background_closure_tree(KernelGlobals *kg,
- ShaderData *sd,
+static void flatten_background_closure_tree(ShaderData *sd,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
@@ -252,14 +249,14 @@ static void flatten_background_closure_tree(KernelGlobals *kg,
switch (closure->id) {
case OSL::ClosureColor::MUL: {
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_background_closure_tree(kg, sd, mul->closure, weight * TO_FLOAT3(mul->weight));
+ flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight));
break;
}
case OSL::ClosureColor::ADD: {
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_background_closure_tree(kg, sd, add->closureA, weight);
- flatten_background_closure_tree(kg, sd, add->closureB, weight);
+ flatten_background_closure_tree(sd, add->closureA, weight);
+ flatten_background_closure_tree(sd, add->closureB, weight);
break;
}
default: {
@@ -270,7 +267,7 @@ static void flatten_background_closure_tree(KernelGlobals *kg,
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(kg, sd, 0, weight);
+ prim->setup(sd, 0, weight);
}
break;
}
@@ -294,13 +291,12 @@ void OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, PathState *st
/* return background color immediately */
if (globals->Ci)
- flatten_background_closure_tree(kg, sd, globals->Ci);
+ flatten_background_closure_tree(sd, globals->Ci);
}
/* Volume */
-static void flatten_volume_closure_tree(KernelGlobals *kg,
- ShaderData *sd,
+static void flatten_volume_closure_tree(ShaderData *sd,
const OSL::ClosureColor *closure,
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
@@ -310,13 +306,13 @@ static void flatten_volume_closure_tree(KernelGlobals *kg,
switch (closure->id) {
case OSL::ClosureColor::MUL: {
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_volume_closure_tree(kg, sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
+ flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
break;
}
case OSL::ClosureColor::ADD: {
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_volume_closure_tree(kg, sd, add->closureA, weight);
- flatten_volume_closure_tree(kg, sd, add->closureB, weight);
+ flatten_volume_closure_tree(sd, add->closureA, weight);
+ flatten_volume_closure_tree(sd, add->closureB, weight);
break;
}
default: {
@@ -327,7 +323,7 @@ static void flatten_volume_closure_tree(KernelGlobals *kg,
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
weight = weight * TO_FLOAT3(comp->w);
#endif
- prim->setup(kg, sd, 0, weight);
+ prim->setup(sd, 0, weight);
}
}
}
@@ -351,7 +347,7 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state,
/* flatten closure tree */
if (globals->Ci)
- flatten_volume_closure_tree(kg, sd, globals->Ci);
+ flatten_volume_closure_tree(sd, globals->Ci);
}
/* Displacement */