51 OSL::TextureSystem *OSLShaderManager::ts_shared =
NULL;
52 int OSLShaderManager::ts_shared_users = 0;
57 int OSLShaderManager::ss_shared_users = 0;
60 int OSLCompiler::texture_shared_unique_id = 0;
64 OSLShaderManager::OSLShaderManager()
66 texture_system_init();
67 shading_system_init();
70 OSLShaderManager::~OSLShaderManager()
72 shading_system_free();
73 texture_system_free();
76 void OSLShaderManager::free_memory()
78 # ifdef OSL_HAS_BLENDER_CLEANUP_FIX
84 OSL::pvt::LLVM_Util::Cleanup();
90 shading_system_free();
91 shading_system_init();
94 void OSLShaderManager::device_update(
Device *device,
104 scene->update_stats->osl.times.add_entry({
"device_update", time});
110 device_free(device, dscene,
scene);
116 OSLGlobals *og = (OSLGlobals *)device->
osl_memory();
131 compiler.background = (
shader == background_shader);
132 compiler.compile(og,
shader);
134 if (
shader->get_use_mis() &&
shader->has_surface_emission)
141 og->services = services;
144 og->background_state = og->surface_state[background_id &
SHADER_MASK];
150 update_flags = UPDATE_NONE;
156 device_update_common(device, dscene,
scene, progress);
171 ss->optimize_all_groups();
177 OSLGlobals *og = (OSLGlobals *)device->
osl_memory();
179 device_free_common(device, dscene,
scene);
186 og->surface_state.clear();
187 og->volume_state.clear();
188 og->displacement_state.clear();
189 og->bump_state.clear();
190 og->background_state.reset();
193 void OSLShaderManager::texture_system_init()
198 if (ts_shared_users == 0) {
199 ts_shared = TextureSystem::create(
true);
201 ts_shared->attribute(
"automip", 1);
202 ts_shared->attribute(
"autotile", 64);
203 ts_shared->attribute(
"gray_to_rgb", 1);
206 ts_shared->attribute(
"max_memory_MB", 16384);
213 void OSLShaderManager::texture_system_free()
219 if (ts_shared_users == 0) {
220 ts_shared->invalidate_all(
true);
221 OSL::TextureSystem::destroy(ts_shared);
228 void OSLShaderManager::shading_system_init()
233 if (ss_shared_users == 0) {
235 services_shared = util_aligned_new<OSLRenderServices>(ts_shared);
237 string shader_path =
path_get(
"shader");
247 shader_path = string_to_ansi(shader_path);
251 ss_shared->attribute(
"lockgeom", 1);
252 ss_shared->attribute(
"commonspace",
"world");
253 ss_shared->attribute(
"searchpath:shader", shader_path);
254 ss_shared->attribute(
"greedyjit", 1);
256 VLOG(1) <<
"Using shader search path: " << shader_path;
259 static const char *raytypes[] = {
273 "__unused__",
"volume_scatter",
276 "__unused__",
"diffuse_ancestor",
277 "__unused__",
"__unused__",
"__unused__",
"__unused__",
278 "__unused__",
"__unused__",
"__unused__",
281 const int nraytypes =
sizeof(raytypes) /
sizeof(raytypes[0]);
282 ss_shared->attribute(
"raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
284 OSLShader::register_closures((OSLShadingSystem *)ss_shared);
286 loaded_shaders.clear();
290 services = services_shared;
294 void OSLShaderManager::shading_system_free()
300 if (ss_shared_users == 0) {
305 services_shared =
NULL;
312 bool OSLShaderManager::osl_compile(
const string &inputfile,
const string &outputfile)
316 string shader_path =
path_get(
"shader");
323 string include_path_arg = string(
"-I") + shader_path;
324 options.push_back(include_path_arg);
326 stdosl_path =
path_join(shader_path,
"stdcycles.h");
329 OSL::OSLCompiler *compiler =
new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
330 bool ok = compiler->compile(string_view(inputfile),
options, string_view(stdosl_path));
336 bool OSLShaderManager::osl_query(OSL::OSLQuery &
query,
const string &filepath)
339 return query.open(filepath, searchpath);
342 static string shader_filepath_hash(
const string &filepath,
uint64_t modified_time)
346 md5.
append((
const uint8_t *)filepath.c_str(), filepath.size());
347 md5.
append((
const uint8_t *)&modified_time,
sizeof(modified_time));
352 const char *OSLShaderManager::shader_test_loaded(
const string &
hash)
354 map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(
hash);
355 return (it == loaded_shaders.end()) ?
NULL : it->first.c_str();
358 OSLShaderInfo *OSLShaderManager::shader_loaded_info(
const string &
hash)
360 map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(
hash);
361 return (it == loaded_shaders.end()) ?
NULL : &it->second;
364 const char *OSLShaderManager::shader_load_filepath(
string filepath)
366 size_t len = filepath.size();
367 string extension = filepath.substr(
len - 4);
370 if (extension ==
".osl") {
372 string osopath = filepath.substr(0,
len - 4) +
".oso";
376 if (oso_modified_time != 0) {
377 const char *
hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time));
384 if (oso_modified_time == 0 || (oso_modified_time < modified_time)) {
385 OSLShaderManager::osl_compile(filepath, osopath);
389 modified_time = oso_modified_time;
394 if (extension ==
".oso") {
407 const char *
hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time));
414 string bytecode_hash = shader_filepath_hash(filepath, modified_time);
418 fprintf(stderr,
"Cycles shader graph: failed to read file %s\n", filepath.c_str());
420 loaded_shaders[bytecode_hash] = info;
424 return shader_load_bytecode(bytecode_hash, bytecode);
427 const char *OSLShaderManager::shader_load_bytecode(
const string &
hash,
const string &bytecode)
429 ss->LoadMemoryCompiledShader(
hash.c_str(), bytecode.c_str());
433 if (!info.query.open_bytecode(bytecode)) {
434 fprintf(stderr,
"OSL query error: %s\n", info.query.geterror().c_str());
438 info.has_surface_emission = (bytecode.find(
"\"emission\"") != string::npos);
439 info.has_surface_transparent = (bytecode.find(
"\"transparent\"") != string::npos);
440 info.has_surface_bssrdf = (bytecode.find(
"\"bssrdf\"") != string::npos);
442 loaded_shaders[
hash] = info;
444 return loaded_shaders.find(
hash)->first.c_str();
451 const std::string &filepath,
452 const std::string &bytecode_hash,
453 const std::string &bytecode)
460 OSLShaderManager *osl_manager =
static_cast<OSLShaderManager *
>(manager);
463 if (!filepath.empty()) {
464 hash = osl_manager->shader_load_filepath(filepath);
467 hash = osl_manager->shader_test_loaded(bytecode_hash);
469 hash = osl_manager->shader_load_bytecode(bytecode_hash, bytecode);
476 OSLShaderInfo *info = osl_manager->shader_loaded_info(
hash);
479 size_t num_inputs = 0;
481 for (
int i = 0; i < info->query.nparams(); i++) {
482 const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
485 if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
488 if (!param->isoutput)
496 set<void *> used_sockets;
498 for (
int i = 0; i < info->query.nparams(); i++) {
499 const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
502 if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
507 if (param->isclosure) {
510 else if (param->type.vecsemantics != TypeDesc::NOSEMANTICS) {
511 if (param->type.vecsemantics == TypeDesc::COLOR)
515 else if (param->type.vecsemantics == TypeDesc::VECTOR)
522 if (!param->isoutput && param->validdefault) {
524 default_value->
x = param->fdefault[0];
525 default_value->
y = param->fdefault[1];
526 default_value->
z = param->fdefault[2];
529 else if (param->type.aggregate == TypeDesc::SCALAR) {
530 if (param->type.basetype == TypeDesc::INT) {
533 if (!param->isoutput && param->validdefault) {
534 *(
int *)
node->input_default_value() = param->idefault[0];
537 else if (param->type.basetype == TypeDesc::FLOAT) {
540 if (!param->isoutput && param->validdefault) {
541 *(
float *)
node->input_default_value() = param->fdefault[0];
544 else if (param->type.basetype == TypeDesc::STRING) {
547 if (!param->isoutput && param->validdefault) {
548 *(ustring *)
node->input_default_value() = param->sdefault[0];
557 if (param->isoutput) {
558 node->add_output(param->name, socket_type);
561 node->add_input(param->name, socket_type);
566 if (!bytecode_hash.empty()) {
567 node->bytecode_hash = bytecode_hash;
570 node->filepath = filepath;
574 node->create_inputs_outputs(
node->type);
581 OSLCompiler::OSLCompiler(OSLShaderManager *manager,
585 :
scene(
scene), manager(manager), services(services), ss(ss)
588 current_shader =
NULL;
596 stream <<
"node_" <<
node->type->name <<
"_" <<
node;
603 string sname(input->
name().string());
607 while ((i = sname.find(
" ")) != string::npos)
608 sname.replace(i, 1,
"");
623 string sname(
output->name().string());
627 while ((i = sname.find(
" ")) != string::npos)
628 sname.replace(i, 1,
"");
660 if (input->
name() ==
"Height")
674 name = manager->shader_load_filepath(name);
684 if (node_skip_input(
node, input))
687 string param_name = compatible_name(
node, input);
689 switch (input->
type()) {
722 ss->Shader(
"surface", name,
id(
node).c_str());
724 ss->Shader(
"surface", name,
id(
node).c_str());
726 ss->Shader(
"displacement", name,
id(
node).c_str());
728 ss->Shader(
"displacement", name,
id(
node).c_str());
735 if (node_skip_input(
node, input))
741 string param_from = compatible_name(input->
link->
parent, input->
link);
742 string param_to = compatible_name(
node, input);
744 ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
749 OSLShaderInfo *info = manager->shader_loaded_info(name);
753 if (info->has_surface_emission)
755 if (info->has_surface_transparent)
757 if (info->has_surface_bssrdf) {
764 if (
node->has_spatial_varying()) {
769 if (
node->has_spatial_varying())
771 if (
node->has_attribute_dependency())
775 if (
node->has_integrator_dependency()) {
780 static TypeDesc array_typedesc(TypeDesc typedesc,
int arraylength)
782 return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype,
783 (TypeDesc::AGGREGATE)typedesc.aggregate,
784 (TypeDesc::VECSEMANTICS)typedesc.vecsemantics,
790 ustring uname = ustring(name);
793 switch (socket.
type) {
795 int value =
node->get_bool(socket);
796 ss->Parameter(name, TypeDesc::TypeInt, &value);
800 float value =
node->get_float(socket);
801 ss->Parameter(uname, TypeDesc::TypeFloat, &value);
805 int value =
node->get_int(socket);
806 ss->Parameter(uname, TypeDesc::TypeInt, &value);
811 ss->Parameter(uname, TypeDesc::TypeColor, &value);
816 ss->Parameter(uname, TypeDesc::TypeVector, &value);
821 ss->Parameter(uname, TypeDesc::TypePoint, &value);
826 ss->Parameter(uname, TypeDesc::TypeNormal, &value);
831 ss->Parameter(uname, TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2,
TypeDesc::POINT), &value);
835 ustring value =
node->get_string(socket);
836 ss->Parameter(uname, TypeDesc::TypeString, &value);
840 ustring value =
node->get_string(socket);
841 ss->Parameter(uname, TypeDesc::TypeString, &value);
848 ss->Parameter(uname, TypeDesc::TypeMatrix, &projection);
855 for (
size_t i = 0; i < value.
size(); i++)
856 intvalue[i] = value[i];
857 ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.
size()), intvalue.data());
862 ss->Parameter(uname, array_typedesc(TypeDesc::TypeFloat, value.
size()), value.
data());
867 ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.
size()), value.
data());
876 switch (socket.
type) {
878 typedesc = TypeDesc::TypeColor;
881 typedesc = TypeDesc::TypeVector;
884 typedesc = TypeDesc::TypePoint;
887 typedesc = TypeDesc::TypeNormal;
897 for (
size_t i = 0, j = 0; i < value.
size(); i++) {
898 fvalue[j++] = value[i].x;
899 fvalue[j++] = value[i].y;
900 fvalue[j++] = value[i].z;
903 ss->Parameter(uname, array_typedesc(typedesc, value.
size()), fvalue.data());
916 ss->Parameter(uname, array_typedesc(TypeDesc::TypeString, value.
size()), value.
data());
922 for (
size_t i = 0; i < value.
size(); i++) {
925 ss->Parameter(uname, array_typedesc(TypeDesc::TypeMatrix, fvalue.size()), fvalue.data());
941 ss->Parameter(name, TypeDesc::TypeFloat, &f);
946 ss->Parameter(name, TypeDesc::TypeColor, &f);
951 ss->Parameter(name, TypeDesc::TypePoint, &f);
956 ss->Parameter(name, TypeDesc::TypeNormal, &f);
961 ss->Parameter(name, TypeDesc::TypeVector, &f);
966 ss->Parameter(name, TypeDesc::TypeInt, &f);
971 ss->Parameter(name, TypeDesc::TypeString, &s);
976 const char *
str = s.c_str();
977 ss->Parameter(name, TypeDesc::TypeString, &
str);
984 ss->Parameter(name, TypeDesc::TypeMatrix, (
float *)&projection);
989 TypeDesc
type = TypeDesc::TypeFloat;
990 type.arraylen = arraylen;
991 ss->Parameter(name,
type, f);
999 for (
int i = 0; i < f.
size(); ++i) {
1000 table[i][0] = f[i].x;
1001 table[i][1] = f[i].y;
1002 table[i][2] = f[i].z;
1005 TypeDesc
type = TypeDesc::TypeColor;
1006 type.arraylen = table.size();
1007 ss->Parameter(name,
type, table.data());
1013 parameter(name, (
string(
"geom:") + s.c_str()).c_str());
1022 if (
node !=
NULL && dependencies.find(
node) == dependencies.end()) {
1024 if (!node_skip_input(
node, in))
1025 find_dependencies(dependencies, in);
1027 dependencies.insert(
node);
1031 void OSLCompiler::generate_nodes(
const ShaderNodeSet &nodes)
1040 if (done.find(
node) == done.end()) {
1041 bool inputs_done =
true;
1044 if (!node_skip_input(
node, input))
1046 inputs_done =
false;
1049 node->compile(*
this);
1053 if (
node->has_surface_emission())
1055 if (
node->has_surface_transparent())
1057 if (
node->has_spatial_varying())
1059 if (
node->has_surface_bssrdf()) {
1061 if (
node->has_bssrdf_bump())
1064 if (
node->has_bump()) {
1069 if (
node->has_spatial_varying())
1077 }
while (!nodes_done);
1082 current_type =
type;
1084 OSL::ShaderGroupRef group = ss->ShaderGroupBegin(
shader->name.c_str());
1091 find_dependencies(dependencies,
output->input(
"Surface"));
1092 generate_nodes(dependencies);
1097 find_dependencies(dependencies,
output->input(
"Normal"));
1098 generate_nodes(dependencies);
1103 find_dependencies(dependencies,
output->input(
"Volume"));
1104 generate_nodes(dependencies);
1109 find_dependencies(dependencies,
output->input(
"Displacement"));
1110 generate_nodes(dependencies);
1116 ss->ShaderGroupEnd();
1123 if (
shader->is_modified()) {
1128 output->input(
"Surface")->link &&
output->input(
"Displacement")->link;
1133 shader->has_integrator_dependency,
1138 shader->has_surface =
false;
1139 shader->has_surface_emission =
false;
1140 shader->has_surface_transparent =
false;
1141 shader->has_surface_bssrdf =
false;
1142 shader->has_bump = has_bump;
1143 shader->has_bssrdf_bump = has_bump;
1144 shader->has_volume =
false;
1145 shader->has_displacement =
false;
1146 shader->has_surface_spatial_varying =
false;
1147 shader->has_volume_spatial_varying =
false;
1148 shader->has_volume_attribute_dependency =
false;
1149 shader->has_integrator_dependency =
false;
1158 shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1160 shader->has_surface =
true;
1163 shader->osl_surface_ref = OSL::ShaderGroupRef();
1164 shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1170 shader->has_volume =
true;
1173 shader->osl_volume_ref = OSL::ShaderGroupRef();
1178 shader->has_displacement =
true;
1181 shader->osl_displacement_ref = OSL::ShaderGroupRef();
1185 og->surface_state.push_back(
shader->osl_surface_ref);
1186 og->volume_state.push_back(
shader->osl_volume_ref);
1187 og->displacement_state.push_back(
shader->osl_displacement_ref);
1188 og->bump_state.push_back(
shader->osl_surface_bump_ref);
1197 services->textures.insert(filename, handle);
1207 ustring filename(
string_printf(
"@svm%d", texture_shared_unique_id++).c_str());
1215 ustring filename(
string_printf(
"@svm%d", texture_shared_unique_id++).c_str());
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum query
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void reset()
clear internal cached data and reset random seed
static AttributeStandard name_standard(const char *name)
Shader * get_shader(const Scene *scene)
static ColorSpaceProcessor * get_processor(ustring colorspace)
virtual void * osl_memory()
void set_osl_texture_system(void *texture_system)
void tag_update(Scene *scene, uint32_t flag)
void append(const uint8_t *data, int size)
void add(ShaderNode *node, const char *name, bool isfilepath=false)
void parameter_vector(const char *name, float3 f)
void parameter_array(const char *name, const float f[], int arraylen)
void parameter_texture_ies(const char *name, int svm_slot)
void parameter_texture(const char *name, ustring filename, ustring colorspace)
void parameter(ShaderNode *node, const char *name)
void parameter_normal(const char *name, float3 f)
void parameter_color_array(const char *name, const array< float3 > &f)
void compile(OSLGlobals *og, Shader *shader)
void parameter_point(const char *name, float3 f)
void parameter_color(const char *name, float3 f)
void parameter_attribute(const char *name, ustring s)
static OSLNode * create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from=NULL)
int get_shader_id(Shader *shader, bool smooth=false)
ShaderNodeSpecialType special_type
bool has_surface_spatial_varying
bool has_volume_attribute_dependency
bool has_integrator_dependency
bool has_surface_emission
bool has_surface_transparent
bool has_volume_spatial_varying
CCL_NAMESPACE_BEGIN struct Options options
@ SHADER_SPECIAL_TYPE_BUMP
@ SHADER_SPECIAL_TYPE_OUTPUT
set< ShaderNode *, ShaderNodeIDComparator > ShaderNodeSet
#define CCL_NAMESPACE_END
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
static const VertexNature POINT
unsigned __int64 uint64_t
ColorSpaceProcessor * processor
vector< Shader * > shaders
ImageManager * image_manager
ShaderManager * shader_manager
LightManager * light_manager
SceneUpdateStats * update_stats
@ SHADER_TYPE_DISPLACEMENT
void util_aligned_delete(T *t)
string path_user_get(const string &sub)
string path_dirname(const string &path)
string path_get(const string &sub)
uint64_t path_modified_time(const string &path)
string path_join(const string &dir, const string &file)
bool path_read_text(const string &path, string &text)
CCL_NAMESPACE_BEGIN struct ProjectionTransform ProjectionTransform
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform &a)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex