diff options
Diffstat (limited to 'intern/cycles/kernel/osl/osl_services.cpp')
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 366 |
1 files changed, 194 insertions, 172 deletions
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, |