Compare commits

..
Author SHA1 Message Date
Larry Gritz f4db549061 runner
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 22:40:36 -07:00
Larry Gritz 4debd96adc Set up workflows to have subsequent PR pushes cancel previous in-progress jobs
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 22:30:58 -07:00
Larry Gritz 30a4a95b7e Experiment: use new big runner to speed up the expensive analysis run
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 22:18:46 -07:00
Larry Gritz a38aa58c0e typo
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 22:08:46 -07:00
Larry Gritz e126a20df7 Analysis build for avx512 as well for more code coverage
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 22:05:08 -07:00
Larry Gritz 52cf2ee418 Improve testing coverage
Looking at the code coverage report and trying to get a higher
coverage amount, employing two strategies: (a) remove unused code
that is not covered because it's... unused; and (b) test things
that are used but aren't in the test run. Details follow.

Arbitrarily pick a couple of render tests to use llvm_opt levels 12
and 13 to verify that they work correctly. (That's a couple hundred
lines of pass setup code that wouldn't otherwise be included in the
coverage analysis, nor tested in the testsuite.) This also required us
to add the --llvm_opt command to testrender, as it is in testshade.

Remove deprecated version of LLVM_Util::make_function.

When OSL_USE_OPTIX is not enabled, exclude compiling contents of
ptx_compile_group.

get_alignment can also be OSL_DEV only as well as simplified

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 21:54:57 -07:00
Larry Gritz 83a1e7e74b WIP: improve coverage analysis
Disable contents of dump_struct_data_layout when OSL_DEV is not
defined, it will never be called in any other circumstances -- it's
strictly a debugging tool, not part of the shipping library.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2022-10-10 18:06:54 -07:00
176 changed files with 2276 additions and 4450 deletions
+3 -1
View File
@@ -37,7 +37,8 @@ jobs:
include:
- desc: sonar gcc9/C++14 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
nametag: static-analysis-sonar
os: ubuntu-latest
os: ubuntu-20.04-8c-32g-300h
# os: ubuntu-latest
vfxyear: 2022
vfxsuffix: -clang13
cxx_std: 14
@@ -76,6 +77,7 @@ jobs:
PYTHON_VERSION: ${{matrix.python_ver}}
USE_BATCHED: ${{matrix.batched}}
USE_SIMD: ${{matrix.simd}}
PARALLEL: 24
# DEBUG_CI: 1
steps:
# We would like to use harden-runner, but it flags too many false
+20 -21
View File
@@ -20,13 +20,16 @@ on:
- '**.rst'
- '**.tex'
schedule:
# Full nightly build, for the main project repo (not for forks)
# Full nightly build
- cron: "0 6 * * *"
if: github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
permissions: read-all
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
@@ -47,7 +50,7 @@ jobs:
pybind11_ver: v2.4.2
- desc: clang9/C++14 llvm9 oiio-release boost1.66 avx2 exr2.3 py2.7
nametag: linux-clang9-llvm9
os: ubuntu-20.04
os: ubuntu-18.04
vfxyear: 2019
vfxsuffix: -clang9
cc_compiler: clang
@@ -68,8 +71,7 @@ jobs:
# pybind11_ver: v2.9.0
simd: avx2,f16c
skip_tests: 1
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=8.1.1
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
- desc: gcc6/C++14 llvm10 py3.7 boost1.70 exr2.4 oiio2.2 sse4
nametag: linux-vfx2020
os: ubuntu-latest
@@ -114,11 +116,11 @@ jobs:
simd: avx2,f16c
batched: b8_AVX2,b8_AVX512,b16_AVX512
setenvs: USE_OPENVDB=0
- desc: icc/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio-master avx2
- desc: icc/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio-master avx2
nametag: linux-icc
os: ubuntu-latest
vfxyear: 2022
vfxsuffix: -clang14
vfxsuffix: -clang13
cc_compiler: icc
cxx_compiler: icpc
cxx_std: 17
@@ -131,11 +133,11 @@ jobs:
setenvs: export OSL_CMAKE_FLAGS="-DSTOP_ON_WARNING=OFF -DEXTRA_CPP_ARGS=-fp-model=consistent"
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=7.1.3
USE_OPENVDB=0
- desc: icx/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio2.3 avx2
- desc: icx/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
nametag: linux-icx
os: ubuntu-latest
vfxyear: 2022
vfxsuffix: -clang14
vfxsuffix: -clang13
cc_compiler: icx
cxx_compiler: icpx
cxx_std: 17
@@ -290,7 +292,7 @@ jobs:
include:
- desc: Debug gcc7/C++14 llvm9 py2.7 oiio2.3 exr2.4 sse4 boost1.65 exr2.4
nametag: linux-debug-gcc7-llvm9
os: ubuntu-20.04
os: ubuntu-18.04
cxx_compiler: g++-7
cxx_std: 14
openexr_ver: v2.4.3
@@ -304,7 +306,7 @@ jobs:
CTEST_TEST_TIMEOUT=240
- desc: gcc10/C++17 llvm10 oiio-release boost1.65 exr2.5 avx2
nametag: linux-2021ish-gcc10-llvm10
os: ubuntu-20.04
os: ubuntu-18.04
cxx_compiler: g++-10
cxx_std: 17
fmt_ver: 7.0.1
@@ -318,20 +320,20 @@ jobs:
PUGIXML_VERSION=v1.10
- desc: latest releases gcc11/C++17 llvm13 boost1.71 exr3.1 py3.9 avx2 batch-b16avx512
nametag: linux-latest-releases
os: ubuntu-22.04
os: ubuntu-20.04
cxx_compiler: g++-11
cxx_std: 17
fmt_ver: 9.1.0
openexr_ver: v3.1.7
openexr_ver: v3.1.5
openimageio_ver: master
pybind11_ver: v2.10.0
python_ver: "3.10"
python_ver: 3.9
simd: avx2,f16c
batched: b8_AVX2,b8_AVX512,b16_AVX512
setenvs: export LLVM_VERSION=13.0.0
LLVM_DISTRO_NAME=ubuntu-20.04
OPENCOLORIO_VERSION=v2.2.0
PUGIXML_VERSION=v1.13
OPENCOLORIO_VERSION=v2.1.2
PUGIXML_VERSION=v1.11.4
- desc: bleeding edge gcc12/C++17 llvm14 oiio/ocio/exr/pybind-master boost1.71 py3.10 avx2 batch-b16avx512
nametag: linux-bleeding-edge
os: ubuntu-22.04
@@ -355,7 +357,7 @@ jobs:
cc_compiler: clang
cxx_std: 17
fmt_ver: 8.1.1
openexr_ver: v3.1.7
openexr_ver: v3.1.5
openimageio_ver: master
pybind11_ver: v2.9.2
python_ver: 3.8
@@ -435,8 +437,6 @@ jobs:
python_ver: "3.10"
aclang: 13
setenvs: export LLVMBREWVER="@14" DO_BREW_UPDATE=1
OPENIMAGEIO_VERSION=release
QT_BREW_VERSION="@5"
- desc: MacOS-12
os: macos-12
nametag: macos11-p310
@@ -446,7 +446,6 @@ jobs:
python_ver: "3.10"
aclang: 13
setenvs: export LLVMBREWVER="@15" DO_BREW_UPDATE=1
OPENIMAGEIO_VERSION=master
runs-on: ${{matrix.os}}
env:
CXX: ${{matrix.cxx_compiler}}
+3 -8
View File
@@ -10,23 +10,18 @@ on:
# Declare default permissions as read only.
permissions: read-all
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
analysis:
name: Scorecards analysis
if: |
github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Used to receive a badge. (Upcoming feature)
id-token: write
# Needs for private repositories.
contents: read
actions: read
steps:
- name: "Checkout code"
+3 -4
View File
@@ -5,14 +5,13 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
- Existing Project Governance
- [X] Project License exists ( [LICENSE.md](../LICENSE.md) ) and is OSI-approved
- [X] Any third-party components/dependencies included are listed along with their licenses ( [THIRD_PARTY.md](../THIRD_PARTY.md) )
- [X] Governance defined, outlining community roles and how decisions are made ( [GOVERNANCE.md](../GOVERNANCE.md) )
- [X] Governance defined, outlining community roles and how decsions are made ( [GOVERNANCE.md](../GOVERNANCE.md] )
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
- [X] Contribution Policy defined ( [CONTRIBUTING.md](../CONTRIBUTING.md) )
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
- [X] Code of Conduct defined ( existing or pull from [ASWF Sample Project](https://github.com/AcademySoftwareFoundation/aswf-sample-project/blob/master/CODE_OF_CONDUCT.md) )
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
- [X] Release methodology defined ( [RELEASING.md](../docs/RELEASING.md) )
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1572
- [ ] Release methodology defined ( [release.md](process/release.md) )
- New Project Governance
- [X] TSC members identified
- [X] First TSC meeting held
@@ -42,7 +41,7 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
- [X] New project announcement done ( https://www.aswf.io/osl-joins-aswf/ )
- [X] Project added to ASWF website and ASWF landscape
- Graduation
- [X] OpenSSF Best Practices Badge achieved
- [ ] CII Badge achieved
- [ ] Committer Diversity established
- [ ] Commit/Contribution growth during incubation
- [ ] Committers defined in the project ( [COMMITTERS.csv](COMMITTERS.csv) or [COMMITTERS.yml](COMMITTERS.yml) )
+1 -68
View File
@@ -23,10 +23,6 @@ API changes, new options, new ShadingSystem features (for renderer writers):
SIMD batched shading mode:
* Fix some array overruns (asymptomatic, but still potentially buggy) in
common_ancestor_between. #1577 (1.13.0.2)
* Fix issue with closure keyword parameters. #1620 (1.13.2.0/1.12.8.0)
* Fix crash when adding a default initialized closure. #1624
(1.13.2.0/1.12.8.0)
* Fix support for closures with array types. #1630 (1.13.2.0/1.12.8.0)
OptiX rendering:
* OptiX 6.0 support has been removed. For GPU rendering with OptiX, a minimum
@@ -38,14 +34,6 @@ OptiX rendering:
* Better PTX cache hit rate by eliminating several sources of not being
strictly deterministic in the PTX text we were generating. #1566 #1570
(1.13.0.1)
* Fix PTX symbol visibility issues. #1609 (1.13.2.0)
* Hide more code that is only used for OptiX mode, when OptiX is disabled.
#1608 (1.13.2.0)
* Remove dependency on OptiX SDK for building core OSL with OptiX support. You
can now build OSL with OptiX support enabled even if you don't have the
OptiX SDK headers present at build time. But you will still need them to
build your OptiX-based application that uses OSL for GPU rendering. #1627
(1.13.2.0/1.12.8.0)
Performance improvements:
@@ -56,82 +44,27 @@ Bug fixes and other improvements (internals):
Internals/developer concerns:
* platform.h:
- New `OSL_ALLOCA` macro to allocate on the stack. #1589 (1.13.0.3)
- Define OSL::bitcast utility. #1610 (1.13.2.0)
* Make sure that std::hash is defined for ustring and ustringhash. #1599
(1.13.1.1)
* Deprecate LLVMUtil::internalize_module_functions. #1606 (1.13.1.0)
* Work toward always representing strings in shaders as ustringhash rather
than ustring: phase 1 #1603 phase2 #1612 (1.13.2.0)
Build & test system improvements:
* CMake build system and scripts:
- The version number is now a cache variable, and so can be overridden at
build time using `-DOSL_VERSION=...`. Use with extreme caution! #1579
(1.13.0.2) Revised again to reduce changes of user error in #1617
(1.13.2.0/1.12.7.1)
- Add clangSupport library as dependency to fix linker error on some
platforms. #1613 (1.13.2.0/1.12.7.1)
(1.13.0.2)
* Dependency version support:
- Fix some issues that came up with the new icx 2022.0 compiler. #1601
(1.13.1.0)
- Test against OpenColorIO 2.2. #1616 (1.13.2.0/1.12.7.1)
* Testing and Continuous integration (CI) systems:
- Dynamic analysis using address and leak sanitizers. #1581 (1.13.0.3)
- `testshade --help` now prints TextureSystem options and all hardware
information. #1584 (1.13.0.3)
- Improvements to SonarCloud and coverage analysis. #1596 (1.13.0.3)
#1607 (1.13.1.0)
- Disabling the dso version of testshade for the coverage analysis test.
#1604 (1.13.1.0)
- Be sure to run pointcloud tests when partio is found. #1611 (1.13.2.0)
- testshade: better testing of all closure parameter types. #1621
(1.13.2.0/1.12.8.0)
* Platform support:
- Include `immintrin.h` only when needed. #1605 (1.13.1.0)
Documentation:
* `doc/RELEASING.md` documents our release process and versioning policies.
#1572 (1.13.0.2)
Release 1.12.8.0 -- 3 Jan 2023 (compared to 1.12.7.1)
-------------------------------------------------------
* Remove dependency on OptiX SDK for building core OSL with OptiX support.
You can now build OSL with OptiX support enabled even if you don't have the
OptiX SDK headers present at build time. But you will still need them to
build your OptiX-based application that uses OSL for GPU rendering. #1627
* Batch mode: fix issue with closure keyword parameters. #1620
* Batch mode: fix crash when adding a default initialized closure. #1624
* Batch mode: Fix support for closures with array types. #1630
* testshade: better testing of all closure parameter types. #1621
* Fix various CI breaks as dependencies shifted. #1629 #1631 #1633
Release 1.12.7.1 -- 1 Dec 2022 (compared to 1.12.7.0)
-------------------------------------------------------
* Add clangSupport library as dependency to fix linker error on some
platforms. #1613
* Test against OpenColorIO 2.2. #1616
* Build: Fix how version overrides work to reduce the chance of user mistakes.
#1617
Release 1.12.7.0 -- 1 Nov 2022 (compared to 1.12.6.2)
-------------------------------------------------------
* Optix: Change naming of certain compiler-generated constants in a way that
improves use of the PTX cache. #1570
* Batch: Fix uninitialized members in ReadEvent internals. #1575
* `testshade --help` now prints TextureSystem options and hardware info. #1584
* oslc: Fix memory leak in ASTvariable_declaration. #1576
* Fix memory leaks in light path expression code. #1593 #1594
* Include the immintrin.h header only when needed. #1605
* icx: Improvements to fix problems exposed by new icx 2022.2 compiler. #1601
* Testing: CMake cache variables to control the testing timeout length. #1571
* CI: Add a dynamic analysis test using address and leak sanitizers. #1581
* CI: Now using SonarCloud static analysis. #1551
* CI: Many improvements in testing code coverage #1607
* CI: Make sure to run pointcloud tests when partio is found. #1611
* Developers: platform.h now defines OSL_ALLOCA macro. #1589
* Developers: platform.h now defines OSL::bitcast utility. #1610
Release 1.12 -- 1 Oct 2022 (compared to 1.11)
----------------------------------------------
Big Deal Changes:
+7 -16
View File
@@ -4,14 +4,7 @@
cmake_minimum_required (VERSION 3.12)
set (OSL_VERSION "1.13.4.0")
set (OSL_VERSION_OVERRIDE "" CACHE STRING
"Version override (use with caution)!")
mark_as_advanced (OSL_VERSION_OVERRIDE)
if (OSL_VERSION_OVERRIDE)
set (OSL_VERSION ${OSL_VERSION_OVERRIDE})
endif ()
set (OSL_VERSION "1.13.1.0" CACHE STRING "Version")
project (OSL VERSION ${OSL_VERSION}
LANGUAGES CXX C
HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/OpenShadingLanguage")
@@ -98,8 +91,7 @@ else ()
endif ()
option (OSL_BUILD_PLUGINS "Bool OSL plugins, for example OIIO plugin" ON)
option (OSL_BUILD_SHADERS "Build shaders" ON)
option (OSL_USE_OPTIX "Include OptiX support" OFF)
message(STATUS "OSL_USE_OPTIX: ${OSL_USE_OPTIX}")
option (USE_OPTIX "Include OptiX support" OFF)
set (OPTIX_EXTRA_LIBS CACHE STRING "Extra lib targets needed for OptiX")
set (CUDA_EXTRA_LIBS CACHE STRING "Extra lib targets needed for CUDA")
set (CUDA_TARGET_ARCH "sm_60" CACHE STRING "CUDA GPU architecture (e.g. sm_50)")
@@ -108,7 +100,6 @@ 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)
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
@@ -128,14 +119,14 @@ if (OIIO_FMATH_SIMD_FRIENDLY)
add_definitions (-DOIIO_FMATH_SIMD_FRIENDLY=1)
endif ()
if (USE_OPTIX)
add_definitions ("-DOSL_USE_OPTIX=1")
endif ()
# Define OSL_INTERNAL symbol only when building OSL itself, will not be
# defined for downstream projects using OSL.
add_definitions (-DOSL_INTERNAL=1)
# To make sure we aren't relying on deprecated OIIO features, we define
# OIIO_DISABLE_DEPRECATED before including any OIIO headers.
add_definitions (-DOIIO_DISABLE_DEPRECATED=1)
# Set the default namespace. For symbol hiding reasons, it's important that
# the project name is a subset of the namespace name.
set (${PROJ_NAME}_NAMESPACE ${PROJECT_NAME} CACHE STRING
@@ -223,7 +214,7 @@ if (OSL_BUILD_PLUGINS)
add_subdirectory (src/osl.imageio)
endif ()
if (USE_QT AND (Qt5_FOUND OR Qt6_FOUND))
if (USE_QT AND Qt5_FOUND)
add_subdirectory (src/osltoy)
endif ()
+7 -8
View File
@@ -12,11 +12,11 @@ Dependencies
OSL requires the following dependencies or tools.
NEW or CHANGED dependencies since the last major release are **bold**.
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.26)
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.24)
* A suitable C++14 or C++17 compiler to build OSL itself, which may be any of:
- GCC 6.1 or newer (tested through gcc 12.1)
- Clang 3.4 or newer (tested through clang 16)
- Clang 3.4 or newer (tested through clang 15)
- Microsoft Visual Studio 2017 or newer
- Intel C++ compiler icc version 17 or newer or LLVM-based icx compiler
version 2022 or newer.
@@ -41,14 +41,13 @@ NEW or CHANGED dependencies since the last major release are **bold**.
DYLD_LIBRARY_PATH on OS X).
* [LLVM](http://www.llvm.org) 9, 10, 11, 12, 13, 14, or 15, including
clang libraries. LLVM 16 doesn't work yet, we need to make changes
on the OSL side to be compatible.
clang libraries.
* (optional) For GPU rendering on NVIDIA GPUs:
* [OptiX](https://developer.nvidia.com/rtx/ray-tracing/optix) 7.0 or higher.
* [Cuda](https://developer.nvidia.com/cuda-downloads) 8.0 or higher.
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.81)
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.80)
* [Ilmbase or Imath](https://github.com/AcademySoftwareFoundation/openexr) 2.3
or newer (recommended: 2.4 or higher; tested through 3.1)
* [Flex](https://github.com/westes/flex) 2.5.35 or newer and
@@ -56,7 +55,7 @@ NEW or CHANGED dependencies since the last major release are **bold**.
Note that on some MacOS/xcode releases, the system-installed Bison is too
old, and it's better to install a newer Bison (via Homebrew is one way to
do this easily).
* [PugiXML](http://pugixml.org/) >= 1.8 (we have tested through 1.13).
* [PugiXML](http://pugixml.org/)
* (optional) [Partio](https://www.disneyanimation.com/technology/partio.html)
If it is not found at build time, the OSL `pointcloud` functions will not
be operative.
@@ -65,8 +64,8 @@ NEW or CHANGED dependencies since the last major release are **bold**.
* Python >= 2.7 (tested against 2.7, 3.7, 3.8, 3.9, 3.10)
* pybind11 >= 2.4.2 (Tested through 2.10)
* NumPy
* (optional) Qt5 >= 5.6 or Qt6 (tested Qt5 through 5.15 and Qt6 through 6.4).
If not found at build time, the `osltoy` application will be disabled.
* (optional) Qt >= 5.6 (tested through 5.15). If not found at build time,
the `osltoy` application will be disabled.
+2 -5
View File
@@ -209,10 +209,7 @@ ifneq (${BUILD_MISSING_DEPS},)
endif
ifneq (${USE_OPTIX},)
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX:BOOL=${USE_OPTIX}
endif
ifneq (${OSL_USE_OPTIX},)
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX:BOOL=${OSL_USE_OPTIX}
MY_CMAKE_FLAGS += -DUSE_OPTIX:BOOL=${USE_OPTIX}
endif
ifneq (${USE_PYTHON},)
@@ -400,7 +397,7 @@ help:
@echo " USE_SIMD=arch Build with SIMD support (comma-separated choices:"
@echo " 0, sse2, sse3, ssse3, sse4.1, sse4.2, f16c,"
@echo " avx, avx2, avx512f)"
@echo " OSL_USE_OPTIX=1 Build the OptiX test renderer"
@echo " USE_OPTIX=1 Build the OptiX test renderer"
@echo " USE_BATCHED=targets Build batched SIMD execution of shaders for (comma-separated choices:"
@echo " 0, b8_AVX, b8_AVX2, b8_AVX2_noFMA,"
@echo " b8_AVX512, b8_AVX512_noFMA,"
+16 -22
View File
@@ -225,7 +225,8 @@ adding OSL support):
* [Blender/Cycles](https://docs.blender.org/manual/en/dev/render/shader_nodes/osl.html)
* [Chaos Group: V-Ray](https://www.chaosgroup.com/)
* [Pixar: PhotoRealistic RenderMan RIS](https://renderman.pixar.com)
* Isotropix: [Clarisse iFX](https://www.isotropix.com/products/clarisse/ifx) / [Clarisse BUiLDER](https://www.isotropix.com/products/clarisse/builder) / [Angie](https://www.isotropix.com/products/angie)
* [Isotropix: Clarisse](http://www.isotropix.com/clarisse)
* [Isotropix: Angie](http://www.isotropix.com/angie)
* [Autodesk Beast](http://www.autodesk.com/products/beast/overview)
* [Appleseed](http://appleseedhq.net)
* [Animal Logic: Glimpse renderer](https://www.fxguide.com/featured/a-glimpse-at-animal-logic/)
@@ -389,9 +390,8 @@ Films using OSL (grouped by year of release date):
Last Night in Soho,
Ghostbusters: Afterlife,
Spider-Man 3: No Way Home,
Matrix Resurrections,
Sing 2
* **(2022)**
Matrix Resurrections
* **(2022 / upcoming)**
Hotel Transylvania 4: Transformania,
Death on the Nile,
Uncharted,
@@ -404,15 +404,11 @@ Films using OSL (grouped by year of release date):
Thor: Love and Thunder,
The Sea Beast,
DC League of Super Pets,
Minions: Rise of Gru,
Bullet Train,
Slumberland,
Glass Onion
* **(2023 / upcoming)**
Ant-Man and the Wasp: Quantumania,
...
Building and Installation
-------------------------
@@ -485,20 +481,18 @@ The current project leadership is documented in the
Many people have contributed features, bug fixes, and other changes to OSL
over the years: Steve Agland, Shane Ambler, Martijn Berger, Farchad
Bidgolirad, Nicholas Bishop, Solomon Boulos, Stefan Bruens, Stefan Büttner,
Matthaus G. Chajdas, Clark Chen, Alejandro Conty, Damien Courtois, Dieter De
Baets, Thomas Dinges, Daniel Dresser, Mads Drøschler, Peter Ellerington, Luke
Emrose, Louis Feng, Mark Final, Henri Fousse, Stephen Friedman, Syoyo Fujita,
Tim Grant, Larry Gritz, Nicolas Guiard, Euan Haahr, Derek Haase, Sven-Hendrik
Haase, John Haddon, Niklas Harrysson, Daniel Heckenberg, Chris Hellmuth,
Adrien Herubel, Dan Horák, Thiago Ize, Matt Johnson, Ronan Keryell, Chris
Matthaus G. Chajdas, Clark Chen, Alejandro Conty, Dieter De Baets, Thomas
Dinges, Mads Drøschler, Luke Emrose, Louis Feng, Mark Final, Henri Fousse,
Stephen Friedman, Syoyo Fujita, Tim Grant, Larry Gritz, Nicolas Guiard, Euan
Haahr, Derek Haase, Sven-Hendrik Haase, John Haddon, Niklas Harrysson, Daniel
Heckenberg, Adrien Herubel, Thiago Ize, Matt Johnson, Ronan Keryell, Chris
Kulla, Elvic Liang, Max Liani, Adam Martinez, John Mertic, Bastien Montagne,
Steena Monteiro, Patrick Mours, Alexis Oblet, Erich Ocean, Mikko Ohtamaa, Jino
Park, Alexei Pawlow, Jay Reynolds, Declan Russell, Benoit Ruiz, Patrick
Scheibe, Alex Schworer, Jonathan Scruggs, Sergey Sharybin, Mark Sisson, Sandip
Shukla, Cliff Stein, Stephan Steinbach, Luya Tshimbalanga, Esteban Tovagliari,
Brecht Van Lommel, Alexander von Knorring, Alex Wells, Roman Zulak. (Listed
alphabetically; if we've left anybody out, it is inadvertent, please let us
know.)
Steena Monteiro, Alexis Oblet, Erich Ocean, Mikko Ohtamaa, Jino Park, Alexei
Pawlow, Jay Reynolds, Declan Russell, Benoit Ruiz, Patrick Scheibe, Alex
Schworer, Jonathan Scruggs, Sergey Sharybin, Sandip Shukla, Cliff Stein,
Stephan Steinbach, Luya Tshimbalanga, Esteban Tovagliari, Brecht Van Lommel,
Alexander von Knorring, Alex Wells, Roman Zulak. (Listed alphabetically; if
we've left anybody out, it is inadvertent, please let us know.)
We cannot possibly express sufficient gratitude to the managers at Sony
Pictures Imageworks who allowed this project to proceed, supported it
+7 -11
View File
@@ -33,7 +33,7 @@ endif # endif ${SP_OS}
MY_CMAKE_FLAGS += -DSP_OS=${SP_OS}
MY_CMAKE_FLAGS += -DSPI_COMPILER_PLATFORM=${SPI_COMPILER_PLATFORM}
MY_CMAKE_FLAGS += -DOSL_SITE:STRING=spi
MY_CMAKE_FLAGS += -DEXTRA_CPP_ARGS:STRING="-DOSL_SPI=1" -DOSL_SITE:STRING=spi
MY_CMAKE_FLAGS += -DSPI_TESTS=1
MY_CMAKE_FLAGS += -DOSL_NAMESPACE_INCLUDE_PATCH=1
REZ_PACKAGE_ROOT ?= /shots/spi/home/software/packages
@@ -147,14 +147,14 @@ ifeq (${SP_OS}, rhel7)
endif
# Cuda/OptiX
OSL_USE_OPTIX ?= 1
USE_OPTIX ?= 1
CUDA_VERSION ?= 11.1.1
OPTIX_VERSION ?= 7.2.0
# CUDA_TOOLKIT_ROOT_DIR = $(shell rez-env -b cuda-${CUDA_VERSION} ${SPI_COMPILER_PLATFORM} -c "echo '$CUDA_TOOLKIT_ROOT'")
CUDA_TOOLKIT_ROOT_DIR ?= /shots/spi/home/lib/arnold/rhel7/cuda_${CUDA_VERSION}
OptiX_ROOT ?= /shots/spi/home/lib/arnold/rhel7/optix_${OPTIX_VERSION}
OPTIXHOME = ${OptiX_ROOT}
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX=${OSL_USE_OPTIX} \
MY_CMAKE_FLAGS += -DUSE_OPTIX=${USE_OPTIX} \
-DCUDA_TOOLKIT_ROOT_DIR=${CUDA_TOOLKIT_ROOT_DIR} \
-DCUDA_EXTRA_LIBS=${CUDA_EXTRA_LIBS} \
-DOPTIXHOME=${OPTIXHOME} -DOPTIX_EXTRA_LIBS=lzma
@@ -189,10 +189,6 @@ else ifeq (${platform}, macosx)
MY_CMAKE_FLAGS += \
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@15/bin/clang \
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@15/bin/clang++
else ifeq (${COMPILER},clang16)
MY_CMAKE_FLAGS += \
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@16/bin/clang \
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@16/bin/clang++
else ifeq (${COMPILER},clang)
MY_CMAKE_FLAGS += -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
else ifeq (${COMPILER},gcc)
@@ -200,13 +196,13 @@ else ifeq (${platform}, macosx)
else ifeq (${COMPILER},)
# default compiler is clang, taken from the LLVM directory
MY_CMAKE_FLAGS += \
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
else ifeq (${COMPILER},llvm)
# "llvm" means "use the clang from our llvm"
MY_CMAKE_FLAGS += \
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
endif
# end generic OSX
+3
View File
@@ -23,3 +23,6 @@ sonar.exclusions=src/include/OSL/Imath/*.h,src/build-scripts/*
# C/C++ analyzer properties
sonar.cfamily.build-wrapper-output=build/bw_output
sonar.cfamily.gcov.reportsPath=_coverage
sonar.cfamily.cache.enabled=true
sonar.cfamily.cache.path=/tmp/sonarcache
+1 -1
View File
@@ -14,7 +14,7 @@ uname
if [[ `uname` == "Linux" ]] ; then
LLVM_VERSION=${LLVM_VERSION:=14.0.0}
LLVM_VERSION=${LLVM_VERSION:=13.0.0}
LLVM_INSTALL_DIR=${LLVM_INSTALL_DIR:=${PWD}/llvm-install}
if [[ "$GITHUB_WORKFLOW" != "" ]] ; then
LLVM_DISTRO_NAME=${LLVM_DISTRO_NAME:=ubuntu-18.04}
+1
View File
@@ -61,6 +61,7 @@ echo "uname -a: " `uname -a`
echo "uname -m: " `uname -m`
echo "uname -s: " `uname -s`
echo "uname -n: " `uname -n`
echo "nproc " `nproc`
pwd
ls
env | sort
+6 -11
View File
@@ -18,8 +18,8 @@ if [[ "$ASWF_ORG" != "" ]] ; then
#ls /etc/yum.repos.d
sudo /usr/bin/yum install -y giflib giflib-devel && true
# sudo /usr/bin/yum install -y ffmpeg ffmpeg-devel && true
sudo yum install -y giflib giflib-devel && true
# sudo yum install -y ffmpeg ffmpeg-devel && true
if [[ "${CONAN_LLVM_VERSION}" != "" ]] ; then
mkdir conan
@@ -42,7 +42,7 @@ if [[ "$ASWF_ORG" != "" ]] ; then
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" || "$CXX" == "icpx" || "$CC" == "icx" || "$USE_ICX" != "" ]] ; then
sudo cp src/build-scripts/oneAPI.repo /etc/yum.repos.d
sudo /usr/bin/yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0-3768
sudo yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0-3768
# Because multiple (possibly newer) versions of oneAPI may be installed,
# use a config file to specify compiler and tbb versions
# NOTE: oneAPI components have independent version numbering.
@@ -61,7 +61,7 @@ if [[ "$ASWF_ORG" != "" ]] ; then
else
# Using native Ubuntu runner
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
time sudo apt-get update
time sudo apt-get -q install -y \
@@ -73,13 +73,8 @@ else
libpugixml-dev \
libopencolorio-dev
if [[ "${QT_VERSION:-5}" == "5" ]] ; then
time sudo apt-get -q install -y \
qt5-default || /bin/true
elif [[ "${QT_VERSION}" == "6" ]] ; then
time sudo apt-get -q install -y \
qt6-base-dev || /bin/true
fi
time sudo apt-get -q install -y \
qt5-default || /bin/true
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu:$CMAKE_PREFIX_PATH
+6 -8
View File
@@ -19,7 +19,6 @@ if [[ `which brew` == "" ]] ; then
exit 1
fi
set -ex
if [[ "$DO_BREW_UPDATE" != "" ]] ; then
brew update >/dev/null
@@ -31,21 +30,20 @@ brew list --versions
brew install --display-times -q gcc ccache cmake ninja boost || true
brew link --overwrite gcc
brew install --display-times -q python@${PYTHON_VERSION} || true
# brew unlink python@2.7 || true
# brew unlink python@3.8 || true
# brew unlink python@3.9 || true
brew unlink python@2.7 || true
brew unlink python@3.8 || true
brew unlink python@3.9 || true
brew unlink python@3.10 || true
brew link --overwrite --force python@${PYTHON_VERSION} || true
brew upgrade --display-times -q cmake || true
brew install --display-times -q imath openexr
brew install --display-times -q ilmbase openexr
#brew install --display-times -q freetype
brew install --display-times -q --overwrite --force opencolorio || true
brew install --display-times -q partio pugixml
brew install --display-times -q opencolorio partio pugixml
brew install --display-times -q pybind11 numpy || true
brew install --display-times -q tbb || true
brew install --display-times -q flex bison
brew install --display-times -q llvm${LLVMBREWVER}
brew install --display-times -q qt${QT_BREW_VERSION}
brew install --display-times -q qt
echo ""
echo "After brew installs:"
+6 -6
View File
@@ -121,11 +121,11 @@ endif ()
# give more fine-grained control for hiding symbols, because sometimes
# dependent libraries may not be well behaved and need extra hiding.
#
set (CMAKE_CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
set (CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
option (VISIBILITY_INLINES_HIDDEN "Hide symbol visibility of inline functions" ON)
set (VISIBILITY_MAP_FILE "${PROJECT_SOURCE_DIR}/src/build-scripts/hidesymbols.map" CACHE FILEPATH "Visibility map file")
set (CMAKE_C_VISIBILITY_PRESET ${CMAKE_CXX_VISIBILITY_PRESET})
if (${CMAKE_CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
set (C_VISIBILITY_PRESET ${CXX_VISIBILITY_PRESET})
if (${CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND
(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU"))
# Linux/FreeBSD/Hurd: also hide all the symbols of dependent libraries
@@ -342,17 +342,17 @@ set (USE_BATCHED "" CACHE STRING "Build batched SIMD shader execution for (0, b8
option (VEC_REPORT "Enable compiler's reporting system for vectorization" OFF)
set (BATCHED_SUPPORT_DEFINES "")
set (BATCHED_TARGET_LIBS "")
set (OSL_BUILD_BATCHED 0)
set (BUILD_BATCHED False)
if (NOT USE_BATCHED STREQUAL "")
message (STATUS "Compiling with batched SIMD targets ${USE_BATCHED}")
if (NOT USE_BATCHED STREQUAL "0")
set (OSL_BUILD_BATCHED 1)
set (BUILD_BATCHED 1)
string (REPLACE "," ";" BATCHED_TARGET_LIST ${USE_BATCHED})
foreach (batched_target ${BATCHED_TARGET_LIST})
if (VERBOSE)
message (STATUS "BATCHED target: ${batched_target}")
endif ()
list (APPEND BATCHED_SUPPORT_DEFINES "__OSL_SUPPORTS_${batched_target}")
set (BATCHED_SUPPORT_DEFINES ${BATCHED_SUPPORT_DEFINES} "__OSL_SUPPORTS_${batched_target}")
endforeach()
else ()
message (STATUS "Compiling with NO batched SIMD targets, USE_BATCHED=0")
-6
View File
@@ -21,12 +21,6 @@ function ( NVCC_COMPILE cuda_src extra_headers ptx_generated extra_nvcc_args )
list (TRANSFORM OpenImageIO_INCLUDES PREPEND -I
OUTPUT_VARIABLE ALL_OpenImageIO_INCLUDES)
if (${LLVM_VERSION} VERSION_GREATER_EQUAL 15.0)
# Until we fully support opaque pointers, we need to disable
# them when using LLVM 15.
list (APPEND LLVM_COMPILE_FLAGS -Xclang -no-opaque-pointers)
endif ()
add_custom_command ( OUTPUT ${cuda_ptx}
COMMAND ${CUDA_NVCC_EXECUTABLE}
"-I${OPTIX_INCLUDES}"
+38 -54
View File
@@ -115,7 +115,6 @@ checked_find_package (pugixml REQUIRED
# LLVM library setup
checked_find_package (LLVM REQUIRED
VERSION_MIN 9.0
VERSION_MAX 15.9
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES)
# ensure include directory is added (in case of non-standard locations
include_directories (BEFORE SYSTEM "${LLVM_INCLUDES}")
@@ -145,19 +144,6 @@ if (LLVM_VERSION VERSION_GREATER_EQUAL 15.0
"If you are using LLVM 15 or higher, you should also use clang version "
"15 or higher, or you may get build errors.${ColorReset}\n")
endif ()
if (LLVM_VERSION VERSION_GREATER_EQUAL 16.0)
message (ERROR "${ColorYellow}OSL is not yet compatible with LLVM 16.${ColorReset}\n")
if (CMAKE_CXX_STANDARD VERSION_LESS 17)
message (WARNING "${ColorYellow}LLVM 16+ requires C++17 or higher. "
"Please set CMAKE_CXX_STANDARD to 17 or higher.${ColorReset}\n")
endif ()
if (CMAKE_COMPILER_IS_GNUCC AND (GCC_VERSION VERSION_LESS 7.0))
message (WARNING "${ColorYellow}LLVM 16+ requires gcc 7.0 or higher.${ColorReset}\n")
endif ()
if (CMAKE_COMPILER_IS_CLANG AND (CLANG_VERSION_STRING VERSION_LESS 5.0))
message (WARNING "${ColorYellow}LLVM 16+ requires clang 5.0 or higher.${ColorReset}\n")
endif ()
endif ()
checked_find_package (partio)
@@ -167,61 +153,58 @@ find_python ()
# Qt -- used for osltoy
set (qt5_modules Core Gui Widgets)
if (OPENGL_FOUND)
list (APPEND qt5_modules OpenGL)
endif ()
option (USE_QT "Use Qt if found" ON)
if (USE_QT)
checked_find_package (Qt6 COMPONENTS Core Gui Widgets OpenGLWidgets)
if (NOT Qt6_FOUND)
checked_find_package (Qt5 COMPONENTS Core Gui Widgets OpenGL)
endif ()
if (NOT Qt5_FOUND AND NOT Qt6_FOUND AND APPLE)
message (STATUS " If you think you installed qt with Homebrew and it still doesn't work,")
message (STATUS " try: export PATH=/usr/local/opt/qt/bin:$PATH")
endif ()
checked_find_package (Qt5 COMPONENTS ${qt5_modules})
if (USE_QT AND NOT Qt5_FOUND AND APPLE)
message (STATUS " If you think you installed qt5 with Homebrew and it still doesn't work,")
message (STATUS " try: export PATH=/usr/local/opt/qt5/bin:$PATH")
endif ()
# CUDA setup
if (OSL_USE_OPTIX)
if (USE_LLVM_BITCODE)
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
endif ()
if (USE_CUDA OR USE_OPTIX)
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
endif ()
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
endif ()
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
endif ()
checked_find_package (CUDA REQUIRED
VERSION_MIN 8.0
PRINT CUDA_INCLUDES)
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
include_directories (BEFORE "${CUDA_INCLUDES}")
checked_find_package (CUDA REQUIRED
VERSION_MIN 8.0
PRINT CUDA_INCLUDES)
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
include_directories (BEFORE "${CUDA_INCLUDES}")
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
if (NOT ${nvptx_index} GREATER -1)
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
endif()
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
if (NOT ${nvptx_index} GREATER -1)
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
endif()
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
find_library(cuda_lib NAMES cudart
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
REQUIRED)
set(CUDA_LIBRARIES ${cuda_lib})
find_library(cuda_lib NAMES cudart
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
REQUIRED)
set(CUDA_LIBRARIES ${cuda_lib})
# testrender & testshade need libnvrtc
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
find_library(nvrtc_lib NAMES nvrtc
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
REQUIRED)
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
# testrender & testshade need libnvrtc
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
find_library(nvrtc_lib NAMES nvrtc
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
REQUIRED)
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
endif()
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
endif()
# OptiX setup
if (OSL_USE_OPTIX AND OSL_BUILD_TESTS)
if (USE_OPTIX)
checked_find_package (OptiX REQUIRED
VERSION_MIN 7.0)
include_directories (BEFORE "${OPTIX_INCLUDES}")
@@ -236,6 +219,7 @@ if (OSL_USE_OPTIX)
target_compile_definitions (${TARGET} PRIVATE "-DPTX_PATH=\"${OSL_PTX_INSTALL_DIR}\"")
target_link_libraries (${TARGET} PRIVATE ${CUDA_LIBRARIES} ${CUDA_EXTRA_LIBS} ${OPTIX_LIBRARIES} ${OPTIX_EXTRA_LIBS})
endfunction()
else ()
function (osl_optix_target TARGET)
endfunction()
+2 -8
View File
@@ -23,13 +23,7 @@
# try to find llvm-config, with a specific version if specified
if (LLVM_DIRECTORY)
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
endif ()
if (LLVM_ROOT)
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_ROOT}/bin")
endif ()
if (DEFINED ENV{LLVM_ROOT})
list (APPEND LLVM_CONFIG_PATH_HINTS "$ENV{LLVM_ROOT}/bin")
set (LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
endif ()
list (APPEND LLVM_CONFIG_PATH_HINTS
"/usr/local/opt/llvm/${LLVM_VERSION}/bin/"
@@ -127,7 +121,7 @@ endif ()
foreach (COMPONENT clangFrontend clangDriver clangSerialization
clangParse clangSema clangAnalysis clangAST clangBasic
clangEdit clangLex clangSupport)
clangEdit clangLex)
find_library ( _CLANG_${COMPONENT}_LIBRARY
NAMES ${COMPONENT}
PATHS ${LLVM_LIB_DIR})
+6 -3
View File
@@ -20,9 +20,12 @@ macro (find_python)
# Attempt to find the desired version, but fall back to other
# additional versions.
set (_req REQUIRED)
if (PYTHON_VERSION)
list (APPEND _req EXACT)
unset (_req)
if (USE_PYTHON)
set (_req REQUIRED)
if (PYTHON_VERSION)
list (APPEND _req EXACT)
endif ()
endif ()
checked_find_package (Python ${PYTHON_VERSION}
${_req}
+10 -15
View File
@@ -71,10 +71,6 @@ macro (add_one_testsuite testname testsrcdir)
set_tests_properties (${testname} PROPERTIES LABELS render
PROCESSORS 4 COST 10 TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
endif ()
# For debug builds, render tests are very slow, so give them a longer timeout
if (${testname} MATCHES "render-" AND ${CMAKE_BUILD_TYPE} STREQUAL Debug)
set_tests_properties (${testname} PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
endif ()
# Some labeling for fun
if (${testname} MATCHES "^texture")
set_tests_properties (${testname} PROPERTIES LABELS texture
@@ -143,11 +139,14 @@ macro ( TESTSUITE )
add_one_testsuite ("${_testname}.opt" "${_testsrcdir}"
ENV TESTSHADE_OPT=2 )
endif ()
if (_testname MATCHES "render-" AND ${CMAKE_BUILD_TYPE} STREQUAL Debug)
set_tests_properties (${_testname} PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
endif ()
# When building for OptiX support, also run it in OptiX mode
# if there is an OPTIX marker file in the directory.
# If an environment variable $TESTSUITE_OPTIX is nonzero, then
# run all tests with OptiX, even if there's no OPTIX marker.
if (OSL_USE_OPTIX
if (USE_OPTIX
AND (EXISTS "${_testsrcdir}/OPTIX" OR test_all_optix OR _testname MATCHES "optix")
AND NOT EXISTS "${_testsrcdir}/NOOPTIX"
AND NOT EXISTS "${_testsrcdir}/NOOPTIX-FIXME"
@@ -162,7 +161,7 @@ macro ( TESTSUITE )
ENV TESTSHADE_OPT=2 TESTSHADE_OPTIX=1 )
endif ()
if (OSL_BUILD_BATCHED)
if (BUILD_BATCHED)
# When building for Batched support, also run it in Batched mode
# if there is an BATCHED marker file in the directory.
# If an environment variable $TESTSUITE_BATCHED is nonzero, then
@@ -237,8 +236,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-parameters closure-zero closure-conditional
color color-reg colorspace comparison
cellnoise closure closure-array color color-reg colorspace comparison
complement-reg compile-buffer compassign-reg
component-range
control-flow-reg connect-components
@@ -299,7 +297,6 @@ macro (osl_add_all_tests)
oslc-err-struct-dup oslc-err-struct-print
oslc-err-type-as-variable
oslc-err-unknown-ctr
oslc-literalfold
oslc-pragma-warnerr
oslc-warn-commainit
oslc-variadic-macro
@@ -311,8 +308,7 @@ macro (osl_add_all_tests)
pragma-nowarn
printf-reg
printf-whole-array
raytype raytype-reg raytype-specialized regex-reg
reparam reparam-arrays
raytype raytype-reg raytype-specialized regex-reg reparam
render-background render-bumptest
render-cornell render-furnace-diffuse
render-mx-furnace-burley-diffuse
@@ -326,7 +322,6 @@ macro (osl_add_all_tests)
render-mx-sheen
render-microfacet render-oren-nayar
render-uv render-veachmis render-ward
render-raytypes
select select-reg shaderglobals shortcircuit
smoothstep-reg
spline spline-reg splineinverse splineinverse-ident
@@ -356,7 +351,7 @@ macro (osl_add_all_tests)
transform transform-reg transformc transformc-reg trig trig-reg
typecast
unknown-instruction
userdata userdata-custom userdata-passthrough
userdata userdata-passthrough
vararray-connect vararray-default
vararray-deserialize vararray-param
vecctr vector vector-reg
@@ -388,7 +383,7 @@ macro (osl_add_all_tests)
endif()
# Only run pointcloud tests if Partio is found
if (partio_FOUND)
if (PARTIO_FOUND)
TESTSUITE ( pointcloud pointcloud-fold )
endif ()
@@ -398,7 +393,7 @@ macro (osl_add_all_tests)
endif ()
# Some regression tests have a lot of combinations and may need more time to finish
if (OSL_BUILD_BATCHED)
if (BUILD_BATCHED)
set_tests_properties (arithmetic-reg.regress.batched.opt
PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
set_tests_properties (transform-reg.regress.batched.opt
+34 -63
View File
@@ -2631,6 +2631,27 @@ and proceeds to the next iteration of the loop.
\section{Functions}
\label{sec:functions}
\subsection{Function calls}
\label{sec:syntax:functioncalls}
\index{function calls}
Function calls are very similar to C and related programming languages:
\begin{tabbing}
\hspace{0.5in} \= \hspace{0.3in} \= \kill
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf )} \\
\end{tabbing}
If the function returns a value (not \void), you may use its value as
an expression. It is fine to completely ignore the value of even
a non-\void function.
In \langname, all arguments are passed by reference. This generally
will not be noticeably different from C-style ``pass by value''
semantics, except if you pass the same variable as two separate
arguments to a function that modifies an argument's value.
\subsection{Function definitions}
\label{sec:syntax:functiondefinitions}
\index{functions!definitions}
@@ -2678,35 +2699,6 @@ passing an {\cf int} when the function expects a {\cf float}, or passing a
{\cf float} when the function expects a \color), and finally by trying to
match the return value to the type of variable the result is assigned to.
\subsection{Function calls}
\label{sec:syntax:functioncalls}
\index{function calls}
Function calls are very similar to C and related programming languages:
\begin{tabbing}
\hspace{0.5in} \= \hspace{0.3in} \= \kill
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf )} \\
\end{tabbing}
If the function returns a value (not \void), you may use its value as
an expression. It is fine to completely ignore the value of even
a non-\void function.
In \langname, all arguments are passed by reference. This generally
will not be noticeably different from C-style ``pass by value''
semantics, except if you pass the same variable as two separate
arguments to a function that modifies an argument's value.
Certain functions allow optional arguments to be passed.
Optional arguments are key-value pairs with the key passed as an
argument and the associated value passed as the subsequent argument:
\begin{tabbing}
\hspace{0.5in} \= \hspace{0.3in} \= \kill
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf ,} \emph{"optionalkey"} {\cf ,} \emph{optionalvalue} {\cf ,} ... {\cf )} \\
\end{tabbing}
\subsection{Operator overloading}
\label{sec:syntax:operatoroverloading}
\index{operator overloading}
@@ -4091,8 +4083,8 @@ are assigned to a \float or a \color (or type cast to one of those)
determines whether the texture lookup is a single channel or three
channels.
The 2D lookup coordinate(s) may be followed by optional key-value
arguments (see Section~\ref{sec:syntax:functioncalls}) that control the behavior of {\cf texture()}:
The 2D lookup coordinate(s) may be followed by optional token/value
arguments that control the behavior of {\cf texture()}:
\apiitem{"blur", <float>}
\vspace{12pt}
@@ -5607,7 +5599,7 @@ forms of the function with no object name, or if the object name is the
empty string \qkw{}, the renderer will first search
per-object attributes on the current object (or interpolated variables
with that name attached to the object), then if not found it will search
global scene-wide attributes.
searching global scene-wide attributes.
If the attribute is found and can be converted to the type of
\emph{destination}, the attribute's value will be stored in
@@ -5909,38 +5901,17 @@ view-dependence into shaders.
The return value is 0 if the ray missed all geometry, 1 if it hit
anything within the distance range.
The following optional key-value arguments
(see Section~\ref{sec:syntax:functioncalls}) can be passed:
Optional parameters include:
\apiitem{"mindist", <float>}
\vspace{12pt}
The minimum hit distance (default: 0).
The units of the {\cf "mindist"} and {\cf "maxdist"} are determined by the renderer
and are sometimes defined by the dir vector, which can lead to unexpected
behavior. So, generally, clearly written and portable shaders should pass
a unit length (see Section~\ref{sec:stdlib:geom}) dir vector.
\apiend
\vspace{-16pt}
\apiitem{"mindist", <float>}
\vspace{12pt}
The maximum hit distance (default: infinite).
\apiend
\vspace{-16pt}
\apiitem{"shade", <int>}
\vspace{12pt}
Defines whether objects hit will be shaded (default: 0).
\apiend
\vspace{-16pt}
\apiitem{"traceset", <string>}
\vspace{12pt}
An optional named set of objects to ray trace (if preceded by a `{\cf -}'
character, it means to exclude that set).
\apiend
\vspace{-16pt}
\begin{tabular}{p{1.2in} p{0.5in} p{3.2in}}
\qkw{mindist} & {\cf float} & Minimum hit distance (default: zero) \\
\qkw{maxdist} & {\cf float} & Maximum hit distance (default: infinite) \\
\qkw{shade} & {\cf int} & Whether objects hit will be shaded
(default: 0) \\
\qkw{traceset} & {\cf string} & An optional named set of objects to
ray trace (if preceded by a `{\cf -}'
character, it means to exclude that set).
\end{tabular}
Information about the closest object hit by the ray may be retrieved
using \\ {\cf getmessage("trace",...)} (see Section~\ref{sec:getmessage}).
+32 -35
View File
@@ -82,13 +82,12 @@ public:
/// Return a Mask with lanes set to true if ok, false if the named matrix
/// is not known.
virtual Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> wresult,
ustringhash from, Wide<const float> wtime)
ustring from, Wide<const float> wtime)
{
return Mask(false);
}
virtual Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
Wide<const ustringhash> wfrom,
Wide<const float> wtime);
Wide<const ustring> wfrom, Wide<const float> wtime);
virtual bool is_overridden_get_matrix_WmWsWf() const = 0;
@@ -98,12 +97,12 @@ public:
/// particular renderer may have a better technique and overload the
/// implementation.
virtual Mask get_inverse_matrix(BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult, ustringhash to,
Masked<Matrix44> wresult, ustring to,
Wide<const float> wtime);
virtual bool is_overridden_get_inverse_matrix_WmsWf() const = 0;
virtual Mask get_inverse_matrix(BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult,
Wide<const ustringhash> wto,
Wide<const ustring> wto,
Wide<const float> wtime);
virtual bool is_overridden_get_inverse_matrix_WmWsWf() const = 0;
@@ -125,23 +124,22 @@ public:
/// specified (object == ustring()), then the renderer should search *first*
/// for the attribute on the currently shaded object, and next, if
/// unsuccessful, on the currently shaded "scene".
virtual Mask get_attribute(BatchedShaderGlobals* bsg, ustringhash object,
ustringhash name, MaskedData wval)
virtual Mask get_attribute(BatchedShaderGlobals* bsg, ustring object,
ustring name, MaskedData wval)
{
return Mask(false);
}
/// Similar to get_attribute(); this method will fetch the 'index'
/// element of an attribute array.
virtual Mask get_array_attribute(BatchedShaderGlobals* bsg,
ustringhash object, ustringhash name,
int index, MaskedData wval)
virtual Mask get_array_attribute(BatchedShaderGlobals* bsg, ustring object,
ustring name, int index, MaskedData wval)
{
return Mask(false);
}
virtual bool get_attribute_uniform(BatchedShaderGlobals* bsg,
ustringhash object, ustringhash name,
ustring object, ustring name,
RefData val)
{
return false;
@@ -150,9 +148,8 @@ public:
/// Similar to get_attribute(); this method will fetch the 'index'
/// element of an attribute array.
virtual bool get_array_attribute_uniform(BatchedShaderGlobals* bsg,
ustringhash object,
ustringhash name, int index,
RefData val)
ustring object, ustring name,
int index, RefData val)
{
return false;
}
@@ -162,7 +159,7 @@ public:
/// as well. It is assumed the results are varying and returns Mask
// with its bit set to off if no user-data with the given name and type was
/// found.
virtual Mask get_userdata(ustringhash name, BatchedShaderGlobals* bsg,
virtual Mask get_userdata(ustring name, BatchedShaderGlobals* bsg,
MaskedData wval)
{
return Mask(false);
@@ -209,7 +206,7 @@ public:
/// error.
///
virtual Mask
texture(ustringhash filename, TextureSystem::TextureHandle* texture_handle,
texture(ustring filename, TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
Wide<const float> ws, Wide<const float> wt, Wide<const float> wdsdx,
@@ -243,7 +240,7 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual Mask texture3d(ustringhash filename,
virtual Mask texture3d(ustring filename,
TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options,
@@ -276,7 +273,7 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual Mask environment(ustringhash filename,
virtual Mask environment(ustring filename,
TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options,
@@ -303,12 +300,12 @@ public:
virtual TextureSystem::TextureHandle* resolve_udim_uniform(
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
float S, float T);
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
float T);
virtual void resolve_udim(BatchedShaderGlobals* bsg,
TexturePerthread* texture_thread_info,
ustringhash filename,
ustring filename,
TextureSystem::TextureHandle* texture_handle,
Wide<const float> wS, Wide<const float> wT,
Masked<TextureSystem::TextureHandle*> wresult);
@@ -316,8 +313,8 @@ public:
// Assumes any UDIM has been resolved already
virtual bool get_texture_info_uniform(
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
int subimage, ustringhash dataname, RefData val);
ustring filename, TextureSystem::TextureHandle* texture_handle,
int subimage, ustring dataname, RefData val);
/// Lookup nearest points in a point cloud. It will search for
@@ -410,25 +407,26 @@ public:
};
virtual void pointcloud_search(BatchedShaderGlobals* bsg,
ustringhash filename, const void* wcenter,
virtual void pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
const void* wcenter,
Wide<const float> wradius, int max_points,
bool sort, PointCloudSearchResults& results);
virtual bool is_overridden_pointcloud_search() const = 0;
virtual Mask pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
virtual Mask pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
Wide<const int[]> windices,
Wide<const int> wnum_points,
ustringhash attr_name, MaskedData wout_data);
Wide<const int> wnum_points, ustring attr_name,
MaskedData wout_data);
virtual bool is_overridden_pointcloud_get() const = 0;
virtual Mask
pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
Wide<const OSL::Vec3> wpos, int nattribs,
const ustring* attr_names, const TypeDesc* attr_types,
const void** pointers_to_wide_attr_value, Mask mask);
virtual Mask pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
Wide<const OSL::Vec3> wpos, int nattribs,
const ustring* attr_names,
const TypeDesc* attr_types,
const void** pointers_to_wide_attr_value,
Mask mask);
virtual bool is_overridden_pointcloud_write() const = 0;
/// Options for the trace call.
@@ -443,8 +441,7 @@ public:
Wide<const Vec3> wdRdy);
virtual void getmessage(BatchedShaderGlobals* bsg, Masked<int> wresult,
ustringhash source, ustringhash name,
MaskedData wval);
ustring source, ustring name, MaskedData wval);
// pointcloud_search is T.B.D.
-72
View File
@@ -1,72 +0,0 @@
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
#pragma once
#include <OSL/oslconfig.h>
OSL_NAMESPACE_ENTER
/// Wrapper class for holding a "device" pointer -- GPU or whatnot. It
/// provides protections so that the pointer cannot easily be accessed on the
/// host side, where presumably it would not be valid memory.
template<class T> class device_ptr {
public:
device_ptr() = default;
// Copy ctr from another device_ptr of the same type
device_ptr(const device_ptr& other) = default;
/// On device, device_ptr can construct from a pointer.
/// On host, it must be explicitly constructed -- use with caution.
#ifdef __CUDA_ARCH__
device_ptr(T* ptr) : m_ptr(ptr) {}
#else
explicit device_ptr(T* ptr) : m_ptr(ptr) {}
#endif
#ifdef __CUDA_ARCH__
/// On device, act as a pointer. None of these things are allowed on the
/// host.
T* operator->() const
{
return m_ptr;
}
T& operator*() const
{
return *m_ptr;
}
#endif
/// Extract the raw device-side pointer. Use with caution! On the host,
/// this will not point to valid memory.
T* d_get() const
{
return m_ptr;
}
/// Evaluate as bool is a null pointer check.
operator bool() const noexcept
{
return m_ptr != nullptr;
}
/// Reset the pointer to `dptr`, which must be a device-side raw pointer,
/// or null. Since this device_ptr is non-owning, any previous value is
/// simply overwritten.
void reset(T* dptr = nullptr)
{
m_ptr = dptr;
}
private:
T* m_ptr = nullptr; // underlying pointer, initializes to null
};
OSL_NAMESPACE_EXIT
+15
View File
@@ -6,6 +6,10 @@
#include <OSL/oslconfig.h>
#ifdef __CUDA_ARCH__
# include <optix.h>
#endif
// USAGE NOTES:
//
// To define a "standard" DeviceString, add a STRDECL to <OSL/strdecls.h>
@@ -15,10 +19,21 @@
OSL_NAMESPACE_ENTER
// Strings are handled differently in OptiX 6 vs OptiX 7.
//
// In OptiX 7+:
// Strings are not stored on the GPU at all. Strings are represented by
// their hash values which are computed at compile-time. Because of this,
// we have no access to either the strings' contents or their lengths.
//
// In OptiX 6:
// Strings are stored in a block of CUDA device memory. String variables hold a
// pointer to the start of the char array for each string. Each canonical string
// has a unique entry in the table, so two strings can be tested for equality by
// comparing their addresses.
//
// As a convenience, the ustring hash and the length of the string are also
// stored in the table, in the 16 bytes preceding the characters.
struct DeviceString {
#ifdef __CUDA_ARCH__
-6
View File
@@ -631,12 +631,6 @@ public:
/// llvm type.
llvm::Type* type_array(llvm::Type* type, int n);
/// Return the true if the llvm::Type is an array
bool is_type_array(llvm::Type* type);
/// Return the llvm::Type of element that the array_type is made up of
llvm::Type* element_type_of(llvm::Type* array_type);
/// Return an llvm::FunctionType that describes a function with the
/// given return types, parameter types (in a cspan), and whether it
/// uses varargs conventions.
+4 -123
View File
@@ -4,11 +4,6 @@
#pragma once
#cmakedefine01 OSL_USE_OPTIX
#cmakedefine01 OSL_BUILD_BATCHED
#define OSL_USE_BATCHED OSL_BUILD_BATCHED
#include <OSL/export.h>
#include <OSL/oslversion.h>
#include <OSL/platform.h>
@@ -67,6 +62,8 @@
OSL_NAMESPACE_ENTER
#define OSL_USE_BATCHED @BUILD_BATCHED@
/// Various compile-time defaults are defined here that could, in
/// principle, be redefined if you are using OSL in some particular
/// renderer that wanted things a different way.
@@ -136,101 +133,6 @@ fmtformat(const Str& fmt, Args&&... args)
/// OSL_USTRINGREP_IS_HASH will be 1 if the build-time option was enabled to
/// make the ustringrep be a ustringhash, rather than a ustring directly.
#cmakedefine01 OSL_USTRINGREP_IS_HASH
#if OSL_USTRINGREP_IS_HASH
/// ustringrep is the class we use to represent strings in the shader.
using ustringrep = ustringhash;
#else
/// ustringrep is the class we use to represent strings in the shader.
using ustringrep = ustring;
#endif
#if OSL_USTRINGREP_IS_HASH
/// ustring_pod is the type we use to pass string data in llvm function calls.
using ustring_pod = size_t;
#else
/// ustring_pod is the type we use to pass string data in llvm function calls.
using ustring_pod = const char*;
#endif
/// Convenience function to convert to a ustring.
inline ustring
ustring_from(ustringhash h)
{
return ustring::from_hash(h.hash());
}
/// Convenience function to convert to a ustring.
inline ustring
ustring_from(ustring u)
{
return u;
}
/// Convenience function to convert to a ustring.
inline ustring
ustring_from(string_view s)
{
return ustring(s);
}
/// Convenience function to convert to a ustringhash.
inline ustringhash
ustringhash_from(ustringhash u)
{
return u;
}
/// Convenience function to convert to a ustringhash.
inline ustringhash
ustringhash_from(ustring u)
{
return u.uhash();
}
/// Convenience function to convert to a ustringrep.
inline ustringrep
ustringrep_from(ustringhash h)
{
#if OSL_USTRINGREP_IS_HASH
return h;
#else
return ustring::from_hash(h.hash());
#endif
}
/// Convenience function to convert to a ustringrep.
inline ustringrep
ustringrep_from(ustring u)
{
#if OSL_USTRINGREP_IS_HASH
return u.hash();
#else
return u;
#endif
}
/// Convenience function to convert to a ustringrep.
inline ustringrep
ustringrep_from(string_view s)
{
ustring u(s);
#if OSL_USTRINGREP_IS_HASH
return u.hash();
#else
return u;
#endif
}
// N.B. SymArena is not really "configuration", but we cram it here for
// lack of a better home.
@@ -241,7 +143,6 @@ enum class SymArena {
Heap, // Belongs to context heap
Outputs, // Belongs to output arena
UserData, // UserData arena
Interactive, // Interactively edited variables
// ShaderGlobals, // RESERVED
};
@@ -328,8 +229,7 @@ OSL_NAMESPACE_EXIT
namespace std { // not necessary in C++17, then we can just say std::hash
#ifndef OIIO_USTRING_HAS_STDHASH
// Not a new enough OIIO to define std::hash<ustring>, so we'll do it.
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
// Not a new enough OIIO to define std::hash<ustring>, so we'll do it
template<> struct hash<OSL::ustring> {
std::size_t operator()(OSL::ustring u) const noexcept { return u.hash(); }
};
@@ -343,8 +243,7 @@ template<> struct hash<OSL::ustringhash> {
};
#endif
// Not necessary once minimum OIIO defines operator< for ustringhash.
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
// Not necessary once minimum OIIO defines operator< for ustringhash
template<> struct less<OSL::ustringhash> {
OSL_HOSTDEVICE constexpr bool operator()(OSL::ustringhash u,
OSL::ustringhash v) const noexcept
@@ -353,21 +252,3 @@ template<> struct less<OSL::ustringhash> {
}
};
} // namespace std
#ifndef OIIO_HAS_USTRINGHASH_FORMATTER
// OIIO is too old to have fmt custom formatter for ustringhash.
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
FMT_BEGIN_NAMESPACE
template<> struct formatter<OIIO::ustringhash> : formatter<fmt::string_view, char> {
template<typename FormatContext>
auto format(const OIIO::ustringhash& h, FormatContext& ctx)
-> decltype(ctx.out()) const
{
OIIO::ustring u(h);
return formatter<fmt::string_view, char>::format({ u.data(), u.size() },
ctx);
}
};
FMT_END_NAMESPACE
#endif
+15 -131
View File
@@ -111,67 +111,6 @@ public:
/// Parameter property hint bitflag values. The enum values must be powers of
/// two so they can be combined with bitwise operators.
enum class ParamHints : uint32_t {
/// `none`: No special properties
none = 0,
/// `interpolated`: This parameter may be an interpolated "user data" or
/// "geometric primitive" variable, and so may take on different values at
/// different points on the surface or on different objects that share the
/// same material. Any optimization of the shader should take this into
/// account.
interpolated = 1,
/// `interactive`: Parameter may have its value interactively modified by
/// subsequent ReParameter calls. Any optimization of the shader should
/// take this into account.
interactive = 2
};
inline constexpr ParamHints
operator|(ParamHints a, ParamHints b)
{
return static_cast<ParamHints>(static_cast<int>(a) | static_cast<int>(b));
}
inline constexpr ParamHints
operator&(ParamHints a, ParamHints b)
{
return static_cast<ParamHints>(static_cast<int>(a) & static_cast<int>(b));
}
inline ParamHints&
operator|=(ParamHints& a, ParamHints b)
{
a = a | b;
return a;
}
inline ParamHints&
operator&=(ParamHints& a, ParamHints b)
{
a = a & b;
return a;
}
inline constexpr ParamHints
operator~(ParamHints a)
{
return static_cast<ParamHints>(~static_cast<int>(a));
}
inline ParamHints&
set(ParamHints& a, ParamHints b, bool on = true)
{
if (on)
a |= b;
else
a &= ~b;
return a;
}
class OSLEXECPUBLIC ShadingSystem {
public:
ShadingSystem(RendererServices* renderer = NULL,
@@ -234,7 +173,7 @@ public:
/// int lazyerror Run layers lazily even if they have error
/// ops after optimization (1).
/// int lazy_userdata Retrieve userdata lazily (0).
/// int userdata_isconnected Should interpolated=1 params (that may
/// int userdata_isconnected Should lockgeom=0 params (that may
/// receive userdata) return true from
/// isconnected()? (0)
/// int greedyjit Optimize and compile all shaders up front,
@@ -261,7 +200,6 @@ public:
/// that don't specify it (1). Lockgeom
/// means a param CANNOT be overridden by
/// interpolated geometric parameters.
/// This option is slated for deprecation.
/// int countlayerexecs Add extra code to count total layers run.
/// int allow_shader_replacement Allow shader to be specified more than
/// once, replacing former definition.
@@ -489,15 +427,12 @@ public:
/// 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, or with
/// multiple different types, it will
/// is requested in multiple scopes, it will
/// appear in the array multiple times - once for
/// each scope/type in which is is queried.
/// 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.
/// ptr attribute_types Retrieves a pointer to the array of
/// TypeDesc describing the attributes.
/// int unknown_attributes_needed Nonzero if additional attributes may be
/// needed, whose names will not be known
/// until the shader actually runs.
@@ -508,15 +443,6 @@ public:
/// string entry_layers[] List of entry point layers.
/// string pickle Retrieves a serialized representation
/// of the shader group declaration.
/// int llvm_groupdata_size Size of the GroupData struct.
/// ptr interactive_params Pointer to the memory block containing
/// host-side interactive parameter values
/// for this shader group.
/// ptr device_interactive_params
/// Pointer to the memory block containing
/// device-side interactive parameter values
/// for this shader group.
///
/// Note: the attributes referred to as "string" are actually on the app
/// side as ustring or const char* (they have the same data layout), NOT
/// std::string!
@@ -604,50 +530,15 @@ public:
bool ShaderGroupEnd(ShaderGroup& group);
/// Set a parameter of the next shader that will be added to the group,
/// optionally setting or overriding properties with the `hints` argument.
/// Individual `hints` bits are defined and documented by the ParamHints
/// enum class.
/// optionally setting the 'lockgeom' metadata for that parameter
/// (despite how it may have been set in the shader). If lockgeom is
/// false, it means that this parameter should NOT be considered locked
/// against changes by the geometry, and therefore the shader should not
/// optimize assuming that the instance value (the 'val' specified by
/// this call) is a constant.
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
const void* val, ParamHints hints = ParamHints::none);
/// DEPRECATED(1.13) Parameter() call: instead of a full ParamHints
/// argument, there is just a bool `lockgeom` that default to true, and
/// when set to false is the same thing as setting
/// `ParamHints::interpolated`.
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
const void* val, bool lockgeom)
{
return Parameter(group, name, t, val,
lockgeom ? ParamHints::none
: ParamHints::interpolated);
}
const void* val, bool lockgeom = true);
// Shortcuts for param passing a single int, float, or string.
bool Parameter(ShaderGroup& group, string_view name, int val,
ParamHints hints = ParamHints::none)
{
return Parameter(group, name, TypeDesc::INT, &val, hints);
}
bool Parameter(ShaderGroup& group, string_view name, float val,
ParamHints hints = ParamHints::none)
{
return Parameter(group, name, TypeDesc::FLOAT, &val, hints);
}
bool Parameter(ShaderGroup& group, string_view name, const std::string& val,
ParamHints hints = ParamHints::none)
{
const char* s = val.c_str();
return Parameter(group, name, TypeDesc::STRING, &s, hints);
}
bool Parameter(ShaderGroup& group, string_view name, ustring val,
ParamHints hints = ParamHints::none)
{
return Parameter(group, name, TypeDesc::STRING, (const char**)&val,
hints);
}
// DEPRECATED(1.13): use the version above that takes ParamHints.
// This is the old version that takes `bool lockgeom`.
bool Parameter(ShaderGroup& group, string_view name, int val,
bool lockgeom = true)
{
@@ -698,8 +589,10 @@ public:
/// Replace a parameter value in a previously-declared shader group.
/// This is meant to called after the ShaderGroupBegin/End, but will
/// fail if the shader has already been irrevocably optimized/compiled,
/// unless the particular parameter is marked as either interpolated=1
/// or interactive=1.
/// unless the particular parameter is marked as lockgeom=0 (which
/// indicates that it's a parameter that may be overridden by the
/// geometric primitive). This call gives you a way of changing the
/// instance value, even if it's not a geometric override.
bool ReParameter(ShaderGroup& group, string_view layername,
string_view paramname, TypeDesc type, const void* val);
// Shortcuts for param passing a single int, float, or string.
@@ -735,22 +628,13 @@ public:
// above that take an explicit `ShaderGroup&`, which are thread-safe
// and re-entrant.
bool Parameter(string_view name, TypeDesc t, const void* val,
ParamHints hints = ParamHints::none);
bool lockgeom = true);
bool Shader(string_view shaderusage, string_view shadername,
string_view layername);
bool ConnectShaders(string_view srclayer, string_view srcparam,
string_view dstlayer, string_view dstparam);
bool ShaderGroupEnd(void);
// DEPRECATED(1.13): use the version above that takes ParamHints.
// This is the old version that takes `bool lockgeom`.
bool Parameter(string_view name, TypeDesc t, const void* val, bool lockgeom)
{
return Parameter(name, t, val,
lockgeom ? ParamHints::none
: ParamHints::interpolated);
}
/// Create a per-thread data needed for shader execution. It's very
/// important for the app to never use a PerThreadInfo from more than
/// one thread (and probably a good idea allocate only one PerThreadInfo
+297 -292
View File
File diff suppressed because it is too large Load Diff
-58
View File
@@ -18,14 +18,10 @@
#pragma once
#include <cstring>
#include <memory>
#include <OSL/oslversion.h>
#if defined(__x86_64__) && !defined(__CUDA_ARCH__)
# include <x86intrin.h>
#endif
/////////////////////////////////////////////////////////////////////////
// Detect which compiler and version we're using
@@ -503,60 +499,6 @@
OSL_NAMESPACE_ENTER
/// Standards-compliant bit cast of two equally sized types. This is used
/// equivalently to C++20 std::bit_cast, but it works prior to C++20 and
/// it has the right decorators to work with Cuda.
/// @version 1.13.2
template <typename To, typename From>
OSL_FORCEINLINE OSL_HOSTDEVICE To bitcast(const From& src) noexcept {
// NOTE: this is the only standards compliant way of doing this type of casting,
// luckily the compilers we care about know how to optimize away this idiom.
static_assert(sizeof(From) == sizeof(To),
"bit_cast must be between objects of the same size");
To dst;
memcpy((void*)&dst, &src, sizeof(From));
return dst;
}
#if defined(__x86_64__) && !defined(__CUDA_ARCH__) && \
(defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) \
|| OSL_CLANG_VERSION >= 100000 || OSL_APPLE_CLANG_VERSION >= 130000)
// On x86/x86_64 for certain compilers we can use Intel CPU intrinsics for
// some common bitcast cases that might be even more understandable to the
// compiler and generate better code without its getting confused about the
// memcpy in the general case. We're a bit conservative with the compiler
// version checks here, it may be that some earlier versions support these
// intrinsics.
template<> OSL_FORCEINLINE uint32_t bitcast<uint32_t, float>(const float& val) noexcept {
return static_cast<uint32_t>(_castf32_u32(val));
}
template<> OSL_FORCEINLINE int32_t bitcast<int32_t, float>(const float& val) noexcept {
return static_cast<int32_t>(_castf32_u32(val));
}
template<> OSL_FORCEINLINE float bitcast<float, uint32_t>(const uint32_t& val) noexcept {
return _castu32_f32(val);
}
template<> OSL_FORCEINLINE float bitcast<float, int32_t>(const int32_t& val) noexcept {
return _castu32_f32(val);
}
template<> OSL_FORCEINLINE uint64_t bitcast<uint64_t, double>(const double& val) noexcept {
return static_cast<uint64_t>(_castf64_u64(val));
}
template<> OSL_FORCEINLINE int64_t bitcast<int64_t, double>(const double& val) noexcept {
return static_cast<int64_t>(_castf64_u64(val));
}
template<> OSL_FORCEINLINE double bitcast<double, uint64_t>(const uint64_t& val) noexcept {
return _castu64_f64(val);
}
template<> OSL_FORCEINLINE double bitcast<double, int64_t>(const int64_t& val) noexcept {
return _castu64_f64(val);
}
#endif
#if OSL_CPLUSPLUS_VERSION >= 20
using std::assume_aligned;
#else
+126 -152
View File
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
// clang-format off
#pragma once
@@ -11,13 +13,14 @@
OSL_NAMESPACE_ENTER
class RendererServices;
template<int WidthT> class BatchedRendererServices;
template<int WidthT>
class BatchedRendererServices;
class ShadingContext;
struct ShaderGlobals;
// Tags for polymorphic dispatch
template<int SimdWidthT> class WidthOf {
};
template <int SimdWidthT>
class WidthOf {};
/// Opaque pointer to whatever the renderer uses to represent a
@@ -46,7 +49,7 @@ public:
RendererServices(TextureSystem* texsys = NULL);
virtual ~RendererServices() {}
virtual ~RendererServices () { }
/// Given the name of a 'feature', return whether this RendererServices
/// supports it. Feature names include:
@@ -59,34 +62,28 @@ public:
/// support it, as long as the OSL runtime only uses that feature if the
/// supports("feature") says it's present, thus preserving source
/// compatibility.
virtual int supports(string_view feature) const { return false; }
virtual int supports (string_view feature) const { return false; }
/// Get the 4x4 matrix that transforms by the specified
/// transformation at the given time. Return true if ok, false
/// on error.
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform, float time)
{
return false;
}
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
TransformationPtr xform, float time) { return false; }
/// Get the 4x4 matrix that transforms by the specified
/// transformation at the given time. Return true if ok, false on
/// error. The default implementation is to use get_matrix and
/// invert it, but a particular renderer may have a better technique
/// and overload the implementation.
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform, float time);
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
TransformationPtr xform, float time);
/// Get the 4x4 matrix that transforms by the specified
/// transformation. Return true if ok, false on error. Since no
/// time value is given, also return false if the transformation may
/// be time-varying.
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform)
{
return false;
}
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
TransformationPtr xform) { return false; }
/// Get the 4x4 matrix that transforms by the specified
/// transformation. Return true if ok, false on error. Since no
@@ -94,29 +91,29 @@ public:
/// be time-varying. The default implementation is to use
/// get_matrix and invert it, but a particular renderer may have a
/// better technique and overload the implementation.
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform);
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
TransformationPtr xform);
/// Get the 4x4 matrix that transforms points from the named
/// 'from' coordinate system to "common" space at the given time.
/// Returns true if ok, false if the named matrix is not known.
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash from, float time);
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
ustring from, float time) { return false; }
/// Get the 4x4 matrix that transforms points from "common" space to
/// the named 'to' coordinate system to at the given time. The
/// default implementation is to use get_matrix and invert it, but a
/// particular renderer may have a better technique and overload the
/// implementation.
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash to, float time);
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
ustring to, float time);
/// Get the 4x4 matrix that transforms 'from' to "common" space.
/// Since there is no time value passed, return false if the
/// transformation may be time-varying (as well as if it's not found
/// at all).
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash from);
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
ustring from) { return false; }
/// Get the 4x4 matrix that transforms points from "common" space to
/// the named 'to' coordinate system. Since there is no time value
@@ -125,8 +122,8 @@ public:
/// implementation is to use get_matrix and invert it, but a
/// particular renderer may have a better technique and overload the
/// implementation.
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash to);
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
ustring to);
/// Transform points Pin[0..npoints-1] in named coordinate system
/// 'from' into 'to' coordinates, storing the result in Pout[] using
@@ -151,10 +148,11 @@ public:
/// Note to RendererServices implementations: just return 'false'
/// if there isn't a special nonlinear transformation between the
/// two spaces.
virtual bool transform_points(ShaderGlobals* sg, ustringhash from,
ustringhash to, float time, const Vec3* Pin,
Vec3* Pout, int npoints,
TypeDesc::VECSEMANTICS vectype);
virtual bool transform_points (ShaderGlobals *sg,
ustring from, ustring to, float time,
const Vec3 *Pin, Vec3 *Pout, int npoints,
TypeDesc::VECSEMANTICS vectype)
{ return false; }
/// Get the named attribute from the renderer and if found then
@@ -169,39 +167,36 @@ public:
/// run on. Be robust to this situation, return 'true' (retrieve the
/// attribute) if you can (known object and attribute name), but
/// otherwise just fail by returning 'false'.
virtual bool get_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
virtual bool get_attribute (ShaderGlobals *sg, bool derivatives,
ustring object, TypeDesc type, ustring name,
void *val) { return false; }
/// Similar to get_attribute(); this method will return the 'index'
/// element of an attribute array.
virtual bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, int index, void* val);
virtual bool get_array_attribute (ShaderGlobals *sg, bool derivatives,
ustring object, TypeDesc type,
ustring name, int index, void *val) { return false; }
/// Get the named user-data from the current object and write it into
/// 'val'. If derivatives is true, the derivatives should be written into val
/// as well. Return false if no user-data with the given name and type was
/// found.
virtual bool get_userdata(bool derivatives, ustringhash name, TypeDesc type,
ShaderGlobals* sg, void* val);
virtual bool get_userdata (bool derivatives, ustring name, TypeDesc type,
ShaderGlobals *sg, void *val) { return false; }
/// Given the name of a texture, return an opaque handle that can be used
/// with texture calls to avoid the name lookups. The `options`, if not
/// null, may be used in renderer-specific ways to specialize a handle
/// based on certain texture option choices.
virtual TextureHandle*
get_texture_handle(ustringhash filename, ShadingContext* context,
const TextureOpt* options = nullptr);
/// Given the name of a texture, return an opaque handle that can be
/// used with texture calls to avoid the name lookups.
virtual TextureHandle * get_texture_handle (ustring filename,
ShadingContext *context);
/// Return true if the texture handle (previously returned by
/// get_texture_handle()) is a valid texture that can be subsequently
/// read or sampled.
virtual bool good(TextureHandle* texture_handle);
virtual bool good (TextureHandle *texture_handle);
/// Return true if the texture handle (previously returned by
/// get_texture_handle()) is udim
virtual bool is_udim(TextureHandle* texture_handle);
virtual bool is_udim (TextureHandle *texture_handle);
/// Filtered 2D texture lookup for a single point.
///
@@ -229,13 +224,13 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual bool texture(ustringhash filename, TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg, float s,
float t, float dsdx, float dtdx, float dsdy,
float dtdy, int nchannels, float* result,
float* dresultds, float* dresultdt,
ustringhash* errormessage);
virtual bool texture (ustring filename, TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
TextureOpt &options, ShaderGlobals *sg,
float s, float t, float dsdx, float dtdx,
float dsdy, float dtdy, int nchannels,
float *result, float *dresultds, float *dresultdt,
ustring *errormessage);
/// Filtered 3D texture lookup for a single point.
///
@@ -262,13 +257,14 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual bool texture3d(ustringhash filename, TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg,
const Vec3& P, const Vec3& dPdx, const Vec3& dPdy,
const Vec3& dPdz, int nchannels, float* result,
float* dresultds, float* dresultdt, float* dresultdr,
ustringhash* errormessage);
virtual bool texture3d (ustring filename, TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
TextureOpt &options, ShaderGlobals *sg,
const Vec3 &P, const Vec3 &dPdx, const Vec3 &dPdy,
const Vec3 &dPdz, int nchannels,
float *result, float *dresultds,
float *dresultdt, float *dresultdr,
ustring *errormessage);
/// Filtered environment lookup for a single point.
///
@@ -292,13 +288,13 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual bool environment(ustringhash filename,
TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg,
const Vec3& R, const Vec3& dRdx, const Vec3& dRdy,
int nchannels, float* result, float* dresultds,
float* dresultdt, ustringhash* errormessage);
virtual bool environment (ustring filename, TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
TextureOpt &options, ShaderGlobals *sg,
const Vec3 &R, const Vec3 &dRdx, const Vec3 &dRdy,
int nchannels, float *result,
float *dresultds, float *dresultdt,
ustring *errormessage);
/// Get information about the given texture. Return true if found
/// and the data has been put in *data. Return false if the texture
@@ -319,20 +315,24 @@ public:
/// messages (in case of failure, when the function returns false) will
/// be stored there, leaving it up to the caller/shader to handle the
/// error.
virtual bool get_texture_info(ustringhash filename,
TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
ShadingContext* shading_context, int subimage,
ustringhash dataname, TypeDesc datatype,
void* data, ustringhash* errormessage);
virtual bool get_texture_info (ustring filename,
TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
ShadingContext *shading_context,
int subimage,
ustring dataname, TypeDesc datatype,
void *data,
ustring *errormessage);
virtual bool get_texture_info(ustringhash filename,
TextureHandle* texture_handle, float s,
float t,
TexturePerthread* texture_thread_info,
ShadingContext* shading_context, int subimage,
ustringhash dataname, TypeDesc datatype,
void* data, ustringhash* errormessage);
virtual bool get_texture_info (ustring filename,
TextureHandle *texture_handle,
float s, float t,
TexturePerthread *texture_thread_info,
ShadingContext *shading_context,
int subimage,
ustring dataname, TypeDesc datatype,
void *data,
ustring *errormessage);
/// Lookup nearest points in a point cloud. It will search for
@@ -343,38 +343,40 @@ public:
/// derivatives will be computed for distances (when provided).
///
/// Return the number of points found, always < max_points
virtual int pointcloud_search(ShaderGlobals* sg, ustringhash filename,
const OSL::Vec3& center, float radius,
int max_points, bool sort,
size_t* out_indices, float* out_distances,
int derivs_offset);
virtual int pointcloud_search (ShaderGlobals *sg,
ustring filename, const OSL::Vec3 &center,
float radius, int max_points, bool sort,
size_t *out_indices,
float *out_distances, int derivs_offset);
/// Retrieve an attribute for an index list. The result is another array
/// of the requested type stored in out_data.
///
/// Return 1 if the attribute is found, 0 otherwise.
virtual int pointcloud_get(ShaderGlobals* sg, ustringhash filename,
size_t* indices, int count,
ustringhash attr_name, TypeDesc attr_type,
void* out_data);
virtual int pointcloud_get (ShaderGlobals *sg,
ustring filename, size_t *indices, int count,
ustring attr_name, TypeDesc attr_type,
void *out_data);
/// Write a point to the named pointcloud, which will be saved
/// at the end of the frame. Return true if everything is ok,
/// false if there was an error.
virtual bool pointcloud_write(ShaderGlobals* sg, ustringhash filename,
const OSL::Vec3& pos, int nattribs,
const ustringrep* names,
const TypeDesc* types, const void** data);
virtual bool pointcloud_write (ShaderGlobals *sg,
ustring filename, const OSL::Vec3 &pos,
int nattribs, const ustring *names,
const TypeDesc *types,
const void **data);
/// Options for the trace call.
struct TraceOpt {
float mindist; ///< ignore hits closer than this
float maxdist; ///< ignore hits farther than this
bool shade; ///< whether to shade what is hit
ustringrep traceset; ///< named trace set
TraceOpt() : mindist(0.0f), maxdist(1.0e30), shade(false) {}
float mindist; ///< ignore hits closer than this
float maxdist; ///< ignore hits farther than this
bool shade; ///< whether to shade what is hit
ustring traceset; ///< named trace set
TraceOpt () : mindist(0.0f), maxdist(1.0e30), shade(false) { }
enum class LLVMMemberIndex {
enum class LLVMMemberIndex
{
mindist = 0,
maxdist,
shade,
@@ -385,59 +387,37 @@ public:
/// Immediately trace a ray from P in the direction R. Return true
/// if anything hit, otherwise false.
virtual bool trace(TraceOpt& options, ShaderGlobals* sg, const OSL::Vec3& P,
const OSL::Vec3& dPdx, const OSL::Vec3& dPdy,
const OSL::Vec3& R, const OSL::Vec3& dRdx,
const OSL::Vec3& dRdy);
virtual bool trace (TraceOpt &options, ShaderGlobals *sg,
const OSL::Vec3 &P, const OSL::Vec3 &dPdx,
const OSL::Vec3 &dPdy, const OSL::Vec3 &R,
const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy) {
return false;
}
/// Get the named message from the renderer and if found then
/// write it into 'val'. Otherwise, return false. This is only
/// called for "sourced" messages, not ordinary intra-group messages.
virtual bool getmessage(ShaderGlobals* sg, ustringhash source,
ustringhash name, TypeDesc type, void* val,
bool derivatives);
virtual bool getmessage (ShaderGlobals *sg, ustring source, ustring name,
TypeDesc type, void *val, bool derivatives) {
return false;
}
/// Return a pointer to the texture system (if available).
virtual TextureSystem* texturesys() const;
virtual TextureSystem *texturesys () const;
/// Allocate `size` bytes of memory on the device that will execute the
/// shaders. (Equivalent to malloc() on the CPU.)
virtual void* device_alloc(size_t size)
virtual uint64_t register_global (const std::string& var_name,
uint64_t value)
{
return nullptr;
// Note: for an OptiX-based renderer, this method should be overriden
// with something like:
//
// void* dptr;
// auto r = cudaMalloc(&dptr, size);
// return r == cudaSuccess ? dptr : nullptr;
return 0;
}
/// Free a previous allocation (by `device_alloc()`) on the device that
/// will execute the shaders. (Equivalent to free() on the CPU.)
virtual void device_free(void* ptr)
virtual bool fetch_global (const std::string& var_name,
uint64_t* value)
{
// Note: for an OptiX-based renderer, this method should be overriden
// with something like:
//
// cudaFree(ptr);
return false;
}
/// Copy `size` bytes from location `src_host` on the host/CPU (the
/// machine making this call) into location `dst_device` on the device
/// executing shaders. (Equivalent to `memcpy(dst, src, size)` on the
/// CPU.)
virtual void* copy_to_device(void* dst_device, const void* src_host,
size_t size)
{
return nullptr;
// Note: for an OptiX-based renderer, this method should be overriden
// with something like:
//
// auto r = cudaMemcpy(dst_device, src_host, size,
// cudaMemcpyHostToDevice);
// return dst_device;
}
/// Options we use for noise calls.
struct NoiseOpt {
@@ -446,25 +426,19 @@ public:
Vec3 direction;
float bandwidth;
float impulses;
NoiseOpt()
: anisotropic(0)
, do_filter(true)
, direction(1.0f, 0.0f, 0.0f)
, bandwidth(1.0f)
, impulses(16.0f)
{
}
NoiseOpt () : anisotropic(0), do_filter(true),
direction(1.0f,0.0f,0.0f), bandwidth(1.0f), impulses(16.0f) { }
};
/// A renderer may choose to support batched execution by providing pointers
/// to objects satisfying the BatchedRendererServices<WidthOf<#>> interface
/// for specific batch sizes.
/// Unless overridden, a nullptr is returned.
virtual BatchedRendererServices<16>* batched(WidthOf<16>);
virtual BatchedRendererServices<8>* batched(WidthOf<8>);
virtual BatchedRendererServices<16> * batched(WidthOf<16>);
virtual BatchedRendererServices<8> * batched(WidthOf<8>);
protected:
TextureSystem* m_texturesys; // A place to hold a TextureSystem
TextureSystem *m_texturesys; // A place to hold a TextureSystem
};
+9 -89
View File
@@ -895,8 +895,6 @@ template<int WidthT> struct alignas(VecReg<WidthT>) Block<Matrix44, WidthT> {
}
};
// Specialization of Block for ustring
template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustring, WidthT> {
static constexpr int width = WidthT;
typedef ustring ValueType;
@@ -944,58 +942,6 @@ template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustring, WidthT> {
}
};
// Specialization of Block for ustringhash
template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustringhash, WidthT> {
static constexpr int width = WidthT;
typedef ustringhash ValueType;
// To enable vectorization, use uintptr_t to store the ustringhash (const char *)
size_t str[WidthT];
static_assert(sizeof(ustringhash) == sizeof(size_t),
"ustringhash must be size_t");
OSL_FORCEINLINE Block() = default;
// We want to avoid accidentally copying these when the intent was to just pass a reference
Block(const Block& other) = delete;
OSL_FORCEINLINE void set(int lane, const ustringhash& value)
{
str[lane] = value.hash();
}
OSL_FORCEINLINE void set(int lane, ustring value)
{
str[lane] = value.hash();
}
OSL_FORCEINLINE void set(int lane, const ustringhash& value, bool laneMask)
{
if (laneMask)
str[lane] = value.hash();
}
OSL_FORCEINLINE ustringhash get(int lane) const
{
#ifdef OIIO_USTRING_HAS_CTR_FROM_USTRINGHASH
return ustringhash::from_hash(str[lane]);
#else
return OSL::bitcast<ustringhash>(str[lane]);
#endif
}
OSL_FORCEINLINE pvt::LaneProxy<ValueType, WidthT> operator[](int lane)
{
return pvt::LaneProxy<ValueType, WidthT>(*this, lane);
}
OSL_FORCEINLINE pvt::ConstLaneProxy<const ValueType, WidthT>
operator[](int lane) const
{
return pvt::ConstLaneProxy<const ValueType, WidthT>(*this, lane);
}
};
template<int WidthT>
struct alignas(VecReg<WidthT>) Block<Dual2<float>, WidthT> {
typedef Dual2<float> ValueType;
@@ -2899,7 +2845,7 @@ public:
// Populate all data lanes of the MaskedData by broadcasting the
// single instance of data pointed to.
// Masked off lanes are not overwritten.
// when has_derivs() is true, Dx and Dy will be zeroed
// Includes value, as well as Dx and Dy when has_derivs() is true
OSL_FORCEINLINE void assign_all_from_scalar(const void* ptr_data) const;
@@ -2917,9 +2863,6 @@ private:
template<typename DataT>
OSL_NOINLINE void assign_all_from_scalar_type(const void* ptr_data,
int deriv_index) const;
template<typename DataT>
OSL_NOINLINE void zero_all_type(int deriv_index) const;
};
@@ -3435,33 +3378,6 @@ MaskedData<WidthT>::assign_all_from_scalar_type(const void* ptr_data,
}
}
template<int WidthT>
template<typename DataT>
OSL_NOINLINE void
MaskedData<WidthT>::zero_all_type(int deriv_index) const
{
// We can't just do a memset because some lanes may be masked off
// Use a SIMD loop to perform masked assignment.
auto* dst_blocks = pvt::block_cast<DataT, WidthT>(m_ptr);
int elem_count = static_cast<int>(m_type.numelements());
int comp_count = m_type.aggregate;
int deriv_offset = deriv_index * elem_count * comp_count;
for (int array_index = 0; array_index < elem_count; ++array_index) {
int array_offset = array_index * comp_count;
for (int comp_index = 0; comp_index < comp_count; ++comp_index) {
int combined_index = deriv_offset + array_offset + comp_index;
auto& bdst = dst_blocks[combined_index];
Masked<DataT, WidthT> wdest(bdst, mask());
OSL_OMP_PRAGMA(omp simd simdlen(WidthT))
for (int lane = 0; lane < WidthT; ++lane) {
wdest[lane] = DataT {};
}
}
}
}
template<int WidthT>
OSL_FORCEINLINE void
MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
@@ -3477,12 +3393,16 @@ MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
assign_all_from_scalar_type<ustring>(ptr_data, /*deriv_index*/ 0);
}
if (has_derivs()) {
size_t src_size = type().size();
const char* dx_src = reinterpret_cast<const char*>(ptr_data) + src_size;
const char* dy_src = dx_src + src_size;
if (isBase32bit) {
zero_all_type<int>(/*deriv_index*/ 1);
zero_all_type<int>(/*deriv_index*/ 2);
assign_all_from_scalar_type<int>(dx_src, /*deriv_index*/ 1);
assign_all_from_scalar_type<int>(dy_src, /*deriv_index*/ 2);
} else {
zero_all_type<ustring>(/*deriv_index*/ 1);
zero_all_type<ustring>(/*deriv_index*/ 2);
assign_all_from_scalar_type<ustring>(dx_src, /*deriv_index*/ 1);
assign_all_from_scalar_type<ustring>(dy_src, /*deriv_index*/ 2);
}
}
}
+3 -4
View File
@@ -8,7 +8,7 @@
#include <OSL/oslconfig.h>
#include <OSL/oslversion.h>
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
# include <cuda_runtime_api.h>
# include <optix.h>
# ifdef _WIN32
@@ -18,9 +18,8 @@
# include <stdlib.h>
#endif
#include <OSL/device_ptr.h>
#if !OSL_USE_OPTIX && !defined(__CUDA_ARCH__)
#if !defined(OSL_USE_OPTIX) && !defined(__CUDA_ARCH__)
using CUdeviceptr = void*;
using float3 = OSL::Vec3;
#endif
@@ -29,7 +28,7 @@ using float3 = OSL::Vec3;
OSL_NAMESPACE_ENTER
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
////////////////////////////////////////////////////////////////////////
// If OptiX is available, alias everything in optix:: namespace into
+9 -50
View File
@@ -386,7 +386,6 @@ public:
/// vector-like (and match their array-ness and closure-ness), or
/// if both are structures with matching fields.
friend bool equivalent(const TypeSpec& a, const TypeSpec& b);
friend bool relaxed_equivalent(const TypeSpec& a, const TypeSpec& b);
/// Is type src is assignable to dst? It is if they are the equivalent(),
/// or if dst is a float or float-aggregate and src is a float or int.
@@ -478,9 +477,7 @@ public:
, m_const_initializer(false)
, m_connected_down(false)
, m_initialized(false)
, m_interpolated(false)
, m_interactive(false)
, m_noninteractive(false)
, m_lockgeom(false)
, m_allowconnect(true)
, m_renderer_output(false)
, m_readonly(false)
@@ -632,18 +629,7 @@ public:
OSL_ASSERT(arena == SymArena::Absolute);
m_arena = static_cast<unsigned int>(arena);
m_data = ptr;
}
/// Specify the location of the symbol's data, relative to an arena
/// (which for now must be Absolute).
void set_dataptr(SymArena arena, void* ptr, int offset)
{
// OSL_ASSERT(arena == SymArena::Absolute);
m_arena = static_cast<unsigned int>(arena);
m_data = ptr;
m_dataoffset = offset;
OSL::print("setting sym {} arena {} offset {}\n", name(), int(m_arena),
m_dataoffset);
// m_dataoffset = static_cast<int64_t>((char*)ptr - (char*)0);
}
@@ -884,36 +870,11 @@ public:
bool lockgeom() const
{
// We can lock a value to a constant (at all places on all pieces of
// geometry) if it is neither interpolated nor interactively modified.
return !m_interpolated && !m_interactive;
return m_lockgeom;
}
bool interpolated() const
void lockgeom(bool lock)
{
return m_interpolated;
}
void interpolated(bool val)
{
m_interpolated = val;
}
bool interactive() const
{
return m_interactive;
}
void interactive(bool val)
{
m_interactive = val;
}
bool noninteractive() const
{
return m_noninteractive;
}
void noninteractive(bool val)
{
m_noninteractive = val;
m_lockgeom = lock;
}
bool allowconnect() const
@@ -1067,12 +1028,10 @@ protected:
unsigned m_symtype : 4; ///< Kind of symbol (param, local, etc.)
unsigned m_has_derivs : 1; ///< Step to derivs (0 == has no derivs)
unsigned m_const_initializer : 1; ///< initializer is a constant expression
unsigned m_connected_down : 1; ///< Connected to a later/downstream layer
unsigned m_initialized : 1; ///< If a param, has it been initialized?
unsigned m_interpolated : 1; ///< Is the param overridden by geom?
unsigned m_interactive : 1; ///< May the param change interactively?
unsigned m_noninteractive : 1; ///< The param def won't modify interactively
unsigned m_allowconnect : 1; ///< Is the param allowd to connect?
unsigned m_connected_down : 1; ///< Connected to a later/downstream layer
unsigned m_initialized : 1; ///< If a param, has it been initialized?
unsigned m_lockgeom : 1; ///< Is the param not overridden by geom?
unsigned m_allowconnect : 1; ///< Is the param not overridden by geom?
unsigned m_renderer_output : 1; ///< Is this sym a renderer output?
unsigned m_readonly : 1; ///< read-only symbol
unsigned m_is_uniform : 1; ///< symbol is uniform under batched execution
+36 -97
View File
@@ -1116,151 +1116,90 @@ ASTassign_expression::opword() const
OSL_ASSERT (0 && "unknown assignment expression");
return "assign"; // punt
}
// clang-format on
}
ASTunary_expression::ASTunary_expression(OSLCompilerImpl* comp, int op,
ASTNode* expr)
: ASTNode(unary_expression_node, comp, op, expr)
ASTunary_expression::ASTunary_expression (OSLCompilerImpl *comp, int op,
ASTNode *expr)
: ASTNode (unary_expression_node, comp, op, expr)
{
// Check for a user-overloaded function for this operator
Symbol* sym = comp->symtab().find(
ustring::fmtformat("__operator__{}__", opword()));
Symbol *sym = comp->symtab().find(ustring::fmtformat("__operator__{}__", opword()));
if (sym && sym->symtype() == SymTypeFunction)
m_function_overload = (FunctionSymbol*)sym;
m_function_overload = (FunctionSymbol *)sym;
}
const char*
ASTunary_expression::childname(size_t i) const
const char *
ASTunary_expression::childname (size_t i) const
{
static const char* name[] = { "expression" };
static const char *name[] = { "expression" };
return name[i];
}
const char*
ASTunary_expression::opname() const
const char *
ASTunary_expression::opname () const
{
switch (m_op) {
case Add: return "+";
case Sub: return "-";
case Not: return "!";
case Compl: return "~";
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
case Add : return "+";
case Sub : return "-";
case Not : return "!";
case Compl : return "~";
default:
OSL_ASSERT (0 && "unknown unary expression");
return "unknown";
}
}
const char*
ASTunary_expression::opword() const
const char *
ASTunary_expression::opword () const
{
switch (m_op) {
case Add: return "add";
case Sub: return "neg";
case Not: return "not";
case Compl: return "compl";
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
case Add : return "add";
case Sub : return "neg";
case Not : return "not";
case Compl : return "compl";
default:
OSL_ASSERT (0 && "unknown unary expression");
return "unknown";
}
}
ASTbinary_expression::ASTbinary_expression(OSLCompilerImpl* comp, Operator op,
ASTNode* left, ASTNode* right)
: ASTNode(binary_expression_node, comp, op, left, right)
ASTbinary_expression::ASTbinary_expression (OSLCompilerImpl *comp, Operator op,
ASTNode *left, ASTNode *right)
: ASTNode (binary_expression_node, comp, op, left, right)
{
// Check for a user-overloaded function for this operator.
// Disallow a few ops from overloading.
if (op != And && op != Or) {
ustring funcname = ustring::fmtformat("__operator__{}__", opword());
Symbol* sym = comp->symtab().find(funcname);
Symbol *sym = comp->symtab().find (funcname);
if (sym && sym->symtype() == SymTypeFunction)
m_function_overload = (FunctionSymbol*)sym;
m_function_overload = (FunctionSymbol *)sym;
}
}
ASTNode*
ASTbinary_expression::make(OSLCompilerImpl* comp, Operator op, ASTNode* left,
ASTNode* right)
const char *
ASTbinary_expression::childname (size_t i) const
{
// If the left and right are both literal constants, fold the expression
if (left->nodetype() == literal_node && right->nodetype() == literal_node) {
ASTNode* cf = nullptr; // constant-folded result
if (left->typespec().is_int() && right->typespec().is_int()) {
int lv = dynamic_cast<ASTliteral*>(left)->intval();
int rv = dynamic_cast<ASTliteral*>(right)->intval();
switch (op) {
case Mul: cf = new ASTliteral(comp, lv * rv); break;
case Div: cf = new ASTliteral(comp, rv ? lv / rv : 0); break;
case Add: cf = new ASTliteral(comp, lv + rv); break;
case Sub: cf = new ASTliteral(comp, lv - rv); break;
case Mod: cf = new ASTliteral(comp, rv ? lv % rv : 0); break;
case Equal: cf = new ASTliteral(comp, lv == rv ? 1 : 0); break;
case NotEqual: cf = new ASTliteral(comp, lv != rv ? 1 : 0); break;
case Greater: cf = new ASTliteral(comp, lv > rv ? 1 : 0); break;
case Less: cf = new ASTliteral(comp, lv < rv ? 1 : 0); break;
case GreaterEqual:
cf = new ASTliteral(comp, lv >= rv ? 1 : 0);
break;
case LessEqual: cf = new ASTliteral(comp, lv <= rv ? 1 : 0); break;
case BitAnd: cf = new ASTliteral(comp, lv & rv); break;
case BitOr: cf = new ASTliteral(comp, lv | rv); break;
case Xor: cf = new ASTliteral(comp, lv ^ rv); break;
case ShiftLeft: cf = new ASTliteral(comp, lv << rv); break;
case ShiftRight: cf = new ASTliteral(comp, lv >> rv); break;
default: break;
}
} else if (left->typespec().is_float()
&& right->typespec().is_float()) {
float lv = dynamic_cast<ASTliteral*>(left)->floatval();
float rv = dynamic_cast<ASTliteral*>(right)->floatval();
switch (op) {
case Mul: cf = new ASTliteral(comp, lv * rv); break;
case Div: cf = new ASTliteral(comp, rv ? lv / rv : 0.0f); break;
case Add: cf = new ASTliteral(comp, lv + rv); break;
case Sub: cf = new ASTliteral(comp, lv - rv); break;
case Equal: cf = new ASTliteral(comp, lv == rv ? 1 : 0); break;
case NotEqual: cf = new ASTliteral(comp, lv != rv ? 1 : 0); break;
case Greater: cf = new ASTliteral(comp, lv > rv ? 1 : 0); break;
case Less: cf = new ASTliteral(comp, lv < rv ? 1 : 0); break;
case GreaterEqual:
cf = new ASTliteral(comp, lv >= rv ? 1 : 0);
break;
case LessEqual: cf = new ASTliteral(comp, lv <= rv ? 1 : 0); break;
default: break;
}
}
if (cf) {
delete left;
delete right;
return cf;
}
}
return new ASTbinary_expression(comp, op, left, right);
}
const char*
ASTbinary_expression::childname(size_t i) const
{
static const char* name[] = { "left", "right" };
static const char *name[] = { "left", "right" };
return name[i];
}
const char*
ASTbinary_expression::opname() const
const char *
ASTbinary_expression::opname () const
{
// clang-format off
switch (m_op) {
-4
View File
@@ -832,10 +832,6 @@ public:
ASTbinary_expression(OSLCompilerImpl* comp, Operator op, ASTNode* left,
ASTNode* right);
// Special consructor wrapper that can collapse ops between literals
static ASTNode* make(OSLCompilerImpl* comp, Operator op, ASTNode* left,
ASTNode* right);
const char* nodetypename() const { return "binary_expression"; }
const char* childname(size_t i) const;
const char* opname() const;
+2 -3
View File
@@ -701,12 +701,11 @@ OSLCompilerImpl::write_oso_const_value(const ConstantSymbol* sym) const
osofmt("{}{}", sym->get_int(i), nelements > 1 ? " " : "");
else if (elemtype == TypeDesc::FLOAT)
for (int i = 0; i < nelements; ++i)
osofmt("{:.9g}{}", sym->floatval(i), nelements > 1 ? " " : "");
osofmt("{}{}", sym->floatval(i), nelements > 1 ? " " : "");
else if (equivalent(elemtype, TypeDesc::TypeVector))
for (int i = 0; i < nelements; ++i) {
Vec3 v = sym->get_vec3(i);
osofmt("{:.9g} {:.9g} {:.9g}{}", v.x, v.y, v.z,
nelements > 1 ? " " : "");
osofmt("{} {} {}{}", v.x, v.y, v.z, nelements > 1 ? " " : "");
}
else {
OSL_ASSERT(0 && "Don't know how to output this constant type");
+18 -18
View File
@@ -858,109 +858,109 @@ variable_ref
binary_expression
: expression OR_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Or, $1, $3);
$$->sourceline (@2.first_line);
}
| expression AND_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::And, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '|' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::BitOr, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '^' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Xor, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '&' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::BitAnd, $1, $3);
$$->sourceline (@2.first_line);
}
| expression EQ_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Equal, $1, $3);
$$->sourceline (@2.first_line);
}
| expression NE_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::NotEqual, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '>' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Greater, $1, $3);
$$->sourceline (@2.first_line);
}
| expression GE_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::GreaterEqual, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '<' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Less, $1, $3);
$$->sourceline (@2.first_line);
}
| expression LE_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::LessEqual, $1, $3);
$$->sourceline (@2.first_line);
}
| expression SHL_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::ShiftLeft, $1, $3);
$$->sourceline (@2.first_line);
}
| expression SHR_OP expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::ShiftRight, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '+' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Add, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '-' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Sub, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '*' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Mul, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '/' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Div, $1, $3);
$$->sourceline (@2.first_line);
}
| expression '%' expression
{
$$ = ASTbinary_expression::make(oslcompiler,
$$ = new ASTbinary_expression (oslcompiler,
ASTNode::Mod, $1, $3);
$$->sourceline (@2.first_line);
}
+12
View File
@@ -397,6 +397,15 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
// Thread safety with the lexer/parser
std::lock_guard<std::mutex> lock(oslcompiler_mutex);
#ifndef OIIO_STRUTIL_HAS_STOF
// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
// This is not necessary for versions of OIIO that have Strutil::stof,
// and we can remove it entirely when OIIO 1.9 is the minimum.
std::locale oldlocale = std::locale::global (std::locale::classic());
#endif
yyscan_t scanner;
yylex_init(&scanner);
YY_BUFFER_STATE buffer = yy_scan_string(preprocessed_buffer.c_str(), scanner);
@@ -406,6 +415,9 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
yy_delete_buffer (buffer, scanner);
yylex_destroy(scanner);
#ifndef OIIO_STRUTIL_HAS_STOF
std::locale::global (oldlocale); // Restore the original locale.
#endif
return parseerr;
}
-4
View File
@@ -143,10 +143,6 @@ Symbol::print(std::ostream& out, int maxvals) const
out << " renderer-output";
if (symtype() == SymTypeParam && !lockgeom())
out << " lockgeom=0";
if (symtype() == SymTypeParam && interactive())
out << " interactive=1";
if (symtype() == SymTypeParam && noninteractive())
out << " interactive=0";
}
out << "\n";
if (symtype() == SymTypeConst) {
+1 -1
View File
@@ -123,7 +123,7 @@ set (lib_src
llvm_gen.cpp llvm_instance.cpp llvm_util.cpp
rs_fallback.cpp
)
if (OSL_BUILD_BATCHED)
if (BUILD_BATCHED)
list(APPEND lib_src
batched_analysis.cpp
batched_backendllvm.cpp
+72 -21
View File
@@ -6,6 +6,10 @@
#include <OpenImageIO/filesystem.h>
#include <OpenImageIO/strutil.h>
#ifdef OSL_USE_OPTIX
# include <optix.h>
#endif
#include "oslexec_pvt.h"
#include "backendllvm.h"
@@ -17,6 +21,55 @@ OSL_NAMESPACE_ENTER
namespace pvt {
#ifdef OSL_SPI
static void
check_cwd(ShadingSystemImpl& shadingsys)
{
std::string err;
char pathname[1024] = { "" };
if (!getcwd(pathname, sizeof(pathname) - 1)) {
int e = errno;
err += fmtformat("Failed getcwd(), errno is {}: {}\n", errno, pathname);
if (e == EACCES || e == ENOENT) {
err += "Read/search permission problem or dir does not exist.\n";
const char* pwdenv = getenv("PWD");
if (!pwdenv) {
err += "$PWD is not even found in the environment.\n";
} else {
err += fmtformat("$PWD is \"{}\"\n", pwdenv);
err += fmtformat("That {}.\n", OIIO::Filesystem::exists(pwdenv)
? "exists"
: "does NOT exist");
err += fmtformat("That {} a directory.\n",
OIIO::Filesystem::is_directory(pwdenv)
? "is"
: "is NOT");
std::vector<std::string> pieces;
Strutil::split(pwdenv, pieces, "/");
std::string p;
for (size_t i = 0; i < pieces.size(); ++i) {
if (!pieces[i].size())
continue;
p += "/";
p += pieces[i];
err += fmtformat(" {} : {} and is{} a directory.\n", p,
OIIO::Filesystem::exists(p)
? "exists"
: "does NOT exist",
OIIO::Filesystem::is_directory(p)
? ""
: " NOT");
}
}
}
}
if (err.size())
shadingsys.error(err);
}
#endif
BackendLLVM::BackendLLVM(ShadingSystemImpl& shadingsys, ShaderGroup& group,
ShadingContext* ctx)
: OSOProcessorBase(shadingsys, group, ctx)
@@ -27,7 +80,12 @@ BackendLLVM::BackendLLVM(ShadingSystemImpl& shadingsys, ShaderGroup& group,
, m_stat_llvm_opt_time(0)
, m_stat_llvm_jit_time(0)
{
m_use_optix = shadingsys.use_optix();
#ifdef OSL_SPI
// Temporary (I hope) check to diagnose an intermittent failure of
// getcwd inside LLVM. Oy.
check_cwd(shadingsys);
#endif
m_use_optix = shadingsys.renderer()->supports("OptiX");
m_use_rs_bitcode = !shadingsys.m_rs_bitcode.empty();
m_name_llvm_syms = shadingsys.m_llvm_output_bitcode;
@@ -226,15 +284,6 @@ BackendLLVM::getLLVMSymbolBase(const Symbol& sym)
llvm_type(sym.typespec().elementtype()));
return result;
}
if (sym.symtype() == SymTypeParam && sym.interactive()) {
// Special case for interactively-edited parameters -- they live in
// the interactive data block for the group.
// Generate the pointer to this symbol by offsetting into the
// interactive data block.
int offset = group().interactive_param_offset(layer(), sym.name());
return ll.offset_ptr(m_llvm_interactive_params_ptr, offset,
llvm_ptr_type(sym.typespec().elementtype()));
}
if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
// Special case for params -- they live in the group data
@@ -290,7 +339,6 @@ BackendLLVM::getOrAllocateLLVMSymbol(const Symbol& sym)
#if OSL_USE_OPTIX
llvm::Value*
BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
int alignment, const void* init_data,
@@ -306,7 +354,7 @@ BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
} else if (type == TypeDesc::TypeInt) {
constant = ll.constant(*(const int*)init_data);
} else if (type == TypeDesc::TypeString) {
constant = ll.constant64(((const ustring*)init_data)->hash());
constant = ll.constant(((const ustring*)init_data)->hash());
// N.B. Since this is the OptiX side specifically, we will represent
// strings as the ustringhash, so we know it as a constant.
} else {
@@ -321,11 +369,11 @@ BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
OSL_DASSERT(g_var && "Unable to create GlobalVariable");
# if OSL_LLVM_VERSION >= 100
#if OSL_LLVM_VERSION >= 100
g_var->setAlignment(llvm::MaybeAlign(alignment));
# else
#else
g_var->setAlignment(alignment);
# endif
#endif
g_var->setLinkage(llvm::GlobalValue::PrivateLinkage);
g_var->setVisibility(llvm::GlobalValue::DefaultVisibility);
@@ -343,7 +391,14 @@ BackendLLVM::getOrAllocateCUDAVariable(const Symbol& sym)
OSL_ASSERT(use_optix()
&& "This function is only supported when using OptiX!");
std::string name = global_unique_symname(sym);
// We need to sanitize the symbol name for PTX compatibility. Also, if the
// sym name starts with a dollar sign, which are not allowed in PTX
// variable names, then prepend another underscore.
std::string sym_name = Strutil::replace(sym.name(), ".", "_", true);
std::string name
= fmtformat("{}{}_{}_{}_{}", sym_name.front() == '$' ? "_" : "",
sym_name, group().name(), inst()->layername(), sym.layer());
// Return the Value if it has already been allocated
auto it = get_const_map().find(name);
@@ -357,7 +412,6 @@ BackendLLVM::getOrAllocateCUDAVariable(const Symbol& sym)
return addCUDAGlobalVariable(name, sym.size(), alignment, sym.data(),
sym.typespec().simpletype());
}
#endif
@@ -375,7 +429,6 @@ BackendLLVM::llvm_get_pointer(const Symbol& sym, int deriv,
llvm::Value* result = NULL;
if (sym.symtype() == SymTypeConst) {
TypeSpec elemtype = sym.typespec().elementtype();
#if OSL_USE_OPTIX
if (use_optix()) {
// Check the constant map for the named Symbol; if it's found, then
// a GlobalVariable has been created for it
@@ -386,9 +439,7 @@ BackendLLVM::llvm_get_pointer(const Symbol& sym, int deriv,
// N.B. llvm_typedesc() for a string will know that on OptiX,
// strings are actually represented as just the hash.
}
} else
#endif
{
} else {
// For constants on the CPU side, start with *OUR* pointer to the
// constant values.
result = ll.constant_ptr(sym.data(),
+10 -69
View File
@@ -216,21 +216,6 @@ public:
/// map, the symbol is alloca'd and placed in the map.
llvm::Value* getOrAllocateLLVMSymbol(const Symbol& sym);
#if OSL_USE_OPTIX
/// Return a globally unique (to the JIT module) name for symbol `sym`,
/// assuming it's part of the currently examined layer of the group.
std::string global_unique_symname(const Symbol& sym)
{
// We need to sanitize the symbol name for PTX compatibility. Also, if
// the sym name starts with a dollar sign, which are not allowed in
// PTX variable names, then prepend another underscore.
auto sym_name = Strutil::replace(sym.name(), ".", "_", true);
int layer = sym.layer();
const ShaderInstance* inst_ = group()[layer];
return fmtformat("{}{}_{}_{}_{}", sym_name.front() == '$' ? "_" : "",
sym_name, group().name(), inst_->layername(), layer);
}
/// Allocate a CUDA variable for the given OSL symbol and return a pointer
/// to the corresponding LLVM GlobalVariable, or return the pointer if it
/// has already been allocated.
@@ -244,7 +229,6 @@ public:
llvm::Value* addCUDAGlobalVariable(const std::string& name, int size,
int alignment, const void* init_data,
TypeDesc type = TypeDesc::UNKNOWN);
#endif
/// Retrieve an llvm::Value that is a pointer holding the start address
/// of the specified symbol. This always works for globals and params;
@@ -282,20 +266,14 @@ public:
/// Return the ShaderGlobals pointer.
///
llvm::Value* sg_ptr() const
{
return m_llvm_shaderglobals_ptr;
}
llvm::Value* sg_ptr() const { return m_llvm_shaderglobals_ptr; }
llvm::Type* llvm_type_closure_component();
llvm::Type* llvm_type_closure_component_ptr();
/// Return the ShaderGlobals pointer cast as a void*.
///
llvm::Value* sg_void_ptr()
{
return ll.void_ptr(m_llvm_shaderglobals_ptr);
}
llvm::Value* sg_void_ptr() { return ll.void_ptr(m_llvm_shaderglobals_ptr); }
/// Cast the pointer variable specified by val to a pointer to the
/// basic type comprising `type`.
@@ -321,10 +299,7 @@ public:
/// Return the group data pointer.
///
llvm::Value* groupdata_ptr() const
{
return m_llvm_groupdata_ptr;
}
llvm::Value* groupdata_ptr() const { return m_llvm_groupdata_ptr; }
/// Return the group data pointer cast as a void*.
///
@@ -342,22 +317,13 @@ public:
TypeDesc type = TypeDesc::UNKNOWN);
/// Return the userdata base pointer.
llvm::Value* userdata_base_ptr() const
{
return m_llvm_userdata_base_ptr;
}
llvm::Value* userdata_base_ptr() const { return m_llvm_userdata_base_ptr; }
/// Return the output base pointer.
llvm::Value* output_base_ptr() const
{
return m_llvm_output_base_ptr;
}
llvm::Value* output_base_ptr() const { return m_llvm_output_base_ptr; }
/// Return the shade index
llvm::Value* shadeindex() const
{
return m_llvm_shadeindex;
}
llvm::Value* shadeindex() const { return m_llvm_shadeindex; }
// For a symloc, compute the llvm::Value of the pointer to its true,
// offset location from the base pointer for shade index `sindex`
@@ -463,13 +429,6 @@ public:
return ll.llvm_type(llvm_typedesc(typespec));
}
/// Generate the appropriate llvm type definition for a pointer to
/// the type specified by the TypeSpec.
llvm::Type* llvm_ptr_type(const TypeSpec& typespec)
{
return ll.type_ptr(ll.llvm_type(llvm_typedesc(typespec)));
}
/// Generate the parameter-passing llvm type definition for an OSL
/// TypeSpec.
llvm::Type* llvm_pass_type(const TypeSpec& typespec);
@@ -485,10 +444,7 @@ public:
/// Return the basic block of the exit for the whole instance.
///
bool llvm_has_exit_instance_block() const
{
return m_exit_instance_block;
}
bool llvm_has_exit_instance_block() const { return m_exit_instance_block; }
/// Return the basic block of the exit for the whole instance.
///
@@ -509,10 +465,7 @@ public:
/// Print debugging line for the op
void llvm_generate_debug_op_printf(const Opcode& op);
llvm::Function* layer_func() const
{
return ll.current_function();
}
llvm::Function* layer_func() const { return ll.current_function(); }
/// Call this when JITing a texture-like call, to track how many.
void generated_texture_call(bool handle)
@@ -522,11 +475,6 @@ public:
shadingsys().m_stat_tex_calls_as_handles += 1;
}
void increment_useparam_ops()
{
shadingsys().m_stat_useparam_ops++;
}
/// Return the mapping from symbol names to GlobalVariables.
std::map<std::string, llvm::GlobalVariable*>& get_const_map()
{
@@ -534,16 +482,10 @@ public:
}
/// Return whether or not we are compiling for an OptiX-based renderer.
bool use_optix()
{
return m_use_optix;
}
bool use_optix() { return m_use_optix; }
/// Return if we should compile against free function versions of Renderer Service.
bool use_rs_bitcode()
{
return m_use_rs_bitcode;
}
bool use_rs_bitcode() { return m_use_rs_bitcode; }
/// Return the userdata index for the given Symbol. Return -1 if the Symbol
/// is not an input parameter or is constant and therefore doesn't have an
@@ -580,7 +522,6 @@ private:
std::map<const Symbol*, int> m_param_order_map;
llvm::Value* m_llvm_shaderglobals_ptr;
llvm::Value* m_llvm_groupdata_ptr;
llvm::Value* m_llvm_interactive_params_ptr;
llvm::Value* m_llvm_userdata_base_ptr;
llvm::Value* m_llvm_output_base_ptr;
llvm::Value* m_llvm_shadeindex;
-12
View File
@@ -2303,17 +2303,6 @@ struct Analyzer {
}
}
void make_closures_varying()
{
// We assume that closures are always stored as varying pointers
FOREACH_PARAM(Symbol & s, inst())
{
if (s.typespec().is_closure()) {
recursively_mark_varying(&s);
}
}
}
void push_varying_of_upstream_connections()
{
OSL_DEV_ONLY(std::cout << "connections to layer begin" << std::endl);
@@ -2406,7 +2395,6 @@ BatchedAnalysis::analyze_layer(ShaderInstance* inst)
analyzer.push_varying_of_shader_globals();
analyzer.make_interpolated_parameters_varying();
analyzer.make_renderer_outputs_varying();
analyzer.make_closures_varying();
analyzer.push_varying_of_upstream_connections();
analyzer.push_varying_of_implicitly_varying_ops();
-10
View File
@@ -448,16 +448,6 @@ BatchedBackendLLVM::getLLVMSymbolBase(const Symbol& sym)
return result;
}
if (sym.symtype() == SymTypeParam && sym.interactive()) {
// Special case for interactively-edited parameters -- they live in
// the interactive data block for the group.
// Generate the pointer to this symbol by offsetting into the
// interactive data block.
int offset = group().interactive_param_offset(layer(), sym.name());
return ll.offset_ptr(m_llvm_interactive_params_ptr, offset,
llvm_ptr_type(sym.typespec().elementtype()));
}
if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
// Special case for params -- they live in the group data
int fieldnum = m_param_order_map[&sym];
+4 -12
View File
@@ -6,6 +6,8 @@
#pragma once
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "oslexec_pvt.h"
@@ -13,7 +15,7 @@
using namespace OSL;
using namespace OSL::pvt;
#include <OSL/llvm_util.h>
#include "OSL/llvm_util.h"
#include "runtimeoptimize.h"
#include <llvm/ADT/SmallString.h>
@@ -656,14 +658,6 @@ public:
return ll.llvm_vector_type(llvm_typedesc(typespec));
}
/// Generate the appropriate llvm type definition for a pointer to
/// the type specified by the TypeSpec.
llvm::Type* llvm_ptr_type(const TypeSpec& typespec)
{
return reinterpret_cast<llvm::Type*>(
ll.type_ptr(ll.llvm_type(llvm_typedesc(typespec))));
}
/// Generate the parameter-passing llvm type definition for an OSL
/// TypeSpec.
llvm::Type* llvm_pass_type(const TypeSpec& typespec);
@@ -711,8 +705,6 @@ public:
shadingsys().m_stat_tex_calls_as_handles += 1;
}
void increment_useparam_ops() { shadingsys().m_stat_useparam_ops++; }
void llvm_print_mask(const char* title, llvm::Value* mask = nullptr);
/// Return the userdata index for the given Symbol. Return -1 if the Symbol
@@ -789,7 +781,7 @@ private:
std::map<const Symbol*, int> m_param_order_map;
llvm::Value* m_llvm_shaderglobals_ptr;
llvm::Value* m_llvm_groupdata_ptr;
llvm::Value* m_llvm_interactive_params_ptr;
llvm::Value* m_llvm_wide_shadeindex_ptr;
llvm::Value* m_llvm_userdata_base_ptr;
llvm::Value* m_llvm_output_base_ptr;
+25 -110
View File
@@ -92,17 +92,13 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
<< " unconditional=" << unconditional << std::endl);
// Make code that looks like:
// if (! groupdata->run[parentlayer])
// parent_layer (sg, groupdata, wide_shadeindex_ptr,
// userdata_base_ptr, output_base_ptr,
// execution_mask, interactive_params_ptr);
// parent_layer (sg, groupdata);
// if it's a conditional call, or
// parent_layer (sg, groupdata, wide_shadeindex_ptr,
// userdata_base_ptr, output_base_ptr,
// execution_mask, interactive_params_ptr);
// parent_layer (sg, groupdata);
// if it's run unconditionally.
// The code in the parent layer itself will set its 'executed' flag.
llvm::Value* args[7];
llvm::Value* args[6];
args[0] = sg_ptr();
args[1] = groupdata_ptr();
args[2] = ll.void_ptr(wide_shadeindex_ptr());
@@ -124,11 +120,13 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
llvm::Value* execution_required
= ll.op_ne(lanes_requiring_execution_value, ll.constant(0));
then_block = ll.new_basic_block(
llvm_debug() ? Strutil::fmt::format("then layer {}", layer)
: std::string());
llvm_debug()
? std::string("then layer ").append(std::to_string(layer))
: std::string());
after_block = ll.new_basic_block(
llvm_debug() ? Strutil::fmt::format("after layer {}", layer)
: std::string());
llvm_debug()
? std::string("after layer ").append(std::to_string(layer))
: std::string());
ll.op_branch(execution_required, then_block, after_block);
// insert point is now then_block
} else {
@@ -136,7 +134,6 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
}
args[5] = lanes_requiring_execution_value;
args[6] = m_llvm_interactive_params_ptr;
// Before the merge, keeping in case we broke it
//std::string name = fmtformat("{}_{}_{}", m_library_selector, parent->layername().c_str(),
@@ -152,8 +149,6 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
if (!unconditional)
ll.op_branch(after_block); // also moves insert point
shadingsys().m_stat_call_layers_inserted++;
}
@@ -204,15 +199,6 @@ BatchedBackendLLVM::llvm_run_connected_layers(const Symbol& sym, int symindex,
}
}
if (shadingsys().m_opt_useparam && inmain) {
// m_call_layers_inserted tracks if we've already run this layer inside the current basic block
const CallLayerKey key = { m_bblockids[opnum], con.srclayer };
if (m_call_layers_inserted.count(key)) {
continue;
}
m_call_layers_inserted.insert(key);
}
// If the earlier layer it comes from has not yet been
// executed, do so now.
llvm_call_layer(con.srclayer);
@@ -250,16 +236,13 @@ LLVMGEN(llvm_gen_useparam)
// initializing them lazily, now we have to do it.
if ((sym.symtype() == SymTypeParam
|| sym.symtype() == SymTypeOutputParam)
&& sym.interpolated() && !sym.typespec().is_closure()
&& !sym.lockgeom() && !sym.typespec().is_closure()
&& !sym.connected() && !sym.connected_down()
&& rop.shadingsys().lazy_userdata()) {
rop.llvm_assign_initial_value(sym, rop.ll.mask_as_int(
rop.ll.current_mask()));
}
}
rop.increment_useparam_ops();
return true;
}
@@ -1280,7 +1263,6 @@ LLVMGEN(llvm_gen_add)
OSL_ASSERT(!A.typespec().is_array() && !B.typespec().is_array());
if (Result.typespec().is_closure()) {
OSL_ASSERT(A.typespec().is_closure() && B.typespec().is_closure());
OSL_ASSERT(!A.is_uniform() && !B.is_uniform() && !result_is_uniform);
llvm::Value* valargs[] = { rop.sg_void_ptr(), rop.llvm_void_ptr(Result),
rop.llvm_void_ptr(A), rop.llvm_void_ptr(B),
rop.ll.mask_as_int(rop.ll.current_mask()) };
@@ -1694,7 +1676,6 @@ LLVMGEN(llvm_gen_modulus)
int num_components = type.aggregate;
#if 0
if (is_float && !op_is_uniform) {
// llvm 5.0.1 did not do a good job with op_mod when its
// parameters were <16xf32>. So we will go ahead
@@ -1721,9 +1702,7 @@ LLVMGEN(llvm_gen_modulus)
}
rop.ll.call_function(rop.build_name(func_spec), call_args);
} else
#endif
{
} else {
for (int i = 0; i < num_components; i++) {
llvm::Value* a = rop.loadLLVMValue(A, i, 0, type, op_is_uniform);
llvm::Value* b = rop.loadLLVMValue(B, i, 0, type, op_is_uniform);
@@ -7085,8 +7064,7 @@ LLVMGEN(llvm_gen_spline)
static void
llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
const ClosureRegistry::ClosureEntry* clentry,
ustring clname, llvm::Value* mem_void_ptr, int argsoffset,
int lane_index)
ustring clname, llvm::Value* mem_void_ptr, int argsoffset)
{
OSL_DASSERT(((op.nargs() - argsoffset) % 2) == 0);
@@ -7110,45 +7088,10 @@ llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
if (equivalent(p.type, ValueType) && !strcmp(key->c_str(), p.key)) {
// store data
OSL_DASSERT(p.offset + p.field_size <= clentry->struct_size);
bool arg_is_uniform = Value.is_uniform();
TypeDesc simpletype(Value.typespec().simpletype());
// We don't currently offer a helper macro in genclosure.h for creating
// keyword array parameters, so perhaps we can assume we don't need to
// support them
OSL_DASSERT(simpletype.arraylen == 0);
int num_components = simpletype.aggregate;
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr,
p.offset);
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
for (int c = 0; c < num_components; c++) {
llvm::Value* dest_elem;
if (num_components > 1)
dest_elem = rop.ll.GEP(dest_base, 0, c);
else
dest_elem = dest_base;
// NOTE: We don't want any uniform arguments to be
// widened, so our typical op_is_uniform doesn't do what we
// want for this when loading. So just pass arg_is_uniform
// which will avoid widening any uniform arguments.
llvm::Value* loaded
= rop.llvm_load_value(Value, 0, NULL, c,
TypeDesc::UNKNOWN,
/*op_is_uniform*/ arg_is_uniform,
/*index_is_uniform*/ true);
if (!arg_is_uniform) {
loaded = rop.ll.op_extract(loaded, lane_index);
}
rop.ll.op_unmasked_store(loaded, dest_elem);
}
llvm::Value* dst = rop.ll.offset_ptr(mem_void_ptr, p.offset);
llvm::Value* src = rop.llvm_void_ptr(Value);
rop.ll.op_memcpy(dst, src, (int)p.type.size(),
4 /* use 4 byte alignment for now */);
legal = true;
break;
}
@@ -7237,7 +7180,6 @@ LLVMGEN(llvm_gen_closure)
rop.ll.type_ptr(rop.llvm_type_closure_component_wide_ptr()));
llvm::Value* comp_wide_ptr = rop.ll.op_load(comp_wide_ptr_ptr);
llvm::Value* mask = rop.ll.current_mask();
// This is an unrolled vector-width loop. It was unrolled because it's
// was more expedient to write the for in C++ than IR, but if compilation
// of the extra ops becomes problematic, this choice can be revisited
@@ -7251,16 +7193,14 @@ LLVMGEN(llvm_gen_closure)
// For the weighted closures, we need a surrounding "if" so that it's safe
// for osl_allocate_weighted_closure_component to return NULL (unless we
// know for sure that it's constant weighted and that the weight is
// not zero). We also need the surrounding "if" to reject writing
// to closures that aren't masked.
// not zero).
llvm::BasicBlock* next_block = NULL;
llvm::BasicBlock* notnull_block = rop.ll.new_basic_block(
"non_null_and_masked_closure");
next_block = rop.ll.new_basic_block("");
llvm::Value* cond = rop.ll.op_and(
rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
rop.ll.void_ptr_null()),
rop.ll.test_mask_lane(mask, lane_index));
"non_null_closure");
next_block = rop.ll.new_basic_block("");
llvm::Value* cond
= rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
rop.ll.void_ptr_null());
rop.ll.op_branch(cond, notnull_block, next_block);
// If the closure has a "prepare" method, call
@@ -7293,30 +7233,7 @@ LLVMGEN(llvm_gen_closure)
int num_components = simpletype.aggregate;
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr, p.offset);
llvm::Type* dest_type = rop.ll.llvm_type(
static_cast<const TypeSpec&>(p.type).simpletype());
dest_base = rop.ll.ptr_to_cast(dest_base, dest_type);
if (num_elements > 1) {
OSL_DASSERT(rop.ll.is_type_array(dest_type));
// The type is an array type,
// which means our pointer is to an array type,
// not to &[0] (the address of the 1st element).
// IE: typedef int Int5Array[5];
// Int5Array *dest_base;
// in contrast to what most of use might consider an array pointer
// int *dest_base;
// So if we dereference Int5Array* to with [4], the 5th element,
// we would be really be pointing to ((int *)dest_base)[5*4] which is
// out of bounds of our 1 instance of Int5Array.
// Thus when dealing with arrays we will just dereference it and get the address to get
// the address of the 1st element.
dest_base = rop.ll.GEP(dest_type, dest_base, 0, 0);
llvm::Type* element_type = rop.ll.element_type_of(dest_type);
dest_type = element_type;
}
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
for (int a = 0; a < num_elements; ++a) {
llvm::Value* arrind = simpletype.arraylen ? rop.ll.constant(a)
@@ -7324,9 +7241,7 @@ LLVMGEN(llvm_gen_closure)
for (int c = 0; c < num_components; c++) {
llvm::Value* dest_elem;
if (num_components > 1)
dest_elem = rop.ll.GEP(dest_type, dest_base, a, c);
else if (num_elements > 1)
dest_elem = rop.ll.GEP(dest_type, dest_base, a);
dest_elem = rop.ll.GEP(dest_base, a, c);
else
dest_elem = dest_base;
@@ -7360,7 +7275,7 @@ LLVMGEN(llvm_gen_closure)
}
llvm_gen_keyword_fill(rop, op, clentry, closure_name, mem_void_ptr,
2 + weighted + clentry->nformal, lane_index);
2 + weighted + clentry->nformal);
if (next_block)
rop.ll.op_branch(next_block);
+46 -91
View File
@@ -63,19 +63,8 @@ Schematically, we want to create code that resembles the following:
float param_1_bar;
};
// Data for the interactively adjusted parameters of this group -- these
// can't be turned into constants because the app may want to modify them
// as it runs (such as for user interaction). This block of memory has
// one global copy specific each the shader group, managed by OSL.
struct InteractiveParams {
float iparam_0_baz;
};
// Name of layer entry is $layer_ID
void $layer_0(ShaderGlobals *sg, GroupData_1 *group,
wide_int* wide_shadeindex_ptr,
void* userdatda_base_ptr, void* output_base_ptr,
int mask, InteractiveParams* interactive_params)
void $layer_0 (ShaderGlobals *sg, GroupData_1 *group)
{
// Declare locals, temps, constants, params with known values.
// Make them all look like stack memory locations:
@@ -85,14 +74,9 @@ Schematically, we want to create code that resembles the following:
// then run the shader body:
*x = sg->u * group->param_0_bar;
group->param_1_foo = *x;
*x += interactive_params->iparam_0_baz;
// ...
}
void $layer_1(ShaderGlobals *sg, GroupData_1 *group,
wide_int* wide_shadeindex_ptr,
void* userdatda_base_ptr, void* output_base_ptr,
int mask, InteractiveParams* interactive_params)
void $layer_1 (ShaderGlobals *sg, GroupData_1 *group)
{
// Because we need the outputs of layer 0 now, we call it if it
// hasn't already run:
@@ -103,10 +87,7 @@ Schematically, we want to create code that resembles the following:
*y = sg->u * group->$param_1_bar;
}
void $group_1(ShaderGlobals *sg, GroupData_1 *group,
wide_int* wide_shadeindex_ptr,
void* userdatda_base_ptr, void* output_base_ptr,
int mask, InteractiveParams* interactive_params)
void $group_1 (ShaderGlobals *sg, GroupData_1 *group)
{
group->layer_run[...] = 0;
// Run just the unconditional layers
@@ -920,13 +901,14 @@ BatchedBackendLLVM::llvm_type_groupdata()
if (offset & (align - 1))
offset += align - (offset & (align - 1));
if (llvm_debug() >= 2)
print(" {} ({}) {} {}, field {}, size {}, offset {}{}{}\n",
inst->layername(), inst->id(), sym.mangled(), ts.c_str(),
order, derivSize * int(sym.size()), offset,
sym.interpolated() ? " (interpolated)" : "",
sym.interactive() ? " (interactive)" : "");
std::cout << " " << inst->layername() << " (" << inst->id()
<< ") " << sym.mangled() << " " << ts.c_str()
<< ", field " << order << ", size "
<< derivSize * int(sym.size()) << ", offset "
<< offset << std::endl;
sym.wide_dataoffset((int)offset);
offset += derivSize * int(sym.size()) * m_width;
m_param_order_map[&sym] = order;
++order;
}
@@ -1059,10 +1041,10 @@ BatchedBackendLLVM::llvm_assign_initial_value(
llvm_assign_zero(sym);
return; // we're done, the parts below are just for params
}
OSL_ASSERT_MSG(sym.symtype() == SymTypeParam
|| sym.symtype() == SymTypeOutputParam,
"symtype was %d, data type was %s", (int)sym.symtype(),
sym.typespec().c_str());
ASSERT_MSG(sym.symtype() == SymTypeParam
|| sym.symtype() == SymTypeOutputParam,
"symtype was %d, data type was %s", (int)sym.symtype(),
sym.typespec().c_str());
// Handle interpolated params by calling osl_bind_interpolated_param,
// which will check if userdata is already retrieved, if not it will
@@ -1077,7 +1059,7 @@ BatchedBackendLLVM::llvm_assign_initial_value(
bool partial_userdata_mask_was_pushed = false;
const SymLocationDesc* symloc = nullptr;
LLVM_Util::ScopedMasking partial_data_masking_scope;
if (sym.interpolated() && !sym.typespec().is_closure()) {
if (!sym.lockgeom() && !sym.typespec().is_closure()) {
ustring symname = sym.name();
TypeDesc type = sym.typespec().simpletype();
@@ -1235,15 +1217,6 @@ BatchedBackendLLVM::llvm_assign_initial_value(
// Handle init ops.
build_llvm_code(sym.initbegin(), sym.initend());
#if 0 /* Is this needed? */
} else if (sym.interpolated() && !sym.typespec().is_closure()) {
// geometrically-varying param; memcpy its default value
TypeDesc t = sym.typespec().simpletype();
ll.op_memcpy(llvm_void_ptr(sym), ll.constant_ptr(sym.data()),
t.size(), t.basesize() /*align*/);
if (sym.has_derivs())
llvm_zero_derivs(sym);
#endif
} else {
// We think the non-memcpy route is preferable as it give the compiler
// a chance to optimize constant values Also memcpy would ignoring the
@@ -1765,17 +1738,16 @@ BatchedBackendLLVM::build_llvm_init()
OSL_ASSERT(m_library_selector);
std::string unique_name = fmtformat("{}_group_{}_init", m_library_selector,
group().id());
ll.current_function(
ll.make_function(unique_name, false,
ll.type_void(), // return type
{
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // wide_shader_index
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int(), // mask
ll.type_void_ptr(), // FIXME: interactive params
}));
ll.current_function(ll.make_function(
unique_name, false,
ll.type_void(), // return type
{
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
static_cast<llvm::Type*>(ll.type_void_ptr()), // wide_shader_index
static_cast<llvm::Type*>(ll.type_void_ptr()), // userdata_base_ptr
static_cast<llvm::Type*>(ll.type_void_ptr()), // output_base_ptr
ll.type_int() // mask
}));
if (ll.debug_is_enabled()) {
ustring file_name
@@ -1785,20 +1757,14 @@ BatchedBackendLLVM::build_llvm_init()
}
// Get shader globals and groupdata pointers
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_groupdata_ptr->setName("groupdata_ptr");
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_wide_shadeindex_ptr = ll.current_function_arg(2); //arg_it++;
m_llvm_wide_shadeindex_ptr->setName("shadeindex");
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
m_llvm_output_base_ptr->setName("output_base_ptr");
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(5);
llvm_initial_shader_mask_value->setName("initial_shader_mask");
m_llvm_interactive_params_ptr = ll.current_function_arg(6); //arg_it++;
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
// TODO: do we need to utilize the shader mask in the init function?
//llvm::Value * llvm_initial_shader_mask_value = ll.current_function_arg(5); //arg_it++;
// New function, reset temp matrix pointer
m_llvm_temp_wide_matrix_ptr = nullptr;
@@ -1847,7 +1813,6 @@ BatchedBackendLLVM::build_llvm_init()
FOREACH_PARAM(Symbol & sym, gi)
{
if (sym.typespec().is_closure_based()) {
OSL_ASSERT(sym.is_varying());
int arraylen = std::max(1, sym.typespec().arraylength());
llvm::Value* val = ll.constant_ptr(NULL, ll.type_void_ptr());
if (!sym.is_uniform())
@@ -1909,11 +1874,10 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
ll.type_void(), // return type
{
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // wide_shader_index
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int(), // mask
ll.type_void_ptr(), // FIXME: interactive params
static_cast<llvm::Type*>(ll.type_void_ptr()), // wide_shader_index
static_cast<llvm::Type*>(ll.type_void_ptr()), // userdata_base_ptr
static_cast<llvm::Type*>(ll.type_void_ptr()), // output_base_ptr
ll.type_int() // mask
}));
if (ll.debug_is_enabled()) {
@@ -1923,20 +1887,14 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
}
// Get shader globals and groupdata pointers
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_groupdata_ptr->setName("groupdata_ptr");
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_wide_shadeindex_ptr = ll.current_function_arg(2); //arg_it++;
m_llvm_wide_shadeindex_ptr->setName("shadeindex");
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
m_llvm_output_base_ptr->setName("output_base_ptr");
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(5);
llvm_initial_shader_mask_value->setName("initial_shader_mask");
m_llvm_interactive_params_ptr = ll.current_function_arg(6); //arg_it++;
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(
5); //arg_it++;
// New function, reset temp matrix pointer
m_llvm_temp_wide_matrix_ptr = nullptr;
@@ -2111,12 +2069,10 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
&& !s.renderer_output())
continue;
// Skip if it's an interpolated (userdata) parameter and we're
// initializing them lazily, or if it's an interactively-adjusted
// parameter.
if (s.symtype() == SymTypeParam && !s.typespec().is_closure()
&& !s.connected() && !s.connected_down()
&& (s.interactive()
|| (s.interpolated() && shadingsys().lazy_userdata())))
// initializing them lazily.
if (s.symtype() == SymTypeParam && !s.lockgeom()
&& !s.typespec().is_closure() && !s.connected()
&& !s.connected_down() && shadingsys().lazy_userdata())
continue;
// Set initial value for params (may contain init ops)
llvm_assign_initial_value(s, llvm_initial_shader_mask_value);
@@ -2139,7 +2095,6 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
// records for each.
find_basic_blocks();
find_conditionals();
m_call_layers_inserted.clear();
build_llvm_code(inst()->maincodebegin(), inst()->maincodeend());
+21 -22
View File
@@ -41,7 +41,7 @@ template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::get_matrix(BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult,
Wide<const ustringhash> wfrom,
Wide<const ustring> wfrom,
Wide<const float> wtime)
{
OSL_ASSERT(
@@ -70,7 +70,7 @@ template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult,
ustringhash to,
ustring to,
Wide<const float> wtime)
{
OSL_ASSERT(
@@ -85,7 +85,7 @@ template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult,
Wide<const ustringhash> wto,
Wide<const ustring> wto,
Wide<const float> wtime)
{
OSL_ASSERT(
@@ -109,13 +109,13 @@ template<int WidthT>
TextureSystem::TextureHandle*
BatchedRendererServices<WidthT>::resolve_udim_uniform(
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
ustringhash filename, TextureSystem::TextureHandle* texture_handle, float S,
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
float T)
{
if (!texture_thread_info)
texture_thread_info = bsg->uniform.context->texture_thread_info();
if (!texture_handle)
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
if (texturesys()->is_udim(texture_handle)) {
// Newer versions of the TextureSystem interface are able to determine the
@@ -141,14 +141,14 @@ template<int WidthT>
void
BatchedRendererServices<WidthT>::resolve_udim(
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
ustring filename, TextureSystem::TextureHandle* texture_handle,
Wide<const float> wS, Wide<const float> wT,
Masked<TextureSystem::TextureHandle*> wresult)
{
if (!texture_thread_info)
texture_thread_info = bsg->uniform.context->texture_thread_info();
if (!texture_handle)
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
if (texturesys()->is_udim(texture_handle)) {
// Newer versions of the TextureSystem interface are able to determine the
@@ -176,17 +176,17 @@ template<int WidthT>
bool
BatchedRendererServices<WidthT>::get_texture_info_uniform(
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
int subimage, ustringhash dataname, RefData val)
ustring filename, TextureSystem::TextureHandle* texture_handle,
int subimage, ustring dataname, RefData val)
{
if (!texture_thread_info)
texture_thread_info = bsg->uniform.context->texture_thread_info();
if (!texture_handle)
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
bool status = texturesys()->get_texture_info(texture_handle, NULL, subimage,
ustring_from(dataname),
val.type(), val.ptr());
dataname, val.type(),
val.ptr());
if (!status) {
std::string err = texturesys()->geterror();
@@ -203,7 +203,7 @@ BatchedRendererServices<WidthT>::get_texture_info_uniform(
template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::texture(
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
ustring filename, TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
Wide<const float> ws, Wide<const float> wt, Wide<const float> wdsdx,
@@ -221,7 +221,7 @@ BatchedRendererServices<WidthT>::texture(
template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::texture3d(
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
ustring filename, TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
Wide<const Vec3> wP, Wide<const Vec3> wdPdx, Wide<const Vec3> wdPdy,
@@ -238,7 +238,7 @@ BatchedRendererServices<WidthT>::texture3d(
template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::environment(
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
ustring filename, TextureSystem::TextureHandle* texture_handle,
TextureSystem::Perthread* texture_thread_info,
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
Wide<const Vec3> wR, Wide<const Vec3> wdRdx, Wide<const Vec3> wdRdy,
@@ -255,7 +255,7 @@ BatchedRendererServices<WidthT>::environment(
template<int WidthT>
void
BatchedRendererServices<WidthT>::pointcloud_search(
BatchedShaderGlobals* bsg, ustringhash filename, const void* wcenter,
BatchedShaderGlobals* bsg, ustring filename, const void* wcenter,
Wide<const float> wradius, int max_points, bool sort,
PointCloudSearchResults& results)
{
@@ -269,8 +269,8 @@ BatchedRendererServices<WidthT>::pointcloud_search(
template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::pointcloud_get(
BatchedShaderGlobals* bsg, ustringhash filename, Wide<const int[]> windices,
Wide<const int> wnum_points, ustringhash attr_name, MaskedData wout_data)
BatchedShaderGlobals* bsg, ustring filename, Wide<const int[]> windices,
Wide<const int> wnum_points, ustring attr_name, MaskedData wout_data)
{
OSL_ASSERT(
0
@@ -283,7 +283,7 @@ BatchedRendererServices<WidthT>::pointcloud_get(
template<int WidthT>
Mask<WidthT>
BatchedRendererServices<WidthT>::pointcloud_write(
BatchedShaderGlobals* bsg, ustringhash filename, Wide<const OSL::Vec3> wpos,
BatchedShaderGlobals* bsg, ustring filename, Wide<const OSL::Vec3> wpos,
int nattribs, const ustring* attr_names, const TypeDesc* attr_types,
const void** pointers_to_wide_attr_value, Mask mask)
{
@@ -312,9 +312,8 @@ BatchedRendererServices<WidthT>::trace(
template<int WidthT>
void
BatchedRendererServices<WidthT>::getmessage(BatchedShaderGlobals* bsg,
Masked<int> wresult,
ustringhash source,
ustringhash name, MaskedData wval)
Masked<int> wresult, ustring source,
ustring name, MaskedData wval)
{
// Currently this code path should only be followed when source == "trace"
OSL_DASSERT(wresult.mask() == wval.mask());
+9 -14
View File
@@ -204,13 +204,13 @@ DECL(osl_dict_next, "iXi")
DECL(osl_dict_value, "iXiXLX")
DECL(osl_raytype_name, "iXs")
#ifdef OSL_LLVM_NO_BITCODE
DECL(osl_range_check, "iiisXsisiss")
DECL(osl_range_check, "iiiXXXiXiXX")
#endif
DECL(osl_range_check_err, "iiisXsisiss")
DECL(osl_naninf_check, "xiXiXsisiis")
DECL(osl_uninit_check, "xLXXsisissisisii")
DECL(osl_get_attribute, "iXissiiLX")
DECL(osl_bind_interpolated_param, "iXsLiXiXiXi")
DECL(osl_range_check_err, "iiiXXXiXiXX")
DECL(osl_naninf_check, "xiXiXXiXiiX")
DECL(osl_uninit_check, "xLXXXiXiXXiXiXii")
DECL(osl_get_attribute, "iXiXXiiLX")
DECL(osl_bind_interpolated_param, "iXXLiXiXiXi")
DECL(osl_get_texture_options, "XX");
DECL(osl_get_noise_options, "XX");
DECL(osl_get_trace_options, "XX");
@@ -248,10 +248,10 @@ UNARY_OP_IMPL(log10)
UNARY_OP_IMPL(exp)
UNARY_OP_IMPL(exp2)
UNARY_OP_IMPL(expm1)
BINARY_OP_IMPL(pow)
UNARY_OP_IMPL(erf)
UNARY_OP_IMPL(erfc)
BINARY_OP_IMPL(pow)
DECL(osl_pow_vvf, "xXXf")
DECL(osl_pow_dvdvdf, "xXXX")
DECL(osl_pow_dvvdf, "xXXX")
@@ -285,12 +285,7 @@ DECL(osl_fabs_ii, "ii")
UNARY_OP_IMPL(abs)
UNARY_OP_IMPL(fabs)
BINARY_OP_IMPL(fmod)
DECL(osl_fmod_vvf, "xXXf")
DECL(osl_fmod_dvdvdf, "xXXX")
DECL(osl_fmod_dvvdf, "xXXX")
DECL(osl_fmod_dvdvf, "xXXf")
DECL(osl_smoothstep_ffff, "ffff")
DECL(osl_smoothstep_dfffdf, "xXffX")
@@ -343,8 +338,8 @@ DECL(osl_substr_ssii, "ssii")
DECL(osl_regex_impl, "iXsXisi")
// Used by wide code generator, but are uniform calls
DECL(osl_texture_decode_wrapmode, "is");
DECL(osl_texture_decode_interpmode, "is");
DECL(osl_texture_decode_wrapmode, "iX");
DECL(osl_texture_decode_interpmode, "iX");
DECL(osl_texture_set_firstchannel, "xXi")
DECL(osl_texture_set_swrap, "xXs")
+15 -15
View File
@@ -315,7 +315,7 @@ DECL(__OSL_MASKED_OP(pointcloud_get), "iXsXiXsLXi")
DECL(__OSL_MASKED_OP(pointcloud_write), "iXsXiXXXi")
DECL(__OSL_MASKED_OP(getmessage), "xXXssLXiisii")
DECL(__OSL_MASKED_OP2(setmessage, s, WX), "xXsLXisii")
DECL(__OSL_MASKED_OP2(setmessage, s, WX), "xXXLXisii")
DECL(__OSL_MASKED_OP2(setmessage, Ws, WX), "xXXLXisii")
DECL(__OSL_OP(blackbody_vf), "xXXf")
@@ -362,24 +362,24 @@ DECL(__OSL_OP(dict_value), "iXiXLX")
DECL(__OSL_MASKED_OP(dict_value), "xXXXXLXi")
DECL(__OSL_OP(raytype_name), "iXs")
DECL(__OSL_OP(raytype_name), "iXX")
DECL(__OSL_MASKED_OP(raytype_name), "xXXXi")
DECL(__OSL_OP(naninf_check), "xiXiXsisiis")
DECL(__OSL_MASKED_OP1(naninf_check_offset, i), "xiiXiXsisiis")
DECL(__OSL_MASKED_OP1(naninf_check_offset, Wi), "xiiXiXsisXis")
DECL(__OSL_OP(range_check), "iiisXsisiss")
DECL(__OSL_MASKED_OP(range_check), "xXiisXsisiss")
DECL(__OSL_OP2(uninit_check_values_offset, X, i), "xLXXsisissisisii")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, X, Wi), "xiLXXsisissisisXi")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, i), "xiLXXsisissisisii")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, Wi), "xiLXXsisissisisXi")
DECL(__OSL_OP(naninf_check), "xiXiXXiXiiX")
DECL(__OSL_MASKED_OP1(naninf_check_offset, i), "xiiXiXXiXiiX")
DECL(__OSL_MASKED_OP1(naninf_check_offset, Wi), "xiiXiXXiXXiX")
DECL(__OSL_OP(range_check), "iiiXXXiXiXX")
DECL(__OSL_MASKED_OP(range_check), "xXiiXXXiXiXX")
DECL(__OSL_OP2(uninit_check_values_offset, X, i), "xLXXXiXiXXiXiXii")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, X, Wi), "xiLXXXiXiXXiXiXXi")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, i), "xiLXXXiXiXXiXiXii")
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, Wi), "xiLXXXiXiXXiXiXXi")
DECL(__OSL_OP1(get_attribute, s), "iXissiiXXi")
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXisXiiXXi")
DECL(__OSL_OP(get_attribute_uniform), "iXissiiXX")
DECL(__OSL_OP1(get_attribute, s), "iXiXXiiXXi")
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXiXXiiXXi")
DECL(__OSL_OP(get_attribute_uniform), "iXiXXiiXX")
// TODO: shouldn't bind_interpolated_param be MASKED? change name to reflect
DECL(__OSL_OP(bind_interpolated_param), "iXsLiXiXiXii")
DECL(__OSL_OP(bind_interpolated_param), "iXXLiXiXiXii")
//DECL (osl_get_texture_options, "XX") // unneeded
DECL(__OSL_OP(get_noise_options), "XX")
+2 -3
View File
@@ -2413,12 +2413,11 @@ DECLFOLDER(constfold_gettextureinfo)
void* mydata = OSL_ALLOCA(char, t.size());
// FIXME(ptex) -- exclude folding of ptex, since these things
// can vary per face.
ustringhash em;
ustring errormessage;
int result = rop.renderer()->get_texture_info(
filename, nullptr, rop.shadingcontext()->texture_thread_info(),
rop.shadingcontext(), 0 /* TODO: subimage? */, dataname, t, mydata,
&em);
ustring errormessage = ustring_from(em);
&errormessage);
// Now we turn
// gettextureinfo result filename dataname data
// into this for success:
+7 -9
View File
@@ -133,7 +133,7 @@ ShadingContext::execute_init(ShaderGroup& sgroup, int shadeindex,
ssg.renderer = renderer();
ssg.Ci = NULL;
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr,
shadeindex, sgroup.interactive_arena_ptr());
shadeindex);
}
if (profile)
@@ -160,8 +160,8 @@ ShadingContext::execute_layer(int shadeindex, ShaderGlobals& ssg,
if (!run_func)
return false;
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr, shadeindex,
group()->interactive_arena_ptr());
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr,
shadeindex);
if (profile)
m_ticks += timer.ticks();
@@ -321,8 +321,7 @@ ShadingContext::Batched<WidthT>::execute_init(
run_mask.set_count_on(batch_size);
run_func(&bsg, context().m_heap.get(), &wide_shadeindex.data(),
userdata_base_ptr, output_base_ptr, run_mask.value(),
sgroup.interactive_arena_ptr());
userdata_base_ptr, output_base_ptr, run_mask.value());
}
}
@@ -361,8 +360,7 @@ ShadingContext::Batched<WidthT>::execute_layer(
run_mask.set_count_on(batch_size);
run_func(&bsg, context().m_heap.get(), &wide_shadeindex.data(),
userdata_base_ptr, output_base_ptr, run_mask.value(),
group()->interactive_arena_ptr());
userdata_base_ptr, output_base_ptr, run_mask.value());
}
if (profile)
@@ -627,8 +625,8 @@ ShadingContext::find_regex(ustring r)
bool
ShadingContext::osl_get_attribute(ShaderGlobals* sg, void* objdata,
int dest_derivs, ustringhash obj_name,
ustringhash attr_name, int array_lookup,
int dest_derivs, ustring obj_name,
ustring attr_name, int array_lookup,
int index, TypeDesc attr_type,
void* attr_dest)
{
+49 -71
View File
@@ -182,8 +182,7 @@ compatible_param(const TypeDesc& a, const TypeDesc& b)
void
ShaderInstance::parameters(const ParamValueList& params,
cspan<ParamHints> hints)
ShaderInstance::parameters(const ParamValueList& params)
{
// Seed the params with the master's defaults
m_iparams = m_master->m_idefaults;
@@ -196,13 +195,11 @@ ShaderInstance::parameters(const ParamValueList& params,
// on the master.
for (int i = 0, e = (int)m_instoverrides.size(); i < e; ++i) {
Symbol* sym = master()->symbol(i);
m_instoverrides[i].interpolated(sym->interpolated());
m_instoverrides[i].interactive(sym->interactive());
m_instoverrides[i].lockgeom(sym->lockgeom());
m_instoverrides[i].dataoffset(sym->dataoffset());
}
for (size_t pi = 0; pi < params.size(); ++pi) {
const ParamValue& p(params[pi]);
for (auto&& p : params) {
if (p.name().size() == 0)
continue; // skip empty names
int i = findparam(p.name());
@@ -247,7 +244,22 @@ ShaderInstance::parameters(const ParamValueList& params,
valuetype = TypeDesc::FLOAT;
}
if (!relaxed_equivalent(sm_typespec, valuetype)) {
// Relaxed rules just look to see that the types are isomorphic to each other (ie: same number of base values)
// Note that:
// * basetypes must match exactly (int vs float vs string)
// * valuetype cannot be unsized (we must know the concrete number of values)
// * if paramtype is sized (or not an array) just check for the total number of entries
// * if paramtype is unsized (shader writer is flexible about how many values come in) -- make sure we are a multiple of the target type
// * allow a single float setting a vec3 (or equivalent)
if (!(valuetype.basetype == paramtype.basetype
&& !valuetype.is_unsized_array()
&& ((!paramtype.is_unsized_array()
&& valuetype.basevalues() == paramtype.basevalues())
|| (paramtype.is_unsized_array()
&& valuetype.basevalues() % paramtype.aggregate
== 0)
|| (paramtype.is_vec3()
&& valuetype == TypeDesc::FLOAT)))) {
// We are being very relaxed in this mode, so if the user _still_ got it wrong
// something more serious is at play and we should treat it as an error.
shadingsys().errorfmt(
@@ -265,14 +277,13 @@ ShaderInstance::parameters(const ParamValueList& params,
// Mark that the override as an instance value
so->valuesource(Symbol::InstanceVal);
// Pass on any interpolated or interactive hints.
auto hint = hints[pi];
so->interpolated(sm->interpolated()
|| (hint & ParamHints::interpolated)
== ParamHints::interpolated);
so->interactive((hint & ParamHints::interactive)
== ParamHints::interactive);
bool lockgeom = !so->interpolated() && !so->interactive();
// Lock the param against geometric primitive overrides if the
// master thinks it was so locked, AND the Parameter() call
// didn't specify lockgeom=false (which would be indicated by
// the parameter's interpolation being non-CONSTANT).
bool lockgeom = (sm->lockgeom()
&& p.interp() == ParamValue::INTERP_CONSTANT);
so->lockgeom(lockgeom);
OSL_DASSERT(so->dataoffset() == sm->dataoffset());
so->dataoffset(sm->dataoffset());
@@ -456,7 +467,7 @@ ShaderInstance::evaluate_writes_globals_and_userdata_params()
// the symbol overrides. This is very important to get instance merging
// working correctly.
for (auto&& s : m_instoverrides) {
if (s.interpolated())
if (!s.lockgeom())
userdata_params(true);
}
}
@@ -495,8 +506,7 @@ ShaderInstance::copy_code_from_master(ShaderGroup& group)
si->arraylen(m_instoverrides[i].arraylen());
si->valuesource(m_instoverrides[i].valuesource());
si->connected_down(m_instoverrides[i].connected_down());
si->interpolated(m_instoverrides[i].interpolated());
si->interactive(m_instoverrides[i].interactive());
si->lockgeom(m_instoverrides[i].lockgeom());
si->dataoffset(m_instoverrides[i].dataoffset());
si->set_dataptr(SymArena::Absolute, param_storage(i));
}
@@ -639,12 +649,10 @@ ShaderInstance::mergeable(const ShaderInstance& b,
continue;
return false;
}
// But still, if they differ in whether they are interpolated or
// interactive, we can't merge the instances.
if (m_instoverrides[i].interpolated()
!= b.m_instoverrides[i].interpolated()
|| m_instoverrides[i].interactive()
!= b.m_instoverrides[i].interactive()) {
// But still, if they differ in their lockgeom'edness, we can't
// merge the instances.
if (m_instoverrides[i].lockgeom()
!= b.m_instoverrides[i].lockgeom()) {
return false;
}
}
@@ -660,14 +668,10 @@ ShaderInstance::mergeable(const ShaderInstance& b,
continue;
if (sym->typespec().is_closure())
continue; // Closures can't have instance override values
// Even if the symbols' values match now, they might not in the
// future with 'interactive' parameters.
const Symbol* b_sym = optimized ? b.symbol(i) : b.mastersymbol(i);
if ((sym->valuesource() == Symbol::InstanceVal
|| sym->valuesource() == Symbol::DefaultVal)
&& (memcmp(param_storage(i), b.param_storage(i),
sym->typespec().simpletype().size())
|| b_sym->interactive())) {
&& memcmp(param_storage(i), b.param_storage(i),
sym->typespec().simpletype().size())) {
return false;
}
}
@@ -732,8 +736,7 @@ ShaderInstance::mergeable(const ShaderInstance& b,
ShaderGroup::ShaderGroup(string_view name, ShadingSystemImpl& shadingsys)
: m_shadingsys(shadingsys)
ShaderGroup::ShaderGroup(string_view name)
{
m_id = ++(*(atomic_int*)&next_id);
if (name.size()) {
@@ -746,6 +749,15 @@ ShaderGroup::ShaderGroup(string_view name, ShadingSystemImpl& shadingsys)
ShaderGroup::ShaderGroup(const ShaderGroup& g, string_view name)
: ShaderGroup(name) // delegate most of the work
{
m_num_entry_layers = g.m_num_entry_layers;
m_layers = g.m_layers;
}
ShaderGroup::~ShaderGroup()
{
#if 0
@@ -760,11 +772,6 @@ ShaderGroup::~ShaderGroup()
<< "executed on " << executions() << " points\n";
}
#endif
// Free any GPU memory associated with this group
if (m_device_interactive_arena)
shadingsys().renderer()->device_free(
m_device_interactive_arena.d_get());
}
@@ -817,34 +824,6 @@ ShaderGroup::mark_entry_layer(int layer)
void
ShaderGroup::setup_interactive_arena(cspan<uint8_t> paramblock)
{
if (paramblock.size()) {
// CPU side
m_interactive_arena_size = paramblock.size();
m_interactive_arena.reset(new uint8_t[m_interactive_arena_size]);
memcpy(m_interactive_arena.get(), paramblock.data(),
m_interactive_arena_size);
if (shadingsys().use_optix()) {
// GPU side
RendererServices* rs = shadingsys().renderer();
m_device_interactive_arena.reset(reinterpret_cast<uint8_t*>(
rs->device_alloc(m_interactive_arena_size)));
rs->copy_to_device(m_device_interactive_arena.d_get(),
paramblock.data(), m_interactive_arena_size);
// print("group {} has device interactive_params set to {:p}\n",
// name(), m_device_interactive_arena.d_get());
}
} else {
m_interactive_arena_size = 0;
m_interactive_arena.reset();
m_device_interactive_arena.reset();
}
}
std::string
ShaderGroup::serialize() const
{
@@ -897,12 +876,11 @@ ShaderGroup::serialize() const
OSL_ASSERT_MSG(0, "unknown type for serialization: %s (%s)",
type.c_str(), s->typespec().c_str());
}
if (dstsyms_exist ? s->interpolated()
: inst->instoverride(p)->interpolated())
print(out, " [[int interpolated=1]]");
if (dstsyms_exist ? s->interactive()
: inst->instoverride(p)->interactive())
print(out, " [[int interactive=1]]");
bool lockgeom = dstsyms_exist
? s->lockgeom()
: inst->instoverride(p)->lockgeom();
if (!lockgeom)
print(out, " [[int lockgeom={}]]", lockgeom);
out << " ;\n";
}
}
+17 -38
View File
@@ -6,6 +6,11 @@
#include <OpenImageIO/fmath.h>
#ifdef OSL_USE_OPTIX
# include <optix.h>
#endif
#include "oslexec_pvt.h"
#include <OSL/genclosure.h>
#include "backendllvm.h"
@@ -111,16 +116,15 @@ BackendLLVM::llvm_call_layer(int layer, bool unconditional)
// Make code that looks like:
// if (! groupdata->run[parentlayer])
// parent_layer (sg, groupdata, userdata_base_ptr,
// output_base_ptr, shadeindex, interactive_params);
// output_base_ptr, shadeindex);
// if it's a conditional call, or
// parent_layer (sg, groupdata, userdata_base_ptr,
// output_base_ptr, shadeindex, interactive_params);
// output_base_ptr, shadeindex);
// if it's run unconditionally.
// The code in the parent layer itself will set its 'executed' flag.
llvm::Value* args[]
= { sg_ptr(), groupdata_ptr(), userdata_base_ptr(),
output_base_ptr(), shadeindex(), m_llvm_interactive_params_ptr };
llvm::Value* args[] = { sg_ptr(), groupdata_ptr(), userdata_base_ptr(),
output_base_ptr(), shadeindex() };
ShaderInstance* parent = group()[layer];
llvm::Value* trueval = ll.constant_bool(true);
@@ -143,8 +147,6 @@ BackendLLVM::llvm_call_layer(int layer, bool unconditional)
if (!unconditional)
ll.op_branch(after_block); // also moves insert point
shadingsys().m_stat_call_layers_inserted++;
}
@@ -191,15 +193,6 @@ BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum,
}
}
if (shadingsys().m_opt_useparam && inmain) {
// m_call_layers_inserted tracks if we've already run this layer inside the current basic block
const CallLayerKey key = { m_bblockids[opnum], con.srclayer };
if (m_call_layers_inserted.count(key)) {
continue;
}
m_call_layers_inserted.insert(key);
}
// If the earlier layer it comes from has not yet been
// executed, do so now.
llvm_call_layer(con.srclayer);
@@ -239,15 +232,12 @@ LLVMGEN(llvm_gen_useparam)
// initializing them lazily, now we have to do it.
if ((sym.symtype() == SymTypeParam
|| sym.symtype() == SymTypeOutputParam)
&& sym.interpolated() && !sym.typespec().is_closure()
&& !sym.lockgeom() && !sym.typespec().is_closure()
&& !sym.connected() && !sym.connected_down()
&& rop.shadingsys().lazy_userdata()) {
rop.llvm_assign_initial_value(sym);
}
}
rop.increment_useparam_ops();
return true;
}
@@ -384,7 +374,6 @@ LLVMGEN(llvm_gen_printf)
}
#if OSL_USE_OPTIX
// In OptiX, printf currently supports 0 or 1 arguments, and the signature
// requires 1 argument, so push a null pointer onto the call args if there
// is no argument.
@@ -393,7 +382,6 @@ LLVMGEN(llvm_gen_printf)
// we push the size of the arguments on the stack
optix_size += sizeof(uint64_t);
}
#endif
// Some ops prepend things
if (op.opname() == op_error || op.opname() == op_warning) {
@@ -402,8 +390,9 @@ LLVMGEN(llvm_gen_printf)
}
// Now go back and put the new format string in its place
#if OSL_USE_OPTIX
if (rop.use_optix()) {
if (!rop.use_optix()) {
call_args[new_format_slot] = rop.llvm_load_string(s);
} else {
// In OptiX7+ case, we do this:
// void* args = { args_size, arg0, arg1, arg2 };
// (where args_size is the size of arg0 + arg1 + arg2...)
@@ -461,10 +450,6 @@ LLVMGEN(llvm_gen_printf)
}
call_args.resize(new_format_slot + 2);
call_args.back() = rop.ll.void_ptr(voids);
} else
#endif
{
call_args[new_format_slot] = rop.llvm_load_string(s);
}
// Construct the function name and call it.
@@ -2476,9 +2461,7 @@ LLVMGEN(llvm_gen_texture)
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
texture_handle
= rop.renderer()->get_texture_handle(Filename.get_string(),
rop.shadingcontext(), nullptr);
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
// that has the colorspace set.
rop.shadingcontext());
}
// Now call the osl_texture function, passing the options and all the
@@ -2543,9 +2526,7 @@ LLVMGEN(llvm_gen_texture3d)
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
texture_handle
= rop.renderer()->get_texture_handle(Filename.get_string(),
rop.shadingcontext(), nullptr);
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
// that has the colorspace set.
rop.shadingcontext());
}
// Now call the osl_texture3d function, passing the options and all the
@@ -2608,9 +2589,7 @@ LLVMGEN(llvm_gen_environment)
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
texture_handle
= rop.renderer()->get_texture_handle(Filename.get_string(),
rop.shadingcontext(), nullptr);
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
// that has the colorspace set.
rop.shadingcontext());
}
// Now call the osl_environment function, passing the options and all the
@@ -3061,7 +3040,7 @@ LLVMGEN(llvm_gen_gettextureinfo)
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
texture_handle
= rop.renderer()->get_texture_handle(Filename.get_string(),
rop.shadingcontext(), nullptr);
rop.shadingcontext());
}
std::vector<llvm::Value*> args;
+45 -92
View File
@@ -18,6 +18,10 @@
#include <OpenImageIO/sysutil.h>
#include <OpenImageIO/timer.h>
#ifdef OSL_USE_OPTIX
# include <optix.h>
#endif
#include "../liboslcomp/oslcomp_pvt.h"
#include "oslexec_pvt.h"
#include "backendllvm.h"
@@ -57,18 +61,10 @@ Schematically, we want to create code that resembles the following:
float param_1_bar;
};
// Data for the interactively adjusted parameters of this group -- these
// can't be turned into constants because the app may want to modify them
// as it runs (such as for user interaction). This block of memory has
// one global copy specific each the shader group, managed by OSL.
struct InteractiveParams {
float iparam_0_baz;
};
// Name of layer entry is $layer_ID
void $layer_0(ShaderGlobals* sg, GroupData* group,
void* userdatda_base_ptr, void* output_base_ptr,
int shadeindex, InteractiveParams* interactive_params)
int shadeindex)
{
// Declare locals, temps, constants, params with known values.
// Make them all look like stack memory locations:
@@ -78,27 +74,25 @@ Schematically, we want to create code that resembles the following:
// then run the shader body:
*x = sg->u * group->param_0_bar;
group->param_1_foo = *x;
*x += interactive_params->iparam_0_baz;
// ...
}
void $layer_1(ShaderGlobals* sg, GroupData* group,
void* userdatda_base_ptr, void* output_base_ptr,
int shadeindex, InteractiveParams* interactive_params)
int shadeindex)
{
// Because we need the outputs of layer 0 now, we call it if it
// hasn't already run:
if (! group->layer_run[0]) {
group->layer_run[0] = 1;
$layer_0 (sg, group, userdata_base_ptr, output_base_ptr,
shadeindex, interactive_params); // because we need its outputs
shadeindex); // because we need its outputs
}
*y = sg->u * group->$param_1_bar;
}
void $group_1(ShaderGlobals* sg, GroupData* group,
void* userdatda_base_ptr, void* output_base_ptr,
int shadeindex, InteractiveParams* interactive_params)
int shadeindex)
{
group->layer_run[...] = 0;
// Run just the unconditional layers
@@ -106,7 +100,7 @@ Schematically, we want to create code that resembles the following:
if (! group->layer_run[1]) {
group->layer_run[1] = 1;
$layer_1(sg, group, userdata_base_ptr, output_base_ptr,
shadeindex, interactive_params);
shadeindex);
}
}
@@ -289,10 +283,14 @@ BackendLLVM::llvm_type_groupdata()
++order;
for (int i = 0; i < nuserdata; ++i) {
TypeDesc type = types[i];
// make room for float derivs only
type.arraylen = type.basetype == TypeDesc::FLOAT
? type.numelements() * 3
: type.numelements();
// NB: Userdata derivs are not currently supported in OptiX, since
// making room for them in the GroupData struct can result in a
// large per-thread memory allocation, which could negatively
// impact performance.
int n = (!use_optix()) ? type.numelements()
* 3 // make room for derivs by default
: type.numelements();
type.arraylen = n;
fields.push_back(llvm_type(type));
m_groupdata_field_names.emplace_back(
fmtformat("userdata{}_{}_", i, names[i]));
@@ -334,8 +332,8 @@ BackendLLVM::llvm_type_groupdata()
&& !sym.connected_down()) {
auto found = group().find_symloc(sym.name());
if (found)
print("layer {} \"{}\" : OUTPUT {}\n", layer,
inst->layername(), found->name);
OIIO::Strutil::print("layer {} \"{}\" : OUTPUT {}\n", layer,
inst->layername(), found->name);
}
// Alignment
@@ -345,11 +343,11 @@ BackendLLVM::llvm_type_groupdata()
if (offset & (align - 1))
offset += align - (offset & (align - 1));
if (llvm_debug() >= 2)
print(" {} ({}) {} {}, field {}, size {}, offset {}{}{}\n",
inst->layername(), inst->id(), sym.mangled(), ts.c_str(),
order, derivSize * int(sym.size()), offset,
sym.interpolated() ? " (interpolated)" : "",
sym.interactive() ? " (interactive)" : "");
std::cout << " " << inst->layername() << " (" << inst->id()
<< ") " << sym.mangled() << " " << ts.c_str()
<< ", field " << order << ", size "
<< derivSize * int(sym.size()) << ", offset "
<< offset << std::endl;
sym.dataoffset((int)offset);
// TODO(arenas): sym.set_dataoffset(SymArena::Heap, offset);
offset += derivSize * sym.size();
@@ -478,7 +476,7 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
// such userdata was available.
llvm::BasicBlock* after_userdata_block = nullptr;
const SymLocationDesc* symloc = nullptr;
if (sym.interpolated() && !sym.typespec().is_closure()) {
if (!sym.lockgeom() && !sym.typespec().is_closure()) {
ustring symname = sym.name();
TypeDesc type = sym.typespec().simpletype();
@@ -562,7 +560,6 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
if (sym.has_init_ops() && sym.valuesource() == Symbol::DefaultVal) {
// Handle init ops.
build_llvm_code(sym.initbegin(), sym.initend());
#if OSL_USE_OPTIX
} else if (use_optix() && !sym.typespec().is_closure()) {
// If the call to osl_bind_interpolated_param returns 0, the default
// value needs to be loaded from a CUDA variable.
@@ -573,10 +570,7 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
llvm::Value* dst = llvm_void_ptr(sym);
TypeDesc t = sym.typespec().simpletype();
ll.op_memcpy(dst, src, t.size(), t.basesize());
if (sym.has_derivs())
llvm_zero_derivs(sym);
#endif
} else if (sym.interpolated() && !sym.typespec().is_closure()) {
} else if (!sym.lockgeom() && !sym.typespec().is_closure()) {
// geometrically-varying param; memcpy its default value
TypeDesc t = sym.typespec().simpletype();
ll.op_memcpy(llvm_void_ptr(sym), ll.constant_ptr(sym.data()),
@@ -870,13 +864,10 @@ BackendLLVM::build_llvm_init()
ll.current_function(
ll.make_function(unique_name, false,
ll.type_void(), // return type
{
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int(),
ll.type_void_ptr(), // FIXME: interactive params
}));
{ llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int() }));
if (ll.debug_is_enabled()) {
ustring sourcefile
@@ -886,17 +877,10 @@ BackendLLVM::build_llvm_init()
// Get shader globals and groupdata pointers
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_groupdata_ptr->setName("groupdata_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_userdata_base_ptr = ll.current_function_arg(2); //arg_it++;
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_output_base_ptr->setName("output_base_ptr");
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
m_llvm_shadeindex->setName("shadeindex");
m_llvm_interactive_params_ptr = ll.current_function_arg(5); //arg_it++;
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
// Set up a new IR builder
llvm::BasicBlock* entry_bb = ll.new_basic_block(unique_name);
@@ -976,13 +960,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
unique_layer_name,
!is_entry_layer, // fastcall for non-entry layer functions
ll.type_void(), // return type
{
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int(),
ll.type_void_ptr(), // FIXME: interactive_params
}));
{ llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
ll.type_void_ptr(), // userdata_base_ptr
ll.type_void_ptr(), // output_base_ptr
ll.type_int() }));
if (ll.debug_is_enabled()) {
const Opcode& mainbegin(inst()->op(inst()->maincodebegin()));
@@ -992,17 +973,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
// Get shader globals and groupdata pointers
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_groupdata_ptr->setName("groupdata_ptr");
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
m_llvm_userdata_base_ptr = ll.current_function_arg(2); //arg_it++;
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_output_base_ptr->setName("output_base_ptr");
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
m_llvm_shadeindex->setName("shadeindex");
m_llvm_interactive_params_ptr = ll.current_function_arg(5); //arg_it++;
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
llvm::BasicBlock* entry_bb = ll.new_basic_block(unique_layer_name);
m_exit_instance_block = NULL;
@@ -1104,12 +1078,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
&& !s.renderer_output())
continue;
// Skip if it's an interpolated (userdata) parameter and we're
// initializing them lazily, or if it's an interactively-adjusted
// parameter.
if (s.symtype() == SymTypeParam && !s.typespec().is_closure()
&& !s.connected() && !s.connected_down()
&& (s.interactive()
|| (s.interpolated() && shadingsys().lazy_userdata())))
// initializing them lazily.
if (s.symtype() == SymTypeParam && !s.lockgeom()
&& !s.typespec().is_closure() && !s.connected()
&& !s.connected_down() && shadingsys().lazy_userdata())
continue;
// Set initial value for params (may contain init ops)
llvm_assign_initial_value(s);
@@ -1132,7 +1104,6 @@ BackendLLVM::build_llvm_instance(bool groupentry)
// records for each.
find_basic_blocks();
find_conditionals();
m_call_layers_inserted.clear();
build_llvm_code(inst()->maincodebegin(), inst()->maincodeend());
@@ -1334,12 +1305,10 @@ BackendLLVM::initialize_llvm_group()
}
types += advance;
}
#if OSL_USE_OPTIX
if (varargs && use_optix()) {
varargs = false;
params.push_back(ll.type_void_ptr());
}
#endif
llvm::Function* f = ll.make_function(funcname, false,
llvm_type(rettype), params,
varargs);
@@ -1395,19 +1364,6 @@ BackendLLVM::run()
#ifdef OSL_LLVM_NO_BITCODE
OSL_ASSERT(!use_rs_bitcode());
ll.module(ll.new_module("llvm_ops"));
# if OSL_USE_OPTIX
if (use_optix()) {
// If the module is created from LLVM bitcode, the target and
// data layout is inherited from that, but if creating an empty
// module like here, have to manually set those, otherwise
// compiling will later fail because the NVPTX target is not found.
// The target triple and data layout used here are those specified
// for NVPTX (https://www.llvm.org/docs/NVPTXUsage.html#triples).
ll.module()->setDataLayout(
"e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
ll.module()->setTargetTriple("nvptx64-nvidia-cuda");
}
# endif
#else
if (!use_optix()) {
if (use_rs_bitcode()) {
@@ -1649,16 +1605,13 @@ BackendLLVM::run()
}
}
#if OSL_USE_OPTIX
if (use_optix()) {
ll.ptx_compile_group(nullptr, group().name().string(),
group().m_llvm_ptx_compiled_version);
if (group().m_llvm_ptx_compiled_version.empty()) {
OSL_ASSERT(0 && "Unable to generate PTX");
}
} else
#endif
{
} else {
// Force the JIT to happen now and retrieve the JITed function pointers
// for the initialization and all public entry points.
group().llvm_compiled_init(
+17 -26
View File
@@ -27,8 +27,9 @@ examples), as you are just coding in C++, but there are some rules:
float. Aggregates (color/point/vector/normal/matrix), arrays of any
types, or floats with derivatives are passed as a void* and to their
memory location you need to cast appropriately. Strings are passed as
ustringrep. See the handy USTR, MAT, VEC, DFLOAT, DVEC macros for
handy/cheap casting of those void*'s to references to ustringrep&,
char*, but they are always the characters of 'ustring' objects, so are
unique. See the handy USTR, MAT, VEC, DFLOAT, DVEC macros for
handy/cheap casting of those void*'s to references to ustring&,
Matrix44&, Vec3&, Dual2<float>&, and Dual2<Vec3>, respectively.
* You must provide all allowable polymorphic and derivative combinations!
@@ -100,23 +101,13 @@ void* __dso_handle = 0; // necessary to avoid linkage issues in bitcode
// Handy re-casting macros
#define USTR(s) (*((ustringrep*)&s))
#define USTREP(s) (*((ustringrep*)&s))
#define MAT(m) (*(Matrix44*)m)
#define VEC(v) (*(Vec3*)v)
#define DFLOAT(x) (*(Dual2<Float>*)x)
#define DVEC(x) (*(Dual2<Vec3>*)x)
#define COL(x) (*(Color3*)x)
#define DCOL(x) (*(Dual2<Color3>*)x)
#if OSL_USTRINGREP_IS_HASH
/// ustring_pod is the type we use to pass string data in llvm function calls.
using ustring_pod = size_t;
#else
/// ustring_pod is the type we use to pass string data in llvm function calls.
using ustring_pod = const char*;
#endif
#define USTR(cstr) (*((ustring*)&cstr))
#define MAT(m) (*(Matrix44*)m)
#define VEC(v) (*(Vec3*)v)
#define DFLOAT(x) (*(Dual2<Float>*)x)
#define DVEC(x) (*(Dual2<Vec3>*)x)
#define COL(x) (*(Color3*)x)
#define DCOL(x) (*(Dual2<Color3>*)x)
#ifndef OSL_SHADEOP
# ifdef __CUDACC__
@@ -984,17 +975,17 @@ osl_raytype_bit(void* sg_, int bit)
// extern declaration
OSL_SHADEOP_NOINLINE int
osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
ustring_pod sourcefile, int sourceline,
ustring_pod groupname, int layer, ustring_pod layername,
ustring_pod shadername);
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername);
OSL_SHADEOP int
osl_range_check(int indexvalue, int length, ustring_pod symname, void* sg,
ustring_pod sourcefile, int sourceline, ustring_pod groupname,
int layer, ustring_pod layername, ustring_pod shadername)
osl_range_check(int indexvalue, int length, const char* symname, void* sg,
const void* sourcefile, int sourceline, const char* groupname,
int layer, const char* layername, const char* shadername)
{
if (indexvalue < 0 || indexvalue >= length) {
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
+19 -41
View File
@@ -92,6 +92,10 @@
#include <llvm/Transforms/Utils/Cloning.h>
#include <llvm/Transforms/Utils/SymbolRewriter.h>
#ifdef OSL_USE_OPTIX
# include <optix.h>
#endif
OSL_NAMESPACE_ENTER
@@ -2451,11 +2455,6 @@ LLVM_Util::make_function(const std::string& name, bool fastcall,
llvm::FunctionType* functype = type_function(rettype, params, varargs);
auto maybe_func = module()->getOrInsertFunction(name, functype).getCallee();
OSL_ASSERT(maybe_func && "getOrInsertFunction returned NULL");
// if (!llvm::isa<llvm::Function>(maybe_func)) {
// print("make_function: getOrInsertFunction returned non-function for {}\n", name);
// for (auto p : params)
// print(" param type: {}\n", llvm_typename(p));
// }
OSL_ASSERT_MSG(llvm::isa<llvm::Function>(maybe_func),
"Declaration for %s is wrong, LLVM had to make a cast",
name.c_str());
@@ -2674,18 +2673,7 @@ LLVM_Util::type_array(llvm::Type* type, int n)
return llvm::ArrayType::get(type, n);
}
bool
LLVM_Util::is_type_array(llvm::Type* type)
{
return type->isArrayTy();
}
llvm::Type*
LLVM_Util::element_type_of(llvm::Type* array_type)
{
OSL_DASSERT(is_type_array(array_type));
return array_type->getArrayElementType();
}
llvm::FunctionType*
LLVM_Util::type_function(llvm::Type* rettype, cspan<llvm::Type*> params,
@@ -2862,21 +2850,15 @@ LLVM_Util::constant(ustring s)
const size_t size_t_bits = sizeof(size_t) * 8;
// Create a const size_t with the ustring character address, or hash,
// depending on the representation we're using.
if (ustring_rep() == UstringRep::charptr) {
return constant_ptr((void*)s.c_str(), type_char_ptr());
} else {
size_t p = s.hash();
auto str = (size_t_bits == 64) ? constant64(p) : constant(int(p));
#if OSL_USTRINGREP_IS_HASH
return str;
#else
// Then cast the int to a char*. Ideally, we would only do that if the rep
// were a charptr, but we disguise the hashes as char*'s also to avoid
// ugliness with function signatures differing between CPU and GPU.
return builder().CreateIntToPtr(str, m_llvm_type_ustring,
"ustring constant");
#endif
}
size_t p = (ustring_rep() == UstringRep::charptr) ? size_t(s.c_str())
: s.hash();
auto str = (size_t_bits == 64) ? constant64(p) : constant(int(p));
// Then cast the int to a char*. Ideally, we would only do that if the rep
// were a charptr, but we disguise the hashes as char*'s also to avoid
// ugliness with function signatures differing between CPU and GPU.
// Maybe some day we'll use the hash representation on both sides?
return builder().CreateIntToPtr(str, m_llvm_type_ustring,
"ustring constant");
}
@@ -3532,12 +3514,8 @@ LLVM_Util::offset_ptr(llvm::Value* ptr, llvm::Value* offset,
llvm::Value*
LLVM_Util::offset_ptr(llvm::Value* ptr, int offset, llvm::Type* ptrtype)
{
if (offset == 0) {
// shortcut for 0 offset
if (ptrtype && ptrtype != type_void_ptr())
ptr = ptr_cast(ptr, ptrtype);
return ptr;
}
if (offset == 0)
return ptr; // shortcut for 0 offset
return offset_ptr(ptr, constant(size_t(offset)), ptrtype);
}
@@ -3613,9 +3591,9 @@ LLVM_Util::call_function(llvm::Value* func, cspan<llvm::Value*> args)
OSL_DASSERT(func);
#if 0
llvm::outs() << "llvm_call_function " << *func << "\n";
llvm::outs() << args.size() << " args:\n";
for (auto a : args)
llvm::outs() << "\t" << *a << "\n";
llvm::outs() << nargs << " args:\n";
for (int i = 0, nargs = args.size(); i < nargs; ++i)
llvm::outs() << "\t" << *(args[i]) << "\n";
#endif
//llvm_gen_debug_printf (std::string("start ") + std::string(name));
#if OSL_LLVM_VERSION >= 110
@@ -5832,7 +5810,7 @@ bool
LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
std::string& out)
{
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
std::string target_triple = module()->getTargetTriple();
OSL_ASSERT(
+2 -8
View File
@@ -171,7 +171,7 @@ OSOReaderToMaster::symbol(SymType symtype, TypeSpec typespec, const char* name_)
sym.dataoffset (m_shadingsys.global_heap_offset (sym.name()));
}
#endif
sym.interpolated(!m_shadingsys.lockgeom_default());
sym.lockgeom(m_shadingsys.lockgeom_default());
m_master->m_symbols.push_back(sym);
m_symmap[name] = int(m_master->m_symbols.size()) - 1;
// Start the index at which we add specified defaults
@@ -419,13 +419,7 @@ OSOReaderToMaster::hint(string_view hintstring)
Symbol& sym(m_master->m_symbols.back());
if (type == TypeDesc::TypeInt && ident == "lockgeom"
&& Strutil::parse_int(h, ival) && ival >= 0)
sym.interpolated(!ival); // soft deprecated
else if (type == TypeDesc::TypeInt && ident == "interpolated"
&& Strutil::parse_int(h, ival) && ival >= 0)
sym.interpolated(ival);
else if (type == TypeDesc::TypeInt && ident == "interactive"
&& Strutil::parse_int(h, ival) && ival >= 0)
sym.interactive(ival);
sym.lockgeom(ival);
else if (type == TypeDesc::TypeInt && ident == "allowconnect"
&& Strutil::parse_int(h, ival) && ival >= 0)
sym.allowconnect(ival);
+5 -1
View File
@@ -18,6 +18,10 @@
#include <OpenImageIO/fmath.h>
#ifdef __CUDACC__
# include <optix.h>
#endif
#include "opcolor.h"
#include "opcolor_impl.h"
@@ -35,7 +39,7 @@ namespace pvt {
#define IlluminantACES 0.32168, 0.33767 /* For ACES, approximate D60 */
namespace { // anon namespace to avoid duplicate OptiX symbols
OSL_CONSTANT_DATA const ColorSystem::Chroma k_color_systems[13] = {
OSL_CONSTANT_DATA const static ColorSystem::Chroma k_color_systems[13] = {
// Index, Name xRed yRed xGreen yGreen xBlue yBlue White point
/* 0 Rec709 */ { 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65 },
/* 1 sRGB */ { 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65 },
+1 -1
View File
@@ -27,7 +27,7 @@ class ShadingContext;
namespace pvt {
class OSLEXECPUBLIC ColorSystem {
class ColorSystem {
#ifdef __CUDACC__
using Context = void*;
#else
+3 -8
View File
@@ -50,13 +50,8 @@ clamp_zero(Color3& c)
//OSL_CONSTANT_DATA const float cie_colour_match[81][3] =
// Choose to access 1d array vs 2d to allow better code generation of gathers
namespace { // anon namespace to avoid duplicate OptiX symbols
// clang-format off
#ifdef __CUDACC__
OSL_CONSTANT_DATA const float cie_colour_match[81*3] =
#else
OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) =
#endif
{
static OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) = {
// clang-format off
0.0014,0.0000,0.0065, 0.0022,0.0001,0.0105, 0.0042,0.0001,0.0201,
0.0076,0.0002,0.0362, 0.0143,0.0004,0.0679, 0.0232,0.0006,0.1102,
0.0435,0.0012,0.2074, 0.0776,0.0022,0.3713, 0.1344,0.0040,0.6456,
@@ -84,8 +79,8 @@ OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) =
0.0007,0.0002,0.0000, 0.0005,0.0002,0.0000, 0.0003,0.0001,0.0000,
0.0002,0.0001,0.0000, 0.0002,0.0001,0.0000, 0.0001,0.0000,0.0000,
0.0001,0.0000,0.0000, 0.0001,0.0000,0.0000, 0.0000,0.0000,0.0000
// clang-format on
};
// clang-format on
} // namespace
+25 -25
View File
@@ -27,34 +27,33 @@ namespace pvt {
OSL_SHADEOP void
osl_setmessage(ShaderGlobals* sg, ustring_pod name_, long long type_, void* val,
int layeridx, ustring_pod sourcefile_, int sourceline)
osl_setmessage(ShaderGlobals* sg, const char* name_, long long type_, void* val,
int layeridx, const char* sourcefile_, int sourceline)
{
ustringhash name = ustringhash_from(USTR(name_));
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
const ustring& name(USTR(name_));
const ustring& sourcefile(USTR(sourcefile_));
// recreate TypeDesc -- we just crammed it into an int!
TypeDesc type = TYPEDESC(type_);
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates closure
bool is_closure = (type.basetype
== TypeDesc::UNKNOWN); // secret code for closure
if (is_closure)
type.basetype = TypeDesc::PTR; // for closures, we store a pointer
MessageList& messages(sg->context->messages());
const Message* m = messages.find(name);
if (m) {
if (m != NULL) {
if (m->name == name) {
// message already exists?
if (m->has_data())
sg->context->errorfmt(
"message \"{}\" already exists (created here: {}:{})"
" cannot set again from {}:{}",
name.c_str(), m->sourcefile.c_str(), m->sourceline,
sourcefile.c_str(), sourceline);
name, m->sourcefile, m->sourceline, sourcefile, sourceline);
else // NOTE: this cannot be triggered when strict_messages=false because we won't record "failed" getmessage calls
sg->context->errorfmt(
"message \"{}\" was queried before being set (queried here: {}:{})"
" setting it now ({}:{}) would lead to inconsistent results",
name.c_str(), m->sourcefile.c_str(), m->sourceline,
sourcefile.c_str(), sourceline);
name, m->sourcefile, m->sourceline, sourcefile, sourceline);
return;
}
}
@@ -65,21 +64,22 @@ osl_setmessage(ShaderGlobals* sg, ustring_pod name_, long long type_, void* val,
OSL_SHADEOP int
osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
osl_getmessage(ShaderGlobals* sg, const char* source_, const char* name_,
long long type_, void* val, int derivs, int layeridx,
ustring_pod sourcefile_, int sourceline)
const char* sourcefile_, int sourceline)
{
ustringhash source = ustringhash_from(USTR(source_));
ustringhash name = ustringhash_from(USTR(name_));
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
const ustring& source(USTR(source_));
const ustring& name(USTR(name_));
const ustring& sourcefile(USTR(sourcefile_));
// recreate TypeDesc -- we just crammed it into an int!
TypeDesc type = TYPEDESC(type_);
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates closure
bool is_closure = (type.basetype
== TypeDesc::UNKNOWN); // secret code for closure
if (is_closure)
type.basetype = TypeDesc::PTR; // for closures, we store a pointer
static ustringrep ktrace("trace");
static ustring ktrace("trace");
if (source == ktrace) {
// Source types where we need to ask the renderer
return sg->renderer->getmessage(sg, source, name, type, val, derivs);
@@ -87,19 +87,19 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
MessageList& messages(sg->context->messages());
const Message* m = messages.find(name);
if (m) {
if (m != NULL) {
if (m->name == name) {
if (m->type != type) {
// found message, but types don't match
sg->context->errorfmt(
"type mismatch for message \"{}\" ({} as {} here: {}:{})"
" cannot fetch as {} from {}:{}",
name.c_str(), m->has_data() ? "created" : "queried",
name, m->has_data() ? "created" : "queried",
m->type == TypeDesc::PTR ? "closure color"
: m->type.c_str(),
m->sourcefile.c_str(), m->sourceline,
is_closure ? "closure color" : type.c_str(),
sourcefile.c_str(), sourceline);
m->sourcefile, m->sourceline,
is_closure ? "closure color" : type.c_str(), sourcefile,
sourceline);
return 0;
}
if (!m->has_data()) {
@@ -113,8 +113,8 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
" but is being queried by layer #{} ({}:{})"
" - messages may only be transferred from nodes "
"that appear earlier in the shading network",
name.c_str(), m->layeridx, m->sourcefile.c_str(),
m->sourceline, layeridx, sourcefile.c_str(), sourceline);
name, m->layeridx, m->sourcefile, m->sourceline, layeridx,
sourcefile, sourceline);
return 0;
}
// Message found!
@@ -127,7 +127,7 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
}
// Message not found -- we must record this event in case another layer tries to set the message again later on
if (sg->context->shadingsys().strict_messages())
messages.add(name, nullptr, type, layeridx, sourcefile, sourceline);
messages.add(name, NULL, type, layeridx, sourcefile, sourceline);
return 0;
}
+50 -65
View File
@@ -43,31 +43,32 @@ osl_texture_set_firstchannel(void* opt, int x)
}
OSL_SHADEOP int
osl_texture_decode_wrapmode(ustring_pod name)
osl_texture_decode_wrapmode(void* name)
{
return OIIO::TextureOpt::decode_wrapmode(ustring_from(USTR(name)));
const ustring& uname = USTR(name);
return OIIO::TextureOpt::decode_wrapmode(uname);
}
OSL_SHADEOP void
osl_texture_set_swrap(void* opt, ustring_pod x)
osl_texture_set_swrap(void* opt, const char* x)
{
((TextureOpt*)opt)->swrap = TextureOpt::decode_wrapmode(USTR(x));
}
OSL_SHADEOP void
osl_texture_set_twrap(void* opt, ustring_pod x)
osl_texture_set_twrap(void* opt, const char* x)
{
((TextureOpt*)opt)->twrap = TextureOpt::decode_wrapmode(USTR(x));
}
OSL_SHADEOP void
osl_texture_set_rwrap(void* opt, ustring_pod x)
osl_texture_set_rwrap(void* opt, const char* x)
{
((TextureOpt*)opt)->rwrap = TextureOpt::decode_wrapmode(USTR(x));
}
OSL_SHADEOP void
osl_texture_set_stwrap(void* opt, ustring_pod x)
osl_texture_set_stwrap(void* opt, const char* x)
{
TextureOpt::Wrap code = TextureOpt::decode_wrapmode(USTR(x));
((TextureOpt*)opt)->swrap = code;
@@ -162,15 +163,16 @@ osl_texture_set_time(void* opt, float x)
}
OSL_SHADEOP int
osl_texture_decode_interpmode(ustring_pod name)
osl_texture_decode_interpmode(void* name)
{
return tex_interp_to_code(ustring_from(USTR(name)));
const ustring& uname = USTR(name);
return tex_interp_to_code(uname);
}
OSL_SHADEOP void
osl_texture_set_interp(void* opt, ustring_pod modename)
osl_texture_set_interp(void* opt, const char* modename)
{
int mode = tex_interp_to_code(ustring_from(USTR(modename)));
int mode = tex_interp_to_code(USTR(modename));
if (mode >= 0)
((TextureOpt*)opt)->interpmode = (TextureOpt::InterpMode)mode;
}
@@ -189,9 +191,9 @@ osl_texture_set_subimage(void* opt, int subimage)
OSL_SHADEOP void
osl_texture_set_subimagename(void* opt, ustring_pod subimagename)
osl_texture_set_subimagename(void* opt, const char* subimagename)
{
((TextureOpt*)opt)->subimagename = ustring_from(USTR(subimagename));
((TextureOpt*)opt)->subimagename = USTR(subimagename);
}
OSL_SHADEOP void
@@ -215,20 +217,19 @@ OSL_SHADEOP int
osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
float t, float dsdx, float dtdx, float dsdy, float dtdy, int chans,
void* result, void* dresultdx, void* dresultdy, void* alpha,
void* dalphadx, void* dalphady, ustringrep* errormessage)
void* dalphadx, void* dalphady, ustring* errormessage)
{
ShaderGlobals* sg = (ShaderGlobals*)sg_;
TextureOpt* opt = (TextureOpt*)opt_;
bool derivs = (dresultdx || dalphadx);
// It's actually faster to ask for 4 channels (even if we need fewer)
// and ensure that they're being put in aligned memory.
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd;
ustringhash em;
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd;
bool ok = sg->renderer->texture(
USTR(name).uhash(), (TextureSystem::TextureHandle*)handle,
USTR(name), (TextureSystem::TextureHandle*)handle,
sg->context->texture_thread_info(), *opt, sg, s, t, dsdx, dtdx, dsdy,
dtdy, 4, (float*)&result_simd, derivs ? (float*)&dresultds_simd : NULL,
derivs ? (float*)&dresultdt_simd : NULL, errormessage ? &em : nullptr);
derivs ? (float*)&dresultdt_simd : NULL, errormessage);
for (int i = 0; i < chans; ++i)
((float*)result)[i] = result_simd[i];
@@ -239,10 +240,10 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
if (derivs) {
OSL_DASSERT((dresultdx == nullptr) == (dresultdy == nullptr));
OSL_DASSERT((dalphadx == nullptr) == (dalphady == nullptr));
OIIO::simd::vfloat4 dresultdx_simd = dresultds_simd * dsdx
+ dresultdt_simd * dtdx;
OIIO::simd::vfloat4 dresultdy_simd = dresultds_simd * dsdy
+ dresultdt_simd * dtdy;
OIIO::simd::float4 dresultdx_simd = dresultds_simd * dsdx
+ dresultdt_simd * dtdx;
OIIO::simd::float4 dresultdy_simd = dresultds_simd * dsdy
+ dresultdt_simd * dtdy;
if (dresultdx) {
for (int i = 0; i < chans; ++i)
((float*)dresultdx)[i] = dresultdx_simd[i];
@@ -255,9 +256,8 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
}
}
if (errormessage)
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
: ustringrep_from(em);
if (ok && errormessage)
*errormessage = Strings::_emptystring_;
return ok;
}
@@ -267,7 +267,7 @@ OSL_SHADEOP int
osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
void* dPdx_, void* dPdy_, void* dPdz_, int chans, void* result,
void* dresultdx, void* dresultdy, void* alpha, void* dalphadx,
void* dalphady, ustringrep* errormessage)
void* dalphady, ustring* errormessage)
{
const Vec3& P(*(Vec3*)P_);
const Vec3& dPdx(*(Vec3*)dPdx_);
@@ -281,16 +281,14 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
bool derivs = (dresultdx != NULL || dalphadx != NULL);
// It's actually faster to ask for 4 channels (even if we need fewer)
// and ensure that they're being put in aligned memory.
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd,
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd,
dresultdr_simd;
ustringhash em;
bool ok = sg->renderer->texture3d(
USTR(name).uhash(), (TextureSystem::TextureHandle*)handle,
USTR(name), (TextureSystem::TextureHandle*)handle,
sg->context->texture_thread_info(), *opt, sg, P, dPdx, dPdy, dPdz, 4,
(float*)&result_simd, derivs ? (float*)&dresultds_simd : nullptr,
derivs ? (float*)&dresultdt_simd : nullptr,
derivs ? (float*)&dresultdr_simd : nullptr,
errormessage ? &em : nullptr);
derivs ? (float*)&dresultdr_simd : nullptr, errormessage);
for (int i = 0; i < chans; ++i)
((float*)result)[i] = result_simd[i];
@@ -299,12 +297,12 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
// Correct our str texture space gradients into xyz-space gradients
if (derivs) {
OIIO::simd::vfloat4 dresultdx_simd = dresultds_simd * dPdx.x
+ dresultdt_simd * dPdx.y
+ dresultdr_simd * dPdx.z;
OIIO::simd::vfloat4 dresultdy_simd = dresultds_simd * dPdy.x
+ dresultdt_simd * dPdy.y
+ dresultdr_simd * dPdy.z;
OIIO::simd::float4 dresultdx_simd = dresultds_simd * dPdx.x
+ dresultdt_simd * dPdx.y
+ dresultdr_simd * dPdx.z;
OIIO::simd::float4 dresultdy_simd = dresultds_simd * dPdy.x
+ dresultdt_simd * dPdy.y
+ dresultdr_simd * dPdy.z;
if (dresultdx) {
for (int i = 0; i < chans; ++i)
((float*)dresultdx)[i] = dresultdx_simd[i];
@@ -317,9 +315,8 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
}
}
if (errormessage)
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
: ustringrep_from(em);
if (ok && errormessage)
*errormessage = Strings::_emptystring_;
return ok;
}
@@ -329,7 +326,7 @@ OSL_SHADEOP int
osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
void* dRdx_, void* dRdy_, int chans, void* result,
void* dresultdx, void* dresultdy, void* alpha, void* dalphadx,
void* dalphady, ustringrep* errormessage)
void* dalphady, ustring* errormessage)
{
const Vec3& R(*(Vec3*)R_);
const Vec3& dRdx(*(Vec3*)dRdx_);
@@ -338,14 +335,13 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
TextureOpt* opt = (TextureOpt*)opt_;
// It's actually faster to ask for 4 channels (even if we need fewer)
// and ensure that they're being put in aligned memory.
OIIO::simd::vfloat4 local_result;
ustringhash em;
bool ok = sg->renderer->environment(USTR(name).uhash(),
OIIO::simd::float4 local_result;
bool ok = sg->renderer->environment(USTR(name),
(TextureSystem::TextureHandle*)handle,
sg->context->texture_thread_info(),
*opt, sg, R, dRdx, dRdy, 4,
(float*)&local_result, NULL, NULL,
errormessage ? &em : nullptr);
errormessage);
for (int i = 0; i < chans; ++i)
((float*)result)[i] = local_result[i];
@@ -372,9 +368,8 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
((float*)dalphady)[0] = 0.0f;
}
if (errormessage)
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
: ustringrep_from(em);
if (ok && errormessage)
*errormessage = Strings::_emptystring_;
return ok;
}
@@ -383,7 +378,7 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
OSL_SHADEOP int
osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
int type, int arraylen, int aggregate, void* data,
ustringrep* errormessage)
ustring* errormessage)
{
// recreate TypeDesc
TypeDesc typedesc;
@@ -393,15 +388,10 @@ osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
ShaderGlobals* sg = (ShaderGlobals*)sg_;
ustringhash em;
bool ok = sg->renderer->get_texture_info(
USTR(name).uhash(), (RendererServices::TextureHandle*)handle,
return sg->renderer->get_texture_info(
USTR(name), (RendererServices::TextureHandle*)handle,
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
if (errormessage)
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
: ustringrep_from(em);
return ok;
USTR(dataname), typedesc, data, errormessage);
}
@@ -409,7 +399,7 @@ osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
OSL_SHADEOP int
osl_get_textureinfo_st(void* sg_, const char* name, void* handle, float s,
float t, void* dataname, int type, int arraylen,
int aggregate, void* data, ustringrep* errormessage)
int aggregate, void* data, ustring* errormessage)
{
// recreate TypeDesc
TypeDesc typedesc;
@@ -419,15 +409,10 @@ osl_get_textureinfo_st(void* sg_, const char* name, void* handle, float s,
ShaderGlobals* sg = (ShaderGlobals*)sg_;
ustringhash em;
bool ok = sg->renderer->get_texture_info(
USTR(name).uhash(), (RendererServices::TextureHandle*)handle, s, t,
return sg->renderer->get_texture_info(
USTR(name), (RendererServices::TextureHandle*)handle, s, t,
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
if (errormessage)
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
: ustringrep_from(em);
return ok;
USTR(dataname), typedesc, data, errormessage);
}
+56 -168
View File
@@ -19,6 +19,7 @@
// Pull in the modified Imath headers and the OSL_HOSTDEVICE macro
#ifdef __CUDACC__
# include <OSL/oslconfig.h>
# include <optix.h>
#endif
#ifdef __CUDACC__
@@ -33,7 +34,6 @@
#include "osl_pvt.h"
#include <OSL/device_ptr.h>
#include <OSL/dual.h>
#include <OSL/dual_vec.h>
#include <OSL/genclosure.h>
@@ -100,16 +100,14 @@ print_closure(std::ostream& out, const ClosureColor* closure,
/// group.
typedef void (*RunLLVMGroupFunc)(void* shaderglobals, void* heap_arena_ptr,
void* userdata_base_pointer,
void* output_base_pointer, int shadeindex,
void* interactive_params_ptr);
void* output_base_pointer, int shadeindex);
#if OSL_USE_BATCHED
typedef void (*RunLLVMGroupFuncWide)(void* batchedshaderglobals,
void* heap_arena_ptr,
const void* wide_shade_index,
void* userdata_base_pointer,
void* output_base_pointer,
int run_mask_value,
void* interactive_params_ptr);
int run_mask_value);
#endif
/// Signature of a constant-folding method
@@ -194,10 +192,8 @@ struct UserDataNeeded {
{
if (a.name != b.name)
return a.name < b.name;
// Checking for layer_num means that if derivs differ find_userdata_index
// may find the wrong layer symbol with the wrong derivs setting.
//if (a.layer_num != b.layer_num)
// return a.layer_num < b.layer_num;
if (a.layer_num != b.layer_num)
return a.layer_num < b.layer_num;
if (a.type.basetype != b.type.basetype)
return a.type.basetype < b.type.basetype;
if (a.type.aggregate != b.type.aggregate)
@@ -216,11 +212,9 @@ struct UserDataNeeded {
struct AttributeNeeded {
ustring name;
ustring scope;
TypeDesc type;
AttributeNeeded(ustring name, ustring scope = ustring(),
TypeDesc type = TypeUnknown)
: name(name), scope(scope), type(type)
AttributeNeeded(ustring name, ustring scope = ustring())
: name(name), scope(scope)
{
}
@@ -230,15 +224,6 @@ struct AttributeNeeded {
return a.name < b.name;
if (a.scope != b.scope)
return a.scope < b.scope;
if (a.type.basetype != b.type.basetype)
return a.type.basetype < b.type.basetype;
if (a.type.aggregate != b.type.aggregate)
return a.type.aggregate < b.type.aggregate;
if (a.type.arraylen != b.type.arraylen)
return a.type.arraylen < b.type.arraylen;
// Ignore vector semantics
// if (a.type.vecsemantics != b.type.vecsemantics)
// return a.type.vecsemantics < b.type.vecsemantics;
return false; // they are equal
}
};
@@ -249,33 +234,18 @@ struct AttributeNeeded {
// Handy re-casting macros
inline ustringrep
USTR(ustring_pod s) noexcept
{
return OSL::bitcast<ustringrep>(s);
}
inline ustringrep
USTREP(ustring_pod s) noexcept
{
return OSL::bitcast<ustringrep>(s);
// return *((ustringrep*)&s);
}
// Get rid of this one soon!
inline ustringrep
USTR(const void* s) noexcept
{
return OSL::bitcast<ustringrep>(s);
}
#define MAT(m) (*(Matrix44*)m)
#define VEC(v) (*(Vec3*)v)
#define DFLOAT(x) (*(Dual2<Float>*)x)
#define DVEC(x) (*(Dual2<Vec3>*)x)
#define COL(x) (*(Color3*)x)
#define DCOL(x) (*(Dual2<Color3>*)x)
#define TYPEDESC(x) OSL::bitcast<TypeDesc, long long>(x)
#define USTR(cstr) (*((ustring*)&cstr))
#define MAT(m) (*(Matrix44*)m)
#define VEC(v) (*(Vec3*)v)
#define DFLOAT(x) (*(Dual2<Float>*)x)
#define DVEC(x) (*(Dual2<Vec3>*)x)
#define COL(x) (*(Color3*)x)
#define DCOL(x) (*(Dual2<Color3>*)x)
#if OPENIMAGEIO_VERSION >= 20500
# define TYPEDESC(x) OIIO::bitcast<TypeDesc, long long>(x)
#else
# define TYPEDESC(x) OIIO::bit_cast<long long, TypeDesc>(x)
#endif
/// Like an int (of type T), but also internally keeps track of the
@@ -555,9 +525,9 @@ public:
void* val);
bool LoadMemoryCompiledShader(string_view shadername, string_view buffer);
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
const void* val, ParamHints props);
const void* val, bool lockgeom);
bool Parameter(string_view name, TypeDesc t, const void* val,
ParamHints props);
bool lockgeom);
bool Shader(ShaderGroup& group, string_view shaderusage,
string_view shadername, string_view layername);
bool Shader(string_view shaderusage, string_view shadername,
@@ -642,7 +612,6 @@ public:
///
TextureSystem* texturesys() const { return m_texturesys; }
bool use_optix() const { return m_use_optix; }
bool debug_nan() const { return m_debugnan; }
bool debug_uninit() const { return m_debug_uninit; }
bool lockgeom_default() const { return m_lockgeom_default; }
@@ -727,7 +696,7 @@ public:
/// Set the current color space.
bool set_colorspace(ustring colorspace);
OSLEXECPUBLIC int raytype_bit(ustring name);
int raytype_bit(ustring name);
void optimize_all_groups(int nthreads = 0, int mythread = 0,
int totalthreads = 1, bool do_jit = true);
@@ -893,7 +862,6 @@ private:
bool m_opt_middleman; ///< Middle-man optimization?
bool m_opt_texture_handle; ///< Use texture handles?
bool m_opt_seed_bblock_aliases; ///< Turn on basic block alias seeds
bool m_opt_useparam; ///< Perform extra useparam analysis for culling run layer calls
bool m_opt_batched_analysis; ///< Perform extra analysis required for batched execution?
bool m_llvm_jit_fma; ///< Allow fused multiply/add in JIT
bool m_llvm_jit_aggressive; ///< Turn on llvm "aggressive" JIT
@@ -927,8 +895,7 @@ private:
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
std::vector<SymLocationDesc> m_symlocs;
int m_max_local_mem_KB; ///< Local storage can a shader use
int m_compile_report; ///< Print compilation report?
bool m_use_optix; ///< This is an OptiX-based renderer
bool m_compile_report; ///< Print compilation report?
bool m_buffer_printf; ///< Buffer/batch printf output?
bool m_no_noise; ///< Substitute trivial noise calls
bool m_no_pointcloud; ///< Substitute trivial pointcloud calls
@@ -974,8 +941,6 @@ private:
atomic_int m_stat_global_connections; ///< Stat: global connections elim'd
atomic_int m_stat_tex_calls_codegened; ///< Stat: total texture calls
atomic_int m_stat_tex_calls_as_handles; ///< Stat: texture calls with handles
atomic_int m_stat_useparam_ops; ///< Stat: pre-optimization useparam ops
atomic_int m_stat_call_layers_inserted; ///< Stat: post-opt layer calls
double m_stat_master_load_time; ///< Stat: time loading masters
double m_stat_optimization_time; ///< Stat: time spent optimizing
double m_stat_opt_locking_time; ///< locking time
@@ -1150,7 +1115,8 @@ public:
ShadingSystemImpl& shadingsys() const { return m_master->shadingsys(); }
/// Apply pending parameters
void parameters(const ParamValueList& params, cspan<ParamHints> hints);
///
void parameters(const ParamValueList& params);
/// Find the named symbol, return its index in the symbol array, or
/// -1 if not found.
@@ -1410,16 +1376,14 @@ public:
// Using bit fields to keep the data in 8 bytes in total.
unsigned char m_valuesource : 3;
bool m_connected_down : 1;
bool m_interpolated : 1;
bool m_interactive : 1;
int m_arraylen : 26;
bool m_lockgeom : 1;
int m_arraylen : 27;
int m_data_offset;
SymOverrideInfo()
: m_valuesource(Symbol::DefaultVal)
, m_connected_down(false)
, m_interpolated(false)
, m_interactive(false)
, m_lockgeom(true)
, m_arraylen(0)
, m_data_offset(0)
{
@@ -1436,10 +1400,8 @@ public:
bool connected_down() const { return m_connected_down; }
void connected_down(bool c) { m_connected_down = c; }
bool connected() const { return valuesource() == Symbol::ConnectedVal; }
bool interpolated() const { return m_interpolated; }
void interpolated(bool val) { m_interpolated = val; }
bool interactive() const { return m_interactive; }
void interactive(bool val) { m_interactive = val; }
bool lockgeom() const { return m_lockgeom; }
void lockgeom(bool l) { m_lockgeom = l; }
int arraylen() const { return m_arraylen; }
void arraylen(int s) { m_arraylen = s; }
int dataoffset() const { return m_data_offset; }
@@ -1448,13 +1410,11 @@ public:
const SymOverrideInfo& b)
{
return a.valuesource() == b.valuesource()
&& a.interpolated() == b.interpolated()
&& a.interactive() == b.interactive()
&& a.lockgeom() == b.lockgeom()
&& a.arraylen() == b.arraylen();
}
};
typedef std::vector<SymOverrideInfo> SymOverrideInfoVec;
static_assert(sizeof(SymOverrideInfo) == 8, "SymOverrideInfo size");
SymOverrideInfo* instoverride(int i)
{
@@ -1573,8 +1533,8 @@ private:
/// Represents a single message for use by getmessage and setmessage opcodes
///
struct Message {
Message(ustringhash name, const TypeDesc& type, int layeridx,
ustringhash sourcefile, int sourceline, Message* next)
Message(ustring name, const TypeDesc& type, int layeridx,
ustring sourcefile, int sourceline, Message* next)
: name(name)
, data(nullptr)
, type(type)
@@ -1585,42 +1545,43 @@ struct Message {
{
}
/// Some messages don't have data because getmessage() was called before
/// setmessage (which is flagged as an error to avoid ambiguities caused
/// by execution order)
/// Some messages don't have data because getmessage() was called before setmessage
/// (which is flagged as an error to avoid ambiguities caused by execution order)
///
bool has_data() const { return data != nullptr; }
ustringhash name; ///< name of this message
ustring name; ///< name of this message
char* data; ///< actual data of the message (will never change once the message is created)
TypeDesc type; ///< what kind of data is stored here?
int layeridx; ///< layer index where this was message was created
ustringhash sourcefile; ///< location of the call that created this message
int sourceline; ///< location of the call that created this message
TypeDesc
type; ///< what kind of data is stored here? FIXME: should be TypeSpec
int layeridx; ///< layer index where this was message was created
ustring
sourcefile; ///< source code file that contains the call that created this message
int sourceline; ///< source code line that contains the call that created this message
Message* next; ///< linked list of messages (managed by MessageList below)
};
/// Represents the list of messages set by a given shader using setmessage and
/// getmessage.
/// Represents the list of messages set by a given shader using setmessage and getmessage
///
struct MessageList {
MessageList() : list_head(nullptr), message_data() {}
void clear()
{
list_head = nullptr;
list_head = NULL;
message_data.clear();
}
const Message* find(ustringhash name) const
const Message* find(ustring name) const
{
for (const Message* m = list_head; m; m = m->next)
for (const Message* m = list_head; m != NULL; m = m->next)
if (m->name == name)
return m; // name matches
return nullptr; // not found
}
void add(ustringhash name, void* data, const TypeDesc& type, int layeridx,
ustringhash sourcefile, int sourceline)
void add(ustring name, void* data, const TypeDesc& type, int layeridx,
ustring sourcefile, int sourceline)
{
list_head = new (message_data.alloc(sizeof(Message), alignof(Message)))
Message(name, type, layeridx, sourcefile, sourceline, list_head);
@@ -1664,7 +1625,8 @@ struct BatchedMessageBuffer {
/// ShaderInstance), and the connections among them.
class ShaderGroup {
public:
ShaderGroup(string_view name, ShadingSystemImpl& shadingsys);
ShaderGroup(string_view name);
ShaderGroup(const ShaderGroup& g, string_view name);
~ShaderGroup();
/// Clear the layers
@@ -1694,9 +1656,6 @@ public:
/// Array indexing returns the i-th layer of the group
ShaderInstance* operator[](int i) const { return layer(i); }
/// Return a reference to the shading system for this group.
ShadingSystemImpl& shadingsys() const { return m_shadingsys; }
int optimized() const { return m_optimized; }
void optimized(int opt) { m_optimized = opt; }
@@ -1923,54 +1882,6 @@ public:
return nullptr;
}
// Given a data block for interactive params, allocate space for it to
// live with the group and copy the initial data.
void setup_interactive_arena(cspan<uint8_t> paramblock);
uint8_t* interactive_arena_ptr()
{
return m_interactive_arena.get();
}
device_ptr<uint8_t>& device_interactive_arena()
{
return m_device_interactive_arena;
}
struct InteractiveParamData {
int layer;
ustring name;
int offset;
InteractiveParamData(int layer, ustring name, int offset)
: layer(layer), name(name), offset(offset)
{
}
bool operator==(const InteractiveParamData& other) const
{
return layer == other.layer && name == other.name;
}
bool operator<(const InteractiveParamData& other) const
{
return layer < other.layer
|| (layer == other.layer && name < other.name);
}
};
void add_interactive_param(int layer, ustring name, size_t offset)
{
m_interactive_params.emplace_back(layer, name,
static_cast<int>(offset));
}
int interactive_param_offset(int layer, ustring name)
{
for (auto& f : m_interactive_params)
if (f.layer == layer && f.name == name)
return f.offset;
return -1;
}
private:
// Put all the things that are read-only (after optimization) and
// needed on every shade execution at the front of the struct, as much
@@ -2014,7 +1925,6 @@ private:
std::vector<void*> m_userdata_init_vals;
std::vector<ustring> m_attributes_needed;
std::vector<ustring> m_attribute_scopes;
std::vector<TypeDesc> m_attribute_types;
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
std::vector<SymLocationDesc> m_symlocs; ///< SORTED!!
bool m_unknown_textures_needed;
@@ -2026,18 +1936,9 @@ private:
// PTX assembly for compiled ShaderGroup
std::string m_llvm_ptx_compiled_version;
ParamValueList m_pending_params; // Pending Parameter() values
std::vector<ParamHints> m_pending_hints; // ParamHints of pending params
ustring m_group_use; // "Usage" of group
bool m_complete = false; // Successfully ShaderGroupEnd?
ShadingSystemImpl& m_shadingsys; // Back-ptr to the shading system
// Per-group home for interactively editable parameters
std::vector<InteractiveParamData> m_interactive_params;
std::unique_ptr<uint8_t[]> m_interactive_arena;
size_t m_interactive_arena_size = 0;
device_ptr<uint8_t> m_device_interactive_arena;
ParamValueList m_pending_params; ///< Pending Parameter() values
ustring m_group_use; ///< "Usage" of group
bool m_complete = false; ///< Successfully ShaderGroupEnd?
friend class OSL::pvt::ShadingSystemImpl;
friend class OSL::pvt::BackendLLVM;
@@ -2309,7 +2210,7 @@ public:
int dict_value(int nodeID, ustring attribname, TypeDesc type, void* data);
bool osl_get_attribute(ShaderGlobals* sg, void* objdata, int dest_derivs,
ustringhash obj_name, ustringhash attr_name,
ustring obj_name, ustring attr_name,
int array_lookup, int index, TypeDesc attr_type,
void* attr_dest);
@@ -2692,19 +2593,6 @@ protected:
std::vector<char> m_in_conditional; ///< Whether each op is in a cond
std::vector<char> m_in_loop; ///< Whether each op is in a loop
int m_first_return; ///< Op number of first return or exit
struct CallLayerKey {
int bblockid;
int layerid;
bool operator<(const CallLayerKey& other) const
{
return bblockid < other.bblockid
|| (bblockid == other.bblockid && layerid < other.layerid);
}
};
std::set<CallLayerKey>
m_call_layers_inserted; ///< Lookup used during llvm gen
};
}; // namespace pvt
+1 -1
View File
@@ -27,7 +27,7 @@
#pragma clang diagnostic ignored "-Wparentheses-equality"
#endif
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
#if OSL_CLANG_VERSION >= 150000
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#endif
+21 -2
View File
@@ -288,8 +288,7 @@ public:
}
// TODO: This is really the only part of parsing that needs the lock still.
// The calling code no longer sets the global locale, so it would
// likely be simple to clean this up.
// But the calling code setting locale complicates this.
//
bool parse(OSOReader* reader, const char* what) {
yy_switch_to_buffer(m_buffer, m_scanner);
@@ -311,6 +310,12 @@ OSOReader::parse_file (const std::string &filename)
// can actually be reading a .oso file at a time.
std::lock_guard<std::mutex> guard (osoread_mutex);
// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
std::locale oldlocale; // save the previous native locale
std::locale::global (std::locale::classic());
FILE* osoin = OIIO::Filesystem::fopen (filename, "r");
if (! osoin) {
m_err.errorfmt("File {} not found", filename);
@@ -321,6 +326,7 @@ OSOReader::parse_file (const std::string &filename)
bool ok = scope.parse(this, filename.c_str());
fclose (osoin);
std::locale::global (oldlocale); // Restore the original locale.
return ok;
}
@@ -333,9 +339,22 @@ OSOReader::parse_memory (const std::string &buffer)
// can actually be reading a .oso file at a time.
std::lock_guard<std::mutex> guard (osoread_mutex);
#ifndef OIIO_STRUTIL_HAS_STOF
// Force classic "C" locale for correct '.' decimal parsing.
// N.B. This is not safe in a multi-threaded program where another
// application thread is expecting the native locale to work properly.
// This is not necessary for versions of OIIO that have Strutil::stof,
// and we can remove it entirely when OIIO 1.9 is the minimum.
std::locale oldlocale = std::locale::global (std::locale::classic());
#endif
Scope scope(buffer);
bool ok = scope.parse(this, "preloaded OSO code");
#ifndef OIIO_STRUTIL_HAS_STOF
std::locale::global (oldlocale); // Restore the original locale.
#endif
return ok;
}
+40 -46
View File
@@ -12,26 +12,25 @@ OSL_NAMESPACE_ENTER
namespace pvt {
#ifdef USE_PARTIO
using PointCloudMap
= std::unordered_map<ustringhash, std::unique_ptr<PointCloud>>;
typedef std::unordered_map<ustring, std::unique_ptr<PointCloud>> PointCloudMap;
static PointCloudMap pointclouds;
static OIIO::spin_mutex pointcloudmap_mutex;
PointCloud*
PointCloud::get(ustringhash filename, bool write)
PointCloud::get(ustring filename, bool write)
{
if (filename.empty())
return nullptr;
return NULL;
spin_lock lock(pointcloudmap_mutex);
PointCloudMap::const_iterator found = pointclouds.find(filename);
if (found != pointclouds.end())
return found->second.get();
// Not found. Create a new one.
Partio::ParticlesDataMutable* partio_cloud = nullptr;
Partio::ParticlesDataMutable* partio_cloud = NULL;
if (!write) {
partio_cloud = Partio::read(filename.c_str(), false);
if (!partio_cloud)
return nullptr;
return NULL;
} else {
partio_cloud = Partio::create();
}
@@ -41,7 +40,7 @@ PointCloud::get(ustringhash filename, bool write)
}
PointCloud::PointCloud(ustringhash filename,
PointCloud::PointCloud(ustring filename,
Partio::ParticlesDataMutable* partio_cloud, bool write)
: m_filename(filename), m_partio_cloud(partio_cloud), m_write(write)
{
@@ -77,10 +76,8 @@ PointCloud::~PointCloud()
} // namespace pvt
int
RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
RendererServices::pointcloud_search(ShaderGlobals* sg, ustring filename,
const Vec3& center, float radius,
int max_points, bool sort,
size_t* out_indices, float* out_distances,
@@ -89,17 +86,17 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
#ifdef USE_PARTIO
if (filename.empty())
return 0;
PointCloud* pc = PointCloud::get(ustring_from(filename));
PointCloud* pc = PointCloud::get(filename);
if (pc == NULL) { // The file failed to load
sg->context->errorfmt("pointcloud_search: could not open \"{}\"",
ustring_from(filename));
filename);
return 0;
}
const Partio::ParticlesData* cloud = pc->read_access();
if (cloud == NULL) { // The file failed to load
sg->context->errorfmt("pointcloud_search: could not open \"{}\"",
ustring_from(filename));
filename);
return 0;
}
@@ -195,26 +192,25 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
int
RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
size_t* indices, int count,
ustringhash attr_name, TypeDesc attr_type,
void* out_data)
RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
size_t* indices, int count, ustring attr_name,
TypeDesc attr_type, void* out_data)
{
#ifdef USE_PARTIO
if (!count)
return 1; // always succeed if not asking for any data
PointCloud* pc = PointCloud::get(ustring_from(filename));
PointCloud* pc = PointCloud::get(filename);
if (pc == NULL) { // The file failed to load
sg->context->errorfmt("pointcloud_get: could not open \"{}\"",
ustring_from(filename));
filename);
return 0;
}
const Partio::ParticlesData* cloud = pc->read_access();
if (cloud == NULL) { // The file failed to load
sg->context->errorfmt("pointcloud_get: could not open \"{}\"",
ustring_from(filename));
filename);
return 0;
}
@@ -223,7 +219,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
if (!attr) {
sg->context->errorfmt(
"Accessing unexisting attribute {} in pointcloud \"{}\"", attr_name,
ustring_from(filename));
filename);
return 0;
}
@@ -236,7 +232,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
if (!compatiblePartioType(partio_type, element_type)) {
sg->context->errorfmt(
"Type of attribute \"{}\" : {} not compatible with OSL's {} in \"{}\" pointcloud",
attr_name, partio_type, element_type, ustring_from(filename));
attr_name, partio_type, element_type, filename);
return 0;
}
@@ -267,9 +263,9 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
for (int i = 0; i < count; ++i) {
int ind = strindices[i];
if (ind >= 0 && ind < sicount)
((ustringrep*)out_data)[i] = ustringrep(strings[ind]);
((ustring*)out_data)[i] = ustring(strings[ind]);
else
((ustringrep*)out_data)[i] = ustringrep();
((ustring*)out_data)[i] = ustring();
}
} else {
// All cases aside from strings are simple.
@@ -290,16 +286,15 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
bool
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustring filename,
const Vec3& pos, int nattribs,
const ustringrep* names,
const TypeDesc* types, const void** data)
const ustring* names, const TypeDesc* types,
const void** data)
{
#ifdef USE_PARTIO
if (filename.empty())
return false;
PointCloud* pc = PointCloud::get(ustring_from(filename),
true /* create file to write */);
PointCloud* pc = PointCloud::get(filename, true /* create file to write */);
spin_lock lock(pc->m_mutex);
Partio::ParticlesDataMutable* cloud = pc->write_access();
if (cloud == NULL) // The file failed to load
@@ -351,11 +346,10 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
*(int*)cloud->dataWrite<int>(*a, p) = *(int*)(data[i]);
break;
case Partio::INDEXEDSTR: {
ustringrep s = *(ustringrep*)(data[i]);
const char* sstr = s.c_str();
int index = cloud->lookupIndexedStr(*a, sstr);
const char* s = *(const char**)(data[i]);
int index = cloud->lookupIndexedStr(*a, s);
if (index == -1)
index = cloud->registerIndexedStr(*a, sstr);
index = cloud->registerIndexedStr(*a, s);
*(int*)cloud->dataWrite<int>(*a, p) = index;
} break;
case Partio::NONE: break;
@@ -372,7 +366,7 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
namespace pvt {
OSL_SHADEOP int
osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
float radius, int max_points, int sort, void* out_indices,
void* out_distances, int derivs_offset, int nattrs, ...)
{
@@ -399,11 +393,11 @@ osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
va_list args;
va_start(args, nattrs);
for (int i = 0; i < nattrs; i++) {
ustring_pod attr_name_rep = (ustring_pod)va_arg(args, ustring_pod);
ustringrep attr_name = USTR(attr_name_rep);
long long lltype = va_arg(args, long long);
TypeDesc attr_type = TYPEDESC(lltype);
void* out_data = va_arg(args, void*);
ustring attr_name = ustring::from_unique(
(const char*)va_arg(args, const char*));
long long lltype = va_arg(args, long long);
TypeDesc attr_type = TYPEDESC(lltype);
void* out_data = va_arg(args, void*);
sg->renderer->pointcloud_get(sg, USTR(filename), indices, count,
attr_name, attr_type, out_data);
}
@@ -422,8 +416,8 @@ osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
OSL_SHADEOP int
osl_pointcloud_get(ShaderGlobals* sg, ustring_pod filename, void* in_indices,
int count, ustring_pod attr_name, long long attr_type,
osl_pointcloud_get(ShaderGlobals* sg, const char* filename, void* in_indices,
int count, const char* attr_name, long long attr_type,
void* out_data)
{
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
@@ -444,8 +438,8 @@ osl_pointcloud_get(ShaderGlobals* sg, ustring_pod filename, void* in_indices,
OSL_SHADEOP void
osl_pointcloud_write_helper(ustringrep* names, TypeDesc* types, void** values,
int index, ustring_pod name, long long type,
osl_pointcloud_write_helper(ustring* names, TypeDesc* types, void** values,
int index, const char* name, long long type,
void* val)
{
names[index] = USTR(name);
@@ -456,9 +450,9 @@ osl_pointcloud_write_helper(ustringrep* names, TypeDesc* types, void** values,
OSL_SHADEOP int
osl_pointcloud_write(ShaderGlobals* sg, ustring_pod filename, const Vec3* pos,
int nattribs, const ustringrep* names,
const TypeDesc* types, const void** values)
osl_pointcloud_write(ShaderGlobals* sg, const char* filename, const Vec3* pos,
int nattribs, const ustring* names, const TypeDesc* types,
const void** values)
{
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
if (shadingsys.no_pointcloud()) // Debug mode to skip pointcloud expense
+5 -5
View File
@@ -15,14 +15,14 @@ namespace pvt {
#ifdef USE_PARTIO
class OSLEXECPUBLIC PointCloud {
class PointCloud {
public:
PointCloud(ustringhash filename, Partio::ParticlesDataMutable* partio_cloud,
PointCloud(ustring filename, Partio::ParticlesDataMutable* partio_cloud,
bool write);
~PointCloud();
static PointCloud* get(ustringhash filename, bool write = false);
static PointCloud* get(ustring filename, bool write = false);
typedef std::unordered_map<ustringhash,
typedef std::unordered_map<ustring,
std::unique_ptr<Partio::ParticleAttribute>>
AttributeMap;
@@ -37,7 +37,7 @@ public:
return m_partio_cloud;
}
ustringhash m_filename;
ustring m_filename;
private:
// hide just this field, because we want to control how it is accessed
+30 -140
View File
@@ -47,24 +47,6 @@ RendererServices::texturesys() const
bool
RendererServices::get_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash from, float time)
{
return false;
}
bool
RendererServices::get_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash from)
{
return false;
}
bool
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform, float time)
@@ -91,9 +73,8 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
bool
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash to, float time)
ustring to, float time)
{
// return get_inverse_matrix(sg, result, ustring_from(to), time);
bool ok = get_matrix(sg, result, to, time);
if (ok)
result.invert();
@@ -104,9 +85,8 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
bool
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash to)
ustring to)
{
// return get_inverse_matrix(sg, result, ustring_from(to));
bool ok = get_matrix(sg, result, to);
if (ok)
result.invert();
@@ -115,60 +95,11 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
bool
RendererServices::transform_points(ShaderGlobals* sg, ustringhash from,
ustringhash to, float time, const Vec3* Pin,
Vec3* Pout, int npoints,
TypeDesc::VECSEMANTICS vectype)
{
return false;
}
bool
RendererServices::get_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, void* val)
{
return false;
}
bool
RendererServices::get_array_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, int index, void* val)
{
return false;
}
bool
RendererServices::get_userdata(bool derivatives, ustringhash name,
TypeDesc type, ShaderGlobals* sg, void* val)
{
return false;
// return get_userdata(derivatives, ustring_from(name), type, sg, val);
}
RendererServices::TextureHandle*
RendererServices::get_texture_handle(ustringhash filename,
ShadingContext* context,
const TextureOpt* options)
RendererServices::get_texture_handle(ustring filename, ShadingContext* context)
{
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
return texturesys()->get_texture_handle(ustring_from(filename),
context->texture_thread_info(),
options);
#else
return texturesys()->get_texture_handle(ustring_from(filename),
return texturesys()->get_texture_handle(filename,
context->texture_thread_info());
#endif
}
@@ -189,26 +120,20 @@ RendererServices::is_udim(TextureHandle* texture_handle)
bool
RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
RendererServices::texture(ustring filename, TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg, float s,
float t, float dsdx, float dtdx, float dsdy,
float dtdy, int nchannels, float* result,
float* dresultds, float* dresultdt,
ustringhash* errormessage)
ustring* errormessage)
{
ShadingContext* context = sg->context;
if (!texture_thread_info)
texture_thread_info = context->texture_thread_info();
if (!texture_handle)
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
texture_handle
= texturesys()->get_texture_handle(ustring_from(filename),
texture_thread_info, &options);
#else
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
#endif
bool status = texturesys()->texture(texture_handle, texture_thread_info,
options, s, t, dsdx, dtdx, dsdy, dtdy,
nchannels, result, dresultds,
@@ -217,12 +142,12 @@ RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
std::string err = texturesys()->geterror();
if (err.size() && sg) {
if (errormessage) {
*errormessage = ustringhash(err);
*errormessage = ustring(err);
} else {
context->errorfmt("[RendererServices::texture] {}", err);
}
} else if (errormessage) {
*errormessage = ustringhash(Strings::unknown);
*errormessage = Strings::unknown;
}
}
return status;
@@ -231,26 +156,20 @@ RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
bool
RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
RendererServices::texture3d(ustring filename, TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg,
const Vec3& P, const Vec3& dPdx, const Vec3& dPdy,
const Vec3& dPdz, int nchannels, float* result,
float* dresultds, float* dresultdt,
float* dresultdr, ustringhash* errormessage)
float* dresultdr, ustring* errormessage)
{
ShadingContext* context = sg->context;
if (!texture_thread_info)
texture_thread_info = context->texture_thread_info();
if (!texture_handle)
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
texture_handle
= texturesys()->get_texture_handle(ustring_from(filename),
texture_thread_info, &options);
#else
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
#endif
bool status = texturesys()->texture3d(texture_handle, texture_thread_info,
options, P, dPdx, dPdy, dPdz,
@@ -260,12 +179,12 @@ RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
std::string err = texturesys()->geterror();
if (err.size() && sg) {
if (errormessage) {
*errormessage = ustringhash(err);
*errormessage = ustring(err);
} else {
sg->context->errorfmt("[RendererServices::texture3d] {}", err);
}
} else if (errormessage) {
*errormessage = Strings::unknown.uhash();
*errormessage = Strings::unknown;
}
}
return status;
@@ -274,26 +193,19 @@ RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
bool
RendererServices::environment(ustringhash filename,
TextureHandle* texture_handle,
RendererServices::environment(ustring filename, TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
TextureOpt& options, ShaderGlobals* sg,
const Vec3& R, const Vec3& dRdx, const Vec3& dRdy,
int nchannels, float* result, float* dresultds,
float* dresultdt, ustringhash* errormessage)
float* dresultdt, ustring* errormessage)
{
ShadingContext* context = sg->context;
if (!texture_thread_info)
texture_thread_info = context->texture_thread_info();
if (!texture_handle)
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
texture_handle
= texturesys()->get_texture_handle(ustring_from(filename),
texture_thread_info, &options);
#else
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
#endif
bool status = texturesys()->environment(texture_handle, texture_thread_info,
options, R, dRdx, dRdy, nchannels,
result, dresultds, dresultdt);
@@ -301,13 +213,13 @@ RendererServices::environment(ustringhash filename,
std::string err = texturesys()->geterror();
if (err.size() && sg) {
if (errormessage) {
*errormessage = ustringhash(err);
*errormessage = ustring(err);
} else {
sg->context->errorfmt("[RendererServices::environment] {}",
err);
}
} else if (errormessage) {
*errormessage = Strings::unknown.uhash();
*errormessage = Strings::unknown;
}
}
return status;
@@ -316,35 +228,34 @@ RendererServices::environment(ustringhash filename,
bool
RendererServices::get_texture_info(ustringhash filename,
RendererServices::get_texture_info(ustring filename,
TextureHandle* texture_handle,
TexturePerthread* texture_thread_info,
ShadingContext* shading_context,
int subimage, ustringhash dataname,
int subimage, ustring dataname,
TypeDesc datatype, void* data,
ustringhash* errormessage)
ustring* errormessage)
{
if (!texture_thread_info)
texture_thread_info = shading_context->texture_thread_info();
if (!texture_handle)
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
bool status = texturesys()->get_texture_info(texture_handle,
texture_thread_info, subimage,
ustring_from(dataname),
datatype, data);
dataname, datatype, data);
if (!status) {
std::string err = texturesys()->geterror();
if (err.size()) {
if (errormessage) {
*errormessage = ustringhash(err);
*errormessage = ustring(err);
} else {
shading_context->errorfmt(
"[RendererServices::get_texture_info] {}", err);
}
} else if (errormessage) {
// gettextureinfo failed but did not provide an error, so none should be emitted
*errormessage = ustringhash();
*errormessage = ustring();
}
}
return status;
@@ -354,10 +265,10 @@ RendererServices::get_texture_info(ustringhash filename,
bool
RendererServices::get_texture_info(
ustringhash filename, TextureHandle* texture_handle, float s, float t,
ustring filename, TextureHandle* texture_handle, float s, float t,
TexturePerthread* texture_thread_info, ShadingContext* shading_context,
int subimage, ustringhash dataname, TypeDesc datatype, void* data,
ustringhash* errormessage)
int subimage, ustring dataname, TypeDesc datatype, void* data,
ustring* errormessage)
{
#if OIIO_VERSION >= 20307
// Newer versions of the TextureSystem interface are able to determine the
@@ -365,7 +276,7 @@ RendererServices::get_texture_info(
if (!texture_thread_info)
texture_thread_info = shading_context->texture_thread_info();
if (!texture_handle)
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
texture_handle = texturesys()->get_texture_handle(filename,
texture_thread_info);
if (texturesys()->is_udim(texture_handle)) {
TextureSystem::TextureHandle* udim_handle
@@ -386,27 +297,6 @@ RendererServices::get_texture_info(
bool
RendererServices::trace(TraceOpt& options, ShaderGlobals* sg,
const OSL::Vec3& P, const OSL::Vec3& dPdx,
const OSL::Vec3& dPdy, const OSL::Vec3& R,
const OSL::Vec3& dRdx, const OSL::Vec3& dRdy)
{
return false;
}
bool
RendererServices::getmessage(ShaderGlobals* sg, ustringhash source,
ustringhash name, TypeDesc type, void* val,
bool derivatives)
{
return false;
}
BatchedRendererServices<16>*
RendererServices::batched(WidthOf<16>)
{
+16 -55
View File
@@ -889,10 +889,8 @@ RuntimeOptimizer::simplify_params()
Symbol* s(inst()->symbol(i));
if (s->symtype() != SymTypeParam)
continue; // Skip non-params
// Don't simplify params that are interpolated or interactively
// editable
if (s->interpolated() || s->interactive())
continue;
if (!s->lockgeom())
continue; // Don't mess with params that can change with the geom
if (s->typespec().is_structure() || s->typespec().is_closure_based())
continue; // We don't mess with struct placeholders or closures
@@ -969,7 +967,7 @@ RuntimeOptimizer::simplify_params()
// examining.
ShaderInstance* uplayer = group()[c.srclayer];
Symbol* srcsym = uplayer->symbol(c.src.param);
if (srcsym->interpolated())
if (!srcsym->lockgeom())
continue; // Not if it can be overridden by geometry
// Is the source symbol known to be a global, from
@@ -2186,7 +2184,7 @@ RuntimeOptimizer::optimize_ops(int beginop, int endop,
if (opnum == inst()->m_maincodebegin) {
for (int i = inst()->firstparam(); i < inst()->lastparam(); ++i) {
Symbol* s(inst()->symbol(i));
if (s->symtype() == SymTypeOutputParam && !s->interpolated()
if (s->symtype() == SymTypeOutputParam && s->lockgeom()
&& (s->valuesource() == Symbol::DefaultVal
|| s->valuesource() == Symbol::InstanceVal)
&& !s->has_init_ops() && !s->typespec().is_closure_based()
@@ -2493,7 +2491,7 @@ RuntimeOptimizer::resolve_isconnected()
s = inst()->symbol(fieldsymid);
}
bool upconnected = s->connected();
if (s->interpolated() && shadingsys().userdata_isconnected())
if (!s->lockgeom() && shadingsys().userdata_isconnected())
upconnected = true;
int val = (upconnected ? 1 : 0) + (s->connected_down() ? 2 : 0);
turn_into_assign(op, add_constant(TypeDesc::TypeInt, &val),
@@ -3253,7 +3251,6 @@ RuntimeOptimizer::run()
m_userdata_needed.clear();
m_attributes_needed.clear();
bool does_nothing = true;
std::vector<uint8_t> interactive_data;
for (int layer = 0; layer < nlayers; ++layer) {
set_inst(layer);
if (inst()->unused())
@@ -3265,7 +3262,7 @@ RuntimeOptimizer::run()
// Find interpolated parameters
if ((s.symtype() == SymTypeParam
|| s.symtype() == SymTypeOutputParam)
&& s.interpolated()) {
&& !s.lockgeom()) {
UserDataNeeded udn(s.name(), layer, s.typespec().simpletype(),
s.data(), s.has_derivs());
std::set<UserDataNeeded>::iterator found;
@@ -3277,21 +3274,6 @@ RuntimeOptimizer::run()
m_userdata_needed.insert(udn);
}
}
// Find interactive parameters
if (s.symtype() == SymTypeParam && s.interactive()) {
// Make enough room in interactive_data to accommodate this
// interactive parameter, including correct alignment.
size_t offset = interactive_data.size();
size_t typesize = s.typespec().simpletype().size();
size_t alignment = typesize > 4 ? 8 : 4;
offset = OIIO::round_to_multiple_of_pow2(offset, alignment);
interactive_data.resize(offset + typesize);
// Copy from the instance value to the interactive block
memcpy(&interactive_data[offset], s.data(), typesize);
// Make sure the symbol remembers it's stored in the interactive
// arena with the right offset.
group().add_interactive_param(layer, s.name(), offset);
}
// Track which globals the group needs
if (s.symtype() == SymTypeGlobal) {
m_globals_needed.insert(s.name());
@@ -3349,44 +3331,27 @@ RuntimeOptimizer::run()
OSL_DASSERT(sym1 && sym1->typespec().is_string());
if (sym1->is_constant()) {
if (op.nargs() == 3) {
Symbol* sym2 = opargsym(op, 2);
// getattribute( attributename, result )
m_attributes_needed.insert(
AttributeNeeded(sym1->get_string(), ustring(),
sym2->typespec().simpletype()));
} else if (op.nargs() == 4) {
AttributeNeeded(sym1->get_string()));
} else {
OSL_DASSERT(op.nargs() == 4 || op.nargs() == 5);
Symbol* sym2 = opargsym(op, 2);
Symbol* sym3 = opargsym(op, 3);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, result )
// getattribute( scopename, attributename, result ) or
// getattribute( scopename, attributename, arrayindex, result )
if (sym2->is_constant()) {
m_attributes_needed.insert(AttributeNeeded(
sym2->get_string(), sym1->get_string(),
sym3->typespec().simpletype()));
m_attributes_needed.insert(
AttributeNeeded(sym2->get_string(),
sym1->get_string()));
} else {
m_unknown_attributes_needed = true;
}
} else {
// getattribute( attributename, arrayindex, result )
m_attributes_needed.insert(
AttributeNeeded(sym1->get_string(), ustring(),
sym3->typespec().simpletype()));
AttributeNeeded(sym1->get_string()));
}
} else if (op.nargs() == 5) {
Symbol* sym2 = opargsym(op, 2);
Symbol* sym4 = opargsym(op, 4);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, arrayindex, result )
if (sym2->is_constant()) {
m_attributes_needed.insert(AttributeNeeded(
sym2->get_string(), sym1->get_string(),
sym4->typespec().simpletype()));
} else {
m_unknown_attributes_needed = true;
}
}
} else {
OSL_DASSERT(false);
}
} else { // sym1 not constant
m_unknown_attributes_needed = true;
@@ -3395,7 +3360,6 @@ RuntimeOptimizer::run()
}
}
group().does_nothing(does_nothing);
group().setup_interactive_arena(interactive_data);
m_stat_specialization_time = rop_timer();
{
@@ -3420,8 +3384,6 @@ RuntimeOptimizer::run()
new_nops, old_nops,
100.0 * double((long long)new_nops - (long long)old_nops)
/ double(old_nops));
}
if (shadingsys().m_compile_report > 1) {
if (does_nothing)
shadingcontext()->infofmt("Group does nothing");
if (m_textures_needed.size()) {
@@ -3441,8 +3403,7 @@ RuntimeOptimizer::run()
if (m_attributes_needed.size()) {
shadingcontext()->infofmt("Group needs attributes:");
for (auto&& f : m_attributes_needed)
shadingcontext()->infofmt(" {} {} {}", f.name, f.scope,
f.type);
shadingcontext()->infofmt(" {} {}", f.name, f.scope);
if (m_unknown_attributes_needed)
shadingcontext()->infofmt(
" Also may construct attribute names on the fly.");
+64 -132
View File
@@ -151,18 +151,18 @@ ShadingSystem::ShaderGroupEnd(void)
bool
ShadingSystem::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
const void* val, ParamHints hints)
const void* val, bool lockgeom)
{
return m_impl->Parameter(group, name, t, val, hints);
return m_impl->Parameter(group, name, t, val, lockgeom);
}
bool
ShadingSystem::Parameter(string_view name, TypeDesc t, const void* val,
ParamHints hints)
bool lockgeom)
{
return m_impl->Parameter(name, t, val, hints);
return m_impl->Parameter(name, t, val, lockgeom);
}
@@ -943,8 +943,6 @@ ShadingSystem::convert_value(void* dst, TypeDesc dsttype, const void* src,
return false; // Unsupported conversion
}
void
register_JIT_Global(const char* global_var_name, void* global_var_addr)
{
@@ -1026,14 +1024,16 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
, m_opt_middleman(true)
, m_opt_texture_handle(true)
, m_opt_seed_bblock_aliases(true)
, m_opt_useparam(false)
,
#if OSL_USE_BATCHED
, m_opt_batched_analysis((renderer->batched(WidthOf<16>()) != nullptr)
|| (renderer->batched(WidthOf<8>()) != nullptr))
m_opt_batched_analysis((renderer->batched(WidthOf<16>()) != nullptr)
|| (renderer->batched(WidthOf<8>()) != nullptr))
,
#else
, m_opt_batched_analysis(false)
m_opt_batched_analysis(false)
,
#endif
, m_llvm_jit_fma(false)
m_llvm_jit_fma(false)
, m_llvm_jit_aggressive(false)
, m_optimize_nondebug(false)
, m_vector_width(4)
@@ -1049,8 +1049,7 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
, m_llvm_output_bitcode(0)
, m_llvm_dumpasm(0)
, m_max_local_mem_KB(2048)
, m_compile_report(0)
, m_use_optix(renderer->supports("OptiX"))
, m_compile_report(false)
, m_buffer_printf(true)
, m_no_noise(false)
, m_no_pointcloud(false)
@@ -1094,8 +1093,6 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
m_stat_global_connections = 0;
m_stat_tex_calls_codegened = 0;
m_stat_tex_calls_as_handles = 0;
m_stat_useparam_ops = 0;
m_stat_call_layers_inserted = 0;
m_stat_master_load_time = 0;
m_stat_optimization_time = 0;
m_stat_getattribute_time = 0;
@@ -1536,7 +1533,6 @@ ShadingSystemImpl::attribute(string_view name, TypeDesc type, const void* val)
ATTR_SET("opt_middleman", int, m_opt_middleman);
ATTR_SET("opt_texture_handle", int, m_opt_texture_handle);
ATTR_SET("opt_seed_bblock_aliases", int, m_opt_seed_bblock_aliases);
ATTR_SET("opt_useparam", int, m_opt_useparam);
ATTR_SET("opt_batched_analysis", int, m_opt_batched_analysis);
ATTR_SET("llvm_jit_fma", int, m_llvm_jit_fma);
ATTR_SET("llvm_jit_aggressive", int, m_llvm_jit_aggressive);
@@ -1706,7 +1702,6 @@ ShadingSystemImpl::getattribute(string_view name, TypeDesc type, void* val)
ATTR_DECODE("opt_middleman", int, m_opt_middleman);
ATTR_DECODE("opt_texture_handle", int, m_opt_texture_handle);
ATTR_DECODE("opt_seed_bblock_aliases", int, m_opt_seed_bblock_aliases);
ATTR_DECODE("opt_useparam", int, m_opt_useparam);
ATTR_DECODE("llvm_jit_fma", int, m_llvm_jit_fma);
ATTR_DECODE("llvm_jit_aggressive", int, m_llvm_jit_aggressive);
ATTR_DECODE_STRING("llvm_jit_target", m_llvm_jit_target);
@@ -1773,8 +1768,6 @@ ShadingSystemImpl::getattribute(string_view name, TypeDesc type, void* val)
ATTR_DECODE("stat:global_connections", int, m_stat_global_connections);
ATTR_DECODE("stat:tex_calls_codegened", int, m_stat_tex_calls_codegened);
ATTR_DECODE("stat:tex_calls_as_handles", int, m_stat_tex_calls_as_handles);
ATTR_DECODE("stat:useparam_ops", int, m_stat_useparam_ops);
ATTR_DECODE("stat:call_layers_inserted", int, m_stat_call_layers_inserted);
ATTR_DECODE("stat:master_load_time", float, m_stat_master_load_time);
ATTR_DECODE("stat:optimization_time", float, m_stat_optimization_time);
ATTR_DECODE("stat:opt_locking_time", float, m_stat_opt_locking_time);
@@ -2017,14 +2010,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
*(std::string*)val = exists ? group->m_llvm_ptx_compiled_version : "";
return true;
}
if (name == "interactive_params" && type.basetype == TypeDesc::PTR) {
*(void**)val = group->m_interactive_arena.get();
return true;
}
if (name == "device_interactive_params" && type.basetype == TypeDesc::PTR) {
*(void**)val = group->m_device_interactive_arena.d_get();
return true;
}
// All the remaining attributes require the group to already be
// optimized.
@@ -2120,11 +2105,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
*(ustring**)val = n ? &group->m_attribute_scopes[0] : NULL;
return true;
}
if (name == "attribute_types" && type.basetype == TypeDesc::PTR) {
size_t n = group->m_attribute_types.size();
*(TypeDesc**)val = n ? &group->m_attribute_types[0] : NULL;
return true;
}
if (name == "unknown_attributes_needed" && type == TypeDesc::TypeInt) {
*(int*)val = (int)group->m_unknown_attributes_needed;
return true;
@@ -2145,10 +2125,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
*(void**)val = n ? &group->m_userdata_init_vals[0] : NULL;
return true;
}
if (name == "llvm_groupdata_size" && type == TypeDesc::TypeInt) {
*(int*)val = (int)group->llvm_groupdata_size();
return true;
}
return false;
}
@@ -2422,8 +2398,6 @@ ShadingSystemImpl::getstats(int level) const
* (double(m_stat_postopt_syms)
/ (std::max(1, (int)m_stat_preopt_syms))
- 1.0));
print(out, " Optimized {} useparam ops into {} llvm run layer calls\n",
m_stat_useparam_ops, m_stat_call_layers_inserted);
}
print(out, " Constant connections eliminated: {}\n",
(int)m_stat_const_connections);
@@ -2572,19 +2546,26 @@ ShadingSystemImpl::printstats() const
bool
ShadingSystemImpl::Parameter(string_view name, TypeDesc t, const void* val,
ParamHints hints)
bool lockgeom)
{
return Parameter(*m_curgroup, name, t, val, hints);
return Parameter(*m_curgroup, name, t, val, lockgeom);
}
bool
ShadingSystemImpl::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
const void* val, ParamHints hints)
const void* val, bool lockgeom)
{
group.m_pending_params.emplace_back(name, t, 1, val);
group.m_pending_hints.push_back(hints);
// We work very hard not to do extra copies of the data. First,
// grow the pending list by one (empty) slot...
group.m_pending_params.grow();
// ...then initialize it in place
group.m_pending_params.back().init(name, t, 1, val);
// If we have a possible geometric override (lockgeom=false), set the
// param's interpolation to VERTEX rather than the default CONSTANT.
if (lockgeom == false)
group.m_pending_params.back().interp(OIIO::ParamValue::INTERP_VERTEX);
return true;
}
@@ -2593,7 +2574,7 @@ ShadingSystemImpl::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
ShaderGroupRef
ShadingSystemImpl::ShaderGroupBegin(string_view groupname)
{
ShaderGroupRef group(new ShaderGroup(groupname, *this));
ShaderGroupRef group(new ShaderGroup(groupname));
group->m_exec_repeat = m_exec_repeat;
{
// Record the group in the SS's census of all extant groups
@@ -2721,11 +2702,9 @@ ShadingSystemImpl::Shader(ShaderGroup& group, string_view shaderusage,
}
ShaderInstanceRef instance(new ShaderInstance(master, layername));
instance->parameters(group.m_pending_params, group.m_pending_hints);
instance->parameters(group.m_pending_params);
group.m_pending_params.clear();
group.m_pending_params.shrink_to_fit();
group.m_pending_hints.clear();
group.m_pending_hints.shrink_to_fit();
if (group.m_group_use.empty()) {
// First in a group
@@ -2997,8 +2976,7 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
}
}
string_view paramname(paramname_string);
int lockgeom = m_lockgeom_default;
ParamHints hints = ParamHints::none;
int lockgeom = m_lockgeom_default;
// For speed, reserve space. Note that for "unsized" arrays, 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.
@@ -3102,26 +3080,6 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
hint_name);
break;
}
set(hints, ParamHints::interpolated, lockgeom == 0);
} else if (hint_name == "interpolated"
&& hint_type == TypeInt) {
int v = 0;
if (!Strutil::parse_int(p, v)) {
err = true;
errdesc = fmtformat("hint {} expected int value",
hint_name);
break;
}
set(hints, ParamHints::interpolated, v);
} else if (hint_name == "interactive" && hint_type == TypeInt) {
int v = 0;
if (!Strutil::parse_int(p, v)) {
err = true;
errdesc = fmtformat("hint {} expected int value",
hint_name);
break;
}
set(hints, ParamHints::interactive, v);
} else {
err = true;
errdesc = fmtformat("unknown hint '{} {}'", hint_type,
@@ -3140,11 +3098,11 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
bool ok = true;
if (type.basetype == TypeDesc::INT) {
ok = Parameter(*g, paramname, type, &intvals[0], hints);
ok = Parameter(*g, paramname, type, &intvals[0], lockgeom);
} else if (type.basetype == TypeDesc::FLOAT) {
ok = Parameter(*g, paramname, type, &floatvals[0], hints);
ok = Parameter(*g, paramname, type, &floatvals[0], lockgeom);
} else if (type.basetype == TypeDesc::STRING) {
ok = Parameter(*g, paramname, type, &stringvals[0], hints);
ok = Parameter(*g, paramname, type, &stringvals[0], lockgeom);
}
if (!ok) {
errstatement = pstart;
@@ -3200,12 +3158,10 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
{
// Find the named layer
ustring layername(layername_);
ShaderInstance* layer = nullptr;
int layerindex = -1;
ShaderInstance* layer = NULL;
for (int i = 0, e = group.nlayers(); i < e; ++i) {
if (group[i]->layername() == layername) {
layer = group[i];
layerindex = i;
layer = group[i];
break;
}
}
@@ -3225,18 +3181,8 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
return false;
}
// Check that it's declared to be an interactive parameter
if (!sym->interactive()) {
errorfmt(
"ReParameter cannot adjust {}.{}, which was not declared interactive",
layername, paramname);
return false;
}
// Check for mismatch versus previously-declared type
if ((relaxed_param_typecheck() && !relaxed_equivalent(sym->typespec(), type))
|| (!relaxed_param_typecheck()
&& !relaxed_equivalent(sym->typespec(), type)))
if (!equivalent(sym->typespec(), type))
return false;
// Can't change param value if the group has already been optimized,
@@ -3245,13 +3191,7 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
return false;
// Do the deed
int offset = group.interactive_param_offset(layerindex, sym->name());
memcpy(group.interactive_arena_ptr() + offset, val, type.size());
if (use_optix()) {
renderer()->copy_to_device(group.device_interactive_arena().d_get()
+ offset,
val, type.size());
}
memcpy(sym->data(), val, type.size());
return true;
}
@@ -3617,7 +3557,6 @@ ShadingSystemImpl::optimize_group(ShaderGroup& group, ShadingContext* ctx,
for (auto&& f : rop.m_attributes_needed) {
group.m_attributes_needed.push_back(f.name);
group.m_attribute_scopes.push_back(f.scope);
group.m_attribute_types.push_back(f.type);
}
group.m_optimized = true;
@@ -4220,8 +4159,7 @@ ShadingContext::ocio_transform(StringParam fromspace, StringParam tospace,
const float eps = 0.001f;
Color3 CC[3] = { C.val(), C.val() + eps * C.dx(),
C.val() + eps * C.dy() };
cp->apply((float*)&CC, 3, 1, 3, sizeof(float), sizeof(Color3),
3 * sizeof(Color3));
cp->apply((float*)&CC, 3, 1, 3, sizeof(float), sizeof(Color3), 0);
Cout.set(CC[0], (CC[1] - CC[0]) * (1.0f / eps),
(CC[2] - CC[0]) * (1.0f / eps));
return true;
@@ -4375,8 +4313,8 @@ OSL::OSLQuery::init(const ShaderGroup* group, int layernum)
// firstcheck,nchecks are used to check just one element of an array.
OSL_SHADEOP void
osl_naninf_check(int ncomps, const void* vals_, int has_derivs, void* sg,
ustring_pod sourcefile, int sourceline, ustring_pod symbolname,
int firstcheck, int nchecks, ustring_pod opname)
const void* sourcefile, int sourceline, void* symbolname,
int firstcheck, int nchecks, const void* opname)
{
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
const float* vals = (const float*)vals_;
@@ -4407,10 +4345,10 @@ osl_naninf_check(int ncomps, const void* vals_, int has_derivs, void* sg,
// element of an array.
OSL_SHADEOP void
osl_uninit_check(long long typedesc_, void* vals_, void* sg,
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)
const void* sourcefile, int sourceline, const char* groupname,
int layer, const char* layername, const char* shadername,
int opnum, const char* opname, int argnum, void* symbolname,
int firstcheck, int nchecks)
{
TypeDesc typedesc = TYPEDESC(typedesc_);
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
@@ -4440,34 +4378,30 @@ osl_uninit_check(long long typedesc_, void* vals_, void* sg,
}
}
if (uninit) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(layername_);
ctx->errorfmt(
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {})",
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
USTR(shadername), opnum, USTR(opname), argnum);
typedesc.c_str(), USTR(symbolname), USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
shadername, opnum, USTR(opname), argnum);
}
}
OSL_SHADEOP int
osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
ustring_pod sourcefile, int sourceline,
ustring_pod groupname_, int layer, ustring_pod layername_,
ustring_pod shadername)
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername)
{
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(layername_);
if (indexvalue < 0 || indexvalue >= length) {
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
ctx->errorfmt(
"Index [{}] out of range {}[0..{}]: {}:{} (group {}, layer {} {}, shader {})",
indexvalue, USTR(symname), length - 1, USTR(sourcefile), sourceline,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
USTR(shadername));
if (indexvalue >= length)
indexvalue = length - 1;
@@ -4481,7 +4415,7 @@ osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
// Asked if the raytype is a name we can't know until mid-shader.
OSL_SHADEOP int
osl_raytype_name(void* sg_, ustring_pod name)
osl_raytype_name(void* sg_, const char* name)
{
ShaderGlobals* sg = (ShaderGlobals*)sg_;
int bit = sg->context->shadingsys().raytype_bit(USTR(name));
@@ -4490,21 +4424,24 @@ osl_raytype_name(void* sg_, ustring_pod name)
OSL_SHADEOP int
osl_get_attribute(void* sg_, int dest_derivs, ustring_pod obj_name,
ustring_pod attr_name, int array_lookup, int index,
long long attr_type, void* attr_dest)
osl_get_attribute(void* sg_, int dest_derivs, void* obj_name_, void* attr_name_,
int array_lookup, int index, long long attr_type,
void* attr_dest)
{
ShaderGlobals* sg = (ShaderGlobals*)sg_;
ShaderGlobals* sg = (ShaderGlobals*)sg_;
const ustring& obj_name = USTR(obj_name_);
const ustring& attr_name = USTR(attr_name_);
return sg->context->osl_get_attribute(sg, sg->objdata, dest_derivs,
USTR(obj_name), USTR(attr_name),
array_lookup, index,
TYPEDESC(attr_type), attr_dest);
obj_name, attr_name, array_lookup,
index, TYPEDESC(attr_type),
attr_dest);
}
OSL_SHADEOP int
osl_bind_interpolated_param(void* sg_, ustring_pod name, long long type,
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
int userdata_has_derivs, void* userdata_data,
int /*symbol_has_derivs*/, void* symbol_data,
int symbol_data_size, char* userdata_initialized,
@@ -4522,13 +4459,8 @@ osl_bind_interpolated_param(void* sg_, ustring_pod name, long long type,
sg->context->incr_get_userdata_calls();
}
if (status == 2) {
int udata_size = (userdata_has_derivs ? 3 : 1) * TYPEDESC(type).size();
// If userdata was present, copy it to the shader variable
memcpy(symbol_data, userdata_data,
std::min(symbol_data_size, udata_size));
if (symbol_data_size > udata_size)
memset((char*)symbol_data + udata_size, 0,
symbol_data_size - udata_size);
memcpy(symbol_data, userdata_data, symbol_data_size);
return 1;
}
return 0; // no such user data
+1 -1
View File
@@ -42,7 +42,7 @@ enum {
// clang-format off
namespace { // anon namespace to avoid duplicate OptiX symbols
OSL_CONSTANT_DATA const SplineBasis gBasisSet[kNumSplineTypes] = {
OSL_CONSTANT_DATA const static SplineBasis gBasisSet[kNumSplineTypes] = {
//
// catmullrom
//
-21
View File
@@ -149,27 +149,6 @@ equivalent(const TypeSpec& a, const TypeSpec& b)
|| a.is_unsized_array() != b.is_unsized_array());
}
// Relaxed rules just look to see that the types are isomorphic to each other (ie: same number of base values)
// Note that:
// * basetypes must match exactly (int vs float vs string)
// * valuetype cannot be unsized (we must know the concrete number of values)
// * if paramtype is sized (or not an array) just check for the total number of entries
// * if paramtype is unsized (shader writer is flexible about how many values come in) -- make sure we are a multiple of the target type
// * allow a single float setting a vec3 (or equivalent)
bool
relaxed_equivalent(const TypeSpec& a, const TypeSpec& b)
{
const TypeDesc paramtype = a.simpletype();
const TypeDesc valuetype = b.simpletype();
return valuetype.basetype == paramtype.basetype
&& !valuetype.is_unsized_array()
&& ((!paramtype.is_unsized_array()
&& valuetype.basevalues() == paramtype.basevalues())
|| (paramtype.is_unsized_array()
&& valuetype.basevalues() % paramtype.aggregate == 0)
|| (paramtype.is_vec3() && valuetype == TypeDesc::FLOAT));
}
}; // namespace pvt
+2 -4
View File
@@ -90,10 +90,8 @@ abs(const Dual2<float>& x)
#define __OSL_XMACRO_ARGS (fabs, std::abs)
#include "wide_opunary_int_xmacro.h"
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod, safe_fmod)
#include "wide_opbinary_per_component_xmacro.h"
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod, safe_fmod)
#include "wide_opbinary_per_component_mixed_vector_float_xmacro.h"
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod)
#include "wide_opbinary_per_component_float_or_vector_xmacro.h"
static OSL_FORCEINLINE float
+6 -1
View File
@@ -28,7 +28,12 @@ namespace {
OSL_FORCEINLINE OSL_HOSTDEVICE int
bitcast_to_uint(float x)
{
return OSL::bitcast<unsigned int>(x);
#if OPENIMAGEIO_VERSION >= 20500
return OIIO::bitcast<unsigned int, float>(x);
#else
// obsolete call
return OIIO::bit_cast<float, unsigned int>(x);
#endif
}
+38 -102
View File
@@ -45,18 +45,6 @@ invoke(FunctorT f)
f();
}
// helper to make a Block<ustringhash> from a pointer
#if !OSL_USTRINGREP_IS_HASH
inline void
block_ustringhash_from_ptr(Block<ustringhash>& b, const void* w_ptr)
{
for (int i = 0; i < __OSL_WIDTH; ++i)
b.set(i, reinterpret_cast<const ustring*>(w_ptr)[i]);
}
#endif
OSL_FORCEINLINE void
invert_wide_matrix(Masked<Matrix44> wresult, Wide<const Matrix44> wmatrix)
{
@@ -100,12 +88,12 @@ invert_wide_matrix(Masked<Matrix44> wresult, Wide<const Matrix44> wmatrix)
Mask
default_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
Masked<Matrix44> wresult, Wide<const ustringhash> wfrom,
Masked<Matrix44> wresult, Wide<const ustring> wfrom,
Wide<const float> wtime)
{
Mask ok(false);
foreach_unique(wfrom, wresult.mask(),
[=, &ok](const ustringhash& from, Mask from_mask) {
[=, &ok](const ustring& from, Mask from_mask) {
// Reuse the uniform from implementation by restricting results to
// just the lanes with the same value of "from".
Masked<Matrix44> wsub_result(wresult.data(), from_mask);
@@ -122,7 +110,7 @@ default_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
// execute the ISA optimized default version built right here.
OSL_FORCEINLINE Mask
dispatch_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
Masked<Matrix44> result, Wide<const ustringhash> from,
Masked<Matrix44> result, Wide<const ustring> from,
Wide<const float> time)
{
if (bsr->is_overridden_get_matrix_WmWsWf()) {
@@ -166,7 +154,7 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
Mask
default_get_inverse_matrix(BatchedRendererServices* bsr,
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
ustringhash to, Wide<const float> time)
ustring to, Wide<const float> time)
{
OSL_FORCEINLINE_BLOCK
{
@@ -182,7 +170,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
OSL_FORCEINLINE Mask
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
ustringhash to, Wide<const float> time)
ustring to, Wide<const float> time)
{
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
return bsr->get_inverse_matrix(bsg, result, to, time);
@@ -195,12 +183,12 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
Mask
default_get_inverse_matrix(BatchedRendererServices* bsr,
BatchedShaderGlobals* bsg, Masked<Matrix44> wresult,
Wide<const ustringhash> wto, Wide<const float> wtime)
Wide<const ustring> wto, Wide<const float> wtime)
{
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
Mask ok(false);
foreach_unique(wto, wresult.mask(),
[=, &ok](const ustringhash& to, Mask from_mask) {
[=, &ok](const ustring& to, Mask from_mask) {
// Reuse the uniform from implementation by restricting results to
// just the lanes with the same value of "from".
Masked<Matrix44> wsub_result(wresult.data(),
@@ -225,7 +213,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
OSL_FORCEINLINE Mask
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
Wide<const ustringhash> to, Wide<const float> time)
Wide<const ustring> to, Wide<const float> time)
{
if (bsr->is_overridden_get_inverse_matrix_WmWsWf()) {
return bsr->get_inverse_matrix(bsg, result, to, time);
@@ -639,7 +627,7 @@ impl_wide_mat_multiply(ResultAccessorT wresult, FromAccessorT wfrom,
OSL_FORCEINLINE Mask
impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
ShadingContext* ctx,
Wide<const ustringhash> wFrom,
Wide<const ustring> wFrom,
Masked<Matrix44> wMfrom)
{
// Deal with a varying 'from' space
@@ -658,7 +646,7 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
: common_space_bits, shader_space_bits,
object_space_bits, named_space_bits))
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
ustringhash from = wFrom[lane];
ustring from = wFrom[lane];
if (wMfrom.mask()[lane]) {
if (from == Strings::common || from == commonspace_synonym) {
// inline of Mask::set_on(lane)
@@ -715,10 +703,10 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
if (ctx->shadingsys().unknown_coordsys_error()) {
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
if (failedLanes[lane]) {
ustringhash from = wFrom[lane];
ustring from = wFrom[lane];
ctx->batched<__OSL_WIDTH>().errorfmt(
Mask(Lane(lane)), "Unknown transformation \"{}\"",
ustring(from));
from);
}
}
}
@@ -758,13 +746,7 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, Ws)(void* bsg_, void* wr,
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wFromName(w_from_name);
#else
Block<ustringhash> bwFromName;
block_ustringhash_from_ptr(bwFromName, w_from_name);
Wide<const ustringhash> wFromName(bwFromName);
#endif
Wide<const ustring> wFromName(w_from_name);
Block<Matrix44> wMfrom;
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
@@ -780,8 +762,7 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, Ws)(void* bsg_, void* wr,
namespace {
OSL_FORCEINLINE Mask
impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
ShadingContext* ctx,
Wide<const ustringhash> wTo,
ShadingContext* ctx, Wide<const ustring> wTo,
Masked<Matrix44> wMto)
{
// Deal with a varying 'to' space
@@ -800,7 +781,7 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
: common_space_bits, shader_space_bits,
object_space_bits, named_space_bits))
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
ustringhash to = wTo[lane];
ustring to = wTo[lane];
if (wMto.mask()[lane]) {
if (to == Strings::common || to == commonspace_synonym) {
// inline of Mask::set_on(lane)
@@ -855,10 +836,10 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
if (ctx->shadingsys().unknown_coordsys_error()) {
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
if (failedLanes[lane]) {
ustringhash to = wTo[lane];
ustring to = wTo[lane];
ctx->batched<__OSL_WIDTH>().errorfmt(
Mask(Lane(lane)), "Unknown transformation \"{}\"",
ustring(to));
to);
}
}
}
@@ -914,13 +895,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, s,
Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix,
from);
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wToSpace(w_to_ptr);
#else
Block<ustringhash> bwToSpace;
block_ustringhash_from_ptr(bwToSpace, w_to_ptr);
Wide<const ustringhash> wToSpace(bwToSpace);
#endif
Wide<const ustring> wToSpace(w_to_ptr);
Block<Matrix44> wMto;
// 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
@@ -942,13 +917,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wFromName(w_from_ptr);
#else
Block<ustringhash> bwFromName;
block_ustringhash_from_ptr(bwFromName, w_from_ptr);
Wide<const ustringhash> wFromName(bwFromName);
#endif
Wide<const ustring> wFromName(w_from_ptr);
Block<Matrix44> wMto;
Masked<Matrix44> to_matrix(wMto, Mask(mask_value));
@@ -976,26 +945,14 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wFromName(w_from_ptr);
#else
Block<ustringhash> bwFromName;
block_ustringhash_from_ptr(bwFromName, w_from_ptr);
Wide<const ustringhash> wFromName(bwFromName);
#endif
Wide<const ustring> wFromName(w_from_ptr);
Block<Matrix44> wMfrom;
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
Mask succeeded = impl_get_varying_from_matrix_batched(bsg, ctx, wFromName,
from_matrix);
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wToSpace(w_to_ptr);
#else
Block<ustringhash> bwToSpace;
block_ustringhash_from_ptr(bwToSpace, w_to_ptr);
Wide<const ustringhash> wToSpace(bwToSpace);
#endif
Wide<const ustring> wToSpace(w_to_ptr);
Block<Matrix44> wMto;
// 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
@@ -1020,9 +977,9 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
// Also zeroing of derivatives is left to the code generator.
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)
__OSL_MASKED_OP3(build_transform_matrix, Wm, s, s)(void* bsg_, void* WM_,
void* from_, void* to_,
unsigned int mask_value)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -1030,8 +987,8 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s,
Masked<Matrix44> mm(WM_, mask);
ShadingContext* ctx = bsg->uniform.context;
ustringrep from = USTR(from_);
ustringrep to = USTR(to_);
ustring from = USTR(from_);
ustring to = USTR(to_);
Mask succeeded;
// Avoid matrix concatenation if possible by detecting when the
@@ -1056,24 +1013,18 @@ __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_,
unsigned int mask_value)
__OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, s)(void* bsg_, void* WM_,
void* wfrom_, void* to_,
unsigned int mask_value)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
Mask mask(mask_value);
Masked<Matrix44> wrm(WM_, mask);
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wfrom_space(wfrom_);
#else
Block<ustringhash> bwfrom_space;
block_ustringhash_from_ptr(bwfrom_space, wfrom_);
Wide<const ustringhash> wfrom_space(bwfrom_space);
#endif
Wide<const ustring> wfrom_space(wfrom_);
ustringrep to_space = USTR(to_);
ustring to_space = USTR(to_);
Block<Matrix44> wMfrom, wMto;
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
@@ -1092,23 +1043,17 @@ __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_,
unsigned int mask_value)
__OSL_MASKED_OP3(build_transform_matrix, Wm, s, Ws)(void* bsg_, void* WM_,
void* from_, void* wto_,
unsigned int mask_value)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
Mask mask(mask_value);
Masked<Matrix44> wrm(WM_, mask);
ustringrep from = USTR(from_);
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wto_space(wto_);
#else
Block<ustringhash> bwto_space;
block_ustringhash_from_ptr(bwto_space, wto_);
Wide<const ustringhash> wto_space(bwto_space);
#endif
ustring from = USTR(from_);
Wide<const ustring> wto_space(wto_);
Block<Matrix44> wMfrom, wMto;
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
@@ -1137,17 +1082,8 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, Ws)(void* bsg_, void* WM_,
Mask mask(mask_value);
Masked<Matrix44> wrm(WM_, mask);
#if OSL_USTRINGREP_IS_HASH
Wide<const ustringhash> wfrom_space(wfrom_);
Wide<const ustringhash> wto_space(wto_);
#else
Block<ustringhash> bwfrom_space;
block_ustringhash_from_ptr(bwfrom_space, wfrom_);
Wide<const ustringhash> wfrom_space(bwfrom_space);
Block<ustringhash> bwto_space;
block_ustringhash_from_ptr(bwto_space, wto_);
Wide<const ustringhash> wto_space(bwto_space);
#endif
Wide<const ustring> wfrom_space(wfrom_);
Wide<const ustring> wto_space(wto_);
Block<Matrix44> wMfrom, wMto;
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
+14 -15
View File
@@ -200,19 +200,18 @@ 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,
void* wvalue, int layeridx,
ustring_pod sourcefile_, int sourceline,
__OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, void* wname,
long long type, void* wvalue, int layeridx,
const char* sourcefile_, int sourceline,
unsigned int mask_value)
{
Mask mask(mask_value);
OSL_ASSERT(mask.any_on());
ustringrep name = USTR(name_);
ustring name = USTR(wname);
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
ustringrep sourcefile = USTR(sourcefile_);
const ustring& sourcefile(USTR(sourcefile_));
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -238,16 +237,16 @@ __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,
const char* sourcefile_, int sourceline,
unsigned int mask_value)
{
Mask mask(mask_value);
OSL_ASSERT(mask.any_on());
Wide<const ustringrep> wName(wname);
Wide<const ustring> wName(wname);
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
ustringrep sourcefile = USTR(sourcefile_);
const ustring& sourcefile(USTR(sourcefile_));
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -275,14 +274,14 @@ __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_,
__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, char* source_,
char* name_, long long type_, void* val, int derivs,
int layeridx, const char* sourcefile_,
int sourceline, unsigned int mask_value)
{
ustringrep source = USTR(source_);
ustringrep name = USTR(name_);
ustringrep sourcefile = USTR(sourcefile_);
const ustring& source(USTR(source_));
const ustring& name(USTR(name_));
const ustring& sourcefile(USTR(sourcefile_));
Mask mask(mask_value);
+27 -26
View File
@@ -35,7 +35,7 @@ using PointCloudSearchResults = BatchedRendererServices::PointCloudSearchResults
namespace {
OSL_FORCEINLINE void
default_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
default_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
const void* wcenter_, Wide<const float> wradius,
int max_points, bool sort,
PointCloudSearchResults& results)
@@ -199,7 +199,7 @@ default_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
OSL_FORCEINLINE void
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
const void* wcenter, Wide<const float> wradius,
int max_points, bool sort,
PointCloudSearchResults& results)
@@ -217,9 +217,9 @@ dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
OSL_FORCEINLINE Mask
default_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
default_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
Wide<const int[]> windices, Wide<const int> wnum_points,
ustringhash attr_name, MaskedData wout_data)
ustring attr_name, MaskedData wout_data)
{
#ifdef USE_PARTIO
Mask success { false };
@@ -364,9 +364,9 @@ default_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
OSL_FORCEINLINE Mask
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
Wide<const int[]> windices, Wide<const int> wnum_points,
ustringhash attr_name, MaskedData wout_data)
ustring attr_name, MaskedData wout_data)
{
auto* bsr = bsg->uniform.renderer->batched(WidthTag());
if (bsr->is_overridden_pointcloud_get()) {
@@ -381,7 +381,7 @@ dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
Mask
default_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
default_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
Wide<const OSL::Vec3> wpos, int nattribs,
const ustring* attr_names, const TypeDesc* attr_types,
const void** ptrs_to_wide_attr_value, Mask mask)
@@ -472,7 +472,7 @@ default_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
OSL_FORCEINLINE Mask
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
Wide<const OSL::Vec3> wpos, int nattribs,
const ustring* attr_names, const TypeDesc* attr_types,
const void** ptrs_to_wide_attr_value, Mask mask)
@@ -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_, const char* 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,
@@ -509,15 +509,16 @@ __OSL_MASKED_OP(pointcloud_search)(
mask_value };
ShadingContext* ctx = bsg->uniform.context;
if (ctx->shadingsys().no_pointcloud()) {
// Debug mode to skip pointcloud expense
if (ctx->shadingsys()
.no_pointcloud()) // Debug mode to skip pointcloud expense
{
assign_all(pcsr.wnum_points(), 0);
return; // mask_value;
}
Wide<const float> wradius(wradius_);
dispatch_pointcloud_search(bsg, USTR(filename).uhash(), wcenter_, wradius,
dispatch_pointcloud_search(bsg, USTR(filename), wcenter_, wradius,
max_points, sort, pcsr);
if (nattrs > 0) {
@@ -527,9 +528,11 @@ __OSL_MASKED_OP(pointcloud_search)(
va_list args;
va_start(args, nattrs);
for (int i = 0; i < nattrs; i++) {
ustringrep attr_name = USTREP(va_arg(args, ustring_pod));
TypeDesc attr_type = TYPEDESC(va_arg(args, long long));
void* out_data = va_arg(args, void*);
ustring attr_name = ustring::from_unique(
(const char*)va_arg(args, const char*));
long long lltype = va_arg(args, long long);
TypeDesc attr_type = TYPEDESC(lltype);
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 });
@@ -544,9 +547,9 @@ __OSL_MASKED_OP(pointcloud_search)(
OSL_BATCHOP int
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename,
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, const char* filename,
void* windices_, int indices_array_length,
void* wnum_points_, ustring_pod attr_name,
void* wnum_points_, const char* attr_name,
long long attr_type_, void* wout_data_,
int mask_value)
{
@@ -561,8 +564,7 @@ __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, USTR(filename), windices, wnum_points, USTR(attr_name),
MaskedData { attr_type, false, Mask { mask_value }, wout_data_ });
return success.value();
}
@@ -571,21 +573,20 @@ __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_,
int nattribs, const ustringrep* attr_names,
const char* filename, const void* wpos_,
int nattribs, const ustring* attr_names,
const TypeDesc* attr_types,
const void** ptrs_to_wide_attr_value,
int mask_value)
{
ShadingContext* ctx = bsg->uniform.context;
// Debug mode to skip pointcloud expense
if (ctx->shadingsys().no_pointcloud())
return 0; // mask_value;
if (ctx->shadingsys()
.no_pointcloud()) // Debug mode to skip pointcloud expense
return 0; // mask_value;
Wide<const OSL::Vec3> wpos(wpos_);
Mask success = dispatch_pointcloud_write(bsg, USTR(filename).uhash(), wpos,
Mask success = dispatch_pointcloud_write(bsg, USTR(filename), wpos,
nattribs, attr_names, attr_types,
ptrs_to_wide_attr_value,
Mask(mask_value));
+2 -2
View File
@@ -456,7 +456,7 @@ spline_evaluate_wide(RAccessorT wR, ustring spline_basis, XAccessorT wX,
true /*is_basis_u_constant */, 1 /* basis_step */,
ConstantWeights, RAccessorT, XAccessorT, KAccessor_T> };
unsigned int basis_type = Spline::basis_type_of(spline_basis);
unsigned int basis_type = Spline::basis_type_of(USTR(spline_basis));
OSL_DASSERT(basis_type < Spline::kNumSplineTypes
&& "unsupported spline basis");
@@ -539,7 +539,7 @@ splineinverse_evaluate_wide(RAccessorT wR, ustring spline_basis, XAccessorT wX,
true /*is_basis_u_constant */, 1 /* basis_step */,
ConstantWeights, RAccessorT, XAccessorT, KAccessor_T> };
unsigned int basis_type = Spline::basis_type_of(spline_basis);
unsigned int basis_type = Spline::basis_type_of(USTR(spline_basis));
OSL_DASSERT(basis_type < Spline::kNumSplineTypes
&& "unsupported spline basis");
+2 -2
View File
@@ -354,7 +354,7 @@ __OSL_MASKED_OP(regex_impl)(void* bsg_, void* wsuccess_ptr, void* wsubject_ptr,
const std::string& subject = usubject.string();
std::match_results<std::string::const_iterator> mresults;
const std::regex& regex(ctx->find_regex(pattern));
const std::regex& regex(ctx->find_regex(USTR(pattern)));
if (nresults > 0) {
std::string::const_iterator start = subject.begin();
int res = fullmatch ? std::regex_match(subject, mresults, regex)
@@ -366,7 +366,7 @@ __OSL_MASKED_OP(regex_impl)(void* bsg_, void* wsuccess_ptr, void* wsubject_ptr,
else
results[r] = mresults[r / 2].second - start;
} else {
results[r] = pattern.length();
results[r] = USTR(pattern).length();
}
}
wsuccess[lane] = res;
+10 -10
View File
@@ -105,8 +105,8 @@ default_texture(BatchedRendererServices* bsr, ustring filename,
// It's actually faster to ask for 4 channels (even if we need fewer)
// and ensure that they're being put in aligned memory.
// TODO: investigate if the above statement is true when nchannels==1
// NOTE: using simd::vfloat4 to speedup texture transformation below
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd;
// NOTE: using simd::float4 to speedup texture transformation below
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd;
bool retVal = false;
@@ -120,8 +120,8 @@ default_texture(BatchedRendererServices* bsr, ustring filename,
has_derivs ? (float*)&dresultds_simd : NULL,
has_derivs ? (float*)&dresultdt_simd : NULL);
OIIO::simd::vfloat4 dresultdx_simd;
OIIO::simd::vfloat4 dresultdy_simd;
OIIO::simd::float4 dresultdx_simd;
OIIO::simd::float4 dresultdy_simd;
if (has_derivs) {
// Correct our st texture space gradients into xy-space gradients
dresultdx_simd = dresultds_simd * dsdx + dresultdt_simd * dtdx;
@@ -297,8 +297,8 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename,
// and ensure that they're being put in aligned memory.
// TODO: investigate if the above statement is true when nchannels==1
// NOTE: using simd::vfloat4 to speedup texture transformation below
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd,
// NOTE: using simd::float4 to speedup texture transformation below
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd,
dresultdr_simd;
bool retVal = false;
@@ -314,8 +314,8 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename,
has_derivs ? (float*)&dresultdt_simd : nullptr,
has_derivs ? (float*)&dresultdr_simd : nullptr);
OIIO::simd::vfloat4 dresultdx_simd;
OIIO::simd::vfloat4 dresultdy_simd;
OIIO::simd::float4 dresultdx_simd;
OIIO::simd::float4 dresultdy_simd;
if (has_derivs) {
// Correct our str texture space gradients into xyz-space gradients
dresultdx_simd = dresultds_simd * dPdx.x + dresultdt_simd * dPdx.y
@@ -480,8 +480,8 @@ default_environment(BatchedRendererServices* bsr, ustring filename,
// and ensure that they're being put in aligned memory.
// TODO: investigate if the above statement is true when nchannels==1
// NOTE: using simd::vfloat4 to speedup texture transformation below
OIIO::simd::vfloat4 result_simd;
// NOTE: using simd::float4 to speedup texture transformation below
OIIO::simd::float4 result_simd;
bool retVal = false;
+84 -99
View File
@@ -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_, const void* sourcefile, int sourceline,
void* symbolname, int firstcheck, int nchecks,
const void* opname)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
@@ -56,9 +56,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_, const void* sourcefile,
int sourceline, void* symbolname, int firstcheck,
int nchecks, const void* opname)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
@@ -88,12 +88,12 @@ __OSL_MASKED_OP1(naninf_check_offset,
// Wide vals + mask + varying index
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,
const void* wide_offsets_ptr, int nchecks,
ustring_pod opname)
__OSL_MASKED_OP1(naninf_check_offset, Wi)(int mask_value, int ncomps,
const void* vals_, int has_derivs,
void* bsg_, const void* sourcefile,
int sourceline, void* symbolname,
const void* wide_offsets_ptr,
int nchecks, const void* opname)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
@@ -129,9 +129,9 @@ __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,
const void* sourcefile, int sourceline, const char* groupname,
int layer, const char* layername, const char* shadername,
int opnum, const char* opname, int argnum, void* symbolname,
int firstcheck, int nchecks)
{
TypeDesc typedesc = TYPEDESC(typedesc_);
@@ -163,14 +163,12 @@ __OSL_OP2(uninit_check_values_offset, X,
}
}
if (uninit) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(layername_);
ctx->errorfmt(
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {})",
typedesc, symbolname, sourcefile, sourceline,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
shadername, opnum, opname, argnum);
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
shadername, opnum, USTR(opname), argnum);
}
}
@@ -181,11 +179,10 @@ __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_, const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername, int opnum, const char* opname,
int argnum, void* symbolname, int firstcheck, int nchecks)
{
TypeDesc typedesc = TYPEDESC(typedesc_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -227,14 +224,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX,
});
}
if (lanes_uninit.any_on()) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(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,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
shadername, opnum, opname, argnum, lanes_uninit.value());
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
}
}
@@ -245,11 +240,11 @@ __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_, const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername, int opnum, const char* opname,
int argnum, void* symbolname, const void* wide_offsets_ptr,
int nchecks)
{
TypeDesc typedesc = TYPEDESC(typedesc_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -293,14 +288,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, X,
}
if (lanes_uninit.any_on()) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(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,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
shadername, opnum, opname, argnum, lanes_uninit.value());
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
}
}
@@ -311,11 +304,11 @@ __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_, const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername, int opnum, const char* opname,
int argnum, void* symbolname, const void* wide_offsets_ptr,
int nchecks)
{
TypeDesc typedesc = TYPEDESC(typedesc_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
@@ -361,38 +354,33 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX,
}
if (lanes_uninit.any_on()) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(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,
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
shadername, opnum, opname, argnum, lanes_uninit.value());
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
}
}
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, const char* symname,
void* bsg_, const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername)
{
if (indexvalue < 0 || indexvalue >= length) {
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(layername_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
ctx->errorfmt("Index [{}] out of range {}[0..{}]: {}:{}"
" (group {}, layer {} {}, shader {})",
indexvalue, USTR(symname), length - 1, USTR(sourcefile),
sourceline,
groupname.empty() ? "<unnamed group>" : groupname.c_str(),
layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
USTR(shadername));
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ShadingContext* ctx = bsg->uniform.context;
ctx->errorfmt(
"Index [{}] out of range {}[0..{}]: {}:{}"
" (group {}, layer {} {}, shader {})",
indexvalue, USTR(symname), length - 1, USTR(sourcefile), sourceline,
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
(layername && layername[0]) ? layername : "<unnamed layer>",
USTR(shadername));
if (indexvalue >= length)
indexvalue = length - 1;
else
@@ -405,14 +393,12 @@ __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, const char* symname, void* bsg_,
const void* sourcefile, int sourceline,
const char* groupname, int layer,
const char* layername, const char* shadername)
{
ustringrep groupname = USTR(groupname_);
ustringrep layername = USTR(layername_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
Masked<int> wIndexValue(wide_indexvalue, Mask(mask_value));
wIndexValue.mask().foreach ([=](ActiveLane lane) -> void {
int indexvalue = wIndexValue[lane];
@@ -422,9 +408,9 @@ __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value,
"Index [{}] out of range {}[0..{}]: {}:{} (group {}, layer {} {}, shader {})",
indexvalue, USTR(symname), length - 1, USTR(sourcefile),
sourceline,
groupname.empty() ? "<unnamed group>" : groupname.c_str(),
(groupname && groupname[0]) ? groupname : "<unnamed group>",
layer,
layername.empty() ? "<unnamed layer>" : layername.c_str(),
(layername && layername[0]) ? layername : "<unnamed layer>",
USTR(shadername));
if (indexvalue >= length)
indexvalue = length - 1;
@@ -439,17 +425,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,
__OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, void* obj_name_,
void* 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<BatchedShaderGlobals*>(bsg_);
ustringrep obj_name = USTR(obj_name_);
ustringrep attr_name = USTR(attr_name_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
const ustring& obj_name = USTR(obj_name_);
const ustring& attr_name = USTR(attr_name_);
// Ignoring m_next_failed_attrib cache for now,
// might be faster
@@ -471,16 +457,16 @@ __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, void* obj_name_,
void* 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<BatchedShaderGlobals*>(bsg_);
ustringrep obj_name = USTR(obj_name_);
Wide<const ustringrep> wAttrName(wattr_name_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
const ustring& obj_name = USTR(obj_name_);
Wide<const ustring> wAttrName(wattr_name_);
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
Mask retVal(false);
@@ -518,14 +504,13 @@ __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,
__OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, void* obj_name_,
void* attr_name_, int array_lookup, int index,
const void* attr_type, void* attr_dest)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
ustringrep obj_name = USTR(obj_name_);
ustringrep attr_name = USTR(attr_name_);
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
const ustring& obj_name = USTR(obj_name_);
const ustring& attr_name = USTR(attr_name_);
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
@@ -545,7 +530,7 @@ __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,
__OSL_OP(bind_interpolated_param)(void* bsg_, const void* name, long long type,
int userdata_has_derivs, void* userdata_data,
int symbol_has_derivs, void* symbol_data,
int symbol_data_size,
@@ -595,7 +580,7 @@ __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_, void* name)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
int bit = bsg->uniform.context->shadingsys().raytype_bit(USTR(name));
@@ -605,11 +590,11 @@ __OSL_OP(raytype_name)(void* bsg_, ustring_pod name)
OSL_BATCHOP void
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, ustringrep* name_,
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, void* name_,
unsigned int mask_value)
{
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
Wide<const ustringrep> wname(name_);
Wide<const ustring> wname(name_);
Mask mask(mask_value);
foreach_unique(wname, mask, [=](ustring name, Mask matching_lanes) -> void {
+5 -5
View File
@@ -67,11 +67,11 @@ scramble(uint32_t v0, uint32_t v1 = 0, uint32_t v2 = 0)
// clang-format off
namespace { // anon namespace to avoid duplicate OptiX symbols
OSL_CONSTANT_DATA float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
static OSL_CONSTANT_DATA float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
// Gradient table for 2D. These could be programmed the Ken Perlin way with
// some clever bit-twiddling, but this is more clear, and not really slower.
OSL_CONSTANT_DATA float grad2lut[8][2] = {
static OSL_CONSTANT_DATA float grad2lut[8][2] = {
{ -1.0f, -1.0f }, { 1.0f, 0.0f }, { -1.0f, 0.0f }, { 1.0f, 1.0f },
{ -1.0f, 1.0f }, { 0.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, -1.0f }
};
@@ -82,7 +82,7 @@ OSL_CONSTANT_DATA float grad2lut[8][2] = {
// but these 12 (including 4 repeats to make the array length a power
// of two) work better. They are not random, they are carefully chosen
// to represent a small, isotropic set of directions.
OSL_CONSTANT_DATA float grad3lut[16][3] = {
static OSL_CONSTANT_DATA float grad3lut[16][3] = {
{ 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, // 12 cube edges
{ -1.0f, 0.0f, 1.0f }, { 0.0f, -1.0f, 1.0f },
{ 1.0f, 0.0f, -1.0f }, { 0.0f, 1.0f, -1.0f },
@@ -94,7 +94,7 @@ OSL_CONSTANT_DATA float grad3lut[16][3] = {
};
// Gradient directions for 4D
OSL_CONSTANT_DATA float grad4lut[32][4] = {
static OSL_CONSTANT_DATA float grad4lut[32][4] = {
{ 0.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, -1.0f }, { 0.0f, 1.0f, -1.0f, 1.0f }, { 0.0f, 1.0f, -1.0f, -1.0f }, // 32 tesseract edges
{ 0.0f, -1.0f, 1.0f, 1.0f }, { 0.0f, -1.0f, 1.0f, -1.0f }, { 0.0f, -1.0f, -1.0f, 1.0f }, { 0.0f, -1.0f, -1.0f, -1.0f },
{ 1.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f, -1.0f }, { 1.0f, 0.0f, -1.0f, 1.0f }, { 1.0f, 0.0f, -1.0f, -1.0f },
@@ -108,7 +108,7 @@ OSL_CONSTANT_DATA float grad4lut[32][4] = {
// A lookup table to traverse the simplex around a given point in 4D.
// Details can be found where this table is used, in the 4D noise method.
/* TODO: This should not be required, backport it from Bill's GLSL code! */
OSL_CONSTANT_DATA unsigned char simplex[64][4] = {
static OSL_CONSTANT_DATA unsigned char simplex[64][4] = {
{0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0},
{0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0},
{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
+2 -2
View File
@@ -521,8 +521,8 @@ OSLInput::open(const std::string& name, ImageSpec& newspec,
exprcount++);
std::string sourcecode = OIIO::Strutil::fmt::format(
"shader {} (\n"
" float s = u [[ int interpolated=1 ]],\n"
" float t = v [[ int interpolated=1 ]],\n"
" float s = u [[ int lockgeom=0 ]],\n"
" float t = v [[ int lockgeom=0 ]],\n"
" output color result = 0,\n"
" output float alpha = 1,\n"
" )\n"
+2 -13
View File
@@ -3,7 +3,7 @@
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
set (CMAKE_AUTOMOC ON)
if (Qt5_POSITION_INDEPENDENT_CODE OR Qt6_POSITION_INDEPENDENT_CODE)
if (Qt5_POSITION_INDEPENDENT_CODE)
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
set (osltoy_srcs
@@ -13,17 +13,6 @@ set_target_properties (osltoy PROPERTIES FOLDER "Tools")
target_link_libraries (osltoy
PRIVATE
oslexec
$<TARGET_NAME_IF_EXISTS:Qt5::Core>
$<TARGET_NAME_IF_EXISTS:Qt5::Gui>
$<TARGET_NAME_IF_EXISTS:Qt5::Widgets>
$<TARGET_NAME_IF_EXISTS:Qt6::Core>
$<TARGET_NAME_IF_EXISTS:Qt6::Gui>
$<TARGET_NAME_IF_EXISTS:Qt6::Widgets>
Qt5::Core Qt5::Gui Qt5::Widgets
${Boost_LIBRARIES} ${CMAKE_DL_LIBS})
if (Qt5_FOUND)
target_compile_definitions(osltoy PRIVATE OSL_QT_MAJOR=5)
endif ()
if (Qt6_FOUND)
target_compile_definitions(osltoy PRIVATE OSL_QT_MAJOR=6)
endif ()
install_targets (osltoy)
+1 -14
View File
@@ -178,8 +178,7 @@ public:
layout->addWidget(m_image);
m_info = new QLabel(this);
m_info->setAlignment(
static_cast<Qt::Alignment>(Qt::AlignTop | Qt::AlignLeft));
m_info->setAlignment(Qt::AlignTop | Qt::AlignLeft);
m_info->setMinimumSize(textSize, m_res);
layout->addWidget(m_info);
@@ -199,11 +198,7 @@ public:
QWidget::hideEvent(e);
}
#if OSL_QT_MAJOR < 6
void enterEvent(QEvent* event) override;
#else
void enterEvent(QEnterEvent* event) override;
#endif
void mouseMoveEvent(QMouseEvent* event) override;
};
@@ -298,11 +293,7 @@ public:
void mouseMoveEvent(QMouseEvent* /*event*/) override { magnifierEvent(); }
#if OSL_QT_MAJOR < 6
void enterEvent(QEvent* /*event*/) override
#else
void enterEvent(QEnterEvent* /*event*/) override
#endif
{
if (shouldShowMagnifier())
showMagnifier();
@@ -352,11 +343,7 @@ public:
};
void
#if OSL_QT_MAJOR < 6
Magnifier::enterEvent(QEvent* event)
#else
Magnifier::enterEvent(QEnterEvent* event)
#endif
{
if (m_renderview)
m_renderview->magnifierEvent();
-4
View File
@@ -16,10 +16,6 @@
#include <OSL/oslquery.h>
#include <OSL/rendererservices.h>
#ifndef OSL_QT_MAJOR
# error "Build problem? OSL_QT_MAJOR not defined."
#endif
#include <QAction>
#include <QMainWindow>
#include <QTimer>
+20 -10
View File
@@ -16,20 +16,30 @@ glass
float eta = 1.5
[[ string help = "Index of refraction",
float min = 1, float max = 3 ]],
int caustics = 0
[[ string help = "Enable indirect lighting through glass",
string widget = "checkBox" ]],
int TIR = 0
[[ string help = "Enable Total Internal Reflection",
string widget = "checkBox" ]]
)
{
// Take into account backfacing to invert eta accordingly
if (backfacing()) {
Ci = Cs * refraction(N, 1.0 / eta);
// If Total Internal Reflection is enabled, we also return a
// reflection closure, which might make rays bounce too much
// inside an object. That's why we make it optional.
if (TIR)
Ci += Ks * reflection(N, 1.0 / eta);
} else {
Ci = Ks * reflection(N, eta) + Cs * refraction(N, eta);
// If the current ray type is glossy or diffuse, that means we
// are computing indirect lighting. Letting that interact with
// glass produces caustics, which are normally hard to trace and
// noisy. So we only return closures if that's not the case or
// the "caustics" flag is on.
if (caustics || (!raytype("glossy") && !raytype("diffuse"))) {
// Take into account backfacing to invert eta accordingly
if (backfacing()) {
Ci = Cs * refraction(N, 1.0 / eta);
// If Total Internal Reflection is enabled, we also return a
// reflection closure, which might make rays bounce too much
// inside an object. That's why we make it optional.
if (TIR)
Ci += Ks * reflection(N, 1.0 / eta);
} else {
Ci = Ks * reflection(N, eta) + Cs * refraction(N, eta);
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ set (testrender_srcs
simpleraytracer.cpp
testrender.cpp)
if (OSL_USE_OPTIX)
if (USE_OPTIX)
list (APPEND testrender_srcs optixraytracer.cpp)
set (testrender_cuda_srcs
cuda/quad.cu
+8 -9
View File
@@ -265,7 +265,7 @@ rend_get_userdata(OSL::StringParam name, void* data, int data_size,
__device__ int
osl_bind_interpolated_param(void* sg_, OSL::StringParam name, long long type,
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
int userdata_has_derivs, void* userdata_data,
int symbol_has_derivs, void* symbol_data,
int symbol_data_size, char* userdata_initialized,
@@ -411,10 +411,10 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
__device__ int
osl_range_check_err(int indexvalue, int length, OSL::ustring_pod symname,
void* sg, OSL::ustring_pod sourcefile, int sourceline,
OSL::ustring_pod groupname, int layer,
OSL::ustring_pod layername, OSL::ustring_pod shadername)
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
const void* sourcefile, int sourceline,
const char* groupname, int layer, const char* layername,
const char* shadername)
{
if (indexvalue < 0 || indexvalue >= length) {
return indexvalue < 0 ? 0 : length - 1;
@@ -425,10 +425,9 @@ osl_range_check_err(int indexvalue, int length, OSL::ustring_pod symname,
__device__ int
osl_range_check(int indexvalue, int length, OSL::ustring_pod symname, void* sg,
OSL::ustring_pod sourcefile, int sourceline,
OSL::ustring_pod groupname, int layer,
OSL::ustring_pod layername, OSL::ustring_pod shadername)
osl_range_check(int indexvalue, int length, const char* symname, void* sg,
const void* sourcefile, int sourceline, const char* groupname,
int layer, const char* layername, const char* shadername)
{
if (indexvalue < 0 || indexvalue >= length) {
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
+6 -11
View File
@@ -183,19 +183,14 @@ __closesthit__closest_hit_osl()
sg.context = &shading_context;
// Run the OSL group and init functions
auto sbtdata = reinterpret_cast<GenericData*>(optixGetSbtDataPointer());
const unsigned int shaderInitOpIdx = 2u + 2u * sg.shaderID + 0u;
const unsigned int shaderGroupIdx = 2u + 2u * sg.shaderID + 1u;
// call osl_init_func
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int, void*>(
shaderInitOpIdx, &sg /*shaderglobals_ptr*/, params /*groupdata_ptr*/,
nullptr /*userdata_base_ptr*/, nullptr /*output_base_ptr*/,
0 /*shadeindex - unused*/, sbtdata->data /*interactive_params_ptr*/);
// call osl_group_func
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int, void*>(
shaderGroupIdx, &sg /*shaderglobals_ptr*/, params /*groupdata_ptr*/,
nullptr /*userdata_base_ptr*/, nullptr /*output_base_ptr*/,
0 /*shadeindex - unused*/, sbtdata->data /*interactive_params_ptr*/);
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int>(
shaderInitOpIdx, &sg, params, nullptr, nullptr,
0); // call osl_init_func
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int>(
shaderGroupIdx, &sg, params, nullptr, nullptr,
0); // call osl_group_func
float3 result = process_closure((OSL::ClosureColor*)sg.Ci);
uint3 launch_dims = optixGetLaunchDimensions();
+22 -49
View File
@@ -111,42 +111,29 @@ OptixRaytracer::~OptixRaytracer()
void*
OptixRaytracer::device_alloc(size_t size)
uint64_t
OptixRaytracer::register_global(const std::string& str, uint64_t value)
{
void* ptr = nullptr;
cudaError_t res = cudaMalloc(reinterpret_cast<void**>(&ptr), size);
if (res != cudaSuccess) {
errhandler().errorfmt("cudaMalloc({}) failed with error: {}\n", size,
cudaGetErrorString(res));
auto it = m_globals_map.find(ustring(str));
if (it != m_globals_map.end()) {
return it->second;
}
return ptr;
m_globals_map[ustring(str)] = value;
return value;
}
void
OptixRaytracer::device_free(void* ptr)
{
cudaError_t res = cudaFree(ptr);
if (res != cudaSuccess) {
errhandler().errorfmt("cudaFree() failed with error: {}\n",
cudaGetErrorString(res));
}
}
void*
OptixRaytracer::copy_to_device(void* dst_device, const void* src_host,
size_t size)
bool
OptixRaytracer::fetch_global(const std::string& str, uint64_t* value)
{
cudaError_t res = cudaMemcpy(dst_device, src_host, size,
cudaMemcpyHostToDevice);
if (res != cudaSuccess) {
errhandler().errorfmt(
"cudaMemcpy host->device of size {} failed with error: {}\n", size,
cudaGetErrorString(res));
auto it = m_globals_map.find(ustring(str));
if (it != m_globals_map.end()) {
*value = it->second;
return true;
}
return dst_device;
return false;
}
@@ -462,7 +449,6 @@ OptixRaytracer::make_optix_materials()
// Create materials
int mtl_id = 0;
std::vector<void*> material_interactive_params;
for (const auto& groupref : shaders()) {
std::string group_name, init_name, entry_name;
shadingsys->getattribute(groupref.get(), "groupname", group_name);
@@ -488,6 +474,7 @@ OptixRaytracer::make_optix_materials()
std::string osl_ptx;
shadingsys->getattribute(groupref.get(), "ptx_compiled_version",
OSL::TypeDesc::PTR, &osl_ptx);
if (osl_ptx.empty()) {
errhandler().errorfmt("Failed to generate PTX for ShaderGroup {}",
group_name);
@@ -499,11 +486,6 @@ OptixRaytracer::make_optix_materials()
OIIO::Filesystem::write_text_file(filename, osl_ptx);
}
void* interactive_params = nullptr;
shadingsys->getattribute(groupref.get(), "device_interactive_params",
TypeDesc::PTR, &interactive_params);
material_interactive_params.push_back(interactive_params);
OptixModule optix_module;
// Create Programs from the init and group_entry functions,
@@ -562,7 +544,6 @@ OptixRaytracer::make_optix_materials()
final_groups.push_back(sphere_fillSG_dc);
// append the shader groups to our "official" list of program groups
// size_t shader_groups_start_index = final_groups.size();
final_groups.insert(final_groups.end(), shader_groups.begin(),
shader_groups.end());
@@ -642,13 +623,6 @@ OptixRaytracer::make_optix_materials()
sbt_records[sbtIndex++].data = reinterpret_cast<void*>(d_quads_list);
sbt_records[sbtIndex++].data = reinterpret_cast<void*>(d_spheres_list);
// Fill in the data pointer for all the osl callables, starting at
// sbtIndex and 2 for each of the materials.
for (size_t i = 0, e = material_interactive_params.size(); i < e; ++i) {
sbt_records[sbtIndex + 2 * i].data = material_interactive_params[i];
sbt_records[sbtIndex + 2 * i + 1].data = material_interactive_params[i];
}
const int nshaders = int(shader_groups.size());
const int nhitgroups = (scene.quads.size() > 0)
+ (scene.spheres.size() > 0);
@@ -908,17 +882,16 @@ OptixRaytracer::good(TextureHandle* handle OSL_MAYBE_UNUSED)
/// Given the name of a texture, return an opaque handle that can be
/// used with texture calls to avoid the name lookups.
RendererServices::TextureHandle*
OptixRaytracer::get_texture_handle(ustringhash filename,
ShadingContext* /*shading_context*/,
const TextureOpt* options)
OptixRaytracer::get_texture_handle(ustring filename OSL_MAYBE_UNUSED,
ShadingContext* shading_context
OSL_MAYBE_UNUSED)
{
auto itr = m_samplers.find(filename);
if (itr == m_samplers.end()) {
// Open image
OIIO::ImageBuf image;
if (!image.init_spec(ustring_from(filename), 0, 0)) {
errhandler().errorfmt("Could not load: {} (hash {})",
ustring_from(filename), filename);
if (!image.init_spec(filename, 0, 0)) {
errhandler().errorfmt("Could not load: {}", filename);
return (TextureHandle*)nullptr;
}
@@ -1099,7 +1072,7 @@ OptixRaytracer::processPrintfBuffer(void* buffer_data, size_t buffer_size)
switch (format[j]) {
case '%':
// seems like a silly to print a '%', but it keeps the logic parallel with the other cases
dst += snprintf(&buffer[dst], BufferSize - dst, "%s",
dst += snprintf(&buffer[dst], BufferSize - dst,
fmt_string.c_str());
format_end_found = true;
break;
+17 -19
View File
@@ -25,7 +25,10 @@ public:
OptixRaytracer();
virtual ~OptixRaytracer();
int supports(string_view feature) const override
uint64_t register_global(const std::string& str, uint64_t value);
bool fetch_global(const std::string& str, uint64_t* value);
virtual int supports(string_view feature) const
{
if (feature == "OptiX")
return true;
@@ -35,25 +38,24 @@ public:
std::string load_ptx_file(string_view filename);
bool synch_attributes();
bool init_optix_context(int xres, int yres);
bool make_optix_materials();
bool finalize_scene();
void prepare_render() override;
void warmup() override;
void render(int xres, int yres) override;
void finalize_pixel_buffer() override;
void clear() override;
virtual bool init_optix_context(int xres, int yres);
virtual bool make_optix_materials();
virtual bool finalize_scene();
virtual void prepare_render();
virtual void warmup();
virtual void render(int xres, int yres);
virtual void finalize_pixel_buffer();
virtual void clear();
/// Return true if the texture handle (previously returned by
/// get_texture_handle()) is a valid texture that can be subsequently
/// read or sampled.
bool good(TextureHandle* handle) override;
virtual bool good(TextureHandle* handle);
/// Given the name of a texture, return an opaque handle that can be
/// used with texture calls to avoid the name lookups.
TextureHandle* get_texture_handle(ustringhash filename,
ShadingContext* shading_context,
const TextureOpt* options) override;
virtual TextureHandle* get_texture_handle(ustring filename,
ShadingContext* shading_context);
// Easy way to do Optix calls
optix::Context& optix_ctx() { return m_optix_ctx; }
@@ -62,11 +64,6 @@ public:
void processPrintfBuffer(void* buffer_data, size_t buffer_size);
virtual void* device_alloc(size_t size) override;
virtual void device_free(void* ptr) override;
virtual void* copy_to_device(void* dst_device, const void* src_host,
size_t size) override;
private:
optix::Context m_optix_ctx = nullptr;
@@ -96,7 +93,8 @@ private:
OptixProgramGroup* pg);
std::string m_materials_ptx;
std::unordered_map<ustringhash, optix::TextureSampler> m_samplers;
std::unordered_map<OIIO::ustring, optix::TextureSampler> m_samplers;
std::unordered_map<OIIO::ustring, uint64_t> m_globals_map;
};
+7 -24
View File
@@ -15,7 +15,7 @@
#include <OSL/oslconfig.h>
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
# include <optix.h>
# include <vector_functions.h> // from CUDA
#endif
@@ -43,24 +43,8 @@ ortho(const Vec3& n, Vec3& x, Vec3& y)
// Note: not used in OptiX mode
struct Ray {
enum RayType {
CAMERA = 1,
SHADOW = 2,
REFLECTION = 4,
REFRACTION = 8,
DIFFUSE = 16,
GLOSSY = 32,
SUBSURFACE = 64,
DISPLACEMENT = 128
};
Ray(const Vec3& o, const Vec3& d, float radius, float spread,
RayType raytype)
: origin(o)
, direction(d)
, radius(radius)
, spread(spread)
, raytype(static_cast<int>(raytype))
Ray(const Vec3& o, const Vec3& d, float radius, float spread)
: origin(o), direction(d), radius(radius), spread(spread)
{
}
@@ -88,7 +72,6 @@ struct Ray {
Vec3 origin, direction;
float radius, spread;
int raytype;
};
@@ -133,7 +116,7 @@ struct Camera {
const float cos_a = dir.dot(v);
const float spread
= sqrtf(invw * invh * cx.length() * cy.length() * cos_a) * cos_a;
return Ray(eye, v, 0, spread, Ray::CAMERA);
return Ray(eye, v, 0, spread);
}
// Specified by user:
@@ -167,7 +150,7 @@ struct Primitive {
void getBounds(float& minx, float& miny, float& minz, float& maxx,
float& maxy, float& maxz) const;
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
virtual void setOptixVariables(void* data) const = 0;
#endif
@@ -278,7 +261,7 @@ struct Sphere final : public Primitive {
return 1 / (TWOPI * (1 - cmax));
}
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
virtual void setOptixVariables(void* data) const
{
SphereParams* sphere_data = reinterpret_cast<SphereParams*>(data);
@@ -377,7 +360,7 @@ struct Quad final : public Primitive {
return d2 / (a * fabsf(dir.dot(n)));
}
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
virtual void setOptixVariables(void* data) const
{
QuadParams* quad_data = reinterpret_cast<QuadParams*>(data);
+2 -12
View File
@@ -1,13 +1,9 @@
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
#pragma once
#include "optix_compat.h"
#if OSL_USE_OPTIX || defined(__CUDA_ARCH__)
#if defined(OSL_USE_OPTIX) || defined(__CUDA_ARCH__)
struct RenderParams {
float3 bad_color;
@@ -67,12 +63,6 @@ struct QuadParams : PrimitiveParams {
struct GenericData {
// For geometry hit callables, data is the pointer to the array of
// primitive params for that primitive type, and sbtGeoIndex is the index
// for this primitive.
//
// For shader/material callables, data points to the interactive parameter
// data arena for that material.
void* data;
unsigned int sbtGeoIndex;
};
@@ -82,7 +72,7 @@ struct GenericData {
struct GenericRecord {
__align__(
OPTIX_SBT_RECORD_ALIGNMENT) char header[OPTIX_SBT_RECORD_HEADER_SIZE];
// What follows should duplicate GenericData
void* data;
unsigned int sbtGeoIndex;
};
+4 -5
View File
@@ -154,11 +154,10 @@ struct MxConductorParams : public MxMicrofacetBaseParams {
Color3 evalT(float cos_theta) const { return Color3(0.0f); }
// Avoid function was declared but never referenced
// float get_ior() const
// {
// return 0; // no transmission possible
// }
float get_ior() const
{
return 0; // no transmission possible
}
};
struct MxGeneralizedSchlickParams : public MxMicrofacetBaseParams {
+39 -45
View File
@@ -441,7 +441,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
bool
SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
ustringhash from, float /*time*/)
ustring from, float /*time*/)
{
TransformMap::const_iterator found = m_named_xforms.find(from);
if (found != m_named_xforms.end()) {
@@ -468,7 +468,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
bool
SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
ustringhash from)
ustring from)
{
// SimpleRaytracer doesn't understand motion blur, so we never fail
// on account of time-varying transformations.
@@ -485,7 +485,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
bool
SimpleRaytracer::get_inverse_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
ustringhash to, float /*time*/)
ustring to, float /*time*/)
{
if (to == u_camera || to == u_screen || to == u_NDC || to == u_raster) {
// clang-format off
@@ -544,15 +544,15 @@ void
SimpleRaytracer::name_transform(const char* name, const OSL::Matrix44& xform)
{
std::shared_ptr<Transformation> M(new OSL::Matrix44(xform));
m_named_xforms[ustringhash(name)] = M;
m_named_xforms[ustring(name)] = M;
}
bool
SimpleRaytracer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, int index, void* val)
ustring object, TypeDesc type,
ustring name, int index, void* val)
{
AttrGetterMap::const_iterator g = m_attr_getters.find(name);
if (g != m_attr_getters.end()) {
@@ -572,8 +572,8 @@ SimpleRaytracer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
bool
SimpleRaytracer::get_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, void* val)
ustring object, TypeDesc type, ustring name,
void* val)
{
return get_array_attribute(sg, derivatives, object, type, name, -1, val);
}
@@ -581,7 +581,7 @@ SimpleRaytracer::get_attribute(ShaderGlobals* sg, bool derivatives,
bool
SimpleRaytracer::get_userdata(bool derivatives, ustringhash name, TypeDesc type,
SimpleRaytracer::get_userdata(bool derivatives, ustring name, TypeDesc type,
ShaderGlobals* sg, void* val)
{
// Just to illustrate how this works, respect s and t userdata, filled
@@ -612,8 +612,8 @@ SimpleRaytracer::get_userdata(bool derivatives, ustringhash name, TypeDesc type,
bool
SimpleRaytracer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeInt) {
((int*)val)[0] = OSL_VERSION;
@@ -625,8 +625,8 @@ SimpleRaytracer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
bool
SimpleRaytracer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeIntArray2) {
((int*)val)[0] = camera.xres;
@@ -639,8 +639,8 @@ SimpleRaytracer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
bool
SimpleRaytracer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeString) {
((ustring*)val)[0] = m_projection;
@@ -652,8 +652,8 @@ SimpleRaytracer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
bool
SimpleRaytracer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
// N.B. in a real renderer, this may be time-dependent
if (type == TypeDesc::TypeFloat) {
@@ -668,8 +668,8 @@ SimpleRaytracer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeFloat) {
((float*)val)[0] = m_pixelaspect;
@@ -683,8 +683,8 @@ SimpleRaytracer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeFloatArray2) {
((float*)val)[0] = m_hither;
@@ -699,8 +699,8 @@ SimpleRaytracer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeFloat) {
((float*)val)[0] = m_hither;
@@ -714,8 +714,8 @@ SimpleRaytracer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeFloat) {
((float*)val)[0] = m_yon;
@@ -730,8 +730,8 @@ SimpleRaytracer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeFloatArray2) {
((float*)val)[0] = m_shutter[0];
@@ -746,8 +746,8 @@ SimpleRaytracer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeFloat) {
((float*)val)[0] = m_shutter[0];
@@ -761,8 +761,8 @@ SimpleRaytracer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
if (type == TypeDesc::TypeFloat) {
((float*)val)[0] = m_shutter[1];
@@ -776,8 +776,8 @@ SimpleRaytracer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
bool
SimpleRaytracer::get_camera_screen_window(ShaderGlobals* /*sg*/, bool derivs,
ustringhash /*object*/, TypeDesc type,
ustringhash /*name*/, void* val)
ustring /*object*/, TypeDesc type,
ustring /*name*/, void* val)
{
// N.B. in a real renderer, this may be time-dependent
if (type == TypeFloatArray4) {
@@ -823,7 +823,6 @@ SimpleRaytracer::globals_from_hit(ShaderGlobals& sg, const Ray& r,
sg.N = -sg.N;
sg.Ng = -sg.Ng;
}
sg.raytype = r.raytype;
sg.flipHandedness = sg.dPdx.cross(sg.dPdy).dot(sg.N) < 0;
// In our SimpleRaytracer, the "renderstate" itself just a pointer to
@@ -832,16 +831,13 @@ SimpleRaytracer::globals_from_hit(ShaderGlobals& sg, const Ray& r,
}
Vec3
SimpleRaytracer::eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx,
int bounce)
SimpleRaytracer::eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx)
{
ShaderGlobals sg;
memset((char*)&sg, 0, sizeof(ShaderGlobals));
sg.I = dir.val();
sg.dIdx = dir.dx();
sg.dIdy = dir.dy();
if (bounce >= 0)
sg.raytype = bounce > 0 ? Ray::DIFFUSE : Ray::CAMERA;
shadingsys->execute(*ctx, *m_shaders[backgroundShaderID], sg);
return process_background_closure(sg.Ci);
}
@@ -863,7 +859,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
if (!scene.intersect(r, t, id)) {
// we hit nothing? check background shader
if (backgroundShaderID >= 0) {
if (b > 0 && backgroundResolution > 0) {
if (backgroundResolution > 0) {
float bg_pdf = 0;
Vec3 bg = background.eval(r.direction, bg_pdf);
path_radiance
@@ -873,7 +869,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
} else {
// we aren't importance sampling the background - so just run it directly
path_radiance += path_weight
* eval_background(r.direction, ctx, b);
* eval_background(r.direction, ctx);
}
}
break;
@@ -935,8 +931,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
b.pdf);
if ((contrib.x + contrib.y + contrib.z) > 0) {
int shadow_id = id;
Ray shadow_ray = Ray(sg.P, bg_dir.val(), radius, 0,
Ray::SHADOW);
Ray shadow_ray = Ray(sg.P, bg_dir.val(), radius, 0);
Dual2<float> shadow_dist;
if (!scene.intersect(shadow_ray, shadow_dist,
shadow_id)) // ray reached the background?
@@ -961,7 +956,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
* MIS::power_heuristic<MIS::EVAL_WEIGHT>(light_pdf,
b.pdf);
if ((contrib.x + contrib.y + contrib.z) > 0) {
Ray shadow_ray = Ray(sg.P, ldir, radius, 0, Ray::SHADOW);
Ray shadow_ray = Ray(sg.P, ldir, radius, 0);
// trace a shadow ray and see if we actually hit the target
// in this tiny renderer, tracing a ray is probably cheaper than evaluating the light shader
int shadow_id = id; // ignore self hit
@@ -984,8 +979,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
// trace indirect ray and continue
BSDF::Sample p = result.bsdf.sample(-sg.I, xi, yi, zi);
path_weight *= p.weight;
bsdf_pdf = p.pdf;
r.raytype = Ray::DIFFUSE; // FIXME? Use DIFFUSE for all indiirect rays
bsdf_pdf = p.pdf;
r.direction = p.wi;
r.radius = radius;
// Just simply use roughness as spread slope
+47 -54
View File
@@ -30,23 +30,23 @@ public:
virtual ~SimpleRaytracer() {}
// RendererServices support:
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform, float time) override;
bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustringhash from,
float time) override;
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform) override;
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
ustringhash from) override;
bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result, ustringhash to,
float time) override;
bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
ustringhash object, TypeDesc type,
ustringhash name, int index, void* val) override;
bool get_attribute(ShaderGlobals* sg, bool derivatives, ustringhash object,
TypeDesc type, ustringhash name, void* val) override;
bool get_userdata(bool derivatives, ustringhash name, TypeDesc type,
ShaderGlobals* sg, void* val) override;
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform, float time);
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustring from,
float time);
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
TransformationPtr xform);
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustring from);
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
ustring to, float time);
virtual bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
ustring object, TypeDesc type,
ustring name, int index, void* val);
virtual bool get_attribute(ShaderGlobals* sg, bool derivatives,
ustring object, TypeDesc type, ustring name,
void* val);
virtual bool get_userdata(bool derivatives, ustring name, TypeDesc type,
ShaderGlobals* sg, void* val);
void name_transform(const char* name, const Transformation& xform);
@@ -109,7 +109,7 @@ private:
float m_screen_window[4];
int backgroundShaderID = -1;
int backgroundResolution = 1024;
int backgroundResolution = 0;
int aa = 1;
int max_bounces = 1000000;
int rr_depth = 5;
@@ -121,7 +121,7 @@ private:
bool m_had_error = false;
// Named transforms
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
typedef std::map<ustring, std::shared_ptr<Transformation>> TransformMap;
TransformMap m_named_xforms;
// Attribute and userdata retrieval -- for fast dispatch, use a hash
@@ -130,50 +130,43 @@ private:
// renderer, we would encourage benchmarking various methods and
// alternate data structures.
typedef bool (SimpleRaytracer::*AttrGetter)(ShaderGlobals* sg, bool derivs,
ustringhash object,
TypeDesc type, ustringhash name,
void* val);
typedef std::unordered_map<ustringhash, AttrGetter> AttrGetterMap;
ustring object, TypeDesc type,
ustring name, void* val);
typedef std::unordered_map<ustring, AttrGetter> AttrGetterMap;
AttrGetterMap m_attr_getters;
// Attribute getters
bool get_osl_version(ShaderGlobals* sg, bool derivs, ustringhash object,
TypeDesc type, ustringhash name, void* val);
bool get_camera_resolution(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
bool get_camera_projection(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
bool get_camera_fov(ShaderGlobals* sg, bool derivs, ustringhash object,
TypeDesc type, ustringhash name, void* val);
bool get_camera_pixelaspect(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
bool get_camera_clip(ShaderGlobals* sg, bool derivs, ustringhash object,
TypeDesc type, ustringhash name, void* val);
bool get_camera_clip_near(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
bool get_camera_clip_far(ShaderGlobals* sg, bool derivs, ustringhash object,
TypeDesc type, ustringhash name, void* val);
bool get_camera_shutter(ShaderGlobals* sg, bool derivs, ustringhash object,
TypeDesc type, ustringhash name, void* val);
bool get_camera_shutter_open(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
bool get_osl_version(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_resolution(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_projection(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_fov(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_pixelaspect(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_clip(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_clip_near(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_clip_far(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_shutter(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_shutter_open(ShaderGlobals* sg, bool derivs, ustring object,
TypeDesc type, ustring name, void* val);
bool get_camera_shutter_close(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
ustring object, TypeDesc type, ustring name,
void* val);
bool get_camera_screen_window(ShaderGlobals* sg, bool derivs,
ustringhash object, TypeDesc type,
ustringhash name, void* val);
ustring object, TypeDesc type, ustring name,
void* val);
// CPU renderer helpers
void globals_from_hit(ShaderGlobals& sg, const Ray& r,
const Dual2<float>& t, int id);
Vec3 eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx,
int bounce = -1);
Vec3 eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx);
Color3 subpixel_radiance(float x, float y, Sampler& sampler,
ShadingContext* ctx);
Color3 antialias_pixel(int x, int y, ShadingContext* ctx);
+4 -8
View File
@@ -25,7 +25,7 @@
#include "shading.h"
#include "simpleraytracer.h"
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
# include "optixraytracer.h"
#endif
@@ -87,6 +87,7 @@ set_shadingsys_options()
shadingsys->attribute("llvm_optimize", llvm_opt);
shadingsys->attribute("profile", int(profile));
shadingsys->attribute("lockgeom", 1);
shadingsys->attribute("debug_nan", debugnan);
shadingsys->attribute("debug_uninit", debug_uninit);
shadingsys->attribute("userdata_isconnected", userdata_isconnected);
@@ -100,11 +101,6 @@ set_shadingsys_options()
shadingsys->attribute("llvm_debugging_symbols", 1);
shadingsys->attribute("llvm_profiling_events", 1);
// We rely on the default set of "raytypes" tags. To use a custom set,
// this is where we would do:
// shadingsys->attribute("raytypes", TypeDesc(TypeDesc::STRING, num_raytypes),
// raytype_names);
shadingsys_options_set = true;
}
@@ -234,7 +230,7 @@ main(int argc, const char* argv[])
aa = aaoverride;
SimpleRaytracer* rend = nullptr;
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
if (use_optix)
rend = new OptixRaytracer;
else
@@ -267,7 +263,7 @@ main(int argc, const char* argv[])
// Setup common attributes
set_shadingsys_options();
#if OSL_USE_OPTIX
#ifdef OSL_USE_OPTIX
if (use_optix)
reinterpret_cast<OptixRaytracer*>(rend)->synch_attributes();
#endif

Some files were not shown because too many files have changed in this diff Show More