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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-12-01 23:15:05 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-12-01 23:15:05 +0400
commit7c0a0bae79bb8f842a575fe83975c6d34d73c64a (patch)
tree844857e85903601f60a083d767d6317f3006d31f /intern/cycles/kernel
parent807fd448a557fbacb70fcd9b5cae76529fdb9b80 (diff)
Fix #33375: OSL geom:trianglevertices gave wrong coordinates for static BVH.
Also some simple OSL optimization, passing thread data pointer directly instead of via thread local storage, and creating ustrings for attribute lookup.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel.cpp32
-rw-r--r--intern/cycles/kernel/kernel_attribute.h22
-rw-r--r--intern/cycles/kernel/kernel_globals.h18
-rw-r--r--intern/cycles/kernel/kernel_path.h6
-rw-r--r--intern/cycles/kernel/kernel_shader.h34
-rw-r--r--intern/cycles/kernel/kernel_triangle.h3
-rw-r--r--intern/cycles/kernel/kernel_types.h9
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp3
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h26
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp121
-rw-r--r--intern/cycles/kernel/osl/osl_services.h33
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp111
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h21
13 files changed, 232 insertions, 207 deletions
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index 62d79bdd946..d760e63a290 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -29,38 +29,6 @@
CCL_NAMESPACE_BEGIN
-/* Globals */
-
-KernelGlobals *kernel_globals_create()
-{
- KernelGlobals *kg = new KernelGlobals();
-#ifdef WITH_OSL
- kg->osl.use = false;
-#endif
- return kg;
-}
-
-void kernel_globals_free(KernelGlobals *kg)
-{
- delete kg;
-}
-
-/* OSL */
-
-#ifdef WITH_OSL
-
-void *kernel_osl_memory(KernelGlobals *kg)
-{
- return (void*)&kg->osl;
-}
-
-bool kernel_osl_use(KernelGlobals *kg)
-{
- return kg->osl.use;
-}
-
-#endif
-
/* Memory Copy */
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size)
diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h
index 2774f5e924b..b7ad731c883 100644
--- a/intern/cycles/kernel/kernel_attribute.h
+++ b/intern/cycles/kernel/kernel_attribute.h
@@ -19,13 +19,6 @@
#ifndef __KERNEL_ATTRIBUTE_CL__
#define __KERNEL_ATTRIBUTE_CL__
-#include "util_types.h"
-
-#ifdef __OSL__
-#include <string>
-#include "util_attribute.h"
-#endif
-
CCL_NAMESPACE_BEGIN
/* note: declared in kernel.h, have to add it here because kernel.h is not available */
@@ -33,20 +26,9 @@ bool kernel_osl_use(KernelGlobals *kg);
__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
{
-
#ifdef __OSL__
- if (kernel_osl_use(kg)) {
- /* for OSL, a hash map is used to lookup the attribute by name. */
- OSLGlobals::AttributeMap &attr_map = kg->osl.attribute_map[sd->object];
- ustring stdname(std::string("std::") + std::string(attribute_standard_name((AttributeStandard)id)));
- OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
- if (it != attr_map.end()) {
- const OSLGlobals::Attribute &osl_attr = it->second;
- /* return result */
- return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
- }
- else
- return (int)ATTR_STD_NOT_FOUND;
+ if (kg->osl) {
+ return OSLShader::find_attribute(kg, sd, id);
}
else
#endif
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index 1e56c11ab90..529b7b8768f 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -18,14 +18,6 @@
/* Constant Globals */
-#ifdef __KERNEL_CPU__
-
-#ifdef __OSL__
-#include "osl_globals.h"
-#endif
-
-#endif
-
CCL_NAMESPACE_BEGIN
/* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in
@@ -35,6 +27,12 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_CPU__
+#ifdef __OSL__
+struct OSLGlobals;
+struct OSLThreadData;
+struct OSLShadingSystem;
+#endif
+
#define MAX_BYTE_IMAGES 512
#define MAX_FLOAT_IMAGES 5
@@ -51,7 +49,9 @@ typedef struct KernelGlobals {
#ifdef __OSL__
/* On the CPU, we also have the OSL globals here. Most data structures are shared
* with SVM, the difference is in the shaders and object/mesh attributes. */
- OSLGlobals osl;
+ OSLGlobals *osl;
+ OSLShadingSystem *osl_ss;
+ OSLThreadData *osl_tdata;
#endif
} KernelGlobals;
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 195291898c6..3588b09c790 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -16,10 +16,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#ifdef __OSL__
+#include "osl_shader.h"
+#endif
+
#include "kernel_differential.h"
#include "kernel_montecarlo.h"
#include "kernel_projection.h"
#include "kernel_object.h"
+#include "kernel_attribute.h"
+#include "kernel_projection.h"
#include "kernel_triangle.h"
#ifdef __QBVH__
#include "kernel_qbvh.h"
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 879160312cf..43ad4b1265a 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -26,10 +26,6 @@
*
*/
-#ifdef __OSL__
-#include "osl_shader.h"
-#endif
-
#include "closure/bsdf.h"
#include "closure/emissive.h"
#include "closure/volume.h"
@@ -61,7 +57,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::init(kg, sd);
#endif
@@ -147,7 +143,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
int shader, int object, int prim, float u, float v, float t, float time)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::init(kg, sd);
#endif
@@ -278,7 +274,7 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
__device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::init(kg, sd);
#endif
@@ -387,7 +383,7 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
else
#endif
@@ -444,7 +440,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
*pdf = 0.0f;
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
else
#endif
@@ -456,7 +452,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
if(sd->num_closure > 1) {
float sweight = sc->sample_weight;
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
_shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
else
#endif
@@ -483,7 +479,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
*pdf = 0.0f;
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
else
#endif
@@ -503,7 +499,7 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes
if(CLOSURE_IS_BSDF(sc->type)) {
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::bsdf_blur(sc, roughness);
else
#endif
@@ -650,7 +646,7 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
if(CLOSURE_IS_EMISSION(sc->type)) {
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
else
#endif
@@ -694,7 +690,7 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
float randb, int path_flag)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::eval_surface(kg, sd, randb, path_flag);
else
#endif
@@ -713,7 +709,7 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
return OSLShader::eval_background(kg, sd, path_flag);
else
#endif
@@ -759,7 +755,7 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
if(CLOSURE_IS_VOLUME(sc->type)) {
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
else
#endif
@@ -780,7 +776,7 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
{
#ifdef __SVM__
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::eval_volume(kg, sd, randb, path_flag);
else
#endif
@@ -795,7 +791,7 @@ __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
/* this will modify sd->P */
#ifdef __SVM__
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::eval_displacement(kg, sd);
else
#endif
@@ -851,7 +847,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __OSL__
- if (kernel_osl_use(kg))
+ if (kg->osl)
OSLShader::release(kg, sd);
#endif
}
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index e39ae1d4fbc..0db447289c8 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -16,9 +16,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
-
CCL_NAMESPACE_BEGIN
/* Point on triangle for Moller-Trumbore triangles */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f519fd989fa..e3a766e56b1 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -366,9 +366,6 @@ typedef struct ShaderClosure {
float sample_weight;
#endif
-#ifdef __OSL__
- void *prim;
-#endif
float data0;
float data1;
@@ -377,6 +374,9 @@ typedef struct ShaderClosure {
float3 T;
#endif
+#ifdef __OSL__
+ void *prim;
+#endif
} ShaderClosure;
/* Shader Data
@@ -403,7 +403,8 @@ enum ShaderDataFlag {
/* object flags */
SD_HOLDOUT_MASK = 4096, /* holdout for camera rays */
- SD_OBJECT_MOTION = 8192 /* has object motion blur */
+ SD_OBJECT_MOTION = 8192, /* has object motion blur */
+ SD_TRANSFORM_APPLIED = 16384 /* vertices have transform applied */
};
typedef struct ShaderData {
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index d42d65608c8..f95859d237d 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -153,8 +153,9 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O
ss->register_closure(name, id, params, prepare, generic_closure_setup, generic_closure_compare);
}
-void OSLShader::register_closures(OSL::ShadingSystem *ss)
+void OSLShader::register_closures(OSLShadingSystem *ss_)
{
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)ss_;
int id = 0;
register_closure(ss, "diffuse", id++,
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index ce283023c5c..1a2a210de88 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -38,7 +38,14 @@ CCL_NAMESPACE_BEGIN
class OSLRenderServices;
struct OSLGlobals {
- /* use */
+ OSLGlobals()
+ {
+ ss = NULL;
+ ts = NULL;
+ services = NULL;
+ use = false;
+ }
+
bool use;
/* shading system */
@@ -66,19 +73,12 @@ struct OSLGlobals {
vector<AttributeMap> attribute_map;
ObjectNameMap object_name_map;
vector<ustring> object_names;
+};
- /* thread key for thread specific data lookup */
- struct ThreadData {
- OSL::ShaderGlobals globals;
- OSL::PerThreadInfo *thread_info;
- };
-
- static tls_ptr(ThreadData, thread_data);
- static thread_mutex thread_data_mutex;
- static volatile int thread_data_users;
-
- void thread_data_init();
- void thread_data_free();
+/* thread key for thread specific data lookup */
+struct OSLThreadData {
+ OSL::ShaderGlobals globals;
+ OSL::PerThreadInfo *thread_info;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index e593387093c..b584a54b1b7 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -23,6 +23,7 @@
#include "scene.h"
#include "osl_closures.h"
+#include "osl_globals.h"
#include "osl_services.h"
#include "osl_shader.h"
@@ -36,6 +37,8 @@
#include "kernel_differential.h"
#include "kernel_object.h"
#include "kernel_bvh.h"
+#include "kernel_attribute.h"
+#include "kernel_projection.h"
#include "kernel_triangle.h"
#include "kernel_accumulate.h"
#include "kernel_shader.h"
@@ -53,6 +56,34 @@ ustring OSLRenderServices::u_camera("camera");
ustring OSLRenderServices::u_screen("screen");
ustring OSLRenderServices::u_raster("raster");
ustring OSLRenderServices::u_ndc("NDC");
+ustring OSLRenderServices::u_object_location("object:location");
+ustring OSLRenderServices::u_object_index("object:index");
+ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
+ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
+ustring OSLRenderServices::u_material_index("material:index");
+ustring OSLRenderServices::u_object_random("object:random");
+ustring OSLRenderServices::u_particle_index("particle:index");
+ustring OSLRenderServices::u_particle_age("particle:age");
+ustring OSLRenderServices::u_particle_lifetime("particle:lifetime");
+ustring OSLRenderServices::u_particle_location("particle:location");
+ustring OSLRenderServices::u_particle_rotation("particle:rotation");
+ustring OSLRenderServices::u_particle_size("particle:size");
+ustring OSLRenderServices::u_particle_velocity("particle:velocity");
+ustring OSLRenderServices::u_particle_angular_velocity("particle:angular_velocity");
+ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
+ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
+ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
+ustring OSLRenderServices::u_geom_name("geom:name");
+ustring OSLRenderServices::u_path_ray_length("path:ray_length");
+ustring OSLRenderServices::u_trace("trace");
+ustring OSLRenderServices::u_hit("hit");
+ustring OSLRenderServices::u_hitdist("hitdist");
+ustring OSLRenderServices::u_N("N");
+ustring OSLRenderServices::u_Ng("Ng");
+ustring OSLRenderServices::u_P("P");
+ustring OSLRenderServices::u_I("I");
+ustring OSLRenderServices::u_u("u");
+ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
OSLRenderServices::OSLRenderServices()
@@ -488,104 +519,108 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat
memset((char *)val + datasize, 0, datasize * 2);
}
-static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val)
+bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
+ TypeDesc type, bool derivatives, void *val)
{
- /* todo: turn this into hash table returning int, which can be used in switch */
+ /* todo: turn this into hash table? */
/* Object Attributes */
- if (name == "object:location") {
+ if (name == u_object_location) {
float3 f = object_location(kg, sd);
return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "object:index") {
+ else if (name == u_object_index) {
float f = object_pass_id(kg, sd->object);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "geom:dupli_generated") {
+ else if (name == u_geom_dupli_generated) {
float3 f = object_dupli_generated(kg, sd->object);
return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "geom:dupli_uv") {
+ else if (name == u_geom_dupli_uv) {
float3 f = object_dupli_uv(kg, sd->object);
return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "material:index") {
+ else if (name == u_material_index) {
float f = shader_pass_id(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "object:random") {
+ else if (name == u_object_random) {
float f = object_random_number(kg, sd->object);
return set_attribute_float(f, type, derivatives, val);
}
/* Particle Attributes */
- else if (name == "particle:index") {
+ else if (name == u_particle_index) {
uint particle_id = object_particle_id(kg, sd->object);
float f = particle_index(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "particle:age") {
+ else if (name == u_particle_age) {
uint particle_id = object_particle_id(kg, sd->object);
float f = particle_age(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "particle:lifetime") {
+ else if (name == u_particle_lifetime) {
uint particle_id = object_particle_id(kg, sd->object);
float f= particle_lifetime(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "particle:location") {
+ else if (name == u_particle_location) {
uint particle_id = object_particle_id(kg, sd->object);
float3 f = particle_location(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
#if 0 /* unsupported */
- else if (name == "particle:rotation") {
+ else if (name == u_particle_rotation) {
uint particle_id = object_particle_id(kg, sd->object);
float4 f = particle_rotation(kg, particle_id);
return set_attribute_float4(f, type, derivatives, val);
}
#endif
- else if (name == "particle:size") {
+ else if (name == u_particle_size) {
uint particle_id = object_particle_id(kg, sd->object);
float f = particle_size(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "particle:velocity") {
+ else if (name == u_particle_velocity) {
uint particle_id = object_particle_id(kg, sd->object);
float3 f = particle_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "particle:angular_velocity") {
+ else if (name == u_particle_angular_velocity) {
uint particle_id = object_particle_id(kg, sd->object);
float3 f = particle_angular_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "geom:numpolyvertices") {
+ else if (name == u_geom_numpolyvertices) {
return set_attribute_int(3, type, derivatives, val);
}
- else if (name == "geom:trianglevertices" || name == "geom:polyvertices") {
+ else if (name == u_geom_trianglevertices || name == u_geom_polyvertices) {
float3 P[3];
triangle_vertices(kg, sd->prim, P);
- object_position_transform(kg, sd, &P[0]);
- object_position_transform(kg, sd, &P[1]);
- object_position_transform(kg, sd, &P[2]);
+
+ if(!(sd->flag & SD_TRANSFORM_APPLIED)) {
+ object_position_transform(kg, sd, &P[0]);
+ object_position_transform(kg, sd, &P[1]);
+ object_position_transform(kg, sd, &P[2]);
+ }
+
return set_attribute_float3_3(P, type, derivatives, val);
}
- else if(name == "geom:name") {
- ustring object_name = kg->osl.object_names[sd->object];
+ else if(name == u_geom_name) {
+ ustring object_name = kg->osl->object_names[sd->object];
return set_attribute_string(object_name, type, derivatives, val);
}
else
return false;
}
-static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val)
+bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
+ TypeDesc type, bool derivatives, void *val)
{
/* Ray Length */
- if (name == "path:ray_length") {
+ if (name == u_path_ray_length) {
float f = sd->ray_length;
return set_attribute_float(f, type, derivatives, val);
}
@@ -604,9 +639,9 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
/* lookup of attribute on another object */
if (object_name != u_empty) {
- OSLGlobals::ObjectNameMap::iterator it = kg->osl.object_name_map.find(object_name);
+ OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
- if (it == kg->osl.object_name_map.end())
+ if (it == kg->osl->object_name_map.end())
return false;
object = it->second;
@@ -617,7 +652,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
}
/* find attribute on object */
- OSLGlobals::AttributeMap& attribute_map = kg->osl.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()) {
@@ -663,7 +698,7 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
float s, float t, float dsdx, float dtdx,
float dsdy, float dtdy, float *result)
{
- OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ OSL::TextureSystem *ts = kernel_globals->osl->ts;
bool status = ts->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, result);
if(!status) {
@@ -685,7 +720,7 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
const OSL::Vec3 &dPdz, float *result)
{
- OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ OSL::TextureSystem *ts = kernel_globals->osl->ts;
bool status = ts->texture3d(filename, options, P, dPdx, dPdy, dPdz, result);
if(!status) {
@@ -707,7 +742,7 @@ bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
{
- OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ OSL::TextureSystem *ts = kernel_globals->osl->ts;
bool status = ts->environment(filename, options, R, dRdx, dRdy, result);
if(!status) {
@@ -728,7 +763,7 @@ bool OSLRenderServices::get_texture_info(ustring filename, int subimage,
ustring dataname,
TypeDesc datatype, void *data)
{
- OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ OSL::TextureSystem *ts = kernel_globals->osl->ts;
return ts->get_texture_info(filename, subimage, dataname, datatype, data);
}
@@ -798,12 +833,12 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
{
TraceData *tracedata = (TraceData*)sg->tracedata;
- if(source == "trace" && tracedata) {
- if(name == "hit") {
+ if(source == u_trace && tracedata) {
+ if(name == u_hit) {
return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
}
else if(tracedata->isect.prim != ~0) {
- if(name == "hitdist") {
+ if(name == u_hitdist) {
float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
return set_attribute_float(f, type, derivatives, val);
}
@@ -817,25 +852,25 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
tracedata->setup = true;
}
- if(name == "N") {
+ if(name == u_N) {
return set_attribute_float3(sd->N, type, derivatives, val);
}
- else if(name == "Ng") {
+ else if(name == u_Ng) {
return set_attribute_float3(sd->Ng, type, derivatives, val);
}
- else if(name == "P") {
+ else if(name == u_P) {
float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy};
return set_attribute_float3(f, type, derivatives, val);
}
- else if(name == "I") {
+ else if(name == u_I) {
float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy};
return set_attribute_float3(f, type, derivatives, val);
}
- else if(name == "u") {
+ else if(name == u_u) {
float f[3] = {sd->u, sd->du.dx, sd->du.dy};
return set_attribute_float(f, type, derivatives, val);
}
- else if(name == "v") {
+ else if(name == u_v) {
float f[3] = {sd->v, sd->dv.dx, sd->dv.dy};
return set_attribute_float(f, type, derivatives, val);
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index b5a7bbae7e5..e687700b383 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -101,6 +101,11 @@ public:
bool get_texture_info(ustring filename, int subimage,
ustring dataname, TypeDesc datatype, void *data);
+ static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
+ TypeDesc type, bool derivatives, void *val);
+ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
+ TypeDesc type, bool derivatives, void *val);
+
struct TraceData {
Ray ray;
Intersection isect;
@@ -114,6 +119,34 @@ public:
static ustring u_screen;
static ustring u_raster;
static ustring u_ndc;
+ static ustring u_object_location;
+ static ustring u_object_index;
+ static ustring u_geom_dupli_generated;
+ static ustring u_geom_dupli_uv;
+ static ustring u_material_index;
+ static ustring u_object_random;
+ static ustring u_particle_index;
+ static ustring u_particle_age;
+ static ustring u_particle_lifetime;
+ static ustring u_particle_location;
+ static ustring u_particle_rotation;
+ static ustring u_particle_size;
+ static ustring u_particle_velocity;
+ static ustring u_particle_angular_velocity;
+ static ustring u_geom_numpolyvertices;
+ static ustring u_geom_trianglevertices;
+ static ustring u_geom_polyvertices;
+ static ustring u_geom_name;
+ static ustring u_path_ray_length;
+ static ustring u_trace;
+ static ustring u_hit;
+ static ustring u_hitdist;
+ static ustring u_N;
+ static ustring u_Ng;
+ static ustring u_P;
+ static ustring u_I;
+ static ustring u_u;
+ static ustring u_v;
static ustring u_empty;
private:
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 2d025f12055..67a0e16419c 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -22,65 +22,56 @@
#include "kernel_object.h"
#include "osl_closures.h"
+#include "osl_globals.h"
#include "osl_services.h"
#include "osl_shader.h"
+#include "util_attribute.h"
#include "util_foreach.h"
#include <OSL/oslexec.h>
CCL_NAMESPACE_BEGIN
-tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
-volatile int OSLGlobals::thread_data_users = 0;
-thread_mutex OSLGlobals::thread_data_mutex;
-
/* Threads */
-void OSLGlobals::thread_data_init()
-{
- thread_scoped_lock thread_data_lock(thread_data_mutex);
-
- if(thread_data_users == 0)
- tls_create(OSLGlobals::ThreadData, thread_data);
-
- thread_data_users++;
-}
-
-void OSLGlobals::thread_data_free()
+void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OSLGlobals *osl_globals)
{
- /* thread local storage delete */
- thread_scoped_lock thread_data_lock(thread_data_mutex);
+ /* no osl used? */
+ if(!osl_globals->use) {
+ kg->osl = NULL;
+ return;
+ }
- thread_data_users--;
+ /* per thread kernel data init*/
+ kg->osl = osl_globals;
+ kg->osl->services->thread_init(kernel_globals);
- if(thread_data_users == 0)
- tls_delete(OSLGlobals::ThreadData, thread_data);
-}
-
-void OSLShader::thread_init(KernelGlobals *kg)
-{
- OSL::ShadingSystem *ss = kg->osl.ss;
-
- OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData();
+ OSL::ShadingSystem *ss = kg->osl->ss;
+ OSLThreadData *tdata = new OSLThreadData();
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
tdata->thread_info = ss->create_thread_info();
- tls_set(kg->osl.thread_data, tdata);
-
- kg->osl.services->thread_init(kg);
+ kg->osl_ss = (OSLShadingSystem*)ss;
+ kg->osl_tdata = tdata;
}
void OSLShader::thread_free(KernelGlobals *kg)
{
- OSL::ShadingSystem *ss = kg->osl.ss;
+ if(!kg->osl)
+ return;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
ss->destroy_thread_info(tdata->thread_info);
delete tdata;
+
+ kg->osl = NULL;
+ kg->osl_ss = NULL;
+ kg->osl_tdata = NULL;
}
/* Globals */
@@ -230,8 +221,8 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{
/* gather pointers */
- OSL::ShadingSystem *ss = kg->osl.ss;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
@@ -241,8 +232,8 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int
/* execute shader for this point */
int shader = sd->shader & SHADER_MASK;
- if (kg->osl.surface_state[shader])
- ss->execute(*ctx, *(kg->osl.surface_state[shader]), *globals);
+ if (kg->osl->surface_state[shader])
+ ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
@@ -291,8 +282,8 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
{
/* gather pointers */
- OSL::ShadingSystem *ss = kg->osl.ss;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
@@ -300,8 +291,8 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
/* execute shader for this point */
- if (kg->osl.background_state)
- ss->execute(*ctx, *(kg->osl.background_state), *globals);
+ if (kg->osl->background_state)
+ ss->execute(*ctx, *(kg->osl->background_state), *globals);
/* free trace data */
if(globals->tracedata)
@@ -371,8 +362,8 @@ static void flatten_volume_closure_tree(ShaderData *sd,
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{
/* gather pointers */
- OSL::ShadingSystem *ss = kg->osl.ss;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
@@ -382,8 +373,8 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
/* execute shader */
int shader = sd->shader & SHADER_MASK;
- if (kg->osl.volume_state[shader])
- ss->execute(*ctx, *(kg->osl.volume_state[shader]), *globals);
+ if (kg->osl->volume_state[shader])
+ ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
@@ -398,8 +389,8 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
{
/* gather pointers */
- OSL::ShadingSystem *ss = kg->osl.ss;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
@@ -409,8 +400,8 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
/* execute shader */
int shader = sd->shader & SHADER_MASK;
- if (kg->osl.displacement_state[shader])
- ss->execute(*ctx, *(kg->osl.displacement_state[shader]), *globals);
+ if (kg->osl->displacement_state[shader])
+ ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
@@ -422,15 +413,15 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
void OSLShader::init(KernelGlobals *kg, ShaderData *sd)
{
- OSL::ShadingSystem *ss = kg->osl.ss;
- OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSLThreadData *tdata = kg->osl_tdata;
sd->osl_ctx = ss->get_context(tdata->thread_info);
}
void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
{
- OSL::ShadingSystem *ss = kg->osl.ss;
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
ss->release_context((OSL::ShadingContext *)sd->osl_ctx);
}
@@ -488,5 +479,23 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
return TO_FLOAT3(volume_eval) * sc->weight;
}
+/* Attributes */
+
+int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
+{
+ /* for OSL, a hash map is used to lookup the attribute by name. */
+ OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[sd->object];
+ ustring stdname(std::string("std::") + std::string(attribute_standard_name((AttributeStandard)id)));
+ OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
+
+ if (it != attr_map.end()) {
+ const OSLGlobals::Attribute &osl_attr = it->second;
+ /* return result */
+ return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
+ }
+ else
+ return (int)ATTR_STD_NOT_FOUND;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index 9ff31e9160b..e614f240dc1 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -31,33 +31,27 @@
* This means no thread state must be passed along in the kernel itself.
*/
-#include <OSL/oslexec.h>
-#include <OSL/oslclosure.h>
-
#include "kernel_types.h"
-#include "util_map.h"
-#include "util_param.h"
-#include "util_vector.h"
-
CCL_NAMESPACE_BEGIN
-namespace OSL = ::OSL;
-
-class OSLRenderServices;
class Scene;
+
struct ShaderClosure;
struct ShaderData;
struct differential3;
struct KernelGlobals;
+struct OSLGlobals;
+struct OSLShadingSystem;
+
class OSLShader {
public:
/* init */
- static void register_closures(OSL::ShadingSystem *ss);
+ static void register_closures(OSLShadingSystem *ss);
/* per thread data */
- static void thread_init(KernelGlobals *kg);
+ static void thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OSLGlobals *osl_globals);
static void thread_free(KernelGlobals *kg);
/* eval */
@@ -82,6 +76,9 @@ public:
/* release */
static void init(KernelGlobals *kg, ShaderData *sd);
static void release(KernelGlobals *kg, ShaderData *sd);
+
+ /* attributes */
+ static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
};
CCL_NAMESPACE_END