diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c612a27e2..c3fe4b873b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ else () endif () set (OSL_LIBNAME_SUFFIX "" CACHE STRING "Optional name appended to ${PROJECT_NAME} libraries that are built") -option (OSL_BUILD_TESTS "Build the unit tests, testshade, testrender" ON) +option (OSL_BUILD_TESTS "Build the unit tests, testminimal, testshade, testrender" ON) if (WIN32) option (USE_LLVM_BITCODE "Generate embedded LLVM bitcode" OFF) else () @@ -113,10 +113,14 @@ set (OSL_SHADER_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/shade set (OSL_PTX_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/ptx" CACHE STRING "Directory where OptiX PTX files will be installed") set (CMAKE_DEBUG_POSTFIX "" CACHE STRING "Library naming postfix for Debug builds (e.g., '_debug')") -option (OSL_USTRINGREP_IS_HASH "Always use ustringhash for strings" OFF) +option (OSL_USTRINGREP_IS_HASH "Always use ustringhash for strings" ON) set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem") + +if (OSL_USTRINGREP_IS_HASH) + add_definitions ("-DOSL_USTRINGREP_IS_HASH=1") +endif () if (OSL_NO_DEFAULT_TEXTURESYSTEM) add_definitions ("-DOSL_NO_DEFAULT_TEXTURESYSTEM=1") endif () @@ -220,6 +224,7 @@ add_subdirectory (src/oslc) add_subdirectory (src/oslinfo) if (OSL_BUILD_TESTS AND BUILD_TESTING) + add_subdirectory (src/testminimal) add_subdirectory (src/testshade) add_subdirectory (src/testrender) endif () diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index fc5e956b05..c3c0bee88e 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -270,7 +270,7 @@ macro (osl_add_all_tests) bug-array-heapoffsets bug-locallifetime bug-outputinit bug-param-duplicate bug-peep bug-return calculatenormal-reg - cellnoise closure closure-array closure-layered closure-parameters closure-zero closure-conditional + cellnoise closure closure-array closure-layered closure-parameters closure-string closure-zero closure-conditional color color-reg colorspace comparison complement-reg compile-buffer compassign-bool compassign-reg component-range diff --git a/src/include/OSL/llvm_util.h b/src/include/OSL/llvm_util.h index 7f112ccf52..be02f75b6a 100644 --- a/src/include/OSL/llvm_util.h +++ b/src/include/OSL/llvm_util.h @@ -1058,10 +1058,14 @@ class OSLEXECPUBLIC LLVM_Util { IRBuilder& builder(); int m_debug; - bool m_dumpasm = false; - bool m_jit_fma = false; - bool m_jit_aggressive = false; + bool m_dumpasm = false; + bool m_jit_fma = false; + bool m_jit_aggressive = false; +#ifndef OSL_USTRINGREP_IS_HASH UstringRep m_ustring_rep = UstringRep::charptr; +#else + UstringRep m_ustring_rep = UstringRep::hash; +#endif PerThreadInfo::Impl* m_thread; llvm::LLVMContext* m_llvm_context; llvm::Module* m_llvm_module; diff --git a/src/liboslexec/batched_backendllvm.cpp b/src/liboslexec/batched_backendllvm.cpp index e94122ef43..3acfbf2425 100644 --- a/src/liboslexec/batched_backendllvm.cpp +++ b/src/liboslexec/batched_backendllvm.cpp @@ -796,7 +796,17 @@ BatchedBackendLLVM::llvm_load_value(const Symbol& sym, int deriv, sym.forced_llvm_bool()); } +llvm::Value* +BatchedBackendLLVM::llvm_const_hash(string_view str) +{ + return llvm_const_hash(ustring(str)); +} +llvm::Value* +BatchedBackendLLVM::llvm_const_hash(ustring str) +{ + return ll.constant64((uint64_t)str.hash()); +} llvm::Value* BatchedBackendLLVM::llvm_load_mask(const Symbol& cond) diff --git a/src/liboslexec/batched_backendllvm.h b/src/liboslexec/batched_backendllvm.h index 9bafa77676..024e9f0463 100644 --- a/src/liboslexec/batched_backendllvm.h +++ b/src/liboslexec/batched_backendllvm.h @@ -102,6 +102,9 @@ class BatchedBackendLLVM : public OSOProcessorBase { bool op_is_uniform = true, bool index_is_uniform = true); + llvm::Value* llvm_const_hash(string_view str); + + llvm::Value* llvm_const_hash(ustring str); /// Given an llvm::Value* of a pointer (and the type of the data /// that it points to), Return the llvm::Value* corresponding to the diff --git a/src/liboslexec/batched_llvm_gen.cpp b/src/liboslexec/batched_llvm_gen.cpp index dacf4f0ba9..6bc55de0b9 100644 --- a/src/liboslexec/batched_llvm_gen.cpp +++ b/src/liboslexec/batched_llvm_gen.cpp @@ -3300,7 +3300,7 @@ LLVMGEN(llvm_gen_construct_triple) = { rop.sg_void_ptr(), rop.ll.void_ptr(transform), space_is_uniform ? rop.llvm_load_value(Space) : rop.llvm_void_ptr(Space), - rop.ll.constant(Strings::common), + rop.llvm_const_hash(Strings::common), rop.ll.mask_as_int(rop.ll.current_mask()) }; // Dynamically build function name diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp index 3dd888cab0..470b8d2957 100644 --- a/src/liboslexec/llvm_util.cpp +++ b/src/liboslexec/llvm_util.cpp @@ -564,10 +564,13 @@ LLVM_Util::ustring_rep(UstringRep rep) } m_llvm_type_ustring_ptr = llvm::PointerType::get(m_llvm_type_ustring, 0); - // Batched versions haven't been updated to handle hash yet. - // For now leave them using the real ustring regardless of UstringRep - m_llvm_type_wide_ustring = llvm_vector_type(m_llvm_type_real_ustring, - m_vector_width); + if (m_ustring_rep == UstringRep::charptr) { + m_llvm_type_wide_ustring = llvm_vector_type(m_llvm_type_real_ustring, + m_vector_width); + } else { + OSL_ASSERT(m_ustring_rep == UstringRep::hash); + m_llvm_type_wide_ustring = llvm::Type::getInt64Ty(*m_llvm_context); + } m_llvm_type_wide_ustring_ptr = llvm::PointerType::get(m_llvm_type_wide_ustring, 0); } diff --git a/src/liboslexec/wide/wide_opcolor.cpp b/src/liboslexec/wide/wide_opcolor.cpp index d1e96320f1..69bdbdaaa8 100644 --- a/src/liboslexec/wide/wide_opcolor.cpp +++ b/src/liboslexec/wide/wide_opcolor.cpp @@ -473,14 +473,14 @@ wide_transformc(const ColorSystem cs, ustring fromspace, ustring tospace, OSL_BATCHOP void __OSL_MASKED_OP3(transform_color, Wv, s, s)(void* bsg_, void* Cin, int Cin_derivs, void* Cout, - int Cout_derivs, ustring_pod from_, ustring_pod to_, + int Cout_derivs, ustringhash_pod from_, ustringhash_pod to_, unsigned int mask_value) { const ColorSystem& cs = cs_from_bsg(bsg_); ShadingContext* ctx = context_from_bsg(bsg_); - const ustring& from = USTR(from_); - const ustring& to = USTR(to_); + ustring from = ustring_from(from_); + ustring to = ustring_from(to_); if (Cout_derivs) { if (Cin_derivs) { @@ -512,13 +512,13 @@ __OSL_MASKED_OP3(transform_color, Wv, s, OSL_BATCHOP void __OSL_OP3(transform_color, v, s, s)(void* bsg_, void* Cin, int Cin_derivs, void* Cout, int Cout_derivs, - ustring_pod from_, ustring_pod to_) + ustringhash_pod from_, ustringhash_pod to_) { const ColorSystem& cs = cs_from_bsg(bsg_); ShadingContext* ctx = context_from_bsg(bsg_); - const ustring& from = USTR(from_); - const ustring& to = USTR(to_); + ustring from = ustring_from(from_); + ustring to = ustring_from(to_); if (Cout_derivs) { if (Cin_derivs) { diff --git a/src/liboslexec/wide/wide_opdictionary.cpp b/src/liboslexec/wide/wide_opdictionary.cpp index b209d9bf84..2c47e0cdc7 100644 --- a/src/liboslexec/wide/wide_opdictionary.cpp +++ b/src/liboslexec/wide/wide_opdictionary.cpp @@ -48,12 +48,12 @@ OSL_USING_DATA_WIDTH(__OSL_WIDTH) #include "define_opname_macros.h" OSL_BATCHOP int -__OSL_OP(dict_find_iis)(void* bsg_, int nodeID, ustring_pod query) +__OSL_OP(dict_find_iis)(void* bsg_, int nodeID, ustringhash_pod query) { auto* bsg = reinterpret_cast(bsg_); return bsg->uniform.context->dict_find( nullptr /*causes errors be reported through ShadingContext*/, nodeID, - USTR(query)); + ustring_from(query)); } @@ -82,12 +82,13 @@ __OSL_MASKED_OP3(dict_find, Wi, Wi, Ws)(void* bsg_, void* wout, void* wnodeID, OSL_BATCHOP int -__OSL_OP(dict_find_iss)(void* bsg_, ustring_pod dictionary, ustring_pod query) +__OSL_OP(dict_find_iss)(void* bsg_, ustringhash_pod dictionary, + ustringhash_pod query) { auto* bsg = reinterpret_cast(bsg_); return bsg->uniform.context->dict_find( nullptr /*causes errors be reported through ShadingContext*/, - USTR(dictionary), USTR(query)); + ustring_from(dictionary), ustring_from(query)); } @@ -145,11 +146,11 @@ __OSL_MASKED_OP(dict_next)(void* bsg_, void* wout, void* wNodeID, OSL_BATCHOP int -__OSL_OP(dict_value)(void* bsg_, int nodeID, ustring_pod attribname, +__OSL_OP(dict_value)(void* bsg_, int nodeID, ustringhash_pod attribname, long long type, void* data) { auto* bsg = reinterpret_cast(bsg_); - return bsg->uniform.context->dict_value(nodeID, USTR(attribname), + return bsg->uniform.context->dict_value(nodeID, ustring_from(attribname), TYPEDESC(type), data, /*treat_ustrings_as_hash*/ false); } diff --git a/src/liboslexec/wide/wide_opmatrix.cpp b/src/liboslexec/wide/wide_opmatrix.cpp index 33b3ef2aac..2679d50e82 100644 --- a/src/liboslexec/wide/wide_opmatrix.cpp +++ b/src/liboslexec/wide/wide_opmatrix.cpp @@ -532,33 +532,35 @@ makeIdentity(Masked wrm) OSL_FORCEINLINE Mask impl_get_uniform_from_matrix_masked(void* bsg_, Masked wrm, - const char* from) + ustringhash_pod from_) { + ustringhash from = ustringhash_from(from_); auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; - if (USTR(from) == Strings::common - || USTR(from) == ctx->shadingsys().commonspace_synonym()) { + if (from == Hashes::common + || from == ctx->shadingsys().commonspace_synonym()) { makeIdentity(wrm); return wrm.mask(); } - if (USTR(from) == Strings::shader) { + if (from == Hashes::shader) { ctx->batched<__OSL_WIDTH>().renderer()->get_matrix( bsg, wrm, bsg->varying.shader2common, bsg->varying.time); // NOTE: matching scalar version of code which ignores the renderservices return value return wrm.mask(); } - if (USTR(from) == Strings::object) { + if (from == Hashes::object) { ctx->batched<__OSL_WIDTH>().renderer()->get_matrix( bsg, wrm, bsg->varying.object2common, bsg->varying.time); // NOTE: matching scalar version of code which ignores the renderservices return value return wrm.mask(); } - Mask succeeded = ctx->batched<__OSL_WIDTH>().renderer()->get_matrix( - bsg, wrm, USTR(from), bsg->varying.time); + Mask succeeded + = ctx->batched<__OSL_WIDTH>().renderer()->get_matrix(bsg, wrm, from, + bsg->varying.time); auto failedResults = wrm & succeeded.invert(); if (failedResults.mask().any_on()) { makeIdentity(failedResults); @@ -572,24 +574,24 @@ impl_get_uniform_from_matrix_masked(void* bsg_, Masked wrm, OSL_FORCEINLINE Mask impl_get_uniform_to_inverse_matrix_masked(void* bsg_, Masked wrm, - const char* to) + ustringhash_pod to_) { + ustringhash to = ustringhash_from(to_); auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; - if (USTR(to) == Strings::common - || USTR(to) == ctx->shadingsys().commonspace_synonym()) { + if (to == Hashes::common || to == ctx->shadingsys().commonspace_synonym()) { makeIdentity(wrm); return wrm.mask(); } - if (USTR(to) == Strings::shader) { + if (to == Hashes::shader) { dispatch_get_inverse_matrix(ctx->batched<__OSL_WIDTH>().renderer(), bsg, wrm, bsg->varying.shader2common, bsg->varying.time); // NOTE: matching scalar version of code which ignores the renderservices return value return wrm.mask(); } - if (USTR(to) == Strings::object) { + if (to == Hashes::object) { dispatch_get_inverse_matrix(ctx->batched<__OSL_WIDTH>().renderer(), bsg, wrm, bsg->varying.object2common, bsg->varying.time); @@ -602,7 +604,7 @@ impl_get_uniform_to_inverse_matrix_masked(void* bsg_, Masked wrm, // so no need to make sure that the values are valid (assuming FP exceptions are disabled) Mask succeeded = dispatch_get_inverse_matrix(ctx->batched<__OSL_WIDTH>().renderer(), - bsg, wrm, USTR(to), bsg->varying.time); + bsg, wrm, to, bsg->varying.time); auto failedResults = wrm & succeeded.invert(); if (failedResults.mask().any_on()) { @@ -658,13 +660,13 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg, for (int lane = 0; lane < __OSL_WIDTH; ++lane) { ustringhash from = wFrom[lane]; if (wMfrom.mask()[lane]) { - if (from == Strings::common || from == commonspace_synonym) { + if (from == Hashes::common || from == commonspace_synonym) { // inline of Mask::set_on(lane) common_space_bits |= 1 << lane; - } else if (from == Strings::shader) { + } else if (from == Hashes::shader) { // inline of Mask::set_on(lane) shader_space_bits |= 1 << lane; - } else if (from == Strings::object) { + } else if (from == Hashes::object) { // inline of Mask::set_on(lane) object_space_bits |= 1 << lane; } else { @@ -731,7 +733,7 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg, OSL_BATCHOP void __OSL_MASKED_OP2(prepend_matrix_from, Wm, s)(void* bsg_, void* wr, - const char* from, + ustringhash_pod from_, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); @@ -739,7 +741,7 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, s)(void* bsg_, void* wr, Block wMfrom; Masked from_matrix(wMfrom, Mask(mask_value)); /*Mask succeeded =*/ - impl_get_uniform_from_matrix_masked(bsg, from_matrix, from); + impl_get_uniform_from_matrix_masked(bsg, from_matrix, from_); Masked wrm(wr, Mask(mask_value)); @@ -796,13 +798,13 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg, for (int lane = 0; lane < __OSL_WIDTH; ++lane) { ustringhash to = wTo[lane]; if (wMto.mask()[lane]) { - if (to == Strings::common || to == commonspace_synonym) { + if (to == Hashes::common || to == commonspace_synonym) { // inline of Mask::set_on(lane) common_space_bits |= 1 << lane; - } else if (to == Strings::shader) { + } else if (to == Hashes::shader) { // inline of Mask::set_on(lane) shader_space_bits |= 1 << lane; - } else if (to == Strings::object) { + } else if (to == Hashes::object) { // inline of Mask::set_on(lane) object_space_bits |= 1 << lane; } else { @@ -867,18 +869,19 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg, OSL_FORCEINLINE Mask impl_get_uniform_from_to_matrix_masked(BatchedShaderGlobals* bsg, - Masked wrm, const char* from, - const char* to) + Masked wrm, + ustringhash_pod from_, + ustringhash_pod to_) { Block wMfrom, wMto; Masked from_matrix(wMfrom, wrm.mask()); Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix, - from); + from_); // NOTE: even if we failed to get a from matrix, it should have been set to // identity, so we still need to try to get the to matrix for the original mask Masked to_matrix(wMto, wrm.mask()); - succeeded &= impl_get_uniform_to_inverse_matrix_masked(bsg, to_matrix, to); + succeeded &= impl_get_uniform_to_inverse_matrix_masked(bsg, to_matrix, to_); impl_wide_mat_multiply(wrm, from_matrix, to_matrix); return succeeded; @@ -886,27 +889,27 @@ impl_get_uniform_from_to_matrix_masked(BatchedShaderGlobals* bsg, } // namespace OSL_BATCHOP int -__OSL_MASKED_OP3(get_from_to_matrix, Wm, s, s)(void* bsg_, void* wr, - const char* from, const char* to, - unsigned int mask_value) +__OSL_MASKED_OP3(get_from_to_matrix, Wm, s, + s)(void* bsg_, void* wr, ustringhash_pod from_, + ustringhash_pod to_, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); Masked wrm(wr, Mask(mask_value)); - return impl_get_uniform_from_to_matrix_masked(bsg, wrm, from, to).value(); + return impl_get_uniform_from_to_matrix_masked(bsg, wrm, from_, to_).value(); } OSL_BATCHOP int __OSL_MASKED_OP3(get_from_to_matrix, Wm, s, - Ws)(void* bsg_, void* wr, const char* from, void* w_to_ptr, - unsigned int mask_value) + Ws)(void* bsg_, void* wr, ustringhash_pod from_, + void* w_to_ptr, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; Block wMfrom; Masked from_matrix(wMfrom, Mask(mask_value)); Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix, - from); + from_); Block bwToSpace; block_ustringhash_from_ptr(bwToSpace, w_to_ptr); @@ -927,7 +930,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, s, OSL_BATCHOP int __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws, - s)(void* bsg_, void* wr, void* w_from_ptr, const char* to, + s)(void* bsg_, void* wr, void* w_from_ptr, ustringhash_pod to_, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); @@ -940,7 +943,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws, Block wMto; Masked to_matrix(wMto, Mask(mask_value)); Mask succeeded = impl_get_uniform_to_inverse_matrix_masked(bsg, to_matrix, - to); + to_); Block wMfrom; // NOTE: even if we failed to get a to matrix, it should have been set to @@ -1001,34 +1004,30 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws, OSL_BATCHOP int __OSL_MASKED_OP3(build_transform_matrix, Wm, s, - s)(void* bsg_, void* WM_, ustring_pod from_, ustring_pod to_, - unsigned int mask_value) + s)(void* bsg_, void* WM_, ustringhash_pod from_, + ustringhash_pod to_, unsigned int mask_value) { - auto* bsg = reinterpret_cast(bsg_); + ustringhash from = ustringhash_from(from_); + ustringhash to = ustringhash_from(to_); + auto* bsg = reinterpret_cast(bsg_); Mask mask(mask_value); Masked mm(WM_, mask); ShadingContext* ctx = bsg->uniform.context; - ustring from = USTR(from_); - ustring to = USTR(to_); - Mask succeeded; // Avoid matrix concatenation if possible by detecting when the // adjacent matrix would be identity // We don't expect both from and to == common, so we are not // optimizing for it - if (from == Strings::common + if (from == Hashes::common || from == ctx->shadingsys().commonspace_synonym()) { - succeeded = impl_get_uniform_to_inverse_matrix_masked(bsg, mm, - to.c_str()); - } else if (to == Strings::common + succeeded = impl_get_uniform_to_inverse_matrix_masked(bsg, mm, to_); + } else if (to == Hashes::common || to == ctx->shadingsys().commonspace_synonym()) { - succeeded = impl_get_uniform_from_matrix_masked(bsg, mm, from.c_str()); + succeeded = impl_get_uniform_from_matrix_masked(bsg, mm, from_); } else { - succeeded = impl_get_uniform_from_to_matrix_masked(bsg, mm, - from.c_str(), - to.c_str()); + succeeded = impl_get_uniform_from_to_matrix_masked(bsg, mm, from_, to_); } return succeeded.value(); } @@ -1037,7 +1036,7 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s, OSL_BATCHOP int __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, - s)(void* bsg_, void* WM_, void* wfrom_, ustring_pod to_, + s)(void* bsg_, void* WM_, void* wfrom_, ustringhash_pod to_, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); @@ -1049,8 +1048,6 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, block_ustringhash_from_ptr(bwfrom_space, wfrom_); Wide wfrom_space(bwfrom_space); - ustring to_space = USTR(to_); - Block wMfrom, wMto; Masked from_matrix(wMfrom, wrm.mask()); ShadingContext* ctx = bsg->uniform.context; @@ -1058,8 +1055,7 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, Mask succeeded = impl_get_varying_from_matrix_batched(bsg, ctx, wfrom_space, from_matrix); Masked to_matrix(wMto, wrm.mask() & succeeded); - succeeded &= impl_get_uniform_to_inverse_matrix_masked(bsg, to_matrix, - to_space.c_str()); + succeeded &= impl_get_uniform_to_inverse_matrix_masked(bsg, to_matrix, to_); impl_wide_mat_multiply(wrm, from_matrix, to_matrix); return succeeded.value(); @@ -1069,7 +1065,7 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, OSL_BATCHOP int __OSL_MASKED_OP3(build_transform_matrix, Wm, s, - Ws)(void* bsg_, void* WM_, ustring_pod from_, void* wto_, + Ws)(void* bsg_, void* WM_, ustringhash_pod from_, void* wto_, unsigned int mask_value) { auto* bsg = reinterpret_cast(bsg_); @@ -1077,7 +1073,6 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s, Mask mask(mask_value); Masked wrm(WM_, mask); - ustring from = USTR(from_); Block bwto_space; block_ustringhash_from_ptr(bwto_space, wto_); Wide wto_space(bwto_space); @@ -1087,7 +1082,7 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s, ShadingContext* ctx = bsg->uniform.context; Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix, - from.c_str()); + from_); Masked to_matrix(wMto, wrm.mask() & succeeded); succeeded &= impl_get_varying_to_matrix_masked(bsg, ctx, wto_space, to_matrix); diff --git a/src/liboslexec/wide/wide_opmessage.cpp b/src/liboslexec/wide/wide_opmessage.cpp index de426f9c7c..be2c11e3e6 100644 --- a/src/liboslexec/wide/wide_opmessage.cpp +++ b/src/liboslexec/wide/wide_opmessage.cpp @@ -201,18 +201,19 @@ impl_setmessage(BatchedShaderGlobals* bsg, ustring sourcefile, int sourceline, OSL_BATCHOP void __OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, - ustring_pod name_, long long type, + ustringhash_pod name_, long long type, void* wvalue, int layeridx, - ustring_pod sourcefile_, int sourceline, + ustringhash_pod sourcefile_, int sourceline, unsigned int mask_value) { Mask mask(mask_value); OSL_ASSERT(mask.any_on()); - ustring name = USTR(name_); + ustring name = ustring_from(name_); + MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue); - ustring sourcefile = USTR(sourcefile_); + ustring sourcefile = ustring_from(sourcefile_); auto* bsg = reinterpret_cast(bsg_); @@ -238,8 +239,8 @@ __OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, OSL_BATCHOP void __OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname, long long type, void* wvalue, int layeridx, - ustring_pod sourcefile_, int sourceline, - unsigned int mask_value) + ustringhash_pod sourcefile_, + int sourceline, unsigned int mask_value) { Mask mask(mask_value); OSL_ASSERT(mask.any_on()); @@ -247,7 +248,7 @@ __OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname, Wide wName(wname); MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue); - ustring sourcefile = USTR(sourcefile_); + ustring sourcefile = ustring_from(sourcefile_); auto* bsg = reinterpret_cast(bsg_); @@ -275,14 +276,15 @@ __OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname, OSL_BATCHOP void -__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, ustring_pod source_, - ustring_pod name_, long long type_, void* val, - int derivs, int layeridx, ustring_pod sourcefile_, - int sourceline, unsigned int mask_value) +__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, ustringhash_pod source_, + ustringhash_pod name_, long long type_, void* val, + int derivs, int layeridx, + ustringhash_pod sourcefile_, int sourceline, + unsigned int mask_value) { - ustring source = USTR(source_); - ustring name = USTR(name_); - ustring sourcefile = USTR(sourcefile_); + ustring source = ustring_from(source_); + ustring name = ustring_from(name_); + ustring sourcefile = ustring_from(sourcefile_); Mask mask(mask_value); @@ -301,7 +303,7 @@ __OSL_MASKED_OP(getmessage)(void* bsg_, void* result, ustring_pod source_, static ustring ktrace("trace"); OSL_ASSERT(val != nullptr); MaskedData valRef(type, derivs, mask, val); - if (USTR(source_) == ktrace) { + if (source == ktrace) { // Source types where we need to ask the renderer return bsg->uniform.renderer->batched(WidthTag()) ->getmessage(bsg, wR, source, name, valRef); diff --git a/src/liboslexec/wide/wide_oppointcloud.cpp b/src/liboslexec/wide/wide_oppointcloud.cpp index 1ed34138b0..091921e2c5 100644 --- a/src/liboslexec/wide/wide_oppointcloud.cpp +++ b/src/liboslexec/wide/wide_oppointcloud.cpp @@ -494,7 +494,7 @@ dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename, OSL_BATCHOP void __OSL_MASKED_OP(pointcloud_search)( - BatchedShaderGlobals* bsg, void* wout_num_points_, ustring_pod filename, + BatchedShaderGlobals* bsg, void* wout_num_points_, ustringhash_pod filename, const void* wcenter_, void* wradius_, int max_points, int sort, void* wout_indices_, int indices_array_length, void* wout_distances_, int distances_array_length, int distances_has_derivs, int mask_value, @@ -521,8 +521,8 @@ __OSL_MASKED_OP(pointcloud_search)( Wide wradius(wradius_); - dispatch_pointcloud_search(bsg, USTR(filename).uhash(), wcenter_, wradius, - max_points, sort, pcsr); + dispatch_pointcloud_search(bsg, ustringhash_from(filename), wcenter_, + wradius, max_points, sort, pcsr); if (nattrs > 0) { Wide windices { wout_indices_, indices_array_length }; @@ -531,12 +531,15 @@ __OSL_MASKED_OP(pointcloud_search)( va_list args; va_start(args, nattrs); for (int i = 0; i < nattrs; i++) { - ustring attr_name = USTR(va_arg(args, ustring_pod)); + ustringhash attr_name = ustringhash_from( + va_arg(args, ustringhash_pod)); TypeDesc attr_type = TYPEDESC(va_arg(args, long long)); void* out_data = va_arg(args, void*); - dispatch_pointcloud_get( - bsg, USTR(filename), windices, wnum_points, attr_name, - MaskedData { attr_type, false, Mask { mask_value }, out_data }); + dispatch_pointcloud_get(bsg, ustringhash_from(filename), windices, + wnum_points, attr_name, + MaskedData { attr_type, false, + Mask { mask_value }, + out_data }); } va_end(args); } @@ -548,11 +551,11 @@ __OSL_MASKED_OP(pointcloud_search)( OSL_BATCHOP int -__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename, - void* windices_, int indices_array_length, - void* wnum_points_, ustring_pod attr_name, - long long attr_type_, void* wout_data_, - int mask_value) +__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, + ustringhash_pod filename, void* windices_, + int indices_array_length, void* wnum_points_, + ustringhash_pod attr_name, long long attr_type_, + void* wout_data_, int mask_value) { ShadingContext* ctx = bsg->uniform.context; if (ctx->shadingsys() @@ -565,8 +568,8 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename, TypeDesc attr_type = TYPEDESC(attr_type_); Mask success = dispatch_pointcloud_get( - bsg, USTR(filename).uhash(), windices, wnum_points, - USTR(attr_name).uhash(), + bsg, ustringhash_from(filename), windices, wnum_points, + ustringhash_from(attr_name), MaskedData { attr_type, false, Mask { mask_value }, wout_data_ }); return success.value(); } @@ -575,7 +578,7 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename, OSL_BATCHOP int __OSL_MASKED_OP(pointcloud_write)(BatchedShaderGlobals* bsg, - ustring_pod filename, const void* wpos_, + ustringhash_pod filename, const void* wpos_, int nattribs, const ustring* attr_names, const TypeDesc* attr_types, const void** ptrs_to_wide_attr_value, @@ -589,10 +592,10 @@ __OSL_MASKED_OP(pointcloud_write)(BatchedShaderGlobals* bsg, Wide wpos(wpos_); - Mask success = dispatch_pointcloud_write(bsg, USTR(filename).uhash(), wpos, - nattribs, attr_names, attr_types, - ptrs_to_wide_attr_value, - Mask(mask_value)); + Mask success + = dispatch_pointcloud_write(bsg, ustringhash_from(filename), wpos, + nattribs, attr_names, attr_types, + ptrs_to_wide_attr_value, Mask(mask_value)); return success.value(); } diff --git a/src/liboslexec/wide/wide_optexture.cpp b/src/liboslexec/wide/wide_optexture.cpp index 63353be226..9a650caaca 100644 --- a/src/liboslexec/wide/wide_optexture.cpp +++ b/src/liboslexec/wide/wide_optexture.cpp @@ -33,7 +33,7 @@ namespace { Mask -default_texture(BatchedRendererServices* bsr, ustring filename, +default_texture(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, BatchedShaderGlobals* bsg, @@ -49,7 +49,7 @@ default_texture(BatchedRendererServices* bsr, ustring filename, texture_thread_info = context->texture_thread_info(); if (!texture_handle) texture_handle - = bsr->texturesys()->get_texture_handle(filename, + = bsr->texturesys()->get_texture_handle(ustring_from(filename), texture_thread_info); Mask mask = outputs.mask(); @@ -194,7 +194,7 @@ default_texture(BatchedRendererServices* bsr, ustring filename, OSL_FORCEINLINE Mask -dispatch_texture(BatchedRendererServices* bsr, ustring filename, +dispatch_texture(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, @@ -204,9 +204,9 @@ dispatch_texture(BatchedRendererServices* bsr, ustring filename, Wide dtdy, BatchedTextureOutputs& outputs) { if (bsr->is_overridden_texture()) { - return bsr->texture(filename, texture_handle, texture_thread_info, - options, bsg, s, t, dsdx, dtdx, dsdy, dtdy, - outputs); + return bsr->texture(ustringhash_from(filename), texture_handle, + texture_thread_info, options, bsg, s, t, dsdx, dtdx, + dsdy, dtdy, outputs); } else { return default_texture(bsr, filename, texture_handle, texture_thread_info, options, bsg, s, t, dsdx, @@ -217,7 +217,7 @@ dispatch_texture(BatchedRendererServices* bsr, ustring filename, Mask -default_texture3d(BatchedRendererServices* bsr, ustring filename, +default_texture3d(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, @@ -232,7 +232,7 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename, texture_thread_info = context->texture_thread_info(); if (!texture_handle) texture_handle - = bsr->texturesys()->get_texture_handle(filename, + = bsr->texturesys()->get_texture_handle(ustring_from(filename), texture_thread_info); Mask mask = outputs.mask(); @@ -391,7 +391,7 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename, OSL_FORCEINLINE Mask -dispatch_texture3d(BatchedRendererServices* bsr, ustring filename, +dispatch_texture3d(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, @@ -400,8 +400,9 @@ dispatch_texture3d(BatchedRendererServices* bsr, ustring filename, Wide dPdz, BatchedTextureOutputs& outputs) { if (bsr->is_overridden_texture3d()) { - return bsr->texture3d(filename, texture_handle, texture_thread_info, - options, bsg, P, dPdx, dPdy, dPdz, outputs); + return bsr->texture3d(ustringhash_from(filename), texture_handle, + texture_thread_info, options, bsg, P, dPdx, dPdy, + dPdz, outputs); } else { return default_texture3d(bsr, filename, texture_handle, texture_thread_info, options, bsg, P, dPdx, @@ -412,7 +413,7 @@ dispatch_texture3d(BatchedRendererServices* bsr, ustring filename, Mask -default_environment(BatchedRendererServices* bsr, ustring filename, +default_environment(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, @@ -427,7 +428,7 @@ default_environment(BatchedRendererServices* bsr, ustring filename, texture_thread_info = context->texture_thread_info(); if (!texture_handle) texture_handle - = bsr->texturesys()->get_texture_handle(filename, + = bsr->texturesys()->get_texture_handle(ustring_from(filename), texture_thread_info); Mask mask = outputs.mask(); @@ -539,7 +540,7 @@ default_environment(BatchedRendererServices* bsr, ustring filename, OSL_FORCEINLINE Mask -dispatch_environment(BatchedRendererServices* bsr, ustring filename, +dispatch_environment(BatchedRendererServices* bsr, ustringhash_pod filename, TextureSystem::TextureHandle* texture_handle, TextureSystem::Perthread* texture_thread_info, const BatchedTextureOptions& options, @@ -548,8 +549,9 @@ dispatch_environment(BatchedRendererServices* bsr, ustring filename, BatchedTextureOutputs& outputs) { if (bsr->is_overridden_texture3d()) { - return bsr->environment(filename, texture_handle, texture_thread_info, - options, bsg, R, dRdx, dRdy, outputs); + return bsr->environment(ustringhash_from(filename), texture_handle, + texture_thread_info, options, bsg, R, dRdx, + dRdy, outputs); } else { return default_environment(bsr, filename, texture_handle, texture_thread_info, options, bsg, R, dRdx, @@ -563,7 +565,7 @@ dispatch_environment(BatchedRendererServices* bsr, ustring filename, OSL_BATCHOP int -__OSL_MASKED_OP(texture)(void* bsg_, ustring_pod name_, void* handle, +__OSL_MASKED_OP(texture)(void* bsg_, ustringhash_pod name_, void* handle, const void* opt_, const void* s, const void* t, const void* dsdx, const void* dtdx, const void* dsdy, const void* dtdy, int chans, void* result, @@ -582,8 +584,8 @@ __OSL_MASKED_OP(texture)(void* bsg_, ustring_pod name_, void* handle, (bool)alphaHasDerivs, errormessage, mask); Mask retVal - = dispatch_texture(bsg->uniform.renderer->batched(WidthTag()), - USTR(name_), (TextureSystem::TextureHandle*)handle, + = dispatch_texture(bsg->uniform.renderer->batched(WidthTag()), name_, + (TextureSystem::TextureHandle*)handle, bsg->uniform.context->texture_thread_info(), opt, bsg, Wide(s), Wide(t), Wide(dsdx), Wide(dtdx), @@ -607,7 +609,7 @@ __OSL_MASKED_OP(texture)(void* bsg_, ustring_pod name_, void* handle, OSL_BATCHOP int -__OSL_MASKED_OP(texture3d)(void* bsg_, ustring_pod name_, void* handle, +__OSL_MASKED_OP(texture3d)(void* bsg_, ustringhash_pod name_, void* handle, const void* opt_, const void* wP, const void* wPdx, const void* wPdy, const void* wPdz, int chans, void* result, int resultHasDerivs, void* alpha, @@ -630,8 +632,8 @@ __OSL_MASKED_OP(texture3d)(void* bsg_, ustring_pod name_, void* handle, // NOTE: If overridden, BatchedRendererServiced::texture is responsible // for correcting our str texture space gradients into xyz-space gradients Mask retVal - = dispatch_texture3d(bsg->uniform.renderer->batched(WidthTag()), - USTR(name_), (TextureSystem::TextureHandle*)handle, + = dispatch_texture3d(bsg->uniform.renderer->batched(WidthTag()), name_, + (TextureSystem::TextureHandle*)handle, bsg->uniform.context->texture_thread_info(), opt, bsg, Wide(wP), Wide(wPdx), Wide(wPdy), Wide(wPdz), @@ -653,7 +655,7 @@ __OSL_MASKED_OP(texture3d)(void* bsg_, ustring_pod name_, void* handle, OSL_BATCHOP int -__OSL_MASKED_OP(environment)(void* bsg_, ustring_pod name_, void* handle, +__OSL_MASKED_OP(environment)(void* bsg_, ustringhash_pod name_, void* handle, const void* opt_, const void* wR, const void* wRdx, const void* wRdy, int chans, void* result, int resultHasDerivs, void* alpha, @@ -670,12 +672,13 @@ __OSL_MASKED_OP(environment)(void* bsg_, ustring_pod name_, void* handle, // NOTE: If overridden, BatchedRendererServiced::texture is responsible // for correcting our str texture space gradients into xyz-space gradients - Mask retVal = dispatch_environment( - bsg->uniform.renderer->batched(WidthTag()), USTR(name_), - (TextureSystem::TextureHandle*)handle, - bsg->uniform.context->texture_thread_info(), opt, bsg, - Wide(wR), Wide(wRdx), Wide(wRdy), - outputs); + Mask retVal + = dispatch_environment(bsg->uniform.renderer->batched(WidthTag()), + name_, (TextureSystem::TextureHandle*)handle, + bsg->uniform.context->texture_thread_info(), opt, + bsg, Wide(wR), + Wide(wRdx), Wide(wRdy), + outputs); // For now, just zero out the result derivatives. If somebody needs // derivatives of environment lookups, we'll fix it. The reason @@ -756,9 +759,9 @@ __OSL_MASKED_OP(resolve_udim)(void* bsg_, const char* name, void* handle, OSL_BATCHOP int -__OSL_OP(get_textureinfo_uniform)(void* bsg_, ustring_pod name_, void* handle, - ustring_pod dataname_, const void* attr_type, - void* attr_dest) +__OSL_OP(get_textureinfo_uniform)(void* bsg_, ustringhash_pod name_, + void* handle, ustringhash_pod dataname_, + const void* attr_type, void* attr_dest) { // recreate TypeDesc auto* bsg = reinterpret_cast(bsg_); @@ -768,8 +771,9 @@ __OSL_OP(get_textureinfo_uniform)(void* bsg_, ustring_pod name_, void* handle, bool retVal = bsg->uniform.renderer->batched(WidthTag()) ->get_texture_info_uniform( bsg, bsg->uniform.context->texture_thread_info(), - USTR(name_), (RendererServices::TextureHandle*)handle, - 0 /*FIXME-ptex*/, USTR(dataname_), dest); + ustringhash_from(name_), + (RendererServices::TextureHandle*)handle, + 0 /*FIXME-ptex*/, ustringhash_from(dataname_), dest); return retVal; } diff --git a/src/liboslexec/wide/wide_shadingsys.cpp b/src/liboslexec/wide/wide_shadingsys.cpp index db52f8c0c3..0d1c3d74bd 100644 --- a/src/liboslexec/wide/wide_shadingsys.cpp +++ b/src/liboslexec/wide/wide_shadingsys.cpp @@ -29,9 +29,9 @@ using WidthTag = OSL::WidthOf<__OSL_WIDTH>; // firstcheck,nchecks are used to check just one element of an array. OSL_BATCHOP void __OSL_OP(naninf_check)(int ncomps, const void* vals_, int has_derivs, - void* bsg_, ustring_pod sourcefile, int sourceline, - ustring_pod symbolname, int firstcheck, int nchecks, - ustring_pod opname) + void* bsg_, ustringhash_pod sourcefile, int sourceline, + ustringhash_pod symbolname, int firstcheck, int nchecks, + ustringhash_pod opname) { auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; @@ -42,8 +42,9 @@ __OSL_OP(naninf_check)(int ncomps, const void* vals_, int has_derivs, if (!OIIO::isfinite(vals[i])) { ctx->errorfmt("Detected {} value in {}{} at {}:{} (op {})", vals[i], d > 0 ? "the derivatives of " : "", - USTR(symbolname), USTR(sourcefile), sourceline, - USTR(opname)); + ustring_from(symbolname), + ustring_from(sourcefile), sourceline, + ustring_from(opname)); return; } } @@ -56,9 +57,9 @@ __OSL_OP(naninf_check)(int ncomps, const void* vals_, int has_derivs, OSL_BATCHOP void __OSL_MASKED_OP1(naninf_check_offset, i)(int mask_value, int ncomps, const void* vals_, - int has_derivs, void* bsg_, ustring_pod sourcefile, - int sourceline, ustring_pod symbolname, int firstcheck, - int nchecks, ustring_pod opname) + int has_derivs, void* bsg_, ustringhash_pod sourcefile, + int sourceline, ustringhash_pod symbolname, int firstcheck, + int nchecks, ustringhash_pod opname) { auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; @@ -72,9 +73,9 @@ __OSL_MASKED_OP1(naninf_check_offset, ctx->errorfmt( "Detected {} value in {}{} at {}:{} (op {}) batch lane:{}", vals[i * __OSL_WIDTH + lane], - d > 0 ? "the derivatives of " : "", USTR(symbolname), - USTR(sourcefile), sourceline, USTR(opname), - lane.value()); + d > 0 ? "the derivatives of " : "", + ustring_from(symbolname), ustring_from(sourcefile), + sourceline, ustring_from(opname), lane.value()); // continue checking all data lanes, and all components // for that matter, we want to find all issues, not just // the 1st, right? @@ -91,10 +92,10 @@ __OSL_MASKED_OP1(naninf_check_offset, OSL_BATCHOP void __OSL_MASKED_OP1(naninf_check_offset, Wi)(int mask_value, int ncomps, const void* vals_, - int has_derivs, void* bsg_, ustring_pod sourcefile, - int sourceline, ustring_pod symbolname, + int has_derivs, void* bsg_, ustringhash_pod sourcefile, + int sourceline, ustringhash_pod symbolname, const void* wide_offsets_ptr, int nchecks, - ustring_pod opname) + ustringhash_pod opname) { auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; @@ -111,9 +112,9 @@ __OSL_MASKED_OP1(naninf_check_offset, ctx->errorfmt( "Detected {} value in {}{} at {}:{} (op {}) batch lane:{}", vals[i * __OSL_WIDTH + lane], - d > 0 ? "the derivatives of " : "", USTR(symbolname), - USTR(sourcefile), sourceline, USTR(opname), - lane.value()); + d > 0 ? "the derivatives of " : "", + ustring_from(symbolname), ustring_from(sourcefile), + sourceline, ustring_from(opname), lane.value()); // continue checking all data lanes, and all components // for that matter, we want to find all issues, not just // the 1st, right? @@ -131,10 +132,11 @@ __OSL_MASKED_OP1(naninf_check_offset, OSL_BATCHOP void __OSL_OP2(uninit_check_values_offset, X, i)(long long typedesc_, void* vals_, void* bsg_, - ustring_pod sourcefile, int sourceline, ustring_pod groupname_, - int layer, ustring_pod layername_, ustring_pod shadername, - int opnum, ustring_pod opname, int argnum, ustring_pod symbolname, - int firstcheck, int nchecks) + ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, ustringhash_pod layername_, + ustringhash_pod shadername, int opnum, ustringhash_pod opname, + int argnum, ustringhash_pod symbolname, int firstcheck, + int nchecks) { TypeDesc typedesc = TYPEDESC(typedesc_); auto* bsg = reinterpret_cast(bsg_); @@ -165,8 +167,8 @@ __OSL_OP2(uninit_check_values_offset, X, } } if (uninit) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); ctx->errorfmt( "Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {})", typedesc, symbolname, sourcefile, sourceline, @@ -183,11 +185,11 @@ __OSL_OP2(uninit_check_values_offset, X, OSL_BATCHOP void __OSL_MASKED_OP2(uninit_check_values_offset, WX, i)(int mask_value, long long typedesc_, void* vals_, - void* bsg_, ustring_pod sourcefile, int sourceline, - ustring_pod groupname_, int layer, ustring_pod layername_, - ustring_pod shadername, int opnum, ustring_pod opname, - int argnum, ustring_pod symbolname, int firstcheck, - int nchecks) + void* bsg_, ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, + ustringhash_pod layername_, ustringhash_pod shadername, + int opnum, ustringhash_pod opname, int argnum, + ustringhash_pod symbolname, int firstcheck, int nchecks) { TypeDesc typedesc = TYPEDESC(typedesc_); auto* bsg = reinterpret_cast(bsg_); @@ -229,8 +231,8 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX, }); } if (lanes_uninit.any_on()) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); ctx->errorfmt( "Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch", typedesc, symbolname, sourcefile, sourceline, @@ -247,11 +249,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX, OSL_BATCHOP void __OSL_MASKED_OP2(uninit_check_values_offset, X, Wi)(int mask_value, long long typedesc_, void* vals_, - void* bsg_, ustring_pod sourcefile, int sourceline, - ustring_pod groupname_, int layer, ustring_pod layername_, - ustring_pod shadername, int opnum, ustring_pod opname, - int argnum, ustring_pod symbolname, - const void* wide_offsets_ptr, int nchecks) + void* bsg_, ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, + ustringhash_pod layername_, ustringhash_pod shadername, + int opnum, ustringhash_pod opname, int argnum, + ustringhash_pod symbolname, const void* wide_offsets_ptr, + int nchecks) { TypeDesc typedesc = TYPEDESC(typedesc_); auto* bsg = reinterpret_cast(bsg_); @@ -295,8 +298,8 @@ __OSL_MASKED_OP2(uninit_check_values_offset, X, } if (lanes_uninit.any_on()) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); ctx->errorfmt( "Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch", typedesc, symbolname, sourcefile, sourceline, @@ -313,11 +316,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, X, OSL_BATCHOP void __OSL_MASKED_OP2(uninit_check_values_offset, WX, Wi)(int mask_value, long long typedesc_, void* vals_, - void* bsg_, ustring_pod sourcefile, int sourceline, - ustring_pod groupname_, int layer, ustring_pod layername_, - ustring_pod shadername, int opnum, ustring_pod opname, - int argnum, ustring_pod symbolname, - const void* wide_offsets_ptr, int nchecks) + void* bsg_, ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, + ustringhash_pod layername_, ustringhash_pod shadername, + int opnum, ustringhash_pod opname, int argnum, + ustringhash_pod symbolname, const void* wide_offsets_ptr, + int nchecks) { TypeDesc typedesc = TYPEDESC(typedesc_); auto* bsg = reinterpret_cast(bsg_); @@ -363,8 +367,8 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX, } if (lanes_uninit.any_on()) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); ctx->errorfmt( "Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch", typedesc, symbolname, sourcefile, sourceline, @@ -377,24 +381,24 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX, OSL_BATCHOP int -__OSL_OP(range_check)(int indexvalue, int length, ustring_pod symname, - void* bsg_, ustring_pod sourcefile, int sourceline, - ustring_pod groupname_, int layer, ustring_pod layername_, - ustring_pod shadername) +__OSL_OP(range_check)(int indexvalue, int length, ustringhash_pod symname, + void* bsg_, ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, + ustringhash_pod layername_, ustringhash_pod shadername) { if (indexvalue < 0 || indexvalue >= length) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); auto* bsg = reinterpret_cast(bsg_); ShadingContext* ctx = bsg->uniform.context; ctx->errorfmt("Index [{}] out of range {}[0..{}]: {}:{}" " (group {}, layer {} {}, shader {})", - indexvalue, USTR(symname), length - 1, USTR(sourcefile), - sourceline, + indexvalue, ustring_from(symname), length - 1, + ustring_from(sourcefile), sourceline, groupname.empty() ? "" : groupname.c_str(), layer, layername.empty() ? "" : layername.c_str(), - USTR(shadername)); + ustring_from(shadername)); if (indexvalue >= length) indexvalue = length - 1; else @@ -407,13 +411,14 @@ __OSL_OP(range_check)(int indexvalue, int length, ustring_pod symname, OSL_BATCHOP void __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value, - int length, ustring_pod symname, void* bsg_, - ustring_pod sourcefile, int sourceline, - ustring_pod groupname_, int layer, - ustring_pod layername_, ustring_pod shadername) + int length, ustringhash_pod symname, void* bsg_, + ustringhash_pod sourcefile, int sourceline, + ustringhash_pod groupname_, int layer, + ustringhash_pod layername_, + ustringhash_pod shadername) { - ustring groupname = USTR(groupname_); - ustring layername = USTR(layername_); + ustring groupname = ustring_from(groupname_); + ustring layername = ustring_from(layername_); auto* bsg = reinterpret_cast(bsg_); Masked wIndexValue(wide_indexvalue, Mask(mask_value)); wIndexValue.mask().foreach ([=](ActiveLane lane) -> void { @@ -422,12 +427,12 @@ __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value, ShadingContext* ctx = bsg->uniform.context; ctx->errorfmt( "Index [{}] out of range {}[0..{}]: {}:{} (group {}, layer {} {}, shader {})", - indexvalue, USTR(symname), length - 1, USTR(sourcefile), - sourceline, + indexvalue, ustring_from(symname), length - 1, + ustring_from(sourcefile), sourceline, groupname.empty() ? "" : groupname.c_str(), layer, layername.empty() ? "" : layername.c_str(), - USTR(shadername)); + ustring_from(shadername)); if (indexvalue >= length) indexvalue = length - 1; else @@ -441,17 +446,17 @@ __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value, OSL_BATCHOP int -__OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, ustring_pod obj_name_, - ustring_pod attr_name_, int array_lookup, int index, - const void* attr_type, void* wide_attr_dest, - int mask_) +__OSL_OP1(get_attribute, + s)(void* bsg_, int dest_derivs, ustringhash_pod obj_name_, + ustringhash_pod attr_name_, int array_lookup, int index, + const void* attr_type, void* wide_attr_dest, int mask_) { Mask mask(mask_); ASSERT(mask.any_on()); auto* bsg = reinterpret_cast(bsg_); - ustring obj_name = USTR(obj_name_); - ustring attr_name = USTR(attr_name_); + ustring obj_name = ustring_from(obj_name_); + ustring attr_name = ustring_from(attr_name_); // Ignoring m_next_failed_attrib cache for now, // might be faster @@ -473,15 +478,15 @@ __OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, ustring_pod obj_name_, OSL_BATCHOP int __OSL_MASKED_OP1(get_attribute, - Ws)(void* bsg_, int dest_derivs, ustring_pod obj_name_, - ustring_pod* wattr_name_, int array_lookup, int index, + Ws)(void* bsg_, int dest_derivs, ustringhash_pod obj_name_, + ustringhash_pod* wattr_name_, int array_lookup, int index, const void* attr_type, void* wide_attr_dest, int mask_) { Mask mask(mask_); ASSERT(mask.any_on()); auto* bsg = reinterpret_cast(bsg_); - ustring obj_name = USTR(obj_name_); + ustring obj_name = ustring_from(obj_name_); Wide wAttrName(wattr_name_); auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer(); @@ -521,13 +526,14 @@ __OSL_MASKED_OP1(get_attribute, OSL_BATCHOP bool __OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, - ustring_pod obj_name_, ustring_pod attr_name_, - int array_lookup, int index, - const void* attr_type, void* attr_dest) + ustringhash_pod obj_name_, + ustringhash_pod attr_name_, int array_lookup, + int index, const void* attr_type, + void* attr_dest) { auto* bsg = reinterpret_cast(bsg_); - ustring obj_name = USTR(obj_name_); - ustring attr_name = USTR(attr_name_); + ustring obj_name = ustring_from(obj_name_); + ustring attr_name = ustring_from(attr_name_); auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer(); @@ -547,10 +553,10 @@ __OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, OSL_BATCHOP int -__OSL_OP(bind_interpolated_param)(void* bsg_, ustring_pod name, long long type, - int userdata_has_derivs, void* userdata_data, - int symbol_has_derivs, void* symbol_data, - int symbol_data_size, +__OSL_OP(bind_interpolated_param)(void* bsg_, ustringhash_pod name, + long long type, int userdata_has_derivs, + void* userdata_data, int symbol_has_derivs, + void* symbol_data, int symbol_data_size, unsigned int* userdata_initialized, int userdata_index, unsigned int mask_value) { @@ -564,7 +570,8 @@ __OSL_OP(bind_interpolated_param)(void* bsg_, ustring_pod name, long long type, MaskedData userDest(TYPEDESC(type), userdata_has_derivs, Mask(mask_value), userdata_data); Mask foundUserData = bsg->uniform.renderer->batched(WidthTag()) - ->get_userdata(USTR(name), bsg, userDest); + ->get_userdata(ustring_from(name), bsg, + userDest); // print("Binding {} {} : index {}, ok = {}\n", name, // TYPEDESC(type).c_str(),userdata_index, foundUserData.value()); @@ -597,10 +604,11 @@ __OSL_OP(raytype_bit)(void* bsg_, int bit) // Asked if the raytype is a name we can't know until mid-shader. OSL_BATCHOP int -__OSL_OP(raytype_name)(void* bsg_, ustring_pod name) +__OSL_OP(raytype_name)(void* bsg_, ustringhash_pod name) { auto* bsg = reinterpret_cast(bsg_); - int bit = bsg->uniform.context->shadingsys().raytype_bit(USTR(name)); + int bit = bsg->uniform.context->shadingsys().raytype_bit( + ustring_from(name)); return (bsg->uniform.raytype & bit) != 0; } diff --git a/src/testminimal/CMakeLists.txt b/src/testminimal/CMakeLists.txt new file mode 100644 index 0000000000..42e6e9d115 --- /dev/null +++ b/src/testminimal/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +# The 'testminimal' executable +set ( testminimal_srcs + testminimal.cpp + oslmaterial.cpp ) + +set(include_dirs ${CMAKE_CURRENT_SOURCE_DIR}) +list(APPEND include_dirs ${CMAKE_SOURCE_DIR}/src/include) +list(APPEND include_dirs ${CMAKE_BINARY_DIR}/include) +list(APPEND include_dirs ${IMATH_INCLUDES}) +list(APPEND include_dirs ${OPENEXR_INCLUDES}) +list(APPEND include_dirs ${OpenImageIO_INCLUDES}) + +set ( rs_srcs + oslmaterial.cpp ) + +EMBED_LLVM_BITCODE_IN_CPP ( "${rs_srcs}" "_host" "testminimal_llvm_compiled_rs" testminimal_srcs "-DOSL_HOST_RS_BITCODE=1" "${include_dirs}") + +add_executable ( testminimal ${testminimal_srcs} ) + +target_link_libraries (testminimal + PRIVATE + oslexec oslquery) + +install (TARGETS testminimal RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + +osl_optix_target(testminimal) diff --git a/src/testminimal/oslmaterial.cpp b/src/testminimal/oslmaterial.cpp new file mode 100644 index 0000000000..9bc5470f73 --- /dev/null +++ b/src/testminimal/oslmaterial.cpp @@ -0,0 +1,199 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + + +#include "oslmaterial.h" +#include + +using std::cout; +using std::endl; + +#if OSL_USE_BATCHED +template +CustomBatchedRendererServices::CustomBatchedRendererServices( + BatchedOSLMaterial& m) + : OSL::BatchedRendererServices(m.texturesys()), m_sr(m) +{ +} +#endif + +OSLMaterial::OSLMaterial() {} + +#if OSL_USE_BATCHED +template +BatchedOSLMaterial::BatchedOSLMaterial() : m_batch(*this) +{ +} + +template BatchedOSLMaterial<8>::BatchedOSLMaterial(); +template BatchedOSLMaterial<16>::BatchedOSLMaterial(); +#endif + +// Supported closures and parameters +struct EmptyParams {}; + +enum ClosureIDs { + EMISSION_ID, + BACKGROUND_ID, + MICROFACET_ID, +}; + +struct MicrofacetParams { + OSL::ustringhash dist; + OSL::Vec3 N, U; + float xalpha, yalpha, eta; + int refract; +}; + +void +register_closures(OSL::ShadingSystem* ss) +{ + // "Describe the memory layout of each closure type to the OSL runtime" + constexpr int MaxParams = 32; + struct BuiltinClosures { + const char* name; + int id; + OSL::ClosureParam params[MaxParams]; // "upper bound" + }; + + using namespace OSL; + + // Closures with support built into OSL, connected by the 1st string + BuiltinClosures supported[] = { + { "emission", EMISSION_ID, { CLOSURE_FINISH_PARAM(EmptyParams) } }, + { "background", BACKGROUND_ID, { CLOSURE_FINISH_PARAM(EmptyParams) } }, + { "microfacet", + MICROFACET_ID, + { CLOSURE_STRING_PARAM(MicrofacetParams, dist), + CLOSURE_VECTOR_PARAM(MicrofacetParams, N), + CLOSURE_VECTOR_PARAM(MicrofacetParams, U), + CLOSURE_FLOAT_PARAM(MicrofacetParams, xalpha), + CLOSURE_FLOAT_PARAM(MicrofacetParams, yalpha), + CLOSURE_FLOAT_PARAM(MicrofacetParams, eta), + CLOSURE_INT_PARAM(MicrofacetParams, refract), + CLOSURE_FINISH_PARAM(MicrofacetParams) } }, + }; + // Closure registration here enables that type of closure, when executing or compiling a shader + for (const BuiltinClosures& c : supported) + ss->register_closure(c.name, c.id, c.params, nullptr, nullptr); +} + +void +process_bsdf_closure(const OSL::ClosureColor* closure) +{ + static const ::OSL::ustringhash uh_ggx(OIIO::Strutil::strhash("ggx")); + //static const ::OSL::ustringhash uh_beckmann(OIIO::Strutil::strhash("beckmann")); + if (!closure) + return; + switch (closure->id) { + case OSL::ClosureColor::MUL: { + process_bsdf_closure(closure->as_mul()->closure); + break; + } + case OSL::ClosureColor::ADD: { + process_bsdf_closure(closure->as_add()->closureA); + process_bsdf_closure(closure->as_add()->closureB); + break; + } + default: { + const OSL::ClosureComponent* comp = closure->as_comp(); + switch (comp->id) { + case EMISSION_ID: cout << "parsing emission closure" << endl; break; + case MICROFACET_ID: { + cout << "parsing microfacet closure" << endl; + const MicrofacetParams* mp = comp->as(); + if (mp->dist.hash() == uh_ggx.hash()) { + cout << "uh_ggx" << endl; + } else { + cout << "uh_beckmann or default" << endl; + } + } break; + default: + OSL_ASSERT(false && "Invalid closure invoked in surface shader"); + break; + } + } break; + } +} + +void +OSLMaterial::run_test(OSL::ShadingSystem* ss, OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, char* shader_name) +{ + register_closures(ss); + OSL::ShaderGlobals globals; + globals_from_hit(globals); + + std::vector options; + + // Create a new shader group + m_shaders.emplace_back(); + m_shaders[0] = ss->ShaderGroupBegin(std::to_string(0)); + OSL::ShaderGroupRef group = m_shaders[0]; + + //{ + // OSL::OSLCompiler compiler; + // std::string name = std::string(shader_name) + ".osl"; + // compiler.compile(name.c_str(), options); + //} + + ss->Shader(*group, "surface", shader_name, "Test"); + ss->ShaderGroupEnd(*group); + + ss->execute(context, *group, globals); + const OSL::ClosureColor* closure = globals.Ci; + process_bsdf_closure(closure); +} + +#if OSL_USE_BATCHED +template +void +BatchedOSLMaterial::run_test(OSL::ShadingSystem* ss, + OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, + char* shader_name) +{ + register_closures(ss); + OSL::BatchedShaderGlobals batched_globals; + + m_batch.globals_from_hit(batched_globals); + + std::vector options; + + // Create a new shader group + m_shaders.emplace_back(); + m_shaders[0] = ss->ShaderGroupBegin(std::to_string(0)); + OSL::ShaderGroupRef group = m_shaders[0]; + + //{ + // OSL::OSLCompiler compiler; + // std::string name = std::string(shader_name) + ".osl"; + // compiler.compile(name.c_str(), options); + //} + + ss->Shader(*group, "surface", shader_name, "Test"); + ss->ShaderGroupEnd(*group); + + // Run the shader that was just created + OSL::Block wide_shadeindex_block; + char* userdata_base_ptr = NULL; + char* output_base_ptr = NULL; + ss->batched().execute(*context, *group, batch_width, + wide_shadeindex_block, batched_globals, + userdata_base_ptr, output_base_ptr); + const OSL::ClosureColor* closure = batched_globals.varying.Ci[0]; + process_bsdf_closure(closure); +} + +template void +BatchedOSLMaterial<8>::run_test(OSL::ShadingSystem* ss, + OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, + char* shader_name); +template void +BatchedOSLMaterial<16>::run_test(OSL::ShadingSystem* ss, + OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, + char* shader_name); +#endif diff --git a/src/testminimal/oslmaterial.h b/src/testminimal/oslmaterial.h new file mode 100644 index 0000000000..12e49fca33 --- /dev/null +++ b/src/testminimal/oslmaterial.h @@ -0,0 +1,235 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + + +#pragma once +#include +#include +#include +#include +#include +#include +#include + +#if OSL_USE_BATCHED +# include +# include +#endif + +class OSLMaterial; + +#if OSL_USE_BATCHED +template class BatchedOSLMaterial; + +using OSL::Vec3; + +/// Custom BatchedRendererServices +template +class CustomBatchedRendererServices + : public OSL::BatchedRendererServices { +public: + explicit CustomBatchedRendererServices(BatchedOSLMaterial& m); + + //OIIO::ErrorHandler& errhandler() const { return *m_errhandler; } + /// Turn information at hitpoint into ShaderGlobals for OSL + void globals_from_hit(OSL::BatchedShaderGlobals& bsg) + { + // Uniform + auto& usg = bsg.uniform; + // Zero it all + std::memset(&usg, 0, sizeof(OSL::UniformShaderGlobals)); + usg.raytype = 1; // 1 stands for camera ray? + // Varying + auto& vsg = bsg.varying; + + //assign_all(vsg.shader2common, TransformationPtr(&Mshad)); + //assign_all(vsg.object2common, TransformationPtr(&Mobj)); + + for (int i = 0; i < batch_width; i++) + vsg.P[i] = { 0.0f, 0.0f, 0.0f }; + + for (int i = 0; i < batch_width; i++) + vsg.I[i] = { 0.0f, 0.0f, -1.0f }; // incident ray + for (int i = 0; i < batch_width; i++) + vsg.N[i] = { 0.0f, 0.0f, 1.0f }; // shading normal + for (int i = 0; i < batch_width; i++) + vsg.Ng[i] = { 0.0f, 0.0f, 1.0f }; // true geometric normal + + assign_all(vsg.u, + 0.5f); // 2D surface parameter u, and its differentials. + assign_all(vsg.v, + 0.5f); // 2D surface parameter u, and its differentials. + + + //if (false == vary_udxdy) { + assign_all(vsg.dudx, 0.0f); //uscale / xres); + assign_all(vsg.dudy, 0.0f); + //} + //if (false == vary_vdxdy) { + assign_all(vsg.dvdx, 0.0f); + assign_all(vsg.dvdy, 0.0f); //vscale / yres); + //} + + + //if (false == vary_Pdxdy) { + // assign_all(vsg.dPdx, Vec3(vsg.dudx[0], vsg.dudy[0], 0.0f)); + // assign_all(vsg.dPdy, Vec3(vsg.dvdx[0], vsg.dvdy[0], 0.0f)); + //} + + assign_all(vsg.dPdz, + Vec3(0.0f, 0.0f, 0.0f)); // just use 0 for volume tangent + + // Tangents of P with respect to surface u,v + assign_all(vsg.dPdu, Vec3(1.0f, 0.0f, 0.0f)); + assign_all(vsg.dPdv, Vec3(0.0f, 1.0f, 0.0f)); + + assign_all(vsg.I, Vec3(0, 0, 0)); + assign_all(vsg.dIdx, Vec3(0, 0, 0)); + assign_all(vsg.dIdy, Vec3(0, 0, 0)); + + // That also implies that our normal points to (0,0,1) + assign_all(vsg.N, Vec3(0, 0, 1)); + assign_all(vsg.Ng, Vec3(0, 0, 1)); + + assign_all(vsg.time, 0.0f); + assign_all(vsg.dtime, 0.0f); + assign_all(vsg.dPdtime, Vec3(0, 0, 0)); + + assign_all(vsg.Ps, Vec3(0, 0, 0)); + assign_all(vsg.dPsdx, Vec3(0, 0, 0)); + assign_all(vsg.dPsdy, Vec3(0, 0, 0)); + + assign_all(vsg.surfacearea, 1.0f); + assign_all(vsg.flipHandedness, 0); + assign_all(vsg.backfacing, 0); + + assign_all(vsg.Ci, (::OSL::ClosureColor*)NULL); + } + + bool is_overridden_get_inverse_matrix_WmWxWf() const override + { + return false; + }; + bool is_overridden_get_matrix_WmWsWf() const override { return false; }; + bool is_overridden_get_inverse_matrix_WmsWf() const override + { + return false; + }; + bool is_overridden_get_inverse_matrix_WmWsWf() const override + { + return false; + }; + bool is_overridden_texture() const override { return false; }; + bool is_overridden_texture3d() const override { return false; }; + bool is_overridden_environment() const override { return false; }; + bool is_overridden_pointcloud_search() const override { return false; }; + bool is_overridden_pointcloud_get() const override { return false; }; + bool is_overridden_pointcloud_write() const override { return false; }; + + BatchedOSLMaterial& m_sr; + +private: +}; +#endif + +/// Custom RendererServices for non-batched case +class OSLMaterial : public OSL::RendererServices { +public: + OSLMaterial(); + + void run_test(OSL::ShadingSystem* ss, OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, char* shader_name); + + OIIO::ErrorHandler& errhandler() const { return *m_errhandler; } + + /// Turn information at hitpoint into ShaderGlobals for OSL + void globals_from_hit(OSL::ShaderGlobals& sg) + { + sg.P = { 0.0f, 0.0f, 0.0f }; // surface pos + sg.dPdx = { 0.0f, 0.0f, 0.0f }; + sg.dPdy = { 0.0f, 0.0f, 0.0f }; + sg.dPdz = { 0.0f, 0.0f, 0.0f }; // for volume shading only + + sg.I = { 0.0f, 0.0f, -1.0f }; // incident ray + sg.dIdx = { 0.0f, 0.0f, 0.0f }; + sg.dIdy = { 0.0f, 0.0f, 0.0f }; + + sg.N = { 0.0f, 0.0f, 1.0f }; // shading normal + sg.Ng = { 0.0f, 0.0f, 1.0f }; // true geometric normal + + sg.u = 0.5f; // 2D surface parameter u, and its differentials. + sg.dudx = 0.0f; + sg.dudy = 0.0f; + sg.v = 0.5f; // 2D surface parameter v, and its differentials. + sg.dvdx = 0.0f; + sg.dvdy = 0.0f; + + // Surface tangents: derivative of P with respect to surface u and v. + sg.dPdu = { 1.0f, 0.0f, 0.0f }; + sg.dPdv = { 0.0f, 1.0f, 0.0f }; + + sg.time = 0.0f; + sg.dtime = 0.001f; + + // Velocity vector: derivative of position P with respect to time. + sg.dPdtime = { 0.0f, 0.0f, 0.0f }; + + // For lights or light attenuation shaders: the point being illuminated (???) + sg.Ps = { 0.0f, 0.0f, 0.0f }; + sg.dPsdx = { 0.0f, 0.0f, 0.0f }; + sg.dPsdy = { 0.0f, 0.0f, 0.0f }; + + // Renderer user pointers + sg.renderstate = NULL; + sg.tracedata = NULL; + sg.objdata = NULL; + + sg.renderer = this; + + sg.raytype = 1; // 1 stands for camera ray? + sg.flipHandedness = 0; + sg.backfacing = 0; + + // output closure, needs to be null initialized + sg.Ci = NULL; + } + + // ShaderGroupRef storage + std::vector& shaders() { return m_shaders; } + std::vector m_shaders; + +private: + std::unique_ptr m_errhandler; +}; + +#if OSL_USE_BATCHED + +/// Custom RendererServices for batched case +template +class BatchedOSLMaterial : public OSL::RendererServices { +public: + BatchedOSLMaterial(); + + void run_test(OSL::ShadingSystem* ss, OSL::PerThreadInfo* thread_info, + OSL::ShadingContext* context, char* shader_name); + + OIIO::ErrorHandler& errhandler() const { return *m_errhandler; } + + // ShaderGroupRef storage + std::vector& shaders() { return m_shaders; } + std::vector m_shaders; + + OSL::BatchedRendererServices* + batched(OSL::WidthOf) override + { + return &m_batch; + } + + CustomBatchedRendererServices m_batch; + +private: + std::unique_ptr m_errhandler; +}; + +#endif diff --git a/src/testminimal/testminimal.cpp b/src/testminimal/testminimal.cpp new file mode 100644 index 0000000000..94c9fcc378 --- /dev/null +++ b/src/testminimal/testminimal.cpp @@ -0,0 +1,143 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + + +#include +#include +#include +#include "oslmaterial.h" + +using namespace OSL; + +int +main(int argc, char** argv) +{ + int batch_width; + char* shader_name; + bool use_fma = false; + if (argc < 2) { + std::cout + << "usage: shader_name(without .oso) [+optional] batch_width (0/8/16) [+optional] use_fma 0/1" + << std::endl; + return 0; + } else if (argc >= 3) { + shader_name = argv[1]; + batch_width = atoi(argv[2]); +#if OSL_USE_BATCHED + if (batch_width != -1 && batch_width != 1 && batch_width != 8 + && batch_width != 16) + batch_width = 1; +#else + if (batch_width != 1) + batch_width = 1; +#endif + if (argc >= 4) { + use_fma = atoi(argv[3]); + } + } else { + shader_name = argv[1]; + batch_width = -1; + } + + OSLMaterial* oslmat = NULL; +#if OSL_USE_BATCHED + BatchedOSLMaterial<8>* boslmat8 = NULL; + BatchedOSLMaterial<16>* boslmat16 = NULL; +#endif + + TextureSystem* texturesys = TextureSystem::create(); + ShadingSystem* ss = NULL; + + if (batch_width == -1) { +#if OSL_USE_BATCHED + oslmat = new OSLMaterial(); + ss = new ShadingSystem(oslmat, NULL, &oslmat->errhandler()); + if (use_fma) + ss->attribute("llvm_jit_fma", true); + if (ss->configure_batch_execution_at(16)) + batch_width = 16; + else if (ss->configure_batch_execution_at(8)) + batch_width = 8; + else + batch_width = 1; + delete oslmat; + oslmat = NULL; + delete ss; + ss = NULL; +#else + if (use_fma) + ss->attribute("llvm_jit_fma", true); + batch_width = 1; +#endif + } + + switch (batch_width) { + case 1: + oslmat = new OSLMaterial(); + ss = new ShadingSystem(oslmat, texturesys, &oslmat->errhandler()); + break; +#if OSL_USE_BATCHED + case 8: + boslmat8 = new BatchedOSLMaterial<8>(); + ss = new ShadingSystem(boslmat8, texturesys, &boslmat8->errhandler()); + break; + case 16: + boslmat16 = new BatchedOSLMaterial<16>(); + ss = new ShadingSystem(boslmat16, texturesys, &boslmat16->errhandler()); + break; +#endif + } + +#if OSL_USE_BATCHED + if (batch_width > 1) { + if (use_fma) + ss->attribute("llvm_jit_fma", true); + ss->configure_batch_execution_at(batch_width); + + // build searchpath for ISA specific OSL shared libraries based on expected + // location of library directories relative to the executables path. + static const char* relative_lib_dirs[] = +# if (defined(_WIN32) || defined(_WIN64)) + { "\\..\\lib64", "\\..\\lib" }; +# else + { "/../lib64", "/../lib" }; +# endif + auto executable_directory = OIIO::Filesystem::parent_path( + OIIO::Sysutil::this_program_path()); + int dirNum = 0; + std::string librarypath; + for (const char* relative_lib_dir : relative_lib_dirs) { + if (dirNum++ > 0) + librarypath += ":"; + librarypath += executable_directory + relative_lib_dir; + } + ss->attribute("searchpath:library", librarypath); + } +#endif + + PerThreadInfo* thread_info; + ShadingContext* context; + thread_info = ss->create_thread_info(); + context = ss->get_context(thread_info); + + switch (batch_width) { + case 1: oslmat->run_test(ss, thread_info, context, shader_name); break; +#if OSL_USE_BATCHED + case 8: boslmat8->run_test(ss, thread_info, context, shader_name); break; + case 16: boslmat16->run_test(ss, thread_info, context, shader_name); break; +#endif + } + + ss->release_context(context); + ss->destroy_thread_info(thread_info); + + delete oslmat; +#if OSL_USE_BATCHED + delete boslmat8; + delete boslmat16; +#endif + delete ss; + + return 0; +} diff --git a/testsuite/closure-string/BATCHED b/testsuite/closure-string/BATCHED new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testsuite/closure-string/ref/out.txt b/testsuite/closure-string/ref/out.txt new file mode 100644 index 0000000000..d497c44d99 --- /dev/null +++ b/testsuite/closure-string/ref/out.txt @@ -0,0 +1,3 @@ +Compiled test.osl -> test.oso +parsing microfacet closure +uh_ggx diff --git a/testsuite/closure-string/run.py b/testsuite/closure-string/run.py new file mode 100755 index 0000000000..5e688f5cb9 --- /dev/null +++ b/testsuite/closure-string/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +command = testminimal("test") diff --git a/testsuite/closure-string/test.osl b/testsuite/closure-string/test.osl new file mode 100644 index 0000000000..4071f5d9e4 --- /dev/null +++ b/testsuite/closure-string/test.osl @@ -0,0 +1,4 @@ +shader test(string distribution = "ggx") +{ + Ci = microfacet(distribution, N, N, 0.1, 0.1, 0.0, 0); +} diff --git a/testsuite/runtest.py b/testsuite/runtest.py index befe278a46..eceec81be2 100755 --- a/testsuite/runtest.py +++ b/testsuite/runtest.py @@ -249,6 +249,14 @@ def oiiodiff (fileA, fileB, extraargs="", silent=True, concat=True) : command += " ;\n" return command +# Construct a command that run testminimal with the specified arguments, +# appending output to the file "out.txt". +def testminimal (args) : + if os.environ.__contains__('OSL_TESTMINIMAL_NAME') : + testminimalname = os.environ['OSL_TESTMINIMAL_NAME'] + " " + else : + testminimalname = osl_app("testminimal") + return (testminimalname + args + redirect + " ;\n") # Construct a command that run testshade with the specified arguments, # appending output to the file "out.txt".