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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-14 13:13:43 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-14 13:24:15 +0300
commitb50cf33d917b3e0fe7152cff96996e5a850c68d4 (patch)
tree775a7e8a6129e634d8a4982671fa0999a76444e7 /intern
parent9fecac32d9e9f3e6dd69f89fe4ceaddcecaf1277 (diff)
Fix T64515, T60434: crash in OSL and preview render after recent changes
The refactoring of texture handles did not take into account that render services are shared between multiple render session. Now the texture to handle map is also shared between render sessions.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-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
-rw-r--r--intern/cycles/render/osl.cpp79
-rw-r--r--intern/cycles/render/osl.h19
14 files changed, 194 insertions, 222 deletions
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 4070d5a8992..18d2a216f72 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -981,6 +981,7 @@ typedef ccl_addr_space struct ShaderData {
differential3 ray_dP;
#ifdef __OSL__
+ struct KernelGlobals *osl_globals;
struct PathState *osl_path_state;
#endif
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 */
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index a65c8e9f338..4bc18e53c9b 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -54,6 +54,7 @@ OSLRenderServices *OSLShaderManager::services_shared = NULL;
int OSLShaderManager::ss_shared_users = 0;
thread_mutex OSLShaderManager::ss_shared_mutex;
thread_mutex OSLShaderManager::ss_mutex;
+int OSLCompiler::texture_shared_unique_id = 0;
/* Shader Manager */
@@ -105,11 +106,6 @@ void OSLShaderManager::device_update(Device *device,
/* create shaders */
OSLGlobals *og = (OSLGlobals *)device->osl_memory();
- /* Partial thread init of services, the OSL compiler can query data like
- * constant texture handles. This will be done again right before rendering
- * with full data available. */
- services->thread_init(NULL, og, ts);
-
foreach (Shader *shader, scene->shaders) {
assert(shader->graph);
@@ -121,9 +117,9 @@ void OSLShaderManager::device_update(Device *device,
* compile shaders alternating */
thread_scoped_lock lock(ss_mutex);
- OSLCompiler compiler((void *)this, (void *)ss, og, scene->image_manager, scene->light_manager);
+ OSLCompiler compiler(this, services, ss, scene->image_manager, scene->light_manager);
compiler.background = (shader == scene->default_background);
- compiler.compile(scene, shader);
+ compiler.compile(scene, og, shader);
if (shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
@@ -147,8 +143,8 @@ void OSLShaderManager::device_update(Device *device,
scene->image_manager->set_osl_texture_system((void *)ts);
/* add special builtin texture types */
- og->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
- og->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
+ services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
+ services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
device_update_common(device, dscene, scene, progress);
@@ -228,7 +224,7 @@ void OSLShaderManager::shading_system_init()
thread_scoped_lock lock(ss_shared_mutex);
if (ss_shared_users == 0) {
- services_shared = new OSLRenderServices();
+ services_shared = new OSLRenderServices(ts_shared);
string shader_path = path_get("shader");
# ifdef _WIN32
@@ -565,17 +561,17 @@ OSLNode *OSLShaderManager::osl_node(const std::string &filepath,
/* Graph Compiler */
-OSLCompiler::OSLCompiler(void *manager_,
- void *shadingsys_,
- OSLGlobals *osl_globals_,
- ImageManager *image_manager_,
- LightManager *light_manager_)
+OSLCompiler::OSLCompiler(OSLShaderManager *manager,
+ OSLRenderServices *services,
+ OSL::ShadingSystem *ss,
+ ImageManager *image_manager,
+ LightManager *light_manager)
+ : image_manager(image_manager),
+ light_manager(light_manager),
+ manager(manager),
+ services(services),
+ ss(ss)
{
- manager = manager_;
- shadingsys = shadingsys_;
- osl_globals = osl_globals_;
- image_manager = image_manager_;
- light_manager = light_manager_;
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
background = false;
@@ -661,11 +657,9 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
-
/* load filepath */
if (isfilepath) {
- name = ((OSLShaderManager *)manager)->shader_load_filepath(name);
+ name = manager->shader_load_filepath(name);
if (name == NULL)
return;
@@ -743,7 +737,7 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
}
/* test if we shader contains specific closures */
- OSLShaderInfo *info = ((OSLShaderManager *)manager)->shader_loaded_info(name);
+ OSLShaderInfo *info = manager->shader_loaded_info(name);
if (current_type == SHADER_TYPE_SURFACE) {
if (info) {
@@ -790,7 +784,6 @@ static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength)
void OSLCompiler::parameter(ShaderNode *node, const char *name)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ustring uname = ustring(name);
const SocketType &socket = *(node->type->find_input(uname));
@@ -942,56 +935,47 @@ void OSLCompiler::parameter(ShaderNode *node, const char *name)
void OSLCompiler::parameter(const char *name, float f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeFloat, &f);
}
void OSLCompiler::parameter_color(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeColor, &f);
}
void OSLCompiler::parameter_point(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypePoint, &f);
}
void OSLCompiler::parameter_normal(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeNormal, &f);
}
void OSLCompiler::parameter_vector(const char *name, float3 f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeVector, &f);
}
void OSLCompiler::parameter(const char *name, int f)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeInt, &f);
}
void OSLCompiler::parameter(const char *name, const char *s)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ss->Parameter(name, TypeDesc::TypeString, &s);
}
void OSLCompiler::parameter(const char *name, ustring s)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
const char *str = s.c_str();
ss->Parameter(name, TypeDesc::TypeString, &str);
}
void OSLCompiler::parameter(const char *name, const Transform &tfm)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
ProjectionTransform projection(tfm);
projection = projection_transpose(projection);
ss->Parameter(name, TypeDesc::TypeMatrix, (float *)&projection);
@@ -999,7 +983,6 @@ void OSLCompiler::parameter(const char *name, const Transform &tfm)
void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
TypeDesc type = TypeDesc::TypeFloat;
type.arraylen = arraylen;
ss->Parameter(name, type, f);
@@ -1016,7 +999,6 @@ void OSLCompiler::parameter_color_array(const char *name, const array<float3> &f
table[i][2] = f[i].z;
}
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
TypeDesc type = TypeDesc::TypeColor;
type.arraylen = table.size();
ss->Parameter(name, type, table.data());
@@ -1094,8 +1076,6 @@ void OSLCompiler::generate_nodes(const ShaderNodeSet &nodes)
OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)shadingsys;
-
current_type = type;
OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
@@ -1135,7 +1115,7 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
return group;
}
-void OSLCompiler::compile(Scene *scene, Shader *shader)
+void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
{
if (shader->need_update) {
ShaderGraph *graph = shader->graph;
@@ -1200,10 +1180,10 @@ void OSLCompiler::compile(Scene *scene, Shader *shader)
}
/* push state to array for lookup */
- osl_globals->surface_state.push_back(shader->osl_surface_ref);
- osl_globals->volume_state.push_back(shader->osl_volume_ref);
- osl_globals->displacement_state.push_back(shader->osl_displacement_ref);
- osl_globals->bump_state.push_back(shader->osl_surface_bump_ref);
+ og->surface_state.push_back(shader->osl_surface_ref);
+ og->volume_state.push_back(shader->osl_volume_ref);
+ og->displacement_state.push_back(shader->osl_displacement_ref);
+ og->bump_state.push_back(shader->osl_surface_bump_ref);
}
void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring colorspace)
@@ -1212,7 +1192,7 @@ void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring
* case we need to do runtime color space conversion. */
OSLTextureHandle *handle = new OSLTextureHandle(OSLTextureHandle::OIIO);
handle->processor = ColorSpaceManager::get_processor(colorspace);
- osl_globals->textures.insert(filename, handle);
+ services->textures.insert(filename, handle);
parameter(name, filename);
}
@@ -1220,17 +1200,18 @@ void OSLCompiler::parameter_texture(const char *name, int svm_slot)
{
/* Texture loaded through SVM image texture system. We generate a unique
* name, which ends up being used in OSLRenderServices::get_texture_handle
- * to get handle again. */
- ustring filename(string_printf("@i%d", svm_slot).c_str());
- osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::SVM, svm_slot));
+ * to get handle again. Note that this name must be unique between multiple
+ * render sessions as the render services are shared. */
+ ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
+ services->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::SVM, svm_slot));
parameter(name, filename);
}
void OSLCompiler::parameter_texture_ies(const char *name, int svm_slot)
{
/* IES light textures stored in SVM. */
- ustring filename(string_printf("@l%d", svm_slot).c_str());
- osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
+ ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
+ services->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
parameter(name, filename);
}
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index ac73f1d3c24..17bf98a3433 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -127,12 +127,14 @@ class OSLShaderManager : public ShaderManager {
class OSLCompiler {
public:
- OSLCompiler(void *manager,
- void *shadingsys,
- OSLGlobals *osl_globals,
+#ifdef WITH_OSL
+ OSLCompiler(OSLShaderManager *manager,
+ OSLRenderServices *services,
+ OSL::ShadingSystem *shadingsys,
ImageManager *image_manager,
LightManager *light_manager);
- void compile(Scene *scene, Shader *shader);
+#endif
+ void compile(Scene *scene, OSLGlobals *og, Shader *shader);
void add(ShaderNode *node, const char *name, bool isfilepath = false);
@@ -176,13 +178,16 @@ class OSLCompiler {
void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input);
void generate_nodes(const ShaderNodeSet &nodes);
+
+ OSLShaderManager *manager;
+ OSLRenderServices *services;
+ OSL::ShadingSystem *ss;
#endif
- void *shadingsys;
- void *manager;
- OSLGlobals *osl_globals;
ShaderType current_type;
Shader *current_shader;
+
+ static int texture_shared_unique_id;
};
CCL_NAMESPACE_END