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:
-rw-r--r--intern/cycles/device/device_cpu.cpp16
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h49
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp366
-rw-r--r--intern/cycles/kernel/shaders/node_ies_light.osl4
-rw-r--r--intern/cycles/render/nodes.cpp26
-rw-r--r--intern/cycles/render/osl.cpp38
-rw-r--r--intern/cycles/render/osl.h3
-rw-r--r--intern/cycles/util/util_aligned_malloc.h7
8 files changed, 308 insertions, 201 deletions
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 837a8186064..32911e054fe 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -43,6 +43,7 @@
#include "render/buffers.h"
#include "render/coverage.h"
+#include "util/util_aligned_malloc.h"
#include "util/util_debug.h"
#include "util/util_foreach.h"
#include "util/util_function.h"
@@ -165,7 +166,7 @@ class CPUDevice : public Device {
bool need_texture_info;
#ifdef WITH_OSL
- OSLGlobals osl_globals;
+ OSLGlobals *osl_globals;
#endif
bool use_split_kernel;
@@ -282,7 +283,9 @@ class CPUDevice : public Device {
}
#ifdef WITH_OSL
- kernel_globals.osl = &osl_globals;
+ /* Must use aligned malloc due to concurrent hash map. */
+ osl_globals = util_aligned_new<OSLGlobals>();
+ kernel_globals.osl = osl_globals;
#endif
use_split_kernel = DebugFlags().cpu.split_kernel;
if (use_split_kernel) {
@@ -317,6 +320,9 @@ class CPUDevice : public Device {
~CPUDevice()
{
+#ifdef WITH_OSL
+ delete osl_globals;
+#endif
task_pool.stop();
texture_info.free();
}
@@ -492,7 +498,7 @@ class CPUDevice : public Device {
void *osl_memory()
{
#ifdef WITH_OSL
- return &osl_globals;
+ return osl_globals;
#else
return NULL;
#endif
@@ -981,7 +987,7 @@ class CPUDevice : public Device {
KernelGlobals kg = kernel_globals;
#ifdef WITH_OSL
- OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
+ OSLShader::thread_init(&kg, &kernel_globals, osl_globals);
#endif
for (int sample = 0; sample < task.num_samples; sample++) {
for (int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
@@ -1053,7 +1059,7 @@ class CPUDevice : public Device {
kg.decoupled_volume_steps_index = 0;
kg.coverage_asset = kg.coverage_object = kg.coverage_material = NULL;
#ifdef WITH_OSL
- OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
+ OSLShader::thread_init(&kg, &kernel_globals, osl_globals);
#endif
return kg;
}
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 641c9967586..414aaf891db 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -21,10 +21,14 @@
# include <OSL/oslexec.h>
+# include <OpenImageIO/refcnt.h>
+# include <OpenImageIO/unordered_map_concurrent.h>
+
# include "util/util_map.h"
# include "util/util_param.h"
# include "util/util_thread.h"
# include "util/util_vector.h"
+# include "util/util_unique_ptr.h"
# ifndef WIN32
using std::isfinite;
@@ -34,6 +38,48 @@ CCL_NAMESPACE_BEGIN
class OSLRenderServices;
+/* 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(OIIO), svm_slot(-1), oiio_handle(NULL)
+ {
+ }
+
+ OSLTextureHandle(Type type) : type(type), svm_slot(-1), oiio_handle(NULL)
+ {
+ }
+
+ OSLTextureHandle(Type type, int svm_slot) : type(type), svm_slot(svm_slot), oiio_handle(NULL)
+ {
+ }
+
+ Type type;
+ int svm_slot;
+ OSL::TextureSystem::TextureHandle *oiio_handle;
+};
+
+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.
+ * This includes all OSL shaders, name to attribute mapping and texture handles.
+ * */
+
struct OSLGlobals {
OSLGlobals()
{
@@ -70,6 +116,9 @@ 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 b4329ab0a71..7de596a2c30 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -124,8 +124,6 @@ ustring OSLRenderServices::u_I("I");
ustring OSLRenderServices::u_u("u");
ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
-ustring OSLRenderServices::u_at_bevel("@bevel");
-ustring OSLRenderServices::u_at_ao("@ao");
OSLRenderServices::OSLRenderServices()
{
@@ -154,7 +152,7 @@ void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_,
OSL::TextureSystem *osl_ts_)
{
kernel_globals = kernel_globals_;
- osl_globals = osl_globals;
+ osl_globals = osl_globals_;
osl_ts = osl_ts_;
}
@@ -956,19 +954,44 @@ bool OSLRenderServices::get_userdata(
TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename)
{
- if (filename.length() && filename[0] == '@') {
- /* Dummy, we don't use texture handles for builtin textures but need
- * to tell the OSL runtime optimizer that this is a valid texture. */
+ OSLTextureHandleMap::iterator it = osl_globals->textures.find(filename);
+
+ /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
+ if (it != osl_globals->textures.end()) {
+ if (it->second->type != OSLTextureHandle::OIIO) {
+ return (TextureSystem::TextureHandle *)it->second.get();
+ }
+ }
+
+ /* Get handle from OpenImageIO. */
+ OSL::TextureSystem *ts = osl_ts;
+ TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
+ if (handle == NULL) {
return NULL;
}
- else {
- return texturesys()->get_texture_handle(filename);
+
+ /* 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);
}
+
+ /* Assign OIIO texture handle and return. */
+ it->second->oiio_handle = handle;
+ return (TextureSystem::TextureHandle *)it->second.get();
}
bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
{
- return texturesys()->good(texture_handle);
+ OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
+
+ if (handle->oiio_handle) {
+ OSL::TextureSystem *ts = osl_ts;
+ return ts->good(handle->oiio_handle);
+ }
+ else {
+ return true;
+ }
}
bool OSLRenderServices::texture(ustring filename,
@@ -988,70 +1011,29 @@ bool OSLRenderServices::texture(ustring filename,
float *dresultdt,
ustring *errormessage)
{
- OSL::TextureSystem *ts = osl_ts;
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- KernelGlobals *kg = kernel_globals;
-
- if (texture_thread_info == NULL) {
- OSLThreadData *tdata = kg->osl_tdata;
- texture_thread_info = tdata->oiio_thread_info;
- }
-
-#ifdef WITH_PTEX
- /* todo: this is just a quick hack, only works with particular files and options */
- if (string_endswith(filename.string(), ".ptx")) {
- float2 uv;
- int faceid;
-
- if (!primitive_ptex(kg, sd, &uv, &faceid))
- return false;
-
- float u = uv.x;
- float v = uv.y;
- float dudx = 0.0f;
- float dvdx = 0.0f;
- float dudy = 0.0f;
- float dvdy = 0.0f;
-
- Ptex::String error;
- PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error));
-
- if (!r) {
- // std::cerr << error.c_str() << std::endl;
- return false;
- }
-
- bool mipmaplerp = false;
- float sharpness = 1.0f;
- PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
- PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
-
- f->eval(result, options.firstchannel, nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
-
- for (int c = r->numChannels(); c < nchannels; c++)
- result[c] = result[0];
-
- return true;
- }
-#endif
+ OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
+ OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
bool status = false;
- if (filename.length() && filename[0] == '@') {
- if (filename == u_at_bevel) {
+ 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;
- float3 N = svm_bevel(kg, sd, state, radius, num_samples);
+ float3 N = svm_bevel(kernel_globals, sd, state, radius, num_samples);
result[0] = N.x;
result[1] = N.y;
result[2] = N.z;
status = true;
}
+ break;
}
- else if (filename == u_at_ao) {
+ 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;
@@ -1066,19 +1048,13 @@ bool OSLRenderServices::texture(ustring filename,
if ((int)options.tblur) {
flags |= NODE_AO_GLOBAL_RADIUS;
}
- result[0] = svm_ao(kg, sd, N, state, radius, num_samples, flags);
+ result[0] = svm_ao(kernel_globals, sd, N, state, radius, num_samples, flags);
status = true;
+ break;
}
- else if (filename[1] == 'l') {
- /* IES light. */
- int slot = atoi(filename.c_str() + 2);
- result[0] = kernel_ies_interp(kg, slot, s, t);
- status = true;
- }
- else {
+ case OSLTextureHandle::SVM: {
/* Packed texture. */
- int slot = atoi(filename.c_str() + 2);
- float4 rgba = kernel_tex_image_interp(kg, slot, s, 1.0f - t);
+ float4 rgba = kernel_tex_image_interp(kernel_globals, handle->svm_slot, s, 1.0f - t);
result[0] = rgba[0];
if (nchannels > 1)
@@ -1088,37 +1064,59 @@ bool OSLRenderServices::texture(ustring filename,
if (nchannels > 3)
result[3] = rgba[3];
status = true;
+ break;
}
- }
- else {
- if (texture_handle != NULL) {
- status = ts->texture(texture_handle,
- texture_thread_info,
- options,
- s,
- t,
- dsdx,
- dtdx,
- dsdy,
- dtdy,
- nchannels,
- result,
- dresultds,
- dresultdt);
+ case OSLTextureHandle::IES: {
+ /* IES light. */
+ result[0] = kernel_ies_interp(kernel_globals, handle->svm_slot, s, t);
+ status = true;
+ break;
}
- else {
- status = ts->texture(filename,
- options,
- s,
- t,
- dsdx,
- dtdx,
- dsdy,
- dtdy,
- nchannels,
- result,
- dresultds,
- dresultdt);
+ case OSLTextureHandle::OIIO: {
+ /* OpenImageIO texture cache. */
+ OSL::TextureSystem *ts = osl_ts;
+
+ if (handle && handle->oiio_handle) {
+ if (texture_thread_info == NULL) {
+ OSLThreadData *tdata = kernel_globals->osl_tdata;
+ texture_thread_info = tdata->oiio_thread_info;
+ }
+
+ status = ts->texture(handle->oiio_handle,
+ texture_thread_info,
+ options,
+ s,
+ t,
+ dsdx,
+ dtdx,
+ dsdy,
+ dtdy,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt);
+ }
+ else {
+ status = ts->texture(filename,
+ options,
+ s,
+ t,
+ dsdx,
+ dtdx,
+ dsdy,
+ dtdy,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt);
+ }
+
+ if (!status) {
+ /* This might be slow, but prevents error messages leak and
+ * other nasty stuff happening. */
+ ts->geterror();
+ }
+ break;
}
}
@@ -1131,11 +1129,6 @@ bool OSLRenderServices::texture(ustring filename,
if (nchannels == 4)
result[3] = 1.0f;
}
- /* This might be slow, but prevents error messages leak and
- * other nasty stuff happening.
- */
- string err = ts->geterror();
- (void)err;
}
return status;
@@ -1157,56 +1150,76 @@ bool OSLRenderServices::texture3d(ustring filename,
float *dresultdr,
ustring *errormessage)
{
- OSL::TextureSystem *ts = osl_ts;
- ShaderData *sd = (ShaderData *)(sg->renderstate);
- KernelGlobals *kg = kernel_globals;
+ OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
+ OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
+ bool status = false;
- if (texture_thread_info == NULL) {
- OSLThreadData *tdata = kg->osl_tdata;
- texture_thread_info = tdata->oiio_thread_info;
- }
+ switch (texture_type) {
+ case OSLTextureHandle::SVM: {
+ /* Packed texture. */
+ int slot = handle->svm_slot;
+ float4 rgba = kernel_tex_image_interp_3d(
+ kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
- bool status;
- if (filename.length() && filename[0] == '@') {
- int slot = atoi(filename.c_str() + 1);
- float4 rgba = kernel_tex_image_interp_3d(kg, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
+ result[0] = rgba[0];
+ if (nchannels > 1)
+ result[1] = rgba[1];
+ if (nchannels > 2)
+ result[2] = rgba[2];
+ if (nchannels > 3)
+ result[3] = rgba[3];
+ status = true;
+ break;
+ }
+ case OSLTextureHandle::OIIO: {
+ /* OpenImageIO texture cache. */
+ OSL::TextureSystem *ts = osl_ts;
+
+ if (handle && handle->oiio_handle) {
+ if (texture_thread_info == NULL) {
+ OSLThreadData *tdata = kernel_globals->osl_tdata;
+ texture_thread_info = tdata->oiio_thread_info;
+ }
- result[0] = rgba[0];
- if (nchannels > 1)
- result[1] = rgba[1];
- if (nchannels > 2)
- result[2] = rgba[2];
- if (nchannels > 3)
- result[3] = rgba[3];
- status = true;
- }
- else {
- if (texture_handle != NULL) {
- status = ts->texture3d(texture_handle,
- texture_thread_info,
- options,
- P,
- dPdx,
- dPdy,
- dPdz,
- nchannels,
- result,
- dresultds,
- dresultdt,
- dresultdr);
+ status = ts->texture3d(handle->oiio_handle,
+ texture_thread_info,
+ options,
+ P,
+ dPdx,
+ dPdy,
+ dPdz,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt,
+ dresultdr);
+ }
+ else {
+ status = ts->texture3d(filename,
+ options,
+ P,
+ dPdx,
+ dPdy,
+ dPdz,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt,
+ dresultdr);
+ }
+
+ if (!status) {
+ /* This might be slow, but prevents error messages leak and
+ * other nasty stuff happening. */
+ ts->geterror();
+ }
+ break;
}
- else {
- status = ts->texture3d(filename,
- options,
- P,
- dPdx,
- dPdy,
- dPdz,
- nchannels,
- result,
- dresultds,
- dresultdt,
- dresultdr);
+ case OSLTextureHandle::IES:
+ case OSLTextureHandle::AO:
+ case OSLTextureHandle::BEVEL: {
+ status = false;
+ break;
}
}
@@ -1219,18 +1232,13 @@ bool OSLRenderServices::texture3d(ustring filename,
if (nchannels == 4)
result[3] = 1.0f;
}
- /* This might be slow, but prevents error messages leak and
- * other nasty stuff happening.
- */
- string err = ts->geterror();
- (void)err;
}
return status;
}
bool OSLRenderServices::environment(ustring filename,
- TextureHandle *th,
+ TextureHandle *texture_handle,
TexturePerthread *thread_info,
TextureOpt &options,
OSL::ShaderGlobals *sg,
@@ -1243,19 +1251,31 @@ bool OSLRenderServices::environment(ustring filename,
float *dresultdt,
ustring *errormessage)
{
+ OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
OSL::TextureSystem *ts = osl_ts;
+ bool status = false;
- if (thread_info == NULL) {
- OSLThreadData *tdata = kernel_globals->osl_tdata;
- thread_info = tdata->oiio_thread_info;
- }
+ if (handle && handle->oiio_handle) {
+ if (thread_info == NULL) {
+ OSLThreadData *tdata = kernel_globals->osl_tdata;
+ thread_info = tdata->oiio_thread_info;
+ }
- if (th == NULL) {
- th = ts->get_texture_handle(filename, thread_info);
+ status = ts->environment(handle->oiio_handle,
+ thread_info,
+ options,
+ R,
+ dRdx,
+ dRdy,
+ nchannels,
+ result,
+ dresultds,
+ dresultdt);
+ }
+ else {
+ status = ts->environment(
+ filename, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
}
-
- bool status = ts->environment(
- th, thread_info, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
if (!status) {
if (nchannels == 3 || nchannels == 4) {
@@ -1273,20 +1293,22 @@ bool OSLRenderServices::environment(ustring filename,
bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
ustring filename,
- TextureHandle *th,
+ TextureHandle *texture_handle,
int subimage,
ustring dataname,
TypeDesc datatype,
void *data)
{
- OSL::TextureSystem *ts = osl_ts;
- if (filename.length() && filename[0] == '@') {
- /* Special builtin textures. */
- return false;
- }
- else {
- return ts->get_texture_info(filename, subimage, dataname, datatype, data);
+ OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
+
+ /* No texture info for other texture types. */
+ if (handle && handle->type != OSLTextureHandle::OIIO) {
+ return NULL;
}
+
+ /* Get texture info from OpenImageIO. */
+ OSL::TextureSystem *ts = osl_ts;
+ return ts->get_texture_info(filename, subimage, dataname, datatype, data);
}
int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg,
diff --git a/intern/cycles/kernel/shaders/node_ies_light.osl b/intern/cycles/kernel/shaders/node_ies_light.osl
index ea8c44e09de..ce0173451da 100644
--- a/intern/cycles/kernel/shaders/node_ies_light.osl
+++ b/intern/cycles/kernel/shaders/node_ies_light.osl
@@ -21,7 +21,7 @@
shader node_ies_light(int use_mapping = 0,
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- int slot = 0,
+ string filename = "",
float Strength = 1.0,
point Vector = I,
output float Fac = 0.0)
@@ -37,5 +37,5 @@ shader node_ies_light(int use_mapping = 0,
float v_angle = acos(-p[2]);
float h_angle = atan2(p[0], p[1]) + M_PI;
- Fac = Strength * texture(format("@l%d", slot), h_angle, v_angle);
+ Fac = Strength * texture(filename, h_angle, v_angle);
}
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 16416a9a009..35e9f8df5a8 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -374,18 +374,7 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
is_linear = metadata.is_linear;
}
- if (slot == -1) {
- compiler.parameter(this, "filename");
- }
- else {
- /* TODO(sergey): It's not so simple to pass custom attribute
- * to the texture() function in order to make builtin images
- * support more clear. So we use special file name which is
- * "@i<slot_number>" and check whether file name matches this
- * mask in the OSLRenderServices::texture().
- */
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
+ compiler.parameter_texture("filename", filename, slot);
if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
compiler.parameter("color_space", "linear");
else
@@ -556,12 +545,7 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
is_linear = metadata.is_linear;
}
- if (slot == -1) {
- compiler.parameter(this, "filename");
- }
- else {
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
+ compiler.parameter_texture("filename", filename, slot);
compiler.parameter(this, "projection");
if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
compiler.parameter("color_space", "linear");
@@ -1080,7 +1064,7 @@ void IESLightNode::compile(OSLCompiler &compiler)
tex_mapping.compile(compiler);
- compiler.parameter("slot", slot);
+ compiler.parameter_texture_ies("filename", slot);
compiler.add(this, "node_ies_light");
}
@@ -1567,9 +1551,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
if (use_density || use_color) {
add_image();
- if (slot != -1) {
- compiler.parameter("filename", string_printf("@i%d", slot).c_str());
- }
+ compiler.parameter_texture("filename", ustring(), slot);
if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
compiler.parameter("mapping", tfm);
compiler.parameter("use_mapping", 1);
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 24c5a599c1a..5ee453275b9 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -145,6 +145,10 @@ void OSLShaderManager::device_update(Device *device,
/* set texture system */
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));
+
device_update_common(device, dscene, scene, progress);
{
@@ -1201,6 +1205,30 @@ void OSLCompiler::compile(Scene *scene, Shader *shader)
osl_globals->bump_state.push_back(shader->osl_surface_bump_ref);
}
+void OSLCompiler::parameter_texture(const char *name, ustring filename, int svm_slot)
+{
+ if (svm_slot != -1) {
+ /* It's not so simple to pass custom attribute to the texture() function
+ * in order to make builtin images support more clear. So we use special
+ * file name which is "@i<slot_number>" and use that for lookup in
+ * in OSLRenderServices::texture(). */
+ filename = string_printf("@i%d", svm_slot).c_str();
+ osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::SVM, svm_slot));
+ }
+ else {
+ osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
+ }
+
+ parameter(name, filename);
+}
+
+void OSLCompiler::parameter_texture_ies(const char *name, int svm_slot)
+{
+ ustring filename(string_printf("@l%d", svm_slot).c_str());
+ osl_globals->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
+ parameter(name, filename);
+}
+
#else
void OSLCompiler::add(ShaderNode * /*node*/, const char * /*name*/, bool /*isfilepath*/)
@@ -1255,6 +1283,16 @@ void OSLCompiler::parameter_color_array(const char * /*name*/, const array<float
{
}
+void OSLCompiler::parameter_texture(const char * /* name */,
+ ustring /* filename */,
+ int /* svm_slot */)
+{
+}
+
+void OSLCompiler::parameter_texture_ies(const char * /* name */, int /* svm_slot */)
+{
+}
+
#endif /* WITH_OSL */
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 4d930d65e45..773252ce9dc 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -153,6 +153,9 @@ class OSLCompiler {
void parameter_attribute(const char *name, ustring s);
+ void parameter_texture(const char *name, ustring filename, int svm_slot);
+ void parameter_texture_ies(const char *name, int svm_slot);
+
ShaderType output_type()
{
return current_type;
diff --git a/intern/cycles/util/util_aligned_malloc.h b/intern/cycles/util/util_aligned_malloc.h
index 0f006e95f6a..a76884b20a5 100644
--- a/intern/cycles/util/util_aligned_malloc.h
+++ b/intern/cycles/util/util_aligned_malloc.h
@@ -30,6 +30,13 @@ void *util_aligned_malloc(size_t size, int alignment);
/* Free memory allocated by util_aligned_malloc. */
void util_aligned_free(void *ptr);
+/* Aligned new operator. */
+template<typename T> T *util_aligned_new()
+{
+ void *mem = util_aligned_malloc(sizeof(T), alignof(T));
+ return new (mem) T();
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_ALIGNED_MALLOC_H__ */