diff --git a/src/include/OSL/llvm_util.h b/src/include/OSL/llvm_util.h index fbf091d60..0006387d4 100644 --- a/src/include/OSL/llvm_util.h +++ b/src/include/OSL/llvm_util.h @@ -804,6 +804,9 @@ class OSLEXECPUBLIC LLVM_Util { /// Dereference a pointer: return *ptr llvm::Value *op_load (llvm::Value *ptr); + /// Dereference an int ptr (casting ptr type if necessary) + llvm::Value *op_load_int (llvm::Value *ptr); + llvm::Value *op_gather(llvm::Value *ptr, llvm::Value *index); /// Store to a dereferenced pointer @@ -858,6 +861,10 @@ class OSLEXECPUBLIC LLVM_Util { llvm::Value *op_int_to_bool (llvm::Value *a); llvm::Value *op_float_to_double (llvm::Value *a); llvm::Value *op_int_to_longlong (llvm::Value *a); + // int_to_bool_to_int is essentially turning any nonzero -> 1 + llvm::Value *op_int_to_bool_to_int (llvm::Value *a) { + return op_bool_to_int(op_int_to_bool(a)); + } llvm::Value *op_and (llvm::Value *a, llvm::Value *b); llvm::Value *op_or (llvm::Value *a, llvm::Value *b); diff --git a/src/include/OSL/strdecls.h b/src/include/OSL/strdecls.h index 1f1028d39..1f071cefd 100644 --- a/src/include/OSL/strdecls.h +++ b/src/include/OSL/strdecls.h @@ -123,6 +123,7 @@ STRDECL("end", end) STRDECL("useparam", useparam) STRDECL("!!!uninitialized!!!", uninitialized_string) STRDECL("unull", unull) +STRDECL("flipHandedness", flipHandedness) STRDECL("raytype", raytype) STRDECL("color", color) STRDECL("point", point) diff --git a/src/liboslexec/batched_analysis.cpp b/src/liboslexec/batched_analysis.cpp index 97847b4a2..7d899e43f 100644 --- a/src/liboslexec/batched_analysis.cpp +++ b/src/liboslexec/batched_analysis.cpp @@ -72,7 +72,6 @@ static ustring op_texture3d("texture3d"); // Shader global strings static ustring object2common("object2common"); static ustring shader2common("shader2common"); -static ustring flipHandedness("flipHandedness"); } // namespace Strings namespace pvt { diff --git a/src/liboslexec/batched_backendllvm.cpp b/src/liboslexec/batched_backendllvm.cpp index 87e7ebb80..d99ea89bb 100644 --- a/src/liboslexec/batched_backendllvm.cpp +++ b/src/liboslexec/batched_backendllvm.cpp @@ -27,7 +27,6 @@ static ustring backfacing("backfacing"); static ustring surfacearea("surfacearea"); static ustring object2common("object2common"); static ustring shader2common("shader2common"); -static ustring flipHandedness("flipHandedness"); } // namespace Strings namespace pvt { diff --git a/src/liboslexec/batched_backendllvm.h b/src/liboslexec/batched_backendllvm.h index 2d85feac1..872c11b90 100644 --- a/src/liboslexec/batched_backendllvm.h +++ b/src/liboslexec/batched_backendllvm.h @@ -324,6 +324,10 @@ class BatchedBackendLLVM : public OSOProcessorBase { /// Retrieve the named global ("P", "N", etc.). /// is_uniform is output parameter llvm::Value* llvm_global_symbol_ptr(ustring name, bool& is_uniform); + llvm::Value* llvm_global_symbol_ptr(ustring name) { + bool is_uniform; + return llvm_global_symbol_ptr(name, is_uniform); + } /// Test whether val is nonzero, return the llvm::Value* that's the /// result of a CreateICmpNE or CreateFCmpUNE (depending on the diff --git a/src/liboslexec/batched_llvm_gen.cpp b/src/liboslexec/batched_llvm_gen.cpp index 7721adf9d..d25b60605 100644 --- a/src/liboslexec/batched_llvm_gen.cpp +++ b/src/liboslexec/batched_llvm_gen.cpp @@ -4054,8 +4054,8 @@ LLVMGEN (llvm_gen_calculatenormal) llvm::Value *args[] = { rop.llvm_void_ptr (Result), - rop.sg_void_ptr(), rop.llvm_load_arg (P, true /*derivs*/, false /*op_is_uniform*/), + rop.llvm_global_symbol_ptr(Strings::flipHandedness), nullptr}; int arg_count = 3; @@ -4313,19 +4313,15 @@ LLVMGEN (llvm_gen_raytype) llvm::Value * sg = rop.sg_void_ptr(); if (Name.is_constant()) { // We can statically determine the bit pattern - ustring name = ((ustring *)Name.data())[0]; - llvm::Value *args[] = { - sg, - rop.ll.constant (rop.shadingsys().raytype_bit (name))}; - - llvm::Value *ret = rop.ll.call_function (rop.build_name("raytype_bit"), args); - - if(!result_is_uniform) - { + llvm::Value* bit; + bit = rop.ll.constant(rop.shadingsys().raytype_bit(Name.get_string())); + llvm::Value* raytype = rop.ll.op_load_int( + rop.llvm_global_symbol_ptr(Strings::raytype)); + llvm::Value* bitanded = rop.ll.op_and(raytype, bit); + llvm::Value* ret = rop.ll.op_int_to_bool_to_int(bitanded); + if (!result_is_uniform) ret = rop.ll.widen_value(ret); - } rop.llvm_store_value (ret, Result); - } else { FuncSpec func_spec("raytype_name"); // No way to know which name is being asked for diff --git a/src/liboslexec/builtindecl.h b/src/liboslexec/builtindecl.h index c5124f967..634471661 100644 --- a/src/liboslexec/builtindecl.h +++ b/src/liboslexec/builtindecl.h @@ -203,7 +203,7 @@ DECL (osl_dict_find_iis, "iXiX") DECL (osl_dict_find_iss, "iXXX") DECL (osl_dict_next, "iXi") DECL (osl_dict_value, "iXiXLX") -DECL (osl_raytype_name, "iXX") +DECL (osl_raytype_bit, "iXX") #ifdef OSL_LLVM_NO_BITCODE DECL (osl_range_check, "iiiXXXiXiXX") #endif @@ -376,11 +376,11 @@ DECL (osl_trace_set_traceset, "xXs") DECL (osl_trace, "iXXXXXXXX") #ifdef OSL_LLVM_NO_BITCODE -DECL (osl_calculatenormal, "xXXX") +DECL (osl_calculatenormal, "xXXi") DECL (osl_area, "fX") DECL (osl_filterwidth_fdf, "fX") DECL (osl_filterwidth_vdv, "xXX") -DECL (osl_raytype_bit, "iXi") +DECL (osl_raytype_bit_from_name, "iXi") #endif diff --git a/src/liboslexec/llvm_gen.cpp b/src/liboslexec/llvm_gen.cpp index 71673530d..30ad0cdd0 100644 --- a/src/liboslexec/llvm_gen.cpp +++ b/src/liboslexec/llvm_gen.cpp @@ -3165,11 +3165,11 @@ LLVMGEN (llvm_gen_calculatenormal) rop.llvm_assign_zero (Result); return true; } - + llvm::Value * args[] = { - rop.llvm_void_ptr (Result), - rop.sg_void_ptr(), - rop.llvm_void_ptr (P), + rop.llvm_void_ptr(Result), + rop.llvm_void_ptr(P), + rop.ll.op_load_int(rop.llvm_global_symbol_ptr(Strings::flipHandedness)) }; rop.ll.call_function ("osl_calculatenormal", args); if (Result.has_derivs()) @@ -3766,20 +3766,22 @@ LLVMGEN (llvm_gen_raytype) OSL_DASSERT(op.nargs() == 2); Symbol& Result = *rop.opargsym (op, 0); Symbol& Name = *rop.opargsym (op, 1); - llvm::Value *args[2] = { rop.sg_void_ptr(), NULL }; - const char *func = NULL; + + llvm::Value* bit = nullptr; if (Name.is_constant()) { // We can statically determine the bit pattern - ustring name = Name.get_string(); - args[1] = rop.ll.constant (rop.shadingsys().raytype_bit (name)); - func = "osl_raytype_bit"; + bit = rop.ll.constant(rop.shadingsys().raytype_bit(Name.get_string())); } else { // No way to know which name is being asked for - args[1] = rop.llvm_get_pointer (Name); - func = "osl_raytype_name"; + bit = rop.ll.call_function("osl_raytype_bit", + rop.sg_void_ptr(), + rop.llvm_get_pointer(Name)); } - llvm::Value *ret = rop.ll.call_function (func, args); - rop.llvm_store_value (ret, Result); + + llvm::Value* raytype = rop.ll.op_load_int( + rop.llvm_global_symbol_ptr(Strings::raytype)); + llvm::Value* bitanded = rop.ll.op_and(raytype, bit); + rop.llvm_store_value (rop.ll.op_int_to_bool_to_int(bitanded), Result); return true; } diff --git a/src/liboslexec/llvm_ops.cpp b/src/liboslexec/llvm_ops.cpp index 28d8dc9b0..922136a12 100644 --- a/src/liboslexec/llvm_ops.cpp +++ b/src/liboslexec/llvm_ops.cpp @@ -59,11 +59,6 @@ examples), as you are just coding in C++, but there are some rules: may write templates or helper functions (which do NOT need to use OSL_SHADEOP, since they don't need to be runtime-discoverable by LLVM. -* If you need to access non-passed globals (P, N, etc.) or make renderer - callbacks, just make the first argument to the function a void* that - you cast to a ShaderGlobals* and access the globals, shading - context (sg->context), opaque renderer state (sg->renderstate), etc. - */ @@ -78,7 +73,6 @@ typedef long double max_align_t; #include #include -#include #include #include using namespace OSL; @@ -768,10 +762,9 @@ OSL_HOSTDEVICE inline Vec3 calculatenormal(void *P_, bool flipHandedness) return tmpP.dx().cross( tmpP.dy()); } -OSL_SHADEOP void osl_calculatenormal(void *out, void *sg_, void *P_) +OSL_SHADEOP void osl_calculatenormal(void *out, void *P_, int flipHandedness) { - ShaderGlobals *sg = (ShaderGlobals *)sg_; - Vec3 N = calculatenormal(P_, sg->flipHandedness); + Vec3 N = calculatenormal(P_, flipHandedness); // Don't normalize N VEC(out) = N; } @@ -806,15 +799,6 @@ OSL_SHADEOP void osl_filterwidth_vdv(void *out, void *x_) -// Asked if the raytype includes a bit pattern. -OSL_SHADEOP int osl_raytype_bit (void *sg_, int bit) -{ - ShaderGlobals *sg = (ShaderGlobals *)sg_; - return (sg->raytype & bit) != 0; -} - - - // extern declaration OSL_SHADEOP_NOINLINE int osl_range_check_err (int indexvalue, int length, const char *symname, void *sg, diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp index 4bd0dca35..0bfb184c4 100644 --- a/src/liboslexec/llvm_util.cpp +++ b/src/liboslexec/llvm_util.cpp @@ -3264,7 +3264,7 @@ LLVM_Util::ptr_to_cast (llvm::Value* val, llvm::Type *type) llvm::Value * LLVM_Util::ptr_cast (llvm::Value* val, llvm::Type *type) { - return builder().CreatePointerCast(val,type); + return val->getType() == type ? val : builder().CreatePointerCast(val,type); } @@ -3600,6 +3600,14 @@ LLVM_Util::op_load (llvm::Value *ptr) } +llvm::Value* +LLVM_Util::op_load_int(llvm::Value* ptr) +{ + return op_load(ptr_cast(ptr, type_int_ptr())); +} + + + llvm::Value * LLVM_Util::op_linearize_16x_indices(llvm::Value *wide_index) diff --git a/src/liboslexec/oslexec_pvt.h b/src/liboslexec/oslexec_pvt.h index 639a8b9de..30087d0d1 100644 --- a/src/liboslexec/oslexec_pvt.h +++ b/src/liboslexec/oslexec_pvt.h @@ -631,6 +631,7 @@ class ShadingSystemImpl /// Set the current color space. bool set_colorspace (ustring colorspace); + /// Return the bit that corresponds to the named ray type. int raytype_bit (ustring name); void optimize_all_groups (int nthreads=0, int mythread=0, int totalthreads=1, bool do_jit=true); diff --git a/src/liboslexec/shadingsys.cpp b/src/liboslexec/shadingsys.cpp index 0908c6f8b..8d3531bc6 100644 --- a/src/liboslexec/shadingsys.cpp +++ b/src/liboslexec/shadingsys.cpp @@ -4174,15 +4174,17 @@ osl_range_check_err (int indexvalue, int length, const char *symname, +// Return the raytype bit corresponding to a raytype name. // Asked if the raytype is a name we can't know until mid-shader. -OSL_SHADEOP int osl_raytype_name (void *sg_, void *name) +// FIXME: We should pass the context, not the sg. +OSL_SHADEOP int osl_raytype_bit (void *sg_, void *name) { ShaderGlobals *sg = (ShaderGlobals *)sg_; - int bit = sg->context->shadingsys().raytype_bit (USTR(name)); - return (sg->raytype & bit) != 0; + return sg->context->shadingsys().raytype_bit(USTR(name)); } + OSL_SHADEOP int osl_get_attribute(void *sg_, int dest_derivs, void *obj_name_, diff --git a/src/liboslexec/wide/wide_opalgebraic.cpp b/src/liboslexec/wide/wide_opalgebraic.cpp index f74d9f9de..400079acd 100644 --- a/src/liboslexec/wide/wide_opalgebraic.cpp +++ b/src/liboslexec/wide/wide_opalgebraic.cpp @@ -984,13 +984,12 @@ __OSL_MASKED_OP2(filterwidth,Wv,Wdv) OSL_BATCHOP void __OSL_OP(calculatenormal) - (void *out, void *bsg_, void *P_) + (void *out, void *P_, void* flip_) { - auto *bsg = reinterpret_cast(bsg_); OSL_FORCEINLINE_BLOCK { Wide> wP(P_); - Wide wFlipHandedness(bsg->varying.flipHandedness); + Wide wFlipHandedness(flip_); Wide wr(out); OSL_OMP_PRAGMA(omp simd simdlen(__OSL_WIDTH)) @@ -1004,21 +1003,19 @@ __OSL_OP(calculatenormal) OSL_BATCHOP void __OSL_MASKED_OP(calculatenormal) - (void *out, void *bsg_, void *P_, unsigned int mask_value) + (void *out, void *P_, void* flip_, unsigned int mask_value) { - auto *bsg = reinterpret_cast(bsg_); OSL_FORCEINLINE_BLOCK { Wide> wP(P_); - Wide wFlipHandedness(bsg->varying.flipHandedness); + Wide wFlipHandedness(flip_); Masked wr(out, Mask(mask_value)); OSL_OMP_PRAGMA(omp simd simdlen(__OSL_WIDTH)) for(int lane=0; lane < __OSL_WIDTH; ++lane) { Dual2 P = wP[lane]; int flip_handedness = wFlipHandedness[lane]; - //std::cout << "P=" << P.val() << "," << P.dx() << "," << P.dy() << std::endl; - + //std::cout << "P=" << P << std::endl; if (wr.mask()[lane]) { Vec3 N = calculatenormal(P, flip_handedness); wr[ActiveLane(lane)] = N;