Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4db549061 | ||
|
|
4debd96adc | ||
|
|
30a4a95b7e | ||
|
|
a38aa58c0e | ||
|
|
e126a20df7 | ||
|
|
52cf2ee418 | ||
|
|
83a1e7e74b |
@@ -37,7 +37,8 @@ jobs:
|
||||
include:
|
||||
- desc: sonar gcc9/C++14 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: static-analysis-sonar
|
||||
os: ubuntu-latest
|
||||
os: ubuntu-20.04-8c-32g-300h
|
||||
# os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
cxx_std: 14
|
||||
@@ -76,6 +77,7 @@ jobs:
|
||||
PYTHON_VERSION: ${{matrix.python_ver}}
|
||||
USE_BATCHED: ${{matrix.batched}}
|
||||
USE_SIMD: ${{matrix.simd}}
|
||||
PARALLEL: 24
|
||||
# DEBUG_CI: 1
|
||||
steps:
|
||||
# We would like to use harden-runner, but it flags too many false
|
||||
|
||||
+20
-21
@@ -20,13 +20,16 @@ on:
|
||||
- '**.rst'
|
||||
- '**.tex'
|
||||
schedule:
|
||||
# Full nightly build, for the main project repo (not for forks)
|
||||
# Full nightly build
|
||||
- cron: "0 6 * * *"
|
||||
if: github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
|
||||
|
||||
|
||||
permissions: read-all
|
||||
|
||||
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -47,7 +50,7 @@ jobs:
|
||||
pybind11_ver: v2.4.2
|
||||
- desc: clang9/C++14 llvm9 oiio-release boost1.66 avx2 exr2.3 py2.7
|
||||
nametag: linux-clang9-llvm9
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-18.04
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang9
|
||||
cc_compiler: clang
|
||||
@@ -68,8 +71,7 @@ jobs:
|
||||
# pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
skip_tests: 1
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=8.1.1
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
- desc: gcc6/C++14 llvm10 py3.7 boost1.70 exr2.4 oiio2.2 sse4
|
||||
nametag: linux-vfx2020
|
||||
os: ubuntu-latest
|
||||
@@ -114,11 +116,11 @@ jobs:
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: USE_OPENVDB=0
|
||||
- desc: icc/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
- desc: icc/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
nametag: linux-icc
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang14
|
||||
vfxsuffix: -clang13
|
||||
cc_compiler: icc
|
||||
cxx_compiler: icpc
|
||||
cxx_std: 17
|
||||
@@ -131,11 +133,11 @@ jobs:
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DSTOP_ON_WARNING=OFF -DEXTRA_CPP_ARGS=-fp-model=consistent"
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=7.1.3
|
||||
USE_OPENVDB=0
|
||||
- desc: icx/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
- desc: icx/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: linux-icx
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang14
|
||||
vfxsuffix: -clang13
|
||||
cc_compiler: icx
|
||||
cxx_compiler: icpx
|
||||
cxx_std: 17
|
||||
@@ -290,7 +292,7 @@ jobs:
|
||||
include:
|
||||
- desc: Debug gcc7/C++14 llvm9 py2.7 oiio2.3 exr2.4 sse4 boost1.65 exr2.4
|
||||
nametag: linux-debug-gcc7-llvm9
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-18.04
|
||||
cxx_compiler: g++-7
|
||||
cxx_std: 14
|
||||
openexr_ver: v2.4.3
|
||||
@@ -304,7 +306,7 @@ jobs:
|
||||
CTEST_TEST_TIMEOUT=240
|
||||
- desc: gcc10/C++17 llvm10 oiio-release boost1.65 exr2.5 avx2
|
||||
nametag: linux-2021ish-gcc10-llvm10
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-18.04
|
||||
cxx_compiler: g++-10
|
||||
cxx_std: 17
|
||||
fmt_ver: 7.0.1
|
||||
@@ -318,20 +320,20 @@ jobs:
|
||||
PUGIXML_VERSION=v1.10
|
||||
- desc: latest releases gcc11/C++17 llvm13 boost1.71 exr3.1 py3.9 avx2 batch-b16avx512
|
||||
nametag: linux-latest-releases
|
||||
os: ubuntu-22.04
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-11
|
||||
cxx_std: 17
|
||||
fmt_ver: 9.1.0
|
||||
openexr_ver: v3.1.7
|
||||
openexr_ver: v3.1.5
|
||||
openimageio_ver: master
|
||||
pybind11_ver: v2.10.0
|
||||
python_ver: "3.10"
|
||||
python_ver: 3.9
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: export LLVM_VERSION=13.0.0
|
||||
LLVM_DISTRO_NAME=ubuntu-20.04
|
||||
OPENCOLORIO_VERSION=v2.2.0
|
||||
PUGIXML_VERSION=v1.13
|
||||
OPENCOLORIO_VERSION=v2.1.2
|
||||
PUGIXML_VERSION=v1.11.4
|
||||
- desc: bleeding edge gcc12/C++17 llvm14 oiio/ocio/exr/pybind-master boost1.71 py3.10 avx2 batch-b16avx512
|
||||
nametag: linux-bleeding-edge
|
||||
os: ubuntu-22.04
|
||||
@@ -355,7 +357,7 @@ jobs:
|
||||
cc_compiler: clang
|
||||
cxx_std: 17
|
||||
fmt_ver: 8.1.1
|
||||
openexr_ver: v3.1.7
|
||||
openexr_ver: v3.1.5
|
||||
openimageio_ver: master
|
||||
pybind11_ver: v2.9.2
|
||||
python_ver: 3.8
|
||||
@@ -435,8 +437,6 @@ jobs:
|
||||
python_ver: "3.10"
|
||||
aclang: 13
|
||||
setenvs: export LLVMBREWVER="@14" DO_BREW_UPDATE=1
|
||||
OPENIMAGEIO_VERSION=release
|
||||
QT_BREW_VERSION="@5"
|
||||
- desc: MacOS-12
|
||||
os: macos-12
|
||||
nametag: macos11-p310
|
||||
@@ -446,7 +446,6 @@ jobs:
|
||||
python_ver: "3.10"
|
||||
aclang: 13
|
||||
setenvs: export LLVMBREWVER="@15" DO_BREW_UPDATE=1
|
||||
OPENIMAGEIO_VERSION=master
|
||||
runs-on: ${{matrix.os}}
|
||||
env:
|
||||
CXX: ${{matrix.cxx_compiler}}
|
||||
|
||||
@@ -10,23 +10,18 @@ on:
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecards analysis
|
||||
if: |
|
||||
github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Used to receive a badge. (Upcoming feature)
|
||||
id-token: write
|
||||
# Needs for private repositories.
|
||||
contents: read
|
||||
actions: read
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
|
||||
@@ -5,14 +5,13 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
|
||||
- Existing Project Governance
|
||||
- [X] Project License exists ( [LICENSE.md](../LICENSE.md) ) and is OSI-approved
|
||||
- [X] Any third-party components/dependencies included are listed along with their licenses ( [THIRD_PARTY.md](../THIRD_PARTY.md) )
|
||||
- [X] Governance defined, outlining community roles and how decisions are made ( [GOVERNANCE.md](../GOVERNANCE.md) )
|
||||
- [X] Governance defined, outlining community roles and how decsions are made ( [GOVERNANCE.md](../GOVERNANCE.md] )
|
||||
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
|
||||
- [X] Contribution Policy defined ( [CONTRIBUTING.md](../CONTRIBUTING.md) )
|
||||
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
|
||||
- [X] Code of Conduct defined ( existing or pull from [ASWF Sample Project](https://github.com/AcademySoftwareFoundation/aswf-sample-project/blob/master/CODE_OF_CONDUCT.md) )
|
||||
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1137
|
||||
- [X] Release methodology defined ( [RELEASING.md](../docs/RELEASING.md) )
|
||||
- Closed by https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1572
|
||||
- [ ] Release methodology defined ( [release.md](process/release.md) )
|
||||
- New Project Governance
|
||||
- [X] TSC members identified
|
||||
- [X] First TSC meeting held
|
||||
@@ -42,7 +41,7 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
|
||||
- [X] New project announcement done ( https://www.aswf.io/osl-joins-aswf/ )
|
||||
- [X] Project added to ASWF website and ASWF landscape
|
||||
- Graduation
|
||||
- [X] OpenSSF Best Practices Badge achieved
|
||||
- [ ] CII Badge achieved
|
||||
- [ ] Committer Diversity established
|
||||
- [ ] Commit/Contribution growth during incubation
|
||||
- [ ] Committers defined in the project ( [COMMITTERS.csv](COMMITTERS.csv) or [COMMITTERS.yml](COMMITTERS.yml) )
|
||||
|
||||
+1
-68
@@ -23,10 +23,6 @@ API changes, new options, new ShadingSystem features (for renderer writers):
|
||||
SIMD batched shading mode:
|
||||
* Fix some array overruns (asymptomatic, but still potentially buggy) in
|
||||
common_ancestor_between. #1577 (1.13.0.2)
|
||||
* Fix issue with closure keyword parameters. #1620 (1.13.2.0/1.12.8.0)
|
||||
* Fix crash when adding a default initialized closure. #1624
|
||||
(1.13.2.0/1.12.8.0)
|
||||
* Fix support for closures with array types. #1630 (1.13.2.0/1.12.8.0)
|
||||
|
||||
OptiX rendering:
|
||||
* OptiX 6.0 support has been removed. For GPU rendering with OptiX, a minimum
|
||||
@@ -38,14 +34,6 @@ OptiX rendering:
|
||||
* Better PTX cache hit rate by eliminating several sources of not being
|
||||
strictly deterministic in the PTX text we were generating. #1566 #1570
|
||||
(1.13.0.1)
|
||||
* Fix PTX symbol visibility issues. #1609 (1.13.2.0)
|
||||
* Hide more code that is only used for OptiX mode, when OptiX is disabled.
|
||||
#1608 (1.13.2.0)
|
||||
* Remove dependency on OptiX SDK for building core OSL with OptiX support. You
|
||||
can now build OSL with OptiX support enabled even if you don't have the
|
||||
OptiX SDK headers present at build time. But you will still need them to
|
||||
build your OptiX-based application that uses OSL for GPU rendering. #1627
|
||||
(1.13.2.0/1.12.8.0)
|
||||
|
||||
Performance improvements:
|
||||
|
||||
@@ -56,82 +44,27 @@ Bug fixes and other improvements (internals):
|
||||
Internals/developer concerns:
|
||||
* platform.h:
|
||||
- New `OSL_ALLOCA` macro to allocate on the stack. #1589 (1.13.0.3)
|
||||
- Define OSL::bitcast utility. #1610 (1.13.2.0)
|
||||
* Make sure that std::hash is defined for ustring and ustringhash. #1599
|
||||
(1.13.1.1)
|
||||
* Deprecate LLVMUtil::internalize_module_functions. #1606 (1.13.1.0)
|
||||
* Work toward always representing strings in shaders as ustringhash rather
|
||||
than ustring: phase 1 #1603 phase2 #1612 (1.13.2.0)
|
||||
|
||||
Build & test system improvements:
|
||||
* CMake build system and scripts:
|
||||
- The version number is now a cache variable, and so can be overridden at
|
||||
build time using `-DOSL_VERSION=...`. Use with extreme caution! #1579
|
||||
(1.13.0.2) Revised again to reduce changes of user error in #1617
|
||||
(1.13.2.0/1.12.7.1)
|
||||
- Add clangSupport library as dependency to fix linker error on some
|
||||
platforms. #1613 (1.13.2.0/1.12.7.1)
|
||||
(1.13.0.2)
|
||||
* Dependency version support:
|
||||
- Fix some issues that came up with the new icx 2022.0 compiler. #1601
|
||||
(1.13.1.0)
|
||||
- Test against OpenColorIO 2.2. #1616 (1.13.2.0/1.12.7.1)
|
||||
* Testing and Continuous integration (CI) systems:
|
||||
- Dynamic analysis using address and leak sanitizers. #1581 (1.13.0.3)
|
||||
- `testshade --help` now prints TextureSystem options and all hardware
|
||||
information. #1584 (1.13.0.3)
|
||||
- Improvements to SonarCloud and coverage analysis. #1596 (1.13.0.3)
|
||||
#1607 (1.13.1.0)
|
||||
- Disabling the dso version of testshade for the coverage analysis test.
|
||||
#1604 (1.13.1.0)
|
||||
- Be sure to run pointcloud tests when partio is found. #1611 (1.13.2.0)
|
||||
- testshade: better testing of all closure parameter types. #1621
|
||||
(1.13.2.0/1.12.8.0)
|
||||
* Platform support:
|
||||
- Include `immintrin.h` only when needed. #1605 (1.13.1.0)
|
||||
|
||||
Documentation:
|
||||
* `doc/RELEASING.md` documents our release process and versioning policies.
|
||||
#1572 (1.13.0.2)
|
||||
|
||||
|
||||
Release 1.12.8.0 -- 3 Jan 2023 (compared to 1.12.7.1)
|
||||
-------------------------------------------------------
|
||||
* Remove dependency on OptiX SDK for building core OSL with OptiX support.
|
||||
You can now build OSL with OptiX support enabled even if you don't have the
|
||||
OptiX SDK headers present at build time. But you will still need them to
|
||||
build your OptiX-based application that uses OSL for GPU rendering. #1627
|
||||
* Batch mode: fix issue with closure keyword parameters. #1620
|
||||
* Batch mode: fix crash when adding a default initialized closure. #1624
|
||||
* Batch mode: Fix support for closures with array types. #1630
|
||||
* testshade: better testing of all closure parameter types. #1621
|
||||
* Fix various CI breaks as dependencies shifted. #1629 #1631 #1633
|
||||
|
||||
Release 1.12.7.1 -- 1 Dec 2022 (compared to 1.12.7.0)
|
||||
-------------------------------------------------------
|
||||
* Add clangSupport library as dependency to fix linker error on some
|
||||
platforms. #1613
|
||||
* Test against OpenColorIO 2.2. #1616
|
||||
* Build: Fix how version overrides work to reduce the chance of user mistakes.
|
||||
#1617
|
||||
|
||||
Release 1.12.7.0 -- 1 Nov 2022 (compared to 1.12.6.2)
|
||||
-------------------------------------------------------
|
||||
* Optix: Change naming of certain compiler-generated constants in a way that
|
||||
improves use of the PTX cache. #1570
|
||||
* Batch: Fix uninitialized members in ReadEvent internals. #1575
|
||||
* `testshade --help` now prints TextureSystem options and hardware info. #1584
|
||||
* oslc: Fix memory leak in ASTvariable_declaration. #1576
|
||||
* Fix memory leaks in light path expression code. #1593 #1594
|
||||
* Include the immintrin.h header only when needed. #1605
|
||||
* icx: Improvements to fix problems exposed by new icx 2022.2 compiler. #1601
|
||||
* Testing: CMake cache variables to control the testing timeout length. #1571
|
||||
* CI: Add a dynamic analysis test using address and leak sanitizers. #1581
|
||||
* CI: Now using SonarCloud static analysis. #1551
|
||||
* CI: Many improvements in testing code coverage #1607
|
||||
* CI: Make sure to run pointcloud tests when partio is found. #1611
|
||||
* Developers: platform.h now defines OSL_ALLOCA macro. #1589
|
||||
* Developers: platform.h now defines OSL::bitcast utility. #1610
|
||||
|
||||
Release 1.12 -- 1 Oct 2022 (compared to 1.11)
|
||||
----------------------------------------------
|
||||
Big Deal Changes:
|
||||
|
||||
+7
-16
@@ -4,14 +4,7 @@
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
|
||||
set (OSL_VERSION "1.13.4.0")
|
||||
set (OSL_VERSION_OVERRIDE "" CACHE STRING
|
||||
"Version override (use with caution)!")
|
||||
mark_as_advanced (OSL_VERSION_OVERRIDE)
|
||||
if (OSL_VERSION_OVERRIDE)
|
||||
set (OSL_VERSION ${OSL_VERSION_OVERRIDE})
|
||||
endif ()
|
||||
|
||||
set (OSL_VERSION "1.13.1.0" CACHE STRING "Version")
|
||||
project (OSL VERSION ${OSL_VERSION}
|
||||
LANGUAGES CXX C
|
||||
HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/OpenShadingLanguage")
|
||||
@@ -98,8 +91,7 @@ else ()
|
||||
endif ()
|
||||
option (OSL_BUILD_PLUGINS "Bool OSL plugins, for example OIIO plugin" ON)
|
||||
option (OSL_BUILD_SHADERS "Build shaders" ON)
|
||||
option (OSL_USE_OPTIX "Include OptiX support" OFF)
|
||||
message(STATUS "OSL_USE_OPTIX: ${OSL_USE_OPTIX}")
|
||||
option (USE_OPTIX "Include OptiX support" OFF)
|
||||
set (OPTIX_EXTRA_LIBS CACHE STRING "Extra lib targets needed for OptiX")
|
||||
set (CUDA_EXTRA_LIBS CACHE STRING "Extra lib targets needed for CUDA")
|
||||
set (CUDA_TARGET_ARCH "sm_60" CACHE STRING "CUDA GPU architecture (e.g. sm_50)")
|
||||
@@ -108,7 +100,6 @@ set (OSL_SHADER_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/shade
|
||||
set (OSL_PTX_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/ptx"
|
||||
CACHE STRING "Directory where OptiX PTX files will be installed")
|
||||
set (CMAKE_DEBUG_POSTFIX "" CACHE STRING "Library naming postfix for Debug builds (e.g., '_debug')")
|
||||
option (OSL_USTRINGREP_IS_HASH "Always use ustringhash for strings" OFF)
|
||||
|
||||
|
||||
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
|
||||
@@ -128,14 +119,14 @@ if (OIIO_FMATH_SIMD_FRIENDLY)
|
||||
add_definitions (-DOIIO_FMATH_SIMD_FRIENDLY=1)
|
||||
endif ()
|
||||
|
||||
if (USE_OPTIX)
|
||||
add_definitions ("-DOSL_USE_OPTIX=1")
|
||||
endif ()
|
||||
|
||||
# Define OSL_INTERNAL symbol only when building OSL itself, will not be
|
||||
# defined for downstream projects using OSL.
|
||||
add_definitions (-DOSL_INTERNAL=1)
|
||||
|
||||
# To make sure we aren't relying on deprecated OIIO features, we define
|
||||
# OIIO_DISABLE_DEPRECATED before including any OIIO headers.
|
||||
add_definitions (-DOIIO_DISABLE_DEPRECATED=1)
|
||||
|
||||
# Set the default namespace. For symbol hiding reasons, it's important that
|
||||
# the project name is a subset of the namespace name.
|
||||
set (${PROJ_NAME}_NAMESPACE ${PROJECT_NAME} CACHE STRING
|
||||
@@ -223,7 +214,7 @@ if (OSL_BUILD_PLUGINS)
|
||||
add_subdirectory (src/osl.imageio)
|
||||
endif ()
|
||||
|
||||
if (USE_QT AND (Qt5_FOUND OR Qt6_FOUND))
|
||||
if (USE_QT AND Qt5_FOUND)
|
||||
add_subdirectory (src/osltoy)
|
||||
endif ()
|
||||
|
||||
|
||||
+7
-8
@@ -12,11 +12,11 @@ Dependencies
|
||||
OSL requires the following dependencies or tools.
|
||||
NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
|
||||
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.26)
|
||||
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.24)
|
||||
|
||||
* A suitable C++14 or C++17 compiler to build OSL itself, which may be any of:
|
||||
- GCC 6.1 or newer (tested through gcc 12.1)
|
||||
- Clang 3.4 or newer (tested through clang 16)
|
||||
- Clang 3.4 or newer (tested through clang 15)
|
||||
- Microsoft Visual Studio 2017 or newer
|
||||
- Intel C++ compiler icc version 17 or newer or LLVM-based icx compiler
|
||||
version 2022 or newer.
|
||||
@@ -41,14 +41,13 @@ NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
DYLD_LIBRARY_PATH on OS X).
|
||||
|
||||
* [LLVM](http://www.llvm.org) 9, 10, 11, 12, 13, 14, or 15, including
|
||||
clang libraries. LLVM 16 doesn't work yet, we need to make changes
|
||||
on the OSL side to be compatible.
|
||||
clang libraries.
|
||||
|
||||
* (optional) For GPU rendering on NVIDIA GPUs:
|
||||
* [OptiX](https://developer.nvidia.com/rtx/ray-tracing/optix) 7.0 or higher.
|
||||
* [Cuda](https://developer.nvidia.com/cuda-downloads) 8.0 or higher.
|
||||
|
||||
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.81)
|
||||
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.80)
|
||||
* [Ilmbase or Imath](https://github.com/AcademySoftwareFoundation/openexr) 2.3
|
||||
or newer (recommended: 2.4 or higher; tested through 3.1)
|
||||
* [Flex](https://github.com/westes/flex) 2.5.35 or newer and
|
||||
@@ -56,7 +55,7 @@ NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
Note that on some MacOS/xcode releases, the system-installed Bison is too
|
||||
old, and it's better to install a newer Bison (via Homebrew is one way to
|
||||
do this easily).
|
||||
* [PugiXML](http://pugixml.org/) >= 1.8 (we have tested through 1.13).
|
||||
* [PugiXML](http://pugixml.org/)
|
||||
* (optional) [Partio](https://www.disneyanimation.com/technology/partio.html)
|
||||
If it is not found at build time, the OSL `pointcloud` functions will not
|
||||
be operative.
|
||||
@@ -65,8 +64,8 @@ NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
* Python >= 2.7 (tested against 2.7, 3.7, 3.8, 3.9, 3.10)
|
||||
* pybind11 >= 2.4.2 (Tested through 2.10)
|
||||
* NumPy
|
||||
* (optional) Qt5 >= 5.6 or Qt6 (tested Qt5 through 5.15 and Qt6 through 6.4).
|
||||
If not found at build time, the `osltoy` application will be disabled.
|
||||
* (optional) Qt >= 5.6 (tested through 5.15). If not found at build time,
|
||||
the `osltoy` application will be disabled.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -209,10 +209,7 @@ ifneq (${BUILD_MISSING_DEPS},)
|
||||
endif
|
||||
|
||||
ifneq (${USE_OPTIX},)
|
||||
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX:BOOL=${USE_OPTIX}
|
||||
endif
|
||||
ifneq (${OSL_USE_OPTIX},)
|
||||
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX:BOOL=${OSL_USE_OPTIX}
|
||||
MY_CMAKE_FLAGS += -DUSE_OPTIX:BOOL=${USE_OPTIX}
|
||||
endif
|
||||
|
||||
ifneq (${USE_PYTHON},)
|
||||
@@ -400,7 +397,7 @@ help:
|
||||
@echo " USE_SIMD=arch Build with SIMD support (comma-separated choices:"
|
||||
@echo " 0, sse2, sse3, ssse3, sse4.1, sse4.2, f16c,"
|
||||
@echo " avx, avx2, avx512f)"
|
||||
@echo " OSL_USE_OPTIX=1 Build the OptiX test renderer"
|
||||
@echo " USE_OPTIX=1 Build the OptiX test renderer"
|
||||
@echo " USE_BATCHED=targets Build batched SIMD execution of shaders for (comma-separated choices:"
|
||||
@echo " 0, b8_AVX, b8_AVX2, b8_AVX2_noFMA,"
|
||||
@echo " b8_AVX512, b8_AVX512_noFMA,"
|
||||
|
||||
@@ -225,7 +225,8 @@ adding OSL support):
|
||||
* [Blender/Cycles](https://docs.blender.org/manual/en/dev/render/shader_nodes/osl.html)
|
||||
* [Chaos Group: V-Ray](https://www.chaosgroup.com/)
|
||||
* [Pixar: PhotoRealistic RenderMan RIS](https://renderman.pixar.com)
|
||||
* Isotropix: [Clarisse iFX](https://www.isotropix.com/products/clarisse/ifx) / [Clarisse BUiLDER](https://www.isotropix.com/products/clarisse/builder) / [Angie](https://www.isotropix.com/products/angie)
|
||||
* [Isotropix: Clarisse](http://www.isotropix.com/clarisse)
|
||||
* [Isotropix: Angie](http://www.isotropix.com/angie)
|
||||
* [Autodesk Beast](http://www.autodesk.com/products/beast/overview)
|
||||
* [Appleseed](http://appleseedhq.net)
|
||||
* [Animal Logic: Glimpse renderer](https://www.fxguide.com/featured/a-glimpse-at-animal-logic/)
|
||||
@@ -389,9 +390,8 @@ Films using OSL (grouped by year of release date):
|
||||
Last Night in Soho,
|
||||
Ghostbusters: Afterlife,
|
||||
Spider-Man 3: No Way Home,
|
||||
Matrix Resurrections,
|
||||
Sing 2
|
||||
* **(2022)**
|
||||
Matrix Resurrections
|
||||
* **(2022 / upcoming)**
|
||||
Hotel Transylvania 4: Transformania,
|
||||
Death on the Nile,
|
||||
Uncharted,
|
||||
@@ -404,15 +404,11 @@ Films using OSL (grouped by year of release date):
|
||||
Thor: Love and Thunder,
|
||||
The Sea Beast,
|
||||
DC League of Super Pets,
|
||||
Minions: Rise of Gru,
|
||||
Bullet Train,
|
||||
Slumberland,
|
||||
Glass Onion
|
||||
* **(2023 / upcoming)**
|
||||
Ant-Man and the Wasp: Quantumania,
|
||||
...
|
||||
|
||||
|
||||
|
||||
Building and Installation
|
||||
-------------------------
|
||||
|
||||
@@ -485,20 +481,18 @@ The current project leadership is documented in the
|
||||
Many people have contributed features, bug fixes, and other changes to OSL
|
||||
over the years: Steve Agland, Shane Ambler, Martijn Berger, Farchad
|
||||
Bidgolirad, Nicholas Bishop, Solomon Boulos, Stefan Bruens, Stefan Büttner,
|
||||
Matthaus G. Chajdas, Clark Chen, Alejandro Conty, Damien Courtois, Dieter De
|
||||
Baets, Thomas Dinges, Daniel Dresser, Mads Drøschler, Peter Ellerington, Luke
|
||||
Emrose, Louis Feng, Mark Final, Henri Fousse, Stephen Friedman, Syoyo Fujita,
|
||||
Tim Grant, Larry Gritz, Nicolas Guiard, Euan Haahr, Derek Haase, Sven-Hendrik
|
||||
Haase, John Haddon, Niklas Harrysson, Daniel Heckenberg, Chris Hellmuth,
|
||||
Adrien Herubel, Dan Horák, Thiago Ize, Matt Johnson, Ronan Keryell, Chris
|
||||
Matthaus G. Chajdas, Clark Chen, Alejandro Conty, Dieter De Baets, Thomas
|
||||
Dinges, Mads Drøschler, Luke Emrose, Louis Feng, Mark Final, Henri Fousse,
|
||||
Stephen Friedman, Syoyo Fujita, Tim Grant, Larry Gritz, Nicolas Guiard, Euan
|
||||
Haahr, Derek Haase, Sven-Hendrik Haase, John Haddon, Niklas Harrysson, Daniel
|
||||
Heckenberg, Adrien Herubel, Thiago Ize, Matt Johnson, Ronan Keryell, Chris
|
||||
Kulla, Elvic Liang, Max Liani, Adam Martinez, John Mertic, Bastien Montagne,
|
||||
Steena Monteiro, Patrick Mours, Alexis Oblet, Erich Ocean, Mikko Ohtamaa, Jino
|
||||
Park, Alexei Pawlow, Jay Reynolds, Declan Russell, Benoit Ruiz, Patrick
|
||||
Scheibe, Alex Schworer, Jonathan Scruggs, Sergey Sharybin, Mark Sisson, Sandip
|
||||
Shukla, Cliff Stein, Stephan Steinbach, Luya Tshimbalanga, Esteban Tovagliari,
|
||||
Brecht Van Lommel, Alexander von Knorring, Alex Wells, Roman Zulak. (Listed
|
||||
alphabetically; if we've left anybody out, it is inadvertent, please let us
|
||||
know.)
|
||||
Steena Monteiro, Alexis Oblet, Erich Ocean, Mikko Ohtamaa, Jino Park, Alexei
|
||||
Pawlow, Jay Reynolds, Declan Russell, Benoit Ruiz, Patrick Scheibe, Alex
|
||||
Schworer, Jonathan Scruggs, Sergey Sharybin, Sandip Shukla, Cliff Stein,
|
||||
Stephan Steinbach, Luya Tshimbalanga, Esteban Tovagliari, Brecht Van Lommel,
|
||||
Alexander von Knorring, Alex Wells, Roman Zulak. (Listed alphabetically; if
|
||||
we've left anybody out, it is inadvertent, please let us know.)
|
||||
|
||||
We cannot possibly express sufficient gratitude to the managers at Sony
|
||||
Pictures Imageworks who allowed this project to proceed, supported it
|
||||
|
||||
+7
-11
@@ -33,7 +33,7 @@ endif # endif ${SP_OS}
|
||||
|
||||
MY_CMAKE_FLAGS += -DSP_OS=${SP_OS}
|
||||
MY_CMAKE_FLAGS += -DSPI_COMPILER_PLATFORM=${SPI_COMPILER_PLATFORM}
|
||||
MY_CMAKE_FLAGS += -DOSL_SITE:STRING=spi
|
||||
MY_CMAKE_FLAGS += -DEXTRA_CPP_ARGS:STRING="-DOSL_SPI=1" -DOSL_SITE:STRING=spi
|
||||
MY_CMAKE_FLAGS += -DSPI_TESTS=1
|
||||
MY_CMAKE_FLAGS += -DOSL_NAMESPACE_INCLUDE_PATCH=1
|
||||
REZ_PACKAGE_ROOT ?= /shots/spi/home/software/packages
|
||||
@@ -147,14 +147,14 @@ ifeq (${SP_OS}, rhel7)
|
||||
endif
|
||||
|
||||
# Cuda/OptiX
|
||||
OSL_USE_OPTIX ?= 1
|
||||
USE_OPTIX ?= 1
|
||||
CUDA_VERSION ?= 11.1.1
|
||||
OPTIX_VERSION ?= 7.2.0
|
||||
# CUDA_TOOLKIT_ROOT_DIR = $(shell rez-env -b cuda-${CUDA_VERSION} ${SPI_COMPILER_PLATFORM} -c "echo '$CUDA_TOOLKIT_ROOT'")
|
||||
CUDA_TOOLKIT_ROOT_DIR ?= /shots/spi/home/lib/arnold/rhel7/cuda_${CUDA_VERSION}
|
||||
OptiX_ROOT ?= /shots/spi/home/lib/arnold/rhel7/optix_${OPTIX_VERSION}
|
||||
OPTIXHOME = ${OptiX_ROOT}
|
||||
MY_CMAKE_FLAGS += -DOSL_USE_OPTIX=${OSL_USE_OPTIX} \
|
||||
MY_CMAKE_FLAGS += -DUSE_OPTIX=${USE_OPTIX} \
|
||||
-DCUDA_TOOLKIT_ROOT_DIR=${CUDA_TOOLKIT_ROOT_DIR} \
|
||||
-DCUDA_EXTRA_LIBS=${CUDA_EXTRA_LIBS} \
|
||||
-DOPTIXHOME=${OPTIXHOME} -DOPTIX_EXTRA_LIBS=lzma
|
||||
@@ -189,10 +189,6 @@ else ifeq (${platform}, macosx)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@15/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@15/bin/clang++
|
||||
else ifeq (${COMPILER},clang16)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@16/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@16/bin/clang++
|
||||
else ifeq (${COMPILER},clang)
|
||||
MY_CMAKE_FLAGS += -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
else ifeq (${COMPILER},gcc)
|
||||
@@ -200,13 +196,13 @@ else ifeq (${platform}, macosx)
|
||||
else ifeq (${COMPILER},)
|
||||
# default compiler is clang, taken from the LLVM directory
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
else ifeq (${COMPILER},llvm)
|
||||
# "llvm" means "use the clang from our llvm"
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
endif
|
||||
|
||||
# end generic OSX
|
||||
|
||||
@@ -23,3 +23,6 @@ sonar.exclusions=src/include/OSL/Imath/*.h,src/build-scripts/*
|
||||
# C/C++ analyzer properties
|
||||
sonar.cfamily.build-wrapper-output=build/bw_output
|
||||
sonar.cfamily.gcov.reportsPath=_coverage
|
||||
|
||||
sonar.cfamily.cache.enabled=true
|
||||
sonar.cfamily.cache.path=/tmp/sonarcache
|
||||
|
||||
@@ -14,7 +14,7 @@ uname
|
||||
|
||||
|
||||
if [[ `uname` == "Linux" ]] ; then
|
||||
LLVM_VERSION=${LLVM_VERSION:=14.0.0}
|
||||
LLVM_VERSION=${LLVM_VERSION:=13.0.0}
|
||||
LLVM_INSTALL_DIR=${LLVM_INSTALL_DIR:=${PWD}/llvm-install}
|
||||
if [[ "$GITHUB_WORKFLOW" != "" ]] ; then
|
||||
LLVM_DISTRO_NAME=${LLVM_DISTRO_NAME:=ubuntu-18.04}
|
||||
|
||||
@@ -61,6 +61,7 @@ echo "uname -a: " `uname -a`
|
||||
echo "uname -m: " `uname -m`
|
||||
echo "uname -s: " `uname -s`
|
||||
echo "uname -n: " `uname -n`
|
||||
echo "nproc " `nproc`
|
||||
pwd
|
||||
ls
|
||||
env | sort
|
||||
|
||||
@@ -18,8 +18,8 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
|
||||
#ls /etc/yum.repos.d
|
||||
|
||||
sudo /usr/bin/yum install -y giflib giflib-devel && true
|
||||
# sudo /usr/bin/yum install -y ffmpeg ffmpeg-devel && true
|
||||
sudo yum install -y giflib giflib-devel && true
|
||||
# sudo yum install -y ffmpeg ffmpeg-devel && true
|
||||
|
||||
if [[ "${CONAN_LLVM_VERSION}" != "" ]] ; then
|
||||
mkdir conan
|
||||
@@ -42,7 +42,7 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
|
||||
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" || "$CXX" == "icpx" || "$CC" == "icx" || "$USE_ICX" != "" ]] ; then
|
||||
sudo cp src/build-scripts/oneAPI.repo /etc/yum.repos.d
|
||||
sudo /usr/bin/yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0-3768
|
||||
sudo yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0-3768
|
||||
# Because multiple (possibly newer) versions of oneAPI may be installed,
|
||||
# use a config file to specify compiler and tbb versions
|
||||
# NOTE: oneAPI components have independent version numbering.
|
||||
@@ -61,7 +61,7 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
else
|
||||
# Using native Ubuntu runner
|
||||
|
||||
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
time sudo apt-get update
|
||||
|
||||
time sudo apt-get -q install -y \
|
||||
@@ -73,13 +73,8 @@ else
|
||||
libpugixml-dev \
|
||||
libopencolorio-dev
|
||||
|
||||
if [[ "${QT_VERSION:-5}" == "5" ]] ; then
|
||||
time sudo apt-get -q install -y \
|
||||
qt5-default || /bin/true
|
||||
elif [[ "${QT_VERSION}" == "6" ]] ; then
|
||||
time sudo apt-get -q install -y \
|
||||
qt6-base-dev || /bin/true
|
||||
fi
|
||||
time sudo apt-get -q install -y \
|
||||
qt5-default || /bin/true
|
||||
|
||||
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu:$CMAKE_PREFIX_PATH
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ if [[ `which brew` == "" ]] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
if [[ "$DO_BREW_UPDATE" != "" ]] ; then
|
||||
brew update >/dev/null
|
||||
@@ -31,21 +30,20 @@ brew list --versions
|
||||
brew install --display-times -q gcc ccache cmake ninja boost || true
|
||||
brew link --overwrite gcc
|
||||
brew install --display-times -q python@${PYTHON_VERSION} || true
|
||||
# brew unlink python@2.7 || true
|
||||
# brew unlink python@3.8 || true
|
||||
# brew unlink python@3.9 || true
|
||||
brew unlink python@2.7 || true
|
||||
brew unlink python@3.8 || true
|
||||
brew unlink python@3.9 || true
|
||||
brew unlink python@3.10 || true
|
||||
brew link --overwrite --force python@${PYTHON_VERSION} || true
|
||||
brew upgrade --display-times -q cmake || true
|
||||
brew install --display-times -q imath openexr
|
||||
brew install --display-times -q ilmbase openexr
|
||||
#brew install --display-times -q freetype
|
||||
brew install --display-times -q --overwrite --force opencolorio || true
|
||||
brew install --display-times -q partio pugixml
|
||||
brew install --display-times -q opencolorio partio pugixml
|
||||
brew install --display-times -q pybind11 numpy || true
|
||||
brew install --display-times -q tbb || true
|
||||
brew install --display-times -q flex bison
|
||||
brew install --display-times -q llvm${LLVMBREWVER}
|
||||
brew install --display-times -q qt${QT_BREW_VERSION}
|
||||
brew install --display-times -q qt
|
||||
|
||||
echo ""
|
||||
echo "After brew installs:"
|
||||
|
||||
@@ -121,11 +121,11 @@ endif ()
|
||||
# give more fine-grained control for hiding symbols, because sometimes
|
||||
# dependent libraries may not be well behaved and need extra hiding.
|
||||
#
|
||||
set (CMAKE_CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
|
||||
set (CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
|
||||
option (VISIBILITY_INLINES_HIDDEN "Hide symbol visibility of inline functions" ON)
|
||||
set (VISIBILITY_MAP_FILE "${PROJECT_SOURCE_DIR}/src/build-scripts/hidesymbols.map" CACHE FILEPATH "Visibility map file")
|
||||
set (CMAKE_C_VISIBILITY_PRESET ${CMAKE_CXX_VISIBILITY_PRESET})
|
||||
if (${CMAKE_CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
|
||||
set (C_VISIBILITY_PRESET ${CXX_VISIBILITY_PRESET})
|
||||
if (${CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
|
||||
(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND
|
||||
(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU"))
|
||||
# Linux/FreeBSD/Hurd: also hide all the symbols of dependent libraries
|
||||
@@ -342,17 +342,17 @@ set (USE_BATCHED "" CACHE STRING "Build batched SIMD shader execution for (0, b8
|
||||
option (VEC_REPORT "Enable compiler's reporting system for vectorization" OFF)
|
||||
set (BATCHED_SUPPORT_DEFINES "")
|
||||
set (BATCHED_TARGET_LIBS "")
|
||||
set (OSL_BUILD_BATCHED 0)
|
||||
set (BUILD_BATCHED False)
|
||||
if (NOT USE_BATCHED STREQUAL "")
|
||||
message (STATUS "Compiling with batched SIMD targets ${USE_BATCHED}")
|
||||
if (NOT USE_BATCHED STREQUAL "0")
|
||||
set (OSL_BUILD_BATCHED 1)
|
||||
set (BUILD_BATCHED 1)
|
||||
string (REPLACE "," ";" BATCHED_TARGET_LIST ${USE_BATCHED})
|
||||
foreach (batched_target ${BATCHED_TARGET_LIST})
|
||||
if (VERBOSE)
|
||||
message (STATUS "BATCHED target: ${batched_target}")
|
||||
endif ()
|
||||
list (APPEND BATCHED_SUPPORT_DEFINES "__OSL_SUPPORTS_${batched_target}")
|
||||
set (BATCHED_SUPPORT_DEFINES ${BATCHED_SUPPORT_DEFINES} "__OSL_SUPPORTS_${batched_target}")
|
||||
endforeach()
|
||||
else ()
|
||||
message (STATUS "Compiling with NO batched SIMD targets, USE_BATCHED=0")
|
||||
|
||||
@@ -21,12 +21,6 @@ function ( NVCC_COMPILE cuda_src extra_headers ptx_generated extra_nvcc_args )
|
||||
list (TRANSFORM OpenImageIO_INCLUDES PREPEND -I
|
||||
OUTPUT_VARIABLE ALL_OpenImageIO_INCLUDES)
|
||||
|
||||
if (${LLVM_VERSION} VERSION_GREATER_EQUAL 15.0)
|
||||
# Until we fully support opaque pointers, we need to disable
|
||||
# them when using LLVM 15.
|
||||
list (APPEND LLVM_COMPILE_FLAGS -Xclang -no-opaque-pointers)
|
||||
endif ()
|
||||
|
||||
add_custom_command ( OUTPUT ${cuda_ptx}
|
||||
COMMAND ${CUDA_NVCC_EXECUTABLE}
|
||||
"-I${OPTIX_INCLUDES}"
|
||||
|
||||
@@ -115,7 +115,6 @@ checked_find_package (pugixml REQUIRED
|
||||
# LLVM library setup
|
||||
checked_find_package (LLVM REQUIRED
|
||||
VERSION_MIN 9.0
|
||||
VERSION_MAX 15.9
|
||||
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES)
|
||||
# ensure include directory is added (in case of non-standard locations
|
||||
include_directories (BEFORE SYSTEM "${LLVM_INCLUDES}")
|
||||
@@ -145,19 +144,6 @@ if (LLVM_VERSION VERSION_GREATER_EQUAL 15.0
|
||||
"If you are using LLVM 15 or higher, you should also use clang version "
|
||||
"15 or higher, or you may get build errors.${ColorReset}\n")
|
||||
endif ()
|
||||
if (LLVM_VERSION VERSION_GREATER_EQUAL 16.0)
|
||||
message (ERROR "${ColorYellow}OSL is not yet compatible with LLVM 16.${ColorReset}\n")
|
||||
if (CMAKE_CXX_STANDARD VERSION_LESS 17)
|
||||
message (WARNING "${ColorYellow}LLVM 16+ requires C++17 or higher. "
|
||||
"Please set CMAKE_CXX_STANDARD to 17 or higher.${ColorReset}\n")
|
||||
endif ()
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND (GCC_VERSION VERSION_LESS 7.0))
|
||||
message (WARNING "${ColorYellow}LLVM 16+ requires gcc 7.0 or higher.${ColorReset}\n")
|
||||
endif ()
|
||||
if (CMAKE_COMPILER_IS_CLANG AND (CLANG_VERSION_STRING VERSION_LESS 5.0))
|
||||
message (WARNING "${ColorYellow}LLVM 16+ requires clang 5.0 or higher.${ColorReset}\n")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
checked_find_package (partio)
|
||||
|
||||
@@ -167,61 +153,58 @@ find_python ()
|
||||
|
||||
|
||||
# Qt -- used for osltoy
|
||||
set (qt5_modules Core Gui Widgets)
|
||||
if (OPENGL_FOUND)
|
||||
list (APPEND qt5_modules OpenGL)
|
||||
endif ()
|
||||
option (USE_QT "Use Qt if found" ON)
|
||||
if (USE_QT)
|
||||
checked_find_package (Qt6 COMPONENTS Core Gui Widgets OpenGLWidgets)
|
||||
if (NOT Qt6_FOUND)
|
||||
checked_find_package (Qt5 COMPONENTS Core Gui Widgets OpenGL)
|
||||
endif ()
|
||||
if (NOT Qt5_FOUND AND NOT Qt6_FOUND AND APPLE)
|
||||
message (STATUS " If you think you installed qt with Homebrew and it still doesn't work,")
|
||||
message (STATUS " try: export PATH=/usr/local/opt/qt/bin:$PATH")
|
||||
endif ()
|
||||
checked_find_package (Qt5 COMPONENTS ${qt5_modules})
|
||||
if (USE_QT AND NOT Qt5_FOUND AND APPLE)
|
||||
message (STATUS " If you think you installed qt5 with Homebrew and it still doesn't work,")
|
||||
message (STATUS " try: export PATH=/usr/local/opt/qt5/bin:$PATH")
|
||||
endif ()
|
||||
|
||||
|
||||
# CUDA setup
|
||||
if (OSL_USE_OPTIX)
|
||||
if (USE_LLVM_BITCODE)
|
||||
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
|
||||
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
|
||||
endif ()
|
||||
if (USE_CUDA OR USE_OPTIX)
|
||||
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
|
||||
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
|
||||
endif ()
|
||||
|
||||
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
|
||||
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
endif ()
|
||||
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
|
||||
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
endif ()
|
||||
|
||||
checked_find_package (CUDA REQUIRED
|
||||
VERSION_MIN 8.0
|
||||
PRINT CUDA_INCLUDES)
|
||||
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
|
||||
include_directories (BEFORE "${CUDA_INCLUDES}")
|
||||
checked_find_package (CUDA REQUIRED
|
||||
VERSION_MIN 8.0
|
||||
PRINT CUDA_INCLUDES)
|
||||
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
|
||||
include_directories (BEFORE "${CUDA_INCLUDES}")
|
||||
|
||||
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
|
||||
if (NOT ${nvptx_index} GREATER -1)
|
||||
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
|
||||
endif()
|
||||
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
|
||||
if (NOT ${nvptx_index} GREATER -1)
|
||||
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
|
||||
endif()
|
||||
|
||||
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
|
||||
find_library(cuda_lib NAMES cudart
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${cuda_lib})
|
||||
find_library(cuda_lib NAMES cudart
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${cuda_lib})
|
||||
|
||||
# testrender & testshade need libnvrtc
|
||||
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
|
||||
find_library(nvrtc_lib NAMES nvrtc
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
|
||||
# testrender & testshade need libnvrtc
|
||||
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
|
||||
find_library(nvrtc_lib NAMES nvrtc
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
|
||||
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
endif()
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
endif()
|
||||
|
||||
# OptiX setup
|
||||
if (OSL_USE_OPTIX AND OSL_BUILD_TESTS)
|
||||
if (USE_OPTIX)
|
||||
checked_find_package (OptiX REQUIRED
|
||||
VERSION_MIN 7.0)
|
||||
include_directories (BEFORE "${OPTIX_INCLUDES}")
|
||||
@@ -236,6 +219,7 @@ if (OSL_USE_OPTIX)
|
||||
target_compile_definitions (${TARGET} PRIVATE "-DPTX_PATH=\"${OSL_PTX_INSTALL_DIR}\"")
|
||||
target_link_libraries (${TARGET} PRIVATE ${CUDA_LIBRARIES} ${CUDA_EXTRA_LIBS} ${OPTIX_LIBRARIES} ${OPTIX_EXTRA_LIBS})
|
||||
endfunction()
|
||||
|
||||
else ()
|
||||
function (osl_optix_target TARGET)
|
||||
endfunction()
|
||||
|
||||
@@ -23,13 +23,7 @@
|
||||
|
||||
# try to find llvm-config, with a specific version if specified
|
||||
if (LLVM_DIRECTORY)
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
|
||||
endif ()
|
||||
if (LLVM_ROOT)
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_ROOT}/bin")
|
||||
endif ()
|
||||
if (DEFINED ENV{LLVM_ROOT})
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "$ENV{LLVM_ROOT}/bin")
|
||||
set (LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
|
||||
endif ()
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS
|
||||
"/usr/local/opt/llvm/${LLVM_VERSION}/bin/"
|
||||
@@ -127,7 +121,7 @@ endif ()
|
||||
|
||||
foreach (COMPONENT clangFrontend clangDriver clangSerialization
|
||||
clangParse clangSema clangAnalysis clangAST clangBasic
|
||||
clangEdit clangLex clangSupport)
|
||||
clangEdit clangLex)
|
||||
find_library ( _CLANG_${COMPONENT}_LIBRARY
|
||||
NAMES ${COMPONENT}
|
||||
PATHS ${LLVM_LIB_DIR})
|
||||
|
||||
@@ -20,9 +20,12 @@ macro (find_python)
|
||||
|
||||
# Attempt to find the desired version, but fall back to other
|
||||
# additional versions.
|
||||
set (_req REQUIRED)
|
||||
if (PYTHON_VERSION)
|
||||
list (APPEND _req EXACT)
|
||||
unset (_req)
|
||||
if (USE_PYTHON)
|
||||
set (_req REQUIRED)
|
||||
if (PYTHON_VERSION)
|
||||
list (APPEND _req EXACT)
|
||||
endif ()
|
||||
endif ()
|
||||
checked_find_package (Python ${PYTHON_VERSION}
|
||||
${_req}
|
||||
|
||||
+10
-15
@@ -71,10 +71,6 @@ macro (add_one_testsuite testname testsrcdir)
|
||||
set_tests_properties (${testname} PROPERTIES LABELS render
|
||||
PROCESSORS 4 COST 10 TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endif ()
|
||||
# For debug builds, render tests are very slow, so give them a longer timeout
|
||||
if (${testname} MATCHES "render-" AND ${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
||||
set_tests_properties (${testname} PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endif ()
|
||||
# Some labeling for fun
|
||||
if (${testname} MATCHES "^texture")
|
||||
set_tests_properties (${testname} PROPERTIES LABELS texture
|
||||
@@ -143,11 +139,14 @@ macro ( TESTSUITE )
|
||||
add_one_testsuite ("${_testname}.opt" "${_testsrcdir}"
|
||||
ENV TESTSHADE_OPT=2 )
|
||||
endif ()
|
||||
if (_testname MATCHES "render-" AND ${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
||||
set_tests_properties (${_testname} PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endif ()
|
||||
# When building for OptiX support, also run it in OptiX mode
|
||||
# if there is an OPTIX marker file in the directory.
|
||||
# If an environment variable $TESTSUITE_OPTIX is nonzero, then
|
||||
# run all tests with OptiX, even if there's no OPTIX marker.
|
||||
if (OSL_USE_OPTIX
|
||||
if (USE_OPTIX
|
||||
AND (EXISTS "${_testsrcdir}/OPTIX" OR test_all_optix OR _testname MATCHES "optix")
|
||||
AND NOT EXISTS "${_testsrcdir}/NOOPTIX"
|
||||
AND NOT EXISTS "${_testsrcdir}/NOOPTIX-FIXME"
|
||||
@@ -162,7 +161,7 @@ macro ( TESTSUITE )
|
||||
ENV TESTSHADE_OPT=2 TESTSHADE_OPTIX=1 )
|
||||
endif ()
|
||||
|
||||
if (OSL_BUILD_BATCHED)
|
||||
if (BUILD_BATCHED)
|
||||
# When building for Batched support, also run it in Batched mode
|
||||
# if there is an BATCHED marker file in the directory.
|
||||
# If an environment variable $TESTSUITE_BATCHED is nonzero, then
|
||||
@@ -237,8 +236,7 @@ macro (osl_add_all_tests)
|
||||
bug-array-heapoffsets bug-locallifetime bug-outputinit
|
||||
bug-param-duplicate bug-peep bug-return
|
||||
calculatenormal-reg
|
||||
cellnoise closure closure-array closure-parameters closure-zero closure-conditional
|
||||
color color-reg colorspace comparison
|
||||
cellnoise closure closure-array color color-reg colorspace comparison
|
||||
complement-reg compile-buffer compassign-reg
|
||||
component-range
|
||||
control-flow-reg connect-components
|
||||
@@ -299,7 +297,6 @@ macro (osl_add_all_tests)
|
||||
oslc-err-struct-dup oslc-err-struct-print
|
||||
oslc-err-type-as-variable
|
||||
oslc-err-unknown-ctr
|
||||
oslc-literalfold
|
||||
oslc-pragma-warnerr
|
||||
oslc-warn-commainit
|
||||
oslc-variadic-macro
|
||||
@@ -311,8 +308,7 @@ macro (osl_add_all_tests)
|
||||
pragma-nowarn
|
||||
printf-reg
|
||||
printf-whole-array
|
||||
raytype raytype-reg raytype-specialized regex-reg
|
||||
reparam reparam-arrays
|
||||
raytype raytype-reg raytype-specialized regex-reg reparam
|
||||
render-background render-bumptest
|
||||
render-cornell render-furnace-diffuse
|
||||
render-mx-furnace-burley-diffuse
|
||||
@@ -326,7 +322,6 @@ macro (osl_add_all_tests)
|
||||
render-mx-sheen
|
||||
render-microfacet render-oren-nayar
|
||||
render-uv render-veachmis render-ward
|
||||
render-raytypes
|
||||
select select-reg shaderglobals shortcircuit
|
||||
smoothstep-reg
|
||||
spline spline-reg splineinverse splineinverse-ident
|
||||
@@ -356,7 +351,7 @@ macro (osl_add_all_tests)
|
||||
transform transform-reg transformc transformc-reg trig trig-reg
|
||||
typecast
|
||||
unknown-instruction
|
||||
userdata userdata-custom userdata-passthrough
|
||||
userdata userdata-passthrough
|
||||
vararray-connect vararray-default
|
||||
vararray-deserialize vararray-param
|
||||
vecctr vector vector-reg
|
||||
@@ -388,7 +383,7 @@ macro (osl_add_all_tests)
|
||||
endif()
|
||||
|
||||
# Only run pointcloud tests if Partio is found
|
||||
if (partio_FOUND)
|
||||
if (PARTIO_FOUND)
|
||||
TESTSUITE ( pointcloud pointcloud-fold )
|
||||
endif ()
|
||||
|
||||
@@ -398,7 +393,7 @@ macro (osl_add_all_tests)
|
||||
endif ()
|
||||
|
||||
# Some regression tests have a lot of combinations and may need more time to finish
|
||||
if (OSL_BUILD_BATCHED)
|
||||
if (BUILD_BATCHED)
|
||||
set_tests_properties (arithmetic-reg.regress.batched.opt
|
||||
PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
set_tests_properties (transform-reg.regress.batched.opt
|
||||
|
||||
+34
-63
@@ -2631,6 +2631,27 @@ and proceeds to the next iteration of the loop.
|
||||
\section{Functions}
|
||||
\label{sec:functions}
|
||||
|
||||
\subsection{Function calls}
|
||||
\label{sec:syntax:functioncalls}
|
||||
\index{function calls}
|
||||
|
||||
Function calls are very similar to C and related programming languages:
|
||||
|
||||
\begin{tabbing}
|
||||
\hspace{0.5in} \= \hspace{0.3in} \= \kill
|
||||
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf )} \\
|
||||
\end{tabbing}
|
||||
|
||||
If the function returns a value (not \void), you may use its value as
|
||||
an expression. It is fine to completely ignore the value of even
|
||||
a non-\void function.
|
||||
|
||||
In \langname, all arguments are passed by reference. This generally
|
||||
will not be noticeably different from C-style ``pass by value''
|
||||
semantics, except if you pass the same variable as two separate
|
||||
arguments to a function that modifies an argument's value.
|
||||
|
||||
|
||||
\subsection{Function definitions}
|
||||
\label{sec:syntax:functiondefinitions}
|
||||
\index{functions!definitions}
|
||||
@@ -2678,35 +2699,6 @@ passing an {\cf int} when the function expects a {\cf float}, or passing a
|
||||
{\cf float} when the function expects a \color), and finally by trying to
|
||||
match the return value to the type of variable the result is assigned to.
|
||||
|
||||
\subsection{Function calls}
|
||||
\label{sec:syntax:functioncalls}
|
||||
\index{function calls}
|
||||
|
||||
Function calls are very similar to C and related programming languages:
|
||||
|
||||
\begin{tabbing}
|
||||
\hspace{0.5in} \= \hspace{0.3in} \= \kill
|
||||
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf )} \\
|
||||
\end{tabbing}
|
||||
|
||||
If the function returns a value (not \void), you may use its value as
|
||||
an expression. It is fine to completely ignore the value of even
|
||||
a non-\void function.
|
||||
|
||||
In \langname, all arguments are passed by reference. This generally
|
||||
will not be noticeably different from C-style ``pass by value''
|
||||
semantics, except if you pass the same variable as two separate
|
||||
arguments to a function that modifies an argument's value.
|
||||
|
||||
Certain functions allow optional arguments to be passed.
|
||||
Optional arguments are key-value pairs with the key passed as an
|
||||
argument and the associated value passed as the subsequent argument:
|
||||
|
||||
\begin{tabbing}
|
||||
\hspace{0.5in} \= \hspace{0.3in} \= \kill
|
||||
\> \emph{functionname} {\cf (} \emph{arg1} {\cf ,} ... {\cf ,} \emph{argn} {\cf ,} \emph{"optionalkey"} {\cf ,} \emph{optionalvalue} {\cf ,} ... {\cf )} \\
|
||||
\end{tabbing}
|
||||
|
||||
\subsection{Operator overloading}
|
||||
\label{sec:syntax:operatoroverloading}
|
||||
\index{operator overloading}
|
||||
@@ -4091,8 +4083,8 @@ are assigned to a \float or a \color (or type cast to one of those)
|
||||
determines whether the texture lookup is a single channel or three
|
||||
channels.
|
||||
|
||||
The 2D lookup coordinate(s) may be followed by optional key-value
|
||||
arguments (see Section~\ref{sec:syntax:functioncalls}) that control the behavior of {\cf texture()}:
|
||||
The 2D lookup coordinate(s) may be followed by optional token/value
|
||||
arguments that control the behavior of {\cf texture()}:
|
||||
|
||||
\apiitem{"blur", <float>}
|
||||
\vspace{12pt}
|
||||
@@ -5607,7 +5599,7 @@ forms of the function with no object name, or if the object name is the
|
||||
empty string \qkw{}, the renderer will first search
|
||||
per-object attributes on the current object (or interpolated variables
|
||||
with that name attached to the object), then if not found it will search
|
||||
global scene-wide attributes.
|
||||
searching global scene-wide attributes.
|
||||
|
||||
If the attribute is found and can be converted to the type of
|
||||
\emph{destination}, the attribute's value will be stored in
|
||||
@@ -5909,38 +5901,17 @@ view-dependence into shaders.
|
||||
The return value is 0 if the ray missed all geometry, 1 if it hit
|
||||
anything within the distance range.
|
||||
|
||||
The following optional key-value arguments
|
||||
(see Section~\ref{sec:syntax:functioncalls}) can be passed:
|
||||
Optional parameters include:
|
||||
|
||||
\apiitem{"mindist", <float>}
|
||||
\vspace{12pt}
|
||||
The minimum hit distance (default: 0).
|
||||
|
||||
The units of the {\cf "mindist"} and {\cf "maxdist"} are determined by the renderer
|
||||
and are sometimes defined by the dir vector, which can lead to unexpected
|
||||
behavior. So, generally, clearly written and portable shaders should pass
|
||||
a unit length (see Section~\ref{sec:stdlib:geom}) dir vector.
|
||||
\apiend
|
||||
\vspace{-16pt}
|
||||
|
||||
\apiitem{"mindist", <float>}
|
||||
\vspace{12pt}
|
||||
The maximum hit distance (default: infinite).
|
||||
\apiend
|
||||
\vspace{-16pt}
|
||||
|
||||
\apiitem{"shade", <int>}
|
||||
\vspace{12pt}
|
||||
Defines whether objects hit will be shaded (default: 0).
|
||||
\apiend
|
||||
\vspace{-16pt}
|
||||
|
||||
\apiitem{"traceset", <string>}
|
||||
\vspace{12pt}
|
||||
An optional named set of objects to ray trace (if preceded by a `{\cf -}'
|
||||
character, it means to exclude that set).
|
||||
\apiend
|
||||
\vspace{-16pt}
|
||||
\begin{tabular}{p{1.2in} p{0.5in} p{3.2in}}
|
||||
\qkw{mindist} & {\cf float} & Minimum hit distance (default: zero) \\
|
||||
\qkw{maxdist} & {\cf float} & Maximum hit distance (default: infinite) \\
|
||||
\qkw{shade} & {\cf int} & Whether objects hit will be shaded
|
||||
(default: 0) \\
|
||||
\qkw{traceset} & {\cf string} & An optional named set of objects to
|
||||
ray trace (if preceded by a `{\cf -}'
|
||||
character, it means to exclude that set).
|
||||
\end{tabular}
|
||||
|
||||
Information about the closest object hit by the ray may be retrieved
|
||||
using \\ {\cf getmessage("trace",...)} (see Section~\ref{sec:getmessage}).
|
||||
|
||||
@@ -82,13 +82,12 @@ public:
|
||||
/// Return a Mask with lanes set to true if ok, false if the named matrix
|
||||
/// is not known.
|
||||
virtual Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> wresult,
|
||||
ustringhash from, Wide<const float> wtime)
|
||||
ustring from, Wide<const float> wtime)
|
||||
{
|
||||
return Mask(false);
|
||||
}
|
||||
virtual Mask get_matrix(BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustringhash> wfrom,
|
||||
Wide<const float> wtime);
|
||||
Wide<const ustring> wfrom, Wide<const float> wtime);
|
||||
virtual bool is_overridden_get_matrix_WmWsWf() const = 0;
|
||||
|
||||
|
||||
@@ -98,12 +97,12 @@ public:
|
||||
/// particular renderer may have a better technique and overload the
|
||||
/// implementation.
|
||||
virtual Mask get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult, ustringhash to,
|
||||
Masked<Matrix44> wresult, ustring to,
|
||||
Wide<const float> wtime);
|
||||
virtual bool is_overridden_get_inverse_matrix_WmsWf() const = 0;
|
||||
virtual Mask get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult,
|
||||
Wide<const ustringhash> wto,
|
||||
Wide<const ustring> wto,
|
||||
Wide<const float> wtime);
|
||||
virtual bool is_overridden_get_inverse_matrix_WmWsWf() const = 0;
|
||||
|
||||
@@ -125,23 +124,22 @@ public:
|
||||
/// specified (object == ustring()), then the renderer should search *first*
|
||||
/// for the attribute on the currently shaded object, and next, if
|
||||
/// unsuccessful, on the currently shaded "scene".
|
||||
virtual Mask get_attribute(BatchedShaderGlobals* bsg, ustringhash object,
|
||||
ustringhash name, MaskedData wval)
|
||||
virtual Mask get_attribute(BatchedShaderGlobals* bsg, ustring object,
|
||||
ustring name, MaskedData wval)
|
||||
{
|
||||
return Mask(false);
|
||||
}
|
||||
|
||||
/// Similar to get_attribute(); this method will fetch the 'index'
|
||||
/// element of an attribute array.
|
||||
virtual Mask get_array_attribute(BatchedShaderGlobals* bsg,
|
||||
ustringhash object, ustringhash name,
|
||||
int index, MaskedData wval)
|
||||
virtual Mask get_array_attribute(BatchedShaderGlobals* bsg, ustring object,
|
||||
ustring name, int index, MaskedData wval)
|
||||
{
|
||||
return Mask(false);
|
||||
}
|
||||
|
||||
virtual bool get_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustringhash object, ustringhash name,
|
||||
ustring object, ustring name,
|
||||
RefData val)
|
||||
{
|
||||
return false;
|
||||
@@ -150,9 +148,8 @@ public:
|
||||
/// Similar to get_attribute(); this method will fetch the 'index'
|
||||
/// element of an attribute array.
|
||||
virtual bool get_array_attribute_uniform(BatchedShaderGlobals* bsg,
|
||||
ustringhash object,
|
||||
ustringhash name, int index,
|
||||
RefData val)
|
||||
ustring object, ustring name,
|
||||
int index, RefData val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -162,7 +159,7 @@ public:
|
||||
/// as well. It is assumed the results are varying and returns Mask
|
||||
// with its bit set to off if no user-data with the given name and type was
|
||||
/// found.
|
||||
virtual Mask get_userdata(ustringhash name, BatchedShaderGlobals* bsg,
|
||||
virtual Mask get_userdata(ustring name, BatchedShaderGlobals* bsg,
|
||||
MaskedData wval)
|
||||
{
|
||||
return Mask(false);
|
||||
@@ -209,7 +206,7 @@ public:
|
||||
/// error.
|
||||
///
|
||||
virtual Mask
|
||||
texture(ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
texture(ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
|
||||
Wide<const float> ws, Wide<const float> wt, Wide<const float> wdsdx,
|
||||
@@ -243,7 +240,7 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual Mask texture3d(ustringhash filename,
|
||||
virtual Mask texture3d(ustring filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options,
|
||||
@@ -276,7 +273,7 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual Mask environment(ustringhash filename,
|
||||
virtual Mask environment(ustring filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options,
|
||||
@@ -303,12 +300,12 @@ public:
|
||||
|
||||
virtual TextureSystem::TextureHandle* resolve_udim_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
float S, float T);
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
|
||||
float T);
|
||||
|
||||
virtual void resolve_udim(BatchedShaderGlobals* bsg,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ustringhash filename,
|
||||
ustring filename,
|
||||
TextureSystem::TextureHandle* texture_handle,
|
||||
Wide<const float> wS, Wide<const float> wT,
|
||||
Masked<TextureSystem::TextureHandle*> wresult);
|
||||
@@ -316,8 +313,8 @@ public:
|
||||
// Assumes any UDIM has been resolved already
|
||||
virtual bool get_texture_info_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustringhash dataname, RefData val);
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustring dataname, RefData val);
|
||||
|
||||
|
||||
/// Lookup nearest points in a point cloud. It will search for
|
||||
@@ -410,25 +407,26 @@ public:
|
||||
};
|
||||
|
||||
|
||||
virtual void pointcloud_search(BatchedShaderGlobals* bsg,
|
||||
ustringhash filename, const void* wcenter,
|
||||
virtual void pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
const void* wcenter,
|
||||
Wide<const float> wradius, int max_points,
|
||||
bool sort, PointCloudSearchResults& results);
|
||||
virtual bool is_overridden_pointcloud_search() const = 0;
|
||||
|
||||
|
||||
virtual Mask pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
virtual Mask pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points,
|
||||
ustringhash attr_name, MaskedData wout_data);
|
||||
Wide<const int> wnum_points, ustring attr_name,
|
||||
MaskedData wout_data);
|
||||
virtual bool is_overridden_pointcloud_get() const = 0;
|
||||
|
||||
|
||||
virtual Mask
|
||||
pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
Wide<const OSL::Vec3> wpos, int nattribs,
|
||||
const ustring* attr_names, const TypeDesc* attr_types,
|
||||
const void** pointers_to_wide_attr_value, Mask mask);
|
||||
virtual Mask pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const OSL::Vec3> wpos, int nattribs,
|
||||
const ustring* attr_names,
|
||||
const TypeDesc* attr_types,
|
||||
const void** pointers_to_wide_attr_value,
|
||||
Mask mask);
|
||||
virtual bool is_overridden_pointcloud_write() const = 0;
|
||||
|
||||
/// Options for the trace call.
|
||||
@@ -443,8 +441,7 @@ public:
|
||||
Wide<const Vec3> wdRdy);
|
||||
|
||||
virtual void getmessage(BatchedShaderGlobals* bsg, Masked<int> wresult,
|
||||
ustringhash source, ustringhash name,
|
||||
MaskedData wval);
|
||||
ustring source, ustring name, MaskedData wval);
|
||||
|
||||
// pointcloud_search is T.B.D.
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
|
||||
/// Wrapper class for holding a "device" pointer -- GPU or whatnot. It
|
||||
/// provides protections so that the pointer cannot easily be accessed on the
|
||||
/// host side, where presumably it would not be valid memory.
|
||||
template<class T> class device_ptr {
|
||||
public:
|
||||
device_ptr() = default;
|
||||
|
||||
// Copy ctr from another device_ptr of the same type
|
||||
device_ptr(const device_ptr& other) = default;
|
||||
|
||||
/// On device, device_ptr can construct from a pointer.
|
||||
/// On host, it must be explicitly constructed -- use with caution.
|
||||
#ifdef __CUDA_ARCH__
|
||||
device_ptr(T* ptr) : m_ptr(ptr) {}
|
||||
#else
|
||||
explicit device_ptr(T* ptr) : m_ptr(ptr) {}
|
||||
#endif
|
||||
|
||||
#ifdef __CUDA_ARCH__
|
||||
/// On device, act as a pointer. None of these things are allowed on the
|
||||
/// host.
|
||||
T* operator->() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
T& operator*() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Extract the raw device-side pointer. Use with caution! On the host,
|
||||
/// this will not point to valid memory.
|
||||
T* d_get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// Evaluate as bool is a null pointer check.
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return m_ptr != nullptr;
|
||||
}
|
||||
|
||||
/// Reset the pointer to `dptr`, which must be a device-side raw pointer,
|
||||
/// or null. Since this device_ptr is non-owning, any previous value is
|
||||
/// simply overwritten.
|
||||
void reset(T* dptr = nullptr)
|
||||
{
|
||||
m_ptr = dptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_ptr = nullptr; // underlying pointer, initializes to null
|
||||
};
|
||||
|
||||
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
#ifdef __CUDA_ARCH__
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
// USAGE NOTES:
|
||||
//
|
||||
// To define a "standard" DeviceString, add a STRDECL to <OSL/strdecls.h>
|
||||
@@ -15,10 +19,21 @@
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
|
||||
// Strings are handled differently in OptiX 6 vs OptiX 7.
|
||||
//
|
||||
// In OptiX 7+:
|
||||
// Strings are not stored on the GPU at all. Strings are represented by
|
||||
// their hash values which are computed at compile-time. Because of this,
|
||||
// we have no access to either the strings' contents or their lengths.
|
||||
//
|
||||
// In OptiX 6:
|
||||
// Strings are stored in a block of CUDA device memory. String variables hold a
|
||||
// pointer to the start of the char array for each string. Each canonical string
|
||||
// has a unique entry in the table, so two strings can be tested for equality by
|
||||
// comparing their addresses.
|
||||
//
|
||||
// As a convenience, the ustring hash and the length of the string are also
|
||||
// stored in the table, in the 16 bytes preceding the characters.
|
||||
|
||||
struct DeviceString {
|
||||
#ifdef __CUDA_ARCH__
|
||||
|
||||
@@ -631,12 +631,6 @@ public:
|
||||
/// llvm type.
|
||||
llvm::Type* type_array(llvm::Type* type, int n);
|
||||
|
||||
/// Return the true if the llvm::Type is an array
|
||||
bool is_type_array(llvm::Type* type);
|
||||
|
||||
/// Return the llvm::Type of element that the array_type is made up of
|
||||
llvm::Type* element_type_of(llvm::Type* array_type);
|
||||
|
||||
/// Return an llvm::FunctionType that describes a function with the
|
||||
/// given return types, parameter types (in a cspan), and whether it
|
||||
/// uses varargs conventions.
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#cmakedefine01 OSL_USE_OPTIX
|
||||
#cmakedefine01 OSL_BUILD_BATCHED
|
||||
#define OSL_USE_BATCHED OSL_BUILD_BATCHED
|
||||
|
||||
|
||||
#include <OSL/export.h>
|
||||
#include <OSL/oslversion.h>
|
||||
#include <OSL/platform.h>
|
||||
@@ -67,6 +62,8 @@
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
#define OSL_USE_BATCHED @BUILD_BATCHED@
|
||||
|
||||
/// Various compile-time defaults are defined here that could, in
|
||||
/// principle, be redefined if you are using OSL in some particular
|
||||
/// renderer that wanted things a different way.
|
||||
@@ -136,101 +133,6 @@ fmtformat(const Str& fmt, Args&&... args)
|
||||
|
||||
|
||||
|
||||
/// OSL_USTRINGREP_IS_HASH will be 1 if the build-time option was enabled to
|
||||
/// make the ustringrep be a ustringhash, rather than a ustring directly.
|
||||
#cmakedefine01 OSL_USTRINGREP_IS_HASH
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
/// ustringrep is the class we use to represent strings in the shader.
|
||||
using ustringrep = ustringhash;
|
||||
#else
|
||||
/// ustringrep is the class we use to represent strings in the shader.
|
||||
using ustringrep = ustring;
|
||||
#endif
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
/// ustring_pod is the type we use to pass string data in llvm function calls.
|
||||
using ustring_pod = size_t;
|
||||
#else
|
||||
/// ustring_pod is the type we use to pass string data in llvm function calls.
|
||||
using ustring_pod = const char*;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/// Convenience function to convert to a ustring.
|
||||
inline ustring
|
||||
ustring_from(ustringhash h)
|
||||
{
|
||||
return ustring::from_hash(h.hash());
|
||||
}
|
||||
|
||||
/// Convenience function to convert to a ustring.
|
||||
inline ustring
|
||||
ustring_from(ustring u)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
/// Convenience function to convert to a ustring.
|
||||
inline ustring
|
||||
ustring_from(string_view s)
|
||||
{
|
||||
return ustring(s);
|
||||
}
|
||||
|
||||
|
||||
/// Convenience function to convert to a ustringhash.
|
||||
inline ustringhash
|
||||
ustringhash_from(ustringhash u)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
/// Convenience function to convert to a ustringhash.
|
||||
inline ustringhash
|
||||
ustringhash_from(ustring u)
|
||||
{
|
||||
return u.uhash();
|
||||
}
|
||||
|
||||
|
||||
/// Convenience function to convert to a ustringrep.
|
||||
inline ustringrep
|
||||
ustringrep_from(ustringhash h)
|
||||
{
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
return h;
|
||||
#else
|
||||
return ustring::from_hash(h.hash());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Convenience function to convert to a ustringrep.
|
||||
inline ustringrep
|
||||
ustringrep_from(ustring u)
|
||||
{
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
return u.hash();
|
||||
#else
|
||||
return u;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Convenience function to convert to a ustringrep.
|
||||
inline ustringrep
|
||||
ustringrep_from(string_view s)
|
||||
{
|
||||
ustring u(s);
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
return u.hash();
|
||||
#else
|
||||
return u;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// N.B. SymArena is not really "configuration", but we cram it here for
|
||||
// lack of a better home.
|
||||
|
||||
@@ -241,7 +143,6 @@ enum class SymArena {
|
||||
Heap, // Belongs to context heap
|
||||
Outputs, // Belongs to output arena
|
||||
UserData, // UserData arena
|
||||
Interactive, // Interactively edited variables
|
||||
// ShaderGlobals, // RESERVED
|
||||
};
|
||||
|
||||
@@ -328,8 +229,7 @@ OSL_NAMESPACE_EXIT
|
||||
|
||||
namespace std { // not necessary in C++17, then we can just say std::hash
|
||||
#ifndef OIIO_USTRING_HAS_STDHASH
|
||||
// Not a new enough OIIO to define std::hash<ustring>, so we'll do it.
|
||||
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
|
||||
// Not a new enough OIIO to define std::hash<ustring>, so we'll do it
|
||||
template<> struct hash<OSL::ustring> {
|
||||
std::size_t operator()(OSL::ustring u) const noexcept { return u.hash(); }
|
||||
};
|
||||
@@ -343,8 +243,7 @@ template<> struct hash<OSL::ustringhash> {
|
||||
};
|
||||
#endif
|
||||
|
||||
// Not necessary once minimum OIIO defines operator< for ustringhash.
|
||||
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
|
||||
// Not necessary once minimum OIIO defines operator< for ustringhash
|
||||
template<> struct less<OSL::ustringhash> {
|
||||
OSL_HOSTDEVICE constexpr bool operator()(OSL::ustringhash u,
|
||||
OSL::ustringhash v) const noexcept
|
||||
@@ -353,21 +252,3 @@ template<> struct less<OSL::ustringhash> {
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
|
||||
#ifndef OIIO_HAS_USTRINGHASH_FORMATTER
|
||||
// OIIO is too old to have fmt custom formatter for ustringhash.
|
||||
// This can be removed once OIIO minimum is 2.4.5+ or >=2.5.0.1
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template<> struct formatter<OIIO::ustringhash> : formatter<fmt::string_view, char> {
|
||||
template<typename FormatContext>
|
||||
auto format(const OIIO::ustringhash& h, FormatContext& ctx)
|
||||
-> decltype(ctx.out()) const
|
||||
{
|
||||
OIIO::ustring u(h);
|
||||
return formatter<fmt::string_view, char>::format({ u.data(), u.size() },
|
||||
ctx);
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
+15
-131
@@ -111,67 +111,6 @@ public:
|
||||
|
||||
|
||||
|
||||
/// Parameter property hint bitflag values. The enum values must be powers of
|
||||
/// two so they can be combined with bitwise operators.
|
||||
enum class ParamHints : uint32_t {
|
||||
/// `none`: No special properties
|
||||
none = 0,
|
||||
/// `interpolated`: This parameter may be an interpolated "user data" or
|
||||
/// "geometric primitive" variable, and so may take on different values at
|
||||
/// different points on the surface or on different objects that share the
|
||||
/// same material. Any optimization of the shader should take this into
|
||||
/// account.
|
||||
interpolated = 1,
|
||||
/// `interactive`: Parameter may have its value interactively modified by
|
||||
/// subsequent ReParameter calls. Any optimization of the shader should
|
||||
/// take this into account.
|
||||
interactive = 2
|
||||
};
|
||||
|
||||
inline constexpr ParamHints
|
||||
operator|(ParamHints a, ParamHints b)
|
||||
{
|
||||
return static_cast<ParamHints>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline constexpr ParamHints
|
||||
operator&(ParamHints a, ParamHints b)
|
||||
{
|
||||
return static_cast<ParamHints>(static_cast<int>(a) & static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline ParamHints&
|
||||
operator|=(ParamHints& a, ParamHints b)
|
||||
{
|
||||
a = a | b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline ParamHints&
|
||||
operator&=(ParamHints& a, ParamHints b)
|
||||
{
|
||||
a = a & b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline constexpr ParamHints
|
||||
operator~(ParamHints a)
|
||||
{
|
||||
return static_cast<ParamHints>(~static_cast<int>(a));
|
||||
}
|
||||
|
||||
inline ParamHints&
|
||||
set(ParamHints& a, ParamHints b, bool on = true)
|
||||
{
|
||||
if (on)
|
||||
a |= b;
|
||||
else
|
||||
a &= ~b;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class OSLEXECPUBLIC ShadingSystem {
|
||||
public:
|
||||
ShadingSystem(RendererServices* renderer = NULL,
|
||||
@@ -234,7 +173,7 @@ public:
|
||||
/// int lazyerror Run layers lazily even if they have error
|
||||
/// ops after optimization (1).
|
||||
/// int lazy_userdata Retrieve userdata lazily (0).
|
||||
/// int userdata_isconnected Should interpolated=1 params (that may
|
||||
/// int userdata_isconnected Should lockgeom=0 params (that may
|
||||
/// receive userdata) return true from
|
||||
/// isconnected()? (0)
|
||||
/// int greedyjit Optimize and compile all shaders up front,
|
||||
@@ -261,7 +200,6 @@ public:
|
||||
/// that don't specify it (1). Lockgeom
|
||||
/// means a param CANNOT be overridden by
|
||||
/// interpolated geometric parameters.
|
||||
/// This option is slated for deprecation.
|
||||
/// int countlayerexecs Add extra code to count total layers run.
|
||||
/// int allow_shader_replacement Allow shader to be specified more than
|
||||
/// once, replacing former definition.
|
||||
@@ -489,15 +427,12 @@ public:
|
||||
/// ptr attributes_needed Retrieves a pointer to the ustring array
|
||||
/// containing the names of the needed attributes.
|
||||
/// Note that if the same attribute
|
||||
/// is requested in multiple scopes, or with
|
||||
/// multiple different types, it will
|
||||
/// is requested in multiple scopes, it will
|
||||
/// appear in the array multiple times - once for
|
||||
/// each scope/type in which is is queried.
|
||||
/// each scope in which is is queried.
|
||||
/// ptr attribute_scopes Retrieves a pointer to a ustring array containing
|
||||
/// the scopes associated with each attribute query
|
||||
/// in the attributes_needed array.
|
||||
/// ptr attribute_types Retrieves a pointer to the array of
|
||||
/// TypeDesc describing the attributes.
|
||||
/// int unknown_attributes_needed Nonzero if additional attributes may be
|
||||
/// needed, whose names will not be known
|
||||
/// until the shader actually runs.
|
||||
@@ -508,15 +443,6 @@ public:
|
||||
/// string entry_layers[] List of entry point layers.
|
||||
/// string pickle Retrieves a serialized representation
|
||||
/// of the shader group declaration.
|
||||
/// int llvm_groupdata_size Size of the GroupData struct.
|
||||
/// ptr interactive_params Pointer to the memory block containing
|
||||
/// host-side interactive parameter values
|
||||
/// for this shader group.
|
||||
/// ptr device_interactive_params
|
||||
/// Pointer to the memory block containing
|
||||
/// device-side interactive parameter values
|
||||
/// for this shader group.
|
||||
///
|
||||
/// Note: the attributes referred to as "string" are actually on the app
|
||||
/// side as ustring or const char* (they have the same data layout), NOT
|
||||
/// std::string!
|
||||
@@ -604,50 +530,15 @@ public:
|
||||
bool ShaderGroupEnd(ShaderGroup& group);
|
||||
|
||||
/// Set a parameter of the next shader that will be added to the group,
|
||||
/// optionally setting or overriding properties with the `hints` argument.
|
||||
/// Individual `hints` bits are defined and documented by the ParamHints
|
||||
/// enum class.
|
||||
/// optionally setting the 'lockgeom' metadata for that parameter
|
||||
/// (despite how it may have been set in the shader). If lockgeom is
|
||||
/// false, it means that this parameter should NOT be considered locked
|
||||
/// against changes by the geometry, and therefore the shader should not
|
||||
/// optimize assuming that the instance value (the 'val' specified by
|
||||
/// this call) is a constant.
|
||||
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
const void* val, ParamHints hints = ParamHints::none);
|
||||
|
||||
/// DEPRECATED(1.13) Parameter() call: instead of a full ParamHints
|
||||
/// argument, there is just a bool `lockgeom` that default to true, and
|
||||
/// when set to false is the same thing as setting
|
||||
/// `ParamHints::interpolated`.
|
||||
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
const void* val, bool lockgeom)
|
||||
{
|
||||
return Parameter(group, name, t, val,
|
||||
lockgeom ? ParamHints::none
|
||||
: ParamHints::interpolated);
|
||||
}
|
||||
|
||||
const void* val, bool lockgeom = true);
|
||||
// Shortcuts for param passing a single int, float, or string.
|
||||
bool Parameter(ShaderGroup& group, string_view name, int val,
|
||||
ParamHints hints = ParamHints::none)
|
||||
{
|
||||
return Parameter(group, name, TypeDesc::INT, &val, hints);
|
||||
}
|
||||
bool Parameter(ShaderGroup& group, string_view name, float val,
|
||||
ParamHints hints = ParamHints::none)
|
||||
{
|
||||
return Parameter(group, name, TypeDesc::FLOAT, &val, hints);
|
||||
}
|
||||
bool Parameter(ShaderGroup& group, string_view name, const std::string& val,
|
||||
ParamHints hints = ParamHints::none)
|
||||
{
|
||||
const char* s = val.c_str();
|
||||
return Parameter(group, name, TypeDesc::STRING, &s, hints);
|
||||
}
|
||||
bool Parameter(ShaderGroup& group, string_view name, ustring val,
|
||||
ParamHints hints = ParamHints::none)
|
||||
{
|
||||
return Parameter(group, name, TypeDesc::STRING, (const char**)&val,
|
||||
hints);
|
||||
}
|
||||
|
||||
// DEPRECATED(1.13): use the version above that takes ParamHints.
|
||||
// This is the old version that takes `bool lockgeom`.
|
||||
bool Parameter(ShaderGroup& group, string_view name, int val,
|
||||
bool lockgeom = true)
|
||||
{
|
||||
@@ -698,8 +589,10 @@ public:
|
||||
/// Replace a parameter value in a previously-declared shader group.
|
||||
/// This is meant to called after the ShaderGroupBegin/End, but will
|
||||
/// fail if the shader has already been irrevocably optimized/compiled,
|
||||
/// unless the particular parameter is marked as either interpolated=1
|
||||
/// or interactive=1.
|
||||
/// unless the particular parameter is marked as lockgeom=0 (which
|
||||
/// indicates that it's a parameter that may be overridden by the
|
||||
/// geometric primitive). This call gives you a way of changing the
|
||||
/// instance value, even if it's not a geometric override.
|
||||
bool ReParameter(ShaderGroup& group, string_view layername,
|
||||
string_view paramname, TypeDesc type, const void* val);
|
||||
// Shortcuts for param passing a single int, float, or string.
|
||||
@@ -735,22 +628,13 @@ public:
|
||||
// above that take an explicit `ShaderGroup&`, which are thread-safe
|
||||
// and re-entrant.
|
||||
bool Parameter(string_view name, TypeDesc t, const void* val,
|
||||
ParamHints hints = ParamHints::none);
|
||||
bool lockgeom = true);
|
||||
bool Shader(string_view shaderusage, string_view shadername,
|
||||
string_view layername);
|
||||
bool ConnectShaders(string_view srclayer, string_view srcparam,
|
||||
string_view dstlayer, string_view dstparam);
|
||||
bool ShaderGroupEnd(void);
|
||||
|
||||
// DEPRECATED(1.13): use the version above that takes ParamHints.
|
||||
// This is the old version that takes `bool lockgeom`.
|
||||
bool Parameter(string_view name, TypeDesc t, const void* val, bool lockgeom)
|
||||
{
|
||||
return Parameter(name, t, val,
|
||||
lockgeom ? ParamHints::none
|
||||
: ParamHints::interpolated);
|
||||
}
|
||||
|
||||
/// Create a per-thread data needed for shader execution. It's very
|
||||
/// important for the app to never use a PerThreadInfo from more than
|
||||
/// one thread (and probably a good idea allocate only one PerThreadInfo
|
||||
|
||||
+297
-292
File diff suppressed because it is too large
Load Diff
@@ -18,14 +18,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <OSL/oslversion.h>
|
||||
|
||||
#if defined(__x86_64__) && !defined(__CUDA_ARCH__)
|
||||
# include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Detect which compiler and version we're using
|
||||
@@ -503,60 +499,6 @@
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
|
||||
/// Standards-compliant bit cast of two equally sized types. This is used
|
||||
/// equivalently to C++20 std::bit_cast, but it works prior to C++20 and
|
||||
/// it has the right decorators to work with Cuda.
|
||||
/// @version 1.13.2
|
||||
template <typename To, typename From>
|
||||
OSL_FORCEINLINE OSL_HOSTDEVICE To bitcast(const From& src) noexcept {
|
||||
// NOTE: this is the only standards compliant way of doing this type of casting,
|
||||
// luckily the compilers we care about know how to optimize away this idiom.
|
||||
static_assert(sizeof(From) == sizeof(To),
|
||||
"bit_cast must be between objects of the same size");
|
||||
To dst;
|
||||
memcpy((void*)&dst, &src, sizeof(From));
|
||||
return dst;
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) && !defined(__CUDA_ARCH__) && \
|
||||
(defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) \
|
||||
|| OSL_CLANG_VERSION >= 100000 || OSL_APPLE_CLANG_VERSION >= 130000)
|
||||
// On x86/x86_64 for certain compilers we can use Intel CPU intrinsics for
|
||||
// some common bitcast cases that might be even more understandable to the
|
||||
// compiler and generate better code without its getting confused about the
|
||||
// memcpy in the general case. We're a bit conservative with the compiler
|
||||
// version checks here, it may be that some earlier versions support these
|
||||
// intrinsics.
|
||||
|
||||
template<> OSL_FORCEINLINE uint32_t bitcast<uint32_t, float>(const float& val) noexcept {
|
||||
return static_cast<uint32_t>(_castf32_u32(val));
|
||||
}
|
||||
template<> OSL_FORCEINLINE int32_t bitcast<int32_t, float>(const float& val) noexcept {
|
||||
return static_cast<int32_t>(_castf32_u32(val));
|
||||
}
|
||||
template<> OSL_FORCEINLINE float bitcast<float, uint32_t>(const uint32_t& val) noexcept {
|
||||
return _castu32_f32(val);
|
||||
}
|
||||
template<> OSL_FORCEINLINE float bitcast<float, int32_t>(const int32_t& val) noexcept {
|
||||
return _castu32_f32(val);
|
||||
}
|
||||
template<> OSL_FORCEINLINE uint64_t bitcast<uint64_t, double>(const double& val) noexcept {
|
||||
return static_cast<uint64_t>(_castf64_u64(val));
|
||||
}
|
||||
template<> OSL_FORCEINLINE int64_t bitcast<int64_t, double>(const double& val) noexcept {
|
||||
return static_cast<int64_t>(_castf64_u64(val));
|
||||
}
|
||||
template<> OSL_FORCEINLINE double bitcast<double, uint64_t>(const uint64_t& val) noexcept {
|
||||
return _castu64_f64(val);
|
||||
}
|
||||
template<> OSL_FORCEINLINE double bitcast<double, int64_t>(const int64_t& val) noexcept {
|
||||
return _castu64_f64(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OSL_CPLUSPLUS_VERSION >= 20
|
||||
using std::assume_aligned;
|
||||
#else
|
||||
|
||||
+126
-152
@@ -2,6 +2,8 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
// clang-format off
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -11,13 +13,14 @@
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
class RendererServices;
|
||||
template<int WidthT> class BatchedRendererServices;
|
||||
template<int WidthT>
|
||||
class BatchedRendererServices;
|
||||
class ShadingContext;
|
||||
struct ShaderGlobals;
|
||||
|
||||
// Tags for polymorphic dispatch
|
||||
template<int SimdWidthT> class WidthOf {
|
||||
};
|
||||
template <int SimdWidthT>
|
||||
class WidthOf {};
|
||||
|
||||
|
||||
/// Opaque pointer to whatever the renderer uses to represent a
|
||||
@@ -46,7 +49,7 @@ public:
|
||||
|
||||
|
||||
RendererServices(TextureSystem* texsys = NULL);
|
||||
virtual ~RendererServices() {}
|
||||
virtual ~RendererServices () { }
|
||||
|
||||
/// Given the name of a 'feature', return whether this RendererServices
|
||||
/// supports it. Feature names include:
|
||||
@@ -59,34 +62,28 @@ public:
|
||||
/// support it, as long as the OSL runtime only uses that feature if the
|
||||
/// supports("feature") says it's present, thus preserving source
|
||||
/// compatibility.
|
||||
virtual int supports(string_view feature) const { return false; }
|
||||
virtual int supports (string_view feature) const { return false; }
|
||||
|
||||
/// Get the 4x4 matrix that transforms by the specified
|
||||
/// transformation at the given time. Return true if ok, false
|
||||
/// on error.
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform, float time)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform, float time) { return false; }
|
||||
|
||||
/// Get the 4x4 matrix that transforms by the specified
|
||||
/// transformation at the given time. Return true if ok, false on
|
||||
/// error. The default implementation is to use get_matrix and
|
||||
/// invert it, but a particular renderer may have a better technique
|
||||
/// and overload the implementation.
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform, float time);
|
||||
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform, float time);
|
||||
|
||||
/// Get the 4x4 matrix that transforms by the specified
|
||||
/// transformation. Return true if ok, false on error. Since no
|
||||
/// time value is given, also return false if the transformation may
|
||||
/// be time-varying.
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform) { return false; }
|
||||
|
||||
/// Get the 4x4 matrix that transforms by the specified
|
||||
/// transformation. Return true if ok, false on error. Since no
|
||||
@@ -94,29 +91,29 @@ public:
|
||||
/// be time-varying. The default implementation is to use
|
||||
/// get_matrix and invert it, but a particular renderer may have a
|
||||
/// better technique and overload the implementation.
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform);
|
||||
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform);
|
||||
|
||||
/// Get the 4x4 matrix that transforms points from the named
|
||||
/// 'from' coordinate system to "common" space at the given time.
|
||||
/// Returns true if ok, false if the named matrix is not known.
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from, float time);
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring from, float time) { return false; }
|
||||
|
||||
/// Get the 4x4 matrix that transforms points from "common" space to
|
||||
/// the named 'to' coordinate system to at the given time. The
|
||||
/// default implementation is to use get_matrix and invert it, but a
|
||||
/// particular renderer may have a better technique and overload the
|
||||
/// implementation.
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash to, float time);
|
||||
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring to, float time);
|
||||
|
||||
/// Get the 4x4 matrix that transforms 'from' to "common" space.
|
||||
/// Since there is no time value passed, return false if the
|
||||
/// transformation may be time-varying (as well as if it's not found
|
||||
/// at all).
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from);
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring from) { return false; }
|
||||
|
||||
/// Get the 4x4 matrix that transforms points from "common" space to
|
||||
/// the named 'to' coordinate system. Since there is no time value
|
||||
@@ -125,8 +122,8 @@ public:
|
||||
/// implementation is to use get_matrix and invert it, but a
|
||||
/// particular renderer may have a better technique and overload the
|
||||
/// implementation.
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash to);
|
||||
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring to);
|
||||
|
||||
/// Transform points Pin[0..npoints-1] in named coordinate system
|
||||
/// 'from' into 'to' coordinates, storing the result in Pout[] using
|
||||
@@ -151,10 +148,11 @@ public:
|
||||
/// Note to RendererServices implementations: just return 'false'
|
||||
/// if there isn't a special nonlinear transformation between the
|
||||
/// two spaces.
|
||||
virtual bool transform_points(ShaderGlobals* sg, ustringhash from,
|
||||
ustringhash to, float time, const Vec3* Pin,
|
||||
Vec3* Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype);
|
||||
virtual bool transform_points (ShaderGlobals *sg,
|
||||
ustring from, ustring to, float time,
|
||||
const Vec3 *Pin, Vec3 *Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype)
|
||||
{ return false; }
|
||||
|
||||
|
||||
/// Get the named attribute from the renderer and if found then
|
||||
@@ -169,39 +167,36 @@ public:
|
||||
/// run on. Be robust to this situation, return 'true' (retrieve the
|
||||
/// attribute) if you can (known object and attribute name), but
|
||||
/// otherwise just fail by returning 'false'.
|
||||
virtual bool get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
virtual bool get_attribute (ShaderGlobals *sg, bool derivatives,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void *val) { return false; }
|
||||
|
||||
/// Similar to get_attribute(); this method will return the 'index'
|
||||
/// element of an attribute array.
|
||||
virtual bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val);
|
||||
virtual bool get_array_attribute (ShaderGlobals *sg, bool derivatives,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, int index, void *val) { return false; }
|
||||
|
||||
/// Get the named user-data from the current object and write it into
|
||||
/// 'val'. If derivatives is true, the derivatives should be written into val
|
||||
/// as well. Return false if no user-data with the given name and type was
|
||||
/// found.
|
||||
virtual bool get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val);
|
||||
virtual bool get_userdata (bool derivatives, ustring name, TypeDesc type,
|
||||
ShaderGlobals *sg, void *val) { return false; }
|
||||
|
||||
/// Given the name of a texture, return an opaque handle that can be used
|
||||
/// with texture calls to avoid the name lookups. The `options`, if not
|
||||
/// null, may be used in renderer-specific ways to specialize a handle
|
||||
/// based on certain texture option choices.
|
||||
virtual TextureHandle*
|
||||
get_texture_handle(ustringhash filename, ShadingContext* context,
|
||||
const TextureOpt* options = nullptr);
|
||||
/// Given the name of a texture, return an opaque handle that can be
|
||||
/// used with texture calls to avoid the name lookups.
|
||||
virtual TextureHandle * get_texture_handle (ustring filename,
|
||||
ShadingContext *context);
|
||||
|
||||
/// Return true if the texture handle (previously returned by
|
||||
/// get_texture_handle()) is a valid texture that can be subsequently
|
||||
/// read or sampled.
|
||||
virtual bool good(TextureHandle* texture_handle);
|
||||
virtual bool good (TextureHandle *texture_handle);
|
||||
|
||||
/// Return true if the texture handle (previously returned by
|
||||
/// get_texture_handle()) is udim
|
||||
virtual bool is_udim(TextureHandle* texture_handle);
|
||||
virtual bool is_udim (TextureHandle *texture_handle);
|
||||
|
||||
/// Filtered 2D texture lookup for a single point.
|
||||
///
|
||||
@@ -229,13 +224,13 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual bool texture(ustringhash filename, TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg, float s,
|
||||
float t, float dsdx, float dtdx, float dsdy,
|
||||
float dtdy, int nchannels, float* result,
|
||||
float* dresultds, float* dresultdt,
|
||||
ustringhash* errormessage);
|
||||
virtual bool texture (ustring filename, TextureHandle *texture_handle,
|
||||
TexturePerthread *texture_thread_info,
|
||||
TextureOpt &options, ShaderGlobals *sg,
|
||||
float s, float t, float dsdx, float dtdx,
|
||||
float dsdy, float dtdy, int nchannels,
|
||||
float *result, float *dresultds, float *dresultdt,
|
||||
ustring *errormessage);
|
||||
|
||||
/// Filtered 3D texture lookup for a single point.
|
||||
///
|
||||
@@ -262,13 +257,14 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual bool texture3d(ustringhash filename, TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg,
|
||||
const Vec3& P, const Vec3& dPdx, const Vec3& dPdy,
|
||||
const Vec3& dPdz, int nchannels, float* result,
|
||||
float* dresultds, float* dresultdt, float* dresultdr,
|
||||
ustringhash* errormessage);
|
||||
virtual bool texture3d (ustring filename, TextureHandle *texture_handle,
|
||||
TexturePerthread *texture_thread_info,
|
||||
TextureOpt &options, ShaderGlobals *sg,
|
||||
const Vec3 &P, const Vec3 &dPdx, const Vec3 &dPdy,
|
||||
const Vec3 &dPdz, int nchannels,
|
||||
float *result, float *dresultds,
|
||||
float *dresultdt, float *dresultdr,
|
||||
ustring *errormessage);
|
||||
|
||||
/// Filtered environment lookup for a single point.
|
||||
///
|
||||
@@ -292,13 +288,13 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual bool environment(ustringhash filename,
|
||||
TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg,
|
||||
const Vec3& R, const Vec3& dRdx, const Vec3& dRdy,
|
||||
int nchannels, float* result, float* dresultds,
|
||||
float* dresultdt, ustringhash* errormessage);
|
||||
virtual bool environment (ustring filename, TextureHandle *texture_handle,
|
||||
TexturePerthread *texture_thread_info,
|
||||
TextureOpt &options, ShaderGlobals *sg,
|
||||
const Vec3 &R, const Vec3 &dRdx, const Vec3 &dRdy,
|
||||
int nchannels, float *result,
|
||||
float *dresultds, float *dresultdt,
|
||||
ustring *errormessage);
|
||||
|
||||
/// Get information about the given texture. Return true if found
|
||||
/// and the data has been put in *data. Return false if the texture
|
||||
@@ -319,20 +315,24 @@ public:
|
||||
/// messages (in case of failure, when the function returns false) will
|
||||
/// be stored there, leaving it up to the caller/shader to handle the
|
||||
/// error.
|
||||
virtual bool get_texture_info(ustringhash filename,
|
||||
TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ShadingContext* shading_context, int subimage,
|
||||
ustringhash dataname, TypeDesc datatype,
|
||||
void* data, ustringhash* errormessage);
|
||||
virtual bool get_texture_info (ustring filename,
|
||||
TextureHandle *texture_handle,
|
||||
TexturePerthread *texture_thread_info,
|
||||
ShadingContext *shading_context,
|
||||
int subimage,
|
||||
ustring dataname, TypeDesc datatype,
|
||||
void *data,
|
||||
ustring *errormessage);
|
||||
|
||||
virtual bool get_texture_info(ustringhash filename,
|
||||
TextureHandle* texture_handle, float s,
|
||||
float t,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ShadingContext* shading_context, int subimage,
|
||||
ustringhash dataname, TypeDesc datatype,
|
||||
void* data, ustringhash* errormessage);
|
||||
virtual bool get_texture_info (ustring filename,
|
||||
TextureHandle *texture_handle,
|
||||
float s, float t,
|
||||
TexturePerthread *texture_thread_info,
|
||||
ShadingContext *shading_context,
|
||||
int subimage,
|
||||
ustring dataname, TypeDesc datatype,
|
||||
void *data,
|
||||
ustring *errormessage);
|
||||
|
||||
|
||||
/// Lookup nearest points in a point cloud. It will search for
|
||||
@@ -343,38 +343,40 @@ public:
|
||||
/// derivatives will be computed for distances (when provided).
|
||||
///
|
||||
/// Return the number of points found, always < max_points
|
||||
virtual int pointcloud_search(ShaderGlobals* sg, ustringhash filename,
|
||||
const OSL::Vec3& center, float radius,
|
||||
int max_points, bool sort,
|
||||
size_t* out_indices, float* out_distances,
|
||||
int derivs_offset);
|
||||
virtual int pointcloud_search (ShaderGlobals *sg,
|
||||
ustring filename, const OSL::Vec3 ¢er,
|
||||
float radius, int max_points, bool sort,
|
||||
size_t *out_indices,
|
||||
float *out_distances, int derivs_offset);
|
||||
|
||||
/// Retrieve an attribute for an index list. The result is another array
|
||||
/// of the requested type stored in out_data.
|
||||
///
|
||||
/// Return 1 if the attribute is found, 0 otherwise.
|
||||
virtual int pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
size_t* indices, int count,
|
||||
ustringhash attr_name, TypeDesc attr_type,
|
||||
void* out_data);
|
||||
virtual int pointcloud_get (ShaderGlobals *sg,
|
||||
ustring filename, size_t *indices, int count,
|
||||
ustring attr_name, TypeDesc attr_type,
|
||||
void *out_data);
|
||||
|
||||
/// Write a point to the named pointcloud, which will be saved
|
||||
/// at the end of the frame. Return true if everything is ok,
|
||||
/// false if there was an error.
|
||||
virtual bool pointcloud_write(ShaderGlobals* sg, ustringhash filename,
|
||||
const OSL::Vec3& pos, int nattribs,
|
||||
const ustringrep* names,
|
||||
const TypeDesc* types, const void** data);
|
||||
virtual bool pointcloud_write (ShaderGlobals *sg,
|
||||
ustring filename, const OSL::Vec3 &pos,
|
||||
int nattribs, const ustring *names,
|
||||
const TypeDesc *types,
|
||||
const void **data);
|
||||
|
||||
/// Options for the trace call.
|
||||
struct TraceOpt {
|
||||
float mindist; ///< ignore hits closer than this
|
||||
float maxdist; ///< ignore hits farther than this
|
||||
bool shade; ///< whether to shade what is hit
|
||||
ustringrep traceset; ///< named trace set
|
||||
TraceOpt() : mindist(0.0f), maxdist(1.0e30), shade(false) {}
|
||||
float mindist; ///< ignore hits closer than this
|
||||
float maxdist; ///< ignore hits farther than this
|
||||
bool shade; ///< whether to shade what is hit
|
||||
ustring traceset; ///< named trace set
|
||||
TraceOpt () : mindist(0.0f), maxdist(1.0e30), shade(false) { }
|
||||
|
||||
enum class LLVMMemberIndex {
|
||||
enum class LLVMMemberIndex
|
||||
{
|
||||
mindist = 0,
|
||||
maxdist,
|
||||
shade,
|
||||
@@ -385,59 +387,37 @@ public:
|
||||
|
||||
/// Immediately trace a ray from P in the direction R. Return true
|
||||
/// if anything hit, otherwise false.
|
||||
virtual bool trace(TraceOpt& options, ShaderGlobals* sg, const OSL::Vec3& P,
|
||||
const OSL::Vec3& dPdx, const OSL::Vec3& dPdy,
|
||||
const OSL::Vec3& R, const OSL::Vec3& dRdx,
|
||||
const OSL::Vec3& dRdy);
|
||||
virtual bool trace (TraceOpt &options, ShaderGlobals *sg,
|
||||
const OSL::Vec3 &P, const OSL::Vec3 &dPdx,
|
||||
const OSL::Vec3 &dPdy, const OSL::Vec3 &R,
|
||||
const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Get the named message from the renderer and if found then
|
||||
/// write it into 'val'. Otherwise, return false. This is only
|
||||
/// called for "sourced" messages, not ordinary intra-group messages.
|
||||
virtual bool getmessage(ShaderGlobals* sg, ustringhash source,
|
||||
ustringhash name, TypeDesc type, void* val,
|
||||
bool derivatives);
|
||||
virtual bool getmessage (ShaderGlobals *sg, ustring source, ustring name,
|
||||
TypeDesc type, void *val, bool derivatives) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return a pointer to the texture system (if available).
|
||||
virtual TextureSystem* texturesys() const;
|
||||
virtual TextureSystem *texturesys () const;
|
||||
|
||||
/// Allocate `size` bytes of memory on the device that will execute the
|
||||
/// shaders. (Equivalent to malloc() on the CPU.)
|
||||
virtual void* device_alloc(size_t size)
|
||||
virtual uint64_t register_global (const std::string& var_name,
|
||||
uint64_t value)
|
||||
{
|
||||
return nullptr;
|
||||
// Note: for an OptiX-based renderer, this method should be overriden
|
||||
// with something like:
|
||||
//
|
||||
// void* dptr;
|
||||
// auto r = cudaMalloc(&dptr, size);
|
||||
// return r == cudaSuccess ? dptr : nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Free a previous allocation (by `device_alloc()`) on the device that
|
||||
/// will execute the shaders. (Equivalent to free() on the CPU.)
|
||||
virtual void device_free(void* ptr)
|
||||
virtual bool fetch_global (const std::string& var_name,
|
||||
uint64_t* value)
|
||||
{
|
||||
// Note: for an OptiX-based renderer, this method should be overriden
|
||||
// with something like:
|
||||
//
|
||||
// cudaFree(ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Copy `size` bytes from location `src_host` on the host/CPU (the
|
||||
/// machine making this call) into location `dst_device` on the device
|
||||
/// executing shaders. (Equivalent to `memcpy(dst, src, size)` on the
|
||||
/// CPU.)
|
||||
virtual void* copy_to_device(void* dst_device, const void* src_host,
|
||||
size_t size)
|
||||
{
|
||||
return nullptr;
|
||||
// Note: for an OptiX-based renderer, this method should be overriden
|
||||
// with something like:
|
||||
//
|
||||
// auto r = cudaMemcpy(dst_device, src_host, size,
|
||||
// cudaMemcpyHostToDevice);
|
||||
// return dst_device;
|
||||
}
|
||||
|
||||
|
||||
/// Options we use for noise calls.
|
||||
struct NoiseOpt {
|
||||
@@ -446,25 +426,19 @@ public:
|
||||
Vec3 direction;
|
||||
float bandwidth;
|
||||
float impulses;
|
||||
NoiseOpt()
|
||||
: anisotropic(0)
|
||||
, do_filter(true)
|
||||
, direction(1.0f, 0.0f, 0.0f)
|
||||
, bandwidth(1.0f)
|
||||
, impulses(16.0f)
|
||||
{
|
||||
}
|
||||
NoiseOpt () : anisotropic(0), do_filter(true),
|
||||
direction(1.0f,0.0f,0.0f), bandwidth(1.0f), impulses(16.0f) { }
|
||||
};
|
||||
|
||||
/// A renderer may choose to support batched execution by providing pointers
|
||||
/// to objects satisfying the BatchedRendererServices<WidthOf<#>> interface
|
||||
/// for specific batch sizes.
|
||||
/// Unless overridden, a nullptr is returned.
|
||||
virtual BatchedRendererServices<16>* batched(WidthOf<16>);
|
||||
virtual BatchedRendererServices<8>* batched(WidthOf<8>);
|
||||
virtual BatchedRendererServices<16> * batched(WidthOf<16>);
|
||||
virtual BatchedRendererServices<8> * batched(WidthOf<8>);
|
||||
|
||||
protected:
|
||||
TextureSystem* m_texturesys; // A place to hold a TextureSystem
|
||||
TextureSystem *m_texturesys; // A place to hold a TextureSystem
|
||||
};
|
||||
|
||||
|
||||
|
||||
+9
-89
@@ -895,8 +895,6 @@ template<int WidthT> struct alignas(VecReg<WidthT>) Block<Matrix44, WidthT> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Specialization of Block for ustring
|
||||
template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustring, WidthT> {
|
||||
static constexpr int width = WidthT;
|
||||
typedef ustring ValueType;
|
||||
@@ -944,58 +942,6 @@ template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustring, WidthT> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Specialization of Block for ustringhash
|
||||
template<int WidthT> struct alignas(VecReg<WidthT>) Block<ustringhash, WidthT> {
|
||||
static constexpr int width = WidthT;
|
||||
typedef ustringhash ValueType;
|
||||
|
||||
// To enable vectorization, use uintptr_t to store the ustringhash (const char *)
|
||||
size_t str[WidthT];
|
||||
static_assert(sizeof(ustringhash) == sizeof(size_t),
|
||||
"ustringhash must be size_t");
|
||||
|
||||
OSL_FORCEINLINE Block() = default;
|
||||
// We want to avoid accidentally copying these when the intent was to just pass a reference
|
||||
Block(const Block& other) = delete;
|
||||
|
||||
OSL_FORCEINLINE void set(int lane, const ustringhash& value)
|
||||
{
|
||||
str[lane] = value.hash();
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set(int lane, ustring value)
|
||||
{
|
||||
str[lane] = value.hash();
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set(int lane, const ustringhash& value, bool laneMask)
|
||||
{
|
||||
if (laneMask)
|
||||
str[lane] = value.hash();
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE ustringhash get(int lane) const
|
||||
{
|
||||
#ifdef OIIO_USTRING_HAS_CTR_FROM_USTRINGHASH
|
||||
return ustringhash::from_hash(str[lane]);
|
||||
#else
|
||||
return OSL::bitcast<ustringhash>(str[lane]);
|
||||
#endif
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE pvt::LaneProxy<ValueType, WidthT> operator[](int lane)
|
||||
{
|
||||
return pvt::LaneProxy<ValueType, WidthT>(*this, lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE pvt::ConstLaneProxy<const ValueType, WidthT>
|
||||
operator[](int lane) const
|
||||
{
|
||||
return pvt::ConstLaneProxy<const ValueType, WidthT>(*this, lane);
|
||||
}
|
||||
};
|
||||
|
||||
template<int WidthT>
|
||||
struct alignas(VecReg<WidthT>) Block<Dual2<float>, WidthT> {
|
||||
typedef Dual2<float> ValueType;
|
||||
@@ -2899,7 +2845,7 @@ public:
|
||||
// Populate all data lanes of the MaskedData by broadcasting the
|
||||
// single instance of data pointed to.
|
||||
// Masked off lanes are not overwritten.
|
||||
// when has_derivs() is true, Dx and Dy will be zeroed
|
||||
// Includes value, as well as Dx and Dy when has_derivs() is true
|
||||
OSL_FORCEINLINE void assign_all_from_scalar(const void* ptr_data) const;
|
||||
|
||||
|
||||
@@ -2917,9 +2863,6 @@ private:
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void assign_all_from_scalar_type(const void* ptr_data,
|
||||
int deriv_index) const;
|
||||
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void zero_all_type(int deriv_index) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -3435,33 +3378,6 @@ MaskedData<WidthT>::assign_all_from_scalar_type(const void* ptr_data,
|
||||
}
|
||||
}
|
||||
|
||||
template<int WidthT>
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void
|
||||
MaskedData<WidthT>::zero_all_type(int deriv_index) const
|
||||
{
|
||||
// We can't just do a memset because some lanes may be masked off
|
||||
// Use a SIMD loop to perform masked assignment.
|
||||
auto* dst_blocks = pvt::block_cast<DataT, WidthT>(m_ptr);
|
||||
int elem_count = static_cast<int>(m_type.numelements());
|
||||
int comp_count = m_type.aggregate;
|
||||
int deriv_offset = deriv_index * elem_count * comp_count;
|
||||
for (int array_index = 0; array_index < elem_count; ++array_index) {
|
||||
int array_offset = array_index * comp_count;
|
||||
for (int comp_index = 0; comp_index < comp_count; ++comp_index) {
|
||||
int combined_index = deriv_offset + array_offset + comp_index;
|
||||
auto& bdst = dst_blocks[combined_index];
|
||||
|
||||
Masked<DataT, WidthT> wdest(bdst, mask());
|
||||
|
||||
OSL_OMP_PRAGMA(omp simd simdlen(WidthT))
|
||||
for (int lane = 0; lane < WidthT; ++lane) {
|
||||
wdest[lane] = DataT {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int WidthT>
|
||||
OSL_FORCEINLINE void
|
||||
MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
|
||||
@@ -3477,12 +3393,16 @@ MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
|
||||
assign_all_from_scalar_type<ustring>(ptr_data, /*deriv_index*/ 0);
|
||||
}
|
||||
if (has_derivs()) {
|
||||
size_t src_size = type().size();
|
||||
const char* dx_src = reinterpret_cast<const char*>(ptr_data) + src_size;
|
||||
const char* dy_src = dx_src + src_size;
|
||||
|
||||
if (isBase32bit) {
|
||||
zero_all_type<int>(/*deriv_index*/ 1);
|
||||
zero_all_type<int>(/*deriv_index*/ 2);
|
||||
assign_all_from_scalar_type<int>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<int>(dy_src, /*deriv_index*/ 2);
|
||||
} else {
|
||||
zero_all_type<ustring>(/*deriv_index*/ 1);
|
||||
zero_all_type<ustring>(/*deriv_index*/ 2);
|
||||
assign_all_from_scalar_type<ustring>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<ustring>(dy_src, /*deriv_index*/ 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <OSL/oslconfig.h>
|
||||
#include <OSL/oslversion.h>
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <cuda_runtime_api.h>
|
||||
# include <optix.h>
|
||||
# ifdef _WIN32
|
||||
@@ -18,9 +18,8 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <OSL/device_ptr.h>
|
||||
|
||||
#if !OSL_USE_OPTIX && !defined(__CUDA_ARCH__)
|
||||
#if !defined(OSL_USE_OPTIX) && !defined(__CUDA_ARCH__)
|
||||
using CUdeviceptr = void*;
|
||||
using float3 = OSL::Vec3;
|
||||
#endif
|
||||
@@ -29,7 +28,7 @@ using float3 = OSL::Vec3;
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// If OptiX is available, alias everything in optix:: namespace into
|
||||
|
||||
+9
-50
@@ -386,7 +386,6 @@ public:
|
||||
/// vector-like (and match their array-ness and closure-ness), or
|
||||
/// if both are structures with matching fields.
|
||||
friend bool equivalent(const TypeSpec& a, const TypeSpec& b);
|
||||
friend bool relaxed_equivalent(const TypeSpec& a, const TypeSpec& b);
|
||||
|
||||
/// Is type src is assignable to dst? It is if they are the equivalent(),
|
||||
/// or if dst is a float or float-aggregate and src is a float or int.
|
||||
@@ -478,9 +477,7 @@ public:
|
||||
, m_const_initializer(false)
|
||||
, m_connected_down(false)
|
||||
, m_initialized(false)
|
||||
, m_interpolated(false)
|
||||
, m_interactive(false)
|
||||
, m_noninteractive(false)
|
||||
, m_lockgeom(false)
|
||||
, m_allowconnect(true)
|
||||
, m_renderer_output(false)
|
||||
, m_readonly(false)
|
||||
@@ -632,18 +629,7 @@ public:
|
||||
OSL_ASSERT(arena == SymArena::Absolute);
|
||||
m_arena = static_cast<unsigned int>(arena);
|
||||
m_data = ptr;
|
||||
}
|
||||
|
||||
/// Specify the location of the symbol's data, relative to an arena
|
||||
/// (which for now must be Absolute).
|
||||
void set_dataptr(SymArena arena, void* ptr, int offset)
|
||||
{
|
||||
// OSL_ASSERT(arena == SymArena::Absolute);
|
||||
m_arena = static_cast<unsigned int>(arena);
|
||||
m_data = ptr;
|
||||
m_dataoffset = offset;
|
||||
OSL::print("setting sym {} arena {} offset {}\n", name(), int(m_arena),
|
||||
m_dataoffset);
|
||||
// m_dataoffset = static_cast<int64_t>((char*)ptr - (char*)0);
|
||||
}
|
||||
|
||||
|
||||
@@ -884,36 +870,11 @@ public:
|
||||
|
||||
bool lockgeom() const
|
||||
{
|
||||
// We can lock a value to a constant (at all places on all pieces of
|
||||
// geometry) if it is neither interpolated nor interactively modified.
|
||||
return !m_interpolated && !m_interactive;
|
||||
return m_lockgeom;
|
||||
}
|
||||
|
||||
bool interpolated() const
|
||||
void lockgeom(bool lock)
|
||||
{
|
||||
return m_interpolated;
|
||||
}
|
||||
void interpolated(bool val)
|
||||
{
|
||||
m_interpolated = val;
|
||||
}
|
||||
|
||||
bool interactive() const
|
||||
{
|
||||
return m_interactive;
|
||||
}
|
||||
void interactive(bool val)
|
||||
{
|
||||
m_interactive = val;
|
||||
}
|
||||
|
||||
bool noninteractive() const
|
||||
{
|
||||
return m_noninteractive;
|
||||
}
|
||||
void noninteractive(bool val)
|
||||
{
|
||||
m_noninteractive = val;
|
||||
m_lockgeom = lock;
|
||||
}
|
||||
|
||||
bool allowconnect() const
|
||||
@@ -1067,12 +1028,10 @@ protected:
|
||||
unsigned m_symtype : 4; ///< Kind of symbol (param, local, etc.)
|
||||
unsigned m_has_derivs : 1; ///< Step to derivs (0 == has no derivs)
|
||||
unsigned m_const_initializer : 1; ///< initializer is a constant expression
|
||||
unsigned m_connected_down : 1; ///< Connected to a later/downstream layer
|
||||
unsigned m_initialized : 1; ///< If a param, has it been initialized?
|
||||
unsigned m_interpolated : 1; ///< Is the param overridden by geom?
|
||||
unsigned m_interactive : 1; ///< May the param change interactively?
|
||||
unsigned m_noninteractive : 1; ///< The param def won't modify interactively
|
||||
unsigned m_allowconnect : 1; ///< Is the param allowd to connect?
|
||||
unsigned m_connected_down : 1; ///< Connected to a later/downstream layer
|
||||
unsigned m_initialized : 1; ///< If a param, has it been initialized?
|
||||
unsigned m_lockgeom : 1; ///< Is the param not overridden by geom?
|
||||
unsigned m_allowconnect : 1; ///< Is the param not overridden by geom?
|
||||
unsigned m_renderer_output : 1; ///< Is this sym a renderer output?
|
||||
unsigned m_readonly : 1; ///< read-only symbol
|
||||
unsigned m_is_uniform : 1; ///< symbol is uniform under batched execution
|
||||
|
||||
+36
-97
@@ -1116,151 +1116,90 @@ ASTassign_expression::opword() const
|
||||
OSL_ASSERT (0 && "unknown assignment expression");
|
||||
return "assign"; // punt
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
|
||||
ASTunary_expression::ASTunary_expression(OSLCompilerImpl* comp, int op,
|
||||
ASTNode* expr)
|
||||
: ASTNode(unary_expression_node, comp, op, expr)
|
||||
ASTunary_expression::ASTunary_expression (OSLCompilerImpl *comp, int op,
|
||||
ASTNode *expr)
|
||||
: ASTNode (unary_expression_node, comp, op, expr)
|
||||
{
|
||||
// Check for a user-overloaded function for this operator
|
||||
Symbol* sym = comp->symtab().find(
|
||||
ustring::fmtformat("__operator__{}__", opword()));
|
||||
Symbol *sym = comp->symtab().find(ustring::fmtformat("__operator__{}__", opword()));
|
||||
if (sym && sym->symtype() == SymTypeFunction)
|
||||
m_function_overload = (FunctionSymbol*)sym;
|
||||
m_function_overload = (FunctionSymbol *)sym;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
ASTunary_expression::childname(size_t i) const
|
||||
const char *
|
||||
ASTunary_expression::childname (size_t i) const
|
||||
{
|
||||
static const char* name[] = { "expression" };
|
||||
static const char *name[] = { "expression" };
|
||||
return name[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
ASTunary_expression::opname() const
|
||||
const char *
|
||||
ASTunary_expression::opname () const
|
||||
{
|
||||
switch (m_op) {
|
||||
case Add: return "+";
|
||||
case Sub: return "-";
|
||||
case Not: return "!";
|
||||
case Compl: return "~";
|
||||
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
|
||||
case Add : return "+";
|
||||
case Sub : return "-";
|
||||
case Not : return "!";
|
||||
case Compl : return "~";
|
||||
default:
|
||||
OSL_ASSERT (0 && "unknown unary expression");
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
ASTunary_expression::opword() const
|
||||
const char *
|
||||
ASTunary_expression::opword () const
|
||||
{
|
||||
switch (m_op) {
|
||||
case Add: return "add";
|
||||
case Sub: return "neg";
|
||||
case Not: return "not";
|
||||
case Compl: return "compl";
|
||||
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
|
||||
case Add : return "add";
|
||||
case Sub : return "neg";
|
||||
case Not : return "not";
|
||||
case Compl : return "compl";
|
||||
default:
|
||||
OSL_ASSERT (0 && "unknown unary expression");
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ASTbinary_expression::ASTbinary_expression(OSLCompilerImpl* comp, Operator op,
|
||||
ASTNode* left, ASTNode* right)
|
||||
: ASTNode(binary_expression_node, comp, op, left, right)
|
||||
ASTbinary_expression::ASTbinary_expression (OSLCompilerImpl *comp, Operator op,
|
||||
ASTNode *left, ASTNode *right)
|
||||
: ASTNode (binary_expression_node, comp, op, left, right)
|
||||
{
|
||||
// Check for a user-overloaded function for this operator.
|
||||
// Disallow a few ops from overloading.
|
||||
if (op != And && op != Or) {
|
||||
ustring funcname = ustring::fmtformat("__operator__{}__", opword());
|
||||
Symbol* sym = comp->symtab().find(funcname);
|
||||
Symbol *sym = comp->symtab().find (funcname);
|
||||
if (sym && sym->symtype() == SymTypeFunction)
|
||||
m_function_overload = (FunctionSymbol*)sym;
|
||||
m_function_overload = (FunctionSymbol *)sym;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ASTNode*
|
||||
ASTbinary_expression::make(OSLCompilerImpl* comp, Operator op, ASTNode* left,
|
||||
ASTNode* right)
|
||||
const char *
|
||||
ASTbinary_expression::childname (size_t i) const
|
||||
{
|
||||
// If the left and right are both literal constants, fold the expression
|
||||
if (left->nodetype() == literal_node && right->nodetype() == literal_node) {
|
||||
ASTNode* cf = nullptr; // constant-folded result
|
||||
if (left->typespec().is_int() && right->typespec().is_int()) {
|
||||
int lv = dynamic_cast<ASTliteral*>(left)->intval();
|
||||
int rv = dynamic_cast<ASTliteral*>(right)->intval();
|
||||
switch (op) {
|
||||
case Mul: cf = new ASTliteral(comp, lv * rv); break;
|
||||
case Div: cf = new ASTliteral(comp, rv ? lv / rv : 0); break;
|
||||
case Add: cf = new ASTliteral(comp, lv + rv); break;
|
||||
case Sub: cf = new ASTliteral(comp, lv - rv); break;
|
||||
case Mod: cf = new ASTliteral(comp, rv ? lv % rv : 0); break;
|
||||
case Equal: cf = new ASTliteral(comp, lv == rv ? 1 : 0); break;
|
||||
case NotEqual: cf = new ASTliteral(comp, lv != rv ? 1 : 0); break;
|
||||
case Greater: cf = new ASTliteral(comp, lv > rv ? 1 : 0); break;
|
||||
case Less: cf = new ASTliteral(comp, lv < rv ? 1 : 0); break;
|
||||
case GreaterEqual:
|
||||
cf = new ASTliteral(comp, lv >= rv ? 1 : 0);
|
||||
break;
|
||||
case LessEqual: cf = new ASTliteral(comp, lv <= rv ? 1 : 0); break;
|
||||
case BitAnd: cf = new ASTliteral(comp, lv & rv); break;
|
||||
case BitOr: cf = new ASTliteral(comp, lv | rv); break;
|
||||
case Xor: cf = new ASTliteral(comp, lv ^ rv); break;
|
||||
case ShiftLeft: cf = new ASTliteral(comp, lv << rv); break;
|
||||
case ShiftRight: cf = new ASTliteral(comp, lv >> rv); break;
|
||||
default: break;
|
||||
}
|
||||
} else if (left->typespec().is_float()
|
||||
&& right->typespec().is_float()) {
|
||||
float lv = dynamic_cast<ASTliteral*>(left)->floatval();
|
||||
float rv = dynamic_cast<ASTliteral*>(right)->floatval();
|
||||
switch (op) {
|
||||
case Mul: cf = new ASTliteral(comp, lv * rv); break;
|
||||
case Div: cf = new ASTliteral(comp, rv ? lv / rv : 0.0f); break;
|
||||
case Add: cf = new ASTliteral(comp, lv + rv); break;
|
||||
case Sub: cf = new ASTliteral(comp, lv - rv); break;
|
||||
case Equal: cf = new ASTliteral(comp, lv == rv ? 1 : 0); break;
|
||||
case NotEqual: cf = new ASTliteral(comp, lv != rv ? 1 : 0); break;
|
||||
case Greater: cf = new ASTliteral(comp, lv > rv ? 1 : 0); break;
|
||||
case Less: cf = new ASTliteral(comp, lv < rv ? 1 : 0); break;
|
||||
case GreaterEqual:
|
||||
cf = new ASTliteral(comp, lv >= rv ? 1 : 0);
|
||||
break;
|
||||
case LessEqual: cf = new ASTliteral(comp, lv <= rv ? 1 : 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (cf) {
|
||||
delete left;
|
||||
delete right;
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
|
||||
return new ASTbinary_expression(comp, op, left, right);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
ASTbinary_expression::childname(size_t i) const
|
||||
{
|
||||
static const char* name[] = { "left", "right" };
|
||||
static const char *name[] = { "left", "right" };
|
||||
return name[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
ASTbinary_expression::opname() const
|
||||
const char *
|
||||
ASTbinary_expression::opname () const
|
||||
{
|
||||
// clang-format off
|
||||
switch (m_op) {
|
||||
|
||||
@@ -832,10 +832,6 @@ public:
|
||||
ASTbinary_expression(OSLCompilerImpl* comp, Operator op, ASTNode* left,
|
||||
ASTNode* right);
|
||||
|
||||
// Special consructor wrapper that can collapse ops between literals
|
||||
static ASTNode* make(OSLCompilerImpl* comp, Operator op, ASTNode* left,
|
||||
ASTNode* right);
|
||||
|
||||
const char* nodetypename() const { return "binary_expression"; }
|
||||
const char* childname(size_t i) const;
|
||||
const char* opname() const;
|
||||
|
||||
@@ -701,12 +701,11 @@ OSLCompilerImpl::write_oso_const_value(const ConstantSymbol* sym) const
|
||||
osofmt("{}{}", sym->get_int(i), nelements > 1 ? " " : "");
|
||||
else if (elemtype == TypeDesc::FLOAT)
|
||||
for (int i = 0; i < nelements; ++i)
|
||||
osofmt("{:.9g}{}", sym->floatval(i), nelements > 1 ? " " : "");
|
||||
osofmt("{}{}", sym->floatval(i), nelements > 1 ? " " : "");
|
||||
else if (equivalent(elemtype, TypeDesc::TypeVector))
|
||||
for (int i = 0; i < nelements; ++i) {
|
||||
Vec3 v = sym->get_vec3(i);
|
||||
osofmt("{:.9g} {:.9g} {:.9g}{}", v.x, v.y, v.z,
|
||||
nelements > 1 ? " " : "");
|
||||
osofmt("{} {} {}{}", v.x, v.y, v.z, nelements > 1 ? " " : "");
|
||||
}
|
||||
else {
|
||||
OSL_ASSERT(0 && "Don't know how to output this constant type");
|
||||
|
||||
+18
-18
@@ -858,109 +858,109 @@ variable_ref
|
||||
binary_expression
|
||||
: expression OR_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Or, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression AND_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::And, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '|' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::BitOr, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '^' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Xor, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '&' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::BitAnd, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression EQ_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Equal, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression NE_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::NotEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '>' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Greater, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression GE_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::GreaterEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '<' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Less, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression LE_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::LessEqual, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression SHL_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::ShiftLeft, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression SHR_OP expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::ShiftRight, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '+' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Add, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '-' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Sub, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '*' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Mul, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '/' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Div, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
| expression '%' expression
|
||||
{
|
||||
$$ = ASTbinary_expression::make(oslcompiler,
|
||||
$$ = new ASTbinary_expression (oslcompiler,
|
||||
ASTNode::Mod, $1, $3);
|
||||
$$->sourceline (@2.first_line);
|
||||
}
|
||||
|
||||
@@ -397,6 +397,15 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
|
||||
// Thread safety with the lexer/parser
|
||||
std::lock_guard<std::mutex> lock(oslcompiler_mutex);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
// This is not necessary for versions of OIIO that have Strutil::stof,
|
||||
// and we can remove it entirely when OIIO 1.9 is the minimum.
|
||||
std::locale oldlocale = std::locale::global (std::locale::classic());
|
||||
#endif
|
||||
|
||||
yyscan_t scanner;
|
||||
yylex_init(&scanner);
|
||||
YY_BUFFER_STATE buffer = yy_scan_string(preprocessed_buffer.c_str(), scanner);
|
||||
@@ -406,6 +415,9 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
|
||||
yy_delete_buffer (buffer, scanner);
|
||||
yylex_destroy(scanner);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
#endif
|
||||
return parseerr;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,10 +143,6 @@ Symbol::print(std::ostream& out, int maxvals) const
|
||||
out << " renderer-output";
|
||||
if (symtype() == SymTypeParam && !lockgeom())
|
||||
out << " lockgeom=0";
|
||||
if (symtype() == SymTypeParam && interactive())
|
||||
out << " interactive=1";
|
||||
if (symtype() == SymTypeParam && noninteractive())
|
||||
out << " interactive=0";
|
||||
}
|
||||
out << "\n";
|
||||
if (symtype() == SymTypeConst) {
|
||||
|
||||
@@ -123,7 +123,7 @@ set (lib_src
|
||||
llvm_gen.cpp llvm_instance.cpp llvm_util.cpp
|
||||
rs_fallback.cpp
|
||||
)
|
||||
if (OSL_BUILD_BATCHED)
|
||||
if (BUILD_BATCHED)
|
||||
list(APPEND lib_src
|
||||
batched_analysis.cpp
|
||||
batched_backendllvm.cpp
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include <OpenImageIO/filesystem.h>
|
||||
#include <OpenImageIO/strutil.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
#include "backendllvm.h"
|
||||
|
||||
@@ -17,6 +21,55 @@ OSL_NAMESPACE_ENTER
|
||||
namespace pvt {
|
||||
|
||||
|
||||
#ifdef OSL_SPI
|
||||
static void
|
||||
check_cwd(ShadingSystemImpl& shadingsys)
|
||||
{
|
||||
std::string err;
|
||||
char pathname[1024] = { "" };
|
||||
if (!getcwd(pathname, sizeof(pathname) - 1)) {
|
||||
int e = errno;
|
||||
err += fmtformat("Failed getcwd(), errno is {}: {}\n", errno, pathname);
|
||||
if (e == EACCES || e == ENOENT) {
|
||||
err += "Read/search permission problem or dir does not exist.\n";
|
||||
const char* pwdenv = getenv("PWD");
|
||||
if (!pwdenv) {
|
||||
err += "$PWD is not even found in the environment.\n";
|
||||
} else {
|
||||
err += fmtformat("$PWD is \"{}\"\n", pwdenv);
|
||||
err += fmtformat("That {}.\n", OIIO::Filesystem::exists(pwdenv)
|
||||
? "exists"
|
||||
: "does NOT exist");
|
||||
err += fmtformat("That {} a directory.\n",
|
||||
OIIO::Filesystem::is_directory(pwdenv)
|
||||
? "is"
|
||||
: "is NOT");
|
||||
std::vector<std::string> pieces;
|
||||
Strutil::split(pwdenv, pieces, "/");
|
||||
std::string p;
|
||||
for (size_t i = 0; i < pieces.size(); ++i) {
|
||||
if (!pieces[i].size())
|
||||
continue;
|
||||
p += "/";
|
||||
p += pieces[i];
|
||||
err += fmtformat(" {} : {} and is{} a directory.\n", p,
|
||||
OIIO::Filesystem::exists(p)
|
||||
? "exists"
|
||||
: "does NOT exist",
|
||||
OIIO::Filesystem::is_directory(p)
|
||||
? ""
|
||||
: " NOT");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err.size())
|
||||
shadingsys.error(err);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
BackendLLVM::BackendLLVM(ShadingSystemImpl& shadingsys, ShaderGroup& group,
|
||||
ShadingContext* ctx)
|
||||
: OSOProcessorBase(shadingsys, group, ctx)
|
||||
@@ -27,7 +80,12 @@ BackendLLVM::BackendLLVM(ShadingSystemImpl& shadingsys, ShaderGroup& group,
|
||||
, m_stat_llvm_opt_time(0)
|
||||
, m_stat_llvm_jit_time(0)
|
||||
{
|
||||
m_use_optix = shadingsys.use_optix();
|
||||
#ifdef OSL_SPI
|
||||
// Temporary (I hope) check to diagnose an intermittent failure of
|
||||
// getcwd inside LLVM. Oy.
|
||||
check_cwd(shadingsys);
|
||||
#endif
|
||||
m_use_optix = shadingsys.renderer()->supports("OptiX");
|
||||
m_use_rs_bitcode = !shadingsys.m_rs_bitcode.empty();
|
||||
m_name_llvm_syms = shadingsys.m_llvm_output_bitcode;
|
||||
|
||||
@@ -226,15 +284,6 @@ BackendLLVM::getLLVMSymbolBase(const Symbol& sym)
|
||||
llvm_type(sym.typespec().elementtype()));
|
||||
return result;
|
||||
}
|
||||
if (sym.symtype() == SymTypeParam && sym.interactive()) {
|
||||
// Special case for interactively-edited parameters -- they live in
|
||||
// the interactive data block for the group.
|
||||
// Generate the pointer to this symbol by offsetting into the
|
||||
// interactive data block.
|
||||
int offset = group().interactive_param_offset(layer(), sym.name());
|
||||
return ll.offset_ptr(m_llvm_interactive_params_ptr, offset,
|
||||
llvm_ptr_type(sym.typespec().elementtype()));
|
||||
}
|
||||
|
||||
if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
|
||||
// Special case for params -- they live in the group data
|
||||
@@ -290,7 +339,6 @@ BackendLLVM::getOrAllocateLLVMSymbol(const Symbol& sym)
|
||||
|
||||
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
llvm::Value*
|
||||
BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
|
||||
int alignment, const void* init_data,
|
||||
@@ -306,7 +354,7 @@ BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
|
||||
} else if (type == TypeDesc::TypeInt) {
|
||||
constant = ll.constant(*(const int*)init_data);
|
||||
} else if (type == TypeDesc::TypeString) {
|
||||
constant = ll.constant64(((const ustring*)init_data)->hash());
|
||||
constant = ll.constant(((const ustring*)init_data)->hash());
|
||||
// N.B. Since this is the OptiX side specifically, we will represent
|
||||
// strings as the ustringhash, so we know it as a constant.
|
||||
} else {
|
||||
@@ -321,11 +369,11 @@ BackendLLVM::addCUDAGlobalVariable(const std::string& name, int size,
|
||||
|
||||
OSL_DASSERT(g_var && "Unable to create GlobalVariable");
|
||||
|
||||
# if OSL_LLVM_VERSION >= 100
|
||||
#if OSL_LLVM_VERSION >= 100
|
||||
g_var->setAlignment(llvm::MaybeAlign(alignment));
|
||||
# else
|
||||
#else
|
||||
g_var->setAlignment(alignment);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
g_var->setLinkage(llvm::GlobalValue::PrivateLinkage);
|
||||
g_var->setVisibility(llvm::GlobalValue::DefaultVisibility);
|
||||
@@ -343,7 +391,14 @@ BackendLLVM::getOrAllocateCUDAVariable(const Symbol& sym)
|
||||
OSL_ASSERT(use_optix()
|
||||
&& "This function is only supported when using OptiX!");
|
||||
|
||||
std::string name = global_unique_symname(sym);
|
||||
// We need to sanitize the symbol name for PTX compatibility. Also, if the
|
||||
// sym name starts with a dollar sign, which are not allowed in PTX
|
||||
// variable names, then prepend another underscore.
|
||||
std::string sym_name = Strutil::replace(sym.name(), ".", "_", true);
|
||||
|
||||
std::string name
|
||||
= fmtformat("{}{}_{}_{}_{}", sym_name.front() == '$' ? "_" : "",
|
||||
sym_name, group().name(), inst()->layername(), sym.layer());
|
||||
|
||||
// Return the Value if it has already been allocated
|
||||
auto it = get_const_map().find(name);
|
||||
@@ -357,7 +412,6 @@ BackendLLVM::getOrAllocateCUDAVariable(const Symbol& sym)
|
||||
return addCUDAGlobalVariable(name, sym.size(), alignment, sym.data(),
|
||||
sym.typespec().simpletype());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -375,7 +429,6 @@ BackendLLVM::llvm_get_pointer(const Symbol& sym, int deriv,
|
||||
llvm::Value* result = NULL;
|
||||
if (sym.symtype() == SymTypeConst) {
|
||||
TypeSpec elemtype = sym.typespec().elementtype();
|
||||
#if OSL_USE_OPTIX
|
||||
if (use_optix()) {
|
||||
// Check the constant map for the named Symbol; if it's found, then
|
||||
// a GlobalVariable has been created for it
|
||||
@@ -386,9 +439,7 @@ BackendLLVM::llvm_get_pointer(const Symbol& sym, int deriv,
|
||||
// N.B. llvm_typedesc() for a string will know that on OptiX,
|
||||
// strings are actually represented as just the hash.
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
// For constants on the CPU side, start with *OUR* pointer to the
|
||||
// constant values.
|
||||
result = ll.constant_ptr(sym.data(),
|
||||
|
||||
@@ -216,21 +216,6 @@ public:
|
||||
/// map, the symbol is alloca'd and placed in the map.
|
||||
llvm::Value* getOrAllocateLLVMSymbol(const Symbol& sym);
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
/// Return a globally unique (to the JIT module) name for symbol `sym`,
|
||||
/// assuming it's part of the currently examined layer of the group.
|
||||
std::string global_unique_symname(const Symbol& sym)
|
||||
{
|
||||
// We need to sanitize the symbol name for PTX compatibility. Also, if
|
||||
// the sym name starts with a dollar sign, which are not allowed in
|
||||
// PTX variable names, then prepend another underscore.
|
||||
auto sym_name = Strutil::replace(sym.name(), ".", "_", true);
|
||||
int layer = sym.layer();
|
||||
const ShaderInstance* inst_ = group()[layer];
|
||||
return fmtformat("{}{}_{}_{}_{}", sym_name.front() == '$' ? "_" : "",
|
||||
sym_name, group().name(), inst_->layername(), layer);
|
||||
}
|
||||
|
||||
/// Allocate a CUDA variable for the given OSL symbol and return a pointer
|
||||
/// to the corresponding LLVM GlobalVariable, or return the pointer if it
|
||||
/// has already been allocated.
|
||||
@@ -244,7 +229,6 @@ public:
|
||||
llvm::Value* addCUDAGlobalVariable(const std::string& name, int size,
|
||||
int alignment, const void* init_data,
|
||||
TypeDesc type = TypeDesc::UNKNOWN);
|
||||
#endif
|
||||
|
||||
/// Retrieve an llvm::Value that is a pointer holding the start address
|
||||
/// of the specified symbol. This always works for globals and params;
|
||||
@@ -282,20 +266,14 @@ public:
|
||||
|
||||
/// Return the ShaderGlobals pointer.
|
||||
///
|
||||
llvm::Value* sg_ptr() const
|
||||
{
|
||||
return m_llvm_shaderglobals_ptr;
|
||||
}
|
||||
llvm::Value* sg_ptr() const { return m_llvm_shaderglobals_ptr; }
|
||||
|
||||
llvm::Type* llvm_type_closure_component();
|
||||
llvm::Type* llvm_type_closure_component_ptr();
|
||||
|
||||
/// Return the ShaderGlobals pointer cast as a void*.
|
||||
///
|
||||
llvm::Value* sg_void_ptr()
|
||||
{
|
||||
return ll.void_ptr(m_llvm_shaderglobals_ptr);
|
||||
}
|
||||
llvm::Value* sg_void_ptr() { return ll.void_ptr(m_llvm_shaderglobals_ptr); }
|
||||
|
||||
/// Cast the pointer variable specified by val to a pointer to the
|
||||
/// basic type comprising `type`.
|
||||
@@ -321,10 +299,7 @@ public:
|
||||
|
||||
/// Return the group data pointer.
|
||||
///
|
||||
llvm::Value* groupdata_ptr() const
|
||||
{
|
||||
return m_llvm_groupdata_ptr;
|
||||
}
|
||||
llvm::Value* groupdata_ptr() const { return m_llvm_groupdata_ptr; }
|
||||
|
||||
/// Return the group data pointer cast as a void*.
|
||||
///
|
||||
@@ -342,22 +317,13 @@ public:
|
||||
TypeDesc type = TypeDesc::UNKNOWN);
|
||||
|
||||
/// Return the userdata base pointer.
|
||||
llvm::Value* userdata_base_ptr() const
|
||||
{
|
||||
return m_llvm_userdata_base_ptr;
|
||||
}
|
||||
llvm::Value* userdata_base_ptr() const { return m_llvm_userdata_base_ptr; }
|
||||
|
||||
/// Return the output base pointer.
|
||||
llvm::Value* output_base_ptr() const
|
||||
{
|
||||
return m_llvm_output_base_ptr;
|
||||
}
|
||||
llvm::Value* output_base_ptr() const { return m_llvm_output_base_ptr; }
|
||||
|
||||
/// Return the shade index
|
||||
llvm::Value* shadeindex() const
|
||||
{
|
||||
return m_llvm_shadeindex;
|
||||
}
|
||||
llvm::Value* shadeindex() const { return m_llvm_shadeindex; }
|
||||
|
||||
// For a symloc, compute the llvm::Value of the pointer to its true,
|
||||
// offset location from the base pointer for shade index `sindex`
|
||||
@@ -463,13 +429,6 @@ public:
|
||||
return ll.llvm_type(llvm_typedesc(typespec));
|
||||
}
|
||||
|
||||
/// Generate the appropriate llvm type definition for a pointer to
|
||||
/// the type specified by the TypeSpec.
|
||||
llvm::Type* llvm_ptr_type(const TypeSpec& typespec)
|
||||
{
|
||||
return ll.type_ptr(ll.llvm_type(llvm_typedesc(typespec)));
|
||||
}
|
||||
|
||||
/// Generate the parameter-passing llvm type definition for an OSL
|
||||
/// TypeSpec.
|
||||
llvm::Type* llvm_pass_type(const TypeSpec& typespec);
|
||||
@@ -485,10 +444,7 @@ public:
|
||||
|
||||
/// Return the basic block of the exit for the whole instance.
|
||||
///
|
||||
bool llvm_has_exit_instance_block() const
|
||||
{
|
||||
return m_exit_instance_block;
|
||||
}
|
||||
bool llvm_has_exit_instance_block() const { return m_exit_instance_block; }
|
||||
|
||||
/// Return the basic block of the exit for the whole instance.
|
||||
///
|
||||
@@ -509,10 +465,7 @@ public:
|
||||
/// Print debugging line for the op
|
||||
void llvm_generate_debug_op_printf(const Opcode& op);
|
||||
|
||||
llvm::Function* layer_func() const
|
||||
{
|
||||
return ll.current_function();
|
||||
}
|
||||
llvm::Function* layer_func() const { return ll.current_function(); }
|
||||
|
||||
/// Call this when JITing a texture-like call, to track how many.
|
||||
void generated_texture_call(bool handle)
|
||||
@@ -522,11 +475,6 @@ public:
|
||||
shadingsys().m_stat_tex_calls_as_handles += 1;
|
||||
}
|
||||
|
||||
void increment_useparam_ops()
|
||||
{
|
||||
shadingsys().m_stat_useparam_ops++;
|
||||
}
|
||||
|
||||
/// Return the mapping from symbol names to GlobalVariables.
|
||||
std::map<std::string, llvm::GlobalVariable*>& get_const_map()
|
||||
{
|
||||
@@ -534,16 +482,10 @@ public:
|
||||
}
|
||||
|
||||
/// Return whether or not we are compiling for an OptiX-based renderer.
|
||||
bool use_optix()
|
||||
{
|
||||
return m_use_optix;
|
||||
}
|
||||
bool use_optix() { return m_use_optix; }
|
||||
|
||||
/// Return if we should compile against free function versions of Renderer Service.
|
||||
bool use_rs_bitcode()
|
||||
{
|
||||
return m_use_rs_bitcode;
|
||||
}
|
||||
bool use_rs_bitcode() { return m_use_rs_bitcode; }
|
||||
|
||||
/// Return the userdata index for the given Symbol. Return -1 if the Symbol
|
||||
/// is not an input parameter or is constant and therefore doesn't have an
|
||||
@@ -580,7 +522,6 @@ private:
|
||||
std::map<const Symbol*, int> m_param_order_map;
|
||||
llvm::Value* m_llvm_shaderglobals_ptr;
|
||||
llvm::Value* m_llvm_groupdata_ptr;
|
||||
llvm::Value* m_llvm_interactive_params_ptr;
|
||||
llvm::Value* m_llvm_userdata_base_ptr;
|
||||
llvm::Value* m_llvm_output_base_ptr;
|
||||
llvm::Value* m_llvm_shadeindex;
|
||||
|
||||
@@ -2303,17 +2303,6 @@ struct Analyzer {
|
||||
}
|
||||
}
|
||||
|
||||
void make_closures_varying()
|
||||
{
|
||||
// We assume that closures are always stored as varying pointers
|
||||
FOREACH_PARAM(Symbol & s, inst())
|
||||
{
|
||||
if (s.typespec().is_closure()) {
|
||||
recursively_mark_varying(&s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_varying_of_upstream_connections()
|
||||
{
|
||||
OSL_DEV_ONLY(std::cout << "connections to layer begin" << std::endl);
|
||||
@@ -2406,7 +2395,6 @@ BatchedAnalysis::analyze_layer(ShaderInstance* inst)
|
||||
analyzer.push_varying_of_shader_globals();
|
||||
analyzer.make_interpolated_parameters_varying();
|
||||
analyzer.make_renderer_outputs_varying();
|
||||
analyzer.make_closures_varying();
|
||||
analyzer.push_varying_of_upstream_connections();
|
||||
analyzer.push_varying_of_implicitly_varying_ops();
|
||||
|
||||
|
||||
@@ -448,16 +448,6 @@ BatchedBackendLLVM::getLLVMSymbolBase(const Symbol& sym)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sym.symtype() == SymTypeParam && sym.interactive()) {
|
||||
// Special case for interactively-edited parameters -- they live in
|
||||
// the interactive data block for the group.
|
||||
// Generate the pointer to this symbol by offsetting into the
|
||||
// interactive data block.
|
||||
int offset = group().interactive_param_offset(layer(), sym.name());
|
||||
return ll.offset_ptr(m_llvm_interactive_params_ptr, offset,
|
||||
llvm_ptr_type(sym.typespec().elementtype()));
|
||||
}
|
||||
|
||||
if (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) {
|
||||
// Special case for params -- they live in the group data
|
||||
int fieldnum = m_param_order_map[&sym];
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
@@ -13,7 +15,7 @@
|
||||
using namespace OSL;
|
||||
using namespace OSL::pvt;
|
||||
|
||||
#include <OSL/llvm_util.h>
|
||||
#include "OSL/llvm_util.h"
|
||||
#include "runtimeoptimize.h"
|
||||
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
@@ -656,14 +658,6 @@ public:
|
||||
return ll.llvm_vector_type(llvm_typedesc(typespec));
|
||||
}
|
||||
|
||||
/// Generate the appropriate llvm type definition for a pointer to
|
||||
/// the type specified by the TypeSpec.
|
||||
llvm::Type* llvm_ptr_type(const TypeSpec& typespec)
|
||||
{
|
||||
return reinterpret_cast<llvm::Type*>(
|
||||
ll.type_ptr(ll.llvm_type(llvm_typedesc(typespec))));
|
||||
}
|
||||
|
||||
/// Generate the parameter-passing llvm type definition for an OSL
|
||||
/// TypeSpec.
|
||||
llvm::Type* llvm_pass_type(const TypeSpec& typespec);
|
||||
@@ -711,8 +705,6 @@ public:
|
||||
shadingsys().m_stat_tex_calls_as_handles += 1;
|
||||
}
|
||||
|
||||
void increment_useparam_ops() { shadingsys().m_stat_useparam_ops++; }
|
||||
|
||||
void llvm_print_mask(const char* title, llvm::Value* mask = nullptr);
|
||||
|
||||
/// Return the userdata index for the given Symbol. Return -1 if the Symbol
|
||||
@@ -789,7 +781,7 @@ private:
|
||||
std::map<const Symbol*, int> m_param_order_map;
|
||||
llvm::Value* m_llvm_shaderglobals_ptr;
|
||||
llvm::Value* m_llvm_groupdata_ptr;
|
||||
llvm::Value* m_llvm_interactive_params_ptr;
|
||||
|
||||
llvm::Value* m_llvm_wide_shadeindex_ptr;
|
||||
llvm::Value* m_llvm_userdata_base_ptr;
|
||||
llvm::Value* m_llvm_output_base_ptr;
|
||||
|
||||
@@ -92,17 +92,13 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
<< " unconditional=" << unconditional << std::endl);
|
||||
// Make code that looks like:
|
||||
// if (! groupdata->run[parentlayer])
|
||||
// parent_layer (sg, groupdata, wide_shadeindex_ptr,
|
||||
// userdata_base_ptr, output_base_ptr,
|
||||
// execution_mask, interactive_params_ptr);
|
||||
// parent_layer (sg, groupdata);
|
||||
// if it's a conditional call, or
|
||||
// parent_layer (sg, groupdata, wide_shadeindex_ptr,
|
||||
// userdata_base_ptr, output_base_ptr,
|
||||
// execution_mask, interactive_params_ptr);
|
||||
// parent_layer (sg, groupdata);
|
||||
// if it's run unconditionally.
|
||||
// The code in the parent layer itself will set its 'executed' flag.
|
||||
|
||||
llvm::Value* args[7];
|
||||
llvm::Value* args[6];
|
||||
args[0] = sg_ptr();
|
||||
args[1] = groupdata_ptr();
|
||||
args[2] = ll.void_ptr(wide_shadeindex_ptr());
|
||||
@@ -124,11 +120,13 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
llvm::Value* execution_required
|
||||
= ll.op_ne(lanes_requiring_execution_value, ll.constant(0));
|
||||
then_block = ll.new_basic_block(
|
||||
llvm_debug() ? Strutil::fmt::format("then layer {}", layer)
|
||||
: std::string());
|
||||
llvm_debug()
|
||||
? std::string("then layer ").append(std::to_string(layer))
|
||||
: std::string());
|
||||
after_block = ll.new_basic_block(
|
||||
llvm_debug() ? Strutil::fmt::format("after layer {}", layer)
|
||||
: std::string());
|
||||
llvm_debug()
|
||||
? std::string("after layer ").append(std::to_string(layer))
|
||||
: std::string());
|
||||
ll.op_branch(execution_required, then_block, after_block);
|
||||
// insert point is now then_block
|
||||
} else {
|
||||
@@ -136,7 +134,6 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
}
|
||||
|
||||
args[5] = lanes_requiring_execution_value;
|
||||
args[6] = m_llvm_interactive_params_ptr;
|
||||
|
||||
// Before the merge, keeping in case we broke it
|
||||
//std::string name = fmtformat("{}_{}_{}", m_library_selector, parent->layername().c_str(),
|
||||
@@ -152,8 +149,6 @@ BatchedBackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
|
||||
if (!unconditional)
|
||||
ll.op_branch(after_block); // also moves insert point
|
||||
|
||||
shadingsys().m_stat_call_layers_inserted++;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,15 +199,6 @@ BatchedBackendLLVM::llvm_run_connected_layers(const Symbol& sym, int symindex,
|
||||
}
|
||||
}
|
||||
|
||||
if (shadingsys().m_opt_useparam && inmain) {
|
||||
// m_call_layers_inserted tracks if we've already run this layer inside the current basic block
|
||||
const CallLayerKey key = { m_bblockids[opnum], con.srclayer };
|
||||
if (m_call_layers_inserted.count(key)) {
|
||||
continue;
|
||||
}
|
||||
m_call_layers_inserted.insert(key);
|
||||
}
|
||||
|
||||
// If the earlier layer it comes from has not yet been
|
||||
// executed, do so now.
|
||||
llvm_call_layer(con.srclayer);
|
||||
@@ -250,16 +236,13 @@ LLVMGEN(llvm_gen_useparam)
|
||||
// initializing them lazily, now we have to do it.
|
||||
if ((sym.symtype() == SymTypeParam
|
||||
|| sym.symtype() == SymTypeOutputParam)
|
||||
&& sym.interpolated() && !sym.typespec().is_closure()
|
||||
&& !sym.lockgeom() && !sym.typespec().is_closure()
|
||||
&& !sym.connected() && !sym.connected_down()
|
||||
&& rop.shadingsys().lazy_userdata()) {
|
||||
rop.llvm_assign_initial_value(sym, rop.ll.mask_as_int(
|
||||
rop.ll.current_mask()));
|
||||
}
|
||||
}
|
||||
|
||||
rop.increment_useparam_ops();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1280,7 +1263,6 @@ LLVMGEN(llvm_gen_add)
|
||||
OSL_ASSERT(!A.typespec().is_array() && !B.typespec().is_array());
|
||||
if (Result.typespec().is_closure()) {
|
||||
OSL_ASSERT(A.typespec().is_closure() && B.typespec().is_closure());
|
||||
OSL_ASSERT(!A.is_uniform() && !B.is_uniform() && !result_is_uniform);
|
||||
llvm::Value* valargs[] = { rop.sg_void_ptr(), rop.llvm_void_ptr(Result),
|
||||
rop.llvm_void_ptr(A), rop.llvm_void_ptr(B),
|
||||
rop.ll.mask_as_int(rop.ll.current_mask()) };
|
||||
@@ -1694,7 +1676,6 @@ LLVMGEN(llvm_gen_modulus)
|
||||
|
||||
int num_components = type.aggregate;
|
||||
|
||||
#if 0
|
||||
if (is_float && !op_is_uniform) {
|
||||
// llvm 5.0.1 did not do a good job with op_mod when its
|
||||
// parameters were <16xf32>. So we will go ahead
|
||||
@@ -1721,9 +1702,7 @@ LLVMGEN(llvm_gen_modulus)
|
||||
}
|
||||
|
||||
rop.ll.call_function(rop.build_name(func_spec), call_args);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
for (int i = 0; i < num_components; i++) {
|
||||
llvm::Value* a = rop.loadLLVMValue(A, i, 0, type, op_is_uniform);
|
||||
llvm::Value* b = rop.loadLLVMValue(B, i, 0, type, op_is_uniform);
|
||||
@@ -7085,8 +7064,7 @@ LLVMGEN(llvm_gen_spline)
|
||||
static void
|
||||
llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
|
||||
const ClosureRegistry::ClosureEntry* clentry,
|
||||
ustring clname, llvm::Value* mem_void_ptr, int argsoffset,
|
||||
int lane_index)
|
||||
ustring clname, llvm::Value* mem_void_ptr, int argsoffset)
|
||||
{
|
||||
OSL_DASSERT(((op.nargs() - argsoffset) % 2) == 0);
|
||||
|
||||
@@ -7110,45 +7088,10 @@ llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
|
||||
if (equivalent(p.type, ValueType) && !strcmp(key->c_str(), p.key)) {
|
||||
// store data
|
||||
OSL_DASSERT(p.offset + p.field_size <= clentry->struct_size);
|
||||
|
||||
bool arg_is_uniform = Value.is_uniform();
|
||||
|
||||
TypeDesc simpletype(Value.typespec().simpletype());
|
||||
|
||||
// We don't currently offer a helper macro in genclosure.h for creating
|
||||
// keyword array parameters, so perhaps we can assume we don't need to
|
||||
// support them
|
||||
OSL_DASSERT(simpletype.arraylen == 0);
|
||||
|
||||
int num_components = simpletype.aggregate;
|
||||
|
||||
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr,
|
||||
p.offset);
|
||||
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
|
||||
|
||||
for (int c = 0; c < num_components; c++) {
|
||||
llvm::Value* dest_elem;
|
||||
if (num_components > 1)
|
||||
dest_elem = rop.ll.GEP(dest_base, 0, c);
|
||||
else
|
||||
dest_elem = dest_base;
|
||||
|
||||
// NOTE: We don't want any uniform arguments to be
|
||||
// widened, so our typical op_is_uniform doesn't do what we
|
||||
// want for this when loading. So just pass arg_is_uniform
|
||||
// which will avoid widening any uniform arguments.
|
||||
llvm::Value* loaded
|
||||
= rop.llvm_load_value(Value, 0, NULL, c,
|
||||
TypeDesc::UNKNOWN,
|
||||
/*op_is_uniform*/ arg_is_uniform,
|
||||
/*index_is_uniform*/ true);
|
||||
|
||||
if (!arg_is_uniform) {
|
||||
loaded = rop.ll.op_extract(loaded, lane_index);
|
||||
}
|
||||
rop.ll.op_unmasked_store(loaded, dest_elem);
|
||||
}
|
||||
|
||||
llvm::Value* dst = rop.ll.offset_ptr(mem_void_ptr, p.offset);
|
||||
llvm::Value* src = rop.llvm_void_ptr(Value);
|
||||
rop.ll.op_memcpy(dst, src, (int)p.type.size(),
|
||||
4 /* use 4 byte alignment for now */);
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
@@ -7237,7 +7180,6 @@ LLVMGEN(llvm_gen_closure)
|
||||
rop.ll.type_ptr(rop.llvm_type_closure_component_wide_ptr()));
|
||||
llvm::Value* comp_wide_ptr = rop.ll.op_load(comp_wide_ptr_ptr);
|
||||
|
||||
llvm::Value* mask = rop.ll.current_mask();
|
||||
// This is an unrolled vector-width loop. It was unrolled because it's
|
||||
// was more expedient to write the for in C++ than IR, but if compilation
|
||||
// of the extra ops becomes problematic, this choice can be revisited
|
||||
@@ -7251,16 +7193,14 @@ LLVMGEN(llvm_gen_closure)
|
||||
// For the weighted closures, we need a surrounding "if" so that it's safe
|
||||
// for osl_allocate_weighted_closure_component to return NULL (unless we
|
||||
// know for sure that it's constant weighted and that the weight is
|
||||
// not zero). We also need the surrounding "if" to reject writing
|
||||
// to closures that aren't masked.
|
||||
// not zero).
|
||||
llvm::BasicBlock* next_block = NULL;
|
||||
llvm::BasicBlock* notnull_block = rop.ll.new_basic_block(
|
||||
"non_null_and_masked_closure");
|
||||
next_block = rop.ll.new_basic_block("");
|
||||
llvm::Value* cond = rop.ll.op_and(
|
||||
rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
|
||||
rop.ll.void_ptr_null()),
|
||||
rop.ll.test_mask_lane(mask, lane_index));
|
||||
"non_null_closure");
|
||||
next_block = rop.ll.new_basic_block("");
|
||||
llvm::Value* cond
|
||||
= rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
|
||||
rop.ll.void_ptr_null());
|
||||
rop.ll.op_branch(cond, notnull_block, next_block);
|
||||
|
||||
// If the closure has a "prepare" method, call
|
||||
@@ -7293,30 +7233,7 @@ LLVMGEN(llvm_gen_closure)
|
||||
int num_components = simpletype.aggregate;
|
||||
|
||||
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr, p.offset);
|
||||
llvm::Type* dest_type = rop.ll.llvm_type(
|
||||
static_cast<const TypeSpec&>(p.type).simpletype());
|
||||
dest_base = rop.ll.ptr_to_cast(dest_base, dest_type);
|
||||
|
||||
if (num_elements > 1) {
|
||||
OSL_DASSERT(rop.ll.is_type_array(dest_type));
|
||||
|
||||
// The type is an array type,
|
||||
// which means our pointer is to an array type,
|
||||
// not to &[0] (the address of the 1st element).
|
||||
// IE: typedef int Int5Array[5];
|
||||
// Int5Array *dest_base;
|
||||
// in contrast to what most of use might consider an array pointer
|
||||
// int *dest_base;
|
||||
// So if we dereference Int5Array* to with [4], the 5th element,
|
||||
// we would be really be pointing to ((int *)dest_base)[5*4] which is
|
||||
// out of bounds of our 1 instance of Int5Array.
|
||||
// Thus when dealing with arrays we will just dereference it and get the address to get
|
||||
// the address of the 1st element.
|
||||
|
||||
dest_base = rop.ll.GEP(dest_type, dest_base, 0, 0);
|
||||
llvm::Type* element_type = rop.ll.element_type_of(dest_type);
|
||||
dest_type = element_type;
|
||||
}
|
||||
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
|
||||
|
||||
for (int a = 0; a < num_elements; ++a) {
|
||||
llvm::Value* arrind = simpletype.arraylen ? rop.ll.constant(a)
|
||||
@@ -7324,9 +7241,7 @@ LLVMGEN(llvm_gen_closure)
|
||||
for (int c = 0; c < num_components; c++) {
|
||||
llvm::Value* dest_elem;
|
||||
if (num_components > 1)
|
||||
dest_elem = rop.ll.GEP(dest_type, dest_base, a, c);
|
||||
else if (num_elements > 1)
|
||||
dest_elem = rop.ll.GEP(dest_type, dest_base, a);
|
||||
dest_elem = rop.ll.GEP(dest_base, a, c);
|
||||
else
|
||||
dest_elem = dest_base;
|
||||
|
||||
@@ -7360,7 +7275,7 @@ LLVMGEN(llvm_gen_closure)
|
||||
}
|
||||
|
||||
llvm_gen_keyword_fill(rop, op, clentry, closure_name, mem_void_ptr,
|
||||
2 + weighted + clentry->nformal, lane_index);
|
||||
2 + weighted + clentry->nformal);
|
||||
|
||||
if (next_block)
|
||||
rop.ll.op_branch(next_block);
|
||||
|
||||
@@ -63,19 +63,8 @@ Schematically, we want to create code that resembles the following:
|
||||
float param_1_bar;
|
||||
};
|
||||
|
||||
// Data for the interactively adjusted parameters of this group -- these
|
||||
// can't be turned into constants because the app may want to modify them
|
||||
// as it runs (such as for user interaction). This block of memory has
|
||||
// one global copy specific each the shader group, managed by OSL.
|
||||
struct InteractiveParams {
|
||||
float iparam_0_baz;
|
||||
};
|
||||
|
||||
// Name of layer entry is $layer_ID
|
||||
void $layer_0(ShaderGlobals *sg, GroupData_1 *group,
|
||||
wide_int* wide_shadeindex_ptr,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int mask, InteractiveParams* interactive_params)
|
||||
void $layer_0 (ShaderGlobals *sg, GroupData_1 *group)
|
||||
{
|
||||
// Declare locals, temps, constants, params with known values.
|
||||
// Make them all look like stack memory locations:
|
||||
@@ -85,14 +74,9 @@ Schematically, we want to create code that resembles the following:
|
||||
// then run the shader body:
|
||||
*x = sg->u * group->param_0_bar;
|
||||
group->param_1_foo = *x;
|
||||
*x += interactive_params->iparam_0_baz;
|
||||
// ...
|
||||
}
|
||||
|
||||
void $layer_1(ShaderGlobals *sg, GroupData_1 *group,
|
||||
wide_int* wide_shadeindex_ptr,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int mask, InteractiveParams* interactive_params)
|
||||
void $layer_1 (ShaderGlobals *sg, GroupData_1 *group)
|
||||
{
|
||||
// Because we need the outputs of layer 0 now, we call it if it
|
||||
// hasn't already run:
|
||||
@@ -103,10 +87,7 @@ Schematically, we want to create code that resembles the following:
|
||||
*y = sg->u * group->$param_1_bar;
|
||||
}
|
||||
|
||||
void $group_1(ShaderGlobals *sg, GroupData_1 *group,
|
||||
wide_int* wide_shadeindex_ptr,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int mask, InteractiveParams* interactive_params)
|
||||
void $group_1 (ShaderGlobals *sg, GroupData_1 *group)
|
||||
{
|
||||
group->layer_run[...] = 0;
|
||||
// Run just the unconditional layers
|
||||
@@ -920,13 +901,14 @@ BatchedBackendLLVM::llvm_type_groupdata()
|
||||
if (offset & (align - 1))
|
||||
offset += align - (offset & (align - 1));
|
||||
if (llvm_debug() >= 2)
|
||||
print(" {} ({}) {} {}, field {}, size {}, offset {}{}{}\n",
|
||||
inst->layername(), inst->id(), sym.mangled(), ts.c_str(),
|
||||
order, derivSize * int(sym.size()), offset,
|
||||
sym.interpolated() ? " (interpolated)" : "",
|
||||
sym.interactive() ? " (interactive)" : "");
|
||||
std::cout << " " << inst->layername() << " (" << inst->id()
|
||||
<< ") " << sym.mangled() << " " << ts.c_str()
|
||||
<< ", field " << order << ", size "
|
||||
<< derivSize * int(sym.size()) << ", offset "
|
||||
<< offset << std::endl;
|
||||
sym.wide_dataoffset((int)offset);
|
||||
offset += derivSize * int(sym.size()) * m_width;
|
||||
|
||||
m_param_order_map[&sym] = order;
|
||||
++order;
|
||||
}
|
||||
@@ -1059,10 +1041,10 @@ BatchedBackendLLVM::llvm_assign_initial_value(
|
||||
llvm_assign_zero(sym);
|
||||
return; // we're done, the parts below are just for params
|
||||
}
|
||||
OSL_ASSERT_MSG(sym.symtype() == SymTypeParam
|
||||
|| sym.symtype() == SymTypeOutputParam,
|
||||
"symtype was %d, data type was %s", (int)sym.symtype(),
|
||||
sym.typespec().c_str());
|
||||
ASSERT_MSG(sym.symtype() == SymTypeParam
|
||||
|| sym.symtype() == SymTypeOutputParam,
|
||||
"symtype was %d, data type was %s", (int)sym.symtype(),
|
||||
sym.typespec().c_str());
|
||||
|
||||
// Handle interpolated params by calling osl_bind_interpolated_param,
|
||||
// which will check if userdata is already retrieved, if not it will
|
||||
@@ -1077,7 +1059,7 @@ BatchedBackendLLVM::llvm_assign_initial_value(
|
||||
bool partial_userdata_mask_was_pushed = false;
|
||||
const SymLocationDesc* symloc = nullptr;
|
||||
LLVM_Util::ScopedMasking partial_data_masking_scope;
|
||||
if (sym.interpolated() && !sym.typespec().is_closure()) {
|
||||
if (!sym.lockgeom() && !sym.typespec().is_closure()) {
|
||||
ustring symname = sym.name();
|
||||
TypeDesc type = sym.typespec().simpletype();
|
||||
|
||||
@@ -1235,15 +1217,6 @@ BatchedBackendLLVM::llvm_assign_initial_value(
|
||||
|
||||
// Handle init ops.
|
||||
build_llvm_code(sym.initbegin(), sym.initend());
|
||||
#if 0 /* Is this needed? */
|
||||
} else if (sym.interpolated() && !sym.typespec().is_closure()) {
|
||||
// geometrically-varying param; memcpy its default value
|
||||
TypeDesc t = sym.typespec().simpletype();
|
||||
ll.op_memcpy(llvm_void_ptr(sym), ll.constant_ptr(sym.data()),
|
||||
t.size(), t.basesize() /*align*/);
|
||||
if (sym.has_derivs())
|
||||
llvm_zero_derivs(sym);
|
||||
#endif
|
||||
} else {
|
||||
// We think the non-memcpy route is preferable as it give the compiler
|
||||
// a chance to optimize constant values Also memcpy would ignoring the
|
||||
@@ -1765,17 +1738,16 @@ BatchedBackendLLVM::build_llvm_init()
|
||||
OSL_ASSERT(m_library_selector);
|
||||
std::string unique_name = fmtformat("{}_group_{}_init", m_library_selector,
|
||||
group().id());
|
||||
ll.current_function(
|
||||
ll.make_function(unique_name, false,
|
||||
ll.type_void(), // return type
|
||||
{
|
||||
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // wide_shader_index
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int(), // mask
|
||||
ll.type_void_ptr(), // FIXME: interactive params
|
||||
}));
|
||||
ll.current_function(ll.make_function(
|
||||
unique_name, false,
|
||||
ll.type_void(), // return type
|
||||
{
|
||||
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // wide_shader_index
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // userdata_base_ptr
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // output_base_ptr
|
||||
ll.type_int() // mask
|
||||
}));
|
||||
|
||||
if (ll.debug_is_enabled()) {
|
||||
ustring file_name
|
||||
@@ -1785,20 +1757,14 @@ BatchedBackendLLVM::build_llvm_init()
|
||||
}
|
||||
|
||||
// Get shader globals and groupdata pointers
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_groupdata_ptr->setName("groupdata_ptr");
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_wide_shadeindex_ptr = ll.current_function_arg(2); //arg_it++;
|
||||
m_llvm_wide_shadeindex_ptr->setName("shadeindex");
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
|
||||
m_llvm_output_base_ptr->setName("output_base_ptr");
|
||||
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(5);
|
||||
llvm_initial_shader_mask_value->setName("initial_shader_mask");
|
||||
m_llvm_interactive_params_ptr = ll.current_function_arg(6); //arg_it++;
|
||||
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
|
||||
|
||||
// TODO: do we need to utilize the shader mask in the init function?
|
||||
//llvm::Value * llvm_initial_shader_mask_value = ll.current_function_arg(5); //arg_it++;
|
||||
|
||||
// New function, reset temp matrix pointer
|
||||
m_llvm_temp_wide_matrix_ptr = nullptr;
|
||||
@@ -1847,7 +1813,6 @@ BatchedBackendLLVM::build_llvm_init()
|
||||
FOREACH_PARAM(Symbol & sym, gi)
|
||||
{
|
||||
if (sym.typespec().is_closure_based()) {
|
||||
OSL_ASSERT(sym.is_varying());
|
||||
int arraylen = std::max(1, sym.typespec().arraylength());
|
||||
llvm::Value* val = ll.constant_ptr(NULL, ll.type_void_ptr());
|
||||
if (!sym.is_uniform())
|
||||
@@ -1909,11 +1874,10 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
|
||||
ll.type_void(), // return type
|
||||
{
|
||||
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // wide_shader_index
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int(), // mask
|
||||
ll.type_void_ptr(), // FIXME: interactive params
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // wide_shader_index
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // userdata_base_ptr
|
||||
static_cast<llvm::Type*>(ll.type_void_ptr()), // output_base_ptr
|
||||
ll.type_int() // mask
|
||||
}));
|
||||
|
||||
if (ll.debug_is_enabled()) {
|
||||
@@ -1923,20 +1887,14 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
|
||||
}
|
||||
|
||||
// Get shader globals and groupdata pointers
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_groupdata_ptr->setName("groupdata_ptr");
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_wide_shadeindex_ptr = ll.current_function_arg(2); //arg_it++;
|
||||
m_llvm_wide_shadeindex_ptr->setName("shadeindex");
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
|
||||
m_llvm_output_base_ptr->setName("output_base_ptr");
|
||||
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(5);
|
||||
llvm_initial_shader_mask_value->setName("initial_shader_mask");
|
||||
m_llvm_interactive_params_ptr = ll.current_function_arg(6); //arg_it++;
|
||||
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(4); //arg_it++;
|
||||
|
||||
llvm::Value* llvm_initial_shader_mask_value = ll.current_function_arg(
|
||||
5); //arg_it++;
|
||||
|
||||
// New function, reset temp matrix pointer
|
||||
m_llvm_temp_wide_matrix_ptr = nullptr;
|
||||
@@ -2111,12 +2069,10 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
|
||||
&& !s.renderer_output())
|
||||
continue;
|
||||
// Skip if it's an interpolated (userdata) parameter and we're
|
||||
// initializing them lazily, or if it's an interactively-adjusted
|
||||
// parameter.
|
||||
if (s.symtype() == SymTypeParam && !s.typespec().is_closure()
|
||||
&& !s.connected() && !s.connected_down()
|
||||
&& (s.interactive()
|
||||
|| (s.interpolated() && shadingsys().lazy_userdata())))
|
||||
// initializing them lazily.
|
||||
if (s.symtype() == SymTypeParam && !s.lockgeom()
|
||||
&& !s.typespec().is_closure() && !s.connected()
|
||||
&& !s.connected_down() && shadingsys().lazy_userdata())
|
||||
continue;
|
||||
// Set initial value for params (may contain init ops)
|
||||
llvm_assign_initial_value(s, llvm_initial_shader_mask_value);
|
||||
@@ -2139,7 +2095,6 @@ BatchedBackendLLVM::build_llvm_instance(bool groupentry)
|
||||
// records for each.
|
||||
find_basic_blocks();
|
||||
find_conditionals();
|
||||
m_call_layers_inserted.clear();
|
||||
|
||||
build_llvm_code(inst()->maincodebegin(), inst()->maincodeend());
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::get_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult,
|
||||
Wide<const ustringhash> wfrom,
|
||||
Wide<const ustring> wfrom,
|
||||
Wide<const float> wtime)
|
||||
{
|
||||
OSL_ASSERT(
|
||||
@@ -70,7 +70,7 @@ template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult,
|
||||
ustringhash to,
|
||||
ustring to,
|
||||
Wide<const float> wtime)
|
||||
{
|
||||
OSL_ASSERT(
|
||||
@@ -85,7 +85,7 @@ template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::get_inverse_matrix(BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult,
|
||||
Wide<const ustringhash> wto,
|
||||
Wide<const ustring> wto,
|
||||
Wide<const float> wtime)
|
||||
{
|
||||
OSL_ASSERT(
|
||||
@@ -109,13 +109,13 @@ template<int WidthT>
|
||||
TextureSystem::TextureHandle*
|
||||
BatchedRendererServices<WidthT>::resolve_udim_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle, float S,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle, float S,
|
||||
float T)
|
||||
{
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = bsg->uniform.context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
if (texturesys()->is_udim(texture_handle)) {
|
||||
// Newer versions of the TextureSystem interface are able to determine the
|
||||
@@ -141,14 +141,14 @@ template<int WidthT>
|
||||
void
|
||||
BatchedRendererServices<WidthT>::resolve_udim(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
Wide<const float> wS, Wide<const float> wT,
|
||||
Masked<TextureSystem::TextureHandle*> wresult)
|
||||
{
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = bsg->uniform.context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
if (texturesys()->is_udim(texture_handle)) {
|
||||
// Newer versions of the TextureSystem interface are able to determine the
|
||||
@@ -176,17 +176,17 @@ template<int WidthT>
|
||||
bool
|
||||
BatchedRendererServices<WidthT>::get_texture_info_uniform(
|
||||
BatchedShaderGlobals* bsg, TexturePerthread* texture_thread_info,
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustringhash dataname, RefData val)
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
int subimage, ustring dataname, RefData val)
|
||||
{
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = bsg->uniform.context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->get_texture_info(texture_handle, NULL, subimage,
|
||||
ustring_from(dataname),
|
||||
val.type(), val.ptr());
|
||||
dataname, val.type(),
|
||||
val.ptr());
|
||||
|
||||
if (!status) {
|
||||
std::string err = texturesys()->geterror();
|
||||
@@ -203,7 +203,7 @@ BatchedRendererServices<WidthT>::get_texture_info_uniform(
|
||||
template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::texture(
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
|
||||
Wide<const float> ws, Wide<const float> wt, Wide<const float> wdsdx,
|
||||
@@ -221,7 +221,7 @@ BatchedRendererServices<WidthT>::texture(
|
||||
template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::texture3d(
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
|
||||
Wide<const Vec3> wP, Wide<const Vec3> wdPdx, Wide<const Vec3> wdPdy,
|
||||
@@ -238,7 +238,7 @@ BatchedRendererServices<WidthT>::texture3d(
|
||||
template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::environment(
|
||||
ustringhash filename, TextureSystem::TextureHandle* texture_handle,
|
||||
ustring filename, TextureSystem::TextureHandle* texture_handle,
|
||||
TextureSystem::Perthread* texture_thread_info,
|
||||
const BatchedTextureOptions& options, BatchedShaderGlobals* bsg,
|
||||
Wide<const Vec3> wR, Wide<const Vec3> wdRdx, Wide<const Vec3> wdRdy,
|
||||
@@ -255,7 +255,7 @@ BatchedRendererServices<WidthT>::environment(
|
||||
template<int WidthT>
|
||||
void
|
||||
BatchedRendererServices<WidthT>::pointcloud_search(
|
||||
BatchedShaderGlobals* bsg, ustringhash filename, const void* wcenter,
|
||||
BatchedShaderGlobals* bsg, ustring filename, const void* wcenter,
|
||||
Wide<const float> wradius, int max_points, bool sort,
|
||||
PointCloudSearchResults& results)
|
||||
{
|
||||
@@ -269,8 +269,8 @@ BatchedRendererServices<WidthT>::pointcloud_search(
|
||||
template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::pointcloud_get(
|
||||
BatchedShaderGlobals* bsg, ustringhash filename, Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points, ustringhash attr_name, MaskedData wout_data)
|
||||
BatchedShaderGlobals* bsg, ustring filename, Wide<const int[]> windices,
|
||||
Wide<const int> wnum_points, ustring attr_name, MaskedData wout_data)
|
||||
{
|
||||
OSL_ASSERT(
|
||||
0
|
||||
@@ -283,7 +283,7 @@ BatchedRendererServices<WidthT>::pointcloud_get(
|
||||
template<int WidthT>
|
||||
Mask<WidthT>
|
||||
BatchedRendererServices<WidthT>::pointcloud_write(
|
||||
BatchedShaderGlobals* bsg, ustringhash filename, Wide<const OSL::Vec3> wpos,
|
||||
BatchedShaderGlobals* bsg, ustring filename, Wide<const OSL::Vec3> wpos,
|
||||
int nattribs, const ustring* attr_names, const TypeDesc* attr_types,
|
||||
const void** pointers_to_wide_attr_value, Mask mask)
|
||||
{
|
||||
@@ -312,9 +312,8 @@ BatchedRendererServices<WidthT>::trace(
|
||||
template<int WidthT>
|
||||
void
|
||||
BatchedRendererServices<WidthT>::getmessage(BatchedShaderGlobals* bsg,
|
||||
Masked<int> wresult,
|
||||
ustringhash source,
|
||||
ustringhash name, MaskedData wval)
|
||||
Masked<int> wresult, ustring source,
|
||||
ustring name, MaskedData wval)
|
||||
{
|
||||
// Currently this code path should only be followed when source == "trace"
|
||||
OSL_DASSERT(wresult.mask() == wval.mask());
|
||||
|
||||
@@ -204,13 +204,13 @@ DECL(osl_dict_next, "iXi")
|
||||
DECL(osl_dict_value, "iXiXLX")
|
||||
DECL(osl_raytype_name, "iXs")
|
||||
#ifdef OSL_LLVM_NO_BITCODE
|
||||
DECL(osl_range_check, "iiisXsisiss")
|
||||
DECL(osl_range_check, "iiiXXXiXiXX")
|
||||
#endif
|
||||
DECL(osl_range_check_err, "iiisXsisiss")
|
||||
DECL(osl_naninf_check, "xiXiXsisiis")
|
||||
DECL(osl_uninit_check, "xLXXsisissisisii")
|
||||
DECL(osl_get_attribute, "iXissiiLX")
|
||||
DECL(osl_bind_interpolated_param, "iXsLiXiXiXi")
|
||||
DECL(osl_range_check_err, "iiiXXXiXiXX")
|
||||
DECL(osl_naninf_check, "xiXiXXiXiiX")
|
||||
DECL(osl_uninit_check, "xLXXXiXiXXiXiXii")
|
||||
DECL(osl_get_attribute, "iXiXXiiLX")
|
||||
DECL(osl_bind_interpolated_param, "iXXLiXiXiXi")
|
||||
DECL(osl_get_texture_options, "XX");
|
||||
DECL(osl_get_noise_options, "XX");
|
||||
DECL(osl_get_trace_options, "XX");
|
||||
@@ -248,10 +248,10 @@ UNARY_OP_IMPL(log10)
|
||||
UNARY_OP_IMPL(exp)
|
||||
UNARY_OP_IMPL(exp2)
|
||||
UNARY_OP_IMPL(expm1)
|
||||
BINARY_OP_IMPL(pow)
|
||||
UNARY_OP_IMPL(erf)
|
||||
UNARY_OP_IMPL(erfc)
|
||||
|
||||
BINARY_OP_IMPL(pow)
|
||||
DECL(osl_pow_vvf, "xXXf")
|
||||
DECL(osl_pow_dvdvdf, "xXXX")
|
||||
DECL(osl_pow_dvvdf, "xXXX")
|
||||
@@ -285,12 +285,7 @@ DECL(osl_fabs_ii, "ii")
|
||||
|
||||
UNARY_OP_IMPL(abs)
|
||||
UNARY_OP_IMPL(fabs)
|
||||
|
||||
BINARY_OP_IMPL(fmod)
|
||||
DECL(osl_fmod_vvf, "xXXf")
|
||||
DECL(osl_fmod_dvdvdf, "xXXX")
|
||||
DECL(osl_fmod_dvvdf, "xXXX")
|
||||
DECL(osl_fmod_dvdvf, "xXXf")
|
||||
|
||||
DECL(osl_smoothstep_ffff, "ffff")
|
||||
DECL(osl_smoothstep_dfffdf, "xXffX")
|
||||
@@ -343,8 +338,8 @@ DECL(osl_substr_ssii, "ssii")
|
||||
DECL(osl_regex_impl, "iXsXisi")
|
||||
|
||||
// Used by wide code generator, but are uniform calls
|
||||
DECL(osl_texture_decode_wrapmode, "is");
|
||||
DECL(osl_texture_decode_interpmode, "is");
|
||||
DECL(osl_texture_decode_wrapmode, "iX");
|
||||
DECL(osl_texture_decode_interpmode, "iX");
|
||||
|
||||
DECL(osl_texture_set_firstchannel, "xXi")
|
||||
DECL(osl_texture_set_swrap, "xXs")
|
||||
|
||||
@@ -315,7 +315,7 @@ DECL(__OSL_MASKED_OP(pointcloud_get), "iXsXiXsLXi")
|
||||
DECL(__OSL_MASKED_OP(pointcloud_write), "iXsXiXXXi")
|
||||
|
||||
DECL(__OSL_MASKED_OP(getmessage), "xXXssLXiisii")
|
||||
DECL(__OSL_MASKED_OP2(setmessage, s, WX), "xXsLXisii")
|
||||
DECL(__OSL_MASKED_OP2(setmessage, s, WX), "xXXLXisii")
|
||||
DECL(__OSL_MASKED_OP2(setmessage, Ws, WX), "xXXLXisii")
|
||||
|
||||
DECL(__OSL_OP(blackbody_vf), "xXXf")
|
||||
@@ -362,24 +362,24 @@ DECL(__OSL_OP(dict_value), "iXiXLX")
|
||||
DECL(__OSL_MASKED_OP(dict_value), "xXXXXLXi")
|
||||
|
||||
|
||||
DECL(__OSL_OP(raytype_name), "iXs")
|
||||
DECL(__OSL_OP(raytype_name), "iXX")
|
||||
DECL(__OSL_MASKED_OP(raytype_name), "xXXXi")
|
||||
DECL(__OSL_OP(naninf_check), "xiXiXsisiis")
|
||||
DECL(__OSL_MASKED_OP1(naninf_check_offset, i), "xiiXiXsisiis")
|
||||
DECL(__OSL_MASKED_OP1(naninf_check_offset, Wi), "xiiXiXsisXis")
|
||||
DECL(__OSL_OP(range_check), "iiisXsisiss")
|
||||
DECL(__OSL_MASKED_OP(range_check), "xXiisXsisiss")
|
||||
DECL(__OSL_OP2(uninit_check_values_offset, X, i), "xLXXsisissisisii")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, X, Wi), "xiLXXsisissisisXi")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, i), "xiLXXsisissisisii")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, Wi), "xiLXXsisissisisXi")
|
||||
DECL(__OSL_OP(naninf_check), "xiXiXXiXiiX")
|
||||
DECL(__OSL_MASKED_OP1(naninf_check_offset, i), "xiiXiXXiXiiX")
|
||||
DECL(__OSL_MASKED_OP1(naninf_check_offset, Wi), "xiiXiXXiXXiX")
|
||||
DECL(__OSL_OP(range_check), "iiiXXXiXiXX")
|
||||
DECL(__OSL_MASKED_OP(range_check), "xXiiXXXiXiXX")
|
||||
DECL(__OSL_OP2(uninit_check_values_offset, X, i), "xLXXXiXiXXiXiXii")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, X, Wi), "xiLXXXiXiXXiXiXXi")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, i), "xiLXXXiXiXXiXiXii")
|
||||
DECL(__OSL_MASKED_OP2(uninit_check_values_offset, WX, Wi), "xiLXXXiXiXXiXiXXi")
|
||||
|
||||
DECL(__OSL_OP1(get_attribute, s), "iXissiiXXi")
|
||||
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXisXiiXXi")
|
||||
DECL(__OSL_OP(get_attribute_uniform), "iXissiiXX")
|
||||
DECL(__OSL_OP1(get_attribute, s), "iXiXXiiXXi")
|
||||
DECL(__OSL_MASKED_OP1(get_attribute, Ws), "iXiXXiiXXi")
|
||||
DECL(__OSL_OP(get_attribute_uniform), "iXiXXiiXX")
|
||||
|
||||
// TODO: shouldn't bind_interpolated_param be MASKED? change name to reflect
|
||||
DECL(__OSL_OP(bind_interpolated_param), "iXsLiXiXiXii")
|
||||
DECL(__OSL_OP(bind_interpolated_param), "iXXLiXiXiXii")
|
||||
|
||||
//DECL (osl_get_texture_options, "XX") // unneeded
|
||||
DECL(__OSL_OP(get_noise_options), "XX")
|
||||
|
||||
@@ -2413,12 +2413,11 @@ DECLFOLDER(constfold_gettextureinfo)
|
||||
void* mydata = OSL_ALLOCA(char, t.size());
|
||||
// FIXME(ptex) -- exclude folding of ptex, since these things
|
||||
// can vary per face.
|
||||
ustringhash em;
|
||||
ustring errormessage;
|
||||
int result = rop.renderer()->get_texture_info(
|
||||
filename, nullptr, rop.shadingcontext()->texture_thread_info(),
|
||||
rop.shadingcontext(), 0 /* TODO: subimage? */, dataname, t, mydata,
|
||||
&em);
|
||||
ustring errormessage = ustring_from(em);
|
||||
&errormessage);
|
||||
// Now we turn
|
||||
// gettextureinfo result filename dataname data
|
||||
// into this for success:
|
||||
|
||||
@@ -133,7 +133,7 @@ ShadingContext::execute_init(ShaderGroup& sgroup, int shadeindex,
|
||||
ssg.renderer = renderer();
|
||||
ssg.Ci = NULL;
|
||||
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr,
|
||||
shadeindex, sgroup.interactive_arena_ptr());
|
||||
shadeindex);
|
||||
}
|
||||
|
||||
if (profile)
|
||||
@@ -160,8 +160,8 @@ ShadingContext::execute_layer(int shadeindex, ShaderGlobals& ssg,
|
||||
if (!run_func)
|
||||
return false;
|
||||
|
||||
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr, shadeindex,
|
||||
group()->interactive_arena_ptr());
|
||||
run_func(&ssg, m_heap.get(), userdata_base_ptr, output_base_ptr,
|
||||
shadeindex);
|
||||
|
||||
if (profile)
|
||||
m_ticks += timer.ticks();
|
||||
@@ -321,8 +321,7 @@ ShadingContext::Batched<WidthT>::execute_init(
|
||||
run_mask.set_count_on(batch_size);
|
||||
|
||||
run_func(&bsg, context().m_heap.get(), &wide_shadeindex.data(),
|
||||
userdata_base_ptr, output_base_ptr, run_mask.value(),
|
||||
sgroup.interactive_arena_ptr());
|
||||
userdata_base_ptr, output_base_ptr, run_mask.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,8 +360,7 @@ ShadingContext::Batched<WidthT>::execute_layer(
|
||||
run_mask.set_count_on(batch_size);
|
||||
|
||||
run_func(&bsg, context().m_heap.get(), &wide_shadeindex.data(),
|
||||
userdata_base_ptr, output_base_ptr, run_mask.value(),
|
||||
group()->interactive_arena_ptr());
|
||||
userdata_base_ptr, output_base_ptr, run_mask.value());
|
||||
}
|
||||
|
||||
if (profile)
|
||||
@@ -627,8 +625,8 @@ ShadingContext::find_regex(ustring r)
|
||||
|
||||
bool
|
||||
ShadingContext::osl_get_attribute(ShaderGlobals* sg, void* objdata,
|
||||
int dest_derivs, ustringhash obj_name,
|
||||
ustringhash attr_name, int array_lookup,
|
||||
int dest_derivs, ustring obj_name,
|
||||
ustring attr_name, int array_lookup,
|
||||
int index, TypeDesc attr_type,
|
||||
void* attr_dest)
|
||||
{
|
||||
|
||||
+49
-71
@@ -182,8 +182,7 @@ compatible_param(const TypeDesc& a, const TypeDesc& b)
|
||||
|
||||
|
||||
void
|
||||
ShaderInstance::parameters(const ParamValueList& params,
|
||||
cspan<ParamHints> hints)
|
||||
ShaderInstance::parameters(const ParamValueList& params)
|
||||
{
|
||||
// Seed the params with the master's defaults
|
||||
m_iparams = m_master->m_idefaults;
|
||||
@@ -196,13 +195,11 @@ ShaderInstance::parameters(const ParamValueList& params,
|
||||
// on the master.
|
||||
for (int i = 0, e = (int)m_instoverrides.size(); i < e; ++i) {
|
||||
Symbol* sym = master()->symbol(i);
|
||||
m_instoverrides[i].interpolated(sym->interpolated());
|
||||
m_instoverrides[i].interactive(sym->interactive());
|
||||
m_instoverrides[i].lockgeom(sym->lockgeom());
|
||||
m_instoverrides[i].dataoffset(sym->dataoffset());
|
||||
}
|
||||
|
||||
for (size_t pi = 0; pi < params.size(); ++pi) {
|
||||
const ParamValue& p(params[pi]);
|
||||
for (auto&& p : params) {
|
||||
if (p.name().size() == 0)
|
||||
continue; // skip empty names
|
||||
int i = findparam(p.name());
|
||||
@@ -247,7 +244,22 @@ ShaderInstance::parameters(const ParamValueList& params,
|
||||
valuetype = TypeDesc::FLOAT;
|
||||
}
|
||||
|
||||
if (!relaxed_equivalent(sm_typespec, valuetype)) {
|
||||
// Relaxed rules just look to see that the types are isomorphic to each other (ie: same number of base values)
|
||||
// Note that:
|
||||
// * basetypes must match exactly (int vs float vs string)
|
||||
// * valuetype cannot be unsized (we must know the concrete number of values)
|
||||
// * if paramtype is sized (or not an array) just check for the total number of entries
|
||||
// * if paramtype is unsized (shader writer is flexible about how many values come in) -- make sure we are a multiple of the target type
|
||||
// * allow a single float setting a vec3 (or equivalent)
|
||||
if (!(valuetype.basetype == paramtype.basetype
|
||||
&& !valuetype.is_unsized_array()
|
||||
&& ((!paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() == paramtype.basevalues())
|
||||
|| (paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() % paramtype.aggregate
|
||||
== 0)
|
||||
|| (paramtype.is_vec3()
|
||||
&& valuetype == TypeDesc::FLOAT)))) {
|
||||
// We are being very relaxed in this mode, so if the user _still_ got it wrong
|
||||
// something more serious is at play and we should treat it as an error.
|
||||
shadingsys().errorfmt(
|
||||
@@ -265,14 +277,13 @@ ShaderInstance::parameters(const ParamValueList& params,
|
||||
// Mark that the override as an instance value
|
||||
so->valuesource(Symbol::InstanceVal);
|
||||
|
||||
// Pass on any interpolated or interactive hints.
|
||||
auto hint = hints[pi];
|
||||
so->interpolated(sm->interpolated()
|
||||
|| (hint & ParamHints::interpolated)
|
||||
== ParamHints::interpolated);
|
||||
so->interactive((hint & ParamHints::interactive)
|
||||
== ParamHints::interactive);
|
||||
bool lockgeom = !so->interpolated() && !so->interactive();
|
||||
// Lock the param against geometric primitive overrides if the
|
||||
// master thinks it was so locked, AND the Parameter() call
|
||||
// didn't specify lockgeom=false (which would be indicated by
|
||||
// the parameter's interpolation being non-CONSTANT).
|
||||
bool lockgeom = (sm->lockgeom()
|
||||
&& p.interp() == ParamValue::INTERP_CONSTANT);
|
||||
so->lockgeom(lockgeom);
|
||||
|
||||
OSL_DASSERT(so->dataoffset() == sm->dataoffset());
|
||||
so->dataoffset(sm->dataoffset());
|
||||
@@ -456,7 +467,7 @@ ShaderInstance::evaluate_writes_globals_and_userdata_params()
|
||||
// the symbol overrides. This is very important to get instance merging
|
||||
// working correctly.
|
||||
for (auto&& s : m_instoverrides) {
|
||||
if (s.interpolated())
|
||||
if (!s.lockgeom())
|
||||
userdata_params(true);
|
||||
}
|
||||
}
|
||||
@@ -495,8 +506,7 @@ ShaderInstance::copy_code_from_master(ShaderGroup& group)
|
||||
si->arraylen(m_instoverrides[i].arraylen());
|
||||
si->valuesource(m_instoverrides[i].valuesource());
|
||||
si->connected_down(m_instoverrides[i].connected_down());
|
||||
si->interpolated(m_instoverrides[i].interpolated());
|
||||
si->interactive(m_instoverrides[i].interactive());
|
||||
si->lockgeom(m_instoverrides[i].lockgeom());
|
||||
si->dataoffset(m_instoverrides[i].dataoffset());
|
||||
si->set_dataptr(SymArena::Absolute, param_storage(i));
|
||||
}
|
||||
@@ -639,12 +649,10 @@ ShaderInstance::mergeable(const ShaderInstance& b,
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
// But still, if they differ in whether they are interpolated or
|
||||
// interactive, we can't merge the instances.
|
||||
if (m_instoverrides[i].interpolated()
|
||||
!= b.m_instoverrides[i].interpolated()
|
||||
|| m_instoverrides[i].interactive()
|
||||
!= b.m_instoverrides[i].interactive()) {
|
||||
// But still, if they differ in their lockgeom'edness, we can't
|
||||
// merge the instances.
|
||||
if (m_instoverrides[i].lockgeom()
|
||||
!= b.m_instoverrides[i].lockgeom()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -660,14 +668,10 @@ ShaderInstance::mergeable(const ShaderInstance& b,
|
||||
continue;
|
||||
if (sym->typespec().is_closure())
|
||||
continue; // Closures can't have instance override values
|
||||
// Even if the symbols' values match now, they might not in the
|
||||
// future with 'interactive' parameters.
|
||||
const Symbol* b_sym = optimized ? b.symbol(i) : b.mastersymbol(i);
|
||||
if ((sym->valuesource() == Symbol::InstanceVal
|
||||
|| sym->valuesource() == Symbol::DefaultVal)
|
||||
&& (memcmp(param_storage(i), b.param_storage(i),
|
||||
sym->typespec().simpletype().size())
|
||||
|| b_sym->interactive())) {
|
||||
&& memcmp(param_storage(i), b.param_storage(i),
|
||||
sym->typespec().simpletype().size())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -732,8 +736,7 @@ ShaderInstance::mergeable(const ShaderInstance& b,
|
||||
|
||||
|
||||
|
||||
ShaderGroup::ShaderGroup(string_view name, ShadingSystemImpl& shadingsys)
|
||||
: m_shadingsys(shadingsys)
|
||||
ShaderGroup::ShaderGroup(string_view name)
|
||||
{
|
||||
m_id = ++(*(atomic_int*)&next_id);
|
||||
if (name.size()) {
|
||||
@@ -746,6 +749,15 @@ ShaderGroup::ShaderGroup(string_view name, ShadingSystemImpl& shadingsys)
|
||||
|
||||
|
||||
|
||||
ShaderGroup::ShaderGroup(const ShaderGroup& g, string_view name)
|
||||
: ShaderGroup(name) // delegate most of the work
|
||||
{
|
||||
m_num_entry_layers = g.m_num_entry_layers;
|
||||
m_layers = g.m_layers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ShaderGroup::~ShaderGroup()
|
||||
{
|
||||
#if 0
|
||||
@@ -760,11 +772,6 @@ ShaderGroup::~ShaderGroup()
|
||||
<< "executed on " << executions() << " points\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Free any GPU memory associated with this group
|
||||
if (m_device_interactive_arena)
|
||||
shadingsys().renderer()->device_free(
|
||||
m_device_interactive_arena.d_get());
|
||||
}
|
||||
|
||||
|
||||
@@ -817,34 +824,6 @@ ShaderGroup::mark_entry_layer(int layer)
|
||||
|
||||
|
||||
|
||||
void
|
||||
ShaderGroup::setup_interactive_arena(cspan<uint8_t> paramblock)
|
||||
{
|
||||
if (paramblock.size()) {
|
||||
// CPU side
|
||||
m_interactive_arena_size = paramblock.size();
|
||||
m_interactive_arena.reset(new uint8_t[m_interactive_arena_size]);
|
||||
memcpy(m_interactive_arena.get(), paramblock.data(),
|
||||
m_interactive_arena_size);
|
||||
if (shadingsys().use_optix()) {
|
||||
// GPU side
|
||||
RendererServices* rs = shadingsys().renderer();
|
||||
m_device_interactive_arena.reset(reinterpret_cast<uint8_t*>(
|
||||
rs->device_alloc(m_interactive_arena_size)));
|
||||
rs->copy_to_device(m_device_interactive_arena.d_get(),
|
||||
paramblock.data(), m_interactive_arena_size);
|
||||
// print("group {} has device interactive_params set to {:p}\n",
|
||||
// name(), m_device_interactive_arena.d_get());
|
||||
}
|
||||
} else {
|
||||
m_interactive_arena_size = 0;
|
||||
m_interactive_arena.reset();
|
||||
m_device_interactive_arena.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string
|
||||
ShaderGroup::serialize() const
|
||||
{
|
||||
@@ -897,12 +876,11 @@ ShaderGroup::serialize() const
|
||||
OSL_ASSERT_MSG(0, "unknown type for serialization: %s (%s)",
|
||||
type.c_str(), s->typespec().c_str());
|
||||
}
|
||||
if (dstsyms_exist ? s->interpolated()
|
||||
: inst->instoverride(p)->interpolated())
|
||||
print(out, " [[int interpolated=1]]");
|
||||
if (dstsyms_exist ? s->interactive()
|
||||
: inst->instoverride(p)->interactive())
|
||||
print(out, " [[int interactive=1]]");
|
||||
bool lockgeom = dstsyms_exist
|
||||
? s->lockgeom()
|
||||
: inst->instoverride(p)->lockgeom();
|
||||
if (!lockgeom)
|
||||
print(out, " [[int lockgeom={}]]", lockgeom);
|
||||
out << " ;\n";
|
||||
}
|
||||
}
|
||||
|
||||
+17
-38
@@ -6,6 +6,11 @@
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
#include <OSL/genclosure.h>
|
||||
#include "backendllvm.h"
|
||||
@@ -111,16 +116,15 @@ BackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
// Make code that looks like:
|
||||
// if (! groupdata->run[parentlayer])
|
||||
// parent_layer (sg, groupdata, userdata_base_ptr,
|
||||
// output_base_ptr, shadeindex, interactive_params);
|
||||
// output_base_ptr, shadeindex);
|
||||
// if it's a conditional call, or
|
||||
// parent_layer (sg, groupdata, userdata_base_ptr,
|
||||
// output_base_ptr, shadeindex, interactive_params);
|
||||
// output_base_ptr, shadeindex);
|
||||
// if it's run unconditionally.
|
||||
// The code in the parent layer itself will set its 'executed' flag.
|
||||
|
||||
llvm::Value* args[]
|
||||
= { sg_ptr(), groupdata_ptr(), userdata_base_ptr(),
|
||||
output_base_ptr(), shadeindex(), m_llvm_interactive_params_ptr };
|
||||
llvm::Value* args[] = { sg_ptr(), groupdata_ptr(), userdata_base_ptr(),
|
||||
output_base_ptr(), shadeindex() };
|
||||
|
||||
ShaderInstance* parent = group()[layer];
|
||||
llvm::Value* trueval = ll.constant_bool(true);
|
||||
@@ -143,8 +147,6 @@ BackendLLVM::llvm_call_layer(int layer, bool unconditional)
|
||||
|
||||
if (!unconditional)
|
||||
ll.op_branch(after_block); // also moves insert point
|
||||
|
||||
shadingsys().m_stat_call_layers_inserted++;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,15 +193,6 @@ BackendLLVM::llvm_run_connected_layers(Symbol& sym, int symindex, int opnum,
|
||||
}
|
||||
}
|
||||
|
||||
if (shadingsys().m_opt_useparam && inmain) {
|
||||
// m_call_layers_inserted tracks if we've already run this layer inside the current basic block
|
||||
const CallLayerKey key = { m_bblockids[opnum], con.srclayer };
|
||||
if (m_call_layers_inserted.count(key)) {
|
||||
continue;
|
||||
}
|
||||
m_call_layers_inserted.insert(key);
|
||||
}
|
||||
|
||||
// If the earlier layer it comes from has not yet been
|
||||
// executed, do so now.
|
||||
llvm_call_layer(con.srclayer);
|
||||
@@ -239,15 +232,12 @@ LLVMGEN(llvm_gen_useparam)
|
||||
// initializing them lazily, now we have to do it.
|
||||
if ((sym.symtype() == SymTypeParam
|
||||
|| sym.symtype() == SymTypeOutputParam)
|
||||
&& sym.interpolated() && !sym.typespec().is_closure()
|
||||
&& !sym.lockgeom() && !sym.typespec().is_closure()
|
||||
&& !sym.connected() && !sym.connected_down()
|
||||
&& rop.shadingsys().lazy_userdata()) {
|
||||
rop.llvm_assign_initial_value(sym);
|
||||
}
|
||||
}
|
||||
|
||||
rop.increment_useparam_ops();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -384,7 +374,6 @@ LLVMGEN(llvm_gen_printf)
|
||||
}
|
||||
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
// In OptiX, printf currently supports 0 or 1 arguments, and the signature
|
||||
// requires 1 argument, so push a null pointer onto the call args if there
|
||||
// is no argument.
|
||||
@@ -393,7 +382,6 @@ LLVMGEN(llvm_gen_printf)
|
||||
// we push the size of the arguments on the stack
|
||||
optix_size += sizeof(uint64_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Some ops prepend things
|
||||
if (op.opname() == op_error || op.opname() == op_warning) {
|
||||
@@ -402,8 +390,9 @@ LLVMGEN(llvm_gen_printf)
|
||||
}
|
||||
|
||||
// Now go back and put the new format string in its place
|
||||
#if OSL_USE_OPTIX
|
||||
if (rop.use_optix()) {
|
||||
if (!rop.use_optix()) {
|
||||
call_args[new_format_slot] = rop.llvm_load_string(s);
|
||||
} else {
|
||||
// In OptiX7+ case, we do this:
|
||||
// void* args = { args_size, arg0, arg1, arg2 };
|
||||
// (where args_size is the size of arg0 + arg1 + arg2...)
|
||||
@@ -461,10 +450,6 @@ LLVMGEN(llvm_gen_printf)
|
||||
}
|
||||
call_args.resize(new_format_slot + 2);
|
||||
call_args.back() = rop.ll.void_ptr(voids);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
call_args[new_format_slot] = rop.llvm_load_string(s);
|
||||
}
|
||||
|
||||
// Construct the function name and call it.
|
||||
@@ -2476,9 +2461,7 @@ LLVMGEN(llvm_gen_texture)
|
||||
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
|
||||
texture_handle
|
||||
= rop.renderer()->get_texture_handle(Filename.get_string(),
|
||||
rop.shadingcontext(), nullptr);
|
||||
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
|
||||
// that has the colorspace set.
|
||||
rop.shadingcontext());
|
||||
}
|
||||
|
||||
// Now call the osl_texture function, passing the options and all the
|
||||
@@ -2543,9 +2526,7 @@ LLVMGEN(llvm_gen_texture3d)
|
||||
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
|
||||
texture_handle
|
||||
= rop.renderer()->get_texture_handle(Filename.get_string(),
|
||||
rop.shadingcontext(), nullptr);
|
||||
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
|
||||
// that has the colorspace set.
|
||||
rop.shadingcontext());
|
||||
}
|
||||
|
||||
// Now call the osl_texture3d function, passing the options and all the
|
||||
@@ -2608,9 +2589,7 @@ LLVMGEN(llvm_gen_environment)
|
||||
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
|
||||
texture_handle
|
||||
= rop.renderer()->get_texture_handle(Filename.get_string(),
|
||||
rop.shadingcontext(), nullptr);
|
||||
// FIXME(colorspace): that nullptr should be replaced by a TextureOpt*
|
||||
// that has the colorspace set.
|
||||
rop.shadingcontext());
|
||||
}
|
||||
|
||||
// Now call the osl_environment function, passing the options and all the
|
||||
@@ -3061,7 +3040,7 @@ LLVMGEN(llvm_gen_gettextureinfo)
|
||||
if (Filename.is_constant() && rop.shadingsys().opt_texture_handle()) {
|
||||
texture_handle
|
||||
= rop.renderer()->get_texture_handle(Filename.get_string(),
|
||||
rop.shadingcontext(), nullptr);
|
||||
rop.shadingcontext());
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <OpenImageIO/sysutil.h>
|
||||
#include <OpenImageIO/timer.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "../liboslcomp/oslcomp_pvt.h"
|
||||
#include "oslexec_pvt.h"
|
||||
#include "backendllvm.h"
|
||||
@@ -57,18 +61,10 @@ Schematically, we want to create code that resembles the following:
|
||||
float param_1_bar;
|
||||
};
|
||||
|
||||
// Data for the interactively adjusted parameters of this group -- these
|
||||
// can't be turned into constants because the app may want to modify them
|
||||
// as it runs (such as for user interaction). This block of memory has
|
||||
// one global copy specific each the shader group, managed by OSL.
|
||||
struct InteractiveParams {
|
||||
float iparam_0_baz;
|
||||
};
|
||||
|
||||
// Name of layer entry is $layer_ID
|
||||
void $layer_0(ShaderGlobals* sg, GroupData* group,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int shadeindex, InteractiveParams* interactive_params)
|
||||
int shadeindex)
|
||||
{
|
||||
// Declare locals, temps, constants, params with known values.
|
||||
// Make them all look like stack memory locations:
|
||||
@@ -78,27 +74,25 @@ Schematically, we want to create code that resembles the following:
|
||||
// then run the shader body:
|
||||
*x = sg->u * group->param_0_bar;
|
||||
group->param_1_foo = *x;
|
||||
*x += interactive_params->iparam_0_baz;
|
||||
// ...
|
||||
}
|
||||
|
||||
void $layer_1(ShaderGlobals* sg, GroupData* group,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int shadeindex, InteractiveParams* interactive_params)
|
||||
int shadeindex)
|
||||
{
|
||||
// Because we need the outputs of layer 0 now, we call it if it
|
||||
// hasn't already run:
|
||||
if (! group->layer_run[0]) {
|
||||
group->layer_run[0] = 1;
|
||||
$layer_0 (sg, group, userdata_base_ptr, output_base_ptr,
|
||||
shadeindex, interactive_params); // because we need its outputs
|
||||
shadeindex); // because we need its outputs
|
||||
}
|
||||
*y = sg->u * group->$param_1_bar;
|
||||
}
|
||||
|
||||
void $group_1(ShaderGlobals* sg, GroupData* group,
|
||||
void* userdatda_base_ptr, void* output_base_ptr,
|
||||
int shadeindex, InteractiveParams* interactive_params)
|
||||
int shadeindex)
|
||||
{
|
||||
group->layer_run[...] = 0;
|
||||
// Run just the unconditional layers
|
||||
@@ -106,7 +100,7 @@ Schematically, we want to create code that resembles the following:
|
||||
if (! group->layer_run[1]) {
|
||||
group->layer_run[1] = 1;
|
||||
$layer_1(sg, group, userdata_base_ptr, output_base_ptr,
|
||||
shadeindex, interactive_params);
|
||||
shadeindex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,10 +283,14 @@ BackendLLVM::llvm_type_groupdata()
|
||||
++order;
|
||||
for (int i = 0; i < nuserdata; ++i) {
|
||||
TypeDesc type = types[i];
|
||||
// make room for float derivs only
|
||||
type.arraylen = type.basetype == TypeDesc::FLOAT
|
||||
? type.numelements() * 3
|
||||
: type.numelements();
|
||||
// NB: Userdata derivs are not currently supported in OptiX, since
|
||||
// making room for them in the GroupData struct can result in a
|
||||
// large per-thread memory allocation, which could negatively
|
||||
// impact performance.
|
||||
int n = (!use_optix()) ? type.numelements()
|
||||
* 3 // make room for derivs by default
|
||||
: type.numelements();
|
||||
type.arraylen = n;
|
||||
fields.push_back(llvm_type(type));
|
||||
m_groupdata_field_names.emplace_back(
|
||||
fmtformat("userdata{}_{}_", i, names[i]));
|
||||
@@ -334,8 +332,8 @@ BackendLLVM::llvm_type_groupdata()
|
||||
&& !sym.connected_down()) {
|
||||
auto found = group().find_symloc(sym.name());
|
||||
if (found)
|
||||
print("layer {} \"{}\" : OUTPUT {}\n", layer,
|
||||
inst->layername(), found->name);
|
||||
OIIO::Strutil::print("layer {} \"{}\" : OUTPUT {}\n", layer,
|
||||
inst->layername(), found->name);
|
||||
}
|
||||
|
||||
// Alignment
|
||||
@@ -345,11 +343,11 @@ BackendLLVM::llvm_type_groupdata()
|
||||
if (offset & (align - 1))
|
||||
offset += align - (offset & (align - 1));
|
||||
if (llvm_debug() >= 2)
|
||||
print(" {} ({}) {} {}, field {}, size {}, offset {}{}{}\n",
|
||||
inst->layername(), inst->id(), sym.mangled(), ts.c_str(),
|
||||
order, derivSize * int(sym.size()), offset,
|
||||
sym.interpolated() ? " (interpolated)" : "",
|
||||
sym.interactive() ? " (interactive)" : "");
|
||||
std::cout << " " << inst->layername() << " (" << inst->id()
|
||||
<< ") " << sym.mangled() << " " << ts.c_str()
|
||||
<< ", field " << order << ", size "
|
||||
<< derivSize * int(sym.size()) << ", offset "
|
||||
<< offset << std::endl;
|
||||
sym.dataoffset((int)offset);
|
||||
// TODO(arenas): sym.set_dataoffset(SymArena::Heap, offset);
|
||||
offset += derivSize * sym.size();
|
||||
@@ -478,7 +476,7 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
|
||||
// such userdata was available.
|
||||
llvm::BasicBlock* after_userdata_block = nullptr;
|
||||
const SymLocationDesc* symloc = nullptr;
|
||||
if (sym.interpolated() && !sym.typespec().is_closure()) {
|
||||
if (!sym.lockgeom() && !sym.typespec().is_closure()) {
|
||||
ustring symname = sym.name();
|
||||
TypeDesc type = sym.typespec().simpletype();
|
||||
|
||||
@@ -562,7 +560,6 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
|
||||
if (sym.has_init_ops() && sym.valuesource() == Symbol::DefaultVal) {
|
||||
// Handle init ops.
|
||||
build_llvm_code(sym.initbegin(), sym.initend());
|
||||
#if OSL_USE_OPTIX
|
||||
} else if (use_optix() && !sym.typespec().is_closure()) {
|
||||
// If the call to osl_bind_interpolated_param returns 0, the default
|
||||
// value needs to be loaded from a CUDA variable.
|
||||
@@ -573,10 +570,7 @@ BackendLLVM::llvm_assign_initial_value(const Symbol& sym, bool force)
|
||||
llvm::Value* dst = llvm_void_ptr(sym);
|
||||
TypeDesc t = sym.typespec().simpletype();
|
||||
ll.op_memcpy(dst, src, t.size(), t.basesize());
|
||||
if (sym.has_derivs())
|
||||
llvm_zero_derivs(sym);
|
||||
#endif
|
||||
} else if (sym.interpolated() && !sym.typespec().is_closure()) {
|
||||
} else if (!sym.lockgeom() && !sym.typespec().is_closure()) {
|
||||
// geometrically-varying param; memcpy its default value
|
||||
TypeDesc t = sym.typespec().simpletype();
|
||||
ll.op_memcpy(llvm_void_ptr(sym), ll.constant_ptr(sym.data()),
|
||||
@@ -870,13 +864,10 @@ BackendLLVM::build_llvm_init()
|
||||
ll.current_function(
|
||||
ll.make_function(unique_name, false,
|
||||
ll.type_void(), // return type
|
||||
{
|
||||
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int(),
|
||||
ll.type_void_ptr(), // FIXME: interactive params
|
||||
}));
|
||||
{ llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int() }));
|
||||
|
||||
if (ll.debug_is_enabled()) {
|
||||
ustring sourcefile
|
||||
@@ -886,17 +877,10 @@ BackendLLVM::build_llvm_init()
|
||||
|
||||
// Get shader globals and groupdata pointers
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_groupdata_ptr->setName("groupdata_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(2); //arg_it++;
|
||||
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_output_base_ptr->setName("output_base_ptr");
|
||||
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
|
||||
m_llvm_shadeindex->setName("shadeindex");
|
||||
m_llvm_interactive_params_ptr = ll.current_function_arg(5); //arg_it++;
|
||||
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
|
||||
|
||||
// Set up a new IR builder
|
||||
llvm::BasicBlock* entry_bb = ll.new_basic_block(unique_name);
|
||||
@@ -976,13 +960,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
|
||||
unique_layer_name,
|
||||
!is_entry_layer, // fastcall for non-entry layer functions
|
||||
ll.type_void(), // return type
|
||||
{
|
||||
llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int(),
|
||||
ll.type_void_ptr(), // FIXME: interactive_params
|
||||
}));
|
||||
{ llvm_type_sg_ptr(), llvm_type_groupdata_ptr(),
|
||||
ll.type_void_ptr(), // userdata_base_ptr
|
||||
ll.type_void_ptr(), // output_base_ptr
|
||||
ll.type_int() }));
|
||||
|
||||
if (ll.debug_is_enabled()) {
|
||||
const Opcode& mainbegin(inst()->op(inst()->maincodebegin()));
|
||||
@@ -992,17 +973,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
|
||||
|
||||
// Get shader globals and groupdata pointers
|
||||
m_llvm_shaderglobals_ptr = ll.current_function_arg(0); //arg_it++;
|
||||
m_llvm_shaderglobals_ptr->setName("shaderglobals_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_groupdata_ptr->setName("groupdata_ptr");
|
||||
m_llvm_groupdata_ptr = ll.current_function_arg(1); //arg_it++;
|
||||
m_llvm_userdata_base_ptr = ll.current_function_arg(2); //arg_it++;
|
||||
m_llvm_userdata_base_ptr->setName("userdata_base_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_output_base_ptr->setName("output_base_ptr");
|
||||
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
|
||||
m_llvm_shadeindex->setName("shadeindex");
|
||||
m_llvm_interactive_params_ptr = ll.current_function_arg(5); //arg_it++;
|
||||
m_llvm_interactive_params_ptr->setName("interactive_params_ptr");
|
||||
m_llvm_output_base_ptr = ll.current_function_arg(3); //arg_it++;
|
||||
m_llvm_shadeindex = ll.current_function_arg(4); //arg_it++;
|
||||
|
||||
llvm::BasicBlock* entry_bb = ll.new_basic_block(unique_layer_name);
|
||||
m_exit_instance_block = NULL;
|
||||
@@ -1104,12 +1078,10 @@ BackendLLVM::build_llvm_instance(bool groupentry)
|
||||
&& !s.renderer_output())
|
||||
continue;
|
||||
// Skip if it's an interpolated (userdata) parameter and we're
|
||||
// initializing them lazily, or if it's an interactively-adjusted
|
||||
// parameter.
|
||||
if (s.symtype() == SymTypeParam && !s.typespec().is_closure()
|
||||
&& !s.connected() && !s.connected_down()
|
||||
&& (s.interactive()
|
||||
|| (s.interpolated() && shadingsys().lazy_userdata())))
|
||||
// initializing them lazily.
|
||||
if (s.symtype() == SymTypeParam && !s.lockgeom()
|
||||
&& !s.typespec().is_closure() && !s.connected()
|
||||
&& !s.connected_down() && shadingsys().lazy_userdata())
|
||||
continue;
|
||||
// Set initial value for params (may contain init ops)
|
||||
llvm_assign_initial_value(s);
|
||||
@@ -1132,7 +1104,6 @@ BackendLLVM::build_llvm_instance(bool groupentry)
|
||||
// records for each.
|
||||
find_basic_blocks();
|
||||
find_conditionals();
|
||||
m_call_layers_inserted.clear();
|
||||
|
||||
build_llvm_code(inst()->maincodebegin(), inst()->maincodeend());
|
||||
|
||||
@@ -1334,12 +1305,10 @@ BackendLLVM::initialize_llvm_group()
|
||||
}
|
||||
types += advance;
|
||||
}
|
||||
#if OSL_USE_OPTIX
|
||||
if (varargs && use_optix()) {
|
||||
varargs = false;
|
||||
params.push_back(ll.type_void_ptr());
|
||||
}
|
||||
#endif
|
||||
llvm::Function* f = ll.make_function(funcname, false,
|
||||
llvm_type(rettype), params,
|
||||
varargs);
|
||||
@@ -1395,19 +1364,6 @@ BackendLLVM::run()
|
||||
#ifdef OSL_LLVM_NO_BITCODE
|
||||
OSL_ASSERT(!use_rs_bitcode());
|
||||
ll.module(ll.new_module("llvm_ops"));
|
||||
# if OSL_USE_OPTIX
|
||||
if (use_optix()) {
|
||||
// If the module is created from LLVM bitcode, the target and
|
||||
// data layout is inherited from that, but if creating an empty
|
||||
// module like here, have to manually set those, otherwise
|
||||
// compiling will later fail because the NVPTX target is not found.
|
||||
// The target triple and data layout used here are those specified
|
||||
// for NVPTX (https://www.llvm.org/docs/NVPTXUsage.html#triples).
|
||||
ll.module()->setDataLayout(
|
||||
"e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
|
||||
ll.module()->setTargetTriple("nvptx64-nvidia-cuda");
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
if (!use_optix()) {
|
||||
if (use_rs_bitcode()) {
|
||||
@@ -1649,16 +1605,13 @@ BackendLLVM::run()
|
||||
}
|
||||
}
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
if (use_optix()) {
|
||||
ll.ptx_compile_group(nullptr, group().name().string(),
|
||||
group().m_llvm_ptx_compiled_version);
|
||||
if (group().m_llvm_ptx_compiled_version.empty()) {
|
||||
OSL_ASSERT(0 && "Unable to generate PTX");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
// Force the JIT to happen now and retrieve the JITed function pointers
|
||||
// for the initialization and all public entry points.
|
||||
group().llvm_compiled_init(
|
||||
|
||||
+17
-26
@@ -27,8 +27,9 @@ examples), as you are just coding in C++, but there are some rules:
|
||||
float. Aggregates (color/point/vector/normal/matrix), arrays of any
|
||||
types, or floats with derivatives are passed as a void* and to their
|
||||
memory location you need to cast appropriately. Strings are passed as
|
||||
ustringrep. See the handy USTR, MAT, VEC, DFLOAT, DVEC macros for
|
||||
handy/cheap casting of those void*'s to references to ustringrep&,
|
||||
char*, but they are always the characters of 'ustring' objects, so are
|
||||
unique. See the handy USTR, MAT, VEC, DFLOAT, DVEC macros for
|
||||
handy/cheap casting of those void*'s to references to ustring&,
|
||||
Matrix44&, Vec3&, Dual2<float>&, and Dual2<Vec3>, respectively.
|
||||
|
||||
* You must provide all allowable polymorphic and derivative combinations!
|
||||
@@ -100,23 +101,13 @@ void* __dso_handle = 0; // necessary to avoid linkage issues in bitcode
|
||||
|
||||
|
||||
// Handy re-casting macros
|
||||
#define USTR(s) (*((ustringrep*)&s))
|
||||
#define USTREP(s) (*((ustringrep*)&s))
|
||||
#define MAT(m) (*(Matrix44*)m)
|
||||
#define VEC(v) (*(Vec3*)v)
|
||||
#define DFLOAT(x) (*(Dual2<Float>*)x)
|
||||
#define DVEC(x) (*(Dual2<Vec3>*)x)
|
||||
#define COL(x) (*(Color3*)x)
|
||||
#define DCOL(x) (*(Dual2<Color3>*)x)
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
/// ustring_pod is the type we use to pass string data in llvm function calls.
|
||||
using ustring_pod = size_t;
|
||||
#else
|
||||
/// ustring_pod is the type we use to pass string data in llvm function calls.
|
||||
using ustring_pod = const char*;
|
||||
#endif
|
||||
|
||||
#define USTR(cstr) (*((ustring*)&cstr))
|
||||
#define MAT(m) (*(Matrix44*)m)
|
||||
#define VEC(v) (*(Vec3*)v)
|
||||
#define DFLOAT(x) (*(Dual2<Float>*)x)
|
||||
#define DVEC(x) (*(Dual2<Vec3>*)x)
|
||||
#define COL(x) (*(Color3*)x)
|
||||
#define DCOL(x) (*(Dual2<Color3>*)x)
|
||||
|
||||
#ifndef OSL_SHADEOP
|
||||
# ifdef __CUDACC__
|
||||
@@ -984,17 +975,17 @@ osl_raytype_bit(void* sg_, int bit)
|
||||
|
||||
// extern declaration
|
||||
OSL_SHADEOP_NOINLINE int
|
||||
osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
|
||||
ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname, int layer, ustring_pod layername,
|
||||
ustring_pod shadername);
|
||||
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername);
|
||||
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_range_check(int indexvalue, int length, ustring_pod symname, void* sg,
|
||||
ustring_pod sourcefile, int sourceline, ustring_pod groupname,
|
||||
int layer, ustring_pod layername, ustring_pod shadername)
|
||||
osl_range_check(int indexvalue, int length, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline, const char* groupname,
|
||||
int layer, const char* layername, const char* shadername)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
#include <llvm/Transforms/Utils/Cloning.h>
|
||||
#include <llvm/Transforms/Utils/SymbolRewriter.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
|
||||
@@ -2451,11 +2455,6 @@ LLVM_Util::make_function(const std::string& name, bool fastcall,
|
||||
llvm::FunctionType* functype = type_function(rettype, params, varargs);
|
||||
auto maybe_func = module()->getOrInsertFunction(name, functype).getCallee();
|
||||
OSL_ASSERT(maybe_func && "getOrInsertFunction returned NULL");
|
||||
// if (!llvm::isa<llvm::Function>(maybe_func)) {
|
||||
// print("make_function: getOrInsertFunction returned non-function for {}\n", name);
|
||||
// for (auto p : params)
|
||||
// print(" param type: {}\n", llvm_typename(p));
|
||||
// }
|
||||
OSL_ASSERT_MSG(llvm::isa<llvm::Function>(maybe_func),
|
||||
"Declaration for %s is wrong, LLVM had to make a cast",
|
||||
name.c_str());
|
||||
@@ -2674,18 +2673,7 @@ LLVM_Util::type_array(llvm::Type* type, int n)
|
||||
return llvm::ArrayType::get(type, n);
|
||||
}
|
||||
|
||||
bool
|
||||
LLVM_Util::is_type_array(llvm::Type* type)
|
||||
{
|
||||
return type->isArrayTy();
|
||||
}
|
||||
|
||||
llvm::Type*
|
||||
LLVM_Util::element_type_of(llvm::Type* array_type)
|
||||
{
|
||||
OSL_DASSERT(is_type_array(array_type));
|
||||
return array_type->getArrayElementType();
|
||||
}
|
||||
|
||||
llvm::FunctionType*
|
||||
LLVM_Util::type_function(llvm::Type* rettype, cspan<llvm::Type*> params,
|
||||
@@ -2862,21 +2850,15 @@ LLVM_Util::constant(ustring s)
|
||||
const size_t size_t_bits = sizeof(size_t) * 8;
|
||||
// Create a const size_t with the ustring character address, or hash,
|
||||
// depending on the representation we're using.
|
||||
if (ustring_rep() == UstringRep::charptr) {
|
||||
return constant_ptr((void*)s.c_str(), type_char_ptr());
|
||||
} else {
|
||||
size_t p = s.hash();
|
||||
auto str = (size_t_bits == 64) ? constant64(p) : constant(int(p));
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
return str;
|
||||
#else
|
||||
// Then cast the int to a char*. Ideally, we would only do that if the rep
|
||||
// were a charptr, but we disguise the hashes as char*'s also to avoid
|
||||
// ugliness with function signatures differing between CPU and GPU.
|
||||
return builder().CreateIntToPtr(str, m_llvm_type_ustring,
|
||||
"ustring constant");
|
||||
#endif
|
||||
}
|
||||
size_t p = (ustring_rep() == UstringRep::charptr) ? size_t(s.c_str())
|
||||
: s.hash();
|
||||
auto str = (size_t_bits == 64) ? constant64(p) : constant(int(p));
|
||||
// Then cast the int to a char*. Ideally, we would only do that if the rep
|
||||
// were a charptr, but we disguise the hashes as char*'s also to avoid
|
||||
// ugliness with function signatures differing between CPU and GPU.
|
||||
// Maybe some day we'll use the hash representation on both sides?
|
||||
return builder().CreateIntToPtr(str, m_llvm_type_ustring,
|
||||
"ustring constant");
|
||||
}
|
||||
|
||||
|
||||
@@ -3532,12 +3514,8 @@ LLVM_Util::offset_ptr(llvm::Value* ptr, llvm::Value* offset,
|
||||
llvm::Value*
|
||||
LLVM_Util::offset_ptr(llvm::Value* ptr, int offset, llvm::Type* ptrtype)
|
||||
{
|
||||
if (offset == 0) {
|
||||
// shortcut for 0 offset
|
||||
if (ptrtype && ptrtype != type_void_ptr())
|
||||
ptr = ptr_cast(ptr, ptrtype);
|
||||
return ptr;
|
||||
}
|
||||
if (offset == 0)
|
||||
return ptr; // shortcut for 0 offset
|
||||
return offset_ptr(ptr, constant(size_t(offset)), ptrtype);
|
||||
}
|
||||
|
||||
@@ -3613,9 +3591,9 @@ LLVM_Util::call_function(llvm::Value* func, cspan<llvm::Value*> args)
|
||||
OSL_DASSERT(func);
|
||||
#if 0
|
||||
llvm::outs() << "llvm_call_function " << *func << "\n";
|
||||
llvm::outs() << args.size() << " args:\n";
|
||||
for (auto a : args)
|
||||
llvm::outs() << "\t" << *a << "\n";
|
||||
llvm::outs() << nargs << " args:\n";
|
||||
for (int i = 0, nargs = args.size(); i < nargs; ++i)
|
||||
llvm::outs() << "\t" << *(args[i]) << "\n";
|
||||
#endif
|
||||
//llvm_gen_debug_printf (std::string("start ") + std::string(name));
|
||||
#if OSL_LLVM_VERSION >= 110
|
||||
@@ -5832,7 +5810,7 @@ bool
|
||||
LLVM_Util::ptx_compile_group(llvm::Module* lib_module, const std::string& name,
|
||||
std::string& out)
|
||||
{
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
std::string target_triple = module()->getTargetTriple();
|
||||
|
||||
OSL_ASSERT(
|
||||
|
||||
@@ -171,7 +171,7 @@ OSOReaderToMaster::symbol(SymType symtype, TypeSpec typespec, const char* name_)
|
||||
sym.dataoffset (m_shadingsys.global_heap_offset (sym.name()));
|
||||
}
|
||||
#endif
|
||||
sym.interpolated(!m_shadingsys.lockgeom_default());
|
||||
sym.lockgeom(m_shadingsys.lockgeom_default());
|
||||
m_master->m_symbols.push_back(sym);
|
||||
m_symmap[name] = int(m_master->m_symbols.size()) - 1;
|
||||
// Start the index at which we add specified defaults
|
||||
@@ -419,13 +419,7 @@ OSOReaderToMaster::hint(string_view hintstring)
|
||||
Symbol& sym(m_master->m_symbols.back());
|
||||
if (type == TypeDesc::TypeInt && ident == "lockgeom"
|
||||
&& Strutil::parse_int(h, ival) && ival >= 0)
|
||||
sym.interpolated(!ival); // soft deprecated
|
||||
else if (type == TypeDesc::TypeInt && ident == "interpolated"
|
||||
&& Strutil::parse_int(h, ival) && ival >= 0)
|
||||
sym.interpolated(ival);
|
||||
else if (type == TypeDesc::TypeInt && ident == "interactive"
|
||||
&& Strutil::parse_int(h, ival) && ival >= 0)
|
||||
sym.interactive(ival);
|
||||
sym.lockgeom(ival);
|
||||
else if (type == TypeDesc::TypeInt && ident == "allowconnect"
|
||||
&& Strutil::parse_int(h, ival) && ival >= 0)
|
||||
sym.allowconnect(ival);
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#ifdef __CUDACC__
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "opcolor.h"
|
||||
|
||||
#include "opcolor_impl.h"
|
||||
@@ -35,7 +39,7 @@ namespace pvt {
|
||||
#define IlluminantACES 0.32168, 0.33767 /* For ACES, approximate D60 */
|
||||
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
OSL_CONSTANT_DATA const ColorSystem::Chroma k_color_systems[13] = {
|
||||
OSL_CONSTANT_DATA const static ColorSystem::Chroma k_color_systems[13] = {
|
||||
// Index, Name xRed yRed xGreen yGreen xBlue yBlue White point
|
||||
/* 0 Rec709 */ { 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65 },
|
||||
/* 1 sRGB */ { 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65 },
|
||||
|
||||
@@ -27,7 +27,7 @@ class ShadingContext;
|
||||
namespace pvt {
|
||||
|
||||
|
||||
class OSLEXECPUBLIC ColorSystem {
|
||||
class ColorSystem {
|
||||
#ifdef __CUDACC__
|
||||
using Context = void*;
|
||||
#else
|
||||
|
||||
@@ -50,13 +50,8 @@ clamp_zero(Color3& c)
|
||||
//OSL_CONSTANT_DATA const float cie_colour_match[81][3] =
|
||||
// Choose to access 1d array vs 2d to allow better code generation of gathers
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
// clang-format off
|
||||
#ifdef __CUDACC__
|
||||
OSL_CONSTANT_DATA const float cie_colour_match[81*3] =
|
||||
#else
|
||||
OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) =
|
||||
#endif
|
||||
{
|
||||
static OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) = {
|
||||
// clang-format off
|
||||
0.0014,0.0000,0.0065, 0.0022,0.0001,0.0105, 0.0042,0.0001,0.0201,
|
||||
0.0076,0.0002,0.0362, 0.0143,0.0004,0.0679, 0.0232,0.0006,0.1102,
|
||||
0.0435,0.0012,0.2074, 0.0776,0.0022,0.3713, 0.1344,0.0040,0.6456,
|
||||
@@ -84,8 +79,8 @@ OSL_CONSTANT_DATA const float cie_colour_match[81 * 3] OSL_ALIGNAS(64) =
|
||||
0.0007,0.0002,0.0000, 0.0005,0.0002,0.0000, 0.0003,0.0001,0.0000,
|
||||
0.0002,0.0001,0.0000, 0.0002,0.0001,0.0000, 0.0001,0.0000,0.0000,
|
||||
0.0001,0.0000,0.0000, 0.0001,0.0000,0.0000, 0.0000,0.0000,0.0000
|
||||
// clang-format on
|
||||
};
|
||||
// clang-format on
|
||||
} // namespace
|
||||
|
||||
|
||||
|
||||
@@ -27,34 +27,33 @@ namespace pvt {
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_setmessage(ShaderGlobals* sg, ustring_pod name_, long long type_, void* val,
|
||||
int layeridx, ustring_pod sourcefile_, int sourceline)
|
||||
osl_setmessage(ShaderGlobals* sg, const char* name_, long long type_, void* val,
|
||||
int layeridx, const char* sourcefile_, int sourceline)
|
||||
{
|
||||
ustringhash name = ustringhash_from(USTR(name_));
|
||||
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
// recreate TypeDesc -- we just crammed it into an int!
|
||||
TypeDesc type = TYPEDESC(type_);
|
||||
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates closure
|
||||
bool is_closure = (type.basetype
|
||||
== TypeDesc::UNKNOWN); // secret code for closure
|
||||
if (is_closure)
|
||||
type.basetype = TypeDesc::PTR; // for closures, we store a pointer
|
||||
|
||||
MessageList& messages(sg->context->messages());
|
||||
const Message* m = messages.find(name);
|
||||
if (m) {
|
||||
if (m != NULL) {
|
||||
if (m->name == name) {
|
||||
// message already exists?
|
||||
if (m->has_data())
|
||||
sg->context->errorfmt(
|
||||
"message \"{}\" already exists (created here: {}:{})"
|
||||
" cannot set again from {}:{}",
|
||||
name.c_str(), m->sourcefile.c_str(), m->sourceline,
|
||||
sourcefile.c_str(), sourceline);
|
||||
name, m->sourcefile, m->sourceline, sourcefile, sourceline);
|
||||
else // NOTE: this cannot be triggered when strict_messages=false because we won't record "failed" getmessage calls
|
||||
sg->context->errorfmt(
|
||||
"message \"{}\" was queried before being set (queried here: {}:{})"
|
||||
" setting it now ({}:{}) would lead to inconsistent results",
|
||||
name.c_str(), m->sourcefile.c_str(), m->sourceline,
|
||||
sourcefile.c_str(), sourceline);
|
||||
name, m->sourcefile, m->sourceline, sourcefile, sourceline);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -65,21 +64,22 @@ osl_setmessage(ShaderGlobals* sg, ustring_pod name_, long long type_, void* val,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
|
||||
osl_getmessage(ShaderGlobals* sg, const char* source_, const char* name_,
|
||||
long long type_, void* val, int derivs, int layeridx,
|
||||
ustring_pod sourcefile_, int sourceline)
|
||||
const char* sourcefile_, int sourceline)
|
||||
{
|
||||
ustringhash source = ustringhash_from(USTR(source_));
|
||||
ustringhash name = ustringhash_from(USTR(name_));
|
||||
ustringhash sourcefile = ustringhash_from(USTR(sourcefile_));
|
||||
const ustring& source(USTR(source_));
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
|
||||
// recreate TypeDesc -- we just crammed it into an int!
|
||||
TypeDesc type = TYPEDESC(type_);
|
||||
bool is_closure = type.basetype == TypeDesc::UNKNOWN; // indicates closure
|
||||
bool is_closure = (type.basetype
|
||||
== TypeDesc::UNKNOWN); // secret code for closure
|
||||
if (is_closure)
|
||||
type.basetype = TypeDesc::PTR; // for closures, we store a pointer
|
||||
|
||||
static ustringrep ktrace("trace");
|
||||
static ustring ktrace("trace");
|
||||
if (source == ktrace) {
|
||||
// Source types where we need to ask the renderer
|
||||
return sg->renderer->getmessage(sg, source, name, type, val, derivs);
|
||||
@@ -87,19 +87,19 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
|
||||
|
||||
MessageList& messages(sg->context->messages());
|
||||
const Message* m = messages.find(name);
|
||||
if (m) {
|
||||
if (m != NULL) {
|
||||
if (m->name == name) {
|
||||
if (m->type != type) {
|
||||
// found message, but types don't match
|
||||
sg->context->errorfmt(
|
||||
"type mismatch for message \"{}\" ({} as {} here: {}:{})"
|
||||
" cannot fetch as {} from {}:{}",
|
||||
name.c_str(), m->has_data() ? "created" : "queried",
|
||||
name, m->has_data() ? "created" : "queried",
|
||||
m->type == TypeDesc::PTR ? "closure color"
|
||||
: m->type.c_str(),
|
||||
m->sourcefile.c_str(), m->sourceline,
|
||||
is_closure ? "closure color" : type.c_str(),
|
||||
sourcefile.c_str(), sourceline);
|
||||
m->sourcefile, m->sourceline,
|
||||
is_closure ? "closure color" : type.c_str(), sourcefile,
|
||||
sourceline);
|
||||
return 0;
|
||||
}
|
||||
if (!m->has_data()) {
|
||||
@@ -113,8 +113,8 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
|
||||
" but is being queried by layer #{} ({}:{})"
|
||||
" - messages may only be transferred from nodes "
|
||||
"that appear earlier in the shading network",
|
||||
name.c_str(), m->layeridx, m->sourcefile.c_str(),
|
||||
m->sourceline, layeridx, sourcefile.c_str(), sourceline);
|
||||
name, m->layeridx, m->sourcefile, m->sourceline, layeridx,
|
||||
sourcefile, sourceline);
|
||||
return 0;
|
||||
}
|
||||
// Message found!
|
||||
@@ -127,7 +127,7 @@ osl_getmessage(ShaderGlobals* sg, ustring_pod source_, ustring_pod name_,
|
||||
}
|
||||
// Message not found -- we must record this event in case another layer tries to set the message again later on
|
||||
if (sg->context->shadingsys().strict_messages())
|
||||
messages.add(name, nullptr, type, layeridx, sourcefile, sourceline);
|
||||
messages.add(name, NULL, type, layeridx, sourcefile, sourceline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,31 +43,32 @@ osl_texture_set_firstchannel(void* opt, int x)
|
||||
}
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_texture_decode_wrapmode(ustring_pod name)
|
||||
osl_texture_decode_wrapmode(void* name)
|
||||
{
|
||||
return OIIO::TextureOpt::decode_wrapmode(ustring_from(USTR(name)));
|
||||
const ustring& uname = USTR(name);
|
||||
return OIIO::TextureOpt::decode_wrapmode(uname);
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_swrap(void* opt, ustring_pod x)
|
||||
osl_texture_set_swrap(void* opt, const char* x)
|
||||
{
|
||||
((TextureOpt*)opt)->swrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_twrap(void* opt, ustring_pod x)
|
||||
osl_texture_set_twrap(void* opt, const char* x)
|
||||
{
|
||||
((TextureOpt*)opt)->twrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_rwrap(void* opt, ustring_pod x)
|
||||
osl_texture_set_rwrap(void* opt, const char* x)
|
||||
{
|
||||
((TextureOpt*)opt)->rwrap = TextureOpt::decode_wrapmode(USTR(x));
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_stwrap(void* opt, ustring_pod x)
|
||||
osl_texture_set_stwrap(void* opt, const char* x)
|
||||
{
|
||||
TextureOpt::Wrap code = TextureOpt::decode_wrapmode(USTR(x));
|
||||
((TextureOpt*)opt)->swrap = code;
|
||||
@@ -162,15 +163,16 @@ osl_texture_set_time(void* opt, float x)
|
||||
}
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_texture_decode_interpmode(ustring_pod name)
|
||||
osl_texture_decode_interpmode(void* name)
|
||||
{
|
||||
return tex_interp_to_code(ustring_from(USTR(name)));
|
||||
const ustring& uname = USTR(name);
|
||||
return tex_interp_to_code(uname);
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_interp(void* opt, ustring_pod modename)
|
||||
osl_texture_set_interp(void* opt, const char* modename)
|
||||
{
|
||||
int mode = tex_interp_to_code(ustring_from(USTR(modename)));
|
||||
int mode = tex_interp_to_code(USTR(modename));
|
||||
if (mode >= 0)
|
||||
((TextureOpt*)opt)->interpmode = (TextureOpt::InterpMode)mode;
|
||||
}
|
||||
@@ -189,9 +191,9 @@ osl_texture_set_subimage(void* opt, int subimage)
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_texture_set_subimagename(void* opt, ustring_pod subimagename)
|
||||
osl_texture_set_subimagename(void* opt, const char* subimagename)
|
||||
{
|
||||
((TextureOpt*)opt)->subimagename = ustring_from(USTR(subimagename));
|
||||
((TextureOpt*)opt)->subimagename = USTR(subimagename);
|
||||
}
|
||||
|
||||
OSL_SHADEOP void
|
||||
@@ -215,20 +217,19 @@ OSL_SHADEOP int
|
||||
osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
float t, float dsdx, float dtdx, float dsdy, float dtdy, int chans,
|
||||
void* result, void* dresultdx, void* dresultdy, void* alpha,
|
||||
void* dalphadx, void* dalphady, ustringrep* errormessage)
|
||||
void* dalphadx, void* dalphady, ustring* errormessage)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
TextureOpt* opt = (TextureOpt*)opt_;
|
||||
bool derivs = (dresultdx || dalphadx);
|
||||
// It's actually faster to ask for 4 channels (even if we need fewer)
|
||||
// and ensure that they're being put in aligned memory.
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
ustringhash em;
|
||||
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
bool ok = sg->renderer->texture(
|
||||
USTR(name).uhash(), (TextureSystem::TextureHandle*)handle,
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(), *opt, sg, s, t, dsdx, dtdx, dsdy,
|
||||
dtdy, 4, (float*)&result_simd, derivs ? (float*)&dresultds_simd : NULL,
|
||||
derivs ? (float*)&dresultdt_simd : NULL, errormessage ? &em : nullptr);
|
||||
derivs ? (float*)&dresultdt_simd : NULL, errormessage);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = result_simd[i];
|
||||
@@ -239,10 +240,10 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
if (derivs) {
|
||||
OSL_DASSERT((dresultdx == nullptr) == (dresultdy == nullptr));
|
||||
OSL_DASSERT((dalphadx == nullptr) == (dalphady == nullptr));
|
||||
OIIO::simd::vfloat4 dresultdx_simd = dresultds_simd * dsdx
|
||||
+ dresultdt_simd * dtdx;
|
||||
OIIO::simd::vfloat4 dresultdy_simd = dresultds_simd * dsdy
|
||||
+ dresultdt_simd * dtdy;
|
||||
OIIO::simd::float4 dresultdx_simd = dresultds_simd * dsdx
|
||||
+ dresultdt_simd * dtdx;
|
||||
OIIO::simd::float4 dresultdy_simd = dresultds_simd * dsdy
|
||||
+ dresultdt_simd * dtdy;
|
||||
if (dresultdx) {
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)dresultdx)[i] = dresultdx_simd[i];
|
||||
@@ -255,9 +256,8 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
}
|
||||
}
|
||||
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ OSL_SHADEOP int
|
||||
osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
void* dPdx_, void* dPdy_, void* dPdz_, int chans, void* result,
|
||||
void* dresultdx, void* dresultdy, void* alpha, void* dalphadx,
|
||||
void* dalphady, ustringrep* errormessage)
|
||||
void* dalphady, ustring* errormessage)
|
||||
{
|
||||
const Vec3& P(*(Vec3*)P_);
|
||||
const Vec3& dPdx(*(Vec3*)dPdx_);
|
||||
@@ -281,16 +281,14 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
bool derivs = (dresultdx != NULL || dalphadx != NULL);
|
||||
// It's actually faster to ask for 4 channels (even if we need fewer)
|
||||
// and ensure that they're being put in aligned memory.
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
dresultdr_simd;
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->texture3d(
|
||||
USTR(name).uhash(), (TextureSystem::TextureHandle*)handle,
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(), *opt, sg, P, dPdx, dPdy, dPdz, 4,
|
||||
(float*)&result_simd, derivs ? (float*)&dresultds_simd : nullptr,
|
||||
derivs ? (float*)&dresultdt_simd : nullptr,
|
||||
derivs ? (float*)&dresultdr_simd : nullptr,
|
||||
errormessage ? &em : nullptr);
|
||||
derivs ? (float*)&dresultdr_simd : nullptr, errormessage);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = result_simd[i];
|
||||
@@ -299,12 +297,12 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
|
||||
// Correct our str texture space gradients into xyz-space gradients
|
||||
if (derivs) {
|
||||
OIIO::simd::vfloat4 dresultdx_simd = dresultds_simd * dPdx.x
|
||||
+ dresultdt_simd * dPdx.y
|
||||
+ dresultdr_simd * dPdx.z;
|
||||
OIIO::simd::vfloat4 dresultdy_simd = dresultds_simd * dPdy.x
|
||||
+ dresultdt_simd * dPdy.y
|
||||
+ dresultdr_simd * dPdy.z;
|
||||
OIIO::simd::float4 dresultdx_simd = dresultds_simd * dPdx.x
|
||||
+ dresultdt_simd * dPdx.y
|
||||
+ dresultdr_simd * dPdx.z;
|
||||
OIIO::simd::float4 dresultdy_simd = dresultds_simd * dPdy.x
|
||||
+ dresultdt_simd * dPdy.y
|
||||
+ dresultdr_simd * dPdy.z;
|
||||
if (dresultdx) {
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)dresultdx)[i] = dresultdx_simd[i];
|
||||
@@ -317,9 +315,8 @@ osl_texture3d(void* sg_, const char* name, void* handle, void* opt_, void* P_,
|
||||
}
|
||||
}
|
||||
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -329,7 +326,7 @@ OSL_SHADEOP int
|
||||
osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
void* dRdx_, void* dRdy_, int chans, void* result,
|
||||
void* dresultdx, void* dresultdy, void* alpha, void* dalphadx,
|
||||
void* dalphady, ustringrep* errormessage)
|
||||
void* dalphady, ustring* errormessage)
|
||||
{
|
||||
const Vec3& R(*(Vec3*)R_);
|
||||
const Vec3& dRdx(*(Vec3*)dRdx_);
|
||||
@@ -338,14 +335,13 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
TextureOpt* opt = (TextureOpt*)opt_;
|
||||
// It's actually faster to ask for 4 channels (even if we need fewer)
|
||||
// and ensure that they're being put in aligned memory.
|
||||
OIIO::simd::vfloat4 local_result;
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->environment(USTR(name).uhash(),
|
||||
OIIO::simd::float4 local_result;
|
||||
bool ok = sg->renderer->environment(USTR(name),
|
||||
(TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(),
|
||||
*opt, sg, R, dRdx, dRdy, 4,
|
||||
(float*)&local_result, NULL, NULL,
|
||||
errormessage ? &em : nullptr);
|
||||
errormessage);
|
||||
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)result)[i] = local_result[i];
|
||||
@@ -372,9 +368,8 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
((float*)dalphady)[0] = 0.0f;
|
||||
}
|
||||
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
if (ok && errormessage)
|
||||
*errormessage = Strings::_emptystring_;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -383,7 +378,7 @@ osl_environment(void* sg_, const char* name, void* handle, void* opt_, void* R_,
|
||||
OSL_SHADEOP int
|
||||
osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
|
||||
int type, int arraylen, int aggregate, void* data,
|
||||
ustringrep* errormessage)
|
||||
ustring* errormessage)
|
||||
{
|
||||
// recreate TypeDesc
|
||||
TypeDesc typedesc;
|
||||
@@ -393,15 +388,10 @@ osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
|
||||
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->get_texture_info(
|
||||
USTR(name).uhash(), (RendererServices::TextureHandle*)handle,
|
||||
return sg->renderer->get_texture_info(
|
||||
USTR(name), (RendererServices::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
|
||||
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
USTR(dataname), typedesc, data, errormessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +399,7 @@ osl_get_textureinfo(void* sg_, const char* name, void* handle, void* dataname,
|
||||
OSL_SHADEOP int
|
||||
osl_get_textureinfo_st(void* sg_, const char* name, void* handle, float s,
|
||||
float t, void* dataname, int type, int arraylen,
|
||||
int aggregate, void* data, ustringrep* errormessage)
|
||||
int aggregate, void* data, ustring* errormessage)
|
||||
{
|
||||
// recreate TypeDesc
|
||||
TypeDesc typedesc;
|
||||
@@ -419,15 +409,10 @@ osl_get_textureinfo_st(void* sg_, const char* name, void* handle, float s,
|
||||
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
|
||||
ustringhash em;
|
||||
bool ok = sg->renderer->get_texture_info(
|
||||
USTR(name).uhash(), (RendererServices::TextureHandle*)handle, s, t,
|
||||
return sg->renderer->get_texture_info(
|
||||
USTR(name), (RendererServices::TextureHandle*)handle, s, t,
|
||||
sg->context->texture_thread_info(), sg->context, 0 /*FIXME-ptex*/,
|
||||
USTR(dataname).uhash(), typedesc, data, errormessage ? &em : nullptr);
|
||||
if (errormessage)
|
||||
*errormessage = ok ? ustringrep_from(Strings::_emptystring_)
|
||||
: ustringrep_from(em);
|
||||
return ok;
|
||||
USTR(dataname), typedesc, data, errormessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+56
-168
@@ -19,6 +19,7 @@
|
||||
// Pull in the modified Imath headers and the OSL_HOSTDEVICE macro
|
||||
#ifdef __CUDACC__
|
||||
# include <OSL/oslconfig.h>
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CUDACC__
|
||||
@@ -33,7 +34,6 @@
|
||||
|
||||
#include "osl_pvt.h"
|
||||
|
||||
#include <OSL/device_ptr.h>
|
||||
#include <OSL/dual.h>
|
||||
#include <OSL/dual_vec.h>
|
||||
#include <OSL/genclosure.h>
|
||||
@@ -100,16 +100,14 @@ print_closure(std::ostream& out, const ClosureColor* closure,
|
||||
/// group.
|
||||
typedef void (*RunLLVMGroupFunc)(void* shaderglobals, void* heap_arena_ptr,
|
||||
void* userdata_base_pointer,
|
||||
void* output_base_pointer, int shadeindex,
|
||||
void* interactive_params_ptr);
|
||||
void* output_base_pointer, int shadeindex);
|
||||
#if OSL_USE_BATCHED
|
||||
typedef void (*RunLLVMGroupFuncWide)(void* batchedshaderglobals,
|
||||
void* heap_arena_ptr,
|
||||
const void* wide_shade_index,
|
||||
void* userdata_base_pointer,
|
||||
void* output_base_pointer,
|
||||
int run_mask_value,
|
||||
void* interactive_params_ptr);
|
||||
int run_mask_value);
|
||||
#endif
|
||||
|
||||
/// Signature of a constant-folding method
|
||||
@@ -194,10 +192,8 @@ struct UserDataNeeded {
|
||||
{
|
||||
if (a.name != b.name)
|
||||
return a.name < b.name;
|
||||
// Checking for layer_num means that if derivs differ find_userdata_index
|
||||
// may find the wrong layer symbol with the wrong derivs setting.
|
||||
//if (a.layer_num != b.layer_num)
|
||||
// return a.layer_num < b.layer_num;
|
||||
if (a.layer_num != b.layer_num)
|
||||
return a.layer_num < b.layer_num;
|
||||
if (a.type.basetype != b.type.basetype)
|
||||
return a.type.basetype < b.type.basetype;
|
||||
if (a.type.aggregate != b.type.aggregate)
|
||||
@@ -216,11 +212,9 @@ struct UserDataNeeded {
|
||||
struct AttributeNeeded {
|
||||
ustring name;
|
||||
ustring scope;
|
||||
TypeDesc type;
|
||||
|
||||
AttributeNeeded(ustring name, ustring scope = ustring(),
|
||||
TypeDesc type = TypeUnknown)
|
||||
: name(name), scope(scope), type(type)
|
||||
AttributeNeeded(ustring name, ustring scope = ustring())
|
||||
: name(name), scope(scope)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,15 +224,6 @@ struct AttributeNeeded {
|
||||
return a.name < b.name;
|
||||
if (a.scope != b.scope)
|
||||
return a.scope < b.scope;
|
||||
if (a.type.basetype != b.type.basetype)
|
||||
return a.type.basetype < b.type.basetype;
|
||||
if (a.type.aggregate != b.type.aggregate)
|
||||
return a.type.aggregate < b.type.aggregate;
|
||||
if (a.type.arraylen != b.type.arraylen)
|
||||
return a.type.arraylen < b.type.arraylen;
|
||||
// Ignore vector semantics
|
||||
// if (a.type.vecsemantics != b.type.vecsemantics)
|
||||
// return a.type.vecsemantics < b.type.vecsemantics;
|
||||
return false; // they are equal
|
||||
}
|
||||
};
|
||||
@@ -249,33 +234,18 @@ struct AttributeNeeded {
|
||||
|
||||
|
||||
// Handy re-casting macros
|
||||
inline ustringrep
|
||||
USTR(ustring_pod s) noexcept
|
||||
{
|
||||
return OSL::bitcast<ustringrep>(s);
|
||||
}
|
||||
inline ustringrep
|
||||
USTREP(ustring_pod s) noexcept
|
||||
{
|
||||
return OSL::bitcast<ustringrep>(s);
|
||||
// return *((ustringrep*)&s);
|
||||
}
|
||||
|
||||
// Get rid of this one soon!
|
||||
inline ustringrep
|
||||
USTR(const void* s) noexcept
|
||||
{
|
||||
return OSL::bitcast<ustringrep>(s);
|
||||
}
|
||||
|
||||
#define MAT(m) (*(Matrix44*)m)
|
||||
#define VEC(v) (*(Vec3*)v)
|
||||
#define DFLOAT(x) (*(Dual2<Float>*)x)
|
||||
#define DVEC(x) (*(Dual2<Vec3>*)x)
|
||||
#define COL(x) (*(Color3*)x)
|
||||
#define DCOL(x) (*(Dual2<Color3>*)x)
|
||||
#define TYPEDESC(x) OSL::bitcast<TypeDesc, long long>(x)
|
||||
|
||||
#define USTR(cstr) (*((ustring*)&cstr))
|
||||
#define MAT(m) (*(Matrix44*)m)
|
||||
#define VEC(v) (*(Vec3*)v)
|
||||
#define DFLOAT(x) (*(Dual2<Float>*)x)
|
||||
#define DVEC(x) (*(Dual2<Vec3>*)x)
|
||||
#define COL(x) (*(Color3*)x)
|
||||
#define DCOL(x) (*(Dual2<Color3>*)x)
|
||||
#if OPENIMAGEIO_VERSION >= 20500
|
||||
# define TYPEDESC(x) OIIO::bitcast<TypeDesc, long long>(x)
|
||||
#else
|
||||
# define TYPEDESC(x) OIIO::bit_cast<long long, TypeDesc>(x)
|
||||
#endif
|
||||
|
||||
|
||||
/// Like an int (of type T), but also internally keeps track of the
|
||||
@@ -555,9 +525,9 @@ public:
|
||||
void* val);
|
||||
bool LoadMemoryCompiledShader(string_view shadername, string_view buffer);
|
||||
bool Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
const void* val, ParamHints props);
|
||||
const void* val, bool lockgeom);
|
||||
bool Parameter(string_view name, TypeDesc t, const void* val,
|
||||
ParamHints props);
|
||||
bool lockgeom);
|
||||
bool Shader(ShaderGroup& group, string_view shaderusage,
|
||||
string_view shadername, string_view layername);
|
||||
bool Shader(string_view shaderusage, string_view shadername,
|
||||
@@ -642,7 +612,6 @@ public:
|
||||
///
|
||||
TextureSystem* texturesys() const { return m_texturesys; }
|
||||
|
||||
bool use_optix() const { return m_use_optix; }
|
||||
bool debug_nan() const { return m_debugnan; }
|
||||
bool debug_uninit() const { return m_debug_uninit; }
|
||||
bool lockgeom_default() const { return m_lockgeom_default; }
|
||||
@@ -727,7 +696,7 @@ public:
|
||||
/// Set the current color space.
|
||||
bool set_colorspace(ustring colorspace);
|
||||
|
||||
OSLEXECPUBLIC int raytype_bit(ustring name);
|
||||
int raytype_bit(ustring name);
|
||||
|
||||
void optimize_all_groups(int nthreads = 0, int mythread = 0,
|
||||
int totalthreads = 1, bool do_jit = true);
|
||||
@@ -893,7 +862,6 @@ private:
|
||||
bool m_opt_middleman; ///< Middle-man optimization?
|
||||
bool m_opt_texture_handle; ///< Use texture handles?
|
||||
bool m_opt_seed_bblock_aliases; ///< Turn on basic block alias seeds
|
||||
bool m_opt_useparam; ///< Perform extra useparam analysis for culling run layer calls
|
||||
bool m_opt_batched_analysis; ///< Perform extra analysis required for batched execution?
|
||||
bool m_llvm_jit_fma; ///< Allow fused multiply/add in JIT
|
||||
bool m_llvm_jit_aggressive; ///< Turn on llvm "aggressive" JIT
|
||||
@@ -927,8 +895,7 @@ private:
|
||||
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
|
||||
std::vector<SymLocationDesc> m_symlocs;
|
||||
int m_max_local_mem_KB; ///< Local storage can a shader use
|
||||
int m_compile_report; ///< Print compilation report?
|
||||
bool m_use_optix; ///< This is an OptiX-based renderer
|
||||
bool m_compile_report; ///< Print compilation report?
|
||||
bool m_buffer_printf; ///< Buffer/batch printf output?
|
||||
bool m_no_noise; ///< Substitute trivial noise calls
|
||||
bool m_no_pointcloud; ///< Substitute trivial pointcloud calls
|
||||
@@ -974,8 +941,6 @@ private:
|
||||
atomic_int m_stat_global_connections; ///< Stat: global connections elim'd
|
||||
atomic_int m_stat_tex_calls_codegened; ///< Stat: total texture calls
|
||||
atomic_int m_stat_tex_calls_as_handles; ///< Stat: texture calls with handles
|
||||
atomic_int m_stat_useparam_ops; ///< Stat: pre-optimization useparam ops
|
||||
atomic_int m_stat_call_layers_inserted; ///< Stat: post-opt layer calls
|
||||
double m_stat_master_load_time; ///< Stat: time loading masters
|
||||
double m_stat_optimization_time; ///< Stat: time spent optimizing
|
||||
double m_stat_opt_locking_time; ///< locking time
|
||||
@@ -1150,7 +1115,8 @@ public:
|
||||
ShadingSystemImpl& shadingsys() const { return m_master->shadingsys(); }
|
||||
|
||||
/// Apply pending parameters
|
||||
void parameters(const ParamValueList& params, cspan<ParamHints> hints);
|
||||
///
|
||||
void parameters(const ParamValueList& params);
|
||||
|
||||
/// Find the named symbol, return its index in the symbol array, or
|
||||
/// -1 if not found.
|
||||
@@ -1410,16 +1376,14 @@ public:
|
||||
// Using bit fields to keep the data in 8 bytes in total.
|
||||
unsigned char m_valuesource : 3;
|
||||
bool m_connected_down : 1;
|
||||
bool m_interpolated : 1;
|
||||
bool m_interactive : 1;
|
||||
int m_arraylen : 26;
|
||||
bool m_lockgeom : 1;
|
||||
int m_arraylen : 27;
|
||||
int m_data_offset;
|
||||
|
||||
SymOverrideInfo()
|
||||
: m_valuesource(Symbol::DefaultVal)
|
||||
, m_connected_down(false)
|
||||
, m_interpolated(false)
|
||||
, m_interactive(false)
|
||||
, m_lockgeom(true)
|
||||
, m_arraylen(0)
|
||||
, m_data_offset(0)
|
||||
{
|
||||
@@ -1436,10 +1400,8 @@ public:
|
||||
bool connected_down() const { return m_connected_down; }
|
||||
void connected_down(bool c) { m_connected_down = c; }
|
||||
bool connected() const { return valuesource() == Symbol::ConnectedVal; }
|
||||
bool interpolated() const { return m_interpolated; }
|
||||
void interpolated(bool val) { m_interpolated = val; }
|
||||
bool interactive() const { return m_interactive; }
|
||||
void interactive(bool val) { m_interactive = val; }
|
||||
bool lockgeom() const { return m_lockgeom; }
|
||||
void lockgeom(bool l) { m_lockgeom = l; }
|
||||
int arraylen() const { return m_arraylen; }
|
||||
void arraylen(int s) { m_arraylen = s; }
|
||||
int dataoffset() const { return m_data_offset; }
|
||||
@@ -1448,13 +1410,11 @@ public:
|
||||
const SymOverrideInfo& b)
|
||||
{
|
||||
return a.valuesource() == b.valuesource()
|
||||
&& a.interpolated() == b.interpolated()
|
||||
&& a.interactive() == b.interactive()
|
||||
&& a.lockgeom() == b.lockgeom()
|
||||
&& a.arraylen() == b.arraylen();
|
||||
}
|
||||
};
|
||||
typedef std::vector<SymOverrideInfo> SymOverrideInfoVec;
|
||||
static_assert(sizeof(SymOverrideInfo) == 8, "SymOverrideInfo size");
|
||||
|
||||
SymOverrideInfo* instoverride(int i)
|
||||
{
|
||||
@@ -1573,8 +1533,8 @@ private:
|
||||
/// Represents a single message for use by getmessage and setmessage opcodes
|
||||
///
|
||||
struct Message {
|
||||
Message(ustringhash name, const TypeDesc& type, int layeridx,
|
||||
ustringhash sourcefile, int sourceline, Message* next)
|
||||
Message(ustring name, const TypeDesc& type, int layeridx,
|
||||
ustring sourcefile, int sourceline, Message* next)
|
||||
: name(name)
|
||||
, data(nullptr)
|
||||
, type(type)
|
||||
@@ -1585,42 +1545,43 @@ struct Message {
|
||||
{
|
||||
}
|
||||
|
||||
/// Some messages don't have data because getmessage() was called before
|
||||
/// setmessage (which is flagged as an error to avoid ambiguities caused
|
||||
/// by execution order)
|
||||
/// Some messages don't have data because getmessage() was called before setmessage
|
||||
/// (which is flagged as an error to avoid ambiguities caused by execution order)
|
||||
///
|
||||
bool has_data() const { return data != nullptr; }
|
||||
|
||||
ustringhash name; ///< name of this message
|
||||
ustring name; ///< name of this message
|
||||
char* data; ///< actual data of the message (will never change once the message is created)
|
||||
TypeDesc type; ///< what kind of data is stored here?
|
||||
int layeridx; ///< layer index where this was message was created
|
||||
ustringhash sourcefile; ///< location of the call that created this message
|
||||
int sourceline; ///< location of the call that created this message
|
||||
TypeDesc
|
||||
type; ///< what kind of data is stored here? FIXME: should be TypeSpec
|
||||
int layeridx; ///< layer index where this was message was created
|
||||
ustring
|
||||
sourcefile; ///< source code file that contains the call that created this message
|
||||
int sourceline; ///< source code line that contains the call that created this message
|
||||
Message* next; ///< linked list of messages (managed by MessageList below)
|
||||
};
|
||||
|
||||
|
||||
/// Represents the list of messages set by a given shader using setmessage and
|
||||
/// getmessage.
|
||||
/// Represents the list of messages set by a given shader using setmessage and getmessage
|
||||
///
|
||||
struct MessageList {
|
||||
MessageList() : list_head(nullptr), message_data() {}
|
||||
|
||||
void clear()
|
||||
{
|
||||
list_head = nullptr;
|
||||
list_head = NULL;
|
||||
message_data.clear();
|
||||
}
|
||||
|
||||
const Message* find(ustringhash name) const
|
||||
const Message* find(ustring name) const
|
||||
{
|
||||
for (const Message* m = list_head; m; m = m->next)
|
||||
for (const Message* m = list_head; m != NULL; m = m->next)
|
||||
if (m->name == name)
|
||||
return m; // name matches
|
||||
return nullptr; // not found
|
||||
}
|
||||
|
||||
void add(ustringhash name, void* data, const TypeDesc& type, int layeridx,
|
||||
ustringhash sourcefile, int sourceline)
|
||||
void add(ustring name, void* data, const TypeDesc& type, int layeridx,
|
||||
ustring sourcefile, int sourceline)
|
||||
{
|
||||
list_head = new (message_data.alloc(sizeof(Message), alignof(Message)))
|
||||
Message(name, type, layeridx, sourcefile, sourceline, list_head);
|
||||
@@ -1664,7 +1625,8 @@ struct BatchedMessageBuffer {
|
||||
/// ShaderInstance), and the connections among them.
|
||||
class ShaderGroup {
|
||||
public:
|
||||
ShaderGroup(string_view name, ShadingSystemImpl& shadingsys);
|
||||
ShaderGroup(string_view name);
|
||||
ShaderGroup(const ShaderGroup& g, string_view name);
|
||||
~ShaderGroup();
|
||||
|
||||
/// Clear the layers
|
||||
@@ -1694,9 +1656,6 @@ public:
|
||||
/// Array indexing returns the i-th layer of the group
|
||||
ShaderInstance* operator[](int i) const { return layer(i); }
|
||||
|
||||
/// Return a reference to the shading system for this group.
|
||||
ShadingSystemImpl& shadingsys() const { return m_shadingsys; }
|
||||
|
||||
int optimized() const { return m_optimized; }
|
||||
void optimized(int opt) { m_optimized = opt; }
|
||||
|
||||
@@ -1923,54 +1882,6 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Given a data block for interactive params, allocate space for it to
|
||||
// live with the group and copy the initial data.
|
||||
void setup_interactive_arena(cspan<uint8_t> paramblock);
|
||||
|
||||
uint8_t* interactive_arena_ptr()
|
||||
{
|
||||
return m_interactive_arena.get();
|
||||
}
|
||||
|
||||
device_ptr<uint8_t>& device_interactive_arena()
|
||||
{
|
||||
return m_device_interactive_arena;
|
||||
}
|
||||
|
||||
struct InteractiveParamData {
|
||||
int layer;
|
||||
ustring name;
|
||||
int offset;
|
||||
|
||||
InteractiveParamData(int layer, ustring name, int offset)
|
||||
: layer(layer), name(name), offset(offset)
|
||||
{
|
||||
}
|
||||
bool operator==(const InteractiveParamData& other) const
|
||||
{
|
||||
return layer == other.layer && name == other.name;
|
||||
}
|
||||
bool operator<(const InteractiveParamData& other) const
|
||||
{
|
||||
return layer < other.layer
|
||||
|| (layer == other.layer && name < other.name);
|
||||
}
|
||||
};
|
||||
|
||||
void add_interactive_param(int layer, ustring name, size_t offset)
|
||||
{
|
||||
m_interactive_params.emplace_back(layer, name,
|
||||
static_cast<int>(offset));
|
||||
}
|
||||
|
||||
int interactive_param_offset(int layer, ustring name)
|
||||
{
|
||||
for (auto& f : m_interactive_params)
|
||||
if (f.layer == layer && f.name == name)
|
||||
return f.offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
// Put all the things that are read-only (after optimization) and
|
||||
// needed on every shade execution at the front of the struct, as much
|
||||
@@ -2014,7 +1925,6 @@ private:
|
||||
std::vector<void*> m_userdata_init_vals;
|
||||
std::vector<ustring> m_attributes_needed;
|
||||
std::vector<ustring> m_attribute_scopes;
|
||||
std::vector<TypeDesc> m_attribute_types;
|
||||
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
|
||||
std::vector<SymLocationDesc> m_symlocs; ///< SORTED!!
|
||||
bool m_unknown_textures_needed;
|
||||
@@ -2026,18 +1936,9 @@ private:
|
||||
// PTX assembly for compiled ShaderGroup
|
||||
std::string m_llvm_ptx_compiled_version;
|
||||
|
||||
ParamValueList m_pending_params; // Pending Parameter() values
|
||||
std::vector<ParamHints> m_pending_hints; // ParamHints of pending params
|
||||
ustring m_group_use; // "Usage" of group
|
||||
bool m_complete = false; // Successfully ShaderGroupEnd?
|
||||
|
||||
ShadingSystemImpl& m_shadingsys; // Back-ptr to the shading system
|
||||
|
||||
// Per-group home for interactively editable parameters
|
||||
std::vector<InteractiveParamData> m_interactive_params;
|
||||
std::unique_ptr<uint8_t[]> m_interactive_arena;
|
||||
size_t m_interactive_arena_size = 0;
|
||||
device_ptr<uint8_t> m_device_interactive_arena;
|
||||
ParamValueList m_pending_params; ///< Pending Parameter() values
|
||||
ustring m_group_use; ///< "Usage" of group
|
||||
bool m_complete = false; ///< Successfully ShaderGroupEnd?
|
||||
|
||||
friend class OSL::pvt::ShadingSystemImpl;
|
||||
friend class OSL::pvt::BackendLLVM;
|
||||
@@ -2309,7 +2210,7 @@ public:
|
||||
int dict_value(int nodeID, ustring attribname, TypeDesc type, void* data);
|
||||
|
||||
bool osl_get_attribute(ShaderGlobals* sg, void* objdata, int dest_derivs,
|
||||
ustringhash obj_name, ustringhash attr_name,
|
||||
ustring obj_name, ustring attr_name,
|
||||
int array_lookup, int index, TypeDesc attr_type,
|
||||
void* attr_dest);
|
||||
|
||||
@@ -2692,19 +2593,6 @@ protected:
|
||||
std::vector<char> m_in_conditional; ///< Whether each op is in a cond
|
||||
std::vector<char> m_in_loop; ///< Whether each op is in a loop
|
||||
int m_first_return; ///< Op number of first return or exit
|
||||
|
||||
struct CallLayerKey {
|
||||
int bblockid;
|
||||
int layerid;
|
||||
|
||||
bool operator<(const CallLayerKey& other) const
|
||||
{
|
||||
return bblockid < other.bblockid
|
||||
|| (bblockid == other.bblockid && layerid < other.layerid);
|
||||
}
|
||||
};
|
||||
std::set<CallLayerKey>
|
||||
m_call_layers_inserted; ///< Lookup used during llvm gen
|
||||
};
|
||||
|
||||
}; // namespace pvt
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#pragma clang diagnostic ignored "-Wparentheses-equality"
|
||||
#endif
|
||||
|
||||
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
|
||||
#if OSL_CLANG_VERSION >= 150000
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
|
||||
+21
-2
@@ -288,8 +288,7 @@ public:
|
||||
}
|
||||
|
||||
// TODO: This is really the only part of parsing that needs the lock still.
|
||||
// The calling code no longer sets the global locale, so it would
|
||||
// likely be simple to clean this up.
|
||||
// But the calling code setting locale complicates this.
|
||||
//
|
||||
bool parse(OSOReader* reader, const char* what) {
|
||||
yy_switch_to_buffer(m_buffer, m_scanner);
|
||||
@@ -311,6 +310,12 @@ OSOReader::parse_file (const std::string &filename)
|
||||
// can actually be reading a .oso file at a time.
|
||||
std::lock_guard<std::mutex> guard (osoread_mutex);
|
||||
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
std::locale oldlocale; // save the previous native locale
|
||||
std::locale::global (std::locale::classic());
|
||||
|
||||
FILE* osoin = OIIO::Filesystem::fopen (filename, "r");
|
||||
if (! osoin) {
|
||||
m_err.errorfmt("File {} not found", filename);
|
||||
@@ -321,6 +326,7 @@ OSOReader::parse_file (const std::string &filename)
|
||||
bool ok = scope.parse(this, filename.c_str());
|
||||
|
||||
fclose (osoin);
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -333,9 +339,22 @@ OSOReader::parse_memory (const std::string &buffer)
|
||||
// can actually be reading a .oso file at a time.
|
||||
std::lock_guard<std::mutex> guard (osoread_mutex);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
// This is not necessary for versions of OIIO that have Strutil::stof,
|
||||
// and we can remove it entirely when OIIO 1.9 is the minimum.
|
||||
std::locale oldlocale = std::locale::global (std::locale::classic());
|
||||
#endif
|
||||
|
||||
Scope scope(buffer);
|
||||
bool ok = scope.parse(this, "preloaded OSO code");
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,26 +12,25 @@ OSL_NAMESPACE_ENTER
|
||||
namespace pvt {
|
||||
|
||||
#ifdef USE_PARTIO
|
||||
using PointCloudMap
|
||||
= std::unordered_map<ustringhash, std::unique_ptr<PointCloud>>;
|
||||
typedef std::unordered_map<ustring, std::unique_ptr<PointCloud>> PointCloudMap;
|
||||
static PointCloudMap pointclouds;
|
||||
static OIIO::spin_mutex pointcloudmap_mutex;
|
||||
|
||||
PointCloud*
|
||||
PointCloud::get(ustringhash filename, bool write)
|
||||
PointCloud::get(ustring filename, bool write)
|
||||
{
|
||||
if (filename.empty())
|
||||
return nullptr;
|
||||
return NULL;
|
||||
spin_lock lock(pointcloudmap_mutex);
|
||||
PointCloudMap::const_iterator found = pointclouds.find(filename);
|
||||
if (found != pointclouds.end())
|
||||
return found->second.get();
|
||||
// Not found. Create a new one.
|
||||
Partio::ParticlesDataMutable* partio_cloud = nullptr;
|
||||
Partio::ParticlesDataMutable* partio_cloud = NULL;
|
||||
if (!write) {
|
||||
partio_cloud = Partio::read(filename.c_str(), false);
|
||||
if (!partio_cloud)
|
||||
return nullptr;
|
||||
return NULL;
|
||||
} else {
|
||||
partio_cloud = Partio::create();
|
||||
}
|
||||
@@ -41,7 +40,7 @@ PointCloud::get(ustringhash filename, bool write)
|
||||
}
|
||||
|
||||
|
||||
PointCloud::PointCloud(ustringhash filename,
|
||||
PointCloud::PointCloud(ustring filename,
|
||||
Partio::ParticlesDataMutable* partio_cloud, bool write)
|
||||
: m_filename(filename), m_partio_cloud(partio_cloud), m_write(write)
|
||||
{
|
||||
@@ -77,10 +76,8 @@ PointCloud::~PointCloud()
|
||||
|
||||
} // namespace pvt
|
||||
|
||||
|
||||
|
||||
int
|
||||
RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
|
||||
RendererServices::pointcloud_search(ShaderGlobals* sg, ustring filename,
|
||||
const Vec3& center, float radius,
|
||||
int max_points, bool sort,
|
||||
size_t* out_indices, float* out_distances,
|
||||
@@ -89,17 +86,17 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
|
||||
#ifdef USE_PARTIO
|
||||
if (filename.empty())
|
||||
return 0;
|
||||
PointCloud* pc = PointCloud::get(ustring_from(filename));
|
||||
PointCloud* pc = PointCloud::get(filename);
|
||||
if (pc == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_search: could not open \"{}\"",
|
||||
ustring_from(filename));
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Partio::ParticlesData* cloud = pc->read_access();
|
||||
if (cloud == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_search: could not open \"{}\"",
|
||||
ustring_from(filename));
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -195,26 +192,25 @@ RendererServices::pointcloud_search(ShaderGlobals* sg, ustringhash filename,
|
||||
|
||||
|
||||
int
|
||||
RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
size_t* indices, int count,
|
||||
ustringhash attr_name, TypeDesc attr_type,
|
||||
void* out_data)
|
||||
RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
size_t* indices, int count, ustring attr_name,
|
||||
TypeDesc attr_type, void* out_data)
|
||||
{
|
||||
#ifdef USE_PARTIO
|
||||
if (!count)
|
||||
return 1; // always succeed if not asking for any data
|
||||
|
||||
PointCloud* pc = PointCloud::get(ustring_from(filename));
|
||||
PointCloud* pc = PointCloud::get(filename);
|
||||
if (pc == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_get: could not open \"{}\"",
|
||||
ustring_from(filename));
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Partio::ParticlesData* cloud = pc->read_access();
|
||||
if (cloud == NULL) { // The file failed to load
|
||||
sg->context->errorfmt("pointcloud_get: could not open \"{}\"",
|
||||
ustring_from(filename));
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,7 +219,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
if (!attr) {
|
||||
sg->context->errorfmt(
|
||||
"Accessing unexisting attribute {} in pointcloud \"{}\"", attr_name,
|
||||
ustring_from(filename));
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -236,7 +232,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
if (!compatiblePartioType(partio_type, element_type)) {
|
||||
sg->context->errorfmt(
|
||||
"Type of attribute \"{}\" : {} not compatible with OSL's {} in \"{}\" pointcloud",
|
||||
attr_name, partio_type, element_type, ustring_from(filename));
|
||||
attr_name, partio_type, element_type, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -267,9 +263,9 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int ind = strindices[i];
|
||||
if (ind >= 0 && ind < sicount)
|
||||
((ustringrep*)out_data)[i] = ustringrep(strings[ind]);
|
||||
((ustring*)out_data)[i] = ustring(strings[ind]);
|
||||
else
|
||||
((ustringrep*)out_data)[i] = ustringrep();
|
||||
((ustring*)out_data)[i] = ustring();
|
||||
}
|
||||
} else {
|
||||
// All cases aside from strings are simple.
|
||||
@@ -290,16 +286,15 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustringhash filename,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
|
||||
RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustring filename,
|
||||
const Vec3& pos, int nattribs,
|
||||
const ustringrep* names,
|
||||
const TypeDesc* types, const void** data)
|
||||
const ustring* names, const TypeDesc* types,
|
||||
const void** data)
|
||||
{
|
||||
#ifdef USE_PARTIO
|
||||
if (filename.empty())
|
||||
return false;
|
||||
PointCloud* pc = PointCloud::get(ustring_from(filename),
|
||||
true /* create file to write */);
|
||||
PointCloud* pc = PointCloud::get(filename, true /* create file to write */);
|
||||
spin_lock lock(pc->m_mutex);
|
||||
Partio::ParticlesDataMutable* cloud = pc->write_access();
|
||||
if (cloud == NULL) // The file failed to load
|
||||
@@ -351,11 +346,10 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
|
||||
*(int*)cloud->dataWrite<int>(*a, p) = *(int*)(data[i]);
|
||||
break;
|
||||
case Partio::INDEXEDSTR: {
|
||||
ustringrep s = *(ustringrep*)(data[i]);
|
||||
const char* sstr = s.c_str();
|
||||
int index = cloud->lookupIndexedStr(*a, sstr);
|
||||
const char* s = *(const char**)(data[i]);
|
||||
int index = cloud->lookupIndexedStr(*a, s);
|
||||
if (index == -1)
|
||||
index = cloud->registerIndexedStr(*a, sstr);
|
||||
index = cloud->registerIndexedStr(*a, s);
|
||||
*(int*)cloud->dataWrite<int>(*a, p) = index;
|
||||
} break;
|
||||
case Partio::NONE: break;
|
||||
@@ -372,7 +366,7 @@ RendererServices::pointcloud_write(ShaderGlobals* /*sg*/, ustringhash filename,
|
||||
namespace pvt {
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
|
||||
osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
|
||||
float radius, int max_points, int sort, void* out_indices,
|
||||
void* out_distances, int derivs_offset, int nattrs, ...)
|
||||
{
|
||||
@@ -399,11 +393,11 @@ osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
|
||||
va_list args;
|
||||
va_start(args, nattrs);
|
||||
for (int i = 0; i < nattrs; i++) {
|
||||
ustring_pod attr_name_rep = (ustring_pod)va_arg(args, ustring_pod);
|
||||
ustringrep attr_name = USTR(attr_name_rep);
|
||||
long long lltype = va_arg(args, long long);
|
||||
TypeDesc attr_type = TYPEDESC(lltype);
|
||||
void* out_data = va_arg(args, void*);
|
||||
ustring attr_name = ustring::from_unique(
|
||||
(const char*)va_arg(args, const char*));
|
||||
long long lltype = va_arg(args, long long);
|
||||
TypeDesc attr_type = TYPEDESC(lltype);
|
||||
void* out_data = va_arg(args, void*);
|
||||
sg->renderer->pointcloud_get(sg, USTR(filename), indices, count,
|
||||
attr_name, attr_type, out_data);
|
||||
}
|
||||
@@ -422,8 +416,8 @@ osl_pointcloud_search(ShaderGlobals* sg, ustring_pod filename, void* center,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_get(ShaderGlobals* sg, ustring_pod filename, void* in_indices,
|
||||
int count, ustring_pod attr_name, long long attr_type,
|
||||
osl_pointcloud_get(ShaderGlobals* sg, const char* filename, void* in_indices,
|
||||
int count, const char* attr_name, long long attr_type,
|
||||
void* out_data)
|
||||
{
|
||||
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
|
||||
@@ -444,8 +438,8 @@ osl_pointcloud_get(ShaderGlobals* sg, ustring_pod filename, void* in_indices,
|
||||
|
||||
|
||||
OSL_SHADEOP void
|
||||
osl_pointcloud_write_helper(ustringrep* names, TypeDesc* types, void** values,
|
||||
int index, ustring_pod name, long long type,
|
||||
osl_pointcloud_write_helper(ustring* names, TypeDesc* types, void** values,
|
||||
int index, const char* name, long long type,
|
||||
void* val)
|
||||
{
|
||||
names[index] = USTR(name);
|
||||
@@ -456,9 +450,9 @@ osl_pointcloud_write_helper(ustringrep* names, TypeDesc* types, void** values,
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_pointcloud_write(ShaderGlobals* sg, ustring_pod filename, const Vec3* pos,
|
||||
int nattribs, const ustringrep* names,
|
||||
const TypeDesc* types, const void** values)
|
||||
osl_pointcloud_write(ShaderGlobals* sg, const char* filename, const Vec3* pos,
|
||||
int nattribs, const ustring* names, const TypeDesc* types,
|
||||
const void** values)
|
||||
{
|
||||
ShadingSystemImpl& shadingsys(sg->context->shadingsys());
|
||||
if (shadingsys.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
|
||||
@@ -15,14 +15,14 @@ namespace pvt {
|
||||
|
||||
#ifdef USE_PARTIO
|
||||
|
||||
class OSLEXECPUBLIC PointCloud {
|
||||
class PointCloud {
|
||||
public:
|
||||
PointCloud(ustringhash filename, Partio::ParticlesDataMutable* partio_cloud,
|
||||
PointCloud(ustring filename, Partio::ParticlesDataMutable* partio_cloud,
|
||||
bool write);
|
||||
~PointCloud();
|
||||
static PointCloud* get(ustringhash filename, bool write = false);
|
||||
static PointCloud* get(ustring filename, bool write = false);
|
||||
|
||||
typedef std::unordered_map<ustringhash,
|
||||
typedef std::unordered_map<ustring,
|
||||
std::unique_ptr<Partio::ParticleAttribute>>
|
||||
AttributeMap;
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
return m_partio_cloud;
|
||||
}
|
||||
|
||||
ustringhash m_filename;
|
||||
ustring m_filename;
|
||||
|
||||
private:
|
||||
// hide just this field, because we want to control how it is accessed
|
||||
|
||||
+30
-140
@@ -47,24 +47,6 @@ RendererServices::texturesys() const
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from, float time)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform, float time)
|
||||
@@ -91,9 +73,8 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
bool
|
||||
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash to, float time)
|
||||
ustring to, float time)
|
||||
{
|
||||
// return get_inverse_matrix(sg, result, ustring_from(to), time);
|
||||
bool ok = get_matrix(sg, result, to, time);
|
||||
if (ok)
|
||||
result.invert();
|
||||
@@ -104,9 +85,8 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
bool
|
||||
RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash to)
|
||||
ustring to)
|
||||
{
|
||||
// return get_inverse_matrix(sg, result, ustring_from(to));
|
||||
bool ok = get_matrix(sg, result, to);
|
||||
if (ok)
|
||||
result.invert();
|
||||
@@ -115,60 +95,11 @@ RendererServices::get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::transform_points(ShaderGlobals* sg, ustringhash from,
|
||||
ustringhash to, float time, const Vec3* Pin,
|
||||
Vec3* Pout, int npoints,
|
||||
TypeDesc::VECSEMANTICS vectype)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_userdata(bool derivatives, ustringhash name,
|
||||
TypeDesc type, ShaderGlobals* sg, void* val)
|
||||
{
|
||||
return false;
|
||||
// return get_userdata(derivatives, ustring_from(name), type, sg, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RendererServices::TextureHandle*
|
||||
RendererServices::get_texture_handle(ustringhash filename,
|
||||
ShadingContext* context,
|
||||
const TextureOpt* options)
|
||||
RendererServices::get_texture_handle(ustring filename, ShadingContext* context)
|
||||
{
|
||||
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
|
||||
return texturesys()->get_texture_handle(ustring_from(filename),
|
||||
context->texture_thread_info(),
|
||||
options);
|
||||
#else
|
||||
return texturesys()->get_texture_handle(ustring_from(filename),
|
||||
return texturesys()->get_texture_handle(filename,
|
||||
context->texture_thread_info());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -189,26 +120,20 @@ RendererServices::is_udim(TextureHandle* texture_handle)
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
|
||||
RendererServices::texture(ustring filename, TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg, float s,
|
||||
float t, float dsdx, float dtdx, float dsdy,
|
||||
float dtdy, int nchannels, float* result,
|
||||
float* dresultds, float* dresultdt,
|
||||
ustringhash* errormessage)
|
||||
ustring* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
|
||||
texture_handle
|
||||
= texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info, &options);
|
||||
#else
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
#endif
|
||||
bool status = texturesys()->texture(texture_handle, texture_thread_info,
|
||||
options, s, t, dsdx, dtdx, dsdy, dtdy,
|
||||
nchannels, result, dresultds,
|
||||
@@ -217,12 +142,12 @@ RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustringhash(err);
|
||||
*errormessage = ustring(err);
|
||||
} else {
|
||||
context->errorfmt("[RendererServices::texture] {}", err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = ustringhash(Strings::unknown);
|
||||
*errormessage = Strings::unknown;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -231,26 +156,20 @@ RendererServices::texture(ustringhash filename, TextureHandle* texture_handle,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
|
||||
RendererServices::texture3d(ustring filename, TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg,
|
||||
const Vec3& P, const Vec3& dPdx, const Vec3& dPdy,
|
||||
const Vec3& dPdz, int nchannels, float* result,
|
||||
float* dresultds, float* dresultdt,
|
||||
float* dresultdr, ustringhash* errormessage)
|
||||
float* dresultdr, ustring* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
|
||||
texture_handle
|
||||
= texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info, &options);
|
||||
#else
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
#endif
|
||||
|
||||
bool status = texturesys()->texture3d(texture_handle, texture_thread_info,
|
||||
options, P, dPdx, dPdy, dPdz,
|
||||
@@ -260,12 +179,12 @@ RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustringhash(err);
|
||||
*errormessage = ustring(err);
|
||||
} else {
|
||||
sg->context->errorfmt("[RendererServices::texture3d] {}", err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = Strings::unknown.uhash();
|
||||
*errormessage = Strings::unknown;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -274,26 +193,19 @@ RendererServices::texture3d(ustringhash filename, TextureHandle* texture_handle,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::environment(ustringhash filename,
|
||||
TextureHandle* texture_handle,
|
||||
RendererServices::environment(ustring filename, TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
TextureOpt& options, ShaderGlobals* sg,
|
||||
const Vec3& R, const Vec3& dRdx, const Vec3& dRdy,
|
||||
int nchannels, float* result, float* dresultds,
|
||||
float* dresultdt, ustringhash* errormessage)
|
||||
float* dresultdt, ustring* errormessage)
|
||||
{
|
||||
ShadingContext* context = sg->context;
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
#ifdef OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE
|
||||
texture_handle
|
||||
= texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_thread_info, &options);
|
||||
#else
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
#endif
|
||||
bool status = texturesys()->environment(texture_handle, texture_thread_info,
|
||||
options, R, dRdx, dRdy, nchannels,
|
||||
result, dresultds, dresultdt);
|
||||
@@ -301,13 +213,13 @@ RendererServices::environment(ustringhash filename,
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size() && sg) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustringhash(err);
|
||||
*errormessage = ustring(err);
|
||||
} else {
|
||||
sg->context->errorfmt("[RendererServices::environment] {}",
|
||||
err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
*errormessage = Strings::unknown.uhash();
|
||||
*errormessage = Strings::unknown;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -316,35 +228,34 @@ RendererServices::environment(ustringhash filename,
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::get_texture_info(ustringhash filename,
|
||||
RendererServices::get_texture_info(ustring filename,
|
||||
TextureHandle* texture_handle,
|
||||
TexturePerthread* texture_thread_info,
|
||||
ShadingContext* shading_context,
|
||||
int subimage, ustringhash dataname,
|
||||
int subimage, ustring dataname,
|
||||
TypeDesc datatype, void* data,
|
||||
ustringhash* errormessage)
|
||||
ustring* errormessage)
|
||||
{
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = shading_context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
bool status = texturesys()->get_texture_info(texture_handle,
|
||||
texture_thread_info, subimage,
|
||||
ustring_from(dataname),
|
||||
datatype, data);
|
||||
dataname, datatype, data);
|
||||
if (!status) {
|
||||
std::string err = texturesys()->geterror();
|
||||
if (err.size()) {
|
||||
if (errormessage) {
|
||||
*errormessage = ustringhash(err);
|
||||
*errormessage = ustring(err);
|
||||
} else {
|
||||
shading_context->errorfmt(
|
||||
"[RendererServices::get_texture_info] {}", err);
|
||||
}
|
||||
} else if (errormessage) {
|
||||
// gettextureinfo failed but did not provide an error, so none should be emitted
|
||||
*errormessage = ustringhash();
|
||||
*errormessage = ustring();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@@ -354,10 +265,10 @@ RendererServices::get_texture_info(ustringhash filename,
|
||||
|
||||
bool
|
||||
RendererServices::get_texture_info(
|
||||
ustringhash filename, TextureHandle* texture_handle, float s, float t,
|
||||
ustring filename, TextureHandle* texture_handle, float s, float t,
|
||||
TexturePerthread* texture_thread_info, ShadingContext* shading_context,
|
||||
int subimage, ustringhash dataname, TypeDesc datatype, void* data,
|
||||
ustringhash* errormessage)
|
||||
int subimage, ustring dataname, TypeDesc datatype, void* data,
|
||||
ustring* errormessage)
|
||||
{
|
||||
#if OIIO_VERSION >= 20307
|
||||
// Newer versions of the TextureSystem interface are able to determine the
|
||||
@@ -365,7 +276,7 @@ RendererServices::get_texture_info(
|
||||
if (!texture_thread_info)
|
||||
texture_thread_info = shading_context->texture_thread_info();
|
||||
if (!texture_handle)
|
||||
texture_handle = texturesys()->get_texture_handle(ustring_from(filename),
|
||||
texture_handle = texturesys()->get_texture_handle(filename,
|
||||
texture_thread_info);
|
||||
if (texturesys()->is_udim(texture_handle)) {
|
||||
TextureSystem::TextureHandle* udim_handle
|
||||
@@ -386,27 +297,6 @@ RendererServices::get_texture_info(
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::trace(TraceOpt& options, ShaderGlobals* sg,
|
||||
const OSL::Vec3& P, const OSL::Vec3& dPdx,
|
||||
const OSL::Vec3& dPdy, const OSL::Vec3& R,
|
||||
const OSL::Vec3& dRdx, const OSL::Vec3& dRdy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
RendererServices::getmessage(ShaderGlobals* sg, ustringhash source,
|
||||
ustringhash name, TypeDesc type, void* val,
|
||||
bool derivatives)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BatchedRendererServices<16>*
|
||||
RendererServices::batched(WidthOf<16>)
|
||||
{
|
||||
|
||||
@@ -889,10 +889,8 @@ RuntimeOptimizer::simplify_params()
|
||||
Symbol* s(inst()->symbol(i));
|
||||
if (s->symtype() != SymTypeParam)
|
||||
continue; // Skip non-params
|
||||
// Don't simplify params that are interpolated or interactively
|
||||
// editable
|
||||
if (s->interpolated() || s->interactive())
|
||||
continue;
|
||||
if (!s->lockgeom())
|
||||
continue; // Don't mess with params that can change with the geom
|
||||
if (s->typespec().is_structure() || s->typespec().is_closure_based())
|
||||
continue; // We don't mess with struct placeholders or closures
|
||||
|
||||
@@ -969,7 +967,7 @@ RuntimeOptimizer::simplify_params()
|
||||
// examining.
|
||||
ShaderInstance* uplayer = group()[c.srclayer];
|
||||
Symbol* srcsym = uplayer->symbol(c.src.param);
|
||||
if (srcsym->interpolated())
|
||||
if (!srcsym->lockgeom())
|
||||
continue; // Not if it can be overridden by geometry
|
||||
|
||||
// Is the source symbol known to be a global, from
|
||||
@@ -2186,7 +2184,7 @@ RuntimeOptimizer::optimize_ops(int beginop, int endop,
|
||||
if (opnum == inst()->m_maincodebegin) {
|
||||
for (int i = inst()->firstparam(); i < inst()->lastparam(); ++i) {
|
||||
Symbol* s(inst()->symbol(i));
|
||||
if (s->symtype() == SymTypeOutputParam && !s->interpolated()
|
||||
if (s->symtype() == SymTypeOutputParam && s->lockgeom()
|
||||
&& (s->valuesource() == Symbol::DefaultVal
|
||||
|| s->valuesource() == Symbol::InstanceVal)
|
||||
&& !s->has_init_ops() && !s->typespec().is_closure_based()
|
||||
@@ -2493,7 +2491,7 @@ RuntimeOptimizer::resolve_isconnected()
|
||||
s = inst()->symbol(fieldsymid);
|
||||
}
|
||||
bool upconnected = s->connected();
|
||||
if (s->interpolated() && shadingsys().userdata_isconnected())
|
||||
if (!s->lockgeom() && shadingsys().userdata_isconnected())
|
||||
upconnected = true;
|
||||
int val = (upconnected ? 1 : 0) + (s->connected_down() ? 2 : 0);
|
||||
turn_into_assign(op, add_constant(TypeDesc::TypeInt, &val),
|
||||
@@ -3253,7 +3251,6 @@ RuntimeOptimizer::run()
|
||||
m_userdata_needed.clear();
|
||||
m_attributes_needed.clear();
|
||||
bool does_nothing = true;
|
||||
std::vector<uint8_t> interactive_data;
|
||||
for (int layer = 0; layer < nlayers; ++layer) {
|
||||
set_inst(layer);
|
||||
if (inst()->unused())
|
||||
@@ -3265,7 +3262,7 @@ RuntimeOptimizer::run()
|
||||
// Find interpolated parameters
|
||||
if ((s.symtype() == SymTypeParam
|
||||
|| s.symtype() == SymTypeOutputParam)
|
||||
&& s.interpolated()) {
|
||||
&& !s.lockgeom()) {
|
||||
UserDataNeeded udn(s.name(), layer, s.typespec().simpletype(),
|
||||
s.data(), s.has_derivs());
|
||||
std::set<UserDataNeeded>::iterator found;
|
||||
@@ -3277,21 +3274,6 @@ RuntimeOptimizer::run()
|
||||
m_userdata_needed.insert(udn);
|
||||
}
|
||||
}
|
||||
// Find interactive parameters
|
||||
if (s.symtype() == SymTypeParam && s.interactive()) {
|
||||
// Make enough room in interactive_data to accommodate this
|
||||
// interactive parameter, including correct alignment.
|
||||
size_t offset = interactive_data.size();
|
||||
size_t typesize = s.typespec().simpletype().size();
|
||||
size_t alignment = typesize > 4 ? 8 : 4;
|
||||
offset = OIIO::round_to_multiple_of_pow2(offset, alignment);
|
||||
interactive_data.resize(offset + typesize);
|
||||
// Copy from the instance value to the interactive block
|
||||
memcpy(&interactive_data[offset], s.data(), typesize);
|
||||
// Make sure the symbol remembers it's stored in the interactive
|
||||
// arena with the right offset.
|
||||
group().add_interactive_param(layer, s.name(), offset);
|
||||
}
|
||||
// Track which globals the group needs
|
||||
if (s.symtype() == SymTypeGlobal) {
|
||||
m_globals_needed.insert(s.name());
|
||||
@@ -3349,44 +3331,27 @@ RuntimeOptimizer::run()
|
||||
OSL_DASSERT(sym1 && sym1->typespec().is_string());
|
||||
if (sym1->is_constant()) {
|
||||
if (op.nargs() == 3) {
|
||||
Symbol* sym2 = opargsym(op, 2);
|
||||
// getattribute( attributename, result )
|
||||
m_attributes_needed.insert(
|
||||
AttributeNeeded(sym1->get_string(), ustring(),
|
||||
sym2->typespec().simpletype()));
|
||||
} else if (op.nargs() == 4) {
|
||||
AttributeNeeded(sym1->get_string()));
|
||||
} else {
|
||||
OSL_DASSERT(op.nargs() == 4 || op.nargs() == 5);
|
||||
Symbol* sym2 = opargsym(op, 2);
|
||||
Symbol* sym3 = opargsym(op, 3);
|
||||
if (sym2->typespec().is_string()) {
|
||||
// getattribute( scopename, attributename, result )
|
||||
// getattribute( scopename, attributename, result ) or
|
||||
// getattribute( scopename, attributename, arrayindex, result )
|
||||
if (sym2->is_constant()) {
|
||||
m_attributes_needed.insert(AttributeNeeded(
|
||||
sym2->get_string(), sym1->get_string(),
|
||||
sym3->typespec().simpletype()));
|
||||
m_attributes_needed.insert(
|
||||
AttributeNeeded(sym2->get_string(),
|
||||
sym1->get_string()));
|
||||
} else {
|
||||
m_unknown_attributes_needed = true;
|
||||
}
|
||||
} else {
|
||||
// getattribute( attributename, arrayindex, result )
|
||||
m_attributes_needed.insert(
|
||||
AttributeNeeded(sym1->get_string(), ustring(),
|
||||
sym3->typespec().simpletype()));
|
||||
AttributeNeeded(sym1->get_string()));
|
||||
}
|
||||
} else if (op.nargs() == 5) {
|
||||
Symbol* sym2 = opargsym(op, 2);
|
||||
Symbol* sym4 = opargsym(op, 4);
|
||||
if (sym2->typespec().is_string()) {
|
||||
// getattribute( scopename, attributename, arrayindex, result )
|
||||
if (sym2->is_constant()) {
|
||||
m_attributes_needed.insert(AttributeNeeded(
|
||||
sym2->get_string(), sym1->get_string(),
|
||||
sym4->typespec().simpletype()));
|
||||
} else {
|
||||
m_unknown_attributes_needed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OSL_DASSERT(false);
|
||||
}
|
||||
} else { // sym1 not constant
|
||||
m_unknown_attributes_needed = true;
|
||||
@@ -3395,7 +3360,6 @@ RuntimeOptimizer::run()
|
||||
}
|
||||
}
|
||||
group().does_nothing(does_nothing);
|
||||
group().setup_interactive_arena(interactive_data);
|
||||
|
||||
m_stat_specialization_time = rop_timer();
|
||||
{
|
||||
@@ -3420,8 +3384,6 @@ RuntimeOptimizer::run()
|
||||
new_nops, old_nops,
|
||||
100.0 * double((long long)new_nops - (long long)old_nops)
|
||||
/ double(old_nops));
|
||||
}
|
||||
if (shadingsys().m_compile_report > 1) {
|
||||
if (does_nothing)
|
||||
shadingcontext()->infofmt("Group does nothing");
|
||||
if (m_textures_needed.size()) {
|
||||
@@ -3441,8 +3403,7 @@ RuntimeOptimizer::run()
|
||||
if (m_attributes_needed.size()) {
|
||||
shadingcontext()->infofmt("Group needs attributes:");
|
||||
for (auto&& f : m_attributes_needed)
|
||||
shadingcontext()->infofmt(" {} {} {}", f.name, f.scope,
|
||||
f.type);
|
||||
shadingcontext()->infofmt(" {} {}", f.name, f.scope);
|
||||
if (m_unknown_attributes_needed)
|
||||
shadingcontext()->infofmt(
|
||||
" Also may construct attribute names on the fly.");
|
||||
|
||||
+64
-132
@@ -151,18 +151,18 @@ ShadingSystem::ShaderGroupEnd(void)
|
||||
|
||||
bool
|
||||
ShadingSystem::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
const void* val, ParamHints hints)
|
||||
const void* val, bool lockgeom)
|
||||
{
|
||||
return m_impl->Parameter(group, name, t, val, hints);
|
||||
return m_impl->Parameter(group, name, t, val, lockgeom);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ShadingSystem::Parameter(string_view name, TypeDesc t, const void* val,
|
||||
ParamHints hints)
|
||||
bool lockgeom)
|
||||
{
|
||||
return m_impl->Parameter(name, t, val, hints);
|
||||
return m_impl->Parameter(name, t, val, lockgeom);
|
||||
}
|
||||
|
||||
|
||||
@@ -943,8 +943,6 @@ ShadingSystem::convert_value(void* dst, TypeDesc dsttype, const void* src,
|
||||
return false; // Unsupported conversion
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
register_JIT_Global(const char* global_var_name, void* global_var_addr)
|
||||
{
|
||||
@@ -1026,14 +1024,16 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
|
||||
, m_opt_middleman(true)
|
||||
, m_opt_texture_handle(true)
|
||||
, m_opt_seed_bblock_aliases(true)
|
||||
, m_opt_useparam(false)
|
||||
,
|
||||
#if OSL_USE_BATCHED
|
||||
, m_opt_batched_analysis((renderer->batched(WidthOf<16>()) != nullptr)
|
||||
|| (renderer->batched(WidthOf<8>()) != nullptr))
|
||||
m_opt_batched_analysis((renderer->batched(WidthOf<16>()) != nullptr)
|
||||
|| (renderer->batched(WidthOf<8>()) != nullptr))
|
||||
,
|
||||
#else
|
||||
, m_opt_batched_analysis(false)
|
||||
m_opt_batched_analysis(false)
|
||||
,
|
||||
#endif
|
||||
, m_llvm_jit_fma(false)
|
||||
m_llvm_jit_fma(false)
|
||||
, m_llvm_jit_aggressive(false)
|
||||
, m_optimize_nondebug(false)
|
||||
, m_vector_width(4)
|
||||
@@ -1049,8 +1049,7 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
|
||||
, m_llvm_output_bitcode(0)
|
||||
, m_llvm_dumpasm(0)
|
||||
, m_max_local_mem_KB(2048)
|
||||
, m_compile_report(0)
|
||||
, m_use_optix(renderer->supports("OptiX"))
|
||||
, m_compile_report(false)
|
||||
, m_buffer_printf(true)
|
||||
, m_no_noise(false)
|
||||
, m_no_pointcloud(false)
|
||||
@@ -1094,8 +1093,6 @@ ShadingSystemImpl::ShadingSystemImpl(RendererServices* renderer,
|
||||
m_stat_global_connections = 0;
|
||||
m_stat_tex_calls_codegened = 0;
|
||||
m_stat_tex_calls_as_handles = 0;
|
||||
m_stat_useparam_ops = 0;
|
||||
m_stat_call_layers_inserted = 0;
|
||||
m_stat_master_load_time = 0;
|
||||
m_stat_optimization_time = 0;
|
||||
m_stat_getattribute_time = 0;
|
||||
@@ -1536,7 +1533,6 @@ ShadingSystemImpl::attribute(string_view name, TypeDesc type, const void* val)
|
||||
ATTR_SET("opt_middleman", int, m_opt_middleman);
|
||||
ATTR_SET("opt_texture_handle", int, m_opt_texture_handle);
|
||||
ATTR_SET("opt_seed_bblock_aliases", int, m_opt_seed_bblock_aliases);
|
||||
ATTR_SET("opt_useparam", int, m_opt_useparam);
|
||||
ATTR_SET("opt_batched_analysis", int, m_opt_batched_analysis);
|
||||
ATTR_SET("llvm_jit_fma", int, m_llvm_jit_fma);
|
||||
ATTR_SET("llvm_jit_aggressive", int, m_llvm_jit_aggressive);
|
||||
@@ -1706,7 +1702,6 @@ ShadingSystemImpl::getattribute(string_view name, TypeDesc type, void* val)
|
||||
ATTR_DECODE("opt_middleman", int, m_opt_middleman);
|
||||
ATTR_DECODE("opt_texture_handle", int, m_opt_texture_handle);
|
||||
ATTR_DECODE("opt_seed_bblock_aliases", int, m_opt_seed_bblock_aliases);
|
||||
ATTR_DECODE("opt_useparam", int, m_opt_useparam);
|
||||
ATTR_DECODE("llvm_jit_fma", int, m_llvm_jit_fma);
|
||||
ATTR_DECODE("llvm_jit_aggressive", int, m_llvm_jit_aggressive);
|
||||
ATTR_DECODE_STRING("llvm_jit_target", m_llvm_jit_target);
|
||||
@@ -1773,8 +1768,6 @@ ShadingSystemImpl::getattribute(string_view name, TypeDesc type, void* val)
|
||||
ATTR_DECODE("stat:global_connections", int, m_stat_global_connections);
|
||||
ATTR_DECODE("stat:tex_calls_codegened", int, m_stat_tex_calls_codegened);
|
||||
ATTR_DECODE("stat:tex_calls_as_handles", int, m_stat_tex_calls_as_handles);
|
||||
ATTR_DECODE("stat:useparam_ops", int, m_stat_useparam_ops);
|
||||
ATTR_DECODE("stat:call_layers_inserted", int, m_stat_call_layers_inserted);
|
||||
ATTR_DECODE("stat:master_load_time", float, m_stat_master_load_time);
|
||||
ATTR_DECODE("stat:optimization_time", float, m_stat_optimization_time);
|
||||
ATTR_DECODE("stat:opt_locking_time", float, m_stat_opt_locking_time);
|
||||
@@ -2017,14 +2010,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
|
||||
*(std::string*)val = exists ? group->m_llvm_ptx_compiled_version : "";
|
||||
return true;
|
||||
}
|
||||
if (name == "interactive_params" && type.basetype == TypeDesc::PTR) {
|
||||
*(void**)val = group->m_interactive_arena.get();
|
||||
return true;
|
||||
}
|
||||
if (name == "device_interactive_params" && type.basetype == TypeDesc::PTR) {
|
||||
*(void**)val = group->m_device_interactive_arena.d_get();
|
||||
return true;
|
||||
}
|
||||
|
||||
// All the remaining attributes require the group to already be
|
||||
// optimized.
|
||||
@@ -2120,11 +2105,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
|
||||
*(ustring**)val = n ? &group->m_attribute_scopes[0] : NULL;
|
||||
return true;
|
||||
}
|
||||
if (name == "attribute_types" && type.basetype == TypeDesc::PTR) {
|
||||
size_t n = group->m_attribute_types.size();
|
||||
*(TypeDesc**)val = n ? &group->m_attribute_types[0] : NULL;
|
||||
return true;
|
||||
}
|
||||
if (name == "unknown_attributes_needed" && type == TypeDesc::TypeInt) {
|
||||
*(int*)val = (int)group->m_unknown_attributes_needed;
|
||||
return true;
|
||||
@@ -2145,10 +2125,6 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
|
||||
*(void**)val = n ? &group->m_userdata_init_vals[0] : NULL;
|
||||
return true;
|
||||
}
|
||||
if (name == "llvm_groupdata_size" && type == TypeDesc::TypeInt) {
|
||||
*(int*)val = (int)group->llvm_groupdata_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2422,8 +2398,6 @@ ShadingSystemImpl::getstats(int level) const
|
||||
* (double(m_stat_postopt_syms)
|
||||
/ (std::max(1, (int)m_stat_preopt_syms))
|
||||
- 1.0));
|
||||
print(out, " Optimized {} useparam ops into {} llvm run layer calls\n",
|
||||
m_stat_useparam_ops, m_stat_call_layers_inserted);
|
||||
}
|
||||
print(out, " Constant connections eliminated: {}\n",
|
||||
(int)m_stat_const_connections);
|
||||
@@ -2572,19 +2546,26 @@ ShadingSystemImpl::printstats() const
|
||||
|
||||
bool
|
||||
ShadingSystemImpl::Parameter(string_view name, TypeDesc t, const void* val,
|
||||
ParamHints hints)
|
||||
bool lockgeom)
|
||||
{
|
||||
return Parameter(*m_curgroup, name, t, val, hints);
|
||||
return Parameter(*m_curgroup, name, t, val, lockgeom);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ShadingSystemImpl::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
const void* val, ParamHints hints)
|
||||
const void* val, bool lockgeom)
|
||||
{
|
||||
group.m_pending_params.emplace_back(name, t, 1, val);
|
||||
group.m_pending_hints.push_back(hints);
|
||||
// We work very hard not to do extra copies of the data. First,
|
||||
// grow the pending list by one (empty) slot...
|
||||
group.m_pending_params.grow();
|
||||
// ...then initialize it in place
|
||||
group.m_pending_params.back().init(name, t, 1, val);
|
||||
// If we have a possible geometric override (lockgeom=false), set the
|
||||
// param's interpolation to VERTEX rather than the default CONSTANT.
|
||||
if (lockgeom == false)
|
||||
group.m_pending_params.back().interp(OIIO::ParamValue::INTERP_VERTEX);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2593,7 +2574,7 @@ ShadingSystemImpl::Parameter(ShaderGroup& group, string_view name, TypeDesc t,
|
||||
ShaderGroupRef
|
||||
ShadingSystemImpl::ShaderGroupBegin(string_view groupname)
|
||||
{
|
||||
ShaderGroupRef group(new ShaderGroup(groupname, *this));
|
||||
ShaderGroupRef group(new ShaderGroup(groupname));
|
||||
group->m_exec_repeat = m_exec_repeat;
|
||||
{
|
||||
// Record the group in the SS's census of all extant groups
|
||||
@@ -2721,11 +2702,9 @@ ShadingSystemImpl::Shader(ShaderGroup& group, string_view shaderusage,
|
||||
}
|
||||
|
||||
ShaderInstanceRef instance(new ShaderInstance(master, layername));
|
||||
instance->parameters(group.m_pending_params, group.m_pending_hints);
|
||||
instance->parameters(group.m_pending_params);
|
||||
group.m_pending_params.clear();
|
||||
group.m_pending_params.shrink_to_fit();
|
||||
group.m_pending_hints.clear();
|
||||
group.m_pending_hints.shrink_to_fit();
|
||||
|
||||
if (group.m_group_use.empty()) {
|
||||
// First in a group
|
||||
@@ -2997,8 +2976,7 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
|
||||
}
|
||||
}
|
||||
string_view paramname(paramname_string);
|
||||
int lockgeom = m_lockgeom_default;
|
||||
ParamHints hints = ParamHints::none;
|
||||
int lockgeom = m_lockgeom_default;
|
||||
// For speed, reserve space. Note that for "unsized" arrays, we only
|
||||
// preallocate 1 slot and let it grow as needed. That's ok. For
|
||||
// everything else, we will reserve the right amount up front.
|
||||
@@ -3102,26 +3080,6 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
|
||||
hint_name);
|
||||
break;
|
||||
}
|
||||
set(hints, ParamHints::interpolated, lockgeom == 0);
|
||||
} else if (hint_name == "interpolated"
|
||||
&& hint_type == TypeInt) {
|
||||
int v = 0;
|
||||
if (!Strutil::parse_int(p, v)) {
|
||||
err = true;
|
||||
errdesc = fmtformat("hint {} expected int value",
|
||||
hint_name);
|
||||
break;
|
||||
}
|
||||
set(hints, ParamHints::interpolated, v);
|
||||
} else if (hint_name == "interactive" && hint_type == TypeInt) {
|
||||
int v = 0;
|
||||
if (!Strutil::parse_int(p, v)) {
|
||||
err = true;
|
||||
errdesc = fmtformat("hint {} expected int value",
|
||||
hint_name);
|
||||
break;
|
||||
}
|
||||
set(hints, ParamHints::interactive, v);
|
||||
} else {
|
||||
err = true;
|
||||
errdesc = fmtformat("unknown hint '{} {}'", hint_type,
|
||||
@@ -3140,11 +3098,11 @@ ShadingSystemImpl::ShaderGroupBegin(string_view groupname, string_view usage,
|
||||
|
||||
bool ok = true;
|
||||
if (type.basetype == TypeDesc::INT) {
|
||||
ok = Parameter(*g, paramname, type, &intvals[0], hints);
|
||||
ok = Parameter(*g, paramname, type, &intvals[0], lockgeom);
|
||||
} else if (type.basetype == TypeDesc::FLOAT) {
|
||||
ok = Parameter(*g, paramname, type, &floatvals[0], hints);
|
||||
ok = Parameter(*g, paramname, type, &floatvals[0], lockgeom);
|
||||
} else if (type.basetype == TypeDesc::STRING) {
|
||||
ok = Parameter(*g, paramname, type, &stringvals[0], hints);
|
||||
ok = Parameter(*g, paramname, type, &stringvals[0], lockgeom);
|
||||
}
|
||||
if (!ok) {
|
||||
errstatement = pstart;
|
||||
@@ -3200,12 +3158,10 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
|
||||
{
|
||||
// Find the named layer
|
||||
ustring layername(layername_);
|
||||
ShaderInstance* layer = nullptr;
|
||||
int layerindex = -1;
|
||||
ShaderInstance* layer = NULL;
|
||||
for (int i = 0, e = group.nlayers(); i < e; ++i) {
|
||||
if (group[i]->layername() == layername) {
|
||||
layer = group[i];
|
||||
layerindex = i;
|
||||
layer = group[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3225,18 +3181,8 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that it's declared to be an interactive parameter
|
||||
if (!sym->interactive()) {
|
||||
errorfmt(
|
||||
"ReParameter cannot adjust {}.{}, which was not declared interactive",
|
||||
layername, paramname);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for mismatch versus previously-declared type
|
||||
if ((relaxed_param_typecheck() && !relaxed_equivalent(sym->typespec(), type))
|
||||
|| (!relaxed_param_typecheck()
|
||||
&& !relaxed_equivalent(sym->typespec(), type)))
|
||||
if (!equivalent(sym->typespec(), type))
|
||||
return false;
|
||||
|
||||
// Can't change param value if the group has already been optimized,
|
||||
@@ -3245,13 +3191,7 @@ ShadingSystemImpl::ReParameter(ShaderGroup& group, string_view layername_,
|
||||
return false;
|
||||
|
||||
// Do the deed
|
||||
int offset = group.interactive_param_offset(layerindex, sym->name());
|
||||
memcpy(group.interactive_arena_ptr() + offset, val, type.size());
|
||||
if (use_optix()) {
|
||||
renderer()->copy_to_device(group.device_interactive_arena().d_get()
|
||||
+ offset,
|
||||
val, type.size());
|
||||
}
|
||||
memcpy(sym->data(), val, type.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3617,7 +3557,6 @@ ShadingSystemImpl::optimize_group(ShaderGroup& group, ShadingContext* ctx,
|
||||
for (auto&& f : rop.m_attributes_needed) {
|
||||
group.m_attributes_needed.push_back(f.name);
|
||||
group.m_attribute_scopes.push_back(f.scope);
|
||||
group.m_attribute_types.push_back(f.type);
|
||||
}
|
||||
group.m_optimized = true;
|
||||
|
||||
@@ -4220,8 +4159,7 @@ ShadingContext::ocio_transform(StringParam fromspace, StringParam tospace,
|
||||
const float eps = 0.001f;
|
||||
Color3 CC[3] = { C.val(), C.val() + eps * C.dx(),
|
||||
C.val() + eps * C.dy() };
|
||||
cp->apply((float*)&CC, 3, 1, 3, sizeof(float), sizeof(Color3),
|
||||
3 * sizeof(Color3));
|
||||
cp->apply((float*)&CC, 3, 1, 3, sizeof(float), sizeof(Color3), 0);
|
||||
Cout.set(CC[0], (CC[1] - CC[0]) * (1.0f / eps),
|
||||
(CC[2] - CC[0]) * (1.0f / eps));
|
||||
return true;
|
||||
@@ -4375,8 +4313,8 @@ OSL::OSLQuery::init(const ShaderGroup* group, int layernum)
|
||||
// firstcheck,nchecks are used to check just one element of an array.
|
||||
OSL_SHADEOP void
|
||||
osl_naninf_check(int ncomps, const void* vals_, int has_derivs, void* sg,
|
||||
ustring_pod sourcefile, int sourceline, ustring_pod symbolname,
|
||||
int firstcheck, int nchecks, ustring_pod opname)
|
||||
const void* sourcefile, int sourceline, void* symbolname,
|
||||
int firstcheck, int nchecks, const void* opname)
|
||||
{
|
||||
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
|
||||
const float* vals = (const float*)vals_;
|
||||
@@ -4407,10 +4345,10 @@ osl_naninf_check(int ncomps, const void* vals_, int has_derivs, void* sg,
|
||||
// element of an array.
|
||||
OSL_SHADEOP void
|
||||
osl_uninit_check(long long typedesc_, void* vals_, void* sg,
|
||||
ustring_pod sourcefile, int sourceline, ustring_pod groupname_,
|
||||
int layer, ustring_pod layername_, ustring_pod shadername,
|
||||
int opnum, ustring_pod opname, int argnum,
|
||||
ustring_pod symbolname, int firstcheck, int nchecks)
|
||||
const void* sourcefile, int sourceline, const char* groupname,
|
||||
int layer, const char* layername, const char* shadername,
|
||||
int opnum, const char* opname, int argnum, void* symbolname,
|
||||
int firstcheck, int nchecks)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
|
||||
@@ -4440,34 +4378,30 @@ osl_uninit_check(long long typedesc_, void* vals_, void* sg,
|
||||
}
|
||||
}
|
||||
if (uninit) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
ctx->errorfmt(
|
||||
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {})",
|
||||
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
USTR(shadername), opnum, USTR(opname), argnum);
|
||||
typedesc.c_str(), USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
|
||||
ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer, ustring_pod layername_,
|
||||
ustring_pod shadername)
|
||||
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername)
|
||||
{
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
ShadingContext* ctx = (ShadingContext*)((ShaderGlobals*)sg)->context;
|
||||
ctx->errorfmt(
|
||||
"Index [{}] out of range {}[0..{}]: {}:{} (group {}, layer {} {}, shader {})",
|
||||
indexvalue, USTR(symname), length - 1, USTR(sourcefile), sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
USTR(shadername));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
@@ -4481,7 +4415,7 @@ osl_range_check_err(int indexvalue, int length, ustring_pod symname, void* sg,
|
||||
|
||||
// Asked if the raytype is a name we can't know until mid-shader.
|
||||
OSL_SHADEOP int
|
||||
osl_raytype_name(void* sg_, ustring_pod name)
|
||||
osl_raytype_name(void* sg_, const char* name)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
int bit = sg->context->shadingsys().raytype_bit(USTR(name));
|
||||
@@ -4490,21 +4424,24 @@ osl_raytype_name(void* sg_, ustring_pod name)
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_get_attribute(void* sg_, int dest_derivs, ustring_pod obj_name,
|
||||
ustring_pod attr_name, int array_lookup, int index,
|
||||
long long attr_type, void* attr_dest)
|
||||
osl_get_attribute(void* sg_, int dest_derivs, void* obj_name_, void* attr_name_,
|
||||
int array_lookup, int index, long long attr_type,
|
||||
void* attr_dest)
|
||||
{
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
ShaderGlobals* sg = (ShaderGlobals*)sg_;
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
|
||||
return sg->context->osl_get_attribute(sg, sg->objdata, dest_derivs,
|
||||
USTR(obj_name), USTR(attr_name),
|
||||
array_lookup, index,
|
||||
TYPEDESC(attr_type), attr_dest);
|
||||
obj_name, attr_name, array_lookup,
|
||||
index, TYPEDESC(attr_type),
|
||||
attr_dest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_SHADEOP int
|
||||
osl_bind_interpolated_param(void* sg_, ustring_pod name, long long type,
|
||||
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
|
||||
int userdata_has_derivs, void* userdata_data,
|
||||
int /*symbol_has_derivs*/, void* symbol_data,
|
||||
int symbol_data_size, char* userdata_initialized,
|
||||
@@ -4522,13 +4459,8 @@ osl_bind_interpolated_param(void* sg_, ustring_pod name, long long type,
|
||||
sg->context->incr_get_userdata_calls();
|
||||
}
|
||||
if (status == 2) {
|
||||
int udata_size = (userdata_has_derivs ? 3 : 1) * TYPEDESC(type).size();
|
||||
// If userdata was present, copy it to the shader variable
|
||||
memcpy(symbol_data, userdata_data,
|
||||
std::min(symbol_data_size, udata_size));
|
||||
if (symbol_data_size > udata_size)
|
||||
memset((char*)symbol_data + udata_size, 0,
|
||||
symbol_data_size - udata_size);
|
||||
memcpy(symbol_data, userdata_data, symbol_data_size);
|
||||
return 1;
|
||||
}
|
||||
return 0; // no such user data
|
||||
|
||||
@@ -42,7 +42,7 @@ enum {
|
||||
|
||||
// clang-format off
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
OSL_CONSTANT_DATA const SplineBasis gBasisSet[kNumSplineTypes] = {
|
||||
OSL_CONSTANT_DATA const static SplineBasis gBasisSet[kNumSplineTypes] = {
|
||||
//
|
||||
// catmullrom
|
||||
//
|
||||
|
||||
@@ -149,27 +149,6 @@ equivalent(const TypeSpec& a, const TypeSpec& b)
|
||||
|| a.is_unsized_array() != b.is_unsized_array());
|
||||
}
|
||||
|
||||
// Relaxed rules just look to see that the types are isomorphic to each other (ie: same number of base values)
|
||||
// Note that:
|
||||
// * basetypes must match exactly (int vs float vs string)
|
||||
// * valuetype cannot be unsized (we must know the concrete number of values)
|
||||
// * if paramtype is sized (or not an array) just check for the total number of entries
|
||||
// * if paramtype is unsized (shader writer is flexible about how many values come in) -- make sure we are a multiple of the target type
|
||||
// * allow a single float setting a vec3 (or equivalent)
|
||||
bool
|
||||
relaxed_equivalent(const TypeSpec& a, const TypeSpec& b)
|
||||
{
|
||||
const TypeDesc paramtype = a.simpletype();
|
||||
const TypeDesc valuetype = b.simpletype();
|
||||
|
||||
return valuetype.basetype == paramtype.basetype
|
||||
&& !valuetype.is_unsized_array()
|
||||
&& ((!paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() == paramtype.basevalues())
|
||||
|| (paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() % paramtype.aggregate == 0)
|
||||
|| (paramtype.is_vec3() && valuetype == TypeDesc::FLOAT));
|
||||
}
|
||||
|
||||
|
||||
}; // namespace pvt
|
||||
|
||||
@@ -90,10 +90,8 @@ abs(const Dual2<float>& x)
|
||||
#define __OSL_XMACRO_ARGS (fabs, std::abs)
|
||||
#include "wide_opunary_int_xmacro.h"
|
||||
|
||||
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod, safe_fmod)
|
||||
#include "wide_opbinary_per_component_xmacro.h"
|
||||
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod, safe_fmod)
|
||||
#include "wide_opbinary_per_component_mixed_vector_float_xmacro.h"
|
||||
#define __OSL_XMACRO_ARGS (fmod, OIIO::safe_fmod)
|
||||
#include "wide_opbinary_per_component_float_or_vector_xmacro.h"
|
||||
|
||||
|
||||
static OSL_FORCEINLINE float
|
||||
|
||||
@@ -28,7 +28,12 @@ namespace {
|
||||
OSL_FORCEINLINE OSL_HOSTDEVICE int
|
||||
bitcast_to_uint(float x)
|
||||
{
|
||||
return OSL::bitcast<unsigned int>(x);
|
||||
#if OPENIMAGEIO_VERSION >= 20500
|
||||
return OIIO::bitcast<unsigned int, float>(x);
|
||||
#else
|
||||
// obsolete call
|
||||
return OIIO::bit_cast<float, unsigned int>(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,18 +45,6 @@ invoke(FunctorT f)
|
||||
f();
|
||||
}
|
||||
|
||||
|
||||
// helper to make a Block<ustringhash> from a pointer
|
||||
#if !OSL_USTRINGREP_IS_HASH
|
||||
inline void
|
||||
block_ustringhash_from_ptr(Block<ustringhash>& b, const void* w_ptr)
|
||||
{
|
||||
for (int i = 0; i < __OSL_WIDTH; ++i)
|
||||
b.set(i, reinterpret_cast<const ustring*>(w_ptr)[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
OSL_FORCEINLINE void
|
||||
invert_wide_matrix(Masked<Matrix44> wresult, Wide<const Matrix44> wmatrix)
|
||||
{
|
||||
@@ -100,12 +88,12 @@ invert_wide_matrix(Masked<Matrix44> wresult, Wide<const Matrix44> wmatrix)
|
||||
|
||||
Mask
|
||||
default_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> wresult, Wide<const ustringhash> wfrom,
|
||||
Masked<Matrix44> wresult, Wide<const ustring> wfrom,
|
||||
Wide<const float> wtime)
|
||||
{
|
||||
Mask ok(false);
|
||||
foreach_unique(wfrom, wresult.mask(),
|
||||
[=, &ok](const ustringhash& from, Mask from_mask) {
|
||||
[=, &ok](const ustring& from, Mask from_mask) {
|
||||
// Reuse the uniform from implementation by restricting results to
|
||||
// just the lanes with the same value of "from".
|
||||
Masked<Matrix44> wsub_result(wresult.data(), from_mask);
|
||||
@@ -122,7 +110,7 @@ default_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
|
||||
// execute the ISA optimized default version built right here.
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_get_matrix(BatchedRendererServices* bsr, BatchedShaderGlobals* bsg,
|
||||
Masked<Matrix44> result, Wide<const ustringhash> from,
|
||||
Masked<Matrix44> result, Wide<const ustring> from,
|
||||
Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_matrix_WmWsWf()) {
|
||||
@@ -166,7 +154,7 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
Mask
|
||||
default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustringhash to, Wide<const float> time)
|
||||
ustring to, Wide<const float> time)
|
||||
{
|
||||
OSL_FORCEINLINE_BLOCK
|
||||
{
|
||||
@@ -182,7 +170,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
ustringhash to, Wide<const float> time)
|
||||
ustring to, Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
|
||||
return bsr->get_inverse_matrix(bsg, result, to, time);
|
||||
@@ -195,12 +183,12 @@ dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
Mask
|
||||
default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> wresult,
|
||||
Wide<const ustringhash> wto, Wide<const float> wtime)
|
||||
Wide<const ustring> wto, Wide<const float> wtime)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmsWf()) {
|
||||
Mask ok(false);
|
||||
foreach_unique(wto, wresult.mask(),
|
||||
[=, &ok](const ustringhash& to, Mask from_mask) {
|
||||
[=, &ok](const ustring& to, Mask from_mask) {
|
||||
// Reuse the uniform from implementation by restricting results to
|
||||
// just the lanes with the same value of "from".
|
||||
Masked<Matrix44> wsub_result(wresult.data(),
|
||||
@@ -225,7 +213,7 @@ default_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_get_inverse_matrix(BatchedRendererServices* bsr,
|
||||
BatchedShaderGlobals* bsg, Masked<Matrix44> result,
|
||||
Wide<const ustringhash> to, Wide<const float> time)
|
||||
Wide<const ustring> to, Wide<const float> time)
|
||||
{
|
||||
if (bsr->is_overridden_get_inverse_matrix_WmWsWf()) {
|
||||
return bsr->get_inverse_matrix(bsg, result, to, time);
|
||||
@@ -639,7 +627,7 @@ impl_wide_mat_multiply(ResultAccessorT wresult, FromAccessorT wfrom,
|
||||
OSL_FORCEINLINE Mask
|
||||
impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
|
||||
ShadingContext* ctx,
|
||||
Wide<const ustringhash> wFrom,
|
||||
Wide<const ustring> wFrom,
|
||||
Masked<Matrix44> wMfrom)
|
||||
{
|
||||
// Deal with a varying 'from' space
|
||||
@@ -658,7 +646,7 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
|
||||
: common_space_bits, shader_space_bits,
|
||||
object_space_bits, named_space_bits))
|
||||
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
|
||||
ustringhash from = wFrom[lane];
|
||||
ustring from = wFrom[lane];
|
||||
if (wMfrom.mask()[lane]) {
|
||||
if (from == Strings::common || from == commonspace_synonym) {
|
||||
// inline of Mask::set_on(lane)
|
||||
@@ -715,10 +703,10 @@ impl_get_varying_from_matrix_batched(BatchedShaderGlobals* bsg,
|
||||
if (ctx->shadingsys().unknown_coordsys_error()) {
|
||||
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
|
||||
if (failedLanes[lane]) {
|
||||
ustringhash from = wFrom[lane];
|
||||
ustring from = wFrom[lane];
|
||||
ctx->batched<__OSL_WIDTH>().errorfmt(
|
||||
Mask(Lane(lane)), "Unknown transformation \"{}\"",
|
||||
ustring(from));
|
||||
from);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,13 +746,7 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, Ws)(void* bsg_, void* wr,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wFromName(w_from_name);
|
||||
#else
|
||||
Block<ustringhash> bwFromName;
|
||||
block_ustringhash_from_ptr(bwFromName, w_from_name);
|
||||
Wide<const ustringhash> wFromName(bwFromName);
|
||||
#endif
|
||||
Wide<const ustring> wFromName(w_from_name);
|
||||
|
||||
Block<Matrix44> wMfrom;
|
||||
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
|
||||
@@ -780,8 +762,7 @@ __OSL_MASKED_OP2(prepend_matrix_from, Wm, Ws)(void* bsg_, void* wr,
|
||||
namespace {
|
||||
OSL_FORCEINLINE Mask
|
||||
impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
|
||||
ShadingContext* ctx,
|
||||
Wide<const ustringhash> wTo,
|
||||
ShadingContext* ctx, Wide<const ustring> wTo,
|
||||
Masked<Matrix44> wMto)
|
||||
{
|
||||
// Deal with a varying 'to' space
|
||||
@@ -800,7 +781,7 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
|
||||
: common_space_bits, shader_space_bits,
|
||||
object_space_bits, named_space_bits))
|
||||
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
|
||||
ustringhash to = wTo[lane];
|
||||
ustring to = wTo[lane];
|
||||
if (wMto.mask()[lane]) {
|
||||
if (to == Strings::common || to == commonspace_synonym) {
|
||||
// inline of Mask::set_on(lane)
|
||||
@@ -855,10 +836,10 @@ impl_get_varying_to_matrix_masked(BatchedShaderGlobals* bsg,
|
||||
if (ctx->shadingsys().unknown_coordsys_error()) {
|
||||
for (int lane = 0; lane < __OSL_WIDTH; ++lane) {
|
||||
if (failedLanes[lane]) {
|
||||
ustringhash to = wTo[lane];
|
||||
ustring to = wTo[lane];
|
||||
ctx->batched<__OSL_WIDTH>().errorfmt(
|
||||
Mask(Lane(lane)), "Unknown transformation \"{}\"",
|
||||
ustring(to));
|
||||
to);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -914,13 +895,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, s,
|
||||
Mask succeeded = impl_get_uniform_from_matrix_masked(bsg, from_matrix,
|
||||
from);
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wToSpace(w_to_ptr);
|
||||
#else
|
||||
Block<ustringhash> bwToSpace;
|
||||
block_ustringhash_from_ptr(bwToSpace, w_to_ptr);
|
||||
Wide<const ustringhash> wToSpace(bwToSpace);
|
||||
#endif
|
||||
Wide<const ustring> wToSpace(w_to_ptr);
|
||||
Block<Matrix44> wMto;
|
||||
// NOTE: even if we failed to get a from matrix, it should have been set to
|
||||
// identity, so we still need to try to get the to matrix for the original mask
|
||||
@@ -942,13 +917,7 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wFromName(w_from_ptr);
|
||||
#else
|
||||
Block<ustringhash> bwFromName;
|
||||
block_ustringhash_from_ptr(bwFromName, w_from_ptr);
|
||||
Wide<const ustringhash> wFromName(bwFromName);
|
||||
#endif
|
||||
Wide<const ustring> wFromName(w_from_ptr);
|
||||
|
||||
Block<Matrix44> wMto;
|
||||
Masked<Matrix44> to_matrix(wMto, Mask(mask_value));
|
||||
@@ -976,26 +945,14 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wFromName(w_from_ptr);
|
||||
#else
|
||||
Block<ustringhash> bwFromName;
|
||||
block_ustringhash_from_ptr(bwFromName, w_from_ptr);
|
||||
Wide<const ustringhash> wFromName(bwFromName);
|
||||
#endif
|
||||
Wide<const ustring> wFromName(w_from_ptr);
|
||||
|
||||
Block<Matrix44> wMfrom;
|
||||
Masked<Matrix44> from_matrix(wMfrom, Mask(mask_value));
|
||||
Mask succeeded = impl_get_varying_from_matrix_batched(bsg, ctx, wFromName,
|
||||
from_matrix);
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wToSpace(w_to_ptr);
|
||||
#else
|
||||
Block<ustringhash> bwToSpace;
|
||||
block_ustringhash_from_ptr(bwToSpace, w_to_ptr);
|
||||
Wide<const ustringhash> wToSpace(bwToSpace);
|
||||
#endif
|
||||
Wide<const ustring> wToSpace(w_to_ptr);
|
||||
Block<Matrix44> wMto;
|
||||
// NOTE: even if we failed to get a from matrix, it should have been set to
|
||||
// identity, so we still need to try to get the to matrix for the original mask
|
||||
@@ -1020,9 +977,9 @@ __OSL_MASKED_OP3(get_from_to_matrix, Wm, Ws,
|
||||
// Also zeroing of derivatives is left to the code generator.
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
s)(void* bsg_, void* WM_, ustring_pod from_, ustring_pod to_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s, s)(void* bsg_, void* WM_,
|
||||
void* from_, void* to_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -1030,8 +987,8 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
Masked<Matrix44> mm(WM_, mask);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
ustringrep from = USTR(from_);
|
||||
ustringrep to = USTR(to_);
|
||||
ustring from = USTR(from_);
|
||||
ustring to = USTR(to_);
|
||||
|
||||
Mask succeeded;
|
||||
// Avoid matrix concatenation if possible by detecting when the
|
||||
@@ -1056,24 +1013,18 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, Ws,
|
||||
s)(void* bsg_, void* WM_, void* wfrom_, ustring_pod to_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, s)(void* bsg_, void* WM_,
|
||||
void* wfrom_, void* to_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wfrom_space(wfrom_);
|
||||
#else
|
||||
Block<ustringhash> bwfrom_space;
|
||||
block_ustringhash_from_ptr(bwfrom_space, wfrom_);
|
||||
Wide<const ustringhash> wfrom_space(bwfrom_space);
|
||||
#endif
|
||||
Wide<const ustring> wfrom_space(wfrom_);
|
||||
|
||||
ustringrep to_space = USTR(to_);
|
||||
ustring to_space = USTR(to_);
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
@@ -1092,23 +1043,17 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s,
|
||||
Ws)(void* bsg_, void* WM_, ustring_pod from_, void* wto_,
|
||||
unsigned int mask_value)
|
||||
__OSL_MASKED_OP3(build_transform_matrix, Wm, s, Ws)(void* bsg_, void* WM_,
|
||||
void* from_, void* wto_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
ustringrep from = USTR(from_);
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wto_space(wto_);
|
||||
#else
|
||||
Block<ustringhash> bwto_space;
|
||||
block_ustringhash_from_ptr(bwto_space, wto_);
|
||||
Wide<const ustringhash> wto_space(bwto_space);
|
||||
#endif
|
||||
ustring from = USTR(from_);
|
||||
Wide<const ustring> wto_space(wto_);
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
@@ -1137,17 +1082,8 @@ __OSL_MASKED_OP3(build_transform_matrix, Wm, Ws, Ws)(void* bsg_, void* WM_,
|
||||
Mask mask(mask_value);
|
||||
Masked<Matrix44> wrm(WM_, mask);
|
||||
|
||||
#if OSL_USTRINGREP_IS_HASH
|
||||
Wide<const ustringhash> wfrom_space(wfrom_);
|
||||
Wide<const ustringhash> wto_space(wto_);
|
||||
#else
|
||||
Block<ustringhash> bwfrom_space;
|
||||
block_ustringhash_from_ptr(bwfrom_space, wfrom_);
|
||||
Wide<const ustringhash> wfrom_space(bwfrom_space);
|
||||
Block<ustringhash> bwto_space;
|
||||
block_ustringhash_from_ptr(bwto_space, wto_);
|
||||
Wide<const ustringhash> wto_space(bwto_space);
|
||||
#endif
|
||||
Wide<const ustring> wfrom_space(wfrom_);
|
||||
Wide<const ustring> wto_space(wto_);
|
||||
|
||||
Block<Matrix44> wMfrom, wMto;
|
||||
Masked<Matrix44> from_matrix(wMfrom, wrm.mask());
|
||||
|
||||
@@ -200,19 +200,18 @@ impl_setmessage(BatchedShaderGlobals* bsg, ustring sourcefile, int sourceline,
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_,
|
||||
ustring_pod name_, long long type,
|
||||
void* wvalue, int layeridx,
|
||||
ustring_pod sourcefile_, int sourceline,
|
||||
__OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
long long type, void* wvalue, int layeridx,
|
||||
const char* sourcefile_, int sourceline,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
Mask mask(mask_value);
|
||||
OSL_ASSERT(mask.any_on());
|
||||
|
||||
ustringrep name = USTR(name_);
|
||||
ustring name = USTR(wname);
|
||||
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
|
||||
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -238,16 +237,16 @@ __OSL_MASKED_OP2(setmessage, s, WX)(BatchedShaderGlobals* bsg_,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
long long type, void* wvalue, int layeridx,
|
||||
ustring_pod sourcefile_, int sourceline,
|
||||
const char* sourcefile_, int sourceline,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
Mask mask(mask_value);
|
||||
OSL_ASSERT(mask.any_on());
|
||||
|
||||
Wide<const ustringrep> wName(wname);
|
||||
Wide<const ustring> wName(wname);
|
||||
MaskedData wsrcval(TYPEDESC(type), false /*has_derivs*/, mask, wvalue);
|
||||
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
|
||||
@@ -275,14 +274,14 @@ __OSL_MASKED_OP2(setmessage, Ws, WX)(BatchedShaderGlobals* bsg_, void* wname,
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, ustring_pod source_,
|
||||
ustring_pod name_, long long type_, void* val,
|
||||
int derivs, int layeridx, ustring_pod sourcefile_,
|
||||
__OSL_MASKED_OP(getmessage)(void* bsg_, void* result, char* source_,
|
||||
char* name_, long long type_, void* val, int derivs,
|
||||
int layeridx, const char* sourcefile_,
|
||||
int sourceline, unsigned int mask_value)
|
||||
{
|
||||
ustringrep source = USTR(source_);
|
||||
ustringrep name = USTR(name_);
|
||||
ustringrep sourcefile = USTR(sourcefile_);
|
||||
const ustring& source(USTR(source_));
|
||||
const ustring& name(USTR(name_));
|
||||
const ustring& sourcefile(USTR(sourcefile_));
|
||||
|
||||
Mask mask(mask_value);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ using PointCloudSearchResults = BatchedRendererServices::PointCloudSearchResults
|
||||
namespace {
|
||||
|
||||
OSL_FORCEINLINE void
|
||||
default_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
default_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
const void* wcenter_, Wide<const float> wradius,
|
||||
int max_points, bool sort,
|
||||
PointCloudSearchResults& results)
|
||||
@@ -199,7 +199,7 @@ default_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE void
|
||||
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustring filename,
|
||||
const void* wcenter, Wide<const float> wradius,
|
||||
int max_points, bool sort,
|
||||
PointCloudSearchResults& results)
|
||||
@@ -217,9 +217,9 @@ dispatch_pointcloud_search(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
default_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
default_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const int[]> windices, Wide<const int> wnum_points,
|
||||
ustringhash attr_name, MaskedData wout_data)
|
||||
ustring attr_name, MaskedData wout_data)
|
||||
{
|
||||
#ifdef USE_PARTIO
|
||||
Mask success { false };
|
||||
@@ -364,9 +364,9 @@ default_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const int[]> windices, Wide<const int> wnum_points,
|
||||
ustringhash attr_name, MaskedData wout_data)
|
||||
ustring attr_name, MaskedData wout_data)
|
||||
{
|
||||
auto* bsr = bsg->uniform.renderer->batched(WidthTag());
|
||||
if (bsr->is_overridden_pointcloud_get()) {
|
||||
@@ -381,7 +381,7 @@ dispatch_pointcloud_get(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
|
||||
Mask
|
||||
default_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
default_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const OSL::Vec3> wpos, int nattribs,
|
||||
const ustring* attr_names, const TypeDesc* attr_types,
|
||||
const void** ptrs_to_wide_attr_value, Mask mask)
|
||||
@@ -472,7 +472,7 @@ default_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
|
||||
OSL_FORCEINLINE Mask
|
||||
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustring filename,
|
||||
Wide<const OSL::Vec3> wpos, int nattribs,
|
||||
const ustring* attr_names, const TypeDesc* attr_types,
|
||||
const void** ptrs_to_wide_attr_value, Mask mask)
|
||||
@@ -494,7 +494,7 @@ dispatch_pointcloud_write(BatchedShaderGlobals* bsg, ustringhash filename,
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(pointcloud_search)(
|
||||
BatchedShaderGlobals* bsg, void* wout_num_points_, ustring_pod filename,
|
||||
BatchedShaderGlobals* bsg, void* wout_num_points_, const char* filename,
|
||||
const void* wcenter_, void* wradius_, int max_points, int sort,
|
||||
void* wout_indices_, int indices_array_length, void* wout_distances_,
|
||||
int distances_array_length, int distances_has_derivs, int mask_value,
|
||||
@@ -509,15 +509,16 @@ __OSL_MASKED_OP(pointcloud_search)(
|
||||
mask_value };
|
||||
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
if (ctx->shadingsys().no_pointcloud()) {
|
||||
// Debug mode to skip pointcloud expense
|
||||
if (ctx->shadingsys()
|
||||
.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
{
|
||||
assign_all(pcsr.wnum_points(), 0);
|
||||
return; // mask_value;
|
||||
}
|
||||
|
||||
Wide<const float> wradius(wradius_);
|
||||
|
||||
dispatch_pointcloud_search(bsg, USTR(filename).uhash(), wcenter_, wradius,
|
||||
dispatch_pointcloud_search(bsg, USTR(filename), wcenter_, wradius,
|
||||
max_points, sort, pcsr);
|
||||
|
||||
if (nattrs > 0) {
|
||||
@@ -527,9 +528,11 @@ __OSL_MASKED_OP(pointcloud_search)(
|
||||
va_list args;
|
||||
va_start(args, nattrs);
|
||||
for (int i = 0; i < nattrs; i++) {
|
||||
ustringrep attr_name = USTREP(va_arg(args, ustring_pod));
|
||||
TypeDesc attr_type = TYPEDESC(va_arg(args, long long));
|
||||
void* out_data = va_arg(args, void*);
|
||||
ustring attr_name = ustring::from_unique(
|
||||
(const char*)va_arg(args, const char*));
|
||||
long long lltype = va_arg(args, long long);
|
||||
TypeDesc attr_type = TYPEDESC(lltype);
|
||||
void* out_data = va_arg(args, void*);
|
||||
dispatch_pointcloud_get(
|
||||
bsg, USTR(filename), windices, wnum_points, attr_name,
|
||||
MaskedData { attr_type, false, Mask { mask_value }, out_data });
|
||||
@@ -544,9 +547,9 @@ __OSL_MASKED_OP(pointcloud_search)(
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename,
|
||||
__OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, const char* filename,
|
||||
void* windices_, int indices_array_length,
|
||||
void* wnum_points_, ustring_pod attr_name,
|
||||
void* wnum_points_, const char* attr_name,
|
||||
long long attr_type_, void* wout_data_,
|
||||
int mask_value)
|
||||
{
|
||||
@@ -561,8 +564,7 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename,
|
||||
TypeDesc attr_type = TYPEDESC(attr_type_);
|
||||
|
||||
Mask success = dispatch_pointcloud_get(
|
||||
bsg, USTR(filename).uhash(), windices, wnum_points,
|
||||
USTR(attr_name).uhash(),
|
||||
bsg, USTR(filename), windices, wnum_points, USTR(attr_name),
|
||||
MaskedData { attr_type, false, Mask { mask_value }, wout_data_ });
|
||||
return success.value();
|
||||
}
|
||||
@@ -571,21 +573,20 @@ __OSL_MASKED_OP(pointcloud_get)(BatchedShaderGlobals* bsg, ustring_pod filename,
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP(pointcloud_write)(BatchedShaderGlobals* bsg,
|
||||
ustring_pod filename, const void* wpos_,
|
||||
int nattribs, const ustringrep* attr_names,
|
||||
const char* filename, const void* wpos_,
|
||||
int nattribs, const ustring* attr_names,
|
||||
const TypeDesc* attr_types,
|
||||
const void** ptrs_to_wide_attr_value,
|
||||
int mask_value)
|
||||
{
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
|
||||
// Debug mode to skip pointcloud expense
|
||||
if (ctx->shadingsys().no_pointcloud())
|
||||
return 0; // mask_value;
|
||||
if (ctx->shadingsys()
|
||||
.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
return 0; // mask_value;
|
||||
|
||||
Wide<const OSL::Vec3> wpos(wpos_);
|
||||
|
||||
Mask success = dispatch_pointcloud_write(bsg, USTR(filename).uhash(), wpos,
|
||||
Mask success = dispatch_pointcloud_write(bsg, USTR(filename), wpos,
|
||||
nattribs, attr_names, attr_types,
|
||||
ptrs_to_wide_attr_value,
|
||||
Mask(mask_value));
|
||||
|
||||
@@ -456,7 +456,7 @@ spline_evaluate_wide(RAccessorT wR, ustring spline_basis, XAccessorT wX,
|
||||
true /*is_basis_u_constant */, 1 /* basis_step */,
|
||||
ConstantWeights, RAccessorT, XAccessorT, KAccessor_T> };
|
||||
|
||||
unsigned int basis_type = Spline::basis_type_of(spline_basis);
|
||||
unsigned int basis_type = Spline::basis_type_of(USTR(spline_basis));
|
||||
|
||||
OSL_DASSERT(basis_type < Spline::kNumSplineTypes
|
||||
&& "unsupported spline basis");
|
||||
@@ -539,7 +539,7 @@ splineinverse_evaluate_wide(RAccessorT wR, ustring spline_basis, XAccessorT wX,
|
||||
true /*is_basis_u_constant */, 1 /* basis_step */,
|
||||
ConstantWeights, RAccessorT, XAccessorT, KAccessor_T> };
|
||||
|
||||
unsigned int basis_type = Spline::basis_type_of(spline_basis);
|
||||
unsigned int basis_type = Spline::basis_type_of(USTR(spline_basis));
|
||||
|
||||
OSL_DASSERT(basis_type < Spline::kNumSplineTypes
|
||||
&& "unsupported spline basis");
|
||||
|
||||
@@ -354,7 +354,7 @@ __OSL_MASKED_OP(regex_impl)(void* bsg_, void* wsuccess_ptr, void* wsubject_ptr,
|
||||
|
||||
const std::string& subject = usubject.string();
|
||||
std::match_results<std::string::const_iterator> mresults;
|
||||
const std::regex& regex(ctx->find_regex(pattern));
|
||||
const std::regex& regex(ctx->find_regex(USTR(pattern)));
|
||||
if (nresults > 0) {
|
||||
std::string::const_iterator start = subject.begin();
|
||||
int res = fullmatch ? std::regex_match(subject, mresults, regex)
|
||||
@@ -366,7 +366,7 @@ __OSL_MASKED_OP(regex_impl)(void* bsg_, void* wsuccess_ptr, void* wsubject_ptr,
|
||||
else
|
||||
results[r] = mresults[r / 2].second - start;
|
||||
} else {
|
||||
results[r] = pattern.length();
|
||||
results[r] = USTR(pattern).length();
|
||||
}
|
||||
}
|
||||
wsuccess[lane] = res;
|
||||
|
||||
@@ -105,8 +105,8 @@ default_texture(BatchedRendererServices* bsr, ustring filename,
|
||||
// It's actually faster to ask for 4 channels (even if we need fewer)
|
||||
// and ensure that they're being put in aligned memory.
|
||||
// TODO: investigate if the above statement is true when nchannels==1
|
||||
// NOTE: using simd::vfloat4 to speedup texture transformation below
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
// NOTE: using simd::float4 to speedup texture transformation below
|
||||
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
|
||||
bool retVal = false;
|
||||
|
||||
@@ -120,8 +120,8 @@ default_texture(BatchedRendererServices* bsr, ustring filename,
|
||||
has_derivs ? (float*)&dresultds_simd : NULL,
|
||||
has_derivs ? (float*)&dresultdt_simd : NULL);
|
||||
|
||||
OIIO::simd::vfloat4 dresultdx_simd;
|
||||
OIIO::simd::vfloat4 dresultdy_simd;
|
||||
OIIO::simd::float4 dresultdx_simd;
|
||||
OIIO::simd::float4 dresultdy_simd;
|
||||
if (has_derivs) {
|
||||
// Correct our st texture space gradients into xy-space gradients
|
||||
dresultdx_simd = dresultds_simd * dsdx + dresultdt_simd * dtdx;
|
||||
@@ -297,8 +297,8 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename,
|
||||
// and ensure that they're being put in aligned memory.
|
||||
// TODO: investigate if the above statement is true when nchannels==1
|
||||
|
||||
// NOTE: using simd::vfloat4 to speedup texture transformation below
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
// NOTE: using simd::float4 to speedup texture transformation below
|
||||
OIIO::simd::float4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
dresultdr_simd;
|
||||
|
||||
bool retVal = false;
|
||||
@@ -314,8 +314,8 @@ default_texture3d(BatchedRendererServices* bsr, ustring filename,
|
||||
has_derivs ? (float*)&dresultdt_simd : nullptr,
|
||||
has_derivs ? (float*)&dresultdr_simd : nullptr);
|
||||
|
||||
OIIO::simd::vfloat4 dresultdx_simd;
|
||||
OIIO::simd::vfloat4 dresultdy_simd;
|
||||
OIIO::simd::float4 dresultdx_simd;
|
||||
OIIO::simd::float4 dresultdy_simd;
|
||||
if (has_derivs) {
|
||||
// Correct our str texture space gradients into xyz-space gradients
|
||||
dresultdx_simd = dresultds_simd * dPdx.x + dresultdt_simd * dPdx.y
|
||||
@@ -480,8 +480,8 @@ default_environment(BatchedRendererServices* bsr, ustring filename,
|
||||
// and ensure that they're being put in aligned memory.
|
||||
// TODO: investigate if the above statement is true when nchannels==1
|
||||
|
||||
// NOTE: using simd::vfloat4 to speedup texture transformation below
|
||||
OIIO::simd::vfloat4 result_simd;
|
||||
// NOTE: using simd::float4 to speedup texture transformation below
|
||||
OIIO::simd::float4 result_simd;
|
||||
|
||||
bool retVal = false;
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ using WidthTag = OSL::WidthOf<__OSL_WIDTH>;
|
||||
// firstcheck,nchecks are used to check just one element of an array.
|
||||
OSL_BATCHOP void
|
||||
__OSL_OP(naninf_check)(int ncomps, const void* vals_, int has_derivs,
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod symbolname, int firstcheck, int nchecks,
|
||||
ustring_pod opname)
|
||||
void* bsg_, const void* sourcefile, int sourceline,
|
||||
void* symbolname, int firstcheck, int nchecks,
|
||||
const void* opname)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
@@ -56,9 +56,9 @@ __OSL_OP(naninf_check)(int ncomps, const void* vals_, int has_derivs,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP1(naninf_check_offset,
|
||||
i)(int mask_value, int ncomps, const void* vals_,
|
||||
int has_derivs, void* bsg_, ustring_pod sourcefile,
|
||||
int sourceline, ustring_pod symbolname, int firstcheck,
|
||||
int nchecks, ustring_pod opname)
|
||||
int has_derivs, void* bsg_, const void* sourcefile,
|
||||
int sourceline, void* symbolname, int firstcheck,
|
||||
int nchecks, const void* opname)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
@@ -88,12 +88,12 @@ __OSL_MASKED_OP1(naninf_check_offset,
|
||||
|
||||
// Wide vals + mask + varying index
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP1(naninf_check_offset,
|
||||
Wi)(int mask_value, int ncomps, const void* vals_,
|
||||
int has_derivs, void* bsg_, ustring_pod sourcefile,
|
||||
int sourceline, ustring_pod symbolname,
|
||||
const void* wide_offsets_ptr, int nchecks,
|
||||
ustring_pod opname)
|
||||
__OSL_MASKED_OP1(naninf_check_offset, Wi)(int mask_value, int ncomps,
|
||||
const void* vals_, int has_derivs,
|
||||
void* bsg_, const void* sourcefile,
|
||||
int sourceline, void* symbolname,
|
||||
const void* wide_offsets_ptr,
|
||||
int nchecks, const void* opname)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
@@ -129,9 +129,9 @@ __OSL_MASKED_OP1(naninf_check_offset,
|
||||
OSL_BATCHOP void
|
||||
__OSL_OP2(uninit_check_values_offset, X,
|
||||
i)(long long typedesc_, void* vals_, void* bsg_,
|
||||
ustring_pod sourcefile, int sourceline, ustring_pod groupname_,
|
||||
int layer, ustring_pod layername_, ustring_pod shadername,
|
||||
int opnum, ustring_pod opname, int argnum, ustring_pod symbolname,
|
||||
const void* sourcefile, int sourceline, const char* groupname,
|
||||
int layer, const char* layername, const char* shadername,
|
||||
int opnum, const char* opname, int argnum, void* symbolname,
|
||||
int firstcheck, int nchecks)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
@@ -163,14 +163,12 @@ __OSL_OP2(uninit_check_values_offset, X,
|
||||
}
|
||||
}
|
||||
if (uninit) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
ctx->errorfmt(
|
||||
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {})",
|
||||
typedesc, symbolname, sourcefile, sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
shadername, opnum, opname, argnum);
|
||||
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,11 +179,10 @@ __OSL_OP2(uninit_check_values_offset, X,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
i)(int mask_value, long long typedesc_, void* vals_,
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer, ustring_pod layername_,
|
||||
ustring_pod shadername, int opnum, ustring_pod opname,
|
||||
int argnum, ustring_pod symbolname, int firstcheck,
|
||||
int nchecks)
|
||||
void* bsg_, const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername, int opnum, const char* opname,
|
||||
int argnum, void* symbolname, int firstcheck, int nchecks)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -227,14 +224,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
});
|
||||
}
|
||||
if (lanes_uninit.any_on()) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
ctx->errorfmt(
|
||||
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch",
|
||||
typedesc, symbolname, sourcefile, sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
shadername, opnum, opname, argnum, lanes_uninit.value());
|
||||
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,11 +240,11 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(uninit_check_values_offset, X,
|
||||
Wi)(int mask_value, long long typedesc_, void* vals_,
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer, ustring_pod layername_,
|
||||
ustring_pod shadername, int opnum, ustring_pod opname,
|
||||
int argnum, ustring_pod symbolname,
|
||||
const void* wide_offsets_ptr, int nchecks)
|
||||
void* bsg_, const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername, int opnum, const char* opname,
|
||||
int argnum, void* symbolname, const void* wide_offsets_ptr,
|
||||
int nchecks)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -293,14 +288,12 @@ __OSL_MASKED_OP2(uninit_check_values_offset, X,
|
||||
}
|
||||
|
||||
if (lanes_uninit.any_on()) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
ctx->errorfmt(
|
||||
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch",
|
||||
typedesc, symbolname, sourcefile, sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
shadername, opnum, opname, argnum, lanes_uninit.value());
|
||||
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,11 +304,11 @@ __OSL_MASKED_OP2(uninit_check_values_offset, X,
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
Wi)(int mask_value, long long typedesc_, void* vals_,
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer, ustring_pod layername_,
|
||||
ustring_pod shadername, int opnum, ustring_pod opname,
|
||||
int argnum, ustring_pod symbolname,
|
||||
const void* wide_offsets_ptr, int nchecks)
|
||||
void* bsg_, const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername, int opnum, const char* opname,
|
||||
int argnum, void* symbolname, const void* wide_offsets_ptr,
|
||||
int nchecks)
|
||||
{
|
||||
TypeDesc typedesc = TYPEDESC(typedesc_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
@@ -361,38 +354,33 @@ __OSL_MASKED_OP2(uninit_check_values_offset, WX,
|
||||
}
|
||||
|
||||
if (lanes_uninit.any_on()) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
ctx->errorfmt(
|
||||
"Detected possible use of uninitialized value in {} {} at {}:{} (group {}, layer {} {}, shader {}, op {} '{}', arg {}) for lanes({:x}) of batch",
|
||||
typedesc, symbolname, sourcefile, sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(), layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
shadername, opnum, opname, argnum, lanes_uninit.value());
|
||||
typedesc, USTR(symbolname), USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
shadername, opnum, USTR(opname), argnum, lanes_uninit.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_OP(range_check)(int indexvalue, int length, ustring_pod symname,
|
||||
void* bsg_, ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer, ustring_pod layername_,
|
||||
ustring_pod shadername)
|
||||
__OSL_OP(range_check)(int indexvalue, int length, const char* symname,
|
||||
void* bsg_, const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
ctx->errorfmt("Index [{}] out of range {}[0..{}]: {}:{}"
|
||||
" (group {}, layer {} {}, shader {})",
|
||||
indexvalue, USTR(symname), length - 1, USTR(sourcefile),
|
||||
sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(),
|
||||
layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
USTR(shadername));
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ShadingContext* ctx = bsg->uniform.context;
|
||||
ctx->errorfmt(
|
||||
"Index [{}] out of range {}[0..{}]: {}:{}"
|
||||
" (group {}, layer {} {}, shader {})",
|
||||
indexvalue, USTR(symname), length - 1, USTR(sourcefile), sourceline,
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>", layer,
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
USTR(shadername));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
else
|
||||
@@ -405,14 +393,12 @@ __OSL_OP(range_check)(int indexvalue, int length, ustring_pod symname,
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value,
|
||||
int length, ustring_pod symname, void* bsg_,
|
||||
ustring_pod sourcefile, int sourceline,
|
||||
ustring_pod groupname_, int layer,
|
||||
ustring_pod layername_, ustring_pod shadername)
|
||||
int length, const char* symname, void* bsg_,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer,
|
||||
const char* layername, const char* shadername)
|
||||
{
|
||||
ustringrep groupname = USTR(groupname_);
|
||||
ustringrep layername = USTR(layername_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
Masked<int> wIndexValue(wide_indexvalue, Mask(mask_value));
|
||||
wIndexValue.mask().foreach ([=](ActiveLane lane) -> void {
|
||||
int indexvalue = wIndexValue[lane];
|
||||
@@ -422,9 +408,9 @@ __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value,
|
||||
"Index [{}] out of range {}[0..{}]: {}:{} (group {}, layer {} {}, shader {})",
|
||||
indexvalue, USTR(symname), length - 1, USTR(sourcefile),
|
||||
sourceline,
|
||||
groupname.empty() ? "<unnamed group>" : groupname.c_str(),
|
||||
(groupname && groupname[0]) ? groupname : "<unnamed group>",
|
||||
layer,
|
||||
layername.empty() ? "<unnamed layer>" : layername.c_str(),
|
||||
(layername && layername[0]) ? layername : "<unnamed layer>",
|
||||
USTR(shadername));
|
||||
if (indexvalue >= length)
|
||||
indexvalue = length - 1;
|
||||
@@ -439,17 +425,17 @@ __OSL_MASKED_OP(range_check)(void* wide_indexvalue, unsigned int mask_value,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, ustring_pod obj_name_,
|
||||
ustring_pod attr_name_, int array_lookup, int index,
|
||||
__OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
void* attr_name_, int array_lookup, int index,
|
||||
const void* attr_type, void* wide_attr_dest,
|
||||
int mask_)
|
||||
{
|
||||
Mask mask(mask_);
|
||||
ASSERT(mask.any_on());
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
ustringrep attr_name = USTR(attr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
|
||||
// Ignoring m_next_failed_attrib cache for now,
|
||||
// might be faster
|
||||
@@ -471,16 +457,16 @@ __OSL_OP1(get_attribute, s)(void* bsg_, int dest_derivs, ustring_pod obj_name_,
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_MASKED_OP1(get_attribute,
|
||||
Ws)(void* bsg_, int dest_derivs, ustring_pod obj_name_,
|
||||
ustring_pod* wattr_name_, int array_lookup, int index,
|
||||
Ws)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
void* wattr_name_, int array_lookup, int index,
|
||||
const void* attr_type, void* wide_attr_dest, int mask_)
|
||||
{
|
||||
Mask mask(mask_);
|
||||
ASSERT(mask.any_on());
|
||||
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
Wide<const ustringrep> wAttrName(wattr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
Wide<const ustring> wAttrName(wattr_name_);
|
||||
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
|
||||
|
||||
Mask retVal(false);
|
||||
@@ -518,14 +504,13 @@ __OSL_MASKED_OP1(get_attribute,
|
||||
|
||||
|
||||
OSL_BATCHOP bool
|
||||
__OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs,
|
||||
ustring_pod obj_name_, ustring_pod attr_name_,
|
||||
int array_lookup, int index,
|
||||
__OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs, void* obj_name_,
|
||||
void* attr_name_, int array_lookup, int index,
|
||||
const void* attr_type, void* attr_dest)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
ustringrep obj_name = USTR(obj_name_);
|
||||
ustringrep attr_name = USTR(attr_name_);
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
const ustring& obj_name = USTR(obj_name_);
|
||||
const ustring& attr_name = USTR(attr_name_);
|
||||
|
||||
auto* renderer = bsg->uniform.context->batched<__OSL_WIDTH>().renderer();
|
||||
|
||||
@@ -545,7 +530,7 @@ __OSL_OP(get_attribute_uniform)(void* bsg_, int dest_derivs,
|
||||
|
||||
|
||||
OSL_BATCHOP int
|
||||
__OSL_OP(bind_interpolated_param)(void* bsg_, ustring_pod name, long long type,
|
||||
__OSL_OP(bind_interpolated_param)(void* bsg_, const void* name, long long type,
|
||||
int userdata_has_derivs, void* userdata_data,
|
||||
int symbol_has_derivs, void* symbol_data,
|
||||
int symbol_data_size,
|
||||
@@ -595,7 +580,7 @@ __OSL_OP(raytype_bit)(void* bsg_, int bit)
|
||||
|
||||
// Asked if the raytype is a name we can't know until mid-shader.
|
||||
OSL_BATCHOP int
|
||||
__OSL_OP(raytype_name)(void* bsg_, ustring_pod name)
|
||||
__OSL_OP(raytype_name)(void* bsg_, void* name)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
int bit = bsg->uniform.context->shadingsys().raytype_bit(USTR(name));
|
||||
@@ -605,11 +590,11 @@ __OSL_OP(raytype_name)(void* bsg_, ustring_pod name)
|
||||
|
||||
|
||||
OSL_BATCHOP void
|
||||
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, ustringrep* name_,
|
||||
__OSL_MASKED_OP(raytype_name)(void* bsg_, void* r_, void* name_,
|
||||
unsigned int mask_value)
|
||||
{
|
||||
auto* bsg = reinterpret_cast<BatchedShaderGlobals*>(bsg_);
|
||||
Wide<const ustringrep> wname(name_);
|
||||
Wide<const ustring> wname(name_);
|
||||
Mask mask(mask_value);
|
||||
|
||||
foreach_unique(wname, mask, [=](ustring name, Mask matching_lanes) -> void {
|
||||
|
||||
@@ -67,11 +67,11 @@ scramble(uint32_t v0, uint32_t v1 = 0, uint32_t v2 = 0)
|
||||
// clang-format off
|
||||
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
OSL_CONSTANT_DATA float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
static OSL_CONSTANT_DATA float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Gradient table for 2D. These could be programmed the Ken Perlin way with
|
||||
// some clever bit-twiddling, but this is more clear, and not really slower.
|
||||
OSL_CONSTANT_DATA float grad2lut[8][2] = {
|
||||
static OSL_CONSTANT_DATA float grad2lut[8][2] = {
|
||||
{ -1.0f, -1.0f }, { 1.0f, 0.0f }, { -1.0f, 0.0f }, { 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f }, { 0.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, -1.0f }
|
||||
};
|
||||
@@ -82,7 +82,7 @@ OSL_CONSTANT_DATA float grad2lut[8][2] = {
|
||||
// but these 12 (including 4 repeats to make the array length a power
|
||||
// of two) work better. They are not random, they are carefully chosen
|
||||
// to represent a small, isotropic set of directions.
|
||||
OSL_CONSTANT_DATA float grad3lut[16][3] = {
|
||||
static OSL_CONSTANT_DATA float grad3lut[16][3] = {
|
||||
{ 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, // 12 cube edges
|
||||
{ -1.0f, 0.0f, 1.0f }, { 0.0f, -1.0f, 1.0f },
|
||||
{ 1.0f, 0.0f, -1.0f }, { 0.0f, 1.0f, -1.0f },
|
||||
@@ -94,7 +94,7 @@ OSL_CONSTANT_DATA float grad3lut[16][3] = {
|
||||
};
|
||||
|
||||
// Gradient directions for 4D
|
||||
OSL_CONSTANT_DATA float grad4lut[32][4] = {
|
||||
static OSL_CONSTANT_DATA float grad4lut[32][4] = {
|
||||
{ 0.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, -1.0f }, { 0.0f, 1.0f, -1.0f, 1.0f }, { 0.0f, 1.0f, -1.0f, -1.0f }, // 32 tesseract edges
|
||||
{ 0.0f, -1.0f, 1.0f, 1.0f }, { 0.0f, -1.0f, 1.0f, -1.0f }, { 0.0f, -1.0f, -1.0f, 1.0f }, { 0.0f, -1.0f, -1.0f, -1.0f },
|
||||
{ 1.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f, -1.0f }, { 1.0f, 0.0f, -1.0f, 1.0f }, { 1.0f, 0.0f, -1.0f, -1.0f },
|
||||
@@ -108,7 +108,7 @@ OSL_CONSTANT_DATA float grad4lut[32][4] = {
|
||||
// A lookup table to traverse the simplex around a given point in 4D.
|
||||
// Details can be found where this table is used, in the 4D noise method.
|
||||
/* TODO: This should not be required, backport it from Bill's GLSL code! */
|
||||
OSL_CONSTANT_DATA unsigned char simplex[64][4] = {
|
||||
static OSL_CONSTANT_DATA unsigned char simplex[64][4] = {
|
||||
{0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0},
|
||||
{0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0},
|
||||
{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
|
||||
|
||||
@@ -521,8 +521,8 @@ OSLInput::open(const std::string& name, ImageSpec& newspec,
|
||||
exprcount++);
|
||||
std::string sourcecode = OIIO::Strutil::fmt::format(
|
||||
"shader {} (\n"
|
||||
" float s = u [[ int interpolated=1 ]],\n"
|
||||
" float t = v [[ int interpolated=1 ]],\n"
|
||||
" float s = u [[ int lockgeom=0 ]],\n"
|
||||
" float t = v [[ int lockgeom=0 ]],\n"
|
||||
" output color result = 0,\n"
|
||||
" output float alpha = 1,\n"
|
||||
" )\n"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
set (CMAKE_AUTOMOC ON)
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE OR Qt6_POSITION_INDEPENDENT_CODE)
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
set (osltoy_srcs
|
||||
@@ -13,17 +13,6 @@ set_target_properties (osltoy PROPERTIES FOLDER "Tools")
|
||||
target_link_libraries (osltoy
|
||||
PRIVATE
|
||||
oslexec
|
||||
$<TARGET_NAME_IF_EXISTS:Qt5::Core>
|
||||
$<TARGET_NAME_IF_EXISTS:Qt5::Gui>
|
||||
$<TARGET_NAME_IF_EXISTS:Qt5::Widgets>
|
||||
$<TARGET_NAME_IF_EXISTS:Qt6::Core>
|
||||
$<TARGET_NAME_IF_EXISTS:Qt6::Gui>
|
||||
$<TARGET_NAME_IF_EXISTS:Qt6::Widgets>
|
||||
Qt5::Core Qt5::Gui Qt5::Widgets
|
||||
${Boost_LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
if (Qt5_FOUND)
|
||||
target_compile_definitions(osltoy PRIVATE OSL_QT_MAJOR=5)
|
||||
endif ()
|
||||
if (Qt6_FOUND)
|
||||
target_compile_definitions(osltoy PRIVATE OSL_QT_MAJOR=6)
|
||||
endif ()
|
||||
install_targets (osltoy)
|
||||
|
||||
@@ -178,8 +178,7 @@ public:
|
||||
layout->addWidget(m_image);
|
||||
|
||||
m_info = new QLabel(this);
|
||||
m_info->setAlignment(
|
||||
static_cast<Qt::Alignment>(Qt::AlignTop | Qt::AlignLeft));
|
||||
m_info->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
m_info->setMinimumSize(textSize, m_res);
|
||||
layout->addWidget(m_info);
|
||||
|
||||
@@ -199,11 +198,7 @@ public:
|
||||
QWidget::hideEvent(e);
|
||||
}
|
||||
|
||||
#if OSL_QT_MAJOR < 6
|
||||
void enterEvent(QEvent* event) override;
|
||||
#else
|
||||
void enterEvent(QEnterEvent* event) override;
|
||||
#endif
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
};
|
||||
|
||||
@@ -298,11 +293,7 @@ public:
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* /*event*/) override { magnifierEvent(); }
|
||||
|
||||
#if OSL_QT_MAJOR < 6
|
||||
void enterEvent(QEvent* /*event*/) override
|
||||
#else
|
||||
void enterEvent(QEnterEvent* /*event*/) override
|
||||
#endif
|
||||
{
|
||||
if (shouldShowMagnifier())
|
||||
showMagnifier();
|
||||
@@ -352,11 +343,7 @@ public:
|
||||
};
|
||||
|
||||
void
|
||||
#if OSL_QT_MAJOR < 6
|
||||
Magnifier::enterEvent(QEvent* event)
|
||||
#else
|
||||
Magnifier::enterEvent(QEnterEvent* event)
|
||||
#endif
|
||||
{
|
||||
if (m_renderview)
|
||||
m_renderview->magnifierEvent();
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
#include <OSL/oslquery.h>
|
||||
#include <OSL/rendererservices.h>
|
||||
|
||||
#ifndef OSL_QT_MAJOR
|
||||
# error "Build problem? OSL_QT_MAJOR not defined."
|
||||
#endif
|
||||
|
||||
#include <QAction>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
|
||||
+20
-10
@@ -16,20 +16,30 @@ glass
|
||||
float eta = 1.5
|
||||
[[ string help = "Index of refraction",
|
||||
float min = 1, float max = 3 ]],
|
||||
int caustics = 0
|
||||
[[ string help = "Enable indirect lighting through glass",
|
||||
string widget = "checkBox" ]],
|
||||
int TIR = 0
|
||||
[[ string help = "Enable Total Internal Reflection",
|
||||
string widget = "checkBox" ]]
|
||||
)
|
||||
{
|
||||
// Take into account backfacing to invert eta accordingly
|
||||
if (backfacing()) {
|
||||
Ci = Cs * refraction(N, 1.0 / eta);
|
||||
// If Total Internal Reflection is enabled, we also return a
|
||||
// reflection closure, which might make rays bounce too much
|
||||
// inside an object. That's why we make it optional.
|
||||
if (TIR)
|
||||
Ci += Ks * reflection(N, 1.0 / eta);
|
||||
} else {
|
||||
Ci = Ks * reflection(N, eta) + Cs * refraction(N, eta);
|
||||
// If the current ray type is glossy or diffuse, that means we
|
||||
// are computing indirect lighting. Letting that interact with
|
||||
// glass produces caustics, which are normally hard to trace and
|
||||
// noisy. So we only return closures if that's not the case or
|
||||
// the "caustics" flag is on.
|
||||
if (caustics || (!raytype("glossy") && !raytype("diffuse"))) {
|
||||
// Take into account backfacing to invert eta accordingly
|
||||
if (backfacing()) {
|
||||
Ci = Cs * refraction(N, 1.0 / eta);
|
||||
// If Total Internal Reflection is enabled, we also return a
|
||||
// reflection closure, which might make rays bounce too much
|
||||
// inside an object. That's why we make it optional.
|
||||
if (TIR)
|
||||
Ci += Ks * reflection(N, 1.0 / eta);
|
||||
} else {
|
||||
Ci = Ks * reflection(N, eta) + Cs * refraction(N, eta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ set (testrender_srcs
|
||||
simpleraytracer.cpp
|
||||
testrender.cpp)
|
||||
|
||||
if (OSL_USE_OPTIX)
|
||||
if (USE_OPTIX)
|
||||
list (APPEND testrender_srcs optixraytracer.cpp)
|
||||
set (testrender_cuda_srcs
|
||||
cuda/quad.cu
|
||||
|
||||
@@ -265,7 +265,7 @@ rend_get_userdata(OSL::StringParam name, void* data, int data_size,
|
||||
|
||||
|
||||
__device__ int
|
||||
osl_bind_interpolated_param(void* sg_, OSL::StringParam name, long long type,
|
||||
osl_bind_interpolated_param(void* sg_, const void* name, long long type,
|
||||
int userdata_has_derivs, void* userdata_data,
|
||||
int symbol_has_derivs, void* symbol_data,
|
||||
int symbol_data_size, char* userdata_initialized,
|
||||
@@ -411,10 +411,10 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
|
||||
|
||||
__device__ int
|
||||
osl_range_check_err(int indexvalue, int length, OSL::ustring_pod symname,
|
||||
void* sg, OSL::ustring_pod sourcefile, int sourceline,
|
||||
OSL::ustring_pod groupname, int layer,
|
||||
OSL::ustring_pod layername, OSL::ustring_pod shadername)
|
||||
osl_range_check_err(int indexvalue, int length, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline,
|
||||
const char* groupname, int layer, const char* layername,
|
||||
const char* shadername)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
return indexvalue < 0 ? 0 : length - 1;
|
||||
@@ -425,10 +425,9 @@ osl_range_check_err(int indexvalue, int length, OSL::ustring_pod symname,
|
||||
|
||||
|
||||
__device__ int
|
||||
osl_range_check(int indexvalue, int length, OSL::ustring_pod symname, void* sg,
|
||||
OSL::ustring_pod sourcefile, int sourceline,
|
||||
OSL::ustring_pod groupname, int layer,
|
||||
OSL::ustring_pod layername, OSL::ustring_pod shadername)
|
||||
osl_range_check(int indexvalue, int length, const char* symname, void* sg,
|
||||
const void* sourcefile, int sourceline, const char* groupname,
|
||||
int layer, const char* layername, const char* shadername)
|
||||
{
|
||||
if (indexvalue < 0 || indexvalue >= length) {
|
||||
indexvalue = osl_range_check_err(indexvalue, length, symname, sg,
|
||||
|
||||
@@ -183,19 +183,14 @@ __closesthit__closest_hit_osl()
|
||||
sg.context = &shading_context;
|
||||
|
||||
// Run the OSL group and init functions
|
||||
auto sbtdata = reinterpret_cast<GenericData*>(optixGetSbtDataPointer());
|
||||
const unsigned int shaderInitOpIdx = 2u + 2u * sg.shaderID + 0u;
|
||||
const unsigned int shaderGroupIdx = 2u + 2u * sg.shaderID + 1u;
|
||||
// call osl_init_func
|
||||
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int, void*>(
|
||||
shaderInitOpIdx, &sg /*shaderglobals_ptr*/, params /*groupdata_ptr*/,
|
||||
nullptr /*userdata_base_ptr*/, nullptr /*output_base_ptr*/,
|
||||
0 /*shadeindex - unused*/, sbtdata->data /*interactive_params_ptr*/);
|
||||
// call osl_group_func
|
||||
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int, void*>(
|
||||
shaderGroupIdx, &sg /*shaderglobals_ptr*/, params /*groupdata_ptr*/,
|
||||
nullptr /*userdata_base_ptr*/, nullptr /*output_base_ptr*/,
|
||||
0 /*shadeindex - unused*/, sbtdata->data /*interactive_params_ptr*/);
|
||||
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int>(
|
||||
shaderInitOpIdx, &sg, params, nullptr, nullptr,
|
||||
0); // call osl_init_func
|
||||
optixDirectCall<void, ShaderGlobals*, void*, void*, void*, int>(
|
||||
shaderGroupIdx, &sg, params, nullptr, nullptr,
|
||||
0); // call osl_group_func
|
||||
|
||||
float3 result = process_closure((OSL::ClosureColor*)sg.Ci);
|
||||
uint3 launch_dims = optixGetLaunchDimensions();
|
||||
|
||||
@@ -111,42 +111,29 @@ OptixRaytracer::~OptixRaytracer()
|
||||
|
||||
|
||||
|
||||
void*
|
||||
OptixRaytracer::device_alloc(size_t size)
|
||||
uint64_t
|
||||
OptixRaytracer::register_global(const std::string& str, uint64_t value)
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
cudaError_t res = cudaMalloc(reinterpret_cast<void**>(&ptr), size);
|
||||
if (res != cudaSuccess) {
|
||||
errhandler().errorfmt("cudaMalloc({}) failed with error: {}\n", size,
|
||||
cudaGetErrorString(res));
|
||||
auto it = m_globals_map.find(ustring(str));
|
||||
if (it != m_globals_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return ptr;
|
||||
m_globals_map[ustring(str)] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OptixRaytracer::device_free(void* ptr)
|
||||
{
|
||||
cudaError_t res = cudaFree(ptr);
|
||||
if (res != cudaSuccess) {
|
||||
errhandler().errorfmt("cudaFree() failed with error: {}\n",
|
||||
cudaGetErrorString(res));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
OptixRaytracer::copy_to_device(void* dst_device, const void* src_host,
|
||||
size_t size)
|
||||
bool
|
||||
OptixRaytracer::fetch_global(const std::string& str, uint64_t* value)
|
||||
{
|
||||
cudaError_t res = cudaMemcpy(dst_device, src_host, size,
|
||||
cudaMemcpyHostToDevice);
|
||||
if (res != cudaSuccess) {
|
||||
errhandler().errorfmt(
|
||||
"cudaMemcpy host->device of size {} failed with error: {}\n", size,
|
||||
cudaGetErrorString(res));
|
||||
auto it = m_globals_map.find(ustring(str));
|
||||
|
||||
if (it != m_globals_map.end()) {
|
||||
*value = it->second;
|
||||
return true;
|
||||
}
|
||||
return dst_device;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -462,7 +449,6 @@ OptixRaytracer::make_optix_materials()
|
||||
|
||||
// Create materials
|
||||
int mtl_id = 0;
|
||||
std::vector<void*> material_interactive_params;
|
||||
for (const auto& groupref : shaders()) {
|
||||
std::string group_name, init_name, entry_name;
|
||||
shadingsys->getattribute(groupref.get(), "groupname", group_name);
|
||||
@@ -488,6 +474,7 @@ OptixRaytracer::make_optix_materials()
|
||||
std::string osl_ptx;
|
||||
shadingsys->getattribute(groupref.get(), "ptx_compiled_version",
|
||||
OSL::TypeDesc::PTR, &osl_ptx);
|
||||
|
||||
if (osl_ptx.empty()) {
|
||||
errhandler().errorfmt("Failed to generate PTX for ShaderGroup {}",
|
||||
group_name);
|
||||
@@ -499,11 +486,6 @@ OptixRaytracer::make_optix_materials()
|
||||
OIIO::Filesystem::write_text_file(filename, osl_ptx);
|
||||
}
|
||||
|
||||
void* interactive_params = nullptr;
|
||||
shadingsys->getattribute(groupref.get(), "device_interactive_params",
|
||||
TypeDesc::PTR, &interactive_params);
|
||||
material_interactive_params.push_back(interactive_params);
|
||||
|
||||
OptixModule optix_module;
|
||||
|
||||
// Create Programs from the init and group_entry functions,
|
||||
@@ -562,7 +544,6 @@ OptixRaytracer::make_optix_materials()
|
||||
final_groups.push_back(sphere_fillSG_dc);
|
||||
|
||||
// append the shader groups to our "official" list of program groups
|
||||
// size_t shader_groups_start_index = final_groups.size();
|
||||
final_groups.insert(final_groups.end(), shader_groups.begin(),
|
||||
shader_groups.end());
|
||||
|
||||
@@ -642,13 +623,6 @@ OptixRaytracer::make_optix_materials()
|
||||
sbt_records[sbtIndex++].data = reinterpret_cast<void*>(d_quads_list);
|
||||
sbt_records[sbtIndex++].data = reinterpret_cast<void*>(d_spheres_list);
|
||||
|
||||
// Fill in the data pointer for all the osl callables, starting at
|
||||
// sbtIndex and 2 for each of the materials.
|
||||
for (size_t i = 0, e = material_interactive_params.size(); i < e; ++i) {
|
||||
sbt_records[sbtIndex + 2 * i].data = material_interactive_params[i];
|
||||
sbt_records[sbtIndex + 2 * i + 1].data = material_interactive_params[i];
|
||||
}
|
||||
|
||||
const int nshaders = int(shader_groups.size());
|
||||
const int nhitgroups = (scene.quads.size() > 0)
|
||||
+ (scene.spheres.size() > 0);
|
||||
@@ -908,17 +882,16 @@ OptixRaytracer::good(TextureHandle* handle OSL_MAYBE_UNUSED)
|
||||
/// Given the name of a texture, return an opaque handle that can be
|
||||
/// used with texture calls to avoid the name lookups.
|
||||
RendererServices::TextureHandle*
|
||||
OptixRaytracer::get_texture_handle(ustringhash filename,
|
||||
ShadingContext* /*shading_context*/,
|
||||
const TextureOpt* options)
|
||||
OptixRaytracer::get_texture_handle(ustring filename OSL_MAYBE_UNUSED,
|
||||
ShadingContext* shading_context
|
||||
OSL_MAYBE_UNUSED)
|
||||
{
|
||||
auto itr = m_samplers.find(filename);
|
||||
if (itr == m_samplers.end()) {
|
||||
// Open image
|
||||
OIIO::ImageBuf image;
|
||||
if (!image.init_spec(ustring_from(filename), 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {} (hash {})",
|
||||
ustring_from(filename), filename);
|
||||
if (!image.init_spec(filename, 0, 0)) {
|
||||
errhandler().errorfmt("Could not load: {}", filename);
|
||||
return (TextureHandle*)nullptr;
|
||||
}
|
||||
|
||||
@@ -1099,7 +1072,7 @@ OptixRaytracer::processPrintfBuffer(void* buffer_data, size_t buffer_size)
|
||||
switch (format[j]) {
|
||||
case '%':
|
||||
// seems like a silly to print a '%', but it keeps the logic parallel with the other cases
|
||||
dst += snprintf(&buffer[dst], BufferSize - dst, "%s",
|
||||
dst += snprintf(&buffer[dst], BufferSize - dst,
|
||||
fmt_string.c_str());
|
||||
format_end_found = true;
|
||||
break;
|
||||
|
||||
@@ -25,7 +25,10 @@ public:
|
||||
OptixRaytracer();
|
||||
virtual ~OptixRaytracer();
|
||||
|
||||
int supports(string_view feature) const override
|
||||
uint64_t register_global(const std::string& str, uint64_t value);
|
||||
bool fetch_global(const std::string& str, uint64_t* value);
|
||||
|
||||
virtual int supports(string_view feature) const
|
||||
{
|
||||
if (feature == "OptiX")
|
||||
return true;
|
||||
@@ -35,25 +38,24 @@ public:
|
||||
std::string load_ptx_file(string_view filename);
|
||||
bool synch_attributes();
|
||||
|
||||
bool init_optix_context(int xres, int yres);
|
||||
bool make_optix_materials();
|
||||
bool finalize_scene();
|
||||
void prepare_render() override;
|
||||
void warmup() override;
|
||||
void render(int xres, int yres) override;
|
||||
void finalize_pixel_buffer() override;
|
||||
void clear() override;
|
||||
virtual bool init_optix_context(int xres, int yres);
|
||||
virtual bool make_optix_materials();
|
||||
virtual bool finalize_scene();
|
||||
virtual void prepare_render();
|
||||
virtual void warmup();
|
||||
virtual void render(int xres, int yres);
|
||||
virtual void finalize_pixel_buffer();
|
||||
virtual void clear();
|
||||
|
||||
/// Return true if the texture handle (previously returned by
|
||||
/// get_texture_handle()) is a valid texture that can be subsequently
|
||||
/// read or sampled.
|
||||
bool good(TextureHandle* handle) override;
|
||||
virtual bool good(TextureHandle* handle);
|
||||
|
||||
/// Given the name of a texture, return an opaque handle that can be
|
||||
/// used with texture calls to avoid the name lookups.
|
||||
TextureHandle* get_texture_handle(ustringhash filename,
|
||||
ShadingContext* shading_context,
|
||||
const TextureOpt* options) override;
|
||||
virtual TextureHandle* get_texture_handle(ustring filename,
|
||||
ShadingContext* shading_context);
|
||||
|
||||
// Easy way to do Optix calls
|
||||
optix::Context& optix_ctx() { return m_optix_ctx; }
|
||||
@@ -62,11 +64,6 @@ public:
|
||||
|
||||
void processPrintfBuffer(void* buffer_data, size_t buffer_size);
|
||||
|
||||
virtual void* device_alloc(size_t size) override;
|
||||
virtual void device_free(void* ptr) override;
|
||||
virtual void* copy_to_device(void* dst_device, const void* src_host,
|
||||
size_t size) override;
|
||||
|
||||
private:
|
||||
optix::Context m_optix_ctx = nullptr;
|
||||
|
||||
@@ -96,7 +93,8 @@ private:
|
||||
OptixProgramGroup* pg);
|
||||
|
||||
std::string m_materials_ptx;
|
||||
std::unordered_map<ustringhash, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<OIIO::ustring, optix::TextureSampler> m_samplers;
|
||||
std::unordered_map<OIIO::ustring, uint64_t> m_globals_map;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
# include <vector_functions.h> // from CUDA
|
||||
#endif
|
||||
@@ -43,24 +43,8 @@ ortho(const Vec3& n, Vec3& x, Vec3& y)
|
||||
|
||||
// Note: not used in OptiX mode
|
||||
struct Ray {
|
||||
enum RayType {
|
||||
CAMERA = 1,
|
||||
SHADOW = 2,
|
||||
REFLECTION = 4,
|
||||
REFRACTION = 8,
|
||||
DIFFUSE = 16,
|
||||
GLOSSY = 32,
|
||||
SUBSURFACE = 64,
|
||||
DISPLACEMENT = 128
|
||||
};
|
||||
|
||||
Ray(const Vec3& o, const Vec3& d, float radius, float spread,
|
||||
RayType raytype)
|
||||
: origin(o)
|
||||
, direction(d)
|
||||
, radius(radius)
|
||||
, spread(spread)
|
||||
, raytype(static_cast<int>(raytype))
|
||||
Ray(const Vec3& o, const Vec3& d, float radius, float spread)
|
||||
: origin(o), direction(d), radius(radius), spread(spread)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -88,7 +72,6 @@ struct Ray {
|
||||
|
||||
Vec3 origin, direction;
|
||||
float radius, spread;
|
||||
int raytype;
|
||||
};
|
||||
|
||||
|
||||
@@ -133,7 +116,7 @@ struct Camera {
|
||||
const float cos_a = dir.dot(v);
|
||||
const float spread
|
||||
= sqrtf(invw * invh * cx.length() * cy.length() * cos_a) * cos_a;
|
||||
return Ray(eye, v, 0, spread, Ray::CAMERA);
|
||||
return Ray(eye, v, 0, spread);
|
||||
}
|
||||
|
||||
// Specified by user:
|
||||
@@ -167,7 +150,7 @@ struct Primitive {
|
||||
void getBounds(float& minx, float& miny, float& minz, float& maxx,
|
||||
float& maxy, float& maxz) const;
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
virtual void setOptixVariables(void* data) const = 0;
|
||||
#endif
|
||||
|
||||
@@ -278,7 +261,7 @@ struct Sphere final : public Primitive {
|
||||
return 1 / (TWOPI * (1 - cmax));
|
||||
}
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
virtual void setOptixVariables(void* data) const
|
||||
{
|
||||
SphereParams* sphere_data = reinterpret_cast<SphereParams*>(data);
|
||||
@@ -377,7 +360,7 @@ struct Quad final : public Primitive {
|
||||
return d2 / (a * fabsf(dir.dot(n)));
|
||||
}
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
virtual void setOptixVariables(void* data) const
|
||||
{
|
||||
QuadParams* quad_data = reinterpret_cast<QuadParams*>(data);
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// Copyright Contributors to the Open Shading Language project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "optix_compat.h"
|
||||
|
||||
#if OSL_USE_OPTIX || defined(__CUDA_ARCH__)
|
||||
#if defined(OSL_USE_OPTIX) || defined(__CUDA_ARCH__)
|
||||
|
||||
struct RenderParams {
|
||||
float3 bad_color;
|
||||
@@ -67,12 +63,6 @@ struct QuadParams : PrimitiveParams {
|
||||
|
||||
|
||||
struct GenericData {
|
||||
// For geometry hit callables, data is the pointer to the array of
|
||||
// primitive params for that primitive type, and sbtGeoIndex is the index
|
||||
// for this primitive.
|
||||
//
|
||||
// For shader/material callables, data points to the interactive parameter
|
||||
// data arena for that material.
|
||||
void* data;
|
||||
unsigned int sbtGeoIndex;
|
||||
};
|
||||
@@ -82,7 +72,7 @@ struct GenericData {
|
||||
struct GenericRecord {
|
||||
__align__(
|
||||
OPTIX_SBT_RECORD_ALIGNMENT) char header[OPTIX_SBT_RECORD_HEADER_SIZE];
|
||||
// What follows should duplicate GenericData
|
||||
|
||||
void* data;
|
||||
unsigned int sbtGeoIndex;
|
||||
};
|
||||
|
||||
@@ -154,11 +154,10 @@ struct MxConductorParams : public MxMicrofacetBaseParams {
|
||||
|
||||
Color3 evalT(float cos_theta) const { return Color3(0.0f); }
|
||||
|
||||
// Avoid function was declared but never referenced
|
||||
// float get_ior() const
|
||||
// {
|
||||
// return 0; // no transmission possible
|
||||
// }
|
||||
float get_ior() const
|
||||
{
|
||||
return 0; // no transmission possible
|
||||
}
|
||||
};
|
||||
|
||||
struct MxGeneralizedSchlickParams : public MxMicrofacetBaseParams {
|
||||
|
||||
@@ -441,7 +441,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustringhash from, float /*time*/)
|
||||
ustring from, float /*time*/)
|
||||
{
|
||||
TransformMap::const_iterator found = m_named_xforms.find(from);
|
||||
if (found != m_named_xforms.end()) {
|
||||
@@ -468,7 +468,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustringhash from)
|
||||
ustring from)
|
||||
{
|
||||
// SimpleRaytracer doesn't understand motion blur, so we never fail
|
||||
// on account of time-varying transformations.
|
||||
@@ -485,7 +485,7 @@ SimpleRaytracer::get_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_inverse_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
|
||||
ustringhash to, float /*time*/)
|
||||
ustring to, float /*time*/)
|
||||
{
|
||||
if (to == u_camera || to == u_screen || to == u_NDC || to == u_raster) {
|
||||
// clang-format off
|
||||
@@ -544,15 +544,15 @@ void
|
||||
SimpleRaytracer::name_transform(const char* name, const OSL::Matrix44& xform)
|
||||
{
|
||||
std::shared_ptr<Transformation> M(new OSL::Matrix44(xform));
|
||||
m_named_xforms[ustringhash(name)] = M;
|
||||
m_named_xforms[ustring(name)] = M;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val)
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, int index, void* val)
|
||||
{
|
||||
AttrGetterMap::const_iterator g = m_attr_getters.find(name);
|
||||
if (g != m_attr_getters.end()) {
|
||||
@@ -572,8 +572,8 @@ SimpleRaytracer::get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val)
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val)
|
||||
{
|
||||
return get_array_attribute(sg, derivatives, object, type, name, -1, val);
|
||||
}
|
||||
@@ -581,7 +581,7 @@ SimpleRaytracer::get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
SimpleRaytracer::get_userdata(bool derivatives, ustring name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val)
|
||||
{
|
||||
// Just to illustrate how this works, respect s and t userdata, filled
|
||||
@@ -612,8 +612,8 @@ SimpleRaytracer::get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeInt) {
|
||||
((int*)val)[0] = OSL_VERSION;
|
||||
@@ -625,8 +625,8 @@ SimpleRaytracer::get_osl_version(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeIntArray2) {
|
||||
((int*)val)[0] = camera.xres;
|
||||
@@ -639,8 +639,8 @@ SimpleRaytracer::get_camera_resolution(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeString) {
|
||||
((ustring*)val)[0] = m_projection;
|
||||
@@ -652,8 +652,8 @@ SimpleRaytracer::get_camera_projection(ShaderGlobals* /*sg*/, bool /*derivs*/,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
@@ -668,8 +668,8 @@ SimpleRaytracer::get_camera_fov(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_pixelaspect;
|
||||
@@ -683,8 +683,8 @@ SimpleRaytracer::get_camera_pixelaspect(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float*)val)[0] = m_hither;
|
||||
@@ -699,8 +699,8 @@ SimpleRaytracer::get_camera_clip(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_hither;
|
||||
@@ -714,8 +714,8 @@ SimpleRaytracer::get_camera_clip_near(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_yon;
|
||||
@@ -730,8 +730,8 @@ SimpleRaytracer::get_camera_clip_far(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float*)val)[0] = m_shutter[0];
|
||||
@@ -746,8 +746,8 @@ SimpleRaytracer::get_camera_shutter(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_shutter[0];
|
||||
@@ -761,8 +761,8 @@ SimpleRaytracer::get_camera_shutter_open(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float*)val)[0] = m_shutter[1];
|
||||
@@ -776,8 +776,8 @@ SimpleRaytracer::get_camera_shutter_close(ShaderGlobals* /*sg*/, bool derivs,
|
||||
|
||||
bool
|
||||
SimpleRaytracer::get_camera_screen_window(ShaderGlobals* /*sg*/, bool derivs,
|
||||
ustringhash /*object*/, TypeDesc type,
|
||||
ustringhash /*name*/, void* val)
|
||||
ustring /*object*/, TypeDesc type,
|
||||
ustring /*name*/, void* val)
|
||||
{
|
||||
// N.B. in a real renderer, this may be time-dependent
|
||||
if (type == TypeFloatArray4) {
|
||||
@@ -823,7 +823,6 @@ SimpleRaytracer::globals_from_hit(ShaderGlobals& sg, const Ray& r,
|
||||
sg.N = -sg.N;
|
||||
sg.Ng = -sg.Ng;
|
||||
}
|
||||
sg.raytype = r.raytype;
|
||||
sg.flipHandedness = sg.dPdx.cross(sg.dPdy).dot(sg.N) < 0;
|
||||
|
||||
// In our SimpleRaytracer, the "renderstate" itself just a pointer to
|
||||
@@ -832,16 +831,13 @@ SimpleRaytracer::globals_from_hit(ShaderGlobals& sg, const Ray& r,
|
||||
}
|
||||
|
||||
Vec3
|
||||
SimpleRaytracer::eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx,
|
||||
int bounce)
|
||||
SimpleRaytracer::eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx)
|
||||
{
|
||||
ShaderGlobals sg;
|
||||
memset((char*)&sg, 0, sizeof(ShaderGlobals));
|
||||
sg.I = dir.val();
|
||||
sg.dIdx = dir.dx();
|
||||
sg.dIdy = dir.dy();
|
||||
if (bounce >= 0)
|
||||
sg.raytype = bounce > 0 ? Ray::DIFFUSE : Ray::CAMERA;
|
||||
shadingsys->execute(*ctx, *m_shaders[backgroundShaderID], sg);
|
||||
return process_background_closure(sg.Ci);
|
||||
}
|
||||
@@ -863,7 +859,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
if (!scene.intersect(r, t, id)) {
|
||||
// we hit nothing? check background shader
|
||||
if (backgroundShaderID >= 0) {
|
||||
if (b > 0 && backgroundResolution > 0) {
|
||||
if (backgroundResolution > 0) {
|
||||
float bg_pdf = 0;
|
||||
Vec3 bg = background.eval(r.direction, bg_pdf);
|
||||
path_radiance
|
||||
@@ -873,7 +869,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
} else {
|
||||
// we aren't importance sampling the background - so just run it directly
|
||||
path_radiance += path_weight
|
||||
* eval_background(r.direction, ctx, b);
|
||||
* eval_background(r.direction, ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -935,8 +931,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
b.pdf);
|
||||
if ((contrib.x + contrib.y + contrib.z) > 0) {
|
||||
int shadow_id = id;
|
||||
Ray shadow_ray = Ray(sg.P, bg_dir.val(), radius, 0,
|
||||
Ray::SHADOW);
|
||||
Ray shadow_ray = Ray(sg.P, bg_dir.val(), radius, 0);
|
||||
Dual2<float> shadow_dist;
|
||||
if (!scene.intersect(shadow_ray, shadow_dist,
|
||||
shadow_id)) // ray reached the background?
|
||||
@@ -961,7 +956,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
* MIS::power_heuristic<MIS::EVAL_WEIGHT>(light_pdf,
|
||||
b.pdf);
|
||||
if ((contrib.x + contrib.y + contrib.z) > 0) {
|
||||
Ray shadow_ray = Ray(sg.P, ldir, radius, 0, Ray::SHADOW);
|
||||
Ray shadow_ray = Ray(sg.P, ldir, radius, 0);
|
||||
// trace a shadow ray and see if we actually hit the target
|
||||
// in this tiny renderer, tracing a ray is probably cheaper than evaluating the light shader
|
||||
int shadow_id = id; // ignore self hit
|
||||
@@ -984,8 +979,7 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
// trace indirect ray and continue
|
||||
BSDF::Sample p = result.bsdf.sample(-sg.I, xi, yi, zi);
|
||||
path_weight *= p.weight;
|
||||
bsdf_pdf = p.pdf;
|
||||
r.raytype = Ray::DIFFUSE; // FIXME? Use DIFFUSE for all indiirect rays
|
||||
bsdf_pdf = p.pdf;
|
||||
r.direction = p.wi;
|
||||
r.radius = radius;
|
||||
// Just simply use roughness as spread slope
|
||||
|
||||
@@ -30,23 +30,23 @@ public:
|
||||
virtual ~SimpleRaytracer() {}
|
||||
|
||||
// RendererServices support:
|
||||
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform, float time) override;
|
||||
bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustringhash from,
|
||||
float time) override;
|
||||
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform) override;
|
||||
bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustringhash from) override;
|
||||
bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result, ustringhash to,
|
||||
float time) override;
|
||||
bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, int index, void* val) override;
|
||||
bool get_attribute(ShaderGlobals* sg, bool derivatives, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val) override;
|
||||
bool get_userdata(bool derivatives, ustringhash name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val) override;
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform, float time);
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustring from,
|
||||
float time);
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
TransformationPtr xform);
|
||||
virtual bool get_matrix(ShaderGlobals* sg, Matrix44& result, ustring from);
|
||||
virtual bool get_inverse_matrix(ShaderGlobals* sg, Matrix44& result,
|
||||
ustring to, float time);
|
||||
virtual bool get_array_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, int index, void* val);
|
||||
virtual bool get_attribute(ShaderGlobals* sg, bool derivatives,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
virtual bool get_userdata(bool derivatives, ustring name, TypeDesc type,
|
||||
ShaderGlobals* sg, void* val);
|
||||
|
||||
void name_transform(const char* name, const Transformation& xform);
|
||||
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
float m_screen_window[4];
|
||||
|
||||
int backgroundShaderID = -1;
|
||||
int backgroundResolution = 1024;
|
||||
int backgroundResolution = 0;
|
||||
int aa = 1;
|
||||
int max_bounces = 1000000;
|
||||
int rr_depth = 5;
|
||||
@@ -121,7 +121,7 @@ private:
|
||||
bool m_had_error = false;
|
||||
|
||||
// Named transforms
|
||||
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
|
||||
typedef std::map<ustring, std::shared_ptr<Transformation>> TransformMap;
|
||||
TransformMap m_named_xforms;
|
||||
|
||||
// Attribute and userdata retrieval -- for fast dispatch, use a hash
|
||||
@@ -130,50 +130,43 @@ private:
|
||||
// renderer, we would encourage benchmarking various methods and
|
||||
// alternate data structures.
|
||||
typedef bool (SimpleRaytracer::*AttrGetter)(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object,
|
||||
TypeDesc type, ustringhash name,
|
||||
void* val);
|
||||
typedef std::unordered_map<ustringhash, AttrGetter> AttrGetterMap;
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, void* val);
|
||||
typedef std::unordered_map<ustring, AttrGetter> AttrGetterMap;
|
||||
AttrGetterMap m_attr_getters;
|
||||
|
||||
// Attribute getters
|
||||
bool get_osl_version(ShaderGlobals* sg, bool derivs, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val);
|
||||
bool get_camera_resolution(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_projection(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_fov(ShaderGlobals* sg, bool derivs, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val);
|
||||
bool get_camera_pixelaspect(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_clip(ShaderGlobals* sg, bool derivs, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val);
|
||||
bool get_camera_clip_near(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_camera_clip_far(ShaderGlobals* sg, bool derivs, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val);
|
||||
bool get_camera_shutter(ShaderGlobals* sg, bool derivs, ustringhash object,
|
||||
TypeDesc type, ustringhash name, void* val);
|
||||
bool get_camera_shutter_open(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
bool get_osl_version(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_resolution(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_projection(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_fov(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_pixelaspect(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_clip(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_clip_near(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_clip_far(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_shutter(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_shutter_open(ShaderGlobals* sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void* val);
|
||||
bool get_camera_shutter_close(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
bool get_camera_screen_window(ShaderGlobals* sg, bool derivs,
|
||||
ustringhash object, TypeDesc type,
|
||||
ustringhash name, void* val);
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
void* val);
|
||||
|
||||
// CPU renderer helpers
|
||||
void globals_from_hit(ShaderGlobals& sg, const Ray& r,
|
||||
const Dual2<float>& t, int id);
|
||||
Vec3 eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx,
|
||||
int bounce = -1);
|
||||
Vec3 eval_background(const Dual2<Vec3>& dir, ShadingContext* ctx);
|
||||
Color3 subpixel_radiance(float x, float y, Sampler& sampler,
|
||||
ShadingContext* ctx);
|
||||
Color3 antialias_pixel(int x, int y, ShadingContext* ctx);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "shading.h"
|
||||
#include "simpleraytracer.h"
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include "optixraytracer.h"
|
||||
#endif
|
||||
|
||||
@@ -87,6 +87,7 @@ set_shadingsys_options()
|
||||
shadingsys->attribute("llvm_optimize", llvm_opt);
|
||||
|
||||
shadingsys->attribute("profile", int(profile));
|
||||
shadingsys->attribute("lockgeom", 1);
|
||||
shadingsys->attribute("debug_nan", debugnan);
|
||||
shadingsys->attribute("debug_uninit", debug_uninit);
|
||||
shadingsys->attribute("userdata_isconnected", userdata_isconnected);
|
||||
@@ -100,11 +101,6 @@ set_shadingsys_options()
|
||||
shadingsys->attribute("llvm_debugging_symbols", 1);
|
||||
shadingsys->attribute("llvm_profiling_events", 1);
|
||||
|
||||
// We rely on the default set of "raytypes" tags. To use a custom set,
|
||||
// this is where we would do:
|
||||
// shadingsys->attribute("raytypes", TypeDesc(TypeDesc::STRING, num_raytypes),
|
||||
// raytype_names);
|
||||
|
||||
shadingsys_options_set = true;
|
||||
}
|
||||
|
||||
@@ -234,7 +230,7 @@ main(int argc, const char* argv[])
|
||||
aa = aaoverride;
|
||||
|
||||
SimpleRaytracer* rend = nullptr;
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
if (use_optix)
|
||||
rend = new OptixRaytracer;
|
||||
else
|
||||
@@ -267,7 +263,7 @@ main(int argc, const char* argv[])
|
||||
// Setup common attributes
|
||||
set_shadingsys_options();
|
||||
|
||||
#if OSL_USE_OPTIX
|
||||
#ifdef OSL_USE_OPTIX
|
||||
if (use_optix)
|
||||
reinterpret_cast<OptixRaytracer*>(rend)->synch_attributes();
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user