Compare commits
53
Commits
analysis
...
dev-1.13.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b7e81fd43 | ||
|
|
edf079ce6d | ||
|
|
2754fa2a08 | ||
|
|
56a6099de1 | ||
|
|
86050991c4 | ||
|
|
4478b290d1 | ||
|
|
26868c8493 | ||
|
|
786e943b61 | ||
|
|
a12f99bf5a | ||
|
|
3a59480628 | ||
|
|
74be126d44 | ||
|
|
d27b57e5b1 | ||
|
|
9a2b49d81e | ||
|
|
1d17ae944a | ||
|
|
6012b09777 | ||
|
|
b43ec5546a | ||
|
|
4d9ef03d76 | ||
|
|
3e2689db51 | ||
|
|
9673b6faa2 | ||
|
|
9644456f0d | ||
|
|
dccf7a3360 | ||
|
|
959b0c1330 | ||
|
|
9ae5b69fd8 | ||
|
|
3bd3778610 | ||
|
|
a8d3ac06e6 | ||
|
|
c0a5998c19 | ||
|
|
5dad5076bc | ||
|
|
317c59ed73 | ||
|
|
66c9b61d72 | ||
|
|
8036e174fb | ||
|
|
b064b25721 | ||
|
|
8d1d9f0cf6 | ||
|
|
1c196d935c | ||
|
|
a878883eeb | ||
|
|
1b3c96603c | ||
|
|
e468ef7595 | ||
|
|
fae61e699f | ||
|
|
7b6854823d | ||
|
|
f84126fb3e | ||
|
|
395e58d6bf | ||
|
|
75401bda4c | ||
|
|
8530aa059a | ||
|
|
bd7fd4cf8c | ||
|
|
61ea4c9a31 | ||
|
|
afec48ebde | ||
|
|
9ef1741056 | ||
|
|
1e8ef316ac | ||
|
|
aafb5cb74e | ||
|
|
d0e49675e5 | ||
|
|
dde0a3451a | ||
|
|
3187864f9b | ||
|
|
66747ac1e6 | ||
|
|
d867d98a50 |
@@ -19,6 +19,11 @@ on:
|
||||
|
||||
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:
|
||||
|
||||
@@ -30,7 +35,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: sonary gcc9/C++14 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
- desc: sonar gcc9/C++14 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: static-analysis-sonar
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
@@ -40,7 +45,7 @@ jobs:
|
||||
python_ver: 3.9
|
||||
pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2
|
||||
batched: b8_AVX2,b16_AVX512
|
||||
coverage: 1
|
||||
# skip_tests: 1
|
||||
sonar: 1
|
||||
|
||||
+17
-12
@@ -20,8 +20,10 @@ on:
|
||||
- '**.rst'
|
||||
- '**.tex'
|
||||
schedule:
|
||||
# Full nightly build
|
||||
# Full nightly build, for the main project repo (not for forks)
|
||||
- cron: "0 6 * * *"
|
||||
if: github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
|
||||
|
||||
|
||||
permissions: read-all
|
||||
|
||||
@@ -45,7 +47,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-18.04
|
||||
os: ubuntu-20.04
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang9
|
||||
cc_compiler: clang
|
||||
@@ -66,7 +68,8 @@ jobs:
|
||||
# pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
skip_tests: 1
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=8.1.1
|
||||
- desc: gcc6/C++14 llvm10 py3.7 boost1.70 exr2.4 oiio2.2 sse4
|
||||
nametag: linux-vfx2020
|
||||
os: ubuntu-latest
|
||||
@@ -111,11 +114,11 @@ jobs:
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: USE_OPENVDB=0
|
||||
- desc: icc/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
- desc: icc/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
nametag: linux-icc
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
vfxsuffix: -clang14
|
||||
cc_compiler: icc
|
||||
cxx_compiler: icpc
|
||||
cxx_std: 17
|
||||
@@ -128,11 +131,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 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
- desc: icx/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: linux-icx
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
vfxsuffix: -clang14
|
||||
cc_compiler: icx
|
||||
cxx_compiler: icpx
|
||||
cxx_std: 17
|
||||
@@ -287,7 +290,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-18.04
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-7
|
||||
cxx_std: 14
|
||||
openexr_ver: v2.4.3
|
||||
@@ -301,7 +304,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-18.04
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-10
|
||||
cxx_std: 17
|
||||
fmt_ver: 7.0.1
|
||||
@@ -319,7 +322,7 @@ jobs:
|
||||
cxx_compiler: g++-11
|
||||
cxx_std: 17
|
||||
fmt_ver: 9.1.0
|
||||
openexr_ver: v3.1.5
|
||||
openexr_ver: v3.1.6
|
||||
openimageio_ver: master
|
||||
pybind11_ver: v2.10.0
|
||||
python_ver: 3.9
|
||||
@@ -327,8 +330,8 @@ jobs:
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: export LLVM_VERSION=13.0.0
|
||||
LLVM_DISTRO_NAME=ubuntu-20.04
|
||||
OPENCOLORIO_VERSION=v2.1.2
|
||||
PUGIXML_VERSION=v1.11.4
|
||||
OPENCOLORIO_VERSION=v2.2.0
|
||||
PUGIXML_VERSION=v1.13
|
||||
- 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
|
||||
@@ -432,6 +435,7 @@ jobs:
|
||||
python_ver: "3.10"
|
||||
aclang: 13
|
||||
setenvs: export LLVMBREWVER="@14" DO_BREW_UPDATE=1
|
||||
OPENIMAGEIO_VERSION=release
|
||||
- desc: MacOS-12
|
||||
os: macos-12
|
||||
nametag: macos11-p310
|
||||
@@ -441,6 +445,7 @@ 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}}
|
||||
|
||||
@@ -10,18 +10,23 @@ 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"
|
||||
|
||||
+68
-1
@@ -23,6 +23,10 @@ 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
|
||||
@@ -34,6 +38,14 @@ 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:
|
||||
|
||||
@@ -44,27 +56,82 @@ 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)
|
||||
(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)
|
||||
* 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:
|
||||
|
||||
+9
-1
@@ -4,7 +4,14 @@
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
|
||||
set (OSL_VERSION "1.13.1.0" CACHE STRING "Version")
|
||||
set (OSL_VERSION "1.13.2.4")
|
||||
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 ()
|
||||
|
||||
project (OSL VERSION ${OSL_VERSION}
|
||||
LANGUAGES CXX C
|
||||
HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/OpenShadingLanguage")
|
||||
@@ -100,6 +107,7 @@ 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")
|
||||
|
||||
+6
-5
@@ -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.24)
|
||||
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.26)
|
||||
|
||||
* 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 15)
|
||||
- Clang 3.4 or newer (tested through clang 16)
|
||||
- Microsoft Visual Studio 2017 or newer
|
||||
- Intel C++ compiler icc version 17 or newer or LLVM-based icx compiler
|
||||
version 2022 or newer.
|
||||
@@ -41,13 +41,14 @@ 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.
|
||||
clang libraries. LLVM 16 doesn't work yet, we need to make changes
|
||||
on the OSL side to be compatible.
|
||||
|
||||
* (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.80)
|
||||
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.81)
|
||||
* [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
|
||||
@@ -55,7 +56,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/)
|
||||
* [PugiXML](http://pugixml.org/) >= 1.8 (we have tested through 1.13).
|
||||
* (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.
|
||||
|
||||
@@ -225,8 +225,7 @@ 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](http://www.isotropix.com/clarisse)
|
||||
* [Isotropix: Angie](http://www.isotropix.com/angie)
|
||||
* 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)
|
||||
* [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/)
|
||||
@@ -390,8 +389,9 @@ Films using OSL (grouped by year of release date):
|
||||
Last Night in Soho,
|
||||
Ghostbusters: Afterlife,
|
||||
Spider-Man 3: No Way Home,
|
||||
Matrix Resurrections
|
||||
* **(2022 / upcoming)**
|
||||
Matrix Resurrections,
|
||||
Sing 2
|
||||
* **(2022)**
|
||||
Hotel Transylvania 4: Transformania,
|
||||
Death on the Nile,
|
||||
Uncharted,
|
||||
@@ -404,11 +404,15 @@ 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
|
||||
-------------------------
|
||||
|
||||
@@ -481,18 +485,20 @@ 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, 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
|
||||
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
|
||||
Kulla, Elvic Liang, Max Liani, Adam Martinez, John Mertic, Bastien Montagne,
|
||||
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.)
|
||||
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.)
|
||||
|
||||
We cannot possibly express sufficient gratitude to the managers at Sony
|
||||
Pictures Imageworks who allowed this project to proceed, supported it
|
||||
|
||||
@@ -189,6 +189,10 @@ 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)
|
||||
@@ -196,13 +200,13 @@ else ifeq (${platform}, macosx)
|
||||
else ifeq (${COMPILER},)
|
||||
# default compiler is clang, taken from the LLVM directory
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
else ifeq (${COMPILER},llvm)
|
||||
# "llvm" means "use the clang from our llvm"
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
endif
|
||||
|
||||
# end generic OSX
|
||||
|
||||
@@ -14,7 +14,7 @@ uname
|
||||
|
||||
|
||||
if [[ `uname` == "Linux" ]] ; then
|
||||
LLVM_VERSION=${LLVM_VERSION:=13.0.0}
|
||||
LLVM_VERSION=${LLVM_VERSION:=14.0.0}
|
||||
LLVM_INSTALL_DIR=${LLVM_INSTALL_DIR:=${PWD}/llvm-install}
|
||||
if [[ "$GITHUB_WORKFLOW" != "" ]] ; then
|
||||
LLVM_DISTRO_NAME=${LLVM_DISTRO_NAME:=ubuntu-18.04}
|
||||
|
||||
@@ -18,8 +18,8 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
|
||||
#ls /etc/yum.repos.d
|
||||
|
||||
sudo yum install -y giflib giflib-devel && true
|
||||
# sudo yum install -y ffmpeg ffmpeg-devel && true
|
||||
sudo /usr/bin/yum install -y giflib giflib-devel && true
|
||||
# sudo /usr/bin/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 yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0-3768
|
||||
sudo /usr/bin/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 \
|
||||
|
||||
@@ -19,6 +19,7 @@ if [[ `which brew` == "" ]] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
if [[ "$DO_BREW_UPDATE" != "" ]] ; then
|
||||
brew update >/dev/null
|
||||
@@ -30,15 +31,16 @@ 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 ilmbase openexr
|
||||
brew install --display-times -q imath openexr
|
||||
#brew install --display-times -q freetype
|
||||
brew install --display-times -q opencolorio partio pugixml
|
||||
brew install --display-times -q --overwrite --force opencolorio || true
|
||||
brew install --display-times -q partio pugixml
|
||||
brew install --display-times -q pybind11 numpy || true
|
||||
brew install --display-times -q tbb || true
|
||||
brew install --display-times -q flex bison
|
||||
|
||||
@@ -352,7 +352,7 @@ if (NOT USE_BATCHED STREQUAL "")
|
||||
if (VERBOSE)
|
||||
message (STATUS "BATCHED target: ${batched_target}")
|
||||
endif ()
|
||||
set (BATCHED_SUPPORT_DEFINES ${BATCHED_SUPPORT_DEFINES} "__OSL_SUPPORTS_${batched_target}")
|
||||
list (APPEND BATCHED_SUPPORT_DEFINES "__OSL_SUPPORTS_${batched_target}")
|
||||
endforeach()
|
||||
else ()
|
||||
message (STATUS "Compiling with NO batched SIMD targets, USE_BATCHED=0")
|
||||
|
||||
@@ -21,6 +21,12 @@ 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}"
|
||||
|
||||
@@ -115,6 +115,7 @@ 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}")
|
||||
@@ -144,6 +145,19 @@ 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,44 +181,46 @@ endif ()
|
||||
|
||||
# CUDA setup
|
||||
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 (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 (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"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${cuda_lib})
|
||||
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})
|
||||
|
||||
# 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})
|
||||
# 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})
|
||||
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# OptiX setup
|
||||
if (USE_OPTIX)
|
||||
if (USE_OPTIX AND OSL_BUILD_TESTS)
|
||||
checked_find_package (OptiX REQUIRED
|
||||
VERSION_MIN 7.0)
|
||||
include_directories (BEFORE "${OPTIX_INCLUDES}")
|
||||
@@ -219,7 +235,6 @@ if (USE_CUDA OR 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()
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
|
||||
# try to find llvm-config, with a specific version if specified
|
||||
if (LLVM_DIRECTORY)
|
||||
set (LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
|
||||
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")
|
||||
endif ()
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS
|
||||
"/usr/local/opt/llvm/${LLVM_VERSION}/bin/"
|
||||
@@ -121,7 +127,7 @@ endif ()
|
||||
|
||||
foreach (COMPONENT clangFrontend clangDriver clangSerialization
|
||||
clangParse clangSema clangAnalysis clangAST clangBasic
|
||||
clangEdit clangLex)
|
||||
clangEdit clangLex clangSupport)
|
||||
find_library ( _CLANG_${COMPONENT}_LIBRARY
|
||||
NAMES ${COMPONENT}
|
||||
PATHS ${LLVM_LIB_DIR})
|
||||
|
||||
@@ -236,7 +236,8 @@ 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 color color-reg colorspace comparison
|
||||
cellnoise closure closure-array closure-parameters closure-zero closure-conditional
|
||||
color color-reg colorspace comparison
|
||||
complement-reg compile-buffer compassign-reg
|
||||
component-range
|
||||
control-flow-reg connect-components
|
||||
@@ -297,6 +298,7 @@ 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
|
||||
@@ -351,7 +353,7 @@ macro (osl_add_all_tests)
|
||||
transform transform-reg transformc transformc-reg trig trig-reg
|
||||
typecast
|
||||
unknown-instruction
|
||||
userdata userdata-passthrough
|
||||
userdata userdata-custom userdata-passthrough
|
||||
vararray-connect vararray-default
|
||||
vararray-deserialize vararray-param
|
||||
vecctr vector vector-reg
|
||||
@@ -383,7 +385,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 ()
|
||||
|
||||
|
||||
@@ -5599,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
|
||||
searching global scene-wide attributes.
|
||||
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
|
||||
|
||||
@@ -82,12 +82,13 @@ 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,
|
||||
ustring from, Wide<const float> wtime)
|
||||
ustringhash from, Wide<const float> wtime)
|
||||
{
|
||||
return Mask(false);
|
||||
}
|
||||
virtual Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustring> wfrom, Wide<const float> wtime);
|
||||
Wide<const ustringhash> wfrom,
|
||||
Wide<const float> wtime);
|
||||
virtual bool is_overridden_get_matrix_WmWsWf() const = 0;
|
||||
|
||||
|
||||
@@ -97,12 +98,12 @@ public:
|
||||
/// particular renderer may have a better technique and overload the
|
||||
/// implementation.
|
||||
virtual Mask get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult, ustring to,
|
||||
Masked<Matrix44> wresult, ustringhash 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 ustring> wto,
|
||||
Wide<const ustringhash> wto,
|
||||
Wide<const float> wtime);
|
||||
virtual bool is_overridden_get_inverse_matrix_WmWsWf() const = 0;
|
||||
|
||||
@@ -124,22 +125,23 @@ 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, ustring object,
|
||||
ustring name, MaskedData wval)
|
||||
virtual Mask get_attribute(BatchedShaderGlobals* bsg, ustringhash object,
|
||||
ustringhash 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, ustring object,
|
||||
ustring name, int index, MaskedData wval)
|
||||
virtual Mask get_array_attribute(BatchedShaderGlobals* bsg,
|
||||
ustringhash object, ustringhash name,
|
||||
int index, MaskedData wval)
|
||||
{
|
||||
return Mask(false);
|
||||
}
|
||||
|
||||
virtual bool get_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustring object, ustring name,
|
||||
ustringhash object, ustringhash name,
|
||||
RefData val)
|
||||
{
|
||||
return false;
|
||||
@@ -148,8 +150,9 @@ public:
|
||||
/// Similar to get_attribute(); this method will fetch the 'index'
|
||||
/// element of an attribute array.
|
||||
virtual bool get_array_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustring object, ustring name,
|
||||
int index, RefData val)
|
||||
ustringhash object,
|
||||
ustringhash name, int index,
|
||||
RefData val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -159,7 +162,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(ustring name, BatchedShaderGlobals* bsg,
|
||||
virtual Mask get_userdata(ustringhash name, BatchedShaderGlobals* bsg,
|
||||
MaskedData wval)
|
||||
{
|
||||
return Mask(false);
|
||||
@@ -206,7 +209,7 @@ public:
|
||||
/// error.
|
||||
///
|
||||
virtual Mask
|
||||
texture(ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
texture(ustringhash 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,
|
||||
@@ -240,7 +243,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(ustring filename,
|
||||
virtual Mask texture3d(ustringhash filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options,
|
||||
@@ -273,7 +276,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(ustring filename,
|
||||
virtual Mask environment(ustringhash filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options,
|
||||
@@ -300,12 +303,12 @@ public:
|
||||
|
||||
virtual TextureSystem::TextureHandle* resolve_udim_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
|
||||
float T);
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
float S, float T);
|
||||
|
||||
virtual void resolve_udim(BatchedShaderGlobals* bsg,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ustring filename,
|
||||
ustringhash filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
Wide<const float> wS, Wide<const float> wT,
|
||||
Masked<TextureSystem::TextureHandle*> wresult);
|
||||
@@ -313,8 +316,8 @@ public:
|
||||
// Assumes any UDIM has been resolved already
|
||||
virtual bool get_texture_info_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustring dataname, RefData val);
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustringhash dataname, RefData val);
|
||||
|
||||
|
||||
/// Lookup nearest points in a point cloud. It will search for
|
||||
@@ -407,26 +410,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
virtual void pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
const void* wcenter,
|
||||
virtual void pointcloud_search(BatchedShaderGlobals* bsg,
|
||||
ustringhash 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, ustring filename,
|
||||
virtual Mask pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points, ustring attr_name,
|
||||
MaskedData wout_data);
|
||||
Wide<const int> wnum_points,
|
||||
ustringhash attr_name, MaskedData wout_data);
|
||||
virtual bool is_overridden_pointcloud_get() const = 0;
|
||||
|
||||
|
||||
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 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 bool is_overridden_pointcloud_write() const = 0;
|
||||
|
||||
/// Options for the trace call.
|
||||
@@ -441,7 +443,8 @@ public:
|
||||
Wide<const Vec3> wdRdy);
|
||||
|
||||
virtual void getmessage(BatchedShaderGlobals* bsg, Masked<int> wresult,
|
||||
ustring source, ustring name, MaskedData wval);
|
||||
ustringhash source, ustringhash name,
|
||||
MaskedData wval);
|
||||
|
||||
// pointcloud_search is T.B.D.
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
|
||||
#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>
|
||||
@@ -19,21 +15,10 @@
|
||||
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__
|
||||
|
||||
@@ -154,15 +154,6 @@ public:
|
||||
void debug_pop_inlined_function();
|
||||
void debug_set_location(OIIO::ustring sourcefile, int sourceline);
|
||||
|
||||
/// Create a new function (that will later be populated with
|
||||
/// instructions) with up to 4 args.
|
||||
OSL_DEPRECATED("Use make_function flavor that takes a cspan (1.12)")
|
||||
llvm::Function* make_function(const std::string& name, bool fastcall,
|
||||
llvm::Type* rettype, llvm::Type* arg1 = NULL,
|
||||
llvm::Type* arg2 = NULL,
|
||||
llvm::Type* arg3 = NULL,
|
||||
llvm::Type* arg4 = NULL);
|
||||
|
||||
/// Create a new function (that will later be populated with
|
||||
/// instructions) with a cspan of args.
|
||||
llvm::Function* make_function(const std::string& name, bool fastcall,
|
||||
@@ -640,6 +631,12 @@ 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.
|
||||
|
||||
@@ -133,6 +133,101 @@ 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.
|
||||
|
||||
@@ -229,7 +324,8 @@ 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
|
||||
// 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
|
||||
template<> struct hash<OSL::ustring> {
|
||||
std::size_t operator()(OSL::ustring u) const noexcept { return u.hash(); }
|
||||
};
|
||||
@@ -243,7 +339,8 @@ template<> struct hash<OSL::ustringhash> {
|
||||
};
|
||||
#endif
|
||||
|
||||
// Not necessary once minimum OIIO defines operator< for ustringhash
|
||||
// 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
|
||||
template<> struct less<OSL::ustringhash> {
|
||||
OSL_HOSTDEVICE constexpr bool operator()(OSL::ustringhash u,
|
||||
OSL::ustringhash v) const noexcept
|
||||
@@ -252,3 +349,21 @@ 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
|
||||
|
||||
@@ -443,6 +443,7 @@ 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.
|
||||
/// 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!
|
||||
|
||||
@@ -144,12 +144,7 @@ inline OSL_HOSTDEVICE float bits_to_01 (unsigned int bits) {
|
||||
OSL_FORCEINLINE OSL_HOSTDEVICE int
|
||||
bitcast_to_uint (float x)
|
||||
{
|
||||
#if OPENIMAGEIO_VERSION >= 20500
|
||||
return OIIO::bitcast<unsigned int, float>(x);
|
||||
#else
|
||||
// obsolete call
|
||||
return OIIO::bit_cast<float, unsigned int>(x);
|
||||
#endif
|
||||
return OSL::bitcast<unsigned int, float>(x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,10 +18,14 @@
|
||||
|
||||
#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
|
||||
@@ -499,6 +503,60 @@
|
||||
|
||||
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
|
||||
|
||||
+118
-121
@@ -2,8 +2,6 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
// clang-format off
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -13,14 +11,13 @@
|
||||
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
|
||||
@@ -49,7 +46,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:
|
||||
@@ -62,28 +59,34 @@ 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
|
||||
@@ -91,29 +94,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,
|
||||
ustring from, float time) { return false; }
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from, float time);
|
||||
|
||||
/// 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,
|
||||
ustring to, float time);
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash 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,
|
||||
ustring from) { return false; }
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from);
|
||||
|
||||
/// Get the 4x4 matrix that transforms points from "common" space to
|
||||
/// the named 'to' coordinate system. Since there is no time value
|
||||
@@ -122,8 +125,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,
|
||||
ustring to);
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash to);
|
||||
|
||||
/// Transform points Pin[0..npoints-1] in named coordinate system
|
||||
/// 'from' into 'to' coordinates, storing the result in Pout[] using
|
||||
@@ -148,11 +151,10 @@ 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,
|
||||
ustring from, ustring to, float time,
|
||||
const Vec3 *Pin, Vec3 *Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype)
|
||||
{ return false; }
|
||||
virtual bool transform_points(ShaderGlobals* sg, ustringhash from,
|
||||
ustringhash to, float time, const Vec3* Pin,
|
||||
Vec3* Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype);
|
||||
|
||||
|
||||
/// Get the named attribute from the renderer and if found then
|
||||
@@ -167,36 +169,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,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void *val) { return false; }
|
||||
virtual bool get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
|
||||
/// Similar to get_attribute(); this method will return the 'index'
|
||||
/// element of an attribute array.
|
||||
virtual bool get_array_attribute (ShaderGlobals *sg, bool derivatives,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, int index, void *val) { return false; }
|
||||
virtual bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val);
|
||||
|
||||
/// 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, ustring name, TypeDesc type,
|
||||
ShaderGlobals *sg, void *val) { return false; }
|
||||
virtual bool get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val);
|
||||
|
||||
/// 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);
|
||||
virtual TextureHandle* get_texture_handle(ustringhash 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.
|
||||
///
|
||||
@@ -224,13 +226,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 (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);
|
||||
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);
|
||||
|
||||
/// Filtered 3D texture lookup for a single point.
|
||||
///
|
||||
@@ -257,14 +259,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 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);
|
||||
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);
|
||||
|
||||
/// Filtered environment lookup for a single point.
|
||||
///
|
||||
@@ -288,13 +289,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 (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);
|
||||
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);
|
||||
|
||||
/// Get information about the given texture. Return true if found
|
||||
/// and the data has been put in *data. Return false if the texture
|
||||
@@ -315,24 +316,20 @@ 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 (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,
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
/// Lookup nearest points in a point cloud. It will search for
|
||||
@@ -343,40 +340,38 @@ public:
|
||||
/// derivatives will be computed for distances (when provided).
|
||||
///
|
||||
/// Return the number of points found, always < max_points
|
||||
virtual int pointcloud_search (ShaderGlobals *sg,
|
||||
ustring filename, const OSL::Vec3 ¢er,
|
||||
float radius, int max_points, bool sort,
|
||||
size_t *out_indices,
|
||||
float *out_distances, int derivs_offset);
|
||||
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);
|
||||
|
||||
/// 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,
|
||||
ustring filename, size_t *indices, int count,
|
||||
ustring attr_name, TypeDesc attr_type,
|
||||
void *out_data);
|
||||
virtual int pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
size_t* indices, int count,
|
||||
ustringhash 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,
|
||||
ustring filename, const OSL::Vec3 &pos,
|
||||
int nattribs, const ustring *names,
|
||||
const TypeDesc *types,
|
||||
const void **data);
|
||||
virtual bool pointcloud_write(ShaderGlobals* sg, ustringhash filename,
|
||||
const OSL::Vec3& pos, int nattribs,
|
||||
const ustringrep* 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
|
||||
ustring 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
|
||||
ustringrep traceset; ///< named trace set
|
||||
TraceOpt() : mindist(0.0f), maxdist(1.0e30), shade(false) {}
|
||||
|
||||
enum class LLVMMemberIndex
|
||||
{
|
||||
enum class LLVMMemberIndex {
|
||||
mindist = 0,
|
||||
maxdist,
|
||||
shade,
|
||||
@@ -387,32 +382,28 @@ 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) {
|
||||
return 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);
|
||||
|
||||
/// 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, ustring source, ustring name,
|
||||
TypeDesc type, void *val, bool derivatives) {
|
||||
return false;
|
||||
}
|
||||
virtual bool getmessage(ShaderGlobals* sg, ustringhash source,
|
||||
ustringhash name, TypeDesc type, void* val,
|
||||
bool derivatives);
|
||||
|
||||
/// Return a pointer to the texture system (if available).
|
||||
virtual TextureSystem *texturesys () const;
|
||||
virtual TextureSystem* texturesys() const;
|
||||
|
||||
virtual uint64_t register_global (const std::string& var_name,
|
||||
uint64_t value)
|
||||
virtual uint64_t register_global(const std::string& var_name,
|
||||
uint64_t value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool fetch_global (const std::string& var_name,
|
||||
uint64_t* value)
|
||||
virtual bool fetch_global(const std::string& var_name, uint64_t* value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -426,19 +417,25 @@ 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
|
||||
};
|
||||
|
||||
|
||||
|
||||
+89
-9
@@ -895,6 +895,8 @@ 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;
|
||||
@@ -942,6 +944,58 @@ 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;
|
||||
@@ -2845,7 +2899,7 @@ public:
|
||||
// Populate all data lanes of the MaskedData by broadcasting the
|
||||
// single instance of data pointed to.
|
||||
// Masked off lanes are not overwritten.
|
||||
// Includes value, as well as Dx and Dy when has_derivs() is true
|
||||
// when has_derivs() is true, Dx and Dy will be zeroed
|
||||
OSL_FORCEINLINE void assign_all_from_scalar(const void* ptr_data) const;
|
||||
|
||||
|
||||
@@ -2863,6 +2917,9 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -3378,6 +3435,33 @@ 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
|
||||
@@ -3393,16 +3477,12 @@ 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) {
|
||||
assign_all_from_scalar_type<int>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<int>(dy_src, /*deriv_index*/ 2);
|
||||
zero_all_type<int>(/*deriv_index*/ 1);
|
||||
zero_all_type<int>(/*deriv_index*/ 2);
|
||||
} else {
|
||||
assign_all_from_scalar_type<ustring>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<ustring>(dy_src, /*deriv_index*/ 2);
|
||||
zero_all_type<ustring>(/*deriv_index*/ 1);
|
||||
zero_all_type<ustring>(/*deriv_index*/ 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +386,7 @@ 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.
|
||||
|
||||
+97
-36
@@ -1116,90 +1116,151 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTbinary_expression::childname (size_t i) const
|
||||
ASTNode*
|
||||
ASTbinary_expression::make(OSLCompilerImpl* comp, Operator op, ASTNode* left,
|
||||
ASTNode* right)
|
||||
{
|
||||
static const char *name[] = { "left", "right" };
|
||||
// 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" };
|
||||
return name[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTbinary_expression::opname () const
|
||||
const char*
|
||||
ASTbinary_expression::opname() const
|
||||
{
|
||||
// clang-format off
|
||||
switch (m_op) {
|
||||
|
||||
@@ -832,6 +832,10 @@ 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;
|
||||
|
||||
+18
-18
@@ -858,109 +858,109 @@ variable_ref
|
||||
binary_expression
|
||||
: expression OR_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Or, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression AND_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::And, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '|' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::BitOr, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '^' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Xor, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '&' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::BitAnd, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression EQ_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Equal, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression NE_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::NotEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '>' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Greater, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression GE_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::GreaterEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '<' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Less, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression LE_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::LessEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression SHL_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::ShiftLeft, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression SHR_OP expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::ShiftRight, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '+' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Add, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '-' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Sub, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '*' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Mul, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '/' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Div, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '%' expression
|
||||
{
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
ASTNode::Mod, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
|
||||
@@ -397,15 +397,6 @@ 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);
|
||||
@@ -415,9 +406,6 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#include <OpenImageIO/filesystem.h>
|
||||
#include <OpenImageIO/strutil.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
#include "backendllvm.h"
|
||||
|
||||
@@ -339,6 +335,7 @@ BackendLLVM::getOrAllocateLLVMSymbol(const Symbol& sym)
|
||||
|
||||
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
llvm::Value*
|
||||
BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
|
||||
int alignment, const void* init_data,
|
||||
@@ -369,11 +366,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);
|
||||
@@ -412,6 +409,7 @@ BackendLLVM::getOrAllocateCUDAVariable(const Symbol& sym)
|
||||
return addCUDAGlobalVariable(name, sym.size(), alignment, sym.data(),
|
||||
sym.typespec().simpletype());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -429,6 +427,7 @@ BackendLLVM::llvm_get_pointer(const Symbol& sym, int deriv,
|
||||
llvm::Value* result = NULL;
|
||||
if (sym.symtype() == SymTypeConst) {
|
||||
TypeSpec elemtype = sym.typespec().elementtype();
|
||||
#ifdef 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
|
||||
@@ -439,7 +438,9 @@ 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 {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// For constants on the CPU side, start with *OUR* pointer to the
|
||||
// constant values.
|
||||
result = ll.constant_ptr(sym.data(),
|
||||
|
||||
@@ -216,6 +216,7 @@ public:
|
||||
/// map, the symbol is alloca'd and placed in the map.
|
||||
llvm::Value* getOrAllocateLLVMSymbol(const Symbol& sym);
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
/// 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.
|
||||
@@ -229,6 +230,7 @@ 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;
|
||||
@@ -266,14 +268,20 @@ 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`.
|
||||
@@ -299,7 +307,10 @@ 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*.
|
||||
///
|
||||
@@ -317,13 +328,22 @@ 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`
|
||||
@@ -378,12 +398,8 @@ public:
|
||||
|
||||
/// Execute the upstream connection (if any, and if not yet run) that
|
||||
/// establishes the value of symbol sym, which has index 'symindex'
|
||||
/// within the current layer rop.inst(). If already_run is not NULL,
|
||||
/// it points to a vector of layer indices that are known to have been
|
||||
/// run -- those can be skipped without dynamically checking their
|
||||
/// execution status.
|
||||
void llvm_run_connected_layers(Symbol& sym, int symindex, int opnum = -1,
|
||||
std::set<int>* already_run = NULL);
|
||||
/// within the current layer rop.inst().
|
||||
void llvm_run_connected_layers(Symbol& sym, int symindex, int opnum = -1);
|
||||
|
||||
/// Generate code for a call to the named function with the given
|
||||
/// arg list as symbols -- float & ints will be passed by value,
|
||||
@@ -444,7 +460,10 @@ 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.
|
||||
///
|
||||
@@ -465,7 +484,10 @@ 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)
|
||||
@@ -475,6 +497,11 @@ 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()
|
||||
{
|
||||
@@ -482,10 +509,16 @@ 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
|
||||
|
||||
@@ -2303,6 +2303,17 @@ 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);
|
||||
@@ -2395,6 +2406,7 @@ 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();
|
||||
|
||||
|
||||
@@ -477,13 +477,9 @@ public:
|
||||
|
||||
/// Execute the upstream connection (if any, and if not yet run) that
|
||||
/// establishes the value of symbol sym, which has index 'symindex'
|
||||
/// within the current layer rop.inst(). If already_run is not NULL,
|
||||
/// it points to a vector of layer indices that are known to have been
|
||||
/// run -- those can be skipped without dynamically checking their
|
||||
/// execution status.
|
||||
/// within the current layer rop.inst().
|
||||
void llvm_run_connected_layers(const Symbol& sym, int symindex,
|
||||
int opnum = -1,
|
||||
std::set<int>* already_run = NULL);
|
||||
int opnum = -1);
|
||||
|
||||
|
||||
|
||||
@@ -705,6 +701,8 @@ 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
|
||||
|
||||
@@ -149,14 +149,15 @@ 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++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BatchedBackendLLVM::llvm_run_connected_layers(const Symbol& sym, int symindex,
|
||||
int opnum,
|
||||
std::set<int>* already_run)
|
||||
int opnum)
|
||||
{
|
||||
if (sym.valuesource() != Symbol::ConnectedVal)
|
||||
return; // Nothing to do
|
||||
@@ -171,16 +172,6 @@ BatchedBackendLLVM::llvm_run_connected_layers(const Symbol& sym, int symindex,
|
||||
const Connection& con(inst()->connection(c));
|
||||
// If the connection gives a value to this param
|
||||
if (con.dst.param == symindex) {
|
||||
// already_run is a set of layers run for this particular op.
|
||||
// Just so we don't stupidly do several consecutive checks on
|
||||
// whether we ran this same layer. It's JUST for this op.
|
||||
if (already_run) {
|
||||
if (already_run->count(con.srclayer))
|
||||
continue; // already ran that one on this op
|
||||
else
|
||||
already_run->insert(con.srclayer); // mark it
|
||||
}
|
||||
|
||||
if (inmain) {
|
||||
// There is an instance-wide m_layers_already_run that tries
|
||||
// to remember which earlier layers have unconditionally
|
||||
@@ -199,6 +190,16 @@ BatchedBackendLLVM::llvm_run_connected_layers(const Symbol& sym, int symindex,
|
||||
}
|
||||
}
|
||||
|
||||
// m_call_layers_inserted tracks if we've already run this layer either:
|
||||
// * inside the current basic block (opnum >= 0)
|
||||
// * while writing output parameters (opnum == -1)
|
||||
const CallLayerKey key = { opnum >= 0 ? m_bblockids[opnum] : 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);
|
||||
@@ -223,15 +224,11 @@ LLVMGEN(llvm_gen_useparam)
|
||||
std::cout << ">>>>>>>>>>>>>>>>>>>>>llvm_gen_useparam <<<<<<<<<<<<<<<<<<<"
|
||||
<< std::endl);
|
||||
|
||||
// If we have multiple params needed on this statement, don't waste
|
||||
// time checking the same upstream layer more than once.
|
||||
std::set<int> already_run;
|
||||
|
||||
Opcode& op(rop.inst()->ops()[opnum]);
|
||||
for (int i = 0; i < op.nargs(); ++i) {
|
||||
Symbol& sym = *rop.opargsym(op, i);
|
||||
int symindex = rop.inst()->arg(op.firstarg() + i);
|
||||
rop.llvm_run_connected_layers(sym, symindex, opnum, &already_run);
|
||||
rop.llvm_run_connected_layers(sym, symindex, opnum);
|
||||
// If it's an interpolated (userdata) parameter and we're
|
||||
// initializing them lazily, now we have to do it.
|
||||
if ((sym.symtype() == SymTypeParam
|
||||
@@ -243,6 +240,9 @@ LLVMGEN(llvm_gen_useparam)
|
||||
rop.ll.current_mask()));
|
||||
}
|
||||
}
|
||||
|
||||
rop.increment_useparam_ops();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1263,6 +1263,7 @@ 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()) };
|
||||
@@ -1676,6 +1677,7 @@ 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
|
||||
@@ -1702,7 +1704,9 @@ LLVMGEN(llvm_gen_modulus)
|
||||
}
|
||||
|
||||
rop.ll.call_function(rop.build_name(func_spec), call_args);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
@@ -7064,7 +7068,8 @@ 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)
|
||||
ustring clname, llvm::Value* mem_void_ptr, int argsoffset,
|
||||
int lane_index)
|
||||
{
|
||||
OSL_DASSERT(((op.nargs() - argsoffset) % 2) == 0);
|
||||
|
||||
@@ -7088,10 +7093,45 @@ 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);
|
||||
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 */);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
@@ -7180,6 +7220,7 @@ 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
|
||||
@@ -7193,14 +7234,16 @@ 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).
|
||||
// not zero). We also need the surrounding "if" to reject writing
|
||||
// to closures that aren't masked.
|
||||
llvm::BasicBlock* next_block = NULL;
|
||||
llvm::BasicBlock* notnull_block = rop.ll.new_basic_block(
|
||||
"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());
|
||||
"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));
|
||||
rop.ll.op_branch(cond, notnull_block, next_block);
|
||||
|
||||
// If the closure has a "prepare" method, call
|
||||
@@ -7233,7 +7276,30 @@ LLVMGEN(llvm_gen_closure)
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
for (int a = 0; a < num_elements; ++a) {
|
||||
llvm::Value* arrind = simpletype.arraylen ? rop.ll.constant(a)
|
||||
@@ -7241,7 +7307,9 @@ 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_base, a, c);
|
||||
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);
|
||||
else
|
||||
dest_elem = dest_base;
|
||||
|
||||
@@ -7275,7 +7343,7 @@ LLVMGEN(llvm_gen_closure)
|
||||
}
|
||||
|
||||
llvm_gen_keyword_fill(rop, op, clentry, closure_name, mem_void_ptr,
|
||||
2 + weighted + clentry->nformal);
|
||||
2 + weighted + clentry->nformal, lane_index);
|
||||
|
||||
if (next_block)
|
||||
rop.ll.op_branch(next_block);
|
||||
|
||||
@@ -1813,6 +1813,7 @@ 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())
|
||||
@@ -2095,6 +2096,7 @@ 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());
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::get_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult,
|
||||
Wide<const ustring> wfrom,
|
||||
Wide<const ustringhash> 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,
|
||||
ustring to,
|
||||
ustringhash 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 ustring> wto,
|
||||
Wide<const ustringhash> 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,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
|
||||
ustringhash 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(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(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,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustringhash 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(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(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,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustring dataname, RefData val)
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustringhash 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(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->get_texture_info(texture_handle, NULL, subimage,
|
||||
dataname, val.type(),
|
||||
val.ptr());
|
||||
ustring_from(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(
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustringhash 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(
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustringhash 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(
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustringhash 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, ustring filename, const void* wcenter,
|
||||
BatchedShaderGlobals* bsg, ustringhash 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, ustring filename, Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points, ustring attr_name, MaskedData wout_data)
|
||||
BatchedShaderGlobals* bsg, ustringhash filename, Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points, ustringhash 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, ustring filename, Wide<const OSL::Vec3> wpos,
|
||||
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)
|
||||
{
|
||||
@@ -312,8 +312,9 @@ BatchedRendererServices<WidthT>::trace(
|
||||
template<int WidthT>
|
||||
void
|
||||
BatchedRendererServices<WidthT>::getmessage(BatchedShaderGlobals* bsg,
|
||||
Masked<int> wresult, ustring source,
|
||||
ustring name, MaskedData wval)
|
||||
Masked<int> wresult,
|
||||
ustringhash source,
|
||||
ustringhash name, MaskedData wval)
|
||||
{
|
||||
// Currently this code path should only be followed when source == "trace"
|
||||
OSL_DASSERT(wresult.mask() == wval.mask());
|
||||
|
||||
@@ -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, "iiiXXXiXiXX")
|
||||
DECL(osl_range_check, "iiisXsisiss")
|
||||
#endif
|
||||
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_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_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,7 +285,12 @@ 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")
|
||||
@@ -338,8 +343,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, "iX");
|
||||
DECL(osl_texture_decode_interpmode, "iX");
|
||||
DECL(osl_texture_decode_wrapmode, "is");
|
||||
DECL(osl_texture_decode_interpmode, "is");
|
||||
|
||||
DECL(osl_texture_set_firstchannel, "xXi")
|
||||
DECL(osl_texture_set_swrap, "xXs")
|
||||
|
||||
@@ -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), "xXXLXisii")
|
||||
DECL(__OSL_MASKED_OP2(setmessage, s, WX), "xXsLXisii")
|
||||
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), "iXX")
|
||||
DECL(__OSL_OP(raytype_name), "iXs")
|
||||
DECL(__OSL_MASKED_OP(raytype_name), "xXXXi")
|
||||
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_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_OP1(get_attribute, s), "iXiXXiiXXi")
|
||||
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXiXXiiXXi")
|
||||
DECL(__OSL_OP(get_attribute_uniform), "iXiXXiiXX")
|
||||
DECL(__OSL_OP1(get_attribute, s), "iXissiiXXi")
|
||||
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXisXiiXXi")
|
||||
DECL(__OSL_OP(get_attribute_uniform), "iXissiiXX")
|
||||
|
||||
// TODO: shouldn't bind_interpolated_param be MASKED? change name to reflect
|
||||
DECL(__OSL_OP(bind_interpolated_param), "iXXLiXiXiXii")
|
||||
DECL(__OSL_OP(bind_interpolated_param), "iXsLiXiXiXii")
|
||||
|
||||
//DECL (osl_get_texture_options, "XX") // unneeded
|
||||
DECL(__OSL_OP(get_noise_options), "XX")
|
||||
|
||||
@@ -2413,11 +2413,12 @@ DECLFOLDER(constfold_gettextureinfo)
|
||||
void* mydata = OSL_ALLOCA(char, t.size());
|
||||
// FIXME(ptex) -- exclude folding of ptex, since these things
|
||||
// can vary per face.
|
||||
ustring errormessage;
|
||||
ustringhash em;
|
||||
int result = rop.renderer()->get_texture_info(
|
||||
filename, nullptr, rop.shadingcontext()->texture_thread_info(),
|
||||
rop.shadingcontext(), 0 /* TODO: subimage? */, dataname, t, mydata,
|
||||
&errormessage);
|
||||
&em);
|
||||
ustring errormessage = ustring_from(em);
|
||||
// Now we turn
|
||||
// gettextureinfo result filename dataname data
|
||||
// into this for success:
|
||||
|
||||
@@ -625,8 +625,8 @@ ShadingContext::find_regex(ustring r)
|
||||
|
||||
bool
|
||||
ShadingContext::osl_get_attribute(ShaderGlobals* sg, void* objdata,
|
||||
int dest_derivs, ustring obj_name,
|
||||
ustring attr_name, int array_lookup,
|
||||
int dest_derivs, ustringhash obj_name,
|
||||
ustringhash attr_name, int array_lookup,
|
||||
int index, TypeDesc attr_type,
|
||||
void* attr_dest)
|
||||
{
|
||||
|
||||
@@ -244,22 +244,7 @@ ShaderInstance::parameters(const ParamValueList& params)
|
||||
valuetype = TypeDesc::FLOAT;
|
||||
}
|
||||
|
||||
// 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)))) {
|
||||
if (!relaxed_equivalent(sm_typespec, valuetype)) {
|
||||
// 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(
|
||||
@@ -668,10 +653,16 @@ 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())) {
|
||||
&& (memcmp(param_storage(i), b.param_storage(i),
|
||||
sym->typespec().simpletype().size())
|
||||
// || b_sym->interactive())
|
||||
|| !b_sym->lockgeom())
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -6,11 +6,6 @@
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
#include <OSL/genclosure.h>
|
||||
#include "backendllvm.h"
|
||||
@@ -147,13 +142,14 @@ 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++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum,
|
||||
std::set<int>* already_run)
|
||||
BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum)
|
||||
{
|
||||
if (sym.valuesource() != Symbol::ConnectedVal)
|
||||
return; // Nothing to do
|
||||
@@ -165,16 +161,6 @@ BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum,
|
||||
const Connection& con(inst()->connection(c));
|
||||
// If the connection gives a value to this param
|
||||
if (con.dst.param == symindex) {
|
||||
// already_run is a set of layers run for this particular op.
|
||||
// Just so we don't stupidly do several consecutive checks on
|
||||
// whether we ran this same layer. It's JUST for this op.
|
||||
if (already_run) {
|
||||
if (already_run->count(con.srclayer))
|
||||
continue; // already ran that one on this op
|
||||
else
|
||||
already_run->insert(con.srclayer); // mark it
|
||||
}
|
||||
|
||||
if (inmain) {
|
||||
// There is an instance-wide m_layers_already_run that tries
|
||||
// to remember which earlier layers have unconditionally
|
||||
@@ -193,6 +179,16 @@ BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum,
|
||||
}
|
||||
}
|
||||
|
||||
// m_call_layers_inserted tracks if we've already run this layer either:
|
||||
// * inside the current basic block (opnum >= 0)
|
||||
// * while writing output parameters (opnum == -1)
|
||||
const CallLayerKey key = { opnum >= 0 ? m_bblockids[opnum] : 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);
|
||||
@@ -219,15 +215,11 @@ LLVMGEN(llvm_gen_useparam)
|
||||
OSL_DASSERT(!rop.inst()->unused()
|
||||
&& "oops, thought this layer was unused, why do we call it?");
|
||||
|
||||
// If we have multiple params needed on this statement, don't waste
|
||||
// time checking the same upstream layer more than once.
|
||||
std::set<int> already_run;
|
||||
|
||||
Opcode& op(rop.inst()->ops()[opnum]);
|
||||
for (int i = 0; i < op.nargs(); ++i) {
|
||||
Symbol& sym = *rop.opargsym(op, i);
|
||||
int symindex = rop.inst()->arg(op.firstarg() + i);
|
||||
rop.llvm_run_connected_layers(sym, symindex, opnum, &already_run);
|
||||
rop.llvm_run_connected_layers(sym, symindex, opnum);
|
||||
// If it's an interpolated (userdata) parameter and we're
|
||||
// initializing them lazily, now we have to do it.
|
||||
if ((sym.symtype() == SymTypeParam
|
||||
@@ -238,6 +230,9 @@ LLVMGEN(llvm_gen_useparam)
|
||||
rop.llvm_assign_initial_value(sym);
|
||||
}
|
||||
}
|
||||
|
||||
rop.increment_useparam_ops();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -374,6 +369,7 @@ LLVMGEN(llvm_gen_printf)
|
||||
}
|
||||
|
||||
|
||||
#ifdef 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.
|
||||
@@ -382,6 +378,7 @@ 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) {
|
||||
@@ -390,9 +387,8 @@ LLVMGEN(llvm_gen_printf)
|
||||
}
|
||||
|
||||
// Now go back and put the new format string in its place
|
||||
if (!rop.use_optix()) {
|
||||
call_args[new_format_slot] = rop.llvm_load_string(s);
|
||||
} else {
|
||||
#ifdef OSL_USE_OPTIX
|
||||
if (rop.use_optix()) {
|
||||
// In OptiX7+ case, we do this:
|
||||
// void* args = { args_size, arg0, arg1, arg2 };
|
||||
// (where args_size is the size of arg0 + arg1 + arg2...)
|
||||
@@ -450,6 +446,10 @@ 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.
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
#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"
|
||||
@@ -283,14 +279,10 @@ BackendLLVM::llvm_type_groupdata()
|
||||
++order;
|
||||
for (int i = 0; i < nuserdata; ++i) {
|
||||
TypeDesc type = types[i];
|
||||
// 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;
|
||||
// make room for float derivs only
|
||||
type.arraylen = type.basetype == TypeDesc::FLOAT
|
||||
? type.numelements() * 3
|
||||
: type.numelements();
|
||||
fields.push_back(llvm_type(type));
|
||||
m_groupdata_field_names.emplace_back(
|
||||
fmtformat("userdata{}_{}_", i, names[i]));
|
||||
@@ -560,6 +552,7 @@ 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());
|
||||
#ifdef 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.
|
||||
@@ -570,6 +563,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());
|
||||
#endif
|
||||
} else if (!sym.lockgeom() && !sym.typespec().is_closure()) {
|
||||
// geometrically-varying param; memcpy its default value
|
||||
TypeDesc t = sym.typespec().simpletype();
|
||||
@@ -1104,6 +1098,7 @@ 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());
|
||||
|
||||
@@ -1305,10 +1300,12 @@ BackendLLVM::initialize_llvm_group()
|
||||
}
|
||||
types += advance;
|
||||
}
|
||||
#ifdef 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);
|
||||
@@ -1364,6 +1361,19 @@ BackendLLVM::run()
|
||||
#ifdef OSL_LLVM_NO_BITCODE
|
||||
OSL_ASSERT(!use_rs_bitcode());
|
||||
ll.module(ll.new_module("llvm_ops"));
|
||||
# ifdef 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()) {
|
||||
@@ -1605,13 +1615,16 @@ BackendLLVM::run()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef 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 {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Force the JIT to happen now and retrieve the JITed function pointers
|
||||
// for the initialization and all public entry points.
|
||||
group().llvm_compiled_init(
|
||||
|
||||
+26
-17
@@ -27,9 +27,8 @@ 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
|
||||
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&,
|
||||
ustringrep. See the handy USTR, MAT, VEC, DFLOAT, DVEC macros for
|
||||
handy/cheap casting of those void*'s to references to ustringrep&,
|
||||
Matrix44&, Vec3&, Dual2<float>&, and Dual2<Vec3>, respectively.
|
||||
|
||||
* You must provide all allowable polymorphic and derivative combinations!
|
||||
@@ -101,13 +100,23 @@ void* __dso_handle = 0; // necessary to avoid linkage issues in bitcode
|
||||
|
||||
|
||||
// Handy re-casting macros
|
||||
#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)
|
||||
#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
|
||||
|
||||
|
||||
#ifndef OSL_SHADEOP
|
||||
# ifdef __CUDACC__
|
||||
@@ -975,17 +984,17 @@ osl_raytype_bit(void* sg_, int bit)
|
||||
|
||||
// extern declaration
|
||||
OSL_SHADEOP_NOINLINE int
|
||||
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_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_SHADEOP int
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
|
||||
|
||||
@@ -92,10 +92,6 @@
|
||||
#include <llvm/Transforms/Utils/Cloning.h>
|
||||
#include <llvm/Transforms/Utils/SymbolRewriter.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
|
||||
@@ -1589,29 +1585,26 @@ LLVM_Util::make_jit_execengine(std::string* err, TargetISA requestedISA,
|
||||
|
||||
|
||||
|
||||
namespace /*anonymous*/ {
|
||||
#ifdef OSL_DEV
|
||||
// The return value of llvm::StructLayout::getAlignment()
|
||||
// changed from an int to llvm::Align, hide with accessor function
|
||||
#if OSL_LLVM_VERSION < 100
|
||||
uint64_t
|
||||
inline uint64_t
|
||||
get_alignment(const llvm::StructLayout* layout)
|
||||
{
|
||||
# if OSL_LLVM_VERSION < 100
|
||||
return layout->getAlignment();
|
||||
}
|
||||
#else
|
||||
uint64_t
|
||||
get_alignment(const llvm::StructLayout* layout)
|
||||
{
|
||||
# else
|
||||
return layout->getAlignment().value();
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
|
||||
|
||||
void
|
||||
LLVM_Util::dump_struct_data_layout(llvm::Type* Ty)
|
||||
LLVM_Util::dump_struct_data_layout(llvm::Type* Ty OSL_MAYBE_UNUSED)
|
||||
{
|
||||
#ifdef OSL_DEV
|
||||
OSL_ASSERT(Ty);
|
||||
OSL_ASSERT(Ty->isStructTy());
|
||||
|
||||
@@ -1635,6 +1628,7 @@ LLVM_Util::dump_struct_data_layout(llvm::Type* Ty)
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2449,25 +2443,6 @@ LLVM_Util::internalize_module_functions(
|
||||
|
||||
|
||||
|
||||
llvm::Function*
|
||||
LLVM_Util::make_function(const std::string& name, bool fastcall,
|
||||
llvm::Type* rettype, llvm::Type* arg1,
|
||||
llvm::Type* arg2, llvm::Type* arg3, llvm::Type* arg4)
|
||||
{
|
||||
std::vector<llvm::Type*> argtypes;
|
||||
if (arg1)
|
||||
argtypes.emplace_back(arg1);
|
||||
if (arg2)
|
||||
argtypes.emplace_back(arg2);
|
||||
if (arg3)
|
||||
argtypes.emplace_back(arg3);
|
||||
if (arg4)
|
||||
argtypes.emplace_back(arg4);
|
||||
return make_function(name, fastcall, rettype, argtypes, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
llvm::Function*
|
||||
LLVM_Util::make_function(const std::string& name, bool fastcall,
|
||||
llvm::Type* rettype, cspan<llvm::Type*> params,
|
||||
@@ -2476,6 +2451,11 @@ 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());
|
||||
@@ -2694,7 +2674,18 @@ 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,
|
||||
@@ -2871,15 +2862,21 @@ 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.
|
||||
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");
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3612,9 +3609,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() << nargs << " args:\n";
|
||||
for (int i = 0, nargs = args.size(); i < nargs; ++i)
|
||||
llvm::outs() << "\t" << *(args[i]) << "\n";
|
||||
llvm::outs() << args.size() << " args:\n";
|
||||
for (auto a : args)
|
||||
llvm::outs() << "\t" << *a << "\n";
|
||||
#endif
|
||||
//llvm_gen_debug_printf (std::string("start ") + std::string(name));
|
||||
#if OSL_LLVM_VERSION >= 110
|
||||
@@ -5831,6 +5828,7 @@ bool
|
||||
LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
|
||||
std::string& out)
|
||||
{
|
||||
#ifdef OSL_USE_OPTIX
|
||||
std::string target_triple = module()->getTargetTriple();
|
||||
|
||||
OSL_ASSERT(
|
||||
@@ -5874,9 +5872,9 @@ LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
|
||||
options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
|
||||
options.NoZerosInBSS = 0;
|
||||
options.GuaranteedTailCallOpt = 0;
|
||||
#if OSL_LLVM_VERSION < 120
|
||||
# if OSL_LLVM_VERSION < 120
|
||||
options.StackAlignmentOverride = 0;
|
||||
#endif
|
||||
# endif
|
||||
options.UseInitArray = 0;
|
||||
|
||||
llvm::TargetMachine* target_machine = llvm_target->createTargetMachine(
|
||||
@@ -5908,15 +5906,15 @@ LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
|
||||
llvm::raw_svector_ostream assembly_stream(assembly);
|
||||
|
||||
// TODO: Make sure rounding modes, etc., are set correctly
|
||||
#if OSL_LLVM_VERSION >= 100
|
||||
# if OSL_LLVM_VERSION >= 100
|
||||
target_machine->addPassesToEmitFile(mod_pm, assembly_stream,
|
||||
nullptr, // FIXME: Correct?
|
||||
llvm::CGFT_AssemblyFile);
|
||||
#else
|
||||
# else
|
||||
target_machine->addPassesToEmitFile(mod_pm, assembly_stream,
|
||||
nullptr, // FIXME: Correct?
|
||||
llvm::TargetMachine::CGFT_AssemblyFile);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// Run the optimization passes on the functions
|
||||
fn_pm.doInitialization();
|
||||
@@ -5942,6 +5940,9 @@ LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
|
||||
delete linked_module;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#ifdef __CUDACC__
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "opcolor.h"
|
||||
|
||||
#include "opcolor_impl.h"
|
||||
@@ -39,7 +35,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 static ColorSystem::Chroma k_color_systems[13] = {
|
||||
OSL_CONSTANT_DATA const 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 },
|
||||
|
||||
@@ -50,8 +50,13 @@ 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
|
||||
static OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) = {
|
||||
// clang-format off
|
||||
// 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
|
||||
{
|
||||
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,
|
||||
@@ -79,8 +84,8 @@ static 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
|
||||
|
||||
|
||||
|
||||
@@ -27,33 +27,34 @@ namespace pvt {
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_setmessage(ShaderGlobals* sg, const char* name_, long long type_, void* val,
|
||||
int layeridx, const char* sourcefile_, int sourceline)
|
||||
osl_setmessage(ShaderGlobals* sg, ustring_pod name_, long long type_, void* val,
|
||||
int layeridx, ustring_pod sourcefile_, int sourceline)
|
||||
{
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
ustringhash name = ustringhash_from(USTR(name_));
|
||||
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
|
||||
// recreate TypeDesc -- we just crammed it into an int!
|
||||
TypeDesc type = TYPEDESC(type_);
|
||||
bool is_closure = (type.basetype
|
||||
== TypeDesc::UNKNOWN); // secret code for closure
|
||||
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates 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 != NULL) {
|
||||
if (m) {
|
||||
if (m->name == name) {
|
||||
// message already exists?
|
||||
if (m->has_data())
|
||||
sg->context->errorfmt(
|
||||
"message \"{}\" already exists (created here: {}:{})"
|
||||
" cannot set again from {}:{}",
|
||||
name, m->sourcefile, m->sourceline, sourcefile, sourceline);
|
||||
name.c_str(), m->sourcefile.c_str(), m->sourceline,
|
||||
sourcefile.c_str(), 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, m->sourcefile, m->sourceline, sourcefile, sourceline);
|
||||
name.c_str(), m->sourcefile.c_str(), m->sourceline,
|
||||
sourcefile.c_str(), sourceline);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -64,22 +65,21 @@ osl_setmessage(ShaderGlobals* sg, const char* name_, long long type_, void* val,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_getmessage(ShaderGlobals* sg, const char* source_, const char* name_,
|
||||
osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
|
||||
long long type_, void* val, int derivs, int layeridx,
|
||||
const char* sourcefile_, int sourceline)
|
||||
ustring_pod sourcefile_, int sourceline)
|
||||
{
|
||||
const ustring& source(USTR(source_));
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
ustringhash source = ustringhash_from(USTR(source_));
|
||||
ustringhash name = ustringhash_from(USTR(name_));
|
||||
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
|
||||
|
||||
// recreate TypeDesc -- we just crammed it into an int!
|
||||
TypeDesc type = TYPEDESC(type_);
|
||||
bool is_closure = (type.basetype
|
||||
== TypeDesc::UNKNOWN); // secret code for closure
|
||||
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates closure
|
||||
if (is_closure)
|
||||
type.basetype = TypeDesc::PTR; // for closures, we store a pointer
|
||||
|
||||
static ustring ktrace("trace");
|
||||
static ustringrep 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, const char* source_, const char* name_,
|
||||
|
||||
MessageList& messages(sg->context->messages());
|
||||
const Message* m = messages.find(name);
|
||||
if (m != NULL) {
|
||||
if (m) {
|
||||
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, m->has_data() ? "created" : "queried",
|
||||
name.c_str(), m->has_data() ? "created" : "queried",
|
||||
m->type == TypeDesc::PTR ? "closure color"
|
||||
: m->type.c_str(),
|
||||
m->sourcefile, m->sourceline,
|
||||
is_closure ? "closure color" : type.c_str(), sourcefile,
|
||||
sourceline);
|
||||
m->sourcefile.c_str(), m->sourceline,
|
||||
is_closure ? "closure color" : type.c_str(),
|
||||
sourcefile.c_str(), sourceline);
|
||||
return 0;
|
||||
}
|
||||
if (!m->has_data()) {
|
||||
@@ -113,8 +113,8 @@ osl_getmessage(ShaderGlobals* sg, const char* source_, const char* name_,
|
||||
" but is being queried by layer #{} ({}:{})"
|
||||
" - messages may only be transferred from nodes "
|
||||
"that appear earlier in the shading network",
|
||||
name, m->layeridx, m->sourcefile, m->sourceline, layeridx,
|
||||
sourcefile, sourceline);
|
||||
name.c_str(), m->layeridx, m->sourcefile.c_str(),
|
||||
m->sourceline, layeridx, sourcefile.c_str(), sourceline);
|
||||
return 0;
|
||||
}
|
||||
// Message found!
|
||||
@@ -127,7 +127,7 @@ osl_getmessage(ShaderGlobals* sg, const char* source_, const char* 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, NULL, type, layeridx, sourcefile, sourceline);
|
||||
messages.add(name, nullptr, type, layeridx, sourcefile, sourceline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,32 +43,31 @@ osl_texture_set_firstchannel(void* opt, int x)
|
||||
}
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_texture_decode_wrapmode(void* name)
|
||||
osl_texture_decode_wrapmode(ustring_pod name)
|
||||
{
|
||||
const ustring& uname = USTR(name);
|
||||
return OIIO::TextureOpt::decode_wrapmode(uname);
|
||||
return OIIO::TextureOpt::decode_wrapmode(ustring_from(USTR(name)));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_swrap(void* opt, const char* x)
|
||||
osl_texture_set_swrap(void* opt, ustring_pod x)
|
||||
{
|
||||
((TextureOpt*)opt)->swrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_twrap(void* opt, const char* x)
|
||||
osl_texture_set_twrap(void* opt, ustring_pod x)
|
||||
{
|
||||
((TextureOpt*)opt)->twrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_rwrap(void* opt, const char* x)
|
||||
osl_texture_set_rwrap(void* opt, ustring_pod x)
|
||||
{
|
||||
((TextureOpt*)opt)->rwrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_stwrap(void* opt, const char* x)
|
||||
osl_texture_set_stwrap(void* opt, ustring_pod x)
|
||||
{
|
||||
TextureOpt::Wrap code = TextureOpt::decode_wrapmode(USTR(x));
|
||||
((TextureOpt*)opt)->swrap = code;
|
||||
@@ -163,16 +162,15 @@ osl_texture_set_time(void* opt, float x)
|
||||
}
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_texture_decode_interpmode(void* name)
|
||||
osl_texture_decode_interpmode(ustring_pod name)
|
||||
{
|
||||
const ustring& uname = USTR(name);
|
||||
return tex_interp_to_code(uname);
|
||||
return tex_interp_to_code(ustring_from(USTR(name)));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_interp(void* opt, const char* modename)
|
||||
osl_texture_set_interp(void* opt, ustring_pod modename)
|
||||
{
|
||||
int mode = tex_interp_to_code(USTR(modename));
|
||||
int mode = tex_interp_to_code(ustring_from(USTR(modename)));
|
||||
if (mode >= 0)
|
||||
((TextureOpt*)opt)->interpmode = (TextureOpt::InterpMode)mode;
|
||||
}
|
||||
@@ -191,9 +189,9 @@ osl_texture_set_subimage(void* opt, int subimage)
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_subimagename(void* opt, const char* subimagename)
|
||||
osl_texture_set_subimagename(void* opt, ustring_pod subimagename)
|
||||
{
|
||||
((TextureOpt*)opt)->subimagename = USTR(subimagename);
|
||||
((TextureOpt*)opt)->subimagename = ustring_from(USTR(subimagename));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
@@ -217,7 +215,7 @@ 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, ustring* errormessage)
|
||||
void* dalphadx, void* dalphady, ustringrep* errormessage)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
TextureOpt* opt = (TextureOpt*)opt_;
|
||||
@@ -225,11 +223,12 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
// 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::float4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->texture(
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
USTR(name).uhash(), (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);
|
||||
derivs ? (float*)&dresultdt_simd : NULL, errormessage ? &em : nullptr);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = result_simd[i];
|
||||
@@ -256,8 +255,9 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
}
|
||||
}
|
||||
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
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, ustring* errormessage)
|
||||
void* dalphady, ustringrep* errormessage)
|
||||
{
|
||||
const Vec3& P(*(Vec3*)P_);
|
||||
const Vec3& dPdx(*(Vec3*)dPdx_);
|
||||
@@ -283,12 +283,14 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
// and ensure that they're being put in aligned memory.
|
||||
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
dresultdr_simd;
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->texture3d(
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
USTR(name).uhash(), (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);
|
||||
derivs ? (float*)&dresultdr_simd : nullptr,
|
||||
errormessage ? &em : nullptr);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = result_simd[i];
|
||||
@@ -315,8 +317,9 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
}
|
||||
}
|
||||
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -326,7 +329,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, ustring* errormessage)
|
||||
void* dalphady, ustringrep* errormessage)
|
||||
{
|
||||
const Vec3& R(*(Vec3*)R_);
|
||||
const Vec3& dRdx(*(Vec3*)dRdx_);
|
||||
@@ -336,12 +339,13 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
// 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::float4 local_result;
|
||||
bool ok = sg->renderer->environment(USTR(name),
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->environment(USTR(name).uhash(),
|
||||
(TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(),
|
||||
*opt, sg, R, dRdx, dRdy, 4,
|
||||
(float*)&local_result, NULL, NULL,
|
||||
errormessage);
|
||||
errormessage ? &em : nullptr);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = local_result[i];
|
||||
@@ -368,8 +372,9 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
((float*)dalphady)[0] = 0.0f;
|
||||
}
|
||||
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -378,7 +383,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,
|
||||
ustring* errormessage)
|
||||
ustringrep* errormessage)
|
||||
{
|
||||
// recreate TypeDesc
|
||||
TypeDesc typedesc;
|
||||
@@ -388,10 +393,15 @@ osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
|
||||
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
|
||||
return sg->renderer->get_texture_info(
|
||||
USTR(name), (RendererServices::TextureHandle*)handle,
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->get_texture_info(
|
||||
USTR(name).uhash(), (RendererServices::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
|
||||
USTR(dataname), typedesc, data, errormessage);
|
||||
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -399,7 +409,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, ustring* errormessage)
|
||||
int aggregate, void* data, ustringrep* errormessage)
|
||||
{
|
||||
// recreate TypeDesc
|
||||
TypeDesc typedesc;
|
||||
@@ -409,10 +419,15 @@ osl_get_textureinfo_st(void* sg_, const char* name, void* handle, float s,
|
||||
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
|
||||
return sg->renderer->get_texture_info(
|
||||
USTR(name), (RendererServices::TextureHandle*)handle, s, t,
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->get_texture_info(
|
||||
USTR(name).uhash(), (RendererServices::TextureHandle*)handle, s, t,
|
||||
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
|
||||
USTR(dataname), typedesc, data, errormessage);
|
||||
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
// Pull in the modified Imath headers and the OSL_HOSTDEVICE macro
|
||||
#ifdef __CUDACC__
|
||||
# include <OSL/oslconfig.h>
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CUDACC__
|
||||
@@ -234,18 +233,33 @@ struct AttributeNeeded {
|
||||
|
||||
|
||||
// Handy re-casting macros
|
||||
#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
|
||||
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)
|
||||
|
||||
|
||||
|
||||
/// Like an int (of type T), but also internally keeps track of the
|
||||
@@ -895,7 +909,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
|
||||
bool m_compile_report; ///< Print compilation report?
|
||||
int 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
|
||||
@@ -941,6 +955,8 @@ 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
|
||||
@@ -1533,8 +1549,8 @@ private:
|
||||
/// Represents a single message for use by getmessage and setmessage opcodes
|
||||
///
|
||||
struct Message {
|
||||
Message(ustring name, const TypeDesc& type, int layeridx,
|
||||
ustring sourcefile, int sourceline, Message* next)
|
||||
Message(ustringhash name, const TypeDesc& type, int layeridx,
|
||||
ustringhash sourcefile, int sourceline, Message* next)
|
||||
: name(name)
|
||||
, data(nullptr)
|
||||
, type(type)
|
||||
@@ -1545,43 +1561,42 @@ 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; }
|
||||
|
||||
ustring name; ///< name of this message
|
||||
ustringhash 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? 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
|
||||
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
|
||||
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 = NULL;
|
||||
list_head = nullptr;
|
||||
message_data.clear();
|
||||
}
|
||||
|
||||
const Message* find(ustring name) const
|
||||
const Message* find(ustringhash name) const
|
||||
{
|
||||
for (const Message* m = list_head; m != NULL; m = m->next)
|
||||
for (const Message* m = list_head; m; m = m->next)
|
||||
if (m->name == name)
|
||||
return m; // name matches
|
||||
return nullptr; // not found
|
||||
}
|
||||
|
||||
void add(ustring name, void* data, const TypeDesc& type, int layeridx,
|
||||
ustring sourcefile, int sourceline)
|
||||
void add(ustringhash name, void* data, const TypeDesc& type, int layeridx,
|
||||
ustringhash sourcefile, int sourceline)
|
||||
{
|
||||
list_head = new (message_data.alloc(sizeof(Message), alignof(Message)))
|
||||
Message(name, type, layeridx, sourcefile, sourceline, list_head);
|
||||
@@ -2210,7 +2225,7 @@ public:
|
||||
int dict_value(int nodeID, ustring attribname, TypeDesc type, void* data);
|
||||
|
||||
bool osl_get_attribute(ShaderGlobals* sg, void* objdata, int dest_derivs,
|
||||
ustring obj_name, ustring attr_name,
|
||||
ustringhash obj_name, ustringhash attr_name,
|
||||
int array_lookup, int index, TypeDesc attr_type,
|
||||
void* attr_dest);
|
||||
|
||||
@@ -2593,6 +2608,19 @@ 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
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#pragma clang diagnostic ignored "-Wparentheses-equality"
|
||||
#endif
|
||||
|
||||
#if OSL_CLANG_VERSION >= 150000
|
||||
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
|
||||
+2
-21
@@ -288,7 +288,8 @@ public:
|
||||
}
|
||||
|
||||
// TODO: This is really the only part of parsing that needs the lock still.
|
||||
// But the calling code setting locale complicates this.
|
||||
// The calling code no longer sets the global locale, so it would
|
||||
// likely be simple to clean this up.
|
||||
//
|
||||
bool parse(OSOReader* reader, const char* what) {
|
||||
yy_switch_to_buffer(m_buffer, m_scanner);
|
||||
@@ -310,12 +311,6 @@ 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);
|
||||
@@ -326,7 +321,6 @@ 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;
|
||||
}
|
||||
@@ -339,22 +333,9 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,25 +12,26 @@ OSL_NAMESPACE_ENTER
|
||||
namespace pvt {
|
||||
|
||||
#ifdef USE_PARTIO
|
||||
typedef std::unordered_map<ustring, std::unique_ptr<PointCloud>> PointCloudMap;
|
||||
using PointCloudMap
|
||||
= std::unordered_map<ustringhash, std::unique_ptr<PointCloud>>;
|
||||
static PointCloudMap pointclouds;
|
||||
static OIIO::spin_mutex pointcloudmap_mutex;
|
||||
|
||||
PointCloud*
|
||||
PointCloud::get(ustring filename, bool write)
|
||||
PointCloud::get(ustringhash filename, bool write)
|
||||
{
|
||||
if (filename.empty())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
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 = NULL;
|
||||
Partio::ParticlesDataMutable* partio_cloud = nullptr;
|
||||
if (!write) {
|
||||
partio_cloud = Partio::read(filename.c_str(), false);
|
||||
if (!partio_cloud)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
} else {
|
||||
partio_cloud = Partio::create();
|
||||
}
|
||||
@@ -40,7 +41,7 @@ PointCloud::get(ustring filename, bool write)
|
||||
}
|
||||
|
||||
|
||||
PointCloud::PointCloud(ustring filename,
|
||||
PointCloud::PointCloud(ustringhash filename,
|
||||
Partio::ParticlesDataMutable* partio_cloud, bool write)
|
||||
: m_filename(filename), m_partio_cloud(partio_cloud), m_write(write)
|
||||
{
|
||||
@@ -76,8 +77,10 @@ PointCloud::~PointCloud()
|
||||
|
||||
} // namespace pvt
|
||||
|
||||
|
||||
|
||||
int
|
||||
RendererServices::pointcloud_search(ShaderGlobals* sg, ustring filename,
|
||||
RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
|
||||
const Vec3& center, float radius,
|
||||
int max_points, bool sort,
|
||||
size_t* out_indices, float* out_distances,
|
||||
@@ -86,17 +89,17 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustring filename,
|
||||
#ifdef USE_PARTIO
|
||||
if (filename.empty())
|
||||
return 0;
|
||||
PointCloud* pc = PointCloud::get(filename);
|
||||
PointCloud* pc = PointCloud::get(ustring_from(filename));
|
||||
if (pc == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_search: could not open \"{}\"",
|
||||
filename);
|
||||
ustring_from(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 \"{}\"",
|
||||
filename);
|
||||
ustring_from(filename));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -192,25 +195,26 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustring filename,
|
||||
|
||||
|
||||
int
|
||||
RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
size_t* indices, int count, ustring attr_name,
|
||||
TypeDesc attr_type, void* out_data)
|
||||
RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
size_t* indices, int count,
|
||||
ustringhash 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(filename);
|
||||
PointCloud* pc = PointCloud::get(ustring_from(filename));
|
||||
if (pc == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_get: could not open \"{}\"",
|
||||
filename);
|
||||
ustring_from(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 \"{}\"",
|
||||
filename);
|
||||
ustring_from(filename));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -219,7 +223,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
if (!attr) {
|
||||
sg->context->errorfmt(
|
||||
"Accessing unexisting attribute {} in pointcloud \"{}\"", attr_name,
|
||||
filename);
|
||||
ustring_from(filename));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -232,7 +236,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustring 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, filename);
|
||||
attr_name, partio_type, element_type, ustring_from(filename));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -263,9 +267,9 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int ind = strindices[i];
|
||||
if (ind >= 0 && ind < sicount)
|
||||
((ustring*)out_data)[i] = ustring(strings[ind]);
|
||||
((ustringrep*)out_data)[i] = ustringrep(strings[ind]);
|
||||
else
|
||||
((ustring*)out_data)[i] = ustring();
|
||||
((ustringrep*)out_data)[i] = ustringrep();
|
||||
}
|
||||
} else {
|
||||
// All cases aside from strings are simple.
|
||||
@@ -286,15 +290,16 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustring filename,
|
||||
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
|
||||
const Vec3& pos, int nattribs,
|
||||
const ustring* names, const TypeDesc* types,
|
||||
const void** data)
|
||||
const ustringrep* names,
|
||||
const TypeDesc* types, const void** data)
|
||||
{
|
||||
#ifdef USE_PARTIO
|
||||
if (filename.empty())
|
||||
return false;
|
||||
PointCloud* pc = PointCloud::get(filename, true /* create file to write */);
|
||||
PointCloud* pc = PointCloud::get(ustring_from(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
|
||||
@@ -346,10 +351,11 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustring filename,
|
||||
*(int*)cloud->dataWrite<int>(*a, p) = *(int*)(data[i]);
|
||||
break;
|
||||
case Partio::INDEXEDSTR: {
|
||||
const char* s = *(const char**)(data[i]);
|
||||
int index = cloud->lookupIndexedStr(*a, s);
|
||||
ustringrep s = *(ustringrep*)(data[i]);
|
||||
const char* sstr = s.c_str();
|
||||
int index = cloud->lookupIndexedStr(*a, sstr);
|
||||
if (index == -1)
|
||||
index = cloud->registerIndexedStr(*a, s);
|
||||
index = cloud->registerIndexedStr(*a, sstr);
|
||||
*(int*)cloud->dataWrite<int>(*a, p) = index;
|
||||
} break;
|
||||
case Partio::NONE: break;
|
||||
@@ -366,7 +372,7 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustring filename,
|
||||
namespace pvt {
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
|
||||
osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
|
||||
float radius, int max_points, int sort, void* out_indices,
|
||||
void* out_distances, int derivs_offset, int nattrs, ...)
|
||||
{
|
||||
@@ -393,11 +399,11 @@ osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
|
||||
va_list args;
|
||||
va_start(args, nattrs);
|
||||
for (int i = 0; i < nattrs; i++) {
|
||||
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*);
|
||||
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*);
|
||||
sg->renderer->pointcloud_get(sg, USTR(filename), indices, count,
|
||||
attr_name, attr_type, out_data);
|
||||
}
|
||||
@@ -416,8 +422,8 @@ osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_get(ShaderGlobals* sg, const char* filename, void* in_indices,
|
||||
int count, const char* attr_name, long long attr_type,
|
||||
osl_pointcloud_get(ShaderGlobals* sg, ustring_pod filename, void* in_indices,
|
||||
int count, ustring_pod attr_name, long long attr_type,
|
||||
void* out_data)
|
||||
{
|
||||
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
|
||||
@@ -438,8 +444,8 @@ osl_pointcloud_get(ShaderGlobals* sg, const char* filename, void* in_indices,
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_pointcloud_write_helper(ustring* names, TypeDesc* types, void** values,
|
||||
int index, const char* name, long long type,
|
||||
osl_pointcloud_write_helper(ustringrep* names, TypeDesc* types, void** values,
|
||||
int index, ustring_pod name, long long type,
|
||||
void* val)
|
||||
{
|
||||
names[index] = USTR(name);
|
||||
@@ -450,9 +456,9 @@ osl_pointcloud_write_helper(ustring* names, TypeDesc* types, void** values,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_write(ShaderGlobals* sg, const char* filename, const Vec3* pos,
|
||||
int nattribs, const ustring* names, const TypeDesc* types,
|
||||
const void** values)
|
||||
osl_pointcloud_write(ShaderGlobals* sg, ustring_pod filename, const Vec3* pos,
|
||||
int nattribs, const ustringrep* names,
|
||||
const TypeDesc* types, const void** values)
|
||||
{
|
||||
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
|
||||
if (shadingsys.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace pvt {
|
||||
|
||||
class PointCloud {
|
||||
public:
|
||||
PointCloud(ustring filename, Partio::ParticlesDataMutable* partio_cloud,
|
||||
PointCloud(ustringhash filename, Partio::ParticlesDataMutable* partio_cloud,
|
||||
bool write);
|
||||
~PointCloud();
|
||||
static PointCloud* get(ustring filename, bool write = false);
|
||||
static PointCloud* get(ustringhash filename, bool write = false);
|
||||
|
||||
typedef std::unordered_map<ustring,
|
||||
typedef std::unordered_map<ustringhash,
|
||||
std::unique_ptr<Partio::ParticleAttribute>>
|
||||
AttributeMap;
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
return m_partio_cloud;
|
||||
}
|
||||
|
||||
ustring m_filename;
|
||||
ustringhash m_filename;
|
||||
|
||||
private:
|
||||
// hide just this field, because we want to control how it is accessed
|
||||
|
||||
+116
-31
@@ -47,6 +47,24 @@ 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)
|
||||
@@ -73,8 +91,9 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
bool
|
||||
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustring to, float time)
|
||||
ustringhash 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();
|
||||
@@ -85,8 +104,9 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
bool
|
||||
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustring to)
|
||||
ustringhash to)
|
||||
{
|
||||
// return get_inverse_matrix(sg, result, ustring_from(to));
|
||||
bool ok = get_matrix(sg, result, to);
|
||||
if (ok)
|
||||
result.invert();
|
||||
@@ -95,10 +115,52 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
|
||||
|
||||
RendererServices::TextureHandle*
|
||||
RendererServices::get_texture_handle(ustring filename, ShadingContext* context)
|
||||
bool
|
||||
RendererServices::transform_points(ShaderGlobals* sg, ustringhash from,
|
||||
ustringhash to, float time, const Vec3* Pin,
|
||||
Vec3* Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype)
|
||||
{
|
||||
return texturesys()->get_texture_handle(filename,
|
||||
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)
|
||||
{
|
||||
return texturesys()->get_texture_handle(ustring_from(filename),
|
||||
context->texture_thread_info());
|
||||
}
|
||||
|
||||
@@ -120,19 +182,19 @@ RendererServices::is_udim(TextureHandle* texture_handle)
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::texture(ustring filename, TextureHandle* texture_handle,
|
||||
RendererServices::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,
|
||||
ustring* errormessage)
|
||||
ustringhash* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->texture(texture_handle, texture_thread_info,
|
||||
options, s, t, dsdx, dtdx, dsdy, dtdy,
|
||||
@@ -142,12 +204,12 @@ RendererServices::texture(ustring filename, TextureHandle* texture_handle,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustring(err);
|
||||
*errormessage = ustringhash(err);
|
||||
} else {
|
||||
context->errorfmt("[RendererServices::texture] {}", err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = Strings::unknown;
|
||||
*errormessage = ustringhash(Strings::unknown);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -156,19 +218,19 @@ RendererServices::texture(ustring filename, TextureHandle* texture_handle,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::texture3d(ustring filename, TextureHandle* texture_handle,
|
||||
RendererServices::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, ustring* errormessage)
|
||||
float* dresultdr, ustringhash* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
|
||||
bool status = texturesys()->texture3d(texture_handle, texture_thread_info,
|
||||
@@ -179,12 +241,12 @@ RendererServices::texture3d(ustring filename, TextureHandle* texture_handle,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustring(err);
|
||||
*errormessage = ustringhash(err);
|
||||
} else {
|
||||
sg->context->errorfmt("[RendererServices::texture3d] {}", err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = Strings::unknown;
|
||||
*errormessage = Strings::unknown.uhash();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -193,18 +255,19 @@ RendererServices::texture3d(ustring filename, TextureHandle* texture_handle,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::environment(ustring filename, TextureHandle* texture_handle,
|
||||
RendererServices::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, ustring* errormessage)
|
||||
float* dresultdt, ustringhash* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->environment(texture_handle, texture_thread_info,
|
||||
options, R, dRdx, dRdy, nchannels,
|
||||
@@ -213,13 +276,13 @@ RendererServices::environment(ustring filename, TextureHandle* texture_handle,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustring(err);
|
||||
*errormessage = ustringhash(err);
|
||||
} else {
|
||||
sg->context->errorfmt("[RendererServices::environment] {}",
|
||||
err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = Strings::unknown;
|
||||
*errormessage = Strings::unknown.uhash();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -228,34 +291,35 @@ RendererServices::environment(ustring filename, TextureHandle* texture_handle,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_texture_info(ustring filename,
|
||||
RendererServices::get_texture_info(ustringhash filename,
|
||||
TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ShadingContext* shading_context,
|
||||
int subimage, ustring dataname,
|
||||
int subimage, ustringhash dataname,
|
||||
TypeDesc datatype, void* data,
|
||||
ustring* errormessage)
|
||||
ustringhash* errormessage)
|
||||
{
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = shading_context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->get_texture_info(texture_handle,
|
||||
texture_thread_info, subimage,
|
||||
dataname, datatype, data);
|
||||
ustring_from(dataname),
|
||||
datatype, data);
|
||||
if (!status) {
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size()) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustring(err);
|
||||
*errormessage = ustringhash(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 = ustring();
|
||||
*errormessage = ustringhash();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -265,10 +329,10 @@ RendererServices::get_texture_info(ustring filename,
|
||||
|
||||
bool
|
||||
RendererServices::get_texture_info(
|
||||
ustring filename, TextureHandle* texture_handle, float s, float t,
|
||||
ustringhash 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)
|
||||
int subimage, ustringhash dataname, TypeDesc datatype, void* data,
|
||||
ustringhash* errormessage)
|
||||
{
|
||||
#if OIIO_VERSION >= 20307
|
||||
// Newer versions of the TextureSystem interface are able to determine the
|
||||
@@ -276,7 +340,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(filename,
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info);
|
||||
if (texturesys()->is_udim(texture_handle)) {
|
||||
TextureSystem::TextureHandle* udim_handle
|
||||
@@ -297,6 +361,27 @@ 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>)
|
||||
{
|
||||
|
||||
@@ -3384,6 +3384,8 @@ 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()) {
|
||||
|
||||
@@ -1049,7 +1049,7 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
|
||||
, m_llvm_output_bitcode(0)
|
||||
, m_llvm_dumpasm(0)
|
||||
, m_max_local_mem_KB(2048)
|
||||
, m_compile_report(false)
|
||||
, m_compile_report(0)
|
||||
, m_buffer_printf(true)
|
||||
, m_no_noise(false)
|
||||
, m_no_pointcloud(false)
|
||||
@@ -1093,6 +1093,8 @@ 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;
|
||||
@@ -1768,6 +1770,8 @@ 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);
|
||||
@@ -2125,6 +2129,10 @@ 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;
|
||||
}
|
||||
@@ -2398,6 +2406,8 @@ 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);
|
||||
@@ -3182,7 +3192,9 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
|
||||
}
|
||||
|
||||
// Check for mismatch versus previously-declared type
|
||||
if (!equivalent(sym->typespec(), type))
|
||||
if ((relaxed_param_typecheck() && !relaxed_equivalent(sym->typespec(), type))
|
||||
|| (!relaxed_param_typecheck()
|
||||
&& !relaxed_equivalent(sym->typespec(), type)))
|
||||
return false;
|
||||
|
||||
// Can't change param value if the group has already been optimized,
|
||||
@@ -4159,7 +4171,8 @@ 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), 0);
|
||||
cp->apply((float*)&CC, 3, 1, 3, sizeof(float), sizeof(Color3),
|
||||
3 * sizeof(Color3));
|
||||
Cout.set(CC[0], (CC[1] - CC[0]) * (1.0f / eps),
|
||||
(CC[2] - CC[0]) * (1.0f / eps));
|
||||
return true;
|
||||
@@ -4313,8 +4326,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,
|
||||
const void* sourcefile, int sourceline, void* symbolname,
|
||||
int firstcheck, int nchecks, const void* opname)
|
||||
ustring_pod sourcefile, int sourceline, ustring_pod symbolname,
|
||||
int firstcheck, int nchecks, ustring_pod opname)
|
||||
{
|
||||
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
|
||||
const float* vals = (const float*)vals_;
|
||||
@@ -4345,10 +4358,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,
|
||||
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)
|
||||
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)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
|
||||
@@ -4378,30 +4391,34 @@ 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.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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
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_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)
|
||||
{
|
||||
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 && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
USTR(shadername));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
@@ -4415,7 +4432,7 @@ osl_range_check_err(int indexvalue, int length, const char* 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_, const char* name)
|
||||
osl_raytype_name(void* sg_, ustring_pod name)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
int bit = sg->context->shadingsys().raytype_bit(USTR(name));
|
||||
@@ -4424,24 +4441,21 @@ osl_raytype_name(void* sg_, const char* name)
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
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)
|
||||
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)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
return sg->context->osl_get_attribute(sg, sg->objdata, dest_derivs,
|
||||
obj_name, attr_name, array_lookup,
|
||||
index, TYPEDESC(attr_type),
|
||||
attr_dest);
|
||||
USTR(obj_name), USTR(attr_name),
|
||||
array_lookup, index,
|
||||
TYPEDESC(attr_type), attr_dest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
|
||||
osl_bind_interpolated_param(void* sg_, ustring_pod 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,
|
||||
|
||||
@@ -42,7 +42,7 @@ enum {
|
||||
|
||||
// clang-format off
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
OSL_CONSTANT_DATA const static SplineBasis gBasisSet[kNumSplineTypes] = {
|
||||
OSL_CONSTANT_DATA const SplineBasis gBasisSet[kNumSplineTypes] = {
|
||||
//
|
||||
// catmullrom
|
||||
//
|
||||
|
||||
@@ -149,6 +149,27 @@ 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
|
||||
|
||||
@@ -90,8 +90,10 @@ 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)
|
||||
#include "wide_opbinary_per_component_float_or_vector_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"
|
||||
|
||||
|
||||
static OSL_FORCEINLINE float
|
||||
|
||||
@@ -28,12 +28,7 @@ namespace {
|
||||
OSL_FORCEINLINE OSL_HOSTDEVICE int
|
||||
bitcast_to_uint(float x)
|
||||
{
|
||||
#if OPENIMAGEIO_VERSION >= 20500
|
||||
return OIIO::bitcast<unsigned int, float>(x);
|
||||
#else
|
||||
// obsolete call
|
||||
return OIIO::bit_cast<float, unsigned int>(x);
|
||||
#endif
|
||||
return OSL::bitcast<unsigned int>(x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,18 @@ 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)
|
||||
{
|
||||
@@ -88,12 +100,12 @@ invert_wide_matrix(Masked<Matrix44> wresult, Wide<const Matrix44> wmatrix)
|
||||
|
||||
Mask
|
||||
default_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult, Wide<const ustring> wfrom,
|
||||
Masked<Matrix44> wresult, Wide<const ustringhash> wfrom,
|
||||
Wide<const float> wtime)
|
||||
{
|
||||
Mask ok(false);
|
||||
foreach_unique(wfrom, wresult.mask(),
|
||||
[=, &ok](const ustring& from, Mask from_mask) {
|
||||
[=, &ok](const ustringhash& 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);
|
||||
@@ -110,7 +122,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 ustring> from,
|
||||
Masked<Matrix44> result, Wide<const ustringhash> from,
|
||||
Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_matrix_WmWsWf()) {
|
||||
@@ -154,7 +166,7 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
Mask
|
||||
default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustring to, Wide<const float> time)
|
||||
ustringhash to, Wide<const float> time)
|
||||
{
|
||||
OSL_FORCEINLINE_BLOCK
|
||||
{
|
||||
@@ -170,7 +182,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustring to, Wide<const float> time)
|
||||
ustringhash to, Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
|
||||
return bsr->get_inverse_matrix(bsg, result, to, time);
|
||||
@@ -183,12 +195,12 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
Mask
|
||||
default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> wresult,
|
||||
Wide<const ustring> wto, Wide<const float> wtime)
|
||||
Wide<const ustringhash> wto, Wide<const float> wtime)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
|
||||
Mask ok(false);
|
||||
foreach_unique(wto, wresult.mask(),
|
||||
[=, &ok](const ustring& to, Mask from_mask) {
|
||||
[=, &ok](const ustringhash& 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(),
|
||||
@@ -213,7 +225,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustring> to, Wide<const float> time)
|
||||
Wide<const ustringhash> to, Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmWsWf()) {
|
||||
return bsr->get_inverse_matrix(bsg, result, to, time);
|
||||
@@ -627,7 +639,7 @@ impl_wide_mat_multiply(ResultAccessorT wresult, FromAccessorT wfrom,
|
||||
OSL_FORCEINLINE Mask
|
||||
impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
|
||||
ShadingContext* ctx,
|
||||
Wide<const ustring> wFrom,
|
||||
Wide<const ustringhash> wFrom,
|
||||
Masked<Matrix44> wMfrom)
|
||||
{
|
||||
// Deal with a varying 'from' space
|
||||
@@ -646,7 +658,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) {
|
||||
ustring from = wFrom[lane];
|
||||
ustringhash from = wFrom[lane];
|
||||
if (wMfrom.mask()[lane]) {
|
||||
if (from == Strings::common || from == commonspace_synonym) {
|
||||
// inline of Mask::set_on(lane)
|
||||
@@ -703,10 +715,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]) {
|
||||
ustring from = wFrom[lane];
|
||||
ustringhash from = wFrom[lane];
|
||||
ctx->batched<__OSL_WIDTH>().errorfmt(
|
||||
Mask(Lane(lane)), "Unknown transformation \"{}\"",
|
||||
from);
|
||||
ustring(from));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -746,7 +758,13 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, Ws)(void* bsg_, void* wr,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
Wide<const ustring> wFromName(w_from_name);
|
||||
#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
|
||||
|
||||
Block<Matrix44> wMfrom;
|
||||
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
|
||||
@@ -762,7 +780,8 @@ __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 ustring> wTo,
|
||||
ShadingContext* ctx,
|
||||
Wide<const ustringhash> wTo,
|
||||
Masked<Matrix44> wMto)
|
||||
{
|
||||
// Deal with a varying 'to' space
|
||||
@@ -781,7 +800,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) {
|
||||
ustring to = wTo[lane];
|
||||
ustringhash to = wTo[lane];
|
||||
if (wMto.mask()[lane]) {
|
||||
if (to == Strings::common || to == commonspace_synonym) {
|
||||
// inline of Mask::set_on(lane)
|
||||
@@ -836,10 +855,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]) {
|
||||
ustring to = wTo[lane];
|
||||
ustringhash to = wTo[lane];
|
||||
ctx->batched<__OSL_WIDTH>().errorfmt(
|
||||
Mask(Lane(lane)), "Unknown transformation \"{}\"",
|
||||
to);
|
||||
ustring(to));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -895,7 +914,13 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, s,
|
||||
Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix,
|
||||
from);
|
||||
|
||||
Wide<const ustring> wToSpace(w_to_ptr);
|
||||
#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
|
||||
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
|
||||
@@ -917,7 +942,13 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
Wide<const ustring> wFromName(w_from_ptr);
|
||||
#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
|
||||
|
||||
Block<Matrix44> wMto;
|
||||
Masked<Matrix44> to_matrix(wMto, Mask(mask_value));
|
||||
@@ -945,14 +976,26 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
Wide<const ustring> wFromName(w_from_ptr);
|
||||
#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
|
||||
|
||||
Block<Matrix44> wMfrom;
|
||||
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
|
||||
Mask succeeded = impl_get_varying_from_matrix_batched(bsg, ctx, wFromName,
|
||||
from_matrix);
|
||||
|
||||
Wide<const ustring> wToSpace(w_to_ptr);
|
||||
#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
|
||||
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
|
||||
@@ -977,9 +1020,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_,
|
||||
void* from_, void* to_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
s)(void* bsg_, void* WM_, ustring_pod from_, ustring_pod to_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -987,8 +1030,8 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s, s)(void* bsg_, void* WM_,
|
||||
Masked<Matrix44> mm(WM_, mask);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
ustring from = USTR(from_);
|
||||
ustring to = USTR(to_);
|
||||
ustringrep from = USTR(from_);
|
||||
ustringrep to = USTR(to_);
|
||||
|
||||
Mask succeeded;
|
||||
// Avoid matrix concatenation if possible by detecting when the
|
||||
@@ -1013,18 +1056,24 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s, s)(void* bsg_, void* WM_,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, s)(void* bsg_, void* WM_,
|
||||
void* wfrom_, void* to_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, Ws,
|
||||
s)(void* bsg_, void* WM_, void* wfrom_, ustring_pod to_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
Wide<const ustring> wfrom_space(wfrom_);
|
||||
#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
|
||||
|
||||
ustring to_space = USTR(to_);
|
||||
ustringrep to_space = USTR(to_);
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
@@ -1043,17 +1092,23 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, s)(void* bsg_, void* WM_,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s, Ws)(void* bsg_, void* WM_,
|
||||
void* from_, void* wto_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
Ws)(void* bsg_, void* WM_, ustring_pod from_, void* wto_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
ustring from = USTR(from_);
|
||||
Wide<const ustring> wto_space(wto_);
|
||||
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
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
@@ -1082,8 +1137,17 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, Ws)(void* bsg_, void* WM_,
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
Wide<const ustring> wfrom_space(wfrom_);
|
||||
Wide<const ustring> wto_space(wto_);
|
||||
#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
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
|
||||
@@ -200,18 +200,19 @@ impl_setmessage(BatchedShaderGlobals* bsg, ustring sourcefile, int sourceline,
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
long long type, void* wvalue, int layeridx,
|
||||
const char* sourcefile_, int sourceline,
|
||||
__OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_,
|
||||
ustring_pod name_, long long type,
|
||||
void* wvalue, int layeridx,
|
||||
ustring_pod sourcefile_, int sourceline,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
Mask mask(mask_value);
|
||||
OSL_ASSERT(mask.any_on());
|
||||
|
||||
ustring name = USTR(wname);
|
||||
ustringrep name = USTR(name_);
|
||||
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
|
||||
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -237,16 +238,16 @@ __OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
long long type, void* wvalue, int layeridx,
|
||||
const char* sourcefile_, int sourceline,
|
||||
ustring_pod sourcefile_, int sourceline,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
Mask mask(mask_value);
|
||||
OSL_ASSERT(mask.any_on());
|
||||
|
||||
Wide<const ustring> wName(wname);
|
||||
Wide<const ustringrep> wName(wname);
|
||||
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
|
||||
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -274,14 +275,14 @@ __OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, char* source_,
|
||||
char* name_, long long type_, void* val, int derivs,
|
||||
int layeridx, const char* sourcefile_,
|
||||
__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, ustring_pod source_,
|
||||
ustring_pod name_, long long type_, void* val,
|
||||
int derivs, int layeridx, ustring_pod sourcefile_,
|
||||
int sourceline, unsigned int mask_value)
|
||||
{
|
||||
const ustring& source(USTR(source_));
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
ustringrep source = USTR(source_);
|
||||
ustringrep name = USTR(name_);
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
|
||||
Mask mask(mask_value);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ using PointCloudSearchResults = BatchedRendererServices::PointCloudSearchResults
|
||||
namespace {
|
||||
|
||||
OSL_FORCEINLINE void
|
||||
default_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
default_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
const void* wcenter_, Wide<const float> wradius,
|
||||
int max_points, bool sort,
|
||||
PointCloudSearchResults& results)
|
||||
@@ -199,7 +199,7 @@ default_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE void
|
||||
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
const void* wcenter, Wide<const float> wradius,
|
||||
int max_points, bool sort,
|
||||
PointCloudSearchResults& results)
|
||||
@@ -217,9 +217,9 @@ dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
default_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
default_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
Wide<const int[]> windices, Wide<const int> wnum_points,
|
||||
ustring attr_name, MaskedData wout_data)
|
||||
ustringhash attr_name, MaskedData wout_data)
|
||||
{
|
||||
#ifdef USE_PARTIO
|
||||
Mask success { false };
|
||||
@@ -364,9 +364,9 @@ default_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
Wide<const int[]> windices, Wide<const int> wnum_points,
|
||||
ustring attr_name, MaskedData wout_data)
|
||||
ustringhash 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, ustring filename,
|
||||
|
||||
|
||||
Mask
|
||||
default_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
|
||||
default_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash 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, ustring filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
|
||||
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash 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, ustring filename,
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(pointcloud_search)(
|
||||
BatchedShaderGlobals* bsg, void* wout_num_points_, const char* filename,
|
||||
BatchedShaderGlobals* bsg, void* wout_num_points_, ustring_pod filename,
|
||||
const void* wcenter_, void* wradius_, int max_points, int sort,
|
||||
void* wout_indices_, int indices_array_length, void* wout_distances_,
|
||||
int distances_array_length, int distances_has_derivs, int mask_value,
|
||||
@@ -509,16 +509,15 @@ __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), wcenter_, wradius,
|
||||
dispatch_pointcloud_search(bsg, USTR(filename).uhash(), wcenter_, wradius,
|
||||
max_points, sort, pcsr);
|
||||
|
||||
if (nattrs > 0) {
|
||||
@@ -528,11 +527,9 @@ __OSL_MASKED_OP(pointcloud_search)(
|
||||
va_list args;
|
||||
va_start(args, nattrs);
|
||||
for (int i = 0; i < nattrs; i++) {
|
||||
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*);
|
||||
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*);
|
||||
dispatch_pointcloud_get(
|
||||
bsg, USTR(filename), windices, wnum_points, attr_name,
|
||||
MaskedData { attr_type, false, Mask { mask_value }, out_data });
|
||||
@@ -547,9 +544,9 @@ __OSL_MASKED_OP(pointcloud_search)(
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, const char* filename,
|
||||
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename,
|
||||
void* windices_, int indices_array_length,
|
||||
void* wnum_points_, const char* attr_name,
|
||||
void* wnum_points_, ustring_pod attr_name,
|
||||
long long attr_type_, void* wout_data_,
|
||||
int mask_value)
|
||||
{
|
||||
@@ -564,7 +561,8 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, const char* filename,
|
||||
TypeDesc attr_type = TYPEDESC(attr_type_);
|
||||
|
||||
Mask success = dispatch_pointcloud_get(
|
||||
bsg, USTR(filename), windices, wnum_points, USTR(attr_name),
|
||||
bsg, USTR(filename).uhash(), windices, wnum_points,
|
||||
USTR(attr_name).uhash(),
|
||||
MaskedData { attr_type, false, Mask { mask_value }, wout_data_ });
|
||||
return success.value();
|
||||
}
|
||||
@@ -573,20 +571,21 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, const char* filename,
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP(pointcloud_write)(BatchedShaderGlobals* bsg,
|
||||
const char* filename, const void* wpos_,
|
||||
int nattribs, const ustring* attr_names,
|
||||
ustring_pod filename, const void* wpos_,
|
||||
int nattribs, const ustringrep* attr_names,
|
||||
const TypeDesc* attr_types,
|
||||
const void** ptrs_to_wide_attr_value,
|
||||
int mask_value)
|
||||
{
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
if (ctx->shadingsys()
|
||||
.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
return 0; // mask_value;
|
||||
|
||||
// Debug mode to skip pointcloud expense
|
||||
if (ctx->shadingsys().no_pointcloud())
|
||||
return 0; // mask_value;
|
||||
|
||||
Wide<const OSL::Vec3> wpos(wpos_);
|
||||
|
||||
Mask success = dispatch_pointcloud_write(bsg, USTR(filename), wpos,
|
||||
Mask success = dispatch_pointcloud_write(bsg, USTR(filename).uhash(), wpos,
|
||||
nattribs, attr_names, attr_types,
|
||||
ptrs_to_wide_attr_value,
|
||||
Mask(mask_value));
|
||||
|
||||
@@ -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(USTR(spline_basis));
|
||||
unsigned int basis_type = Spline::basis_type_of(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(USTR(spline_basis));
|
||||
unsigned int basis_type = Spline::basis_type_of(spline_basis);
|
||||
|
||||
OSL_DASSERT(basis_type < Spline::kNumSplineTypes
|
||||
&& "unsupported spline basis");
|
||||
|
||||
@@ -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(USTR(pattern)));
|
||||
const std::regex& regex(ctx->find_regex(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] = USTR(pattern).length();
|
||||
results[r] = pattern.length();
|
||||
}
|
||||
}
|
||||
wsuccess[lane] = res;
|
||||
|
||||
@@ -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_, const void* sourcefile, int sourceline,
|
||||
void* symbolname, int firstcheck, int nchecks,
|
||||
const void* opname)
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod symbolname, int firstcheck, int nchecks,
|
||||
ustring_pod 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_, const void* sourcefile,
|
||||
int sourceline, void* symbolname, int firstcheck,
|
||||
int nchecks, const void* opname)
|
||||
int has_derivs, void* bsg_, ustring_pod sourcefile,
|
||||
int sourceline, ustring_pod symbolname, int firstcheck,
|
||||
int nchecks, ustring_pod 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_, const void* sourcefile,
|
||||
int sourceline, void* symbolname,
|
||||
const void* wide_offsets_ptr,
|
||||
int nchecks, const void* opname)
|
||||
__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)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
@@ -129,9 +129,9 @@ __OSL_MASKED_OP1(naninf_check_offset, Wi)(int mask_value, int ncomps,
|
||||
OSL_BATCHOP void
|
||||
__OSL_OP2(uninit_check_values_offset, X,
|
||||
i)(long long typedesc_, void* vals_, 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,
|
||||
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)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
@@ -163,12 +163,14 @@ __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, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum);
|
||||
typedesc, symbolname, sourcefile, sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
shadername, opnum, opname, argnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,10 +181,11 @@ __OSL_OP2(uninit_check_values_offset, X,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
i)(int mask_value, long long typedesc_, void* vals_,
|
||||
void* bsg_, 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)
|
||||
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)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -224,12 +227,14 @@ __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, 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());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,11 +245,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_, 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)
|
||||
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)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -288,12 +293,14 @@ __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, 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());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,11 +311,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_, 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)
|
||||
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)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -354,33 +361,38 @@ __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, 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());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__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)
|
||||
__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)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
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));
|
||||
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));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
else
|
||||
@@ -393,12 +405,14 @@ __OSL_OP(range_check)(int indexvalue, int length, const char* symname,
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value,
|
||||
int length, const char* symname, void* bsg_,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer,
|
||||
const char* layername, const char* shadername)
|
||||
int length, ustring_pod symname, void* bsg_,
|
||||
ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer,
|
||||
ustring_pod layername_, ustring_pod shadername)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
Masked<int> wIndexValue(wide_indexvalue, Mask(mask_value));
|
||||
wIndexValue.mask().foreach ([=](ActiveLane lane) -> void {
|
||||
int indexvalue = wIndexValue[lane];
|
||||
@@ -408,9 +422,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 && groupname[0]) ? groupname : "<unnamed group>",
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(),
|
||||
layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
USTR(shadername));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
@@ -425,17 +439,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, void* obj_name_,
|
||||
void* attr_name_, int array_lookup, int index,
|
||||
__OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, ustring_pod obj_name_,
|
||||
ustring_pod attr_name_, int array_lookup, int index,
|
||||
const void* attr_type, void* wide_attr_dest,
|
||||
int mask_)
|
||||
{
|
||||
Mask mask(mask_);
|
||||
ASSERT(mask.any_on());
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
ustringrep attr_name = USTR(attr_name_);
|
||||
|
||||
// Ignoring m_next_failed_attrib cache for now,
|
||||
// might be faster
|
||||
@@ -457,16 +471,16 @@ __OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP1(get_attribute,
|
||||
Ws)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
void* wattr_name_, int array_lookup, int index,
|
||||
Ws)(void* bsg_, int dest_derivs, ustring_pod obj_name_,
|
||||
ustring_pod* wattr_name_, int array_lookup, int index,
|
||||
const void* attr_type, void* wide_attr_dest, int mask_)
|
||||
{
|
||||
Mask mask(mask_);
|
||||
ASSERT(mask.any_on());
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
Wide<const ustring> wAttrName(wattr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
Wide<const ustringrep> wAttrName(wattr_name_);
|
||||
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
|
||||
|
||||
Mask retVal(false);
|
||||
@@ -504,13 +518,14 @@ __OSL_MASKED_OP1(get_attribute,
|
||||
|
||||
|
||||
OSL_BATCHOP bool
|
||||
__OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
void* attr_name_, int array_lookup, int index,
|
||||
__OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs,
|
||||
ustring_pod obj_name_, ustring_pod attr_name_,
|
||||
int array_lookup, int index,
|
||||
const void* attr_type, void* attr_dest)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
ustringrep attr_name = USTR(attr_name_);
|
||||
|
||||
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
|
||||
|
||||
@@ -530,7 +545,7 @@ __OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_OP(bind_interpolated_param)(void* bsg_, const void* name, long long type,
|
||||
__OSL_OP(bind_interpolated_param)(void* bsg_, ustring_pod name, long long type,
|
||||
int userdata_has_derivs, void* userdata_data,
|
||||
int symbol_has_derivs, void* symbol_data,
|
||||
int symbol_data_size,
|
||||
@@ -580,7 +595,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_, void* name)
|
||||
__OSL_OP(raytype_name)(void* bsg_, ustring_pod name)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
int bit = bsg->uniform.context->shadingsys().raytype_bit(USTR(name));
|
||||
@@ -590,11 +605,11 @@ __OSL_OP(raytype_name)(void* bsg_, void* name)
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, void* name_,
|
||||
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, ustringrep* name_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
Wide<const ustring> wname(name_);
|
||||
Wide<const ustringrep> wname(name_);
|
||||
Mask mask(mask_value);
|
||||
|
||||
foreach_unique(wname, mask, [=](ustring name, Mask matching_lanes) -> void {
|
||||
|
||||
@@ -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
|
||||
static OSL_CONSTANT_DATA float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
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.
|
||||
static OSL_CONSTANT_DATA float grad2lut[8][2] = {
|
||||
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 @@ static 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.
|
||||
static OSL_CONSTANT_DATA float grad3lut[16][3] = {
|
||||
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 @@ static OSL_CONSTANT_DATA float grad3lut[16][3] = {
|
||||
};
|
||||
|
||||
// Gradient directions for 4D
|
||||
static OSL_CONSTANT_DATA float grad4lut[32][4] = {
|
||||
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 @@ static 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! */
|
||||
static OSL_CONSTANT_DATA unsigned char simplex[64][4] = {
|
||||
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},
|
||||
|
||||
@@ -265,7 +265,7 @@ rend_get_userdata(OSL::StringParam name, void* data, int data_size,
|
||||
|
||||
|
||||
__device__ int
|
||||
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
|
||||
osl_bind_interpolated_param(void* sg_, OSL::StringParam 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, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername)
|
||||
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)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
return indexvalue < 0 ? 0 : length - 1;
|
||||
@@ -425,9 +425,10 @@ osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
|
||||
|
||||
|
||||
__device__ int
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
|
||||
|
||||
@@ -882,16 +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(ustring filename OSL_MAYBE_UNUSED,
|
||||
ShadingContext* shading_context
|
||||
OSL_MAYBE_UNUSED)
|
||||
OptixRaytracer::get_texture_handle(ustringhash filename,
|
||||
ShadingContext* /*shading_context*/)
|
||||
{
|
||||
auto itr = m_samplers.find(filename);
|
||||
if (itr == m_samplers.end()) {
|
||||
// Open image
|
||||
OIIO::ImageBuf image;
|
||||
if (!image.init_spec(filename, 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {}", filename);
|
||||
if (!image.init_spec(ustring_from(filename), 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {} (hash {})",
|
||||
ustring_from(filename), filename);
|
||||
return (TextureHandle*)nullptr;
|
||||
}
|
||||
|
||||
@@ -1072,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,
|
||||
dst += snprintf(&buffer[dst], BufferSize - dst, "%s",
|
||||
fmt_string.c_str());
|
||||
format_end_found = true;
|
||||
break;
|
||||
|
||||
@@ -25,10 +25,10 @@ public:
|
||||
OptixRaytracer();
|
||||
virtual ~OptixRaytracer();
|
||||
|
||||
uint64_t register_global(const std::string& str, uint64_t value);
|
||||
bool fetch_global(const std::string& str, uint64_t* value);
|
||||
uint64_t register_global(const std::string& str, uint64_t value) override;
|
||||
bool fetch_global(const std::string& str, uint64_t* value) override;
|
||||
|
||||
virtual int supports(string_view feature) const
|
||||
int supports(string_view feature) const override
|
||||
{
|
||||
if (feature == "OptiX")
|
||||
return true;
|
||||
@@ -38,24 +38,24 @@ public:
|
||||
std::string load_ptx_file(string_view filename);
|
||||
bool synch_attributes();
|
||||
|
||||
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();
|
||||
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;
|
||||
|
||||
/// 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* handle);
|
||||
bool good(TextureHandle* handle) override;
|
||||
|
||||
/// 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* shading_context);
|
||||
TextureHandle* get_texture_handle(ustringhash filename,
|
||||
ShadingContext* shading_context) override;
|
||||
|
||||
// Easy way to do Optix calls
|
||||
optix::Context& optix_ctx() { return m_optix_ctx; }
|
||||
@@ -93,8 +93,8 @@ private:
|
||||
OptixProgramGroup* pg);
|
||||
|
||||
std::string m_materials_ptx;
|
||||
std::unordered_map<OIIO::ustring, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<OIIO::ustring, uint64_t> m_globals_map;
|
||||
std::unordered_map<ustringhash, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<ustringhash, uint64_t> m_globals_map;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -154,10 +154,11 @@ struct MxConductorParams : public MxMicrofacetBaseParams {
|
||||
|
||||
Color3 evalT(float cos_theta) const { return Color3(0.0f); }
|
||||
|
||||
float get_ior() const
|
||||
{
|
||||
return 0; // no transmission possible
|
||||
}
|
||||
// Avoid function was declared but never referenced
|
||||
// float get_ior() const
|
||||
// {
|
||||
// return 0; // no transmission possible
|
||||
// }
|
||||
};
|
||||
|
||||
struct MxGeneralizedSchlickParams : public MxMicrofacetBaseParams {
|
||||
|
||||
@@ -441,7 +441,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustring from, float /*time*/)
|
||||
ustringhash 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,
|
||||
ustring from)
|
||||
ustringhash 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,
|
||||
ustring to, float /*time*/)
|
||||
ustringhash 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[ustring(name)] = M;
|
||||
m_named_xforms[ustringhash(name)] = M;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, int index, void* val)
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash 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,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val)
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash 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, ustring name, TypeDesc type,
|
||||
SimpleRaytracer::get_userdata(bool derivatives, ustringhash 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, ustring name, TypeDesc type,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*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,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
if (type == TypeFloatArray4) {
|
||||
|
||||
@@ -30,23 +30,23 @@ public:
|
||||
virtual ~SimpleRaytracer() {}
|
||||
|
||||
// RendererServices support:
|
||||
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);
|
||||
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;
|
||||
|
||||
void name_transform(const char* name, const Transformation& xform);
|
||||
|
||||
@@ -121,7 +121,7 @@ private:
|
||||
bool m_had_error = false;
|
||||
|
||||
// Named transforms
|
||||
typedef std::map<ustring, std::shared_ptr<Transformation>> TransformMap;
|
||||
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
|
||||
TransformMap m_named_xforms;
|
||||
|
||||
// Attribute and userdata retrieval -- for fast dispatch, use a hash
|
||||
@@ -130,38 +130,44 @@ private:
|
||||
// renderer, we would encourage benchmarking various methods and
|
||||
// alternate data structures.
|
||||
typedef bool (SimpleRaytracer::*AttrGetter)(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, void* val);
|
||||
typedef std::unordered_map<ustring, AttrGetter> AttrGetterMap;
|
||||
ustringhash object,
|
||||
TypeDesc type, ustringhash name,
|
||||
void* val);
|
||||
typedef std::unordered_map<ustringhash, AttrGetter> AttrGetterMap;
|
||||
AttrGetterMap m_attr_getters;
|
||||
|
||||
// Attribute getters
|
||||
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_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_camera_shutter_close(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_screen_window(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
|
||||
// CPU renderer helpers
|
||||
void globals_from_hit(ShaderGlobals& sg, const Ray& r,
|
||||
|
||||
@@ -42,6 +42,7 @@ static bool saveptx = false;
|
||||
static bool warmup = false;
|
||||
static bool profile = false;
|
||||
static bool O0 = false, O1 = false, O2 = false;
|
||||
static int llvm_opt = 1; // LLVM optimization level
|
||||
static bool debugnan = false;
|
||||
static bool debug_uninit = false;
|
||||
static bool userdata_isconnected = false;
|
||||
@@ -76,6 +77,15 @@ set_shadingsys_options()
|
||||
if (const char* opt_env = getenv("TESTSHADE_OPT")) // overrides opt
|
||||
opt = atoi(opt_env);
|
||||
shadingsys->attribute("optimize", opt);
|
||||
|
||||
// The cost of more optimization passes usually pays for itself by
|
||||
// reducing the number of instructions JIT ultimately has to lower to
|
||||
// the target ISA.
|
||||
if (const char* llvm_opt_env = getenv(
|
||||
"TESTSHADE_LLVM_OPT")) // overrides llvm_opt
|
||||
llvm_opt = atoi(llvm_opt_env);
|
||||
shadingsys->attribute("llvm_optimize", llvm_opt);
|
||||
|
||||
shadingsys->attribute("profile", int(profile));
|
||||
shadingsys->attribute("lockgeom", 1);
|
||||
shadingsys->attribute("debug_nan", debugnan);
|
||||
@@ -149,6 +159,8 @@ getargs(int argc, const char* argv[])
|
||||
.help("Do a little runtime shader optimization");
|
||||
ap.arg("-O2", &O2)
|
||||
.help("Do lots of runtime shader optimization");
|
||||
ap.arg("--llvm_opt %d:LEVEL", &llvm_opt)
|
||||
.help("LLVM JIT optimization level");
|
||||
ap.arg("--debugnan", &debugnan)
|
||||
.help("Turn on 'debugnan' mode");
|
||||
ap.arg("--path SEARCHPATH", &shaderpath)
|
||||
|
||||
@@ -195,7 +195,7 @@ template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_matrix(BatchedShaderGlobals* /*bsg*/,
|
||||
Masked<Matrix44> wresult,
|
||||
ustring from,
|
||||
ustringhash from,
|
||||
Wide<const float> /*wtime*/)
|
||||
{
|
||||
auto found = m_sr.m_named_xforms.find(from);
|
||||
@@ -219,14 +219,14 @@ template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_matrix(BatchedShaderGlobals* /*bsg*/,
|
||||
Masked<Matrix44> wresult,
|
||||
Wide<const ustring> wfrom,
|
||||
Wide<const ustringhash> wfrom,
|
||||
Wide<const float> /*wtime*/)
|
||||
{
|
||||
Mask succeeded(false);
|
||||
wresult.mask().template foreach<1 /*MinOccupancyT*/>(
|
||||
[&](ActiveLane lane) -> void {
|
||||
ustring from = wfrom[lane];
|
||||
auto found = m_sr.m_named_xforms.find(from);
|
||||
ustringhash from = wfrom[lane];
|
||||
auto found = m_sr.m_named_xforms.find(from);
|
||||
if (found != m_sr.m_named_xforms.end()) {
|
||||
const Matrix44& transform = *(found->second);
|
||||
wresult[lane] = transform;
|
||||
@@ -242,7 +242,7 @@ template<int WidthT>
|
||||
template<typename RAccessorT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::impl_get_inverse_matrix(RAccessorT& result,
|
||||
ustring to) const
|
||||
ustringhash to) const
|
||||
{
|
||||
if (to == ucache().camera || to == ucache().screen || to == ucache().NDC
|
||||
|| to == ucache().raster) {
|
||||
@@ -304,7 +304,7 @@ template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> result,
|
||||
ustring to,
|
||||
ustringhash to,
|
||||
Wide<const float> time)
|
||||
{
|
||||
Matrix44 scalar_result;
|
||||
@@ -326,7 +326,7 @@ template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wResult,
|
||||
Wide<const ustring> wTo,
|
||||
Wide<const ustringhash> wTo,
|
||||
Wide<const float> wTime)
|
||||
|
||||
{
|
||||
@@ -334,8 +334,8 @@ BatchedSimpleRenderer<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
|
||||
for (int i = 0; i < WidthT; ++i) {
|
||||
if (wResult.mask()[i]) {
|
||||
ustring to = wTo[i];
|
||||
auto result = wResult[i];
|
||||
ustringhash to = wTo[i];
|
||||
auto result = wResult[i];
|
||||
if (impl_get_inverse_matrix(result, to)) {
|
||||
status.set_on(i);
|
||||
}
|
||||
@@ -391,31 +391,32 @@ BatchedSimpleRenderer<WidthT>::trace(
|
||||
template<int WidthT>
|
||||
void
|
||||
BatchedSimpleRenderer<WidthT>::getmessage(BatchedShaderGlobals* bsg,
|
||||
Masked<int> result, ustring source,
|
||||
ustring name, MaskedData val)
|
||||
Masked<int> result,
|
||||
ustringhash source, ustringhash name,
|
||||
MaskedData val)
|
||||
{
|
||||
OSL_ASSERT(source == ustring("trace"));
|
||||
OSL_ASSERT(source == "trace");
|
||||
for (int lane = 0; lane < WidthT; ++lane) {
|
||||
if (bsg->varying.u[lane] > 0.5) {
|
||||
if (name == ustring("hitdist")) {
|
||||
if (name == "hitdist") {
|
||||
if (Masked<float>::is(val)) {
|
||||
Masked<float> dest(val);
|
||||
dest[lane] = 0.5;
|
||||
}
|
||||
}
|
||||
if (name == ustring("hit")) {
|
||||
if (name == "hit") {
|
||||
if (Masked<int>::is(val)) {
|
||||
Masked<int> dest(val);
|
||||
dest[lane] = 1;
|
||||
}
|
||||
}
|
||||
if (name == ustring("geom:name")) {
|
||||
if (name == "geom:name") {
|
||||
if (Masked<ustring>::is(val)) {
|
||||
Masked<ustring> dest(val);
|
||||
dest[lane] = ustring("teapot");
|
||||
}
|
||||
}
|
||||
if (name == ustring("N")) {
|
||||
if (name == "N") {
|
||||
if (Masked<Vec3>::is(val)) {
|
||||
Masked<Vec3> dest(val);
|
||||
dest[lane] = Vec3(1.0 - bsg->varying.v[lane], 0.25,
|
||||
@@ -427,7 +428,7 @@ BatchedSimpleRenderer<WidthT>::getmessage(BatchedShaderGlobals* bsg,
|
||||
|
||||
result[lane] = 1;
|
||||
} else {
|
||||
if (name == ustring("hit")) {
|
||||
if (name == "hit") {
|
||||
if (Masked<int>::is(val)) {
|
||||
Masked<int> dest(val);
|
||||
dest[lane] = 0;
|
||||
@@ -444,8 +445,9 @@ BatchedSimpleRenderer<WidthT>::getmessage(BatchedShaderGlobals* bsg,
|
||||
template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_array_attribute(BatchedShaderGlobals* bsg,
|
||||
ustring object, ustring name,
|
||||
int index, MaskedData val)
|
||||
ustringhash object,
|
||||
ustringhash name, int index,
|
||||
MaskedData val)
|
||||
{
|
||||
// Normally the common_get_attribute would be for is_attribute_uniform() == true only
|
||||
// However a name that has a uniform answer could be part of a varying name inside
|
||||
@@ -551,8 +553,8 @@ BatchedSimpleRenderer<WidthT>::get_array_attribute(BatchedShaderGlobals* bsg,
|
||||
template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_attribute(BatchedShaderGlobals* bsg,
|
||||
ustring object, ustring name,
|
||||
MaskedData val)
|
||||
ustringhash object,
|
||||
ustringhash name, MaskedData val)
|
||||
{
|
||||
return get_array_attribute(bsg, object, name, -1, val);
|
||||
}
|
||||
@@ -562,7 +564,7 @@ BatchedSimpleRenderer<WidthT>::get_attribute(BatchedShaderGlobals* bsg,
|
||||
template<int WidthT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_array_attribute_uniform(
|
||||
BatchedShaderGlobals* bsg, ustring object, ustring name, int index,
|
||||
BatchedShaderGlobals* bsg, ustringhash object, ustringhash name, int index,
|
||||
RefData val)
|
||||
{
|
||||
ASSERT(!name.empty());
|
||||
@@ -617,8 +619,9 @@ BatchedSimpleRenderer<WidthT>::get_array_attribute_uniform(
|
||||
template<int WidthT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustring object,
|
||||
ustring name, RefData val)
|
||||
ustringhash object,
|
||||
ustringhash name,
|
||||
RefData val)
|
||||
{
|
||||
return get_array_attribute_uniform(bsg, object, name, -1, val);
|
||||
}
|
||||
@@ -627,7 +630,7 @@ BatchedSimpleRenderer<WidthT>::get_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
|
||||
template<int WidthT>
|
||||
typename BatchedSimpleRenderer<WidthT>::Mask
|
||||
BatchedSimpleRenderer<WidthT>::get_userdata(ustring name,
|
||||
BatchedSimpleRenderer<WidthT>::get_userdata(ustringhash name,
|
||||
BatchedShaderGlobals* bsg,
|
||||
MaskedData val)
|
||||
{
|
||||
@@ -746,8 +749,8 @@ assign_and_zero_derivs(MaskedData<WidthT> data, const DataT& val)
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_osl_version(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_osl_version(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, int(OSL_VERSION));
|
||||
@@ -758,8 +761,8 @@ BatchedSimpleRenderer<WidthT>::get_osl_version(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_resolution(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_resolution(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
int res[2] = { m_sr.m_xres, m_sr.m_yres };
|
||||
@@ -771,8 +774,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_resolution(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_projection(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_projection(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_projection);
|
||||
@@ -783,8 +786,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_projection(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_fov(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_fov(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
@@ -796,8 +799,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_fov(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_pixelaspect(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_pixelaspect(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_pixelaspect);
|
||||
@@ -808,8 +811,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_pixelaspect(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
float clip[2] = { m_sr.m_hither, m_sr.m_yon };
|
||||
@@ -821,8 +824,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_clip(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip_near(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip_near(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_hither);
|
||||
@@ -833,8 +836,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_clip_near(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip_far(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_clip_far(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_yon);
|
||||
@@ -845,8 +848,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_clip_far(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_shutter);
|
||||
@@ -857,8 +860,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_shutter(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter_open(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter_open(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_shutter[0]);
|
||||
@@ -869,8 +872,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_shutter_open(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter_close(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_shutter_close(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_shutter[1]);
|
||||
@@ -881,8 +884,8 @@ BatchedSimpleRenderer<WidthT>::get_camera_shutter_close(ustring /*object*/,
|
||||
template<int WidthT>
|
||||
template<typename RefOrMaskedT>
|
||||
bool
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_screen_window(ustring /*object*/,
|
||||
ustring /*name*/,
|
||||
BatchedSimpleRenderer<WidthT>::get_camera_screen_window(ustringhash /*object*/,
|
||||
ustringhash /*name*/,
|
||||
RefOrMaskedT data)
|
||||
{
|
||||
return assign_and_zero_derivs(data, m_sr.m_screen_window);
|
||||
|
||||
@@ -37,25 +37,26 @@ public:
|
||||
}
|
||||
|
||||
Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustring from, Wide<const float> time) override;
|
||||
ustringhash from, Wide<const float> time) override;
|
||||
Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustring> from, Wide<const float> time) override;
|
||||
Wide<const ustringhash> from,
|
||||
Wide<const float> time) override;
|
||||
bool is_overridden_get_matrix_WmWsWf() const override { return true; }
|
||||
|
||||
private:
|
||||
template<typename RAccessorT>
|
||||
OSL_FORCEINLINE bool impl_get_inverse_matrix(RAccessorT& result,
|
||||
ustring to) const;
|
||||
ustringhash to) const;
|
||||
|
||||
public:
|
||||
Mask get_inverse_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustring to, Wide<const float> time) override;
|
||||
ustringhash to, Wide<const float> time) override;
|
||||
bool is_overridden_get_inverse_matrix_WmsWf() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Mask get_inverse_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustring> to,
|
||||
Wide<const ustringhash> to,
|
||||
Wide<const float> time) override;
|
||||
bool is_overridden_get_inverse_matrix_WmWsWf() const override
|
||||
{
|
||||
@@ -65,21 +66,22 @@ public:
|
||||
|
||||
bool is_attribute_uniform(ustring object, ustring name) override;
|
||||
|
||||
Mask get_array_attribute(BatchedShaderGlobals* bsg, ustring object,
|
||||
ustring name, int index, MaskedData amd) override;
|
||||
Mask get_array_attribute(BatchedShaderGlobals* bsg, ustringhash object,
|
||||
ustringhash name, int index,
|
||||
MaskedData amd) override;
|
||||
|
||||
Mask get_attribute(BatchedShaderGlobals* bsg, ustring object, ustring name,
|
||||
MaskedData amd) override;
|
||||
Mask get_attribute(BatchedShaderGlobals* bsg, ustringhash object,
|
||||
ustringhash name, MaskedData amd) override;
|
||||
|
||||
|
||||
bool get_array_attribute_uniform(BatchedShaderGlobals* bsg, ustring object,
|
||||
ustring name, int index,
|
||||
RefData val) override;
|
||||
bool get_array_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustringhash object, ustringhash name,
|
||||
int index, RefData val) override;
|
||||
|
||||
bool get_attribute_uniform(BatchedShaderGlobals* bsg, ustring object,
|
||||
ustring name, RefData val) override;
|
||||
bool get_attribute_uniform(BatchedShaderGlobals* bsg, ustringhash object,
|
||||
ustringhash name, RefData val) override;
|
||||
|
||||
Mask get_userdata(ustring name, BatchedShaderGlobals* bsg,
|
||||
Mask get_userdata(ustringhash name, BatchedShaderGlobals* bsg,
|
||||
MaskedData val) override;
|
||||
|
||||
bool is_overridden_texture() const override { return false; }
|
||||
@@ -95,7 +97,8 @@ public:
|
||||
Wide<const Vec3> dRdy) override;
|
||||
|
||||
void getmessage(BatchedShaderGlobals* bsg, Masked<int> result,
|
||||
ustring source, ustring name, MaskedData val) override;
|
||||
ustringhash source, ustringhash name,
|
||||
MaskedData val) override;
|
||||
|
||||
private:
|
||||
SimpleRenderer& m_sr;
|
||||
@@ -107,46 +110,56 @@ private:
|
||||
// imagine this to be fairly quick, but for a performance-critical
|
||||
// renderer, we would encourage benchmarking various methods and
|
||||
// alternate data structures.
|
||||
typedef bool (BatchedSimpleRenderer::*VaryingAttrGetter)(ustring object,
|
||||
ustring name,
|
||||
typedef bool (BatchedSimpleRenderer::*VaryingAttrGetter)(ustringhash object,
|
||||
ustringhash name,
|
||||
MaskedData val);
|
||||
typedef std::unordered_map<ustring, VaryingAttrGetter> VaryingAttrGetterMap;
|
||||
typedef std::unordered_map<ustringhash, VaryingAttrGetter>
|
||||
VaryingAttrGetterMap;
|
||||
VaryingAttrGetterMap m_varying_attr_getters;
|
||||
|
||||
typedef bool (BatchedSimpleRenderer::*UniformAttrGetter)(ustring object,
|
||||
ustring name,
|
||||
typedef bool (BatchedSimpleRenderer::*UniformAttrGetter)(ustringhash object,
|
||||
ustringhash name,
|
||||
RefData val);
|
||||
typedef std::unordered_map<ustring, UniformAttrGetter> UniformAttrGetterMap;
|
||||
typedef std::unordered_map<ustringhash, UniformAttrGetter>
|
||||
UniformAttrGetterMap;
|
||||
UniformAttrGetterMap m_uniform_attr_getters;
|
||||
|
||||
// Attribute getters
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_osl_version(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_osl_version(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_resolution(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_resolution(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_projection(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_projection(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_fov(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_fov(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_pixelaspect(ustring object, ustring name,
|
||||
bool get_camera_pixelaspect(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_clip(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_clip(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_clip_near(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_clip_near(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_clip_far(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_clip_far(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_shutter(ustring object, ustring name, RefOrMaskedT data);
|
||||
bool get_camera_shutter(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_shutter_open(ustring object, ustring name,
|
||||
bool get_camera_shutter_open(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_shutter_close(ustring object, ustring name,
|
||||
bool get_camera_shutter_close(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
template<typename RefOrMaskedT>
|
||||
bool get_camera_screen_window(ustring object, ustring name,
|
||||
bool get_camera_screen_window(ustringhash object, ustringhash name,
|
||||
RefOrMaskedT data);
|
||||
};
|
||||
|
||||
|
||||
@@ -684,16 +684,16 @@ OptixGridRenderer::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*
|
||||
OptixGridRenderer::get_texture_handle(ustring filename OSL_MAYBE_UNUSED,
|
||||
ShadingContext* shading_context
|
||||
OSL_MAYBE_UNUSED)
|
||||
OptixGridRenderer::get_texture_handle(ustringhash filename,
|
||||
ShadingContext* /*shading_context*/)
|
||||
{
|
||||
auto itr = m_samplers.find(filename);
|
||||
if (itr == m_samplers.end()) {
|
||||
// Open image
|
||||
OIIO::ImageBuf image;
|
||||
if (!image.init_spec(filename, 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {}", filename);
|
||||
if (!image.init_spec(ustring_from(filename), 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {} (hash {})",
|
||||
ustring_from(filename), filename);
|
||||
return (TextureHandle*)nullptr;
|
||||
}
|
||||
|
||||
@@ -874,7 +874,7 @@ OptixGridRenderer::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,
|
||||
dst += snprintf(&buffer[dst], BufferSize - dst, "%s",
|
||||
fmt_string.c_str());
|
||||
format_end_found = true;
|
||||
break;
|
||||
|
||||
@@ -25,10 +25,10 @@ public:
|
||||
OptixGridRenderer();
|
||||
virtual ~OptixGridRenderer();
|
||||
|
||||
uint64_t register_global(const std::string& str, uint64_t value);
|
||||
bool fetch_global(const std::string& str, uint64_t* value);
|
||||
uint64_t register_global(const std::string& str, uint64_t value) override;
|
||||
bool fetch_global(const std::string& str, uint64_t* value) override;
|
||||
|
||||
virtual int supports(string_view feature) const
|
||||
int supports(string_view feature) const override
|
||||
{
|
||||
if (feature == "OptiX")
|
||||
return true;
|
||||
@@ -38,15 +38,15 @@ public:
|
||||
std::string load_ptx_file(string_view filename);
|
||||
bool synch_attributes();
|
||||
|
||||
virtual void init_shadingsys(ShadingSystem* ss);
|
||||
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();
|
||||
void init_shadingsys(ShadingSystem* ss) final;
|
||||
bool init_optix_context(int xres, int yres);
|
||||
bool make_optix_materials();
|
||||
bool finalize_scene();
|
||||
void prepare_render() final;
|
||||
void warmup() final;
|
||||
void render(int xres, int yres) final;
|
||||
void finalize_pixel_buffer() final;
|
||||
void clear() final;
|
||||
|
||||
virtual void set_transforms(const OSL::Matrix44& object2common,
|
||||
const OSL::Matrix44& shader2common);
|
||||
@@ -56,12 +56,12 @@ public:
|
||||
/// 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* handle);
|
||||
bool good(TextureHandle* handle) override;
|
||||
|
||||
/// 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* shading_context);
|
||||
TextureHandle* get_texture_handle(ustringhash filename,
|
||||
ShadingContext* shading_context) override;
|
||||
|
||||
OptixDeviceContext optix_ctx() { return m_optix_ctx; }
|
||||
OptixDeviceContext context() { return m_optix_ctx; }
|
||||
@@ -90,8 +90,8 @@ private:
|
||||
const unsigned long OSL_PRINTF_BUFFER_SIZE = 8 * 1024 * 1024;
|
||||
|
||||
std::string m_materials_ptx;
|
||||
std::unordered_map<OIIO::ustring, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<OIIO::ustring, uint64_t> m_globals_map;
|
||||
std::unordered_map<ustringhash, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<ustringhash, uint64_t> m_globals_map;
|
||||
|
||||
OSL::Matrix44 m_shader2common; // "shader" space to "common" space matrix
|
||||
OSL::Matrix44 m_object2common; // "object" space to "common" space matrix
|
||||
|
||||
@@ -45,6 +45,7 @@ enum ClosureIDs {
|
||||
TRANSPARENT_ID,
|
||||
DEBUG_ID,
|
||||
HOLDOUT_ID,
|
||||
PARAMETER_TEST_ID,
|
||||
};
|
||||
|
||||
// these structures hold the parameters of each closure type
|
||||
@@ -84,6 +85,23 @@ struct MicrofacetParams {
|
||||
struct DebugParams {
|
||||
ustring tag;
|
||||
};
|
||||
struct ParameterTestParams {
|
||||
int int_param;
|
||||
float float_param;
|
||||
Color3 color_param;
|
||||
Vec3 vector_param;
|
||||
ustring string_param;
|
||||
int int_array[5];
|
||||
Vec3 vector_array[5];
|
||||
Color3 color_array[5];
|
||||
float float_array[5];
|
||||
ustring string_array[5];
|
||||
int int_key;
|
||||
float float_key;
|
||||
Color3 color_key;
|
||||
Vec3 vector_key;
|
||||
ustring string_key;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@@ -170,7 +188,27 @@ register_closures(OSL::ShadingSystem* shadingsys)
|
||||
DEBUG_ID,
|
||||
{ CLOSURE_STRING_PARAM(DebugParams, tag),
|
||||
CLOSURE_FINISH_PARAM(DebugParams) } },
|
||||
{ "holdout", HOLDOUT_ID, { CLOSURE_FINISH_PARAM(EmptyParams) } }
|
||||
{ "holdout", HOLDOUT_ID, { CLOSURE_FINISH_PARAM(EmptyParams) } },
|
||||
{ "parameter_test",
|
||||
PARAMETER_TEST_ID,
|
||||
{ CLOSURE_INT_PARAM(ParameterTestParams, int_param),
|
||||
CLOSURE_FLOAT_PARAM(ParameterTestParams, float_param),
|
||||
CLOSURE_COLOR_PARAM(ParameterTestParams, color_param),
|
||||
CLOSURE_VECTOR_PARAM(ParameterTestParams, vector_param),
|
||||
CLOSURE_STRING_PARAM(ParameterTestParams, string_param),
|
||||
CLOSURE_INT_ARRAY_PARAM(ParameterTestParams, int_array, 5),
|
||||
CLOSURE_VECTOR_ARRAY_PARAM(ParameterTestParams, vector_array, 5),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(ParameterTestParams, color_array, 5),
|
||||
CLOSURE_FLOAT_ARRAY_PARAM(ParameterTestParams, float_array, 5),
|
||||
CLOSURE_STRING_ARRAY_PARAM(ParameterTestParams, string_array, 5),
|
||||
CLOSURE_INT_KEYPARAM(ParameterTestParams, int_key, "int_key"),
|
||||
CLOSURE_FLOAT_KEYPARAM(ParameterTestParams, float_key, "float_key"),
|
||||
CLOSURE_COLOR_KEYPARAM(ParameterTestParams, color_key, "color_key"),
|
||||
CLOSURE_VECTOR_KEYPARAM(ParameterTestParams, vector_key,
|
||||
"vector_key"),
|
||||
CLOSURE_STRING_KEYPARAM(ParameterTestParams, string_key,
|
||||
"string_key"),
|
||||
CLOSURE_FINISH_PARAM(ParameterTestParams) } }
|
||||
};
|
||||
|
||||
for (const auto& b : builtins)
|
||||
@@ -310,7 +348,7 @@ SimpleRenderer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustring from, float /*time*/)
|
||||
ustringhash from, float /*time*/)
|
||||
{
|
||||
TransformMap::const_iterator found = m_named_xforms.find(from);
|
||||
if (found != m_named_xforms.end()) {
|
||||
@@ -337,7 +375,7 @@ SimpleRenderer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustring from)
|
||||
ustringhash from)
|
||||
{
|
||||
// SimpleRenderer doesn't understand motion blur, so we never fail
|
||||
// on account of time-varying transformations.
|
||||
@@ -354,7 +392,7 @@ SimpleRenderer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_inverse_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustring to, float /*time*/)
|
||||
ustringhash to, float /*time*/)
|
||||
{
|
||||
if (to == u_camera || to == u_screen || to == u_NDC || to == u_raster) {
|
||||
Matrix44 M = m_world_to_camera;
|
||||
@@ -408,15 +446,15 @@ void
|
||||
SimpleRenderer::name_transform(const char* name, const OSL::Matrix44& xform)
|
||||
{
|
||||
std::shared_ptr<Transformation> M(new OSL::Matrix44(xform));
|
||||
m_named_xforms[ustring(name)] = M;
|
||||
m_named_xforms[ustringhash(name)] = M;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
int index, void* val)
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val)
|
||||
{
|
||||
AttrGetterMap::const_iterator g = m_attr_getters.find(name);
|
||||
if (g != m_attr_getters.end()) {
|
||||
@@ -444,8 +482,8 @@ SimpleRenderer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val)
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val)
|
||||
{
|
||||
return get_array_attribute(sg, derivatives, object, type, name, -1, val);
|
||||
}
|
||||
@@ -453,7 +491,7 @@ SimpleRenderer::get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_userdata(bool derivatives, ustring name, TypeDesc type,
|
||||
SimpleRenderer::get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val)
|
||||
{
|
||||
// Just to illustrate how this works, respect s and t userdata, filled
|
||||
@@ -482,7 +520,7 @@ SimpleRenderer::get_userdata(bool derivatives, ustring name, TypeDesc type,
|
||||
size_t size = p->type().size();
|
||||
memcpy(val, p->data(), size);
|
||||
if (derivatives)
|
||||
memcpy(val, (char*)p->data() + size, 2 * size);
|
||||
memset((char*)val + size, 0, 2 * size);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -508,10 +546,14 @@ SimpleRenderer::trace(TraceOpt& options, ShaderGlobals* sg, const OSL::Vec3& P,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::getmessage(ShaderGlobals* sg, ustring source, ustring name,
|
||||
TypeDesc type, void* val, bool derivatives)
|
||||
SimpleRenderer::getmessage(ShaderGlobals* sg, ustringhash source_,
|
||||
ustringhash name_, TypeDesc type, void* val,
|
||||
bool derivatives)
|
||||
{
|
||||
ustring source = ustring_from(source_);
|
||||
ustring name = ustring_from(name_);
|
||||
OSL_ASSERT(source == ustring("trace"));
|
||||
// Don't have any real ray tracing results
|
||||
// so just fill in some repeatable values for testsuite
|
||||
@@ -552,10 +594,11 @@ SimpleRenderer::getmessage(ShaderGlobals* sg, ustring source, ustring name,
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeInt) {
|
||||
((int*)val)[0] = OSL_VERSION;
|
||||
@@ -567,8 +610,8 @@ SimpleRenderer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeIntArray2) {
|
||||
((int*)val)[0] = m_xres;
|
||||
@@ -581,8 +624,8 @@ SimpleRenderer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeString) {
|
||||
((ustring*)val)[0] = m_projection;
|
||||
@@ -594,8 +637,8 @@ SimpleRenderer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
@@ -610,8 +653,8 @@ SimpleRenderer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_pixelaspect;
|
||||
@@ -625,8 +668,8 @@ SimpleRenderer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float*)val)[0] = m_hither;
|
||||
@@ -641,8 +684,8 @@ SimpleRenderer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_hither;
|
||||
@@ -656,8 +699,8 @@ SimpleRenderer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_yon;
|
||||
@@ -672,8 +715,8 @@ SimpleRenderer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float*)val)[0] = m_shutter[0];
|
||||
@@ -688,8 +731,8 @@ SimpleRenderer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_shutter[0];
|
||||
@@ -703,8 +746,8 @@ SimpleRenderer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_shutter[1];
|
||||
@@ -718,8 +761,8 @@ SimpleRenderer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_screen_window(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
if (type == TypeFloatArray4) {
|
||||
|
||||
+59
-54
@@ -40,35 +40,34 @@ public:
|
||||
// Ensure destructor is in .cpp
|
||||
~SimpleRenderer();
|
||||
|
||||
virtual int supports(string_view feature) const;
|
||||
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);
|
||||
int supports(string_view feature) const override;
|
||||
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;
|
||||
|
||||
void name_transform(const char* name, const Transformation& xform);
|
||||
|
||||
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);
|
||||
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 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);
|
||||
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) override;
|
||||
|
||||
virtual bool getmessage(ShaderGlobals* sg, ustring source, ustring name,
|
||||
TypeDesc type, void* val, bool derivatives);
|
||||
bool getmessage(ShaderGlobals* sg, ustringhash source, ustringhash name,
|
||||
TypeDesc type, void* val, bool derivatives) override;
|
||||
|
||||
|
||||
// Set and get renderer attributes/options
|
||||
@@ -143,11 +142,11 @@ public:
|
||||
OIIO::ParamValueList userdata;
|
||||
|
||||
#if OSL_USE_BATCHED
|
||||
virtual BatchedRendererServices<16>* batched(WidthOf<16>)
|
||||
BatchedRendererServices<16>* batched(WidthOf<16>) override
|
||||
{
|
||||
return &m_batch_16_simple_renderer;
|
||||
}
|
||||
virtual BatchedRendererServices<8>* batched(WidthOf<8>)
|
||||
BatchedRendererServices<8>* batched(WidthOf<8>) override
|
||||
{
|
||||
return &m_batch_8_simple_renderer;
|
||||
}
|
||||
@@ -172,7 +171,7 @@ protected:
|
||||
std::unique_ptr<OIIO::ErrorHandler> m_errhandler { new OIIO::ErrorHandler };
|
||||
|
||||
// Named transforms
|
||||
typedef std::map<ustring, std::shared_ptr<Transformation>> TransformMap;
|
||||
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
|
||||
TransformMap m_named_xforms;
|
||||
|
||||
// Attribute and userdata retrieval -- for fast dispatch, use a hash
|
||||
@@ -181,38 +180,44 @@ protected:
|
||||
// renderer, we would encourage benchmarking various methods and
|
||||
// alternate data structures.
|
||||
typedef bool (SimpleRenderer::*AttrGetter)(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, void* val);
|
||||
typedef std::unordered_map<ustring, AttrGetter> AttrGetterMap;
|
||||
ustringhash object,
|
||||
TypeDesc type, ustringhash name,
|
||||
void* val);
|
||||
typedef std::unordered_map<ustringhash, AttrGetter> AttrGetterMap;
|
||||
AttrGetterMap m_attr_getters;
|
||||
|
||||
// Attribute getters
|
||||
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_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_camera_shutter_close(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_screen_window(ShaderGlobals* sg, bool derivs,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
};
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -71,7 +71,7 @@ def run_binary_tests (opname) :
|
||||
return
|
||||
|
||||
# Run binary tests with mixing combinations of varying(v), uniform(u), and constant(c) parameters.
|
||||
# Test with constants to pass non-deriviative parameters to functions
|
||||
# Test with constants to pass non-derivative parameters to functions
|
||||
# Choose not to test variation of 2 constant argument, as that should be constant folded
|
||||
run_binary_tests ("fmod")
|
||||
run_binary_tests ("fmod_u_u")
|
||||
@@ -82,6 +82,15 @@ run_binary_tests ("fmod_c_v")
|
||||
run_binary_tests ("fmod_u_c")
|
||||
run_binary_tests ("fmod_c_u")
|
||||
|
||||
run_binary_tests ("fmod_u_u_float")
|
||||
run_binary_tests ("fmod_v_u_float")
|
||||
run_binary_tests ("fmod_u_v_float")
|
||||
run_binary_tests ("fmod_v_v_float")
|
||||
run_binary_tests ("fmod_v_c_float")
|
||||
run_binary_tests ("fmod_c_v_float")
|
||||
run_binary_tests ("fmod_u_c_float")
|
||||
run_binary_tests ("fmod_c_u_float")
|
||||
|
||||
run_binary_tests ("step")
|
||||
run_binary_tests ("step_u_u")
|
||||
run_binary_tests ("step_v_u")
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_c_u_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_CONSTANT_IN
|
||||
#define __OSL_XMACRO_UNIFORM_IN2
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_c_v_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_CONSTANT_IN
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_u_c_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_UNIFORM_IN
|
||||
#define __OSL_XMACRO_CONSTANT_IN2
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_u_u_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_UNIFORM_IN
|
||||
#define __OSL_XMACRO_UNIFORM_IN2
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_u_v_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_UNIFORM_IN
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_v_c_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_CONSTANT_IN2
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_v_u_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
#define __OSL_XMACRO_UNIFORM_IN2
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#define __OSL_XMACRO_OPNAME fmod_v_v_float
|
||||
#define __OSL_XMACRO_OP fmod
|
||||
|
||||
#include "../common/shaders/test_binary_mixed_triple_float_xmacro.h"
|
||||
@@ -0,0 +1,7 @@
|
||||
Compiled test.osl -> test.oso
|
||||
Ci = (1, 0, 0) * emission ()
|
||||
Ci = (1, 0, 0) * emission ()
|
||||
Ci = (1, 0, 0) * emission ()
|
||||
Ci = (0.75, 0.75, 0.75) * emission ()
|
||||
Ci = (1, 1, 1) * emission ()
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
command = testshade("-g 5 1 test")
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
shader
|
||||
test()
|
||||
{
|
||||
if (u > 0.5) {
|
||||
Ci = u * emission();
|
||||
} else {
|
||||
Ci = color(1, 0, 0) * emission();
|
||||
}
|
||||
|
||||
printf(" Ci = %s\n", Ci);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
Compiled test.osl -> test.oso
|
||||
Ci = (1, 1, 1) * parameter_test (30, 31, (32, 33, 34), (35, 36, 37), "testString", [6, 7, 8, 101, 102], [(9, 10, 11), (12, 13, 14), (15, 16, 17), (103, 104, 105), (106, 107, 108)], [(18, 19, 20), (21, 22, 23), (24, 25, 26), (109, 110, 111), (112, 113, 114)], [27, 28, 29, 115, 116], ["a", "b", "testString", "more", "words"], "int_key", 38, "float_key", 39, "color_key", (40, 41, 42), "vector_key", (43, 44, 45), "string_key", "keywordTestString")
|
||||
Ci = (1, 1, 1) * parameter_test (0, 0, (0, 0, 0.3), (0.2, 0, 0), "0.000000", [0, 0, 7, 117, 0], [(0.1, 0.1, 0.1), (0.2, 0, 0), (42, 42, 42), (118, 119, 120), (0, 0, 121)], [(0, 0, 0), (0, 0, 0.3), (0, 0, 0), (122, 123, 124), (0, 0, 0)], [0, 0, 0.7, 0.8, 0], ["a", "b", "0.000000", "more", "0.000000"], "int_key", 0, "float_key", 0, "color_key", (0, 0, 0.3), "vector_key", (0.2, 0, 0), "string_key", "0.000000")
|
||||
Ci = (1, 1, 1) * parameter_test (30, 31, (32, 33, 34), (35, 36, 37), "testString", [6, 7, 8, 101, 102], [(9, 10, 11), (12, 13, 14), (15, 16, 17), (103, 104, 105), (106, 107, 108)], [(18, 19, 20), (21, 22, 23), (24, 25, 26), (109, 110, 111), (112, 113, 114)], [27, 28, 29, 115, 116], ["a", "b", "testString", "more", "words"], "int_key", 38, "float_key", 39, "color_key", (40, 41, 42), "vector_key", (43, 44, 45), "string_key", "keywordTestString")
|
||||
Ci = (1, 1, 1) * parameter_test (10, 1, (1, 0, 0.3), (0.2, 1, 0), "1.000000", [10, 0, 7, 117, 10], [(0.1, 0.1, 0.1), (0.2, 1, 0), (42, 42, 42), (118, 119, 120), (0, 1, 121)], [(1, 1, 1), (1, 0, 0.3), (0, 0, 0), (122, 123, 124), (1, 1, 1)], [1, 0, 0.7, 0.8, 1], ["a", "b", "1.000000", "more", "0.000000"], "int_key", 10, "float_key", 1, "color_key", (1, 0, 0.3), "vector_key", (0.2, 1, 0), "string_key", "1.000000")
|
||||
Ci = (1, 1, 1) * parameter_test (30, 31, (32, 33, 34), (35, 36, 37), "testString", [6, 7, 8, 101, 102], [(9, 10, 11), (12, 13, 14), (15, 16, 17), (103, 104, 105), (106, 107, 108)], [(18, 19, 20), (21, 22, 23), (24, 25, 26), (109, 110, 111), (112, 113, 114)], [27, 28, 29, 115, 116], ["a", "b", "testString", "more", "words"], "int_key", 38, "float_key", 39, "color_key", (40, 41, 42), "vector_key", (43, 44, 45), "string_key", "keywordTestString")
|
||||
Ci = (1, 1, 1) * parameter_test (0, 0, (0, 1, 0.3), (0.2, 0, 1), "0.000000", [0, 10, 7, 117, 10], [(0.1, 0.1, 0.1), (0.2, 0, 1), (42, 42, 42), (118, 119, 120), (1, 0, 121)], [(0, 0, 0), (0, 1, 0.3), (1, 1, 1), (122, 123, 124), (1, 1, 1)], [0, 1, 0.7, 0.8, 1], ["a", "b", "0.000000", "more", "1.000000"], "int_key", 0, "float_key", 0, "color_key", (0, 1, 0.3), "vector_key", (0.2, 0, 1), "string_key", "0.000000")
|
||||
Ci = (1, 1, 1) * parameter_test (30, 31, (32, 33, 34), (35, 36, 37), "testString", [6, 7, 8, 101, 102], [(9, 10, 11), (12, 13, 14), (15, 16, 17), (103, 104, 105), (106, 107, 108)], [(18, 19, 20), (21, 22, 23), (24, 25, 26), (109, 110, 111), (112, 113, 114)], [27, 28, 29, 115, 116], ["a", "b", "testString", "more", "words"], "int_key", 38, "float_key", 39, "color_key", (40, 41, 42), "vector_key", (43, 44, 45), "string_key", "keywordTestString")
|
||||
Ci = (1, 1, 1) * parameter_test (10, 1, (1, 1, 0.3), (0.2, 1, 1), "1.000000", [10, 10, 7, 117, 20], [(0.1, 0.1, 0.1), (0.2, 1, 1), (42, 42, 42), (118, 119, 120), (1, 1, 121)], [(1, 1, 1), (1, 1, 0.3), (1, 1, 1), (122, 123, 124), (2, 2, 2)], [1, 1, 0.7, 0.8, 2], ["a", "b", "1.000000", "more", "1.000000"], "int_key", 10, "float_key", 1, "color_key", (1, 1, 0.3), "vector_key", (0.2, 1, 1), "string_key", "1.000000")
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
command = testshade("-g 2 2 test")
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
closure color
|
||||
parameter_test(int int_param, float float_param, color color_param,
|
||||
vector vector_param, string string_param, int int_array[5],
|
||||
vector vector_array[5], color color_array[5],
|
||||
float float_array[5], string string_array[5])[[int builtin = 1]];
|
||||
|
||||
shader
|
||||
test()
|
||||
{
|
||||
// Test all parameter types with uniform values
|
||||
int a[5] = { 6, 7, 8, 101, 102 };
|
||||
vector b[5] = { vector(9, 10, 11), vector(12, 13, 14), vector(15, 16, 17),
|
||||
vector(103, 104, 105), vector(106, 107, 108) };
|
||||
color c[5] = { color(18, 19, 20), color(21, 22, 23), color(24, 25, 26),
|
||||
color(109, 110, 111), color(112, 113, 114) };
|
||||
float d[5] = { 27, 28, 29, 115, 116 };
|
||||
string e[5] = { "a", "b", "testString", "more", "words" };
|
||||
|
||||
Ci = parameter_test(30, 31.0, color(32, 33, 34), vector(35, 36, 37),
|
||||
"testString", a, b, c, d, e, "int_key", 38, "float_key",
|
||||
39.0, "color_key", color(40, 41, 42), "vector_key",
|
||||
vector(43, 44, 45), "string_key", "keywordTestString");
|
||||
printf(" Ci = %s\n", Ci);
|
||||
|
||||
// Test all parameter types with varying values
|
||||
int a2[5] = { int(u * 10), int(v * 10), 7, 117, int((u + v) * 10) };
|
||||
vector b2[5] = { vector(0.1), vector(0.2, u, v), vector(42.0),
|
||||
vector(118, 119, 120), vector(v, u, 121) };
|
||||
color c2[5] = { color(u), color(u, v, 0.3), color(v), color(122, 123, 124),
|
||||
color(u + v) };
|
||||
float d2[5] = { u, v, 0.7, 0.8, v + u };
|
||||
string e2[5] = { "a", "b", format("%f", u), "more", format("%f", v) };
|
||||
|
||||
Ci = parameter_test(int(u * 10), u, color(u, v, 0.3), vector(0.2, u, v),
|
||||
format("%f", u), a2, b2, c2, d2, e2, "int_key",
|
||||
int(u * 10), "float_key", u, "color_key",
|
||||
color(u, v, 0.3), "vector_key", vector(0.2, u, v),
|
||||
"string_key", format("%f", u));
|
||||
printf(" Ci = %s\n", Ci);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user