Compare commits

...
39 Commits
Author SHA1 Message Date
Larry Gritz be53b07590 CHANGES 2015-11-18 15:52:43 -08:00
Larry Gritz 3606edd98b Make robust to some OIIO-side thread.h changes 2015-11-16 17:51:46 -08:00
Larry Gritz 2662e3c3a8 Use boost::thread_specific_ptr, don't rely on it in OIIO namespace. 2015-11-16 17:24:42 -08:00
Larry Gritz 6a5b9fb1f1 Fix typo bug, ick 2015-09-29 14:47:14 -07:00
Larry Gritz 4b12f100a3 Important bug fix for code generation of struct parameters copied whole.
When a shader param that was a struct had its value initialized by copying
another struct WHOLE, it neglected to set the "method" name for the init
ops for each field. This made it incorectly chalk up the init ops to the
struct param itself (which is just a dummy placeholder) instead of the
fields, and under some circumstances this could simply leave the struct
fields uninitialized.

It was fine all along if the struct param's fields were initialized one
by one -- in that case, the init ops were correctly associated with each
field individually. It was only the case of initializing by copying
another whole struct that was problematic.

The solution is to pass a flag to codegen_assign_struct indicating if we
are generating that code for a parameter initialization, in which case
it will do the proper calls to associate the init ops with the right
variable. This is just like we already did for the field-by-field case
handled in codegen_struct_initializers.
2015-09-29 14:46:43 -07:00
Brecht Van Lommel 2af62ddb81 Fix build error on Windows when not using TINYFORMAT_ALLOW_WCHAR_STRINGS. 2015-09-25 10:36:40 -07:00
Larry Gritz 2cd9387e18 Post-release version bump 2015-07-16 11:29:35 -07:00
Larry Gritz 7cc17a79cc CHANGES 2015-07-16 11:04:09 -07:00
John Haddon dd4840e817 Add query for which getattribute() calls a shader group might make.
New shader group queries for "num_attributes_needed", "attributes_needed", "attribute_scopes", "unknown_attributes_needed". These follow the convention for the existing texture and closure queries.
2015-07-14 17:02:18 -07:00
Larry Gritz a7b5483989 Fix initialization order fiasco introduced by recent change 2015-07-03 16:43:15 -07:00
Farchad Bidgolirad 6b89b52a28 Support for closure arrays in shader inputs 2015-07-03 11:41:09 -07:00
Farchad Bidgolirad ceda6e7c1c Fix for uninitialized static array in case of multithreaded access to ShaderGlobalNamesToIndex when compiled with vs2012 2015-07-03 11:31:17 -07:00
Farchad Bidgolirad f5bc9b239e Fix for range checking asserts in vs2012 debug builds 2015-07-02 16:42:20 +02:00
Larry Gritz 6a08652861 Enforce LLVM 3.5+'s need for C++11 with helpful build errors. 2015-06-29 16:50:59 -07:00
Larry Gritz b75ed8e187 Fix broken build after recent OIIO header change 2015-06-25 11:06:18 -07:00
Larry Gritz 1b1a740241 Bug fix with unconditional running of earlier layers.
Subtlety: When generating code for the "group entry" (last) layer, which
is also responsible for executing all earlier layers that are marked as
needing to run unconditionally (non-lazily), it is important that the
group entry layer initialize its input parameters BEFORE it runs the
earlier unconditional layers and copies the upstream outputs to its own
inputs. Of course. Because, duh, if it first runs the upstream layer and
copies the upsteam outputs to its own input, THEN zeroes out or
otherwise initializes its inputs, it will overwrite the value set by the
earlier layer.
2015-06-25 10:36:22 -07:00
Alejandro Conty 92e2038866 Fixing build with LLVM 3.5 2015-06-25 10:36:10 -07:00
Larry Gritz 0243926093 Bug fix serializing shader groups with "unsized arrays"
If asked the serialize the group before it's been optimized & jitted,
information about the concrete size of instance values of "unsized" arrays
will be in the SymOverrideInfo, not yet copied to the instance's copy
of the Symbol itself. So get it from the right place.
2015-06-24 10:24:20 -07:00
Larry Gritz 86dd484084 Bug fix in format() constant folding: was incorrectly calling insert_code
without specifying that variable read/write ranges should be recomputed.
This could lead to bad things.
2015-06-19 21:18:52 -07:00
Larry Gritz 157198aef0 RuntimeOptimizer::insert_code() call convention improvements
For clarity, use typed enums rather than bool and int for tricky
parameters, and make the recompute_rw_ranges parameter required rather
than optional.
2015-06-19 21:18:40 -07:00
Larry Gritz bcde312aab Improve debugging output when rewriting ops - list the args of the old op 2015-06-19 21:18:04 -07:00
Larry Gritz b6e0b7a52d Fix bugs when deserializing shader group strings with unsized arrays.
When an unsized array parameter comes in (like: param int[] 1 2 3 4) we
don't actually know the parameter type yet, because the shader itself
hasn't been declared. So, first of all, handle the "int[]" part without
ending up with an uninitialized length, duh. But then, we can't
preallocate at that point, because we don't know how many ints there
will be, so grow the array as we read them, and then reset the type to
the right length that we actually saw.
2015-06-19 09:48:19 -07:00
Larry Gritz 4125540682 Bug fix - beware of NULL string (passing as ustring is safe) 2015-06-18 13:10:12 -07:00
Larry Gritz 93f6c83ff3 Bump version after release 2015-06-11 22:58:17 -07:00
Larry Gritz 3d5331c726 Fix -- misspelled ENABLERTTI 2015-06-11 22:57:06 -07:00
Larry Gritz e95a49f39a Release 1.6.7 2015-06-11 11:38:46 -07:00
Larry Gritz b891e9d892 site customization file for Pixar 2015-06-11 11:32:23 -07:00
Larry Gritz 1626525b46 Add an alternate place to find stdosl.h 2015-06-11 11:32:15 -07:00
Larry Gritz 4568396f97 CMake option to disallow creation of OIIO::TextureSystem.
For renderers that supply their own TextureSystem class, this will
cause an assertion if a TS isn't either passed to the ShadingSystem ctr
or returned by RendererServices::texturesys(), and definitely won't
construct a default one on its own.
2015-06-09 16:38:31 -07:00
Larry Gritz 06d8cda6db CMake build-time option for turning on -fPIC 2015-06-08 11:26:39 -07:00
Larry Gritz 7efc45ee76 Build-time way to turn off building of test programs 2015-06-08 11:25:44 -07:00
Larry Gritz 28f45940a5 Docs/versions for official release 2015-06-03 23:46:36 -07:00
Larry Gritz 1e754f4fb6 Release candidate 2015-05-26 10:58:52 -07:00
Larry Gritz 2d47f217ca CHANGES 2015-05-26 10:55:45 -07:00
Larry Gritz 66982e9df0 Fixes to compiler warnings when using C++11 2015-05-22 10:50:42 -07:00
Larry Gritz c786fe0e09 C++11 work: Define OSL_BUILD_CPP11 to be 1 if OSL was built with C++11.
Note that this is subtly different than OSL_USING_CPP11, which is 1 if
C++11 is being used at that very moment. (They will be the same for OSL,
but may be different while building another package that uses OSL and/or
its public headers, if one package was built with C++11 and the other
not.)
2015-05-22 10:50:36 -07:00
Larry Gritz 84c5e24933 Move threadsafe ops outside of a lock 2015-05-21 11:39:14 -07:00
Larry Gritz 1ef5adadd8 Improve some debugging printfs, assertions, and the like.
Odds and ends I found while debugging, but these are not the actual fixes.
2015-05-21 11:39:01 -07:00
Larry Gritz da18dca6c5 Bump version 2015-05-21 10:53:12 -07:00
48 changed files with 756 additions and 145 deletions
+45 -1
View File
@@ -1,6 +1,45 @@
Changes:
Release 1.6 (1.6.5 - beta) -- 20 May 2015 (compared to 1.5)
Release 1.6.9 -- 18 Nov 2015 (compared to 1.6.8)
------------------------------------------------
* Bug fix for code generation of struct parameters copied whole. #564
* Fix Windows build issues. #561
* Some changes that will allow us to build against OIIO 1.6 trunk (a few
declarations have changed there). #581, #582
Release 1.6.8 -- 16 Jul 2015 (compared to 1.6.7)
------------------------------------------------
* Support shader parameters that are arrays of closures. (Thanks,
Ubisoft!) #544
* New shader group ShadingSystem::getattribute() queries:
num_attributes_needed, attributes_needed, attribute_scopes, and
unknown_attributes_needed. Collectively, these let you find out
exactly which getattribute tokens a compiled shader group may request.
(Works like the similar queries for userdata tokens.)
(Thanks, Image Engine!) #537
* Fix bugs when deserializing shader group strings with unsized arrays. #534
* Fix bugs when serializing shader groups with unsized arrays. #539
* Fix format() constant folding. #536
* Fix bug with unconditional running of earlier layers -- could botch
certain parameter initialization. #541
* Make sure we build correctly against LLVM 3.5.
* When building against LLVM 3.5, abort the build and give a clear error
message if not also using USE_CPP11=1 (because LLVM3.5 requres C++11). #542
* Fixes for clean VS2012 builds. #545
* Fix static array initialization problem with VS2012.
Release 1.6.7 -- 11 Jun 2015 (compared to 1.6.6)
-----------------------------------------------
* CMake option OSL_BUILD_TESTS=0 turns off building of test programs,
testshade, testrender. #522
* CMake option USE_fPIC=1 turns on -fPIC flag for C++ compilation. #521
* CMake option to disallow creation of OIIO::TextureSystem. #523
* Alternate place to find stdosl.h. (mostly for Pixar) #524
* Site customization file for Pixar. #524
Release 1.6 (1.6.6) -- 26 May 2015 (compared to 1.5)
-----------------------------------------------
Language, standard libary, and compiler changes (for shader writers):
* It is now supported to have shader parameters that are arrays of
@@ -215,6 +254,11 @@ Build & test system improvements and developer goodies:
#487 #488 (1.6.4)
* Fixes to work with LLVM 3.5 and 3.6, though 3.6 especially has not yet
been very thoroughly tested for OSL. #487 (1.6.4)
* C++11 support: the preprocessor symbol OSL_BUILD_CPP11 is set to 1 if
OSL was built with C++11 (or higher) support, and the separate
OSL_USING_CPP11 is set to 1 if C++11 is detected right now. (These can
be different from the point of view of an app using OSL headers.)
#508 (1.6.6RC1)
Documentation:
* Short chapter added to spec describing the syntax of our serialization
+29 -10
View File
@@ -3,8 +3,8 @@ project (OSL)
# Release version of the library
set (OSL_LIBRARY_VERSION_MAJOR 1)
set (OSL_LIBRARY_VERSION_MINOR 6)
set (OSL_LIBRARY_VERSION_PATCH 5)
set (OSL_LIBRARY_VERSION_RELEASE_TYPE "beta") # "dev", "betaX", "RCY", ""
set (OSL_LIBRARY_VERSION_PATCH 9)
set (OSL_LIBRARY_VERSION_RELEASE_TYPE "") # "dev", "betaX", "RCY", ""
# Version of the OSO file format and instruction set
set (OSO_FILE_VERSION_MAJOR 1)
@@ -109,6 +109,11 @@ if (BUILDSTATIC)
add_definitions ("-DOSL_STATIC_LIBRARY")
endif()
set (USE_fPIC OFF CACHE BOOL "Build with -fPIC")
if (USE_fPIC)
add_definitions ("-fPIC")
endif ()
if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNUCC)
# CMake doesn't automatically know what do do with
# include_directories(SYSTEM...) when using clang or gcc.
@@ -150,6 +155,7 @@ if (EXISTS "/usr/lib/libc++.dylib")
endif ()
set (VERBOSE OFF CACHE BOOL "Print lots of messages while compiling")
set (OSL_BUILD_TESTS ON CACHE BOOL "Build the unit tests, testshade, testrender")
set (BUILDSTATIC OFF CACHE BOOL "Build static library instead of shared")
set (HIDE_SYMBOLS OFF CACHE BOOL "Hide symbols not in the public API")
set (USE_EXTERNAL_PUGIXML OFF CACHE BOOL
@@ -162,10 +168,11 @@ else ()
endif ()
set (USE_PARTIO ON CACHE BOOL "Use Partio if found")
set (USE_FAST_MATH ON CACHE BOOL "Use fast math approximations (if no, then use system math library)")
set (USE_CPP11 OFF CACHE BOOL "Compile in C++11 mode")
set (USE_LIBCPLUSPLUS OFF CACHE BOOL "Compile with clang libc++")
set (OSL_BUILD_CPP11 OFF CACHE BOOL "Compile in C++11 mode")
set (OSL_BUILD_LIBCPLUSPLUS OFF CACHE BOOL "Compile with clang libc++")
set (EXTRA_CPP_ARGS "" CACHE STRING "Extra C++ command line definitions")
set (USE_SIMD "" CACHE STRING "Use SIMD directives (0, sse2, sse3, sse4.1, sse4.2)")
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
if (LLVM_NAMESPACE)
add_definitions ("-DLLVM_NAMESPACE=${LLVM_NAMESPACE}")
@@ -181,12 +188,16 @@ else ()
add_definitions ("-DOSL_FAST_MATH=0")
endif ()
if (OSL_NO_DEFAULT_TEXTURESYSTEM)
add_definitions ("-DOSL_NO_DEFAULT_TEXTURESYSTEM=1")
endif ()
if (EXTRA_CPP_ARGS)
message (STATUS "Extra C++ args: ${EXTRA_CPP_ARGS}")
add_definitions ("${EXTRA_CPP_ARGS}")
endif()
if (USE_CPP11)
if (OSL_BUILD_CPP11)
message (STATUS "Building for C++11")
add_definitions ("-std=c++11")
if (CMAKE_COMPILER_IS_CLANG)
@@ -274,8 +285,11 @@ add_subdirectory (src/liboslexec)
add_subdirectory (src/oslc)
add_subdirectory (src/shaders)
add_subdirectory (src/oslinfo)
if (OSL_BUILD_TESTS)
add_subdirectory (src/testshade)
add_subdirectory (src/testrender)
endif ()
add_subdirectory (src/include)
add_subdirectory (src/doc)
@@ -331,13 +345,14 @@ macro ( TESTSUITE )
endforeach ()
endmacro ()
if (OSL_BUILD_TESTS)
# List all the individual testsuite tests here, except those that need
# special installed tests.
TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
blackbody blendmath breakcont
bug-array-heapoffsets
bug-locallifetime bug-outputinit bug-param-duplicate bug-peep
cellnoise closure color comparison
cellnoise closure closure-array color comparison
compile-buffer
component-range const-array-params const-array-fill
debugnan debug-uninit
@@ -346,7 +361,8 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
geomath getattribute-camera getsymbol-nonheap gettextureinfo
group-outputs groupstring
hyperb ieee_fp if incdec initops intbits isconnected
layers layers-Ciassign layers-lazy layers-repeatedoutputs
layers layers-Ciassign layers-lazy
layers-nonlazycopy layers-repeatedoutputs
logic loop matrix message mergeinstances-nouserdata
metadata-braces miscmath missing-shader
noise noise-cell
@@ -368,8 +384,9 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
render-microfacet render-oren-nayar render-veachmis render-ward
shortcircuit spline splineinverse string
struct struct-array struct-array-mixture
struct-err struct-in-struct-init struct-layers struct-with-array
struct-within-struct ternary
struct-err struct-in-struct-init struct-init-copy struct-layers
struct-with-array struct-within-struct
ternary
texture-alpha texture-blur texture-derivs texture-field3d
texture-firstchannel texture-interp
texture-missingcolor texture-simple
@@ -377,9 +394,11 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
texture-width texture-withderivs texture-wrap
trailing-commas transform transformc trig typecast
unknown-instruction
vararray-connect vararray-default vararray-param
vararray-connect vararray-default
vararray-deserialize vararray-param
vecctr vector
wavelength_color xml )
endif ()
+10 -2
View File
@@ -37,6 +37,9 @@ $(info OSL_SITE = ${OSL_SITE})
ifneq (${shell echo ${OSL_SITE} | grep imageworks},)
include ${working_dir}/site/spi/Makefile-bits
endif
ifneq (${shell echo ${OSL_SITE} | grep pixar},)
include ${working_dir}/site/pixar/Makefile-bits
endif
# Set up variables holding the names of platform-dependent directories --
# set these after evaluating site-specific instructions
@@ -116,6 +119,10 @@ ifneq (${LINKSTATIC},)
MY_CMAKE_FLAGS += -DLINKSTATIC:BOOL=${LINKSTATIC}
endif
ifneq (${OSL_BUILD_TESTS},)
MY_CMAKE_FLAGS += -DOSL_BUILD_TESTS:BOOL=${OSL_BUILD_TESTS}
endif
ifneq (${USE_EXTERNAL_PUGIXML},)
MY_CMAKE_FLAGS += -DUSE_EXTERNAL_PUGIXML:BOOL=${USE_EXTERNAL_PUGIXML} -DPUGIXML_HOME=${PUGIXML_HOME}
endif
@@ -136,11 +143,11 @@ MY_CMAKE_FLAGS += -DCMAKE_CXX_COMPILER:STRING="${MYCXX}"
endif
ifneq (${USE_CPP11},)
MY_CMAKE_FLAGS += -DUSE_CPP11:BOOL=${USE_CPP11}
MY_CMAKE_FLAGS += -DOSL_BUILD_CPP11:BOOL=${USE_CPP11}
endif
ifneq (${USE_LIBCPLUSPLUS},)
MY_CMAKE_FLAGS += -DUSE_LIBCPLUSPLUS:BOOL=${USE_LIBCPLUSPLUS}
MY_CMAKE_FLAGS += -DOSL_BUILD_LIBCPLUSPLUS:BOOL=${USE_LIBCPLUSPLUS}
endif
ifneq (${EXTRA_CPP_ARGS},)
@@ -286,6 +293,7 @@ help:
@echo " OSL build-time options:"
@echo " NAMESPACE=name Wrap OSL APIs in another namespace"
@echo " USE_FAST_MATH=1 Use faster, but less accurate math (set to 0 for libm defaults)"
@echo " OSL_BUILD_TESTS=0 Skip building the unit tests, testshade, testrender"
@echo " USE_SIMD=arch Build with SIMD support (choices: 0, sse2, sse3,"
@echo " sse4.1, sse4.2)"
@echo ""
+28
View File
@@ -0,0 +1,28 @@
# Pixar-specific settings
ifneq (${VERBOSE},)
$(info Including pixar/Makefile-bits)
endif
MY_CMAKE_FLAGS += -DUSE_fPIC:BOOL=1
MY_CMAKE_FLAGS += -DENABLERTTI:BOOL=1
MY_CMAKE_FLAGS += -DSTOP_ON_WARNING:BOOL=0
MY_CMAKE_FLAGS += -DHIDE_SYMBOLS:BOOL=1
MY_CMAKE_FLAGS += -DBUILDSTATIC:BOOL=1
MY_CMAKE_FLAGS += -DLINKSTATIC:BOOL=1
MY_CMAKE_FLAGS += -DUSE_FAST_MATH:BOOL=1
MY_CMAKE_FLAGS += -DILMBASE_LIB_AREA:STRING=${ILMBASE_HOME}/lib/linux-ix86-64/gcc4.1
MY_CMAKE_FLAGS += -DILMBASE_CUSTOM:BOOL=True
MY_CMAKE_FLAGS += -DILMBASE_CUSTOM_LIBRARIES:STRING="Half-fPIC Iex-fPIC IexMath-fPIC IlmThread-fPIC Imath-fPIC"
# Don't build testshade or testrender (mostly because they require the
# image-handling parts of OIIO, which Pixar doesn't build)
MY_CMAKE_FLAGS += -DOSL_BUILD_TESTS:BOOL=0
# Don't let OSL create a default OIIO::TextureSystem. If the renderer
# doesn't pass in whatever proxy it wants, it will assert.
MY_CMAKE_FLAGS += -DOSL_NO_DEFAULT_TEXTURESYSTEM:BOOL=1
ifneq (${VERBOSE},)
$(info MY_CMAKE_FLAGS: $(MY_CMAKE_FLAGS))
endif
+4 -1
View File
@@ -172,6 +172,10 @@ if(NOT LLVM_DIRECTORY OR EXISTS ${LLVM_CONFIG})
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if (LLVM_VERSION VERSION_GREATER 3.4.9 AND NOT OSL_BUILD_CPP11)
message (FATAL_ERROR "LLVM ${LLVM_VERSION} requires C++11. You must build with USE_CPP11=1.")
endif ()
find_library ( LLVM_LIBRARY
NAMES LLVM-${LLVM_VERSION}
PATHS ${LLVM_LIB_DIR})
@@ -213,7 +217,6 @@ if ((LLVM_LIBRARY OR LLVM_STATIC) AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_
message (STATUS "LLVM library = ${LLVM_LIBRARY}")
endif ()
if (NOT LLVM_LIBRARY)
message (FATAL_ERROR "LLVM library not found.")
endif()
Binary file not shown.
+11 -11
View File
@@ -46,28 +46,28 @@ struct ClosureParam {
#define fieldsize(st, fld) sizeof(((st *)0)->fld)
#define CLOSURE_INT_PARAM(st, fld) \
{ TypeDesc::TypeInt, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::TypeInt, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_FLOAT_PARAM(st, fld) \
{ TypeDesc::TypeFloat, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::TypeFloat, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_COLOR_PARAM(st, fld) \
{ TypeDesc::TypeColor, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::TypeColor, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_VECTOR_PARAM(st, fld) \
{ TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_STRING_PARAM(st, fld) \
{ TypeDesc::TypeString, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::TypeString, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_CLOSURE_PARAM(st, fld) \
{ TypeDesc::PTR, reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc::PTR, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_INT_ARRAY_PARAM(st, fld, n) \
{ TypeDesc(TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc(TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_VECTOR_ARRAY_PARAM(st,fld,n) \
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR, n),reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_COLOR_ARRAY_PARAM(st,fld,n) \
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR, n),reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_FLOAT_ARRAY_PARAM(st,fld,n) \
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc(TypeDesc::FLOAT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
#define CLOSURE_STRING_ARRAY_PARAM(st,fld,n) \
{ TypeDesc(TypeDesc::STRING, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
{ TypeDesc(TypeDesc::STRING, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) }
// NOTE: this keyword args have to be always at the end of the list
#define CLOSURE_INT_KEYPARAM(key) \
+13 -4
View File
@@ -35,9 +35,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// renderer that wanted things a different way.
/////////////////////////////////////////////////////////////////////////
// Test if we are using C++11
// Detect if we're C++11.
//
// Note: oslversion.h defined OSL_BUILD_CPP11 to be 1 if OSL was built
// using C++11. In contrast, OSL_USING_CPP11 defined below will be 1 if
// we're compiling C++11 RIGHT NOW. These two things may be the same when
// compiling OSL, but they may not be the same if another packages is
// compiling against OSL and using these headers (OSL may be C++11 but the
// client package may be older, or vice versa -- use these two symbols to
// differentiate these cases, when important).
#if (__cplusplus >= 201103L)
#define OSL_USING_CPLUSPLUS11 1
#define OSL_USING_CPP11 1
#define OSL_USING_CPLUSPLUS11 1 /* DEPRECATED */
#endif
// Symbol export defines
@@ -56,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <OpenImageIO/ustring.h>
// Sort out smart pointers
#ifdef OSL_USING_CPLUSPLUS11
#ifdef OSL_USING_CPP11
# include <memory>
#else
# include <boost/shared_ptr.hpp>
@@ -109,7 +118,7 @@ using OIIO::ustringHash;
using OIIO::string_view;
// Sort out smart pointers
#ifdef OSL_USING_CPLUSPLUS11
#ifdef OSL_USING_CPP11
using std::shared_ptr;
using std::weak_ptr;
#else
+16
View File
@@ -263,6 +263,22 @@ public:
/// ptr userdata_offsets Retrieves a pointer to the array of
/// int describing the userdata offsets
/// within the heap.
/// int num_attributes_needed The number of attribute/scope pairs that
/// are known to be queried by the group (the
/// length of the attributes_needed and
/// attribute_scopes arrays).
/// ptr attributes_needed Retrieves a pointer to the ustring array
/// containing the names of the needed attributes.
/// Note that if the same attribute
/// is requested in multiple scopes, it will
/// appear in the array multiple times - once for
/// each scope in which is is queried.
/// ptr attribute_scopes Retrieves a pointer to a ustring array containing
/// the scopes associated with each attribute query
/// in the attributes_needed array.
/// int unknown_attributes_needed Nonzero if additonal attributes may be
/// needed, whose names will not be known
/// until the shader actually runs.
/// string pickle Retrieves a serialized representation
/// of the shader group declaration.
/// Note: the attributes referred to as "string" are actually on the app
+4
View File
@@ -87,5 +87,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define OSL_NAMESPACE_EXIT };
#endif
/// OSL_BUILD_CPP11 will be 1 if this OSL was built using C++11
#cmakedefine01 OSL_BUILD_CPP11
/// OSL_BUILD_USELIBPLUSPLUS will be 1 if this OSL was built using libc++
#cmakedefine01 OSL_BUILD_LIBCPLUSPLUS
#endif /* OSLVERSION_H */
+3 -4
View File
@@ -30,12 +30,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <sstream>
#include <boost/filesystem.hpp>
#include "osl_pvt.h"
#include "oslcomp_pvt.h"
#include <OpenImageIO/dassert.h>
#include <OpenImageIO/filesystem.h>
#include <OpenImageIO/strutil.h>
namespace Strutil = OIIO::Strutil;
@@ -317,9 +316,9 @@ ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp,
if (f && ! m_ismetadata) {
std::string e = Strutil::format ("\"%s\" already declared in this scope", name.c_str());
if (f->node()) {
boost::filesystem::path p(f->node()->sourcefile().string());
std::string filename = OIIO::Filesystem::filename(f->node()->sourcefile().string());
e += Strutil::format ("\n\t\tprevious declaration was at %s:%d",
p.filename().c_str(), f->node()->sourceline());
filename, f->node()->sourceline());
}
if (f->scope() == 0 && f->symtype() == SymTypeFunction && isparam) {
// special case: only a warning for param to mask global function
+5 -2
View File
@@ -311,11 +311,14 @@ protected:
/// true, we are (perhaps recursively) copying entire arrays, of
/// or within the struct, and intindex is the element number if we
/// know it -- these two items let us take some interesting shortcuts
/// with whole arrays (copyarray versus assigning elements).
/// with whole arrays (copyarray versus assigning elements). Pass
/// paraminit=true if we're doing the assignment as init ops of a
/// shader param.
void codegen_assign_struct (StructSpec *structspec,
ustring dstsym, ustring srcsym,
Symbol *arrayindex,
bool copywholearrays, int intindex);
bool copywholearrays, int intindex,
bool paraminit);
protected:
NodeType m_nodetype; ///< Type of node this is
+24 -11
View File
@@ -488,7 +488,7 @@ ASTassign_expression::codegen (Symbol *dest)
StructSpec *structspec = typespec().structspec ();
codegen_assign_struct (structspec, ustring(dest->mangled()),
ustring(operand->mangled()), NULL,
true, 0);
true, 0, false /*not a shader param init*/);
}
return dest;
}
@@ -505,13 +505,15 @@ ASTassign_expression::codegen (Symbol *dest)
Symbol *v = index->lvalue()->codegen();
codegen_assign_struct (structspec, ustring(v->mangled()),
ustring(operand->mangled()), arrayindex,
false, -1 /* means we don't know */);
false, -1 /* means we don't know */,
false /*not a shader param init*/);
} else {
// Assignment of one scalar struct to another scalar struct
ASSERT (dest);
codegen_assign_struct (structspec, ustring(dest->mangled()),
ustring(operand->mangled()), NULL,
true, 0);
true, 0,
false /*not a shader param init*/);
}
}
return dest;
@@ -537,7 +539,8 @@ void
ASTNode::codegen_assign_struct (StructSpec *structspec,
ustring dstsym, ustring srcsym,
Symbol *arrayindex,
bool copywholearrays, int intindex)
bool copywholearrays, int intindex,
bool paraminit)
{
for (int i = 0; i < (int)structspec->numfields(); ++i) {
const TypeSpec &fieldtype (structspec->field(i).type);
@@ -547,7 +550,7 @@ ASTNode::codegen_assign_struct (StructSpec *structspec,
codegen_assign_struct (fieldtype.structspec(),
ustring::format ("%s.%s", dstsym, fieldname),
ustring::format ("%s.%s", srcsym, fieldname),
arrayindex, copywholearrays, 0);
arrayindex, copywholearrays, 0, paraminit);
continue;
}
@@ -561,7 +564,7 @@ ASTNode::codegen_assign_struct (StructSpec *structspec,
codegen_assign_struct (fieldtype.structspec(),
dstfield, srcfield,
m_compiler->make_constant(i),
copywholearrays, i);
copywholearrays, i, paraminit);
}
continue;
}
@@ -569,6 +572,10 @@ ASTNode::codegen_assign_struct (StructSpec *structspec,
Symbol *dfield, *ofield;
m_compiler->struct_field_pair (structspec, i, dstsym, srcsym,
dfield, ofield);
if (paraminit) {
m_compiler->codegen_method (ustring(dfield->mangled()));
dfield->initbegin (m_compiler->next_op_label ());
}
if (arrayindex) {
// field is a scalar, but we're assigning to one element of
// an array of structs.
@@ -598,6 +605,8 @@ ASTNode::codegen_assign_struct (StructSpec *structspec,
// field is a scalar, struct is a scalar
emitcode ("assign", dfield, ofield);
}
if (paraminit)
dfield->initend (m_compiler->next_op_label ());
}
}
@@ -886,6 +895,13 @@ ASTvariable_declaration::codegen_initlist (ref init, TypeSpec type,
Symbol *
ASTvariable_declaration::codegen_struct_initializers (ref init)
{
// If we're doing this initialization for shader params for their
// init ops, we need to take care to set the codegen method names
// properly.
bool paraminit = (m_compiler->codegen_method() != m_compiler->main_method_name() &&
(m_sym->symtype() == SymTypeParam ||
m_sym->symtype() == SymTypeOutputParam));
if (! init->next() && init->typespec() == m_typespec &&
init->nodetype() != compound_initializer_node) {
// Special case: just one initializer, it's a whole struct of
@@ -894,16 +910,13 @@ ASTvariable_declaration::codegen_struct_initializers (ref init)
if (initsym != m_sym) {
StructSpec *structspec (m_typespec.structspec());
codegen_assign_struct (structspec, ustring(m_sym->mangled()),
ustring(initsym->mangled()), NULL, true, 0);
ustring(initsym->mangled()), NULL, true, 0,
paraminit);
}
return m_sym;
}
// General case -- per-field initializers
bool paraminit = (m_compiler->codegen_method() != m_compiler->main_method_name() &&
(m_sym->symtype() == SymTypeParam ||
m_sym->symtype() == SymTypeOutputParam));
for (int i = 0; init; init = init->next(), ++i) {
// Structure element -- assign to the i-th member field
StructSpec *structspec (m_typespec.structspec());
+1 -1
View File
@@ -625,7 +625,7 @@ OSLCompilerImpl::write_oso_const_value (const ConstantSymbol *sym) const
int nelements = std::max (1, type.arraylen);
if (elemtype == TypeDesc::STRING)
for (int i = 0; i < nelements; ++i)
oso ("\"%s\"%s", sym->strval(i).c_str(), nelements>1 ? " " : "");
oso ("\"%s\"%s", sym->strval(i), nelements>1 ? " " : "");
else if (elemtype == TypeDesc::INT)
for (int i = 0; i < nelements; ++i)
oso ("%d%s", sym->intval(i), nelements>1 ? " " : "");
+12 -10
View File
@@ -221,26 +221,28 @@ BackendLLVM::llvm_zero_derivs (const Symbol &sym, llvm::Value *count)
}
}
int
BackendLLVM::ShaderGlobalNameToIndex (ustring name)
namespace
{
// N.B. The order of names in this table MUST exactly match the
// ShaderGlobals struct in oslexec.h, as well as the llvm 'sg' type
// defined in llvm_type_sg().
static ustring fields[] = {
Strings::P, ustring("_dPdz"), Strings::I, Strings::N, Strings::Ng,
Strings::u, Strings::v, Strings::dPdu, Strings::dPdv,
Strings::time, Strings::dtime, Strings::dPdtime, Strings::Ps,
ustring("P"), ustring("_dPdz"), ustring("I"),
ustring("N"), ustring("Ng"),
ustring("u"), ustring("v"), ustring("dPdu"), ustring("dPdv"),
ustring("time"), ustring("dtime"), ustring("dPdtime"), ustring("Ps"),
ustring("renderstate"), ustring("tracedata"), ustring("objdata"),
ustring("shadingcontext"), ustring("renderer"),
ustring("object2common"), ustring("shader2common"),
Strings::Ci,
ustring("Ci"),
ustring("surfacearea"), ustring("raytype"),
ustring("flipHandedness"), ustring("backfacing")
};
}
int
BackendLLVM::ShaderGlobalNameToIndex (ustring name)
{
for (int i = 0; i < int(sizeof(fields)/sizeof(fields[0])); ++i)
if (name == fields[i])
return i;
@@ -778,8 +780,8 @@ BackendLLVM::llvm_assign_impl (Symbol &Result, Symbol &Src,
llvm::Value *arrind = arrayindex >= 0 ? ll.constant (arrayindex) : NULL;
if (Result.typespec().is_closure_based() || Src.typespec().is_closure_based()) {
if (Src.typespec().is_closure_based()) {
if (Result.typespec().is_closure() || Src.typespec().is_closure()) {
if (Src.typespec().is_closure()) {
llvm::Value *srcval = llvm_load_value (Src, 0, arrind, 0);
llvm_store_value (srcval, Result, 0, arrind, 0);
} else {
+44 -19
View File
@@ -1143,7 +1143,9 @@ DECLFOLDER(constfold_split)
std::vector<int> args;
args.push_back (resultsarg);
args.push_back (cind);
rop.insert_code (opnum, u_assign, args, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
return 1;
}
@@ -1263,7 +1265,8 @@ DECLFOLDER(constfold_format)
newargs[1] = rop.add_constant (ustring(prefix + suffix));
ustring opname = op.opname();
rop.turn_into_nop (op, "partial constant fold format()");
rop.insert_code (opnum, opname, newargs);
rop.insert_code (opnum, opname, newargs,
RuntimeOptimizer::RecomputeRWRanges);
return 1;
}
@@ -1457,13 +1460,15 @@ DECLFOLDER(constfold_mix)
// just R=A and not have to access B
int cond = rop.add_temp (TypeDesc::TypeInt);
int fzero = rop.add_constant (0.0f);
rop.insert_code (opnum++, u_eq, 1 /*relation*/, cond, Xind, fzero);
rop.insert_code (opnum++, u_eq, RuntimeOptimizer::GroupWithNext,
cond, Xind, fzero);
if0op = opnum;
rop.insert_code (opnum++, u_if, 1 /*relation*/, cond);
rop.insert_code (opnum++, u_if, RuntimeOptimizer::GroupWithNext, cond);
rop.op(if0op).argreadonly (0);
rop.symbol(cond)->mark_rw (if0op, true, false);
// Add the true (R=A) clause
rop.insert_code (opnum++, u_assign, 1 /*relation*/, Rind, Aind);
rop.insert_code (opnum++, u_assign,
RuntimeOptimizer::GroupWithNext, Rind, Aind);
}
int if0op_false = opnum; // Where we jump if the 'if x==0' is false
if (A.connected()) {
@@ -1471,13 +1476,15 @@ DECLFOLDER(constfold_mix)
// just R=B and not have to access A
int cond = rop.add_temp (TypeDesc::TypeInt);
int fone = rop.add_constant (1.0f);
rop.insert_code (opnum++, u_eq, 1 /*relation*/, cond, Xind, fone);
rop.insert_code (opnum++, u_eq, RuntimeOptimizer::GroupWithNext,
cond, Xind, fone);
if1op = opnum;
rop.insert_code (opnum++, u_if, 1 /*relation*/, cond);
rop.insert_code (opnum++, u_if, RuntimeOptimizer::GroupWithNext, cond);
rop.op(if1op).argreadonly (0);
rop.symbol(cond)->mark_rw (if1op, true, false);
// Add the true (R=B) clause
rop.insert_code (opnum++, u_assign, 1 /*relation*/, Rind, Bind);
rop.insert_code (opnum++, u_assign, RuntimeOptimizer::GroupWithNext,
Rind, Bind);
}
int if1op_false = opnum; // Where we jump if the 'if x==1' is false
// Add the (R=A*(1-X)+B*X) clause -- always need that
@@ -1485,10 +1492,14 @@ DECLFOLDER(constfold_mix)
int temp1 = rop.add_temp (A.typespec());
int temp2 = rop.add_temp (B.typespec());
int fone = rop.add_constant (1.0f);
rop.insert_code (opnum++, u_sub, 1 /*relation*/, one_minus_x, fone, Xind);
rop.insert_code (opnum++, u_mul, 1 /*relation*/, temp1, Aind, one_minus_x);
rop.insert_code (opnum++, u_mul, 1 /*relation*/, temp2, Bind, Xind);
rop.insert_code (opnum++, u_add, 1 /*relation*/, Rind, temp1, temp2);
rop.insert_code (opnum++, u_sub, RuntimeOptimizer::GroupWithNext,
one_minus_x, fone, Xind);
rop.insert_code (opnum++, u_mul, RuntimeOptimizer::GroupWithNext,
temp1, Aind, one_minus_x);
rop.insert_code (opnum++, u_mul, RuntimeOptimizer::GroupWithNext,
temp2, Bind, Xind);
rop.insert_code (opnum++, u_add, RuntimeOptimizer::GroupWithNext,
Rind, temp1, temp2);
// Now go back and patch the 'if' ops with the right jump addresses
if (if0op >= 0)
rop.op(if0op).set_jump (if0op_false, opnum);
@@ -1722,7 +1733,9 @@ DECLFOLDER(constfold_sincos)
std::vector<int> args_to_add;
args_to_add.push_back (cosarg);
args_to_add.push_back (rop.add_constant (c));
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
Opcode &newop (rop.inst()->ops()[opnum]);
newop.argwriteonly (0);
newop.argreadonly (1);
@@ -1909,7 +1922,9 @@ DECLFOLDER(constfold_getmatrix)
std::vector<int> args_to_add;
args_to_add.push_back (resultarg);
args_to_add.push_back (rop.add_constant (TypeDesc::TypeInt, &one));
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
Opcode &newop (rop.inst()->ops()[opnum]);
newop.argwriteonly (0);
newop.argread (1, true);
@@ -2076,7 +2091,9 @@ DECLFOLDER(constfold_getattribute)
std::vector<int> args_to_add;
args_to_add.push_back (oldresultarg);
args_to_add.push_back (rop.add_constant (TypeDesc::TypeInt, &one));
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
Opcode &newop (rop.inst()->ops()[opnum]);
newop.argwriteonly (0);
newop.argread (1, true);
@@ -2131,7 +2148,9 @@ DECLFOLDER(constfold_gettextureinfo)
std::vector<int> args_to_add;
args_to_add.push_back (oldresultarg);
args_to_add.push_back (rop.add_constant (TypeDesc::TypeInt, &one));
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
Opcode &newop (rop.inst()->ops()[opnum]);
newop.argwriteonly (0);
newop.argread (1, true);
@@ -2404,7 +2423,9 @@ DECLFOLDER(constfold_pointcloud_search)
std::vector<int> args_to_add;
args_to_add.push_back (value_args[i]);
args_to_add.push_back (const_array_sym);
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
}
// Query results all copied. The only thing left to do is to assign
@@ -2412,7 +2433,9 @@ DECLFOLDER(constfold_pointcloud_search)
std::vector<int> args_to_add;
args_to_add.push_back (result_sym);
args_to_add.push_back (rop.add_constant (TypeDesc::TypeInt, &count));
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
return 1;
}
@@ -2468,7 +2491,9 @@ DECLFOLDER(constfold_pointcloud_get)
std::vector<int> args_to_add;
args_to_add.push_back (rop.oparg(op,5) /* Data symbol*/);
args_to_add.push_back (const_array_sym);
rop.insert_code (opnum, u_assign, args_to_add, true, 1 /* relation */);
rop.insert_code (opnum, u_assign, args_to_add,
RuntimeOptimizer::RecomputeRWRanges,
RuntimeOptimizer::GroupWithNext);
return 1;
}
+32 -5
View File
@@ -312,10 +312,10 @@ ShaderInstance::parameters (const ParamValueList &params)
{
// Adjust the stats
ShadingSystemImpl &ss (shadingsys());
spin_lock lock (ss.m_stat_mutex);
size_t symmem = vectorbytes(m_instoverrides);
size_t parammem = (vectorbytes(m_iparams) + vectorbytes(m_fparams) +
vectorbytes(m_sparams));
spin_lock lock (ss.m_stat_mutex);
ss.m_stat_mem_inst_syms += symmem;
ss.m_stat_mem_inst_paramvals += parammem;
ss.m_stat_mem_inst += (symmem+parammem);
@@ -482,7 +482,7 @@ ShaderInstance::copy_code_from_master (ShaderGroup &group)
std::string
ShaderInstance::print ()
ShaderInstance::print (const ShaderGroup &group)
{
std::stringstream out;
out << "Shader " << shadername() << "\n";
@@ -540,6 +540,24 @@ ShaderInstance::print ()
out << " (" << filename << ":" << op.sourceline() << ")";
out << "\n";
}
if (nconnections()) {
out << " connections upstream:\n";
for (int i = 0, e = nconnections(); i < e; ++i) {
const Connection &c (connection(i));
out << " " << c.dst.type.c_str() << ' '
<< symbol(c.dst.param)->name();
if (c.dst.arrayindex >= 0)
out << '[' << c.dst.arrayindex << ']';
out << " upconnected from layer " << c.srclayer << ' ';
const ShaderInstance *up = group[c.srclayer];
out << "(" << up->layername() << ") ";
out << " " << c.src.type.c_str() << ' '
<< up->symbol(c.src.param)->name();
if (c.src.arrayindex >= 0)
out << '[' << c.src.arrayindex << ']';
out << "\n";
}
}
return out.str ();
}
@@ -562,7 +580,8 @@ ShaderInstance::compute_run_lazily ()
// Suggested warning below... but are there use cases where people
// want these to run (because they will extract the results they
// want from output params)?
if (! outgoing_connections() && ! writes_globals())
if (! outgoing_connections() && ! empty_instance() &&
! writes_globals() && ! renderer_outputs())
shadingsys().warning ("Layer \"%s\" (shader %s) will run even though it appears to have no used results",
layername(), shadername());
#endif
@@ -704,7 +723,7 @@ ShaderInstance::mergeable (const ShaderInstance &b, const ShaderGroup &g) const
// Make sure system didn't ask for instances that query userdata to be
// immune from instance merging.
if (! shadingsys().m_opt_merge_instances_with_userdata
&& userdata_params()) {
&& (userdata_params() || b.userdata_params())) {
return false;
}
@@ -828,8 +847,16 @@ ShaderGroup::serialize () const
: inst->instoverride(p)->valuesource();
if (vs == Symbol::InstanceVal) {
TypeDesc type = s->typespec().simpletype();
out << "param " << type << ' ' << s->name();
int offset = s->dataoffset();
if (type.is_unsized_array() && ! dstsyms_exist) {
// If we're being asked to serialize a group that isn't
// yet optimized, any "unsized" arrays will have their
// concrete length and offset in the SymOverrideInfo,
// not in the Symbol belonging to the instance.
type.arraylen = inst->instoverride(p)->arraylen();
offset = inst->instoverride(p)->dataoffset();
}
out << "param " << type << ' ' << s->name();
int nvals = type.numelements() * type.aggregate;
if (type.basetype == TypeDesc::INT) {
const int *vals = &inst->m_iparams[offset];
+21 -7
View File
@@ -711,8 +711,8 @@ BackendLLVM::build_llvm_instance (bool groupentry)
if (llvm_debug() && groupentry)
llvm_gen_debug_printf (Strutil::format("\n\n\n\nGROUP! %s",group().name()));
if (llvm_debug())
llvm_gen_debug_printf (Strutil::format("enter layer %s %s",
inst()->layername(), inst()->shadername()));
llvm_gen_debug_printf (Strutil::format("enter layer %d %s %s",
this->layer(), inst()->layername(), inst()->shadername()));
#endif
if (shadingsys().countlayerexecs())
ll.call_function ("osl_incr_layers_executed", sg_void_ptr());
@@ -746,9 +746,6 @@ BackendLLVM::build_llvm_instance (bool groupentry)
}
}
}
// Unconditionally execute earlier layers that are not lazy
if (! gi->run_lazily() && i < group().nlayers()-1)
llvm_call_layer (i, true /* unconditionally run */);
}
}
@@ -816,6 +813,17 @@ BackendLLVM::build_llvm_instance (bool groupentry)
// All the symbols are stack allocated now.
if (groupentry) {
// Group entries also need to run any earlier layers that must be
// run unconditionally. It's important that we do this AFTER all the
// parameter initialization for this layer.
for (int i = 0; i < group().nlayers()-1; ++i) {
ShaderInstance *gi = group()[i];
if (!gi->unused() && !gi->empty_instance() && !gi->run_lazily())
llvm_call_layer (i, true /* unconditionally run */);
}
}
// Mark all the basic blocks, including allocating llvm::BasicBlock
// records for each.
find_basic_blocks ();
@@ -850,8 +858,8 @@ BackendLLVM::build_llvm_instance (bool groupentry)
// All done
#if 0 /* helpful for debugging */
if (llvm_debug())
llvm_gen_debug_printf (Strutil::format("exit layer %s %s",
inst()->layername(), inst()->shadername()));
llvm_gen_debug_printf (Strutil::format("exit layer %d %s %s",
this->layer(), inst()->layername(), inst()->shadername()));
#endif
ll.op_return();
@@ -964,11 +972,17 @@ BackendLLVM::run ()
int nlayers = group().nlayers();
m_layer_remap.resize (nlayers);
m_num_used_layers = 0;
if (shadingsys().debug() >= 1)
std::cout << "\nLayers used:\n";
for (int layer = 0; layer < nlayers; ++layer) {
bool lastlayer = (layer == (nlayers-1));
if (lastlayer ||
(! group()[layer]->unused() && !group()[layer]->empty_instance()))
{
if (shadingsys().debug() >= 1)
std::cout << " " << layer << "\n";
m_layer_remap[layer] = m_num_used_layers++;
}
else
m_layer_remap[layer] = -1;
}
+7 -2
View File
@@ -28,10 +28,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <OpenImageIO/thread.h>
#include <boost/thread/tss.hpp> /* for thread_specific_ptr */
#include "OSL/oslconfig.h"
#include "OSL/llvm_util.h"
#if OSL_LLVM_VERSION >= 35 && ! OSL_BUILD_CPP11
#error "LLVM >= 3.5 requires USE_CPP11=1"
#endif
#ifndef USE_MCJIT
// MCJIT first appeared with LLVM 3.3
# define USE_MCJIT (OSL_LLVM_VERSION>=33)
@@ -120,7 +125,7 @@ namespace pvt {
namespace {
static OIIO::spin_mutex llvm_global_mutex;
static bool setup_done = false;
static OIIO::thread_specific_ptr<LLVM_Util::PerThreadInfo> perthread_infos;
static boost::thread_specific_ptr<LLVM_Util::PerThreadInfo> perthread_infos;
static std::vector<shared_ptr<llvm::JITMemoryManager> > jitmm_hold;
};
@@ -457,7 +462,7 @@ LLVM_Util::module_from_bitcode (const char *bitcode, size_t size,
// called functions due to disagreement about whether a leading "_"
// is part of the symbol name.
#if OSL_LLVM_VERSION >= 35
llvm::ErrorOr<llvm::Module *> ModuleOrErr = llvm::ParseBitcodeFile (buf, context());
llvm::ErrorOr<llvm::Module *> ModuleOrErr = llvm::parseBitcodeFile (buf, context());
if (std::error_code EC = ModuleOrErr.getError())
if (err)
*err = EC.message();
+1 -1
View File
@@ -168,7 +168,7 @@ OSOReaderToMaster::symbol (SymType symtype, TypeSpec typespec, const char *name_
} else if (typespec.simpletype().basetype == TypeDesc::STRING) {
sym.dataoffset ((int) m_master->m_sdefaults.size());
expand (m_master->m_sdefaults, nvals);
} else if (typespec.is_closure()) {
} else if (typespec.is_closure_based()) {
// Closures are pointers, so we allocate a string default taking
// adventage of their default being NULL as well.
sym.dataoffset ((int) m_master->m_sdefaults.size());
+23 -6
View File
@@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/regex_fwd.hpp>
#include <boost/unordered_map.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/thread/tss.hpp> /* for thread_specific_ptr */
#include <OpenImageIO/ustring.h>
#include <OpenImageIO/thread.h>
@@ -62,7 +63,6 @@ using OIIO::mutex;
using OIIO::lock_guard;
using OIIO::spin_mutex;
using OIIO::spin_lock;
using OIIO::thread_specific_ptr;
using OIIO::ustringHash;
namespace Strutil = OIIO::Strutil;
@@ -185,8 +185,22 @@ struct UserDataNeeded {
}
};
// Struct defining an attribute needed by a shader group
struct AttributeNeeded {
ustring name;
ustring scope;
AttributeNeeded (ustring name, ustring scope = ustring())
: name(name), scope(scope) {}
friend bool operator< (const AttributeNeeded &a, const AttributeNeeded &b) {
if (a.name != b.name)
return a.name < b.name;
if (a.scope != b.scope)
return a.scope < b.scope;
return false; // they are equal
}
};
// Prefix for OSL shade up declarations, so LLVM can find them
#define OSL_SHADEOP extern "C" OSL_LLVM_EXPORT
@@ -593,14 +607,14 @@ public:
return std::pair<Symbol*,Symbol*> ((Symbol*)NULL, (Symbol*)NULL);
else
return std::pair<Symbol*,Symbol*> (&i->m_instsymbols[0],
&i->m_instsymbols[i->m_instsymbols.size()]);
&i->m_instsymbols[0] + i->m_instsymbols.size());
}
friend std::pair<const Symbol *,const Symbol *> sym_range (const ShaderInstance *i) {
if (i->m_instsymbols.size() == 0)
return std::pair<const Symbol*,const Symbol*> ((const Symbol*)NULL, (const Symbol*)NULL);
else
return std::pair<const Symbol*,const Symbol*> (&i->m_instsymbols[0],
&i->m_instsymbols[i->m_instsymbols.size()]);
&i->m_instsymbols[0] + i->m_instsymbols.size());
}
int Psym () const { return m_Psym; }
@@ -614,7 +628,7 @@ public:
const OpcodeVec & ops () const { return m_instops; }
OpcodeVec & ops () { return m_instops; }
std::string print (); // Debugging
std::string print (const ShaderGroup &group); // Debugging
SymbolVec &symbols () { return m_instsymbols; }
const SymbolVec &symbols () const { return m_instsymbols; }
@@ -647,7 +661,7 @@ public:
/// instance overrides from the master copy.
struct SymOverrideInfo {
// Using bit fields to keep the data in 8 bytes in total.
char m_valuesource: 3;
unsigned char m_valuesource: 3;
bool m_connected_down: 1;
bool m_lockgeom: 1;
int m_arraylen: 27;
@@ -1085,7 +1099,7 @@ private:
ParamValueList m_pending_params; ///< Pending Parameter() values
ShaderGroupRef m_curgroup; ///< Current shading attribute state
mutable mutex m_mutex; ///< Thread safety
mutable thread_specific_ptr<PerThreadInfo> m_perthread_info;
mutable boost::thread_specific_ptr<PerThreadInfo> m_perthread_info;
// Stats
atomic_int m_stat_shaders_loaded; ///< Stat: shaders loaded
@@ -1355,9 +1369,12 @@ private:
std::vector<TypeDesc> m_userdata_types;
std::vector<int> m_userdata_offsets;
std::vector<char> m_userdata_derivs;
std::vector<ustring> m_attributes_needed;
std::vector<ustring> m_attribute_scopes;
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
bool m_unknown_textures_needed;
bool m_unknown_closures_needed;
bool m_unknown_attributes_needed;
atomic_ll m_executions; ///< Number of times the group executed
atomic_ll m_stat_total_shading_time_ticks; ///< Total shading time (ticks)
+8
View File
@@ -60,10 +60,18 @@ RendererServices::RendererServices (TextureSystem *texsys)
if (texsys) {// caller provided a texture system
texturesys_ = texsys;
} else { // Need to create a new texture system
#if OSL_NO_DEFAULT_TEXTURESYSTEM
// This build option instructs OSL to never create a TextureSystem
// itself. (Most likely reason: this build of OSL is for a renderer
// that replaces OIIO's TextureSystem with its own, and therefore
// wouldn't want to accidentally make an OIIO one here.
ASSERT (0 && "RendererServices was not passed a working TextureSystem*");
#else
texturesys_ = TextureSystem::create (true /* shared */);
// Make some good guesses about default options
texturesys_->attribute ("automip", 1);
texturesys_->attribute ("autotile", 64);
#endif
}
}
}
+63 -16
View File
@@ -58,7 +58,8 @@ static ustring u_nop ("nop"),
u_pointcloud_write ("pointcloud_write"),
u_isconnected ("isconnected"),
u_setmessage ("setmessage"),
u_getmessage ("getmessage");
u_getmessage ("getmessage"),
u_getattribute ("getattribute");
OSL_NAMESPACE_ENTER
@@ -330,11 +331,11 @@ RuntimeOptimizer::turn_into_new_op (Opcode &op, ustring newop, int newarg0,
DASSERT (opnum >= 0 && opnum < (int)inst()->ops().size());
if (debug() > 1)
std::cout << "turned op " << opnum
<< " from " << op.opname() << " to "
<< " from '" << op_string(op) << "' to '"
<< newop << ' ' << inst()->symbol(newarg0)->name() << ' '
<< inst()->symbol(newarg1)->name() << ' '
<< (newarg2<0 ? "" : inst()->symbol(newarg2)->name().c_str())
<< (why.size() ? " : " : "") << why << "\n";
<< (why.size() ? "' : " : "'") << why << "\n";
op.reset (newop, newarg2<0 ? 2 : 3);
inst()->args()[op.firstarg()+0] = newarg0;
op.argwriteonly (0);
@@ -358,9 +359,9 @@ RuntimeOptimizer::turn_into_assign (Opcode &op, int newarg, string_view why)
int opnum = &op - &(inst()->ops()[0]);
if (debug() > 1)
std::cout << "turned op " << opnum
<< " from " << op.opname() << " to "
<< " from '" << op_string(op) << "' to '"
<< opargsym(op,0)->name() << " = "
<< inst()->symbol(newarg)->name()
<< inst()->symbol(newarg)->name() << "'"
<< (why.size() ? " : " : "") << why << "\n";
op.reset (u_assign, 2);
inst()->args()[op.firstarg()+1] = newarg;
@@ -415,7 +416,7 @@ RuntimeOptimizer::turn_into_nop (Opcode &op, string_view why)
if (op.opname() != u_nop) {
if (debug() > 1)
std::cout << "turned op " << (&op - &(inst()->ops()[0]))
<< " from " << op.opname() << " to nop"
<< " from '" << op_string(op) << "' to 'nop'"
<< (why.size() ? " : " : "") << why << "\n";
op.reset (u_nop, 0);
return 1;
@@ -437,7 +438,7 @@ RuntimeOptimizer::turn_into_nop (int begin, int end, string_view why)
}
}
if (debug() > 1 && changed)
std::cout << "turned ops " << begin << "-" << (end-1) << " into nop"
std::cout << "turned ops " << begin << "-" << (end-1) << " into 'nop'"
<< (why.size() ? " : " : "") << why << "\n";
return changed;
}
@@ -447,7 +448,8 @@ RuntimeOptimizer::turn_into_nop (int begin, int end, string_view why)
void
RuntimeOptimizer::insert_code (int opnum, ustring opname,
const int *argsbegin, const int *argsend,
bool recompute_rw_ranges, int relation)
RecomputeRWRangesOption recompute_rw_ranges,
InsertRelation relation)
{
OpcodeVec &code (inst()->ops());
std::vector<int> &opargs (inst()->args());
@@ -550,7 +552,8 @@ RuntimeOptimizer::insert_code (int opnum, ustring opname,
void
RuntimeOptimizer::insert_code (int opnum, ustring opname,
const std::vector<int> &args_to_add,
bool recompute_rw_ranges, int relation)
RecomputeRWRangesOption recompute_rw_ranges,
InsertRelation relation)
{
const int *argsbegin = (args_to_add.size())? &args_to_add[0]: NULL;
const int *argsend = argsbegin + args_to_add.size();
@@ -562,7 +565,8 @@ RuntimeOptimizer::insert_code (int opnum, ustring opname,
void
RuntimeOptimizer::insert_code (int opnum, ustring opname, int relation,
RuntimeOptimizer::insert_code (int opnum, ustring opname,
InsertRelation relation,
int arg0, int arg1, int arg2, int arg3)
{
int args[4];
@@ -571,7 +575,7 @@ RuntimeOptimizer::insert_code (int opnum, ustring opname, int relation,
if (arg1 >= 0) args[nargs++] = arg1;
if (arg2 >= 0) args[nargs++] = arg2;
if (arg3 >= 0) args[nargs++] = arg3;
insert_code (opnum, opname, args, args+nargs, true, relation);
insert_code (opnum, opname, args, args+nargs, RecomputeRWRanges, relation);
}
@@ -584,7 +588,8 @@ RuntimeOptimizer::insert_useparam (size_t opnum,
{
ASSERT (params_to_use.size() > 0);
OpcodeVec &code (inst()->ops());
insert_code (opnum, u_useparam, params_to_use, 1);
insert_code (opnum, u_useparam, params_to_use,
RecomputeRWRanges, GroupWithNext);
// All ops are "read"
code[opnum].argwrite (0, false);
@@ -1660,7 +1665,8 @@ RuntimeOptimizer::peephole2 (int opnum)
newargs.push_back (oparg(op,i));
turn_into_nop (op, "combine closure+mul");
turn_into_nop (next, "combine closure+mul");
insert_code (opnum, u_closure, newargs, true, 1);
insert_code (opnum, u_closure, newargs,
RecomputeRWRanges, GroupWithNext);
if (debug() > 1)
std::cout << "op " << opnum << "-" << (op2num)
<< " combined closure+mul\n";
@@ -1816,7 +1822,7 @@ RuntimeOptimizer::eliminate_middleman ()
dsym = downinst->mastersymbol(c.dst.param);
const Symbol *usym = upinst->symbol(upstream_symbol);
if (! usym)
usym = downinst->mastersymbol(upstream_symbol);
usym = upinst->mastersymbol(upstream_symbol);
ASSERT (dsym && usym);
std::cout << "Removed " << inst()->layername() << "."
<< s.name() << " middleman for "
@@ -2712,7 +2718,7 @@ RuntimeOptimizer::run ()
std::cout.flush ();
std::cout << "Before optimizing layer " << layer << " "
<< inst()->layername()
<< ", I get:\n" << inst()->print()
<< ", I get:\n" << inst()->print(group())
<< "\n--------------------------------\n\n";
std::cout.flush ();
}
@@ -2787,7 +2793,11 @@ RuntimeOptimizer::run ()
<< " out? " << (inst()->outgoing_connections()?'y':'n')
<< (inst()->writes_globals() ? " writes_globals" : "")
<< (inst()->userdata_params() ? " userdata_params" : "")
<< "\n" << inst()->print()
<< (inst()->run_lazily() ? " run_lazily" : "")
<< (inst()->outgoing_connections() ? " outgoing_connections" : "")
<< (inst()->renderer_outputs() ? " renderer_outputs" : "")
<< (inst()->writes_globals() ? " writes_globals" : "")
<< "\n" << inst()->print(group())
<< "\n--------------------------------\n\n";
std::cout.flush ();
}
@@ -2797,10 +2807,12 @@ RuntimeOptimizer::run ()
m_unknown_textures_needed = false;
m_unknown_closures_needed = false;
m_unknown_attributes_needed = false;
m_textures_needed.clear();
m_closures_needed.clear();
m_globals_needed.clear();
m_userdata_needed.clear();
m_attributes_needed.clear();
for (int layer = 0; layer < nlayers; ++layer) {
set_inst (layer);
if (inst()->unused())
@@ -2850,6 +2862,34 @@ RuntimeOptimizer::run ()
} else {
m_unknown_closures_needed = true;
}
} else if (op.opname() == u_getattribute) {
Symbol *sym1 = opargsym (op, 1);
ASSERT (sym1 && sym1->typespec().is_string());
if (sym1->is_constant()) {
if (op.nargs() == 3) {
// getattribute( attributename, result )
m_attributes_needed.insert( AttributeNeeded( *(ustring *)sym1->data() ) );
} else {
ASSERT (op.nargs() == 4 || op.nargs() == 5);
Symbol *sym2 = opargsym (op, 2);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, result ) or
// getattribute( scopename, attributename, arrayindex, result )
if (sym2->is_constant()) {
m_attributes_needed.insert( AttributeNeeded(
*(ustring *)sym2->data(), *(ustring *)sym1->data()
) );
} else {
m_unknown_attributes_needed = true;
}
} else {
// getattribute( attributename, arrayindex, result )
m_attributes_needed.insert( AttributeNeeded( *(ustring *)sym1->data() ) );
}
}
} else { // sym1 not constant
m_unknown_attributes_needed = true;
}
}
}
}
@@ -2884,6 +2924,13 @@ RuntimeOptimizer::run ()
shadingcontext()->info (" %s %s %s", f.name, f.type,
f.derivs ? "(derivs)" : "");
}
if (m_attributes_needed.size()) {
shadingcontext()->info ("Group needs attributes:");
BOOST_FOREACH (const AttributeNeeded &f, m_attributes_needed)
shadingcontext()->info (" %s %s", f.name, f.scope);
if (m_unknown_attributes_needed)
shadingcontext()->info (" Also may construct attribute names on the fly.");
}
}
}
+31 -16
View File
@@ -231,29 +231,35 @@ public:
void make_symbol_room (int howmany=1);
/// Insert instruction 'opname' with arguments 'args_to_add' into the
/// code at instruction 'opnum'. The existing code and concatenated
/// argument lists can be found in code and opargs, respectively, and
/// allsyms contains pointers to all symbols. mainstart is a reference
/// to the address where the 'main' shader begins, and may be modified
/// if the new instruction is inserted before that point.
/// If recompute_rw_ranges is true, also adjust all symbols' read/write
/// ranges to take the new instruction into consideration.
/// Relation indicates its relation to surrounding instructions:
/// 0 means none, -1 means it should have the same method, sourcefile,
/// and sourceline as the preceeding instruction, 1 means it should
/// have the same method, sourcefile, and sourceline as the subsequent
/// instruction.
enum RecomputeRWRangesOption { DontRecomputeRWRanges, RecomputeRWRanges };
enum InsertRelation { NoRelation=0, GroupWithPrevious=-1, GroupWithNext=1 };
/// Insert instruction 'opname' with arguments 'args_to_add' into
/// the code at instruction 'opnum'. The existing code and
/// concatenated argument lists can be found in code and opargs,
/// respectively, and allsyms contains pointers to all symbols.
/// mainstart is a reference to the address where the 'main' shader
/// begins, and may be modified if the new instruction is inserted
/// before that point. The recompute_rw_ranges parameter determines
/// whether all symbols' read/write ranges should be adjusted to
/// take the new instruction into consideration. Relation indicates
/// its relation to surrounding instructions: GroupWithPrevious
/// means it should have the same method, sourcefile, and sourceline
/// as the preceeding instruction; GroupWithNext means it should
/// have the same method, sourcefile, and sourceline as the
/// subsequent instruction; NoRelation means we have no information,
/// so don't copy that info from anywhere.
void insert_code (int opnum, ustring opname,
const std::vector<int> &args_to_add,
bool recompute_rw_ranges=false, int relation=0);
RecomputeRWRangesOption recompute_rw_ranges,
InsertRelation relation=GroupWithNext);
/// insert_code with begin/end arg array pointers.
void insert_code (int opnum, ustring opname,
const int *argsbegin, const int *argsend,
bool recompute_rw_ranges=false, int relation=0);
RecomputeRWRangesOption recompute_rw_ranges,
InsertRelation relation=GroupWithNext);
/// insert_code with explicit arguments (up to 4, a value of -1 means
/// the arg isn't used). Presume recompute_rw_ranges is true.
void insert_code (int opnum, ustring opname, int relation,
void insert_code (int opnum, ustring opname, InsertRelation relation,
int arg0=-1, int arg1=-1, int arg2=-1, int arg3=-1);
void insert_useparam (size_t opnum, const std::vector<int> &params_to_use);
@@ -342,6 +348,13 @@ public:
void stop_optimizing () { m_stop_optimizing = true; }
std::string op_string (const Opcode &op) {
std::string s = op.opname().string();
for (int a = 0; a < op.nargs(); ++a)
s = s + ' ' + opargsym(op,a)->name().string();
return s;
}
private:
int m_optimize; ///< Current optimization level
bool m_opt_simplify_param; ///< Turn instance params into const?
@@ -375,8 +388,10 @@ private:
std::set<ustring> m_textures_needed;
std::set<ustring> m_closures_needed;
std::set<ustring> m_globals_needed;
std::set<AttributeNeeded> m_attributes_needed;
bool m_unknown_textures_needed;
bool m_unknown_closures_needed;
bool m_unknown_attributes_needed;
std::set<UserDataNeeded> m_userdata_needed;
double m_stat_opt_locking_time; ///< locking time
double m_stat_specialization_time; ///< specialization time
+94 -12
View File
@@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include "oslexec_pvt.h"
#include "OSL/genclosure.h"
@@ -661,11 +662,19 @@ ShadingSystemImpl::ShadingSystemImpl (RendererServices *renderer,
// If we still don't have a texture system, create a new one
if (! m_texturesys) {
#if OSL_NO_DEFAULT_TEXTURESYSTEM
// This build option instructs OSL to never create a TextureSystem
// itself. (Most likely reason: this build of OSL is for a renderer
// that replaces OIIO's TextureSystem with its own, and therefore
// wouldn't want to accidentally make an OIIO one here.
ASSERT (0 && "ShadingSystem was not passed a working TextureSystem*");
#else
m_texturesys = TextureSystem::create (true /* shared */);
ASSERT (m_texturesys);
// Make some good guesses about default options
m_texturesys->attribute ("automip", 1);
m_texturesys->attribute ("autotile", 64);
#endif
}
// Alternate way of turning on LLVM debug mode (temporary/experimental)
@@ -1295,6 +1304,34 @@ ShadingSystemImpl::getattribute (ShaderGroup *group, string_view name,
*(ustring *)val = ustring(group->serialize());
return true;
}
if (name == "num_attributes_needed" && type == TypeDesc::TypeInt) {
if (! group->optimized())
optimize_group (*group);
*(int *)val = (int)group->m_attributes_needed.size();
return true;
}
if (name == "attributes_needed" && type.basetype == TypeDesc::PTR) {
if (! group->optimized())
optimize_group (*group);
size_t n = group->m_attributes_needed.size();
*(ustring **)val = n ? &group->m_attributes_needed[0] : NULL;
return true;
}
if (name == "attribute_scopes" && type.basetype == TypeDesc::PTR) {
if (! group->optimized())
optimize_group (*group);
size_t n = group->m_attribute_scopes.size();
*(ustring **)val = n ? &group->m_attribute_scopes[0] : NULL;
return true;
}
if (name == "unknown_attributes_needed" && type == TypeDesc::TypeInt) {
if (! group->optimized())
optimize_group (*group);
*(int *)val = (int)group->m_unknown_attributes_needed;
return true;
}
return false;
}
@@ -1911,7 +1948,7 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
break; // error
}
if (Strutil::parse_char (p, '[')) {
int arraylen;
int arraylen = -1;
Strutil::parse_int (p, arraylen);
Strutil::parse_char (p, ']');
type.arraylen = arraylen;
@@ -1928,27 +1965,59 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
}
string_view paramname (paramname_string);
int lockgeom = true;
int nvals = type.numelements() * type.aggregate;
// For speed, reserve space. Note that for "unsized" arrays,
// numelements() will return 1, so we only preallocate 1 slot
// and let it grow as needed. That's ok. For everything else, we
// will reserve the right amount up front.
int vals_to_preallocate = type.numelements() * type.aggregate;
// Stop parsing values when we hit the limit based on the
// declaration.
int max_vals = type.is_unsized_array() ? 1<<28 : vals_to_preallocate;
if (type.basetype == TypeDesc::INT) {
intvals.clear ();
intvals.resize (nvals, 0);
for (int i = 0; i < nvals; ++i) {
if (! Strutil::parse_int (p, intvals[i]))
intvals.reserve (vals_to_preallocate);
int i;
for (i = 0; i < max_vals; ++i) {
int val = 0;
if (Strutil::parse_int (p, val))
intvals.push_back (val);
else
break;
}
if (type.is_unsized_array()) {
// For unsized arrays, now set the size based on how many
// values we actually read.
type.arraylen = std::max (1, i/type.aggregate);
}
// Zero-pad if we parsed fewer values than we needed
intvals.resize (type.numelements()*type.aggregate, 0);
ASSERT (type.numelements()*type.aggregate == int(intvals.size()));
Parameter (paramname, type, &intvals[0], lockgeom);
} else if (type.basetype == TypeDesc::FLOAT) {
floatvals.clear ();
floatvals.resize (nvals, 0.0f);
for (int i = 0; i < nvals; ++i) {
if (! Strutil::parse_float (p, floatvals[i]))
floatvals.reserve (vals_to_preallocate);
int i;
for (i = 0; i < max_vals; ++i) {
float val = 0;
if (Strutil::parse_float (p, val))
floatvals.push_back (val);
else
break;
}
if (type.is_unsized_array()) {
// For unsized arrays, now set the size based on how many
// values we actually read.
type.arraylen = std::max (1, i/type.aggregate);
}
// Zero-pad if we parsed fewer values than we needed
floatvals.resize (type.numelements()*type.aggregate, 0);
ASSERT (type.numelements()*type.aggregate == int(floatvals.size()));
Parameter (paramname, type, &floatvals[0], lockgeom);
} else if (type.basetype == TypeDesc::STRING) {
stringvals.clear ();
stringvals.resize (nvals);
for (int i = 0; i < nvals; ++i) {
stringvals.reserve (vals_to_preallocate);
int i;
for (i = 0; i < max_vals; ++i) {
std::string unescaped;
string_view s;
Strutil::skip_whitespace (p);
@@ -1963,8 +2032,16 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
if (s.size() == 0)
break;
}
stringvals[i] = ustring(s);
stringvals.push_back (ustring(s));
}
if (type.is_unsized_array()) {
// For unsized arrays, now set the size based on how many
// values we actually read.
type.arraylen = std::max (1, i/type.aggregate);
}
// Zero-pad if we parsed fewer values than we needed
stringvals.resize (type.numelements()*type.aggregate, ustring());
ASSERT (type.numelements()*type.aggregate == int(stringvals.size()));
Parameter (paramname, type, &stringvals[0], lockgeom);
}
@@ -2407,6 +2484,11 @@ ShadingSystemImpl::optimize_group (ShaderGroup &group)
group.m_userdata_types.push_back (n.type);
group.m_userdata_derivs.push_back (n.derivs);
}
group.m_unknown_attributes_needed = rop.m_unknown_attributes_needed;
BOOST_FOREACH (const AttributeNeeded &f, rop.m_attributes_needed) {
group.m_attributes_needed.push_back (f.name);
group.m_attribute_scopes.push_back (f.scope);
}
BackendLLVM lljitter (*this, group, ctx);
lljitter.run ();
@@ -2561,7 +2643,7 @@ ShadingSystemImpl::merge_instances (ShaderGroup &group, bool post_opt)
if (con.srclayer == b) {
con.srclayer = a;
A->outgoing_connections (true);
if (B->symbols().size()) {
if (A->symbols().size() && B->symbols().size()) {
ASSERT (A->symbol(con.src.param)->name() ==
B->symbol(con.src.param)->name());
}
+9 -1
View File
@@ -78,7 +78,15 @@ stdoslpath ()
boost::filesystem::path path (program); // our program
path = path.parent_path (); // now the bin dir of our program
path = path.parent_path (); // now the parent dir
path = path / "shaders";
boost::filesystem::path savepath = path;
// We search two spots: ../../lib/osl/include, and ../shaders
path = savepath / "lib" / "osl" / "include";
if (OIIO::Filesystem::exists (path.string())) {
path = path / "stdosl.h";
if (OIIO::Filesystem::exists (path.string()))
return path.string();
}
path = savepath / "shaders";
if (OIIO::Filesystem::exists (path.string())) {
path = path / "stdosl.h";
if (OIIO::Filesystem::exists (path.string()))
+2 -1
View File
@@ -29,7 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <map>
#include <OpenImageIO/hash.h>
#include <boost/unordered_map.hpp>
#include <OpenImageIO/ustring.h>
#include "OSL/oslexec.h"
OSL_NAMESPACE_ENTER
+2 -1
View File
@@ -29,7 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <map>
#include <OpenImageIO/hash.h>
#include <boost/unordered_map.hpp>
#include <OpenImageIO/ustring.h>
#include "OSL/oslexec.h"
OSL_NAMESPACE_ENTER
+21 -1
View File
@@ -33,7 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <cmath>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include <OpenImageIO/imageio.h>
#include <OpenImageIO/imagebuf.h>
@@ -708,6 +708,26 @@ test_group_attributes (ShaderGroup *group)
<< userdata_offsets[i] << " deriv="
<< userdata_derivs[i] << "\n";
}
int nattr = 0;
if (shadingsys->getattribute (group, "num_attributes_needed", nattr) && nattr) {
std::cout << "Need " << nattr << " attributes:\n";
ustring *names = NULL;
ustring *scopes = NULL;
shadingsys->getattribute (group, "attributes_needed",
TypeDesc::PTR, &names);
shadingsys->getattribute (group, "attribute_scopes",
TypeDesc::PTR, &scopes);
DASSERT (names && scopes);
for (int i = 0; i < nattr; ++i)
std::cout << " " << names[i] << ' '
<< scopes[i] << "\n";
int unk = 0;
shadingsys->getattribute (group, "unknown_attributes_needed", unk);
if (unk)
std::cout << " and unknown attributes\n";
}
}
+8
View File
@@ -0,0 +1,8 @@
shader a (output closure color output_closure = 0)
{
printf("Shader a \n");
for (int i = 1; i < 3 ; ++i)
{
output_closure += color(u/i, 2.0, 0.0) * diffuse(N);
}
}
+10
View File
@@ -0,0 +1,10 @@
shader b (closure color input_closures[2] = {0})
{
printf("Shader b \n");
for (int i = 0; i < 2 ; ++i)
{
printf("In %d : %s\n", i, input_closures[i]);
Ci += input_closures[i];
}
printf("Ci : %s \n", Ci);
}
+8
View File
@@ -0,0 +1,8 @@
shader c (
closure color in0 = 0,
closure color in1 = 0,
output closure color output_closures[2] = {in0, in1}
)
{
printf("Shader c \n");
}
+8
View File
@@ -0,0 +1,8 @@
shader d (output closure color output_closure = 0)
{
printf("Shader d \n");
for (int i = 1; i < 4 ; ++i)
{
output_closure += color(v/i, 0.0, 3.0) * diffuse(N);
}
}
+22
View File
@@ -0,0 +1,22 @@
Compiled a.osl -> a.oso
Compiled b.osl -> b.oso
Compiled c.osl -> c.oso
Compiled d.osl -> d.oso
Connect alayer.output_closure to clayer.in0
Connect dlayer.output_closure to clayer.in1
Connect clayer.output_closures to blayer.input_closures
Shader b
Shader a
Shader d
Shader c
In 0 : (0.5, 2, 0) * diffuse ((0, 0, 1))
+ (0.25, 2, 0) * diffuse ((0, 0, 1))
In 1 : (0.5, 0, 3) * diffuse ((0, 0, 1))
+ (0.25, 0, 3) * diffuse ((0, 0, 1))
+ (0.166667, 0, 3) * diffuse ((0, 0, 1))
Ci : (0.5, 2, 0) * diffuse ((0, 0, 1))
+ (0.25, 2, 0) * diffuse ((0, 0, 1))
+ (0.5, 0, 3) * diffuse ((0, 0, 1))
+ (0.25, 0, 3) * diffuse ((0, 0, 1))
+ (0.166667, 0, 3) * diffuse ((0, 0, 1))
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env python
command += testshade ("-layer alayer a -layer dlayer d --layer clayer c --layer blayer b --connect alayer output_closure clayer in0 --connect dlayer output_closure clayer in1 --connect clayer output_closures blayer input_closures ")
+7
View File
@@ -0,0 +1,7 @@
surface a ( output closure color CCout = 0 )
{
CCout = diffuse(N) * color(0,0.18,0);
Ci = CCout;
printf ("a: CCout = %s\n", CCout);
printf ("a: Ci = %s\n", Ci);
}
+6
View File
@@ -0,0 +1,6 @@
surface b ( closure color CCin = 0 )
{
printf("\nb: CCin = %s\n", CCin);
Ci = CCin + diffuse(N) * color(.18,0,0);
printf("b: Ci = %s\n",Ci);
}
+10
View File
@@ -0,0 +1,10 @@
Compiled a.osl -> a.oso
Compiled b.osl -> b.oso
Connect alayer.CCout to blayer.CCin
a: CCout = (0, 0.18, 0) * diffuse ((0, 0, 1))
a: Ci = (0, 0.18, 0) * diffuse ((0, 0, 1))
b: CCin = (0, 0.18, 0) * diffuse ((0, 0, 1))
b: Ci = (0, 0.18, 0) * diffuse ((0, 0, 1))
+ (0.18, 0, 0) * diffuse ((0, 0, 1))
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env python
# Example that failed with a prior bug.
# The test case is that layer a modifies Ci so is unconditional, but also
# its output CCout is connected to layer b's CCin. There was a bug where
# the earlier layer was run and its values copied before (duh, not after)
# b's params would be initialized, thus overwriting the copied values.
command += testshade("-layer alayer a -layer blayer b --connect alayer CCout blayer CCin")
+4
View File
@@ -0,0 +1,4 @@
struct Astruct {
float s, t;
};
+7
View File
@@ -0,0 +1,7 @@
#include "Astruct.h"
shader a (output Astruct Aout = {-1, -1})
{
Aout.s = u;
Aout.t = v;
}
+9
View File
@@ -0,0 +1,9 @@
#include "Astruct.h"
shader b (Astruct Ain = {0,0},
output Astruct Bout = Ain,
output color Cout = 0)
{
Cout = color (Bout.s, Bout.t, 0);
printf ("%g : should be %g %g 0\n", Cout, u, v);
}
+6
View File
@@ -0,0 +1,6 @@
Compiled a.osl -> a.oso
Compiled b.osl -> b.oso
Connect a.Aout to b.Ain
Output Cout to out.exr
0.5 0.5 0 : should be 0.5 0.5 0
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env python
command = testshade("--layer a a --layer b b --connect a Aout b Ain -o Cout out.exr")
@@ -0,0 +1,18 @@
Compiled test.osl -> test.oso
farr array length 5
[0] = 1.1
[1] = 1.2
[2] = 1.3
[3] = 1.4
[4] = 1.5
carr array length 2
[0] = 0.1 0.2 0.3
[1] = 0.4 0.5 0.6
iarr array length 2
[0] = 11
[1] = 12
sarr array length 3
[0] = "foo"
[1] = "bar"
[2] = "baz"
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env python
command += testshade("-group serial.oslgroup")
@@ -0,0 +1,7 @@
param float[] farr 1.1 1.2 1.3 1.4 1.5 ;
param int[] iarr 11 12 ;
param string[] sarr "foo" "bar" "baz" ;
param color[] carr 0.1 0.2 0.3 0.4 0.5 0.6 ;
shader test ;
+43
View File
@@ -0,0 +1,43 @@
void print_array_contents (string name, int arr[])
{
printf ("%s array length %d\n", name, arraylength(arr));
for (int i = 0; i < arraylength(arr); ++i)
printf (" [%d] = %d\n", i, arr[i]);
}
void print_array_contents (string name, float arr[])
{
printf ("%s array length %d\n", name, arraylength(arr));
for (int i = 0; i < arraylength(arr); ++i)
printf (" [%d] = %g\n", i, arr[i]);
}
void print_array_contents (string name, color arr[])
{
printf ("%s array length %d\n", name, arraylength(arr));
for (int i = 0; i < arraylength(arr); ++i)
printf (" [%d] = %g\n", i, arr[i]);
}
void print_array_contents (string name, string arr[])
{
printf ("%s array length %d\n", name, arraylength(arr));
for (int i = 0; i < arraylength(arr); ++i)
printf (" [%d] = \"%s\"\n", i, arr[i]);
}
shader test (float farr[] = {0},
color carr[] = {0},
int iarr[] = {0},
string sarr[] = {""}
)
{
print_array_contents ("farr", farr);
print_array_contents ("carr", carr);
print_array_contents ("iarr", iarr);
print_array_contents ("sarr", sarr);
}