Compare commits
142
Commits
dev-1.13.2
...
release
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0be867f7bf | ||
|
|
362b01ecdd | ||
|
|
657dab9da0 | ||
|
|
26ad18688d | ||
|
|
a5857c5525 | ||
|
|
e2a3153667 | ||
|
|
34fa5c3755 | ||
|
|
67a3c0b93c | ||
|
|
60dcec97e7 | ||
|
|
cf47571daa | ||
|
|
c9672c8a0d | ||
|
|
e8fce16d36 | ||
|
|
76f187e4d0 | ||
|
|
7678df2971 | ||
|
|
9ffb5fb2a3 | ||
|
|
f61edf2fdf | ||
|
|
b2190faa27 | ||
|
|
35aa264dc8 | ||
|
|
5c1617fec2 | ||
|
|
f1c2299ff7 | ||
|
|
c7aee41a1c | ||
|
|
79ab666246 | ||
|
|
c8b59032fb | ||
|
|
0a9070cb62 | ||
|
|
80dee64963 | ||
|
|
901bea3aac | ||
|
|
b7a1a87dc7 | ||
|
|
0c60a1a170 | ||
|
|
98cc66a2e2 | ||
|
|
5592be9f11 | ||
|
|
517d10934f | ||
|
|
8ac55309ab | ||
|
|
c882e823c1 | ||
|
|
a5777fddc5 | ||
|
|
c14bcd2785 | ||
|
|
a23c42fcc6 | ||
|
|
434f04d336 | ||
|
|
a1002c61c1 | ||
|
|
92b0135971 | ||
|
|
3896d22a21 | ||
|
|
500381cc64 | ||
|
|
b2b5e5eaba | ||
|
|
8e420b4bc8 | ||
|
|
a90ed53f88 | ||
|
|
7ee3e36dbb | ||
|
|
18d79314df | ||
|
|
6f9c907db8 | ||
|
|
b20183d13e | ||
|
|
cdbc05a2b2 | ||
|
|
b218c1853b | ||
|
|
a2b9334422 | ||
|
|
c17553af3f | ||
|
|
b08c484bca | ||
|
|
e5f0833d51 | ||
|
|
6979f995d9 | ||
|
|
a0c3665725 | ||
|
|
b88122e7ca | ||
|
|
100490bf8d | ||
|
|
7130058741 | ||
|
|
7394f997db | ||
|
|
f7399cee8e | ||
|
|
5dd94cf83d | ||
|
|
78ba7b8f0d | ||
|
|
2dd1883f95 | ||
|
|
410c04ead8 | ||
|
|
a31fba5505 | ||
|
|
98587dfdf8 | ||
|
|
822518f920 | ||
|
|
442b265940 | ||
|
|
09bfd07da7 | ||
|
|
74a53ff545 | ||
|
|
6ae6aef389 | ||
|
|
4a44416156 | ||
|
|
a30b4f4290 | ||
|
|
f31791b23a | ||
|
|
4a9fc9cc87 | ||
|
|
3e6c52366b | ||
|
|
a014de80fe | ||
|
|
e8bbd79b70 | ||
|
|
b75ce26416 | ||
|
|
c193b0753e | ||
|
|
cf725983de | ||
|
|
fc16c8dde2 | ||
|
|
257ca66afe | ||
|
|
fde2a3e5ee | ||
|
|
6906daebdc | ||
|
|
d80bbaa50a | ||
|
|
a1a77b86ab | ||
|
|
267c93104b | ||
|
|
d08f476b3c | ||
|
|
7e9ddadc0f | ||
|
|
0cdf072c22 | ||
|
|
9f033074fa | ||
|
|
6d9db5a761 | ||
|
|
6cd6849580 | ||
|
|
db1dcc1053 | ||
|
|
af15fb3b3d | ||
|
|
9e9acd1592 | ||
|
|
60975da4e2 | ||
|
|
c25cdd4eab | ||
|
|
01284d3af8 | ||
|
|
c0185c1482 | ||
|
|
93866b7c77 | ||
|
|
d9db605bed | ||
|
|
13d2c1914f | ||
|
|
61d10d6aaf | ||
|
|
3601a3fd1c | ||
|
|
2d6210a893 | ||
|
|
26e8da310b | ||
|
|
07b2d9fb15 | ||
|
|
6c06652cfd | ||
|
|
4ee62cd2ef | ||
|
|
68c67633f5 | ||
|
|
6f65f91b49 | ||
|
|
475a109281 | ||
|
|
91eb43227a | ||
|
|
8c2a10268f | ||
|
|
ec8ec11cfd | ||
|
|
61bb9ac11e | ||
|
|
bd7d138f04 | ||
|
|
38015b6be2 | ||
|
|
d42c5d3e1d | ||
|
|
162b355bc8 | ||
|
|
d383680521 | ||
|
|
95ed032dcd | ||
|
|
0c5544e4dc | ||
|
|
54844fe68d | ||
|
|
760561d74e | ||
|
|
354eb8576c | ||
|
|
a725f2b97e | ||
|
|
29e8d0bf50 | ||
|
|
422c0966a6 | ||
|
|
9b706d30bf | ||
|
|
ceda8c0d23 | ||
|
|
b561a67ad1 | ||
|
|
4e34e8dd20 | ||
|
|
905058ee13 | ||
|
|
d3e443b766 | ||
|
|
d860eae924 | ||
|
|
71a518e9a5 | ||
|
|
2bbd6610c8 | ||
|
|
5bcee23e34 |
@@ -6,3 +6,40 @@ bdb473cbdb119f3d9060d48f75f965cbd45f6d7a
|
||||
|
||||
# More clang-format: liboslquery, oslinfo, oslc, osl.imageio, osltoy (#1220)
|
||||
bf366d7a90c46599b82071dac6dbef7c5e3ca157
|
||||
|
||||
# Turn on clang-format for cpp files in testsuite (#1269)
|
||||
00c895fc642eb89685797c292048bdff15d675e7
|
||||
5e848fb761261521a3ee7cd8a4f6814f32fe4a47
|
||||
|
||||
# CI: Change our clang-format standard to clang11 (#1372)
|
||||
91d22ebe2f65d4ed0599e421172a15d99fe0e1b4
|
||||
|
||||
# More clang-format (this time, testrender and liboslnoise) (#1511)
|
||||
08706b7cbac781b6a9389780428016be985d9d89
|
||||
|
||||
# clang-format #1509
|
||||
b4026fd1695c08532557b3ba1c2142323087ccf9
|
||||
1f73b075c99861afa42fac44567b37f797bc72f2
|
||||
7f2e83794e6fa63d5180653cffb77be2cc38b32b
|
||||
28399fefc890442b5ac020e7a90cee0d5bf9f03c
|
||||
e56851056d33233b0bb8324faac251907099961a
|
||||
1c57fc61d8ab7c3f309be4335e4c71c26399edd4
|
||||
46d451ce74d00e904874df476ebeca19bb119ea9
|
||||
c1045f2c2845a98e661c7181932a031eb3c76063
|
||||
|
||||
# More clang-format (#1512)
|
||||
8c6ffdd911b9eb7db4adf41ab88891360452d7c5
|
||||
|
||||
# style: more clang-format (#1515)
|
||||
102430c83554fe7e328cd8c3317db00507bcfaba
|
||||
|
||||
# Revert some formatting (#1518)
|
||||
21eac9d9215d071b0a7b9ce2c32f189ed0c62c4a
|
||||
|
||||
# Another round of clang-format (#1540)
|
||||
38015b6be28643254aea530154b7860136cf5e15
|
||||
89d5db2b5c5fda79184d8245d903e580fc6a4e9c
|
||||
|
||||
# clang-format: the very last piece of the puzzle (#1555)
|
||||
4ee62cd2ef05543f818f4d95a19efc1d684a7381
|
||||
5be7c6bd4e7bd2e560cb6be8c06f11985384a87a
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# Copyright 2008-present Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
name: Analysis
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run nightly while we're still working our way through the warnings
|
||||
- cron: "0 8 * * *"
|
||||
# Run unconditionally once weekly
|
||||
# - cron: "0 0 * * 0"
|
||||
push:
|
||||
branches:
|
||||
# - master
|
||||
- '*analysis*'
|
||||
# Allow manual kicking off of the workflow from github.com
|
||||
workflow_dispatch:
|
||||
|
||||
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:
|
||||
|
||||
aswf:
|
||||
name: "SonarCloud Analysis"
|
||||
if: |
|
||||
github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: sonar gcc9/C++14 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: static-analysis-sonar
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
cxx_std: 14
|
||||
python_ver: 3.9
|
||||
pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b16_AVX512
|
||||
coverage: 1
|
||||
# skip_tests: 1
|
||||
sonar: 1
|
||||
setenvs: export SONAR_SCANNER_VERSION=4.7.0.2747
|
||||
SONAR_SERVER_URL="https://sonarcloud.io"
|
||||
BUILD_WRAPPER_OUT_DIR=bw_output
|
||||
OSL_CMAKE_BUILD_WRAPPER="build-wrapper-linux-x86-64 --out-dir bw_output"
|
||||
CMAKE_BUILD_TYPE=Debug
|
||||
CMAKE_UNITY_BUILD=OFF
|
||||
CODECOV=1
|
||||
TESTRENDER_AA=1
|
||||
OSL_TESTSUITE_SKIP_DIFF=1
|
||||
CTEST_TEST_TIMEOUT=1200
|
||||
OSL_CMAKE_FLAGS="-DOSL_TEST_BIG_TIMEOUT=1200"
|
||||
CTEST_EXCLUSIONS="broken|noise-reg.regress|noise-gabor-reg.regress"
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
container:
|
||||
image: aswf/ci-osl:${{matrix.vfxyear}}${{matrix.vfxsuffix}}
|
||||
env:
|
||||
CXX: ${{matrix.cxx_compiler}}
|
||||
CC: ${{matrix.cc_compiler}}
|
||||
CMAKE_CXX_STANDARD: ${{matrix.cxx_std}}
|
||||
USE_SIMD: ${{matrix.simd}}
|
||||
FMT_VERSION: ${{matrix.fmt_ver}}
|
||||
OPENEXR_VERSION: ${{matrix.openexr_ver}}
|
||||
PYBIND11_VERSION: ${{matrix.pybind11_ver}}
|
||||
PYTHON_VERSION: ${{matrix.python_ver}}
|
||||
# DEBUG_CI: 1
|
||||
steps:
|
||||
# We would like to use harden-runner, but it flags too many false
|
||||
# positives, every time we download a dependency. We should use it only
|
||||
# on CI runs where we are producing artifacts that users might rely on.
|
||||
# - name: Harden Runner
|
||||
# uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813 # v1.4.3
|
||||
# with:
|
||||
# egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_keys
|
||||
run: echo "::set-output name=date::`date -u +'%Y-%m-%dT%H:%M:%SZ'`"
|
||||
- name: ccache
|
||||
id: ccache
|
||||
uses: actions/cache@c3f1317a9e7b1ef106c153ac8c0f00fed3ddbc0d # v3.0.4
|
||||
with:
|
||||
path: /tmp/ccache
|
||||
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
|
||||
restore-keys: ${{github.job}}-
|
||||
- name: Build setup
|
||||
run: |
|
||||
${{matrix.setenvs}}
|
||||
src/build-scripts/ci-startup.bash
|
||||
- name: Dependencies
|
||||
run: |
|
||||
${{matrix.depcmds}}
|
||||
src/build-scripts/gh-installdeps.bash
|
||||
- name: Build
|
||||
run: src/build-scripts/ci-build.bash
|
||||
- name: Testsuite
|
||||
if: matrix.skip_tests != '1'
|
||||
run: src/build-scripts/ci-test.bash
|
||||
- name: Code coverage
|
||||
if: matrix.coverage == '1'
|
||||
run: src/build-scripts/ci-coverage.bash
|
||||
- name: Sonar-scanner
|
||||
if: matrix.sonar == 1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner -X --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="build/bw_output" --define sonar.cfamily.gcov.reportsPath="_coverage"
|
||||
+174
-95
@@ -20,8 +20,12 @@ on:
|
||||
- '**.rst'
|
||||
- '**.tex'
|
||||
schedule:
|
||||
# Full nightly build
|
||||
# Full nightly build, for the main project repo (not for forks)
|
||||
- cron: "0 6 * * *"
|
||||
if: github.repository == 'AcademySoftwareFoundation/OpenShadingLanguage'
|
||||
|
||||
|
||||
permissions: read-all
|
||||
|
||||
|
||||
jobs:
|
||||
@@ -32,20 +36,20 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: gcc6/C++14 llvm9 py2.7 boost1.66 exr2.3 oiio2.2 sse2
|
||||
- desc: gcc6/C++14 llvm9 py2.7 boost1.66 exr2.3 oiio2.3 sse2
|
||||
nametag: linux-vfx2019
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2019-clang9
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang9
|
||||
cxx_std: 14
|
||||
openimageio_ver: v2.2.17.0
|
||||
python_ver: 2.7
|
||||
pybind11_ver: v2.4.2
|
||||
- desc: clang9/C++14 llvm9 oiio-release boost1.66 avx2 exr2.3 py2.7
|
||||
nametag: linux-clang9-llvm9
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-20.04
|
||||
container: aswftesting/ci-osl:2019-clang9
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang9
|
||||
cc_compiler: clang
|
||||
cxx_compiler: clang++
|
||||
cxx_std: 14
|
||||
@@ -56,18 +60,20 @@ jobs:
|
||||
- desc: GPU Cuda10 gcc6/C++14 llvm10 py2.7 boost-1.70 exr-2.3 OIIO-master avx2
|
||||
nametag: linux-optix7-2019
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2019-clang10
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang10
|
||||
cxx_std: 14
|
||||
openimageio_ver: master
|
||||
python_ver: 2.7
|
||||
# pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
skip_tests: 1
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DUSE_OPTIX=1" OPTIX_VERSION=7.0
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=8.1.1
|
||||
- desc: gcc6/C++14 llvm10 py3.7 boost1.70 exr2.4 oiio2.2 sse4
|
||||
nametag: linux-vfx2020
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2020
|
||||
vfxyear: 2020
|
||||
cxx_std: 14
|
||||
openimageio_ver: v2.2.17.0
|
||||
@@ -75,22 +81,22 @@ jobs:
|
||||
pybind11_ver: v2.5.0
|
||||
simd: sse4.2
|
||||
setenvs: export CONAN_LLVM_VERSION=10.0.1
|
||||
- desc: gcc9/C++17 llvm11 py3.7 boost1.73 exr2.5 oiio2.2 avx2 batch-b8avx2
|
||||
- desc: gcc9/C++17 llvm11 py3.7 boost1.73 exr2.5 oiio2.3 avx2 batch-b8avx2
|
||||
nametag: linux-vfx2021
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2021-clang11
|
||||
vfxyear: 2021
|
||||
vfxsuffix: -clang11
|
||||
cxx_std: 17
|
||||
openimageio_ver: dev-2.2
|
||||
openimageio_ver: v2.2.21.0
|
||||
python_ver: 3.7
|
||||
pybind11_ver: v2.7.0
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2_noFMA
|
||||
- desc: gcc9/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
- desc: gcc9/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio-rel avx2
|
||||
nametag: linux-vfx2022
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang13
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
cxx_std: 17
|
||||
openimageio_ver: release
|
||||
python_ver: 3.9
|
||||
@@ -100,8 +106,8 @@ jobs:
|
||||
- desc: clang12/C++17 llvm12 oiio-master boost1.73 exr3.1 py3.9 avx2 batch-avx512
|
||||
nametag: linux-clang12-llvm12-batch
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang12
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang12
|
||||
cxx_std: 17
|
||||
openimageio_ver: master
|
||||
python_ver: 3.9
|
||||
@@ -109,10 +115,11 @@ jobs:
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: USE_OPENVDB=0
|
||||
- desc: icc/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
- desc: icc/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio-master avx2
|
||||
nametag: linux-icc
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang14
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
cc_compiler: icc
|
||||
cxx_compiler: icpc
|
||||
cxx_std: 17
|
||||
@@ -125,10 +132,11 @@ jobs:
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DSTOP_ON_WARNING=OFF -DEXTRA_CPP_ARGS=-fp-model=consistent"
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=7.1.3
|
||||
USE_OPENVDB=0
|
||||
- desc: icx/C++17 llvm13 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
- desc: icx/C++17 llvm14 py3.9 boost1.76 exr3.1 oiio2.3 avx2
|
||||
nametag: linux-icx
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang14
|
||||
vfxyear: 2022
|
||||
vfxsuffix: -clang13
|
||||
cc_compiler: icx
|
||||
cxx_compiler: icpx
|
||||
cxx_std: 17
|
||||
@@ -139,11 +147,22 @@ jobs:
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2_noFMA
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DSTOP_ON_WARNING=OFF" USE_OPENVDB=0
|
||||
- desc: oldest everything gcc6/C++14 llvm9 py2.7 boost1.66 oiio2.2 no-simd exr2.3
|
||||
- desc: gcc11/C++17 llvm15 py3.10 boost1.80 exr3.1 oiio-rel avx2
|
||||
nametag: linux-vfx2023
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2023-clang15
|
||||
vfxyear: 2023
|
||||
cxx_std: 17
|
||||
openimageio_ver: release
|
||||
python_ver: "3.10"
|
||||
pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2
|
||||
- desc: oldest everything gcc6/C++14 llvm9 py2.7 boost1.66 oiio2.3 no-simd exr2.3
|
||||
nametag: linux-oldest
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2019-clang9
|
||||
vfxyear: 2019
|
||||
vfxsuffix: -clang9
|
||||
cxx_std: 14
|
||||
openimageio_ver: v2.2.17.0
|
||||
python_ver: 2.7
|
||||
@@ -151,9 +170,69 @@ jobs:
|
||||
simd: 0
|
||||
setenvs: export PUGIXML_VERSION=v1.8
|
||||
|
||||
# Address and leak sanitizers
|
||||
- desc: sanitizers
|
||||
nametag: sanitizer
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang13
|
||||
vfxyear: 2022
|
||||
cc_compiler: clang
|
||||
cxx_compiler: clang++
|
||||
cxx_std: 17
|
||||
openimageio_ver: master
|
||||
python_ver: 3.9
|
||||
pybind11_ver: v2.9.0
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2
|
||||
setenvs: export OSL_CMAKE_FLAGS="-DSANITIZE=address -DOSL_TEST_BIG_TIMEOUT=1200"
|
||||
CMAKE_BUILD_TYPE=Debug
|
||||
CTEST_TEST_TIMEOUT=1200
|
||||
CTEST_EXCLUSIONS="broken|noise-reg.regress|noise-gabor-reg.regress|example-.*deformer|spline-reg.regress.batched|osl-imageio"
|
||||
OSL_OPTIONS=llvm_debugging_symbols=1
|
||||
TESTRENDER_AA=1
|
||||
OSL_TESTSUITE_SKIP_DIFF=1
|
||||
# Sanitizer notes:
|
||||
# - There are a handful of tests we disable entirely with
|
||||
# CTEST_EXCLUSIONS because they are irrelevant or just cannot be
|
||||
# made to be clean (and that's ok).
|
||||
# - Tests with sanitizers run slow, so we increase timeouts, and
|
||||
# also set AA to 1 for render tests to speed them up.
|
||||
# OSL_TESTSUITE_SKIP_DIFF prevents making the AA=1 image result
|
||||
# fail, but that's ok because every other CI test is checking
|
||||
# the results; here we have no reason to believe results will
|
||||
# differ from other tests, we just need to run with sanitizers
|
||||
# turned on.
|
||||
# - In testing.cmake, we rig texture tests to disable the leak
|
||||
# sanitizer, because we can't eliminate some completely benign
|
||||
# leaks from the texture system, and because they are called
|
||||
# from JITed code, we don't get a clean stack trace of things
|
||||
# that happen in OIIO and therefore we just can't enumerate the
|
||||
# allowed exceptions. So we trust that OIIO itself tests the
|
||||
# texture system adequately and is able to ignore the benign
|
||||
# "leaks."
|
||||
|
||||
# Test formatting. This test entry doesn't do a full build, it
|
||||
# just runs clang-format on everything, and passes if nothing is
|
||||
# misformatted. Upon failure, the build artifact will be the full
|
||||
# source code with the formatting fixed (diffs will also appear in
|
||||
# the console output).
|
||||
- desc: "clang-format"
|
||||
nametag: clang-format
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2022-clang14
|
||||
vfxyear: 2022
|
||||
cxx_std: 17
|
||||
openimageio_ver: release
|
||||
python_ver: 3.9
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2
|
||||
skip_tests: 1
|
||||
setenvs: export BUILDTARGET=clang-format
|
||||
OPENIMAGEIO_CMAKE_FLAGS=-DUSE_PYTHON=0
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
container:
|
||||
image: aswftesting/ci-osl:${{matrix.vfxyear}}${{matrix.vfxsuffix}}
|
||||
image: ${{ matrix.container }}
|
||||
env:
|
||||
CXX: ${{matrix.cxx_compiler}}
|
||||
CC: ${{matrix.cc_compiler}}
|
||||
@@ -166,13 +245,20 @@ jobs:
|
||||
USE_BATCHED: ${{matrix.batched}}
|
||||
USE_SIMD: ${{matrix.simd}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# We would like to use harden-runner, but it flags too many false
|
||||
# positives, every time we download a dependency. We should use it only
|
||||
# on CI runs where we are producing artifacts that users might rely on.
|
||||
# - name: Harden Runner
|
||||
# uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813 # v1.4.3
|
||||
# with:
|
||||
# egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_keys
|
||||
run: echo "::set-output name=date::`date -u +'%Y-%m-%dT%H:%M:%SZ'`"
|
||||
- name: ccache
|
||||
id: ccache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@c3f1317a9e7b1ef106c153ac8c0f00fed3ddbc0d # v3.0.4
|
||||
with:
|
||||
path: /tmp/ccache
|
||||
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
|
||||
@@ -198,7 +284,7 @@ jobs:
|
||||
- name: Testsuite
|
||||
if: matrix.skip_tests != '1'
|
||||
run: src/build-scripts/ci-test.bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
|
||||
if: failure()
|
||||
with:
|
||||
name: osl-${{github.job}}-${{matrix.nametag}}
|
||||
@@ -216,11 +302,11 @@ jobs:
|
||||
include:
|
||||
- desc: Debug gcc7/C++14 llvm9 py2.7 oiio2.3 exr2.4 sse4 boost1.65 exr2.4
|
||||
nametag: linux-debug-gcc7-llvm9
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-7
|
||||
cxx_std: 14
|
||||
openexr_ver: v2.4.3
|
||||
openimageio_ver: dev-2.3
|
||||
openimageio_ver: v2.3.21.0
|
||||
pybind11_ver: v2.6.2
|
||||
python_ver: 2.7
|
||||
simd: sse4.2
|
||||
@@ -230,7 +316,7 @@ jobs:
|
||||
CTEST_TEST_TIMEOUT=240
|
||||
- desc: gcc10/C++17 llvm10 oiio-release boost1.65 exr2.5 avx2
|
||||
nametag: linux-2021ish-gcc10-llvm10
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-10
|
||||
cxx_std: 17
|
||||
fmt_ver: 7.0.1
|
||||
@@ -242,32 +328,32 @@ jobs:
|
||||
setenvs: export LLVM_VERSION=10.0.0
|
||||
OPENIMAGEIO_CMAKE_FLAGS="-DBUILD_FMT_VERSION=7.0.1"
|
||||
PUGIXML_VERSION=v1.10
|
||||
- desc: latest releases gcc11/C++17 llvm13 boost1.71 exr3.1 py3.8 avx2 batch-b16avx512
|
||||
- desc: latest releases gcc11/C++17 llvm13 boost1.71 exr3.1 py3.9 avx2 batch-b16avx512
|
||||
nametag: linux-latest-releases
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
cxx_compiler: g++-11
|
||||
cxx_std: 17
|
||||
fmt_ver: 8.1.1
|
||||
openexr_ver: v3.1.5
|
||||
fmt_ver: 9.1.0
|
||||
openexr_ver: v3.1.7
|
||||
openimageio_ver: master
|
||||
pybind11_ver: v2.9.2
|
||||
python_ver: 3.8
|
||||
pybind11_ver: v2.10.0
|
||||
python_ver: "3.10"
|
||||
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.1.2
|
||||
PUGIXML_VERSION=v1.11.4
|
||||
- desc: bleeding edge gcc11/C++17 llvm14 oiio/ocio/exr/pybind-master boost1.71 py3.9 avx2 batch-b16avx512
|
||||
OPENCOLORIO_VERSION=v2.2.0
|
||||
PUGIXML_VERSION=v1.13
|
||||
- desc: bleeding edge gcc12/C++17 llvm14 oiio/ocio/exr/pybind-master boost1.71 py3.10 avx2 batch-b16avx512
|
||||
nametag: linux-bleeding-edge
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: g++-11
|
||||
os: ubuntu-22.04
|
||||
cxx_compiler: g++-12
|
||||
cxx_std: 17
|
||||
fmt_ver: master
|
||||
openexr_ver: main
|
||||
openimageio_ver: master
|
||||
pybind11_ver: master
|
||||
python_ver: 3.9
|
||||
python_ver: "3.10"
|
||||
simd: avx2,f16c
|
||||
batched: b8_AVX2,b8_AVX512,b16_AVX512
|
||||
setenvs: export LLVM_VERSION=14.0.0
|
||||
@@ -275,13 +361,13 @@ jobs:
|
||||
OPENCOLORIO_VERSION=main
|
||||
PUGIXML_VERSION=master
|
||||
- desc: clang14/C++17 llvm14 boost1.71 exr3.1 py3.8 avx2 batch-b16avx512
|
||||
nametag: linux-latest-releases
|
||||
nametag: linux-latest-releases-clang
|
||||
os: ubuntu-20.04
|
||||
cxx_compiler: clang++
|
||||
cc_compiler: clang
|
||||
cxx_std: 17
|
||||
fmt_ver: 8.1.1
|
||||
openexr_ver: v3.1.5
|
||||
openexr_ver: v3.1.7
|
||||
openimageio_ver: master
|
||||
pybind11_ver: v2.9.2
|
||||
python_ver: 3.8
|
||||
@@ -305,13 +391,20 @@ jobs:
|
||||
USE_BATCHED: ${{matrix.batched}}
|
||||
USE_SIMD: ${{matrix.simd}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# We would like to use harden-runner, but it flags too many false
|
||||
# positives, every time we download a dependency. We should use it only
|
||||
# on CI runs where we are producing artifacts that users might rely on.
|
||||
# - name: Harden Runner
|
||||
# uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813 # v1.4.3
|
||||
# with:
|
||||
# egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_keys
|
||||
run: echo "::set-output name=date::`date -u +'%Y-%m-%dT%H:%M:%SZ'`"
|
||||
- name: ccache
|
||||
id: ccache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@c3f1317a9e7b1ef106c153ac8c0f00fed3ddbc0d # v3.0.4
|
||||
with:
|
||||
path: /tmp/ccache
|
||||
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
|
||||
@@ -329,7 +422,7 @@ jobs:
|
||||
- name: Testsuite
|
||||
if: matrix.skip_tests != '1'
|
||||
run: src/build-scripts/ci-test.bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
|
||||
if: failure()
|
||||
with:
|
||||
name: osl-${{github.job}}-${{matrix.nametag}}
|
||||
@@ -342,88 +435,74 @@ jobs:
|
||||
macos:
|
||||
name: "${{matrix.os}} appleclang${{matrix.aclang}}/C++${{matrix.cxx_std}} py${{matrix.python_ver}} ${{matrix.desc}}"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: llvm11
|
||||
os: macos-10.15
|
||||
nametag: macos10-py39
|
||||
cxx_std: 14
|
||||
python_ver: 3.9
|
||||
aclang: 12
|
||||
- desc: llvm11
|
||||
- desc: MacOS-11
|
||||
os: macos-11
|
||||
nametag: macos11-py39
|
||||
cc_compiler: /usr/local/opt/llvm@14/bin/clang
|
||||
cxx_compiler: /usr/local/opt/llvm@14/bin/clang++
|
||||
cxx_std: 17
|
||||
python_ver: 3.9
|
||||
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
|
||||
cc_compiler: /usr/local/opt/llvm@15/bin/clang
|
||||
cxx_compiler: /usr/local/opt/llvm@15/bin/clang++
|
||||
cxx_std: 17
|
||||
python_ver: "3.10"
|
||||
aclang: 13
|
||||
setenvs: export LLVMBREWVER="@15" DO_BREW_UPDATE=1
|
||||
OPENIMAGEIO_VERSION=master
|
||||
runs-on: ${{matrix.os}}
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CXX: ${{matrix.cxx_compiler}}
|
||||
CC: ${{matrix.cc_compiler}}
|
||||
CMAKE_CXX_STANDARD: ${{matrix.cxx_std}}
|
||||
PYTHON_VERSION: ${{matrix.python_ver}}
|
||||
OPENIMAGEIO_VERSION: ${{matrix.openimageio_ver}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_keys
|
||||
run: echo "::set-output name=date::`date -u +'%Y-%m-%dT%H:%M:%SZ'`"
|
||||
- name: ccache
|
||||
id: ccache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@c3f1317a9e7b1ef106c153ac8c0f00fed3ddbc0d # v3.0.4
|
||||
with:
|
||||
path: /Users/runner/.ccache
|
||||
key: ${{github.job}}-${{matrix.os}}-${{steps.ccache_cache_keys.outputs.date}}
|
||||
restore-keys: ${{github.job}}-${{matrix.os}}-
|
||||
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
|
||||
restore-keys: ${{github.job}}-${{matrix.nametag}}-
|
||||
- name: Build setup
|
||||
run: src/build-scripts/ci-startup.bash
|
||||
run: |
|
||||
${{matrix.setenvs}}
|
||||
src/build-scripts/ci-startup.bash
|
||||
- name: Dependencies
|
||||
run: |
|
||||
source src/build-scripts/install_homebrew_deps.bash
|
||||
# OPENIMAGEIO_CMAKE_FLAGS="-DOIIO_BUILD_TESTS=0 -DUSE_OPENGL=0"
|
||||
# source src/build-scripts/build_openimageio.bash
|
||||
brew install --display-times -q openimageio
|
||||
PYTHONPATH=$PYTHONPATH:/usr/local/python${PYTHON_VERSION}/site-packages
|
||||
if [[ "$OPENIMAGEIO_VERSION" != "" ]] ; then \
|
||||
OPENIMAGEIO_CMAKE_FLAGS="-DOIIO_BUILD_TESTS=0 -DUSE_OPENGL=0" ; \
|
||||
source src/build-scripts/build_openimageio.bash ; \
|
||||
else \
|
||||
brew install --display-times -q openimageio ; \
|
||||
PYTHONPATH=$PYTHONPATH:/usr/local/python${PYTHON_VERSION}/site-packages ; \
|
||||
fi
|
||||
src/build-scripts/save-env.bash
|
||||
- name: Build
|
||||
run: |
|
||||
src/build-scripts/ci-build.bash
|
||||
- name: Testsuite
|
||||
run: src/build-scripts/ci-test.bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
|
||||
if: failure()
|
||||
with:
|
||||
name: osl-${{github.job}}
|
||||
name: osl-${{github.job}}-${{matrix.nametag}}
|
||||
path: |
|
||||
build/*.cmake
|
||||
build/CMake*
|
||||
build/testsuite/*/*.*
|
||||
|
||||
|
||||
clang-format:
|
||||
# Test formatting. This test entry doesn't do a full build, it just runs
|
||||
# clang-format on everything, and passes if nothing is misformatted.
|
||||
# Upon failure, the build artifact will be the full source code with the
|
||||
# formatting fixed (diffs will also appear in the console output).
|
||||
name: "clang-format verification"
|
||||
runs-on: ubuntu-18.04
|
||||
container:
|
||||
image: aswf/ci-osl:2021-clang11
|
||||
env:
|
||||
BUILDTARGET: run-clang-format
|
||||
CMAKE_CXX_STANDARD: 17
|
||||
PYTHON_VERSION: 3.7
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build setup
|
||||
run: |
|
||||
src/build-scripts/ci-startup.bash
|
||||
- name: Dependencies
|
||||
run: |
|
||||
src/build-scripts/gh-installdeps.bash
|
||||
- name: Build
|
||||
run: |
|
||||
src/build-scripts/ci-build.bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: osl-${{github.job}}
|
||||
path: src/*/*.{cpp,h}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
name: Scorecards supply-chain security
|
||||
on:
|
||||
# Only the default branch is supported.
|
||||
branch_protection_rule:
|
||||
schedule:
|
||||
- cron: '44 20 * * 6'
|
||||
push:
|
||||
branches: [ "main", "scorecard" ]
|
||||
|
||||
# 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
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # v3.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@3e15ea8318eee9b333819ec77a36aca8d39df13e # v1.1.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecards on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
# repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
|
||||
|
||||
# Publish the results for public repositories to enable scorecard badges. For more details, see
|
||||
# https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories, `publish_results` will automatically be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -9,4 +9,5 @@ build
|
||||
*.pyc
|
||||
*.log
|
||||
.vscode
|
||||
.envrc
|
||||
|
||||
|
||||
@@ -50,4 +50,4 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
|
||||
- [X] License scan completed and no issues found
|
||||
- Minor issues were found but already fixed in PR https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/pull/1145
|
||||
- [X] Code repository imported to ASWF GitHub organization
|
||||
- [ ] Developer Certificate of Origin past commit signoff done and DCO Probot enabled.
|
||||
- [X] Developer Certificate of Origin post commit signoff done and DCO Probot enabled.
|
||||
|
||||
+168
-9
@@ -1,8 +1,133 @@
|
||||
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
|
||||
<!-- Copyright Contributors to the Open Shading Language Project. -->
|
||||
|
||||
Release 1.12 -- ?? (compared to 1.11)
|
||||
--------------------------------------------------
|
||||
Release 1.12.13.0 -- 1 July 2023 (compared to 1.12.12.0)
|
||||
--------------------------------------------------------
|
||||
- *fix*: Fix constant float values being converted to ints
|
||||
[#1674](https://github.com/OpenImageIO/oiio/pull/1674) (by Declan Russell)
|
||||
- *build* Fix builds when USE_PYTHON=OFF
|
||||
[#1675](https://github.com/OpenImageIO/oiio/pull/1675) (by Declan Russell)
|
||||
- *build* Changes to support fmt 10.0
|
||||
[#1691](https://github.com/OpenImageIO/oiio/pull/1691)
|
||||
- *cleanup* Switch deprecated oiio simd names to modern
|
||||
[#1679](https://github.com/OpenImageIO/oiio/pull/1679)
|
||||
- *testing*: Avoid deprecated OSLQuery ctr in test example
|
||||
[#1699](https://github.com/OpenImageIO/oiio/pull/1699)
|
||||
- *ci*: Fix package name for icc
|
||||
[#1690](https://github.com/OpenImageIO/oiio/pull/1690)
|
||||
- *ci*: Add VFX Platform 2023 tests using new ASWF containers
|
||||
[#1696](https://github.com/OpenImageIO/oiio/pull/1696)
|
||||
- *ci*: Switch oiio obsolete branch names to immutable tags
|
||||
[#1701](https://github.com/OpenImageIO/oiio/pull/1701)
|
||||
- *docs* Improve documentation of `trace` function
|
||||
[#1671](https://github.com/OpenImageIO/oiio/pull/1671) (by AidanWelch)
|
||||
- *docs* README.md: added filmography and Siggraph OSL course info.
|
||||
[#1692](https://github.com/OpenImageIO/oiio/pull/1692)
|
||||
[#1694](https://github.com/OpenImageIO/oiio/pull/1694) (by Mitch Prater)
|
||||
- *docs* Amend the filmography
|
||||
[#1695](https://github.com/OpenImageIO/oiio/pull/1695)
|
||||
- *docs* Fix incorrect links in CONTRIBUTING
|
||||
[#1688](https://github.com/OpenImageIO/oiio/pull/1688)
|
||||
|
||||
|
||||
Release 1.12.12.0 -- 1 May 2023 (compared to 1.12.11.0)
|
||||
--------------------------------------------------------
|
||||
* New ShadingSystem getattribute query for shader groups: "attribute_types"
|
||||
retrieves a pointer to the array of TypeDesc values describing the
|
||||
attributes retrieved by existing "attributes_needed" and "attribute_scopes".
|
||||
#1650
|
||||
* Fix a bug with binding userdata when it's used by more than one shader
|
||||
within the group and they disagree about whether derivatives are needed when
|
||||
retrieving the attribute. #1673
|
||||
|
||||
Release 1.12.11.0 -- 5 Apr 2023 (compared to 1.12.10.0)
|
||||
--------------------------------------------------------
|
||||
* Build: Add Qt 6.x compatibility (Qt is only used for `osltoy`). #1655
|
||||
* Build: more careful about paths to look for LLVM. #1656
|
||||
* Build: Fix Cuda compilation flags for LLVM 15. #1659
|
||||
* Notice: OSL does not yet build properly against the newly release LLVM 16.
|
||||
You must use LLVM 9-15. For Mac users who get their llvm from Homebrew,
|
||||
please be aware that Homebrew has changed its default llvm to 16, so you'll
|
||||
need to `brew install llvm@14` and make your OSL CMake define:
|
||||
`-DLLVM_ROOT=/usr/local/opt/llvm@14`
|
||||
|
||||
Release 1.12.10.0 -- 1 Mar 2023 (compared to 1.12.9.0)
|
||||
--------------------------------------------------------
|
||||
* feat(testrender): Modify testrender so that it correctly sets raytype to
|
||||
"camera" for camera rays, "shadow" for shadow rays, and "diffuse" for all
|
||||
secondary rays. Also rerun the shades for background shader group on the
|
||||
camera rays rather than use the cached map. This helps the MaterialX project
|
||||
use testrender for certain unit tests and verification. #1648 #1649
|
||||
* feat: Expose llvm groupdata size as a shadergroup attribute
|
||||
"llvm_groupdata_size". #1642
|
||||
* fix: Crash could result from uncaught exception in OpenColorIO when calling
|
||||
transformc with derivatives for color spaces that require OCIO. #1646
|
||||
* fix: certain uses of fmod() in shaders could fail to generate LLVM code
|
||||
correctly, due to a missing implementation for the fmod(triple,float)
|
||||
varieties. #1643
|
||||
* build: Change snprintf formatting to satisfy some compilers. #1640
|
||||
* CI: Fix broken Mac ci. #1647
|
||||
|
||||
Release 1.12.9.0 -- 1 Feb 2023 (compared to 1.12.8.0)
|
||||
-------------------------------------------------------
|
||||
* Remove unnecessary setting of locale::global. #1630
|
||||
* Batch shading: Fix bug with masked wide closure generation. #1637
|
||||
* Make sure ReParameter() has the same relaxed type checking rules as
|
||||
Parameter(). Before, it was stricter about type conversion. #1639
|
||||
* Windows: Fix some GPU build errors. #1638
|
||||
|
||||
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:
|
||||
* **Batch shading**: A fully operational "batch shading" support when using
|
||||
CPUs supporting the Intel AVX2 or AVX512 instruction set architectures,
|
||||
allows shading 8 or 16 points at a time, accelerated by using SIMD
|
||||
instructions. (Changes contributed by Intel.)
|
||||
* **OptiX**: A reasonable subset of the OSL language can run on NVIDIA GPUs
|
||||
for Cuda or OptiX-based renderers.
|
||||
* **Standardized material closures**: Synchronize with MaterialX on a minimum
|
||||
standard set of material closures. This is reflected in both the OSL spec as
|
||||
well as reference implementations of those closures in testrender. #1533
|
||||
#1536 #1537 #1538 #1539 #1541 #1542 #1547 #1557
|
||||
|
||||
Dependency and standards requirements changes:
|
||||
* The minimum (and default) compilation mode is now C++14. C++17 and 20 are
|
||||
also supported. #1362 #1369 (1.12.2)
|
||||
@@ -33,6 +158,8 @@ OSL Standard library:
|
||||
* Fix previously-broken color conversions from RGB to xyY. #1410 (1.12.3)
|
||||
* Fully removed MaterialX shaders (get those from the MaterialX project).
|
||||
#1450 (1.12.3)
|
||||
* Fix incorrect implementation of `matrix4 * vector4` in vector4.h #1513
|
||||
(1.12.5.0)
|
||||
|
||||
API changes, new options, new ShadingSystem features (for renderer writers):
|
||||
* Custom experimental llvm optimization levels 10, 11, 12, and 13. These
|
||||
@@ -58,7 +185,7 @@ API changes, new options, new ShadingSystem features (for renderer writers):
|
||||
triggered for those cases that cannot be resolved by the end of the "runtime
|
||||
optimization" phase. #1497 (1.12.4.6)
|
||||
|
||||
Continued work on experimental SIMD batched shading mode:
|
||||
SIMD batched shading mode:
|
||||
* Added support for masked operations to LLVMUtil. #1248 #1250 (1.12.0.0)
|
||||
* Add interface to ShadingSystem for batched execution. #1272 (1.12.0.1)
|
||||
* Add interface to batched RendererServices. #1276 (1.12.0.1)
|
||||
@@ -83,8 +210,11 @@ Continued work on experimental SIMD batched shading mode:
|
||||
* Batched isnan, isinf, isfinite. #1456 (1.12.4.2)
|
||||
* Batched userdata and output placement. #1455 (1.12.4.2)
|
||||
* Batched pointcloud functions. #1464 (1.12.4.4)
|
||||
* Batched closures #1500
|
||||
* Fix overrunning allocation region in debug common_ancestor_between. #1577
|
||||
(1.12.6.1)
|
||||
|
||||
Continued work on experimental OptiX rendering:
|
||||
OptiX rendering:
|
||||
* Explicitly set the OptiX pipeline stack size. #1254 (1.12.0.0)
|
||||
* CI tests now at least compile and build with USE_OPTIX=1 (though not yet
|
||||
run the tests). #1281 (1.12.0.1)
|
||||
@@ -101,10 +231,12 @@ Continued work on experimental OptiX rendering:
|
||||
* Fix race conditions when compiling for OptiX 7. #1411 (1.12.3)
|
||||
* osl_get_attribute() uses device strings when compiling for OptiX.
|
||||
#1435 (1.12.3)
|
||||
* Fix issue with OptiX + clang 14 with duplicate symbols. #1561 (1.12.6.0)
|
||||
|
||||
Performance improvements:
|
||||
* Less mutex locking around use and retrieval of ColorSystem related to
|
||||
doing color transforms. #1405 (1.12.3)
|
||||
* Constant folding of `startswith()`. #1507 (1.12.5.0)
|
||||
|
||||
Bug fixes and other improvements (internals):
|
||||
* Fix derivatives of texture calls when only derivatives of the "alpha"
|
||||
@@ -142,8 +274,16 @@ Bug fixes and other improvements (internals):
|
||||
* Print all 4 levels of version numbers in help messages. #1477 (1.12.4.4)
|
||||
* Fix GPU code generation crash. #1479 (1.12.4.4)
|
||||
* Work to transition internals to use modern std::format notation for
|
||||
formatted output. #1487 #1490 (1.12.4.6)
|
||||
* Fix testrender memory error on teardown. #1499 (1.12.4.6)
|
||||
formatted output. #1487 #1490 (1.12.4.6) #1504 #1506 (1.12.5.0)
|
||||
* testrender improvements:
|
||||
* Fix testrender memory error on teardown. #1499 (1.12.4.6)
|
||||
* Modernize the sampler in testrender, improving quality and performance.
|
||||
#1534 (1.12.6.0)
|
||||
* Switch to cone tracing for derivatives. #1543 (1.12.6.0)
|
||||
* Fix error that prevented correct typecheck of ternary operator. #1552
|
||||
(1.12.6.0)
|
||||
* Fix bug where assigning an init-op param its default value as an instance
|
||||
value would get lost. #1578 (1.12.6.1)
|
||||
|
||||
Internals/developer concerns:
|
||||
* Use the `final` keyword in certain internal classes where applicable.
|
||||
@@ -167,6 +307,12 @@ Internals/developer concerns:
|
||||
to be used in OSL 1.12. #1494 (1.12.5.0)
|
||||
* Work on gradually converting printf-style formatted strings to fmt /
|
||||
std::format style. #1493 (1.12.5.0)
|
||||
* LLVM_Util: allow naming of llvm symbols to help with IR debugging. #1530
|
||||
(1.12.6.0)
|
||||
* clang-format the code base. #1508 #1509 #1511 #1512 #1515 #1518 #1540
|
||||
(1.12.5.0) #1555 #1562 #1568 (1.12.6.0)
|
||||
* A round of spell-checking all the comments in the code base. #1550
|
||||
(1.12.5.0)
|
||||
|
||||
Build & test system improvements:
|
||||
* CMake build system and scripts:
|
||||
@@ -206,14 +352,17 @@ Build & test system improvements:
|
||||
(1.12.4.1)
|
||||
- Make exported cmake configs relocatable by using relative paths. #1466
|
||||
(1.12.4.4)
|
||||
- Make the version number be a cmake cache variable. #1579 (1.12.6.1)
|
||||
* Dependency version support:
|
||||
- Build properly against Cuda 11 and OptiX 7.1. #1232 (1.12.0.1)
|
||||
and up to OptiX 7.4 #1559 (1.12.6.0)
|
||||
- PugiXML build fixes on some systems. #1262 (1.12.0.1/1.11.8)
|
||||
- Cuda/OptiX back end: Add `__CUDADEVRT_INTERNAL__` define to bitcode
|
||||
generation, needed to avoid duplicate cudaMalloc symbols with CUDA9+
|
||||
#1271 (1.12.0.1)
|
||||
- Build against LLVM 11 #1274 (1.12.0.1), LLVM 12 #1351 (1.12.1.0)
|
||||
#1412 (1.12.3), LLVM 13 #1420 (1.12.3), LLVM 14 #1492 (1.12.4.6)
|
||||
LLVM 15 #1592 (1.12.6.2)
|
||||
- Fix build break against recent OIIO master change where m_mutex field
|
||||
was removed from ImageInput. #1281 (1.12.0.1/1.11.9)
|
||||
- Work to ensure that OIIO will build correctly against the upcoming
|
||||
@@ -232,6 +381,8 @@ Build & test system improvements:
|
||||
compilers. #1459 #1473 #1475. (1.12.4.4)
|
||||
- Fixes for recent OIIO TextureSystem changes that hide Imath types.
|
||||
#1476 (1.12.4.4)
|
||||
- Changes to work correctly with OpenImageIO 2.4 and its master being
|
||||
the start of 2.5. #1569 (1.12.6.0)
|
||||
* Testing and Continuous integration (CI) systems:
|
||||
- Eliminate the old Travis CI and Appveyor. #1334 #1338 (1.12.1)
|
||||
- Use ccache + GitHub 'cache' action to greatly speed up CI runs. #1335
|
||||
@@ -240,14 +391,15 @@ Build & test system improvements:
|
||||
scripts for CentOS and Ubuntu ito a single script. #1338 (1.12.1)
|
||||
- CI tests clang11, also batched shading with clang. #1379 (1.12.2)
|
||||
- CI speeds up OIIO builds by not building its tests. #1380 (1.12.2)
|
||||
- CI tests gcc11. #1381 (1.12.2)
|
||||
- CI tests gcc11 #1381 (1.12.2) and gcc12 #1565 (1.12.6)
|
||||
- Deal with OpenColorIO changing its master branch to "main". #1429
|
||||
(1.12.3)
|
||||
- Fix tests for texture3d now that OIIO has dropped support for Field3D.
|
||||
#1437 (1.12.3)
|
||||
- Test against LLVM13/clang13 for the VFX Platform 2022 tests. #1434
|
||||
(1.12.3)
|
||||
- Test against MacOS-11. #1434 (1.12.3)
|
||||
- CI test against MacOS-11 #1434 (1.12.3) and MacOS-12 #1554 (1.12.6)
|
||||
#1522 (1.12.5)
|
||||
- Add testsuite coverage of environment(). #1438 (1.12.3)
|
||||
- Use a project-specific environment variable `OSL_CI` instead of the more
|
||||
generic `CI` to avoid clashes with other systems. #1446 (1.12.3)
|
||||
@@ -262,6 +414,10 @@ Build & test system improvements:
|
||||
#1501 (1.12.5.0)
|
||||
- Overhaul of GHA ci.yml to use strategy matrix. #1474 (1.12.4.4)
|
||||
- Test against clang 14 and fix new warnings. #1498 (1.12.5.0)
|
||||
- Test against clang 15 and fix new warnings. #1586 (1.12.6.2)
|
||||
- A scorecards workflow guards against a variety of security issues of
|
||||
the CI system itself. #1529 (1.12.6.0)
|
||||
- Enable SonarCloud static analysis. #1551 #1556 #1563 (1.12.6.0)
|
||||
* Platform support:
|
||||
- Various Windows compile fixes. #1263 #1285 (1.12.0.1)
|
||||
- Windows+Cuda build fixes. #1292 (1.12.0.1)
|
||||
@@ -281,6 +437,9 @@ Documentation:
|
||||
#1326 (1.12.1)
|
||||
* Fix missing explanation of the optional "errormessage" parameter to
|
||||
environment() and texture3d(). #1442 (1.12.3/1.11.17)
|
||||
* A SECURITY.md file explains how to confidentially report vulnerabilities.
|
||||
#1529 (1.12.6)
|
||||
* Document all the new MaterialX closures. #1564
|
||||
|
||||
|
||||
|
||||
@@ -748,7 +907,7 @@ Build & test system improvements:
|
||||
use clang library components for preprocessing. #1089 (1.11.3)
|
||||
* Add an optional build-time `EXTRA_WARNINGS` option (default: OFF) that
|
||||
enables even more picky than usual warnings. Fix many warnings that cropped
|
||||
up during testing, mostly related to unused function paramters. #1106 (1.11.3)
|
||||
up during testing, mostly related to unused function parameters. #1106 (1.11.3)
|
||||
* The testsuite can run in parallel, with a number of threads set by the
|
||||
environment variable `CTEST_PARALLEL_LEVEL`. #1119 (1.11.4)
|
||||
* oslconfig.h is now generated by a cmake configure_file step, from
|
||||
|
||||
+17
-4
@@ -3,18 +3,27 @@
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
project (OSL VERSION 1.12.5.0
|
||||
|
||||
set (OSL_VERSION "1.12.13.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 ()
|
||||
|
||||
project (OSL VERSION ${OSL_VERSION}
|
||||
LANGUAGES CXX C
|
||||
HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/OpenShadingLanguage")
|
||||
set (PROJ_NAME ${PROJECT_NAME}) # short name
|
||||
string (TOLOWER ${PROJ_NAME} PROJ_NAME_LOWER) # short name lower case
|
||||
string (TOUPPER ${PROJ_NAME} PROJ_NAME_UPPER) # short name upper case
|
||||
set (PROJECT_VERSION_RELEASE_TYPE "dev" CACHE STRING
|
||||
set (PROJECT_VERSION_RELEASE_TYPE "" CACHE STRING
|
||||
"Build type, for example: dev, beta2, RC1 (empty string for normal release)")
|
||||
set (${PROJECT_NAME}_VERSION_RELEASE_TYPE ${PROJECT_VERSION_RELEASE_TYPE})
|
||||
set (PROJECT_AUTHORS "Contributors to the Open Shading Language project")
|
||||
option (${PROJECT_NAME}_SUPPORTED_RELEASE
|
||||
"Set ON for supported release branch, OFF for master" OFF)
|
||||
"Set ON for supported release branch, OFF for master" ON)
|
||||
if (${PROJECT_NAME}_SUPPORTED_RELEASE)
|
||||
set (${PROJECT_NAME}_DEV_RELEASE OFF)
|
||||
else ()
|
||||
@@ -125,6 +134,10 @@ endif ()
|
||||
# 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
|
||||
@@ -212,7 +225,7 @@ if (OSL_BUILD_PLUGINS)
|
||||
add_subdirectory (src/osl.imageio)
|
||||
endif ()
|
||||
|
||||
if (USE_QT AND Qt5_FOUND)
|
||||
if (USE_QT AND (Qt5_FOUND OR Qt6_FOUND))
|
||||
add_subdirectory (src/osltoy)
|
||||
endif ()
|
||||
|
||||
|
||||
+15
-11
@@ -55,13 +55,13 @@ Contributor License Agreement (CLA) and Intellectual Property
|
||||
To protect the project -- and the contributors! -- we do require a
|
||||
Contributor License Agreement (CLA) for anybody submitting changes.
|
||||
|
||||
* [Corporate CLA](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/ASWF/OSL-CLA-corporate.md)
|
||||
* [Corporate CLA](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/blob/main/ASWF/CLA-corporate.md)
|
||||
If you are writing the code as part of your job, or if there is any
|
||||
possibility that your employers might think they own any intellectual
|
||||
property you create. This needs to be executed by someone who has
|
||||
signatory power for the company.
|
||||
|
||||
* [Individual]((https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/ASWF/OSL-CLA-individual.md)).
|
||||
* [Individual CLA](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/blob/main/ASWF/CLA-individual.md).
|
||||
If you are an individual writing the code on your own time and you're SURE
|
||||
you are the sole owner of any intellectual property you contribute.
|
||||
|
||||
@@ -173,9 +173,16 @@ it really only applies to the particular file in which it appears.
|
||||
|
||||
#### Formatting
|
||||
|
||||
NEVER alter somebody else's code to reformat just because you found
|
||||
something that violates the rules. Let the group/author/leader know, and
|
||||
resist the temptation to change it yourself.
|
||||
We use clang-format to enforce formatting rules for the vast majority of the
|
||||
code base. It is automatically run during CI and is a CI failure if the code
|
||||
does not conform. There are, however, parts of the code base that are not
|
||||
clang-formatted, either because we have not yet put them under the
|
||||
clang-format regime, or because individual modules were deemed to be less
|
||||
clear with clang-format than with hand formatting.
|
||||
|
||||
For non-clang-format regions of code, NEVER alter somebody else's code to
|
||||
reformat just because you found something that violates the rules. Let the
|
||||
group/author/leader know, and resist the temptation to change it yourself.
|
||||
|
||||
Each line of text in your code should be at most 80 characters long.
|
||||
Exceptions are allowed for those rare cases where letting a line be longer
|
||||
@@ -217,13 +224,10 @@ Function calls should have a space between the function name and the opening
|
||||
parenthesis, NO space inside the parenthesis, except for a single blank
|
||||
space between each argument. For example:
|
||||
|
||||
x = foo (a, b); // Yes, this is always ok
|
||||
x = foo(a, b); // Yes
|
||||
|
||||
x = foo ( a, b ); // No
|
||||
x = foo (a,b); // No
|
||||
x = foo(a, b); // No
|
||||
x = foo(a); // Occasionally, this just looks better, when the function name is short,
|
||||
// and there's just one very short argument. What can I say, I do it too.
|
||||
|
||||
Function declarations: function names should begin at column 0 for a full
|
||||
function definition. (It's ok to violate this rule for very short inline
|
||||
@@ -233,7 +237,7 @@ functions within class definitions.)
|
||||
Here is a short code fragment that shows some of these rules in action:
|
||||
|
||||
static int
|
||||
function (int a, int b)
|
||||
function(int a, int b)
|
||||
{
|
||||
int x = a + b;
|
||||
if (a == 0 || b == 0) {
|
||||
@@ -244,7 +248,7 @@ Here is a short code fragment that shows some of these rules in action:
|
||||
}
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
x += a * i;
|
||||
x *= foo (i); // function call
|
||||
x *= foo(i); // function call
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
+23
-22
@@ -12,16 +12,16 @@ 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.23)
|
||||
* Build system: [CMake](https://cmake.org/) 3.12 or newer (tested through 3.26)
|
||||
|
||||
* A suitable **C++14 or C++17** compiler to build OSL itself, which may be any of:
|
||||
- **GCC 6.1 or newer** (tested through gcc 11.2)
|
||||
- Clang 3.4 or newer (tested through clang 14)
|
||||
- **GCC 6.1 or newer** (tested through gcc 12.1)
|
||||
- Clang 3.4 or newer (tested through clang 16)
|
||||
- Microsoft Visual Studio **2017 or newer**
|
||||
- Intel C++ compiler icc **version 17 or newer** or LLVM-based icx compiler
|
||||
**version 2022 or newer**.
|
||||
|
||||
* **[OpenImageIO](http://openimageio.org) 2.2 or newer** (tested through 2.3)
|
||||
* **[OpenImageIO](http://openimageio.org) 2.2 or newer** (tested through 2.4)
|
||||
|
||||
OSL uses OIIO both for its texture mapping functionality as well as
|
||||
numerous utility classes. If you are integrating OSL into an existing
|
||||
@@ -40,10 +40,16 @@ NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
$OpenImageIO_ROOT/lib to be in your LD_LIBRARY_PATH (or
|
||||
DYLD_LIBRARY_PATH on OS X).
|
||||
|
||||
* **[LLVM](http://www.llvm.org) 9, 10, 11, 12, 13, or 14**, including clang
|
||||
libraries.
|
||||
* **[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.
|
||||
|
||||
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.78)
|
||||
* (optional) For GPU rendering on NVIDIA GPUs:
|
||||
* [Cuda](https://developer.nvidia.com/cuda-downloads) 8.0 or higher.
|
||||
* [OptiX](https://developer.nvidia.com/rtx/ray-tracing/optix) 5.1 or higher
|
||||
(though 7.0+ is highly recommended).
|
||||
|
||||
* [Boost](https://www.boost.org) 1.55 or newer (tested through boost 1.81)
|
||||
* [Ilmbase or Imath](https://github.com/AcademySoftwareFoundation/openexr) 2.3
|
||||
or newer (recommended: 2.4 or higher; tested through 3.1)
|
||||
* [Flex](https://github.com/westes/flex) 2.5.35 or newer and
|
||||
@@ -51,17 +57,17 @@ NEW or CHANGED dependencies since the last major release are **bold**.
|
||||
Note that on some MacOS/xcode releases, the system-installed Bison is too
|
||||
old, and it's better to install a newer Bison (via Homebrew is one way to
|
||||
do this easily).
|
||||
* [PugiXML](http://pugixml.org/)
|
||||
* [PugiXML](http://pugixml.org/) >= 1.8 (we have tested through 1.13).
|
||||
* (optional) [Partio](https://www.disneyanimation.com/technology/partio.html)
|
||||
If it is not found at build time, the OSL `pointcloud` functions will not
|
||||
be operative.
|
||||
* (optional) Python: If you are building the Python bindings or running the
|
||||
testsuite:
|
||||
* Python >= 2.7 (tested against 2.7, 3.7, 3.8, 3.9)
|
||||
* pybind11 >= 2.4.2 (Tested through 2.9)
|
||||
* 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) Qt >= 5.6 (tested through 5.15). If not found at build time,
|
||||
the `osltoy` application will be disabled.
|
||||
* (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.
|
||||
|
||||
|
||||
|
||||
@@ -93,19 +99,14 @@ Here are the steps to check out, build, and test the OSL distribution:
|
||||
full errors, not warnings.
|
||||
|
||||
4. After compilation, you'll end up with a full OSL distribution in
|
||||
dist/ARCH, where ARCH is the architecture you are building on, one of
|
||||
"linux", "linux64", "macosx", "windows", or "windows64".
|
||||
dist/
|
||||
|
||||
Note: The default is to make an optimized "release" build. If
|
||||
instead type 'make debug' at the top level, you will end up with
|
||||
a debug build (no optimization, full symbols) in "dist/ARCH.debug".
|
||||
|
||||
5. Add the "dist/ARCH/bin" to your $PATH, and "dist/ARCH/lib" to your
|
||||
$LD_LIBRAY_PATH (or $DYLD_LIBRARY_PATH on OS X), or copy the contents
|
||||
5. Add the "dist/bin" to your $PATH, and "dist/lib" to your
|
||||
$LD_LIBRAY_PATH (or $DYLD_LIBRARY_PATH on MacOS), or copy the contents
|
||||
of those files to appropriate directories. Public include files
|
||||
(those needed when building applications that incorporate OSL)
|
||||
can be found in "dist/ARCH/include", and documentation can be found
|
||||
in "dist/ARCH/share/doc".
|
||||
can be found in "dist/include", and documentation can be found
|
||||
in "dist/share/doc".
|
||||
|
||||
6. After building (and setting your library path), you can run the
|
||||
test suite with:
|
||||
|
||||
@@ -294,7 +294,7 @@ package_source: install
|
||||
# 'make clang-format' runs clang-format on all source files (if it's installed)
|
||||
clang-format: config
|
||||
@ ( cd ${build_dir} ; \
|
||||
${CMAKE} --build . --target run-clang-format --config ${CMAKE_BUILD_TYPE} \
|
||||
${CMAKE} --build . --target clang-format --config ${CMAKE_BUILD_TYPE} \
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -219,14 +219,15 @@ inferred from public sources, or that we've been told is ok to list here. If
|
||||
an OSL-using project is missing and it's not a secret, just email the OSL
|
||||
project leader or submit a PR with edits to this file.*
|
||||
|
||||
Renderers and other tools with OSL support (in approximate order of
|
||||
adding OSL support):
|
||||
* Sony Pictures Imageworks: in-house "Arnold" renderer
|
||||
### Renderers and other production tools with OSL support
|
||||
|
||||
(In approximate order of adding OSL support)
|
||||
|
||||
* [Sony Pictures Imageworks: in-house "Arnold" renderer](https://dl.acm.org/doi/10.1145/3180495)
|
||||
* [Blender/Cycles](https://docs.blender.org/manual/en/dev/render/shader_nodes/osl.html)
|
||||
* [Chaos Group: V-Ray](https://www.chaosgroup.com/)
|
||||
* [Pixar: PhotoRealistic RenderMan RIS](https://renderman.pixar.com)
|
||||
* [Isotropix: Clarisse](http://www.isotropix.com/clarisse)
|
||||
* [Isotropix: Angie](http://www.isotropix.com/angie)
|
||||
* Isotropix: [Clarisse iFX](https://www.isotropix.com/products/clarisse/ifx) / [Clarisse BUiLDER](https://www.isotropix.com/products/clarisse/builder) / [Angie](https://www.isotropix.com/products/angie)
|
||||
* [Autodesk Beast](http://www.autodesk.com/products/beast/overview)
|
||||
* [Appleseed](http://appleseedhq.net)
|
||||
* [Animal Logic: Glimpse renderer](https://www.fxguide.com/featured/a-glimpse-at-animal-logic/)
|
||||
@@ -237,7 +238,13 @@ adding OSL support):
|
||||
* [Autodesk: 3DS Max 2019](https://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_3ds_max_sdk_features_rendering_osl_html)
|
||||
* [Maxon: Redshift](https://www.maxon.net/en/redshift)
|
||||
|
||||
Films using OSL (grouped by year of release date):
|
||||
### Significant work using OSL, grouped by year of release date:
|
||||
|
||||
(Here we are considering "significant work" to mean a feature film released
|
||||
theatrically or on a major streaming platform, TV/streaming series heavily
|
||||
featuring visual effects or animation, or short films that have won or been
|
||||
nominated for major awards.)
|
||||
|
||||
* **(2012)**
|
||||
Men in Black 3, The Amazing Spider-Man, Hotel Transylvania
|
||||
* **(2013)**
|
||||
@@ -272,6 +279,7 @@ Films using OSL (grouped by year of release date):
|
||||
Ghostbusters,
|
||||
Star Trek Beyond,
|
||||
Suicide Squad,
|
||||
Kubo and the Two Strings,
|
||||
Kingsglaive: Final Fantasy XV,
|
||||
Storks,
|
||||
Miss Peregrine's Home for Peculiar Children,
|
||||
@@ -306,7 +314,7 @@ Films using OSL (grouped by year of release date):
|
||||
* **(2018)**
|
||||
Peter Rabbit,
|
||||
Black Panther,
|
||||
Annnihilation,
|
||||
Annihilation,
|
||||
Red Sparrow,
|
||||
Pacific Rim Uprising,
|
||||
Avengers Infinity War,
|
||||
@@ -354,7 +362,8 @@ Films using OSL (grouped by year of release date):
|
||||
Richard Jewell,
|
||||
Game of Thrones (S8),
|
||||
Lost in Space (S1),
|
||||
Togo
|
||||
Togo,
|
||||
Missing Link
|
||||
* **(2020)**
|
||||
Underwater,
|
||||
Birds of Prey,
|
||||
@@ -370,7 +379,9 @@ Films using OSL (grouped by year of release date):
|
||||
Over the Moon,
|
||||
Wonder Woman 1984,
|
||||
Soul,
|
||||
The Mandalorian (S2)
|
||||
The Mandalorian (S2),
|
||||
The Boys (S2),
|
||||
Umbrella Academy (S2)
|
||||
* **(2021)**
|
||||
Chaos Walking,
|
||||
Peter Rabbit 2: The Runaway,
|
||||
@@ -383,6 +394,7 @@ Films using OSL (grouped by year of release date):
|
||||
F9,
|
||||
Vivo,
|
||||
Jungle Cruise,
|
||||
Cinderella,
|
||||
Dune,
|
||||
No Time To Die,
|
||||
Ron's Gone Wrong,
|
||||
@@ -390,13 +402,41 @@ Films using OSL (grouped by year of release date):
|
||||
Last Night in Soho,
|
||||
Ghostbusters: Afterlife,
|
||||
Spider-Man 3: No Way Home,
|
||||
Matrix Resurrections
|
||||
* **(2022 / upcoming)**
|
||||
Matrix Resurrections,
|
||||
Sing 2
|
||||
* **(2022)**
|
||||
Hotel Transylvania 4: Transformania,
|
||||
Death on the Nile,
|
||||
Uncharted,
|
||||
Turning Red,
|
||||
The Adam Project,
|
||||
Doctor Strange in the Multiverse of Madness,
|
||||
Love, Death, and Robots: In Vaulted Halls Entombed,
|
||||
Jurassic World: Dominion,
|
||||
Lightyear,
|
||||
Thor: Love and Thunder,
|
||||
The Sea Beast,
|
||||
DC League of Super Pets,
|
||||
Minions: Rise of Gru,
|
||||
Bullet Train,
|
||||
Slumberland,
|
||||
Glass Onion,
|
||||
Archive 81 (series),
|
||||
Moon Night (series),
|
||||
Obi-Wan Kenobi (series),
|
||||
The Boys (S3),
|
||||
Andor (S1)
|
||||
* **(2023 / upcoming)**
|
||||
Ant-Man and the Wasp: Quantumania,
|
||||
The Mandalorian S3,
|
||||
The Magician's Elephant,
|
||||
Super Mario Bros Film,
|
||||
Guardians of the Galaxy 3,
|
||||
Spider-Man: Across the Spider-Verse,
|
||||
Elemental,
|
||||
...
|
||||
|
||||
|
||||
|
||||
Building and Installation
|
||||
-------------------------
|
||||
|
||||
@@ -412,6 +452,13 @@ The OSL language specification can be found at
|
||||
distribution) or in the share/doc/OSL/osl-languagespec.pdf file of an
|
||||
installed binary distribution.
|
||||
|
||||
For those interested in learning to program in OSL, there is the
|
||||
[Siggraph 2022 Educator's Forum](https://dl.acm.org/doi/proceedings/10.1145/3532724)
|
||||
[OSL Shaders for RenderMan](https://dl.acm.org/doi/abs/10.1145/3532724.3535604) course,
|
||||
which uses RenderMan in the examples and
|
||||
[Supplementary Materials](https://github.com/LaikaStudios/OSLShadersForRenderMan),
|
||||
but which is primarily about shader writing in OSL.
|
||||
|
||||
|
||||
Contact & reporting problems
|
||||
----------------------------
|
||||
@@ -427,9 +474,13 @@ certain is a legit problem in the code, and for which you can give clear
|
||||
instructions for how to reproduce, should be [reported as
|
||||
issues](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/issues).
|
||||
|
||||
If confidentiality precludes a public question or issue, you may contact the
|
||||
project administrator privately at [lg@imageworks.com](lg@imageworks.com),
|
||||
including for security-related issues.
|
||||
If you think you've found a potential vulnerability in OSL, please
|
||||
confidentially report it by emailing the project administrators at
|
||||
[security@openshadinglanguage.org](security@openshadinglanguage.org).
|
||||
|
||||
If any other issue requires confidentiality that precludes a public question
|
||||
or issue, you may contact the project administrator privately at
|
||||
[lg@larrygritz.com](lg@larrygritz.com).
|
||||
|
||||
|
||||
Contributing
|
||||
@@ -453,7 +504,6 @@ Contacts, Links, and References
|
||||
|
||||
[OSL home page](http://openshadinglanguage.org)
|
||||
|
||||
[Sony Pictures Imageworks main open source page](http://opensource.imageworks.com)
|
||||
|
||||
|
||||
|
||||
@@ -466,19 +516,20 @@ The current project leadership is documented in the
|
||||
Many people have contributed features, bug fixes, and other changes to OSL
|
||||
over the years: Steve Agland, Shane Ambler, Martijn Berger, Farchad
|
||||
Bidgolirad, Nicholas Bishop, Solomon Boulos, Stefan Bruens, Stefan Büttner,
|
||||
Matthaus G. Chajdas, Clark Chen, Alejandro Conty,
|
||||
Dieter De Baets, Thomas Dinges, Mads Drøschler,
|
||||
Luke Emrose, Louis Feng, Mark Final, Henri Fousse, Syoyo Fujita,
|
||||
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, Thiago Ize, Matt
|
||||
Johnson, Ronan Keryell, Chris Kulla, Elvic Liang, Max Liani, Adam Martinez,
|
||||
John Mertic, Bastien Montagne, Steena Monteiro, Alexis Oblet, Erich Ocean,
|
||||
Mikko Ohtamaa, Jino Park, Alexei Pawlow, Jay Reynolds, Declan Russell, Benoit
|
||||
Ruiz, Patrick Scheibe, Alex Schworer, Jonathan Scruggs, Sergey Sharybin,
|
||||
Sandip Shukla, Cliff Stein, Stephan Steinbach, Luya Tshimbalanga, Esteban
|
||||
Tovagliari, Brecht Van Lommel, Alexander von Knorring, Alex Wells, Roman
|
||||
Zulak. (Listed alphabetically; if we've left anybody out, it is inadvertent,
|
||||
please let us know.)
|
||||
Haase, John Haddon, Niklas Harrysson, Daniel Heckenberg, Chris Hellmuth,
|
||||
Adrien Herubel, Dan Horák, Thiago Ize, Matt Johnson, Ronan Keryell, Chris
|
||||
Kulla, Elvic Liang, Max Liani, Adam Martinez, John Mertic, Bastien Montagne,
|
||||
Steena Monteiro, Patrick Mours, Alexis Oblet, Erich Ocean, Mikko Ohtamaa, Jino
|
||||
Park, Alexei Pawlow, Jay Reynolds, Declan Russell, Benoit Ruiz, Patrick
|
||||
Scheibe, Alex Schworer, Jonathan Scruggs, Sergey Sharybin, Mark Sisson, Sandip
|
||||
Shukla, Cliff Stein, Stephan Steinbach, Luya Tshimbalanga, Esteban Tovagliari,
|
||||
Brecht Van Lommel, Alexander von Knorring, Alex Wells, Roman Zulak. (Listed
|
||||
alphabetically; if we've left anybody out, it is inadvertent, please let us
|
||||
know.)
|
||||
|
||||
We cannot possibly express sufficient gratitude to the managers at Sony
|
||||
Pictures Imageworks who allowed this project to proceed, supported it
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
This gives guidance about which branches are supported with patches to
|
||||
security vulnerabilities.
|
||||
|
||||
| Version / branch | Supported |
|
||||
| --------- | ---------------------------------------------------- |
|
||||
| main | :white_check_mark: :construction: ALL fixes immediately, but this is a branch under development with a frequently unstable ABI and occasionally unstable API. |
|
||||
| 1.12.x | :white_check_mark: All fixes that can be backported without breaking ABI compatibility. New tagged releases monthly. |
|
||||
| 1.11.x | :warning: Only the most critical fixes, only if they can be easily backported. |
|
||||
| <= 1.10.x | :x: No longer receiving patches of any kind. |
|
||||
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you think you've found a potential vulnerability in OSL, please report it
|
||||
by emailing the project administrators at
|
||||
[security@openshadinglanguage.org](security@openshadinglanguage.org). Only the
|
||||
project administrators have access to these messages. Include detailed steps to
|
||||
reproduce the issue, and any other information that could aid an
|
||||
investigation. Our policy is to respond to vulnerability reports within 14
|
||||
days.
|
||||
|
||||
Our policy is to address critical security vulnerabilities rapidly and post
|
||||
patches as quickly as possible.
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
The OSL Documentation Project is a work in progress.
|
||||
|
||||
The plan is to adopt the OCIO Documentation Project's methodology for maintaining and building documention of various kinds as it becomes the blueprint for the ASWF.
|
||||
The plan is to adopt the OCIO Documentation Project's methodology for maintaining and building documentation of various kinds as it becomes the blueprint for the ASWF.
|
||||
|
||||
There is much work to be done here.
|
||||
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
|
||||
<!-- Copyright Contributors to the Open Shading Language Project. -->
|
||||
|
||||
# Release Procedures for Open Shading Language
|
||||
|
||||
## Version nomenclature and release cadence
|
||||
|
||||
### The meaning of the version parts
|
||||
|
||||
Our release numbers are of the form `MAJOR.MINOR.PATCH.TWEAK`, and we follow
|
||||
an almost-semantic-versioning scheme.
|
||||
|
||||
MAJOR changes are those that break backward-compatibility of the public APIs,
|
||||
requiring existing application code to change their source code where it calls
|
||||
OSL API functions in order to compile and work correctly.
|
||||
|
||||
MINOR changes guarantee API backward-compatibility with prior releases that
|
||||
have the same major number, but can introduce ABI or link incompatibilities.
|
||||
Applications using OSL need to be recompiled to move to a new minor release,
|
||||
but should not need to change their source code. Minor releases are allowed
|
||||
to drop support for sufficiently old compilers and dependencies.
|
||||
|
||||
PATCH changes guarantee both API and ABI/link backward-compatibility with
|
||||
prior releases that have the same minor number. Features and new public API
|
||||
calls may be added (thus deviating from strict semantic versioning), but only
|
||||
if they preserve ABI/link compatibility. This means that standalone functions
|
||||
or static methods may be added, but existing functions will not change their
|
||||
parameters, and no new virtual methods or struct data layouts change for patch
|
||||
releases (for classes in public header files). Application code can be
|
||||
re-linked to a new patch release without needing to be recompiled. We also
|
||||
guarantee that any compilers or dependencies supported for the first release
|
||||
of a minor series will continue to be supported for all patches to that minor
|
||||
series.
|
||||
|
||||
TWEAK changes are restricted to critical bug fixes or build breaks that do
|
||||
not alter public APIs in any way.
|
||||
|
||||
### Cadence of releases
|
||||
|
||||
Major (arbitrarily incompatible) releases happen rarely, usually with multiple
|
||||
years between them.
|
||||
|
||||
Minor (API backward-compatible) releases are scheduled annually, targeted at
|
||||
late summer (SIGGRAPH time) to be in beta, and early autumn for a full
|
||||
release.
|
||||
|
||||
Patch (API and ABI backward-compatible) releases are scheduled monthly,
|
||||
usually aiming for the first day of each month.
|
||||
|
||||
Tweak (fully forward and backward compatible) releases are not regularly
|
||||
scheduled, and only happen sporadically, when a critical fix is needed in
|
||||
between scheduled patch releases.
|
||||
|
||||
### Things are different in "main"
|
||||
|
||||
The "main" branch is where ongoing development occurs without any
|
||||
compatibility guarantees. We don't always know if the next year's release from
|
||||
main will turn out to be major (API breaking) or minor (only ABI breaking).
|
||||
|
||||
Some studios or products need the most up-to-date enhancements, and thus tend
|
||||
to build OSL from the "main" branch rather than using tagged releases. For
|
||||
these users, we try to set version numbers and occasionally tag in main, to
|
||||
send a signal about which points in main seem safe to rely on various
|
||||
compatibility levels. However, the rules are slightly different than we use
|
||||
for releases.
|
||||
|
||||
In the "main" branch:
|
||||
|
||||
- TWEAK changes within "main" only guarantee ABI back-compatibility, but may
|
||||
have additions or non-bug-fix behavior changes (akin to patch releases
|
||||
within a release branch).
|
||||
- PATCH changes within "main" are allowed to break ABI or API (changes that
|
||||
would require minor or major releases, if they were not in "main").
|
||||
- Beware of unmarked breaks in compatibility of commits in main that are
|
||||
in between developer preview tags.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Branch and tag names
|
||||
|
||||
**Branches** are places where commits containing new development may be added
|
||||
(and thus the branch markers will move over time). Branch names obey the
|
||||
following conventions:
|
||||
|
||||
- `main` is the area for arbitrary changes intended for the next year's major
|
||||
or minor release.
|
||||
- `dev-1.2` are the areas for staging additions to the next month's patch
|
||||
release for the designated minor version series.
|
||||
- `release` is a special branch marker that is always set to the latest tag of
|
||||
the currently supported, stable release family. People can count on
|
||||
"release" always being the latest stable release, whatever that may be at
|
||||
the time.
|
||||
|
||||
**Tags** indicate releases or developer previews, and once a commit is
|
||||
tagged, it is permanent and will never be moved. Tag names obey the following
|
||||
conventions:
|
||||
|
||||
- `v1.2.3.4` is a specific public stable release, corresponding to official
|
||||
major, minor, public, or tweak releases.
|
||||
- `v1.2.3.4-alpha`, `v1.2.3.4-beta`, or `v1.2.3.4-RC1` are pre-releases for an
|
||||
upcoming public stable release, at the alpha, beta, or release candidate
|
||||
stages, respectively.
|
||||
- `v1.2.3.4-dev` is a "developer preview" within "main." It is not an official
|
||||
supported release, and while the numbering may indicate compatibility versus
|
||||
other recent developer previews, they should not be assumed to be compatible
|
||||
with any prior official stable releases.
|
||||
|
||||
*Very* occasionally, other branch or tag names (with custom suffixes or
|
||||
different naming schemes) may be used for special purposes by particular
|
||||
developers or users, but should not be considered reliable or permanent, and
|
||||
in general should be ignored by anyone who didn't make the tag or branch.
|
||||
|
||||
---
|
||||
|
||||
## Release Procedures
|
||||
|
||||
### Soft freeze for monthly tweak releases:
|
||||
|
||||
We freely backport *safe*, non-ABI-breaking changes by cherry-picking them
|
||||
from main to the supported branch continually throughout most of the month.
|
||||
|
||||
In the seven days before the new month, we do a "soft freeze" where only
|
||||
important bug fixes are backported. Hold on to any other patches you wish to
|
||||
backport until after the monthly patch release (i.e., save them for the next
|
||||
month's release so you never have a release that contains changes that are
|
||||
only a few days old, and therefore not as well tested). You may, of course,
|
||||
continue to backport fixes to documentation or other non-code parts of the
|
||||
project during this soft freeze.
|
||||
|
||||
### Branching for annual major/minor releases
|
||||
|
||||
By mid-June (about 1-2 months before the beta of a new annual big release),
|
||||
you should branch and mark it as an alpha.
|
||||
|
||||
At the tip of "main," create a new branch named `dev-MAJOR.MINOR` that will be
|
||||
the staging area for the next release.
|
||||
|
||||
Customarily, at that point we add a commit to main (but not to the new
|
||||
dev-MAJ.MIN branch) that bumps main's version to the next minor level, to
|
||||
avoid any confusion between builds from main versus what will be the next
|
||||
release branch. This starts the divergence between main and the release
|
||||
branch, and henceforth, any big or compatibility-breaking changes will only be
|
||||
committed to main and not backported to the release branch. (Though we are
|
||||
loose about this rule during the alpha period and allow continued breaking
|
||||
changes in the alpha, but by the time we call it beta, we allow no more
|
||||
breaking changes.) Also at this stage, the main branch's CHANGES.md should
|
||||
have a heading added at the top for the *next* version.
|
||||
|
||||
|
||||
### Prior to a release
|
||||
|
||||
1. Update CI dependencies: Ensure that the "latest" CI test specifies the
|
||||
current releases of the dependencies and compilers (check their home
|
||||
pages), and that the [INSTALL.md](../INSTALL.md) file correctly documents
|
||||
the version ranges that we expect to work and that we actively test.
|
||||
|
||||
2. Release notes: [CHANGES.md](../CHANGES.md) should be updated to reflect
|
||||
all the new features and fixes. Looking at the notes from older releases
|
||||
should provide a good example of what we're aiming for.
|
||||
|
||||
- Patch and tweak releases can be brief one-line descriptions (often the
|
||||
first line of the commit messages involved), presented in a single
|
||||
section in either chronological or any other order that seems right.
|
||||
- Minor or major releases have a much more extensive, prose-based
|
||||
description of all changes since the last minor release, broken into
|
||||
sections (dependency changes, major new features, enhancements and fixes,
|
||||
internals and developer goodies, testing/CI/ports, etc.) and ordered for
|
||||
readability and relevance.
|
||||
|
||||
3. Ensure docs are up to date:
|
||||
|
||||
- Actually read the [README.md](../README.md), [INSTALL.md](../INSTALL.md),
|
||||
and other repository docs and make sure all the information is up to
|
||||
date. Check the "contributor credits" in the README against the recent
|
||||
repo history to be sure new contributors are listed. Also check the
|
||||
list of films and make sure it includes any recent productions that are
|
||||
known to have used OSL.
|
||||
- Skim the primary user documentation to look for any obvious errors,
|
||||
especially the parts that describe new features. In the case of PDF docs
|
||||
(such as osl-languagespec.pdf), make sure that a new PDF book is built if
|
||||
the documentation source has been changed since the last release.
|
||||
- If we are using any online docs (like readthedocs), make sure it is
|
||||
building and looks correct on the web site.
|
||||
|
||||
4. Make sure the the top-level CMakeLists.txt file is updated:
|
||||
|
||||
- The version on the `project()` call should be correct.
|
||||
- The `PROJECT_VERSION_RELEASE_TYPE` variable should be set to "alpha" or
|
||||
"beta" if appropriate, "RC" for release candidate, or empty string `""`
|
||||
for most supported releases, and "dev" only for the main branch or
|
||||
developer previews.
|
||||
- The `${PROJECT_NAME}_SUPPORTED_RELEASE` variable should be `ON` for any
|
||||
release branch, `OFF` for main.
|
||||
|
||||
5. Make sure everything passes the usual CI workflow. Also check the daily or
|
||||
weekly "analysis" workflows to make sure there aren't any important
|
||||
warnings that should be fixed.
|
||||
|
||||
|
||||
### Staging alpha / beta / release candidate (annual minor/major releases only)
|
||||
|
||||
For monthly patch releases, we don't have any formal alpha/beta/RC stages.
|
||||
|
||||
For the annual minor or major releases we have a staged release:
|
||||
|
||||
- `alpha` is everything after we have branched, in which we think all the big
|
||||
new features have been added, and while we will make continued changes and
|
||||
fixes, we are aiming for increased stability and to minimize additional
|
||||
breaking changes prior to the release.
|
||||
- `beta` should be about one month prior to the final release date. We create
|
||||
a tag `v1.2.3.4-beta` and announce the beta (see below "Making the
|
||||
release"). Once we tag a beta, we try very hard not to allow any further
|
||||
changes that change the API or are not ABI-compatible (i.e., safe fixes
|
||||
only).
|
||||
- `RC` or release candidates around one week prior to the final release date.
|
||||
This is a trial run, hopefully identical to the final release (except for
|
||||
removing the RC label and making a new tag). The only changes allowed after
|
||||
RC are fixes to the most critical bugs or build breaks that would be bad for
|
||||
users to encounter. If critical problems are found with RC1, they should be
|
||||
fixed and immediately re-tagged as RC2, etc. All other fixes should be
|
||||
postponed until the next month's patch release.
|
||||
|
||||
### Making the release
|
||||
|
||||
A final release is made on the scheduled date, provided the latest RC has
|
||||
survived for at least a few days of testing without finding any critical
|
||||
problems. Don't make the release final until you are sure there are no
|
||||
truly critical bugs or build breaks that users will encounter.
|
||||
|
||||
The following are the steps for making the release:
|
||||
|
||||
1. Edit the top-level CMakeLists.txt to remove any RC designation
|
||||
(i.e., `PROJECT_VERSION_RELEASE_TYPE` should be set to `""`).
|
||||
|
||||
2. Edit CHANGES.md to reflect the correct date of the release and ensure it
|
||||
includes any last-minute changes that were made during beta or release
|
||||
candidate stages.
|
||||
|
||||
3. Push it to **your** GitHub, make sure it passes CI.
|
||||
|
||||
4. Tag the release: `git tag v1.2.3.4` (no more beta, RC, or dev suffix).
|
||||
|
||||
5. If this will now be the recommended stable release, move the `release`
|
||||
branch marker to the same position.
|
||||
|
||||
6. Push it to GitHub: `git push aswf release --tags`
|
||||
|
||||
(This example assumes "aswf" is the name of the remote for the GitHub
|
||||
`AcademySoftwareFoundation/OpenShadingLanguage` repo.)
|
||||
|
||||
7. Draft a release on GitHub: On
|
||||
https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/releases
|
||||
select "Draft a new release." Choose the new tag you just pushed. Make the
|
||||
release title "Open Shading Language v1.2.3.4" (and beta, etc., designation
|
||||
if applicable). In the description, paste the release notes for this
|
||||
release (from Changes.md). If this is a beta or release candidate, check
|
||||
"this is a pre-release" box at the bottom.
|
||||
|
||||
8. Announce the release on the [osl-dev mail list](https://lists.aswf.io/g/osl-dev)
|
||||
with the subject "Release: OSL v1.2.3.4" and using one of these templates
|
||||
for the body of the email.
|
||||
|
||||
For a monthly patch release:
|
||||
|
||||
> We have tagged v1.2.3.4 as the latest production release and moved the
|
||||
> "release" branch marker to that point. This is guaranteed to be API,
|
||||
> ABI, and link back-compatible with prior 1.2 releases. Release notes
|
||||
> are below.
|
||||
>
|
||||
> (Paste the full set of 1.2 changes here, just copy the appropriate
|
||||
> part of CHANGES.md)
|
||||
|
||||
For an annual major/minor release:
|
||||
|
||||
> OSL version 1.2 has been released! Officially tagged as "v1.2.3.4", we
|
||||
> have also moved the "release" branch tag to this position. Henceforth,
|
||||
> 1.2 is the supported production release family. The API is now frozen --
|
||||
> we promise that subsequent 1.2.x releases (which should happen monthly)
|
||||
> will not break back-compatibility of API, ABI, or linkage, compared to
|
||||
> this release. Please note that this release is *not* ABI or link
|
||||
> compatible with 1.1 or older releases.
|
||||
>
|
||||
> Release notes for 1.2 outlining all the changes since last year's
|
||||
> release are below.
|
||||
>
|
||||
> Please note that a few of the build and runtime dependencies have
|
||||
> changed their minimum supported versions. (List here any important
|
||||
> changes to dependencies, compilers, or C++ standard that users should be
|
||||
> aware of.)
|
||||
>
|
||||
> (List here anything else that people should know about this release
|
||||
> family that may be surprising if they haven't followed the last year of
|
||||
> development closely, or that they must know even if they are too lazy to
|
||||
> read the release notes. If this is a major release that is not
|
||||
> backward-compatible with prior versions, warn about that here.)
|
||||
>
|
||||
> Enjoy, and please report any problems. We will continue to make patch
|
||||
> releases to the 1.2 family roughly monthly, which will contain bug fixes
|
||||
> and non-breaking enhancements.
|
||||
>
|
||||
> The older 1.1 series of releases is now considered obsolete. We will
|
||||
> continue for now to make 1.1 patch releases, but over time, these will
|
||||
> become less frequent and be reserved for only the most critical bug
|
||||
> fixes.
|
||||
>
|
||||
> The "main" branch is now progressing toward an eventual 1.3 release next
|
||||
> summer. As usual, you are welcome to use main for real work, but we do
|
||||
> not make any compatibility guarantees and don't guarantee continuing API
|
||||
> compatibility in main.
|
||||
>
|
||||
> (Paste the full set of 1.2 changes here, just copy the appropriate
|
||||
> part of CHANGES.md)
|
||||
|
||||
For a beta leading up to the annual major/minor release:
|
||||
|
||||
> OSL version 1.2 is now in beta, tagged as "v1.2.3.4-beta". We
|
||||
> will try very hard not to make any further API or ABI changes between
|
||||
> now and the final release (unless it is absolutely necessary to fix
|
||||
> an important problem identified during beta testing). The final 1.2
|
||||
> release is scheduled for [DATE GOES HERE], so please try building and
|
||||
> testing the beta so we are sure to find any problems.
|
||||
>
|
||||
> Release notes for 1.2 outlining all the changes since last year's
|
||||
> release are below.
|
||||
>
|
||||
> (Paste the full set of 1.2 changes here, just copy the appropriate
|
||||
> part of CHANGES.md)
|
||||
|
||||
|
||||
### After the release
|
||||
|
||||
Odds and ends to do after the tag is pushed and the announcements are sent:
|
||||
|
||||
- Re-read RELEASING.md and ensure that the instructions match what you
|
||||
have done. Update as necessary.
|
||||
|
||||
- For annual beta releases, post a short message to the "Open Shading
|
||||
Language" channel of the ASWF slack. It can be a one-line announcement and
|
||||
then just a link to the GitHub release page for this version.
|
||||
|
||||
- Edit the top-level CMakeList.txt to update the version to the *next*
|
||||
anticipated release on the branch, in order to ensure that anybody building
|
||||
from subsequent patches won't get a release number that advertises itself
|
||||
incorrectly as a prior tagged release. Also edit CHANGES.md to add a new
|
||||
(blank) heading for the next patch or release.
|
||||
+14
-10
@@ -181,14 +181,18 @@ else ifeq (${platform}, macosx)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=gcc-9 -DCMAKE_CXX_COMPILER=g++-9
|
||||
USE_LIBCPLUSPLUS := 0
|
||||
else ifeq (${COMPILER},clang11)
|
||||
else ifeq (${COMPILER},clang14)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@11/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@11/bin/clang++
|
||||
else ifeq (${COMPILER},clang12)
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@14/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@14/bin/clang++
|
||||
else ifeq (${COMPILER},clang15)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@12/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@12/bin/clang++
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@15/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@15/bin/clang++
|
||||
else ifeq (${COMPILER},clang16)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@16/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@16/bin/clang++
|
||||
else ifeq (${COMPILER},clang)
|
||||
MY_CMAKE_FLAGS += -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
else ifeq (${COMPILER},gcc)
|
||||
@@ -196,13 +200,13 @@ else ifeq (${platform}, macosx)
|
||||
else ifeq (${COMPILER},)
|
||||
# default compiler is clang, taken from the LLVM directory
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
else ifeq (${COMPILER},llvm)
|
||||
# "llvm" means "use the clang from our llvm"
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=${LLVM_DIRECTORY}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_DIRECTORY}/bin/clang++
|
||||
-DCMAKE_C_COMPILER=${LLVM_ROOT}/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_ROOT}/bin/clang++
|
||||
endif
|
||||
|
||||
# end generic OSX
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the Open Shading Language Project.
|
||||
|
||||
sonar.host.url=https://sonarcloud.io
|
||||
|
||||
# Required metadata
|
||||
sonar.organization=academysoftwarefoundation
|
||||
sonar.projectName=OpenShadingLanguage
|
||||
sonar.projectVersion=1.12
|
||||
sonar.projectKey=AcademySoftwareFoundation_OpenShadingLanguage
|
||||
|
||||
# Project links
|
||||
sonar.links.homepage=https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
sonar.links.ci=https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/actions
|
||||
sonar.links.scm=https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
sonar.links.issue=https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/issues
|
||||
|
||||
# Source properties
|
||||
sonar.sources=src
|
||||
sonar.sourceEncoding=UTF-8
|
||||
|
||||
# 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:=13.0.0}
|
||||
LLVM_VERSION=${LLVM_VERSION:=14.0.0}
|
||||
LLVM_INSTALL_DIR=${LLVM_INSTALL_DIR:=${PWD}/llvm-install}
|
||||
if [[ "$GITHUB_WORKFLOW" != "" ]] ; then
|
||||
LLVM_DISTRO_NAME=${LLVM_DISTRO_NAME:=ubuntu-18.04}
|
||||
|
||||
@@ -12,6 +12,10 @@ if [[ "$USE_SIMD" != "" ]] ; then
|
||||
OSL_CMAKE_FLAGS="$OSL_CMAKE_FLAGS -DUSE_SIMD=$USE_SIMD"
|
||||
fi
|
||||
|
||||
if [[ -n "$CODECOV" ]] ; then
|
||||
OSL_CMAKE_FLAGS="$OSL_CMAKE_FLAGS -DCODECOV=${CODECOV}"
|
||||
fi
|
||||
|
||||
pushd build
|
||||
cmake .. -G "$CMAKE_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \
|
||||
@@ -23,7 +27,16 @@ cmake .. -G "$CMAKE_GENERATOR" \
|
||||
-DCMAKE_INSTALL_LIBDIR="$OSL_ROOT/lib" \
|
||||
-DCMAKE_CXX_STANDARD="$CMAKE_CXX_STANDARD" \
|
||||
$OSL_CMAKE_FLAGS -DVERBOSE=1
|
||||
time cmake --build . --target ${BUILDTARGET:=install} --config ${CMAKE_BUILD_TYPE}
|
||||
|
||||
# Save a copy of the generated files for debugging broken CI builds.
|
||||
mkdir cmake-save || /bin/true
|
||||
cp -r CMake* *.cmake cmake-save
|
||||
|
||||
: ${BUILDTARGET:=install}
|
||||
if [[ "$BUILDTARGET" != "none" ]] ; then
|
||||
echo "Parallel build ${CMAKE_BUILD_PARALLEL_LEVEL} of target ${BUILDTARGET}"
|
||||
time ${OSL_CMAKE_BUILD_WRAPPER} cmake --build . --target ${BUILDTARGET} --config ${CMAKE_BUILD_TYPE}
|
||||
fi
|
||||
popd
|
||||
|
||||
if [[ "${DEBUG_CI:=0}" != "0" ]] ; then
|
||||
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run code coverage analysis
|
||||
# This assumes that the build occurred with CODECOV=1 andtests have already
|
||||
# fully run.
|
||||
|
||||
set -ex
|
||||
|
||||
echo "Performing code coverage analysis"
|
||||
mkdir _coverage
|
||||
pushd _coverage
|
||||
|
||||
ls -R ../build/src/
|
||||
|
||||
# The sed command below converts from:
|
||||
# ../build/src/liboslexec/CMakeFiles/oslexec.dir/foo.gcno
|
||||
# to:
|
||||
# ../src/liboslexec/foo.cpp
|
||||
|
||||
for g in $(find ../build -name "*.gcno" -type f); do
|
||||
echo "Processing $g"
|
||||
echo "dirname $g = $(dirname $g) to " `$(echo "$g" | sed -e 's/\/build\//\//' -e 's/\.gcno/\.cpp/' -e 's/\.cpp\.cpp/\.cpp/' -e 's/\/CMakeFiles.*\.dir\//\//')`
|
||||
gcov -l -p -o $(dirname "$g") $(echo "$g" | sed -e 's/\/build\//\//' -e 's/\.gcno/\.cpp/' -e 's/\/CMakeFiles.*\.dir\//\//')
|
||||
done
|
||||
popd
|
||||
@@ -23,7 +23,7 @@ export DYLD_LIBRARY_PATH=$OSL_ROOT/lib:$DYLD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=$OSL_ROOT/lib:$LD_LIBRARY_PATH
|
||||
export OIIO_LIBRARY_PATH=$OSL_ROOT/lib:${OIIO_LIBRARY_PATH}
|
||||
export LSAN_OPTIONS=suppressions=$PWD/src/build-scripts/nosanitize.txt
|
||||
export ASAN_OPTIONS=print_suppressions=0
|
||||
export ASAN_OPTIONS=print_suppressions=0:detect_odr_violation=1
|
||||
|
||||
export USE_PYTHON=${USE_PYTHON:=1}
|
||||
export PYTHON_VERSION=${PYTHON_VERSION:="2.7"}
|
||||
|
||||
@@ -8,12 +8,26 @@
|
||||
# any command in it fails. This is crucial for CI tests.
|
||||
set -ex
|
||||
|
||||
: ${CTEST_EXCLUSIONS:="broken"}
|
||||
: ${CTEST_TEST_TIMEOUT:=60}
|
||||
|
||||
$OSL_ROOT/bin/testshade --help
|
||||
|
||||
echo "Parallel test " ${CTEST_PARALLEL_LEVEL}
|
||||
echo "Parallel test ${CTEST_PARALLEL_LEVEL}"
|
||||
echo "Default timeout ${CTEST_TEST_TIMEOUT}"
|
||||
echo "Test exclusions '${CTEST_EXCLUSIONS}'"
|
||||
echo "CTEST_ARGS '${CTEST_ARGS}'"
|
||||
|
||||
pushd build
|
||||
time ctest -C ${CMAKE_BUILD_TYPE} -E broken --force-new-ctest-process \
|
||||
--output-on-failure --timeout ${CTEST_TEST_TIMEOUT:=60} ${CTEST_ARGS}
|
||||
|
||||
ctest -C ${CMAKE_BUILD_TYPE} --force-new-ctest-process --output-on-failure \
|
||||
--timeout ${CTEST_TEST_TIMEOUT} -E "${CTEST_EXCLUSIONS}" ${CTEST_ARGS} \
|
||||
|| \
|
||||
ctest -C ${CMAKE_BUILD_TYPE} --force-new-ctest-process \
|
||||
--rerun-failed --repeat until-pass:5 -R render --output-on-failure \
|
||||
--timeout ${CTEST_TEST_TIMEOUT} -E "${CTEST_EXCLUSIONS}" ${CTEST_ARGS}
|
||||
# The weird construct above allows the render-* tests to run multiple times
|
||||
|
||||
popd
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ from __future__ import print_function, absolute_import
|
||||
###
|
||||
### Only one main doc region will be output by the `docdeep` program,
|
||||
### specified with the `-d` command line argument. Any other doc-regions
|
||||
### will not be included in the documention output of that run.
|
||||
### will not be included in the documentation output of that run.
|
||||
###
|
||||
### However, one doc-region may *include* the text of another doc-region
|
||||
### as follows:
|
||||
@@ -114,7 +114,7 @@ from __future__ import print_function, absolute_import
|
||||
### For pre-code comments, the contiguous comment region associated with
|
||||
### a declaration immediately precedes the declaration. Such a comment
|
||||
### set has its first line start with `///>`. For post-code comments,
|
||||
### the documentaiton comments follows the code declaration, and this is
|
||||
### the documentation comments follows the code declaration, and this is
|
||||
### designated by having its first line start with `///<`. I like to
|
||||
### just remember that the `<` or `>` points in the direction of the code
|
||||
### declaration that the comment applies to.
|
||||
|
||||
@@ -18,8 +18,8 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
|
||||
#ls /etc/yum.repos.d
|
||||
|
||||
sudo yum install -y giflib giflib-devel && true
|
||||
# sudo yum install -y ffmpeg ffmpeg-devel && true
|
||||
sudo /usr/bin/yum install -y giflib giflib-devel && true
|
||||
# sudo /usr/bin/yum install -y ffmpeg ffmpeg-devel && true
|
||||
|
||||
if [[ "${CONAN_LLVM_VERSION}" != "" ]] ; then
|
||||
mkdir conan
|
||||
@@ -42,8 +42,12 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
|
||||
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" || "$CXX" == "icpx" || "$CC" == "icx" || "$USE_ICX" != "" ]] ; then
|
||||
sudo cp src/build-scripts/oneAPI.repo /etc/yum.repos.d
|
||||
sudo yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic
|
||||
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||
sudo /usr/bin/yum install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.1.0.x86_64
|
||||
# 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.
|
||||
set +e; source /opt/intel/oneapi/setvars.sh --config oneapi_2022.1.0.cfg; set -e
|
||||
|
||||
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" ]] ; then
|
||||
echo "Verifying installation of Intel(r) C++ Compiler:"
|
||||
icpc --version
|
||||
@@ -57,22 +61,39 @@ 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 \
|
||||
git cmake ninja-build ccache g++ \
|
||||
libboost-dev libboost-thread-dev libboost-filesystem-dev \
|
||||
libilmbase-dev libopenexr-dev \
|
||||
python-dev python-numpy \
|
||||
libtiff-dev libgif-dev libpng-dev \
|
||||
flex bison libbison-dev \
|
||||
libpugixml-dev \
|
||||
libopencolorio-dev \
|
||||
qt5-default
|
||||
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
|
||||
|
||||
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu:$CMAKE_PREFIX_PATH
|
||||
|
||||
# Nonstandard python versions
|
||||
if [[ "${PYTHON_VERSION}" == "3.9" ]] ; then
|
||||
time sudo apt-get -q install -y python3.9-dev python3-numpy
|
||||
pip3 --version
|
||||
pip3 install numpy
|
||||
elif [[ "$PYTHON_VERSION" == "2.7" ]] ; then
|
||||
time sudo apt-get -q install -y python-dev python-numpy
|
||||
else
|
||||
pip3 install numpy
|
||||
fi
|
||||
|
||||
if [[ "$CXX" == "g++-6" ]] ; then
|
||||
time sudo apt-get install -y g++-6
|
||||
elif [[ "$CXX" == "g++-7" ]] ; then
|
||||
@@ -85,6 +106,8 @@ else
|
||||
time sudo apt-get install -y g++-10
|
||||
elif [[ "$CXX" == "g++-11" ]] ; then
|
||||
time sudo apt-get install -y g++-11
|
||||
elif [[ "$CXX" == "g++-12" ]] ; then
|
||||
time sudo apt-get install -y g++-12
|
||||
fi
|
||||
|
||||
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" || "$CXX" == "icpx" || "$CC" == "icx" || "$USE_ICX" != "" ]] ; then
|
||||
@@ -92,22 +115,11 @@ else
|
||||
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
|
||||
time sudo apt-get update
|
||||
time sudo apt-get install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic
|
||||
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||
if [[ "$CXX" == "icpc" || "$CC" == "icc" || "$USE_ICC" != "" ]] ; then
|
||||
icpc --version
|
||||
fi
|
||||
if [[ "$CXX" == "icpx" || "$CC" == "icx" || "$USE_ICX" != "" ]] ; then
|
||||
icpx --version
|
||||
fi
|
||||
fi
|
||||
|
||||
# Nonstandard python versions
|
||||
if [[ "${PYTHON_VERSION}" == "3.8" ]] ; then
|
||||
#time sudo apt-get -q install -y python3.8-dev python3-numpy
|
||||
echo "skip?"
|
||||
elif [[ "${PYTHON_VERSION}" == "3.9" ]] ; then
|
||||
time sudo apt-get -q install -y python3.9-dev python3-numpy
|
||||
time sudo apt-get 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.
|
||||
set +e; source /opt/intel/oneapi/setvars.sh --config oneapi_2022.1.0.cfg; set -e
|
||||
fi
|
||||
|
||||
source src/build-scripts/build_llvm.bash
|
||||
@@ -164,7 +176,7 @@ if [[ "$OPENIMAGEIO_VERSION" != "" ]] ; then
|
||||
# Don't let warnings in OIIO break OSL's CI run
|
||||
export OPENIMAGEIO_CMAKE_FLAGS+=" -DSTOP_ON_WARNING=OFF"
|
||||
export OPENIMAGEIO_CMAKE_FLAGS+=" -DUSE_OPENGL=0"
|
||||
if [[ $OPENIMAGEIO_VERSION == master ]] ; then
|
||||
if [[ $OPENIMAGEIO_VERSION == master && "${OPENIMAGEIO_UNITY:-1}" != "0" ]] ; then
|
||||
# Speed up the OIIO build by doing a "unity" build. (Note: this is
|
||||
# only a savings in CI where there are only 1-2 cores available, and
|
||||
# is only supported for OIIO 2.3.14 and later)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
# This script, which assumes it is runnign on a Mac OSX with Homebrew
|
||||
# This script, which assumes it is running on a Mac OSX with Homebrew
|
||||
# installed, does a "brew install" in all packages reasonably needed by
|
||||
# OSL and its dependencies.
|
||||
|
||||
@@ -19,27 +19,33 @@ if [[ `which brew` == "" ]] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
#brew update >/dev/null
|
||||
if [[ "$DO_BREW_UPDATE" != "" ]] ; then
|
||||
brew update >/dev/null
|
||||
fi
|
||||
echo ""
|
||||
echo "Before my brew installs:"
|
||||
brew list --versions
|
||||
|
||||
brew install --display-times -q gcc ccache cmake ninja boost || true
|
||||
brew link --overwrite gcc
|
||||
brew unlink python@2.7 || true
|
||||
brew unlink python@3.9 || true
|
||||
brew unlink python@3.8 || true
|
||||
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@3.10 || true
|
||||
brew link --overwrite --force python@${PYTHON_VERSION} || true
|
||||
brew upgrade --display-times -q cmake || true
|
||||
brew install --display-times -q ilmbase openexr
|
||||
brew install --display-times -q imath openexr
|
||||
#brew install --display-times -q freetype
|
||||
brew install --display-times -q opencolorio partio pugixml
|
||||
brew install --display-times -q --overwrite --force opencolorio || true
|
||||
brew install --display-times -q partio pugixml
|
||||
brew install --display-times -q pybind11 numpy || true
|
||||
brew install --display-times -q tbb || true
|
||||
brew install --display-times -q flex bison
|
||||
brew install --display-times -q llvm${LLVMBREWVER}
|
||||
brew install --display-times -q qt
|
||||
brew install --display-times -q qt${QT_BREW_VERSION}
|
||||
|
||||
echo ""
|
||||
echo "After brew installs:"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
leak:Imf_2_2
|
||||
leak:Imf_2_3
|
||||
leak:Imf_2_4
|
||||
leak:libIlmImf
|
||||
leak:oslgram.y
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
default=exclude
|
||||
compiler=2022.1.0
|
||||
tbb=2021.6.0
|
||||
Regular → Executable
+1
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
@@ -22,7 +22,7 @@ find_dependency(OpenImageIO @OpenImageIO_VERSION@ REQUIRED)
|
||||
# Compute the installation prefix relative to this file
|
||||
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
|
||||
|
||||
# There's no guarantee that CMAKE_INSTALL_XXXDIR is a relative path so we extract the final component to handle asbolute paths
|
||||
# There's no guarantee that CMAKE_INSTALL_XXXDIR is a relative path so we extract the final component to handle absolute paths
|
||||
get_filename_component(_INCLUDE_DIR_NAME "@CMAKE_INSTALL_INCLUDEDIR@" NAME)
|
||||
get_filename_component(_LIB_DIR_NAME "@CMAKE_INSTALL_LIBDIR@" NAME)
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ endif ()
|
||||
|
||||
|
||||
|
||||
# We wil use this for ccache and timing
|
||||
# We will use this for ccache and timing
|
||||
set (MY_RULE_LAUNCH "")
|
||||
|
||||
|
||||
@@ -376,11 +376,9 @@ include (CheckCXXSourceRuns)
|
||||
option (CODECOV "Build code coverage tests" OFF)
|
||||
if (CODECOV AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
|
||||
message (STATUS "Compiling for code coverage analysis")
|
||||
add_compile_options ("-ftest-coverage -fprofile-arcs -O0")
|
||||
add_compile_options (-ftest-coverage -fprofile-arcs)
|
||||
add_definitions ("-D${PROJ_NAME}_CODE_COVERAGE=1")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
|
||||
link_libraries(gcov)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -394,22 +392,9 @@ if (SANITIZE AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
|
||||
foreach (feature ${SANITIZE_FEATURE_LIST})
|
||||
message (STATUS " sanitize feature: ${feature}")
|
||||
add_compile_options (-fsanitize=${feature})
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${feature}")
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=${feature}")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=${feature}")
|
||||
add_link_options (-fsanitize=${feature})
|
||||
endforeach()
|
||||
add_compile_options (-g -fno-omit-frame-pointer)
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set (SANITIZE_ON_LINUX 1)
|
||||
endif ()
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
add_compile_options ("-fuse-ld=gold")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold")
|
||||
set (SANITIZE_LIBRARIES "asan;pthread")
|
||||
# set (SANITIZE_LIBRARIES "asan" "ubsan")
|
||||
endif()
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
# turn on glibcxx extra annotations to find vector writes past end
|
||||
add_definitions ("-D_GLIBCXX_SANITIZE_VECTOR=1")
|
||||
@@ -475,29 +460,7 @@ endif ()
|
||||
# is being built as a subproject.
|
||||
if (PROJECT_IS_TOP_LEVEL)
|
||||
set (CLANG_FORMAT_EXE_HINT "" CACHE PATH "clang-format executable's directory (will search if not specified")
|
||||
set (CLANG_FORMAT_INCLUDES # "src/*.cpp"
|
||||
"src/*.h"
|
||||
"src/*.cu"
|
||||
"src/include/*.h"
|
||||
"src/liboslcomp/*.cpp"
|
||||
"src/liboslcomp/*.h"
|
||||
"src/liboslexec/batch*.cpp"
|
||||
"src/liboslexec/wide/*.cpp"
|
||||
"src/liboslexec/wide/*.h"
|
||||
"src/liboslexec/rs_fallback.cpp"
|
||||
"src/liboslquery/*.cpp"
|
||||
"src/liboslnoise/*.cpp"
|
||||
"src/liboslquery/*.h"
|
||||
"src/oslinfo/*.cpp"
|
||||
"src/oslc/*.cpp"
|
||||
"src/osl.imageio/*.cpp"
|
||||
"src/osltoy/*.cpp"
|
||||
"src/osltoy/*.h"
|
||||
"src/testrender/*.h"
|
||||
"src/testrender/*.cpp"
|
||||
"src/testshade/*.h"
|
||||
"src/testshade/*.cpp"
|
||||
"testsuite/*.cpp"
|
||||
set (CLANG_FORMAT_INCLUDES "src/*.cpp" "src/*.h" "src/*.cu"
|
||||
CACHE STRING "Glob patterns to include for clang-format")
|
||||
set (CLANG_FORMAT_EXCLUDES
|
||||
# Files "imported and modified" that we don't want to reformat, so
|
||||
@@ -508,7 +471,6 @@ if (PROJECT_IS_TOP_LEVEL)
|
||||
"testsuite/*.h"
|
||||
# Header files in shaders are OSL, not C++
|
||||
"src/shaders/*.h"
|
||||
""
|
||||
CACHE STRING "Glob patterns to exclude for clang-format")
|
||||
find_program (CLANG_FORMAT_EXE
|
||||
NAMES clang-format bin/clang-format
|
||||
@@ -529,7 +491,7 @@ if (PROJECT_IS_TOP_LEVEL)
|
||||
# message (STATUS "clang-format file list: ${FILES_TO_FORMAT}")
|
||||
file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/.clang-format
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_custom_target (run-clang-format
|
||||
add_custom_target (clang-format
|
||||
COMMAND "${CLANG_FORMAT_EXE}" -i -style=file ${FILES_TO_FORMAT} )
|
||||
else ()
|
||||
message (STATUS "clang-format not found.")
|
||||
|
||||
@@ -21,6 +21,12 @@ function ( NVCC_COMPILE cuda_src extra_headers ptx_generated extra_nvcc_args )
|
||||
list (TRANSFORM OpenImageIO_INCLUDES PREPEND -I
|
||||
OUTPUT_VARIABLE ALL_OpenImageIO_INCLUDES)
|
||||
|
||||
if (${LLVM_VERSION} VERSION_GREATER_EQUAL 15.0)
|
||||
# Until we fully support opaque pointers, we need to disable
|
||||
# them when using LLVM 15.
|
||||
list (APPEND LLVM_COMPILE_FLAGS -Xclang -no-opaque-pointers)
|
||||
endif ()
|
||||
|
||||
add_custom_command ( OUTPUT ${cuda_ptx}
|
||||
COMMAND ${CUDA_NVCC_EXECUTABLE}
|
||||
"-I${OPTIX_INCLUDES}"
|
||||
|
||||
@@ -88,7 +88,7 @@ checked_find_package (OpenEXR REQUIRED
|
||||
)
|
||||
# Force Imath includes to be before everything else to ensure that we have
|
||||
# the right Imath/OpenEXR version, not some older version in the system
|
||||
# library. This shoudn't be necessary, except for the common case of people
|
||||
# library. This shouldn't be necessary, except for the common case of people
|
||||
# building against Imath/OpenEXR 3.x when there is still a system-level
|
||||
# install version of 2.x.
|
||||
include_directories(BEFORE ${IMATH_INCLUDES})
|
||||
@@ -115,6 +115,7 @@ checked_find_package (pugixml REQUIRED
|
||||
# LLVM library setup
|
||||
checked_find_package (LLVM REQUIRED
|
||||
VERSION_MIN 9.0
|
||||
VERSION_MAX 15.9
|
||||
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES)
|
||||
# ensure include directory is added (in case of non-standard locations
|
||||
include_directories (BEFORE SYSTEM "${LLVM_INCLUDES}")
|
||||
@@ -136,6 +137,27 @@ if (APPLE AND LLVM_VERSION VERSION_EQUAL 10.0.1 AND EXISTS "/usr/local/Cellar/ll
|
||||
" brew upgrade llvm \n"
|
||||
"${ColorReset}\n")
|
||||
endif ()
|
||||
if (LLVM_VERSION VERSION_GREATER_EQUAL 15.0
|
||||
AND ( (CMAKE_COMPILER_IS_APPLECLANG AND APPLECLANG_VERSION_STRING VERSION_LESS 15.0)
|
||||
OR (CMAKE_COMPILER_IS_CLANG AND CLANG_VERSION_STRING VERSION_LESS 15.0)))
|
||||
message (WARNING
|
||||
"${ColorYellow}"
|
||||
"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)
|
||||
|
||||
@@ -145,58 +167,61 @@ 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)
|
||||
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")
|
||||
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 ()
|
||||
endif ()
|
||||
|
||||
|
||||
# CUDA setup
|
||||
if (USE_CUDA OR USE_OPTIX)
|
||||
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
|
||||
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
|
||||
endif ()
|
||||
if (USE_LLVM_BITCODE)
|
||||
if (NOT CUDA_TOOLKIT_ROOT_DIR AND NOT $ENV{CUDA_TOOLKIT_ROOT_DIR} STREQUAL "")
|
||||
set (CUDA_TOOLKIT_ROOT_DIR $ENV{CUDA_TOOLKIT_ROOT_DIR})
|
||||
endif ()
|
||||
|
||||
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
|
||||
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
endif ()
|
||||
if (NOT CUDA_FIND_QUIETLY OR NOT OptiX_FIND_QUIETLY)
|
||||
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
endif ()
|
||||
|
||||
checked_find_package (CUDA REQUIRED
|
||||
VERSION_MIN 8.0
|
||||
PRINT CUDA_INCLUDES)
|
||||
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
|
||||
include_directories (BEFORE "${CUDA_INCLUDES}")
|
||||
checked_find_package (CUDA REQUIRED
|
||||
VERSION_MIN 8.0
|
||||
PRINT CUDA_INCLUDES)
|
||||
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
|
||||
include_directories (BEFORE "${CUDA_INCLUDES}")
|
||||
|
||||
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
|
||||
if (NOT ${nvptx_index} GREATER -1)
|
||||
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
|
||||
endif()
|
||||
STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
|
||||
if (NOT ${nvptx_index} GREATER -1)
|
||||
message (FATAL_ERROR "NVPTX target is not available in the provided LLVM build")
|
||||
endif()
|
||||
|
||||
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
set (CUDA_LIB_FLAGS "--cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
|
||||
find_library(cuda_lib NAMES cudart
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${cuda_lib})
|
||||
find_library(cuda_lib NAMES cudart
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${cuda_lib})
|
||||
|
||||
# testrender & testshade need libnvrtc
|
||||
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
|
||||
find_library(nvrtc_lib NAMES nvrtc
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
|
||||
# testrender & testshade need libnvrtc
|
||||
if ("${CUDA_VERSION}" VERSION_GREATER_EQUAL "10.0")
|
||||
find_library(nvrtc_lib NAMES nvrtc
|
||||
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64"
|
||||
REQUIRED)
|
||||
set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${nvrtc_lib})
|
||||
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# OptiX setup
|
||||
if (USE_OPTIX)
|
||||
if (USE_OPTIX AND OSL_BUILD_TESTS)
|
||||
checked_find_package (OptiX REQUIRED
|
||||
VERSION_MIN 5.1)
|
||||
include_directories (BEFORE "${OPTIX_INCLUDES}")
|
||||
@@ -211,7 +236,6 @@ if (USE_CUDA OR USE_OPTIX)
|
||||
target_compile_definitions (${TARGET} PRIVATE "-DPTX_PATH=\"${OSL_PTX_INSTALL_DIR}\"")
|
||||
target_link_libraries (${TARGET} PRIVATE ${CUDA_LIBRARIES} ${CUDA_EXTRA_LIBS} ${OPTIX_LIBRARIES} ${OPTIX_EXTRA_LIBS})
|
||||
endfunction()
|
||||
|
||||
else ()
|
||||
function (osl_optix_target TARGET)
|
||||
endfunction()
|
||||
|
||||
@@ -82,6 +82,11 @@ function ( EMBED_LLVM_BITCODE_IN_CPP src_list suffix output_name list_to_append_
|
||||
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 ()
|
||||
|
||||
# Command to turn the .cpp file into LLVM assembly language .s, into
|
||||
# LLVM bitcode .bc, then back into a C++ file with the bc embedded!
|
||||
@@ -103,8 +108,8 @@ function ( EMBED_LLVM_BITCODE_IN_CPP src_list suffix output_name list_to_append_
|
||||
-O3 -fno-math-errno -S -emit-llvm ${extra_clang_args}
|
||||
-o ${src_asm} ${src}
|
||||
COMMAND ${LLVM_AS_TOOL} -f -o ${src_bc} ${src_asm}
|
||||
# Do NOT setup a MAIN_DEPENDENCY because only 1 may exist
|
||||
# and we may have the several outputs dependant on the same source
|
||||
# Do NOT setup a MAIN_DEPENDENCY because only 1 may exist
|
||||
# and we may have the several outputs dependent on the same source
|
||||
DEPENDS ${src} ${exec_headers} ${PROJECT_PUBLIC_HEADERS}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" )
|
||||
endforeach ()
|
||||
@@ -132,7 +137,7 @@ function ( EMBED_LLVM_BITCODE_IN_CPP src_list suffix output_name list_to_append_
|
||||
${exec_headers} ${PROJECT_PUBLIC_HEADERS}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" )
|
||||
|
||||
# add generated .cpp with embedded bitcode to the list of soures
|
||||
# add generated .cpp with embedded bitcode to the list of sources
|
||||
set ( ${list_to_append_cpp} ${${list_to_append_cpp}} ${src_bc_cpp} PARENT_SCOPE )
|
||||
|
||||
endfunction ( )
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
|
||||
# try to find llvm-config, with a specific version if specified
|
||||
if (LLVM_DIRECTORY)
|
||||
set (LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_DIRECTORY}/bin")
|
||||
endif ()
|
||||
if (LLVM_ROOT)
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "${LLVM_ROOT}/bin")
|
||||
endif ()
|
||||
if (DEFINED ENV{LLVM_ROOT})
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS "$ENV{LLVM_ROOT}/bin")
|
||||
endif ()
|
||||
list (APPEND LLVM_CONFIG_PATH_HINTS
|
||||
"/usr/local/opt/llvm/${LLVM_VERSION}/bin/"
|
||||
@@ -121,7 +127,7 @@ endif ()
|
||||
|
||||
foreach (COMPONENT clangFrontend clangDriver clangSerialization
|
||||
clangParse clangSema clangAnalysis clangAST clangBasic
|
||||
clangEdit clangLex)
|
||||
clangEdit clangLex clangSupport)
|
||||
find_library ( _CLANG_${COMPONENT}_LIBRARY
|
||||
NAMES ${COMPONENT}
|
||||
PATHS ${LLVM_LIB_DIR})
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# PARTIO_LIBRARIES - library to link against
|
||||
# PARTIO_FOUND - true if Partio was found.
|
||||
|
||||
# Hack! perfer a config if it can be found
|
||||
# Hack! prefer a config if it can be found
|
||||
find_package(partio CONFIG)
|
||||
if (PARTIO_FOUND OR partio_FOUND)
|
||||
if (VERBOSE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright Contributors to the Open Shading Languge project.
|
||||
# Copyright Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/
|
||||
|
||||
|
||||
@@ -20,12 +20,9 @@ macro (find_python)
|
||||
|
||||
# Attempt to find the desired version, but fall back to other
|
||||
# additional versions.
|
||||
unset (_req)
|
||||
if (USE_PYTHON)
|
||||
set (_req REQUIRED)
|
||||
if (PYTHON_VERSION)
|
||||
list (APPEND _req EXACT)
|
||||
endif ()
|
||||
set (_req REQUIRED)
|
||||
if (PYTHON_VERSION)
|
||||
list (APPEND _req EXACT)
|
||||
endif ()
|
||||
checked_find_package (Python ${PYTHON_VERSION}
|
||||
${_req}
|
||||
@@ -77,7 +74,7 @@ macro (setup_python_module)
|
||||
PRIVATE
|
||||
pybind11::pybind11
|
||||
Python::Python
|
||||
${lib_LIBS} ${SANITIZE_LIBRARIES})
|
||||
${lib_LIBS})
|
||||
if (APPLE)
|
||||
set_target_properties (${target_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||
endif ()
|
||||
|
||||
+61
-27
@@ -1,4 +1,4 @@
|
||||
# Copyright Contributors to the Open Shading Languge project.
|
||||
# Copyright Contributors to the Open Shading Language project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/
|
||||
|
||||
@@ -16,6 +16,10 @@ add_custom_command (OUTPUT "${CMAKE_BINARY_DIR}/testsuite/runtest.py"
|
||||
MAIN_DEPENDENCY "${CMAKE_SOURCE_DIR}/testsuite/runtest.py")
|
||||
add_custom_target ( CopyFiles ALL DEPENDS "${CMAKE_BINARY_DIR}/testsuite/runtest.py" )
|
||||
|
||||
|
||||
set (OSL_TEST_BIG_TIMEOUT 800 CACHE STRING "Timeout for tests that take a long time")
|
||||
|
||||
|
||||
# add_one_testsuite() - set up one testsuite entry
|
||||
#
|
||||
# Usage:
|
||||
@@ -26,10 +30,12 @@ add_custom_target ( CopyFiles ALL DEPENDS "${CMAKE_BINARY_DIR}/testsuite/runtest
|
||||
# [COMMAND cmd...] - optional override of launch command
|
||||
# )
|
||||
#
|
||||
|
||||
macro (add_one_testsuite testname testsrcdir)
|
||||
cmake_parse_arguments (_tst "" "" "ENV;COMMAND" ${ARGN})
|
||||
set (testsuite "${CMAKE_SOURCE_DIR}/testsuite")
|
||||
set (testdir "${CMAKE_BINARY_DIR}/testsuite/${testname}")
|
||||
file (MAKE_DIRECTORY "${testdir}")
|
||||
if (NOT _tst_COMMAND)
|
||||
set (_tst_COMMAND ${Python_EXECUTABLE} "${testsuite}/runtest.py" ${testdir})
|
||||
if (MSVC_IDE)
|
||||
@@ -45,7 +51,17 @@ macro (add_one_testsuite testname testsrcdir)
|
||||
OSL_TESTSUITE_SRC=${testsrcdir}
|
||||
OSL_TESTSUITE_CUR=${testdir}
|
||||
)
|
||||
file (MAKE_DIRECTORY "${testdir}")
|
||||
|
||||
# We need to suppress the leak sanitizer for "texture" tests, because of a
|
||||
# minor leak inside OIIO (140 bytes! -- inconsequential) but which we
|
||||
# can't use the suppressions list becuase the leaks come from calls made
|
||||
# inside JITed code for which there is not a good stack trace. Any real
|
||||
# leaks from OIIO or its dependencies we assume will be caught by lsan on
|
||||
# the OIIO side, where there is no JIT to complicate things.
|
||||
if (${testname} MATCHES "^texture" OR ${testname} MATCHES "gettextureinfo")
|
||||
list (APPEND _tst_ENV ASAN_OPTIONS=detect_leaks=0:$ENV{ASAN_OPTIONS})
|
||||
endif ()
|
||||
|
||||
add_test ( NAME ${testname} COMMAND ${_tst_COMMAND} )
|
||||
# message ("Test -- env ${_tst_ENV} cmd ${_tst_COMMAND}")
|
||||
set_tests_properties (${testname} PROPERTIES ENVIRONMENT "${_tst_ENV}" )
|
||||
@@ -53,8 +69,11 @@ macro (add_one_testsuite testname testsrcdir)
|
||||
# from piling up together, allocate a few cores each.
|
||||
if (${testname} MATCHES "^render-")
|
||||
set_tests_properties (${testname} PROPERTIES LABELS render
|
||||
TIMEOUT 240
|
||||
PROCESSORS 4 COST 10 TIMEOUT 240)
|
||||
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")
|
||||
@@ -76,7 +95,7 @@ macro (add_one_testsuite testname testsrcdir)
|
||||
# These are batched shading regression tests. Some are quite
|
||||
# long, so give them a higher cost and timeout.
|
||||
set_tests_properties (${testname} PROPERTIES LABELS batchregression
|
||||
COST 15 TIMEOUT 300)
|
||||
COST 15 TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
@@ -107,7 +126,7 @@ macro ( TESTSUITE )
|
||||
|
||||
# Run the test unoptimized, unless it matches a few patterns that
|
||||
# we don't test unoptimized (or has an OPTIMIZEONLY marker file).
|
||||
if (NOT _testname MATCHES "optix"
|
||||
if (NOT _testname MATCHES "optix"
|
||||
AND NOT EXISTS "${_testsrcdir}/NOSCALAR"
|
||||
AND NOT EXISTS "${_testsrcdir}/BATCHED_REGRESSION"
|
||||
AND NOT EXISTS "${_testsrcdir}/OPTIMIZEONLY")
|
||||
@@ -142,7 +161,7 @@ macro ( TESTSUITE )
|
||||
add_one_testsuite ("${_testname}.optix.opt" "${_testsrcdir}"
|
||||
ENV TESTSHADE_OPT=2 TESTSHADE_OPTIX=1 )
|
||||
endif ()
|
||||
|
||||
|
||||
if (BUILD_BATCHED)
|
||||
# When building for Batched support, also run it in Batched mode
|
||||
# if there is an BATCHED marker file in the directory.
|
||||
@@ -156,7 +175,7 @@ macro ( TESTSUITE )
|
||||
add_one_testsuite ("${_testname}.batched" "${_testsrcdir}"
|
||||
ENV TESTSHADE_OPT=0 TESTSHADE_BATCHED=1 )
|
||||
endif ()
|
||||
|
||||
|
||||
if ((EXISTS "${_testsrcdir}/BATCHED" OR test_all_batched OR _testname MATCHES "batched")
|
||||
AND NOT EXISTS "${_testsrcdir}/BATCHED_REGRESSION"
|
||||
AND NOT EXISTS "${_testsrcdir}/NOBATCHED"
|
||||
@@ -165,7 +184,7 @@ macro ( TESTSUITE )
|
||||
add_one_testsuite ("${_testname}.batched.opt" "${_testsrcdir}"
|
||||
ENV TESTSHADE_OPT=2 TESTSHADE_BATCHED=1 )
|
||||
endif ()
|
||||
|
||||
|
||||
# When building for Batched support, optionally run a regression test
|
||||
# if there is an BATCHED_REGRESSION marker file in the directory.
|
||||
if ((EXISTS "${_testsrcdir}/BATCHED_REGRESSION")
|
||||
@@ -211,16 +230,17 @@ macro (osl_add_all_tests)
|
||||
# special installed tests.
|
||||
TESTSUITE ( aastep allowconnect-err andor-reg and-or-not-synonyms
|
||||
arithmetic area-reg arithmetic-reg
|
||||
array array-reg array-copy-reg array-derivs array-range
|
||||
array array-reg array-copy-reg array-derivs array-range
|
||||
array-aassign array-assign-reg array-length-reg
|
||||
bitwise-and-reg bitwise-or-reg bitwise-shl-reg bitwise-shr-reg bitwise-xor-reg
|
||||
blackbody blackbody-reg blendmath breakcont breakcont-reg
|
||||
bug-array-heapoffsets bug-locallifetime bug-outputinit
|
||||
bug-param-duplicate bug-peep bug-return
|
||||
calculatenormal-reg
|
||||
cellnoise closure closure-array color color-reg colorspace comparison
|
||||
cellnoise closure closure-array closure-parameters closure-zero closure-conditional
|
||||
color color-reg colorspace comparison
|
||||
complement-reg compile-buffer compassign-reg
|
||||
component-range
|
||||
component-range
|
||||
control-flow-reg connect-components
|
||||
const-array-params const-array-fill
|
||||
debugnan debug-uninit
|
||||
@@ -239,7 +259,9 @@ macro (osl_add_all_tests)
|
||||
globals-needed
|
||||
group-outputs groupstring
|
||||
hash hashnoise hex hyperb
|
||||
ieee_fp ieee_fp-reg if if-reg incdec initlist initops intbits isconnected
|
||||
ieee_fp ieee_fp-reg if if-reg incdec initlist
|
||||
initops initops-instance-clash
|
||||
intbits isconnected
|
||||
isconstant
|
||||
layers layers-Ciassign layers-entry layers-lazy layers-lazyerror
|
||||
layers-nonlazycopy layers-repeatedoutputs
|
||||
@@ -259,7 +281,7 @@ macro (osl_add_all_tests)
|
||||
noise-perlin noise-simplex
|
||||
noise-reg
|
||||
normalize-reg
|
||||
pnoise pnoise-cell pnoise-gabor
|
||||
pnoise pnoise-cell pnoise-gabor
|
||||
pnoise-generic pnoise-perlin
|
||||
pnoise-reg
|
||||
operator-overloading
|
||||
@@ -291,11 +313,21 @@ macro (osl_add_all_tests)
|
||||
raytype raytype-reg raytype-specialized regex-reg reparam
|
||||
render-background render-bumptest
|
||||
render-cornell render-furnace-diffuse
|
||||
render-mx-furnace-burley-diffuse
|
||||
render-mx-furnace-oren-nayar
|
||||
render-mx-furnace-sheen
|
||||
render-mx-burley-diffuse
|
||||
render-mx-dielectric render-mx-dielectric-glass
|
||||
render-mx-conductor
|
||||
render-mx-generalized-schlick render-mx-generalized-schlick-glass
|
||||
render-mx-layer
|
||||
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
|
||||
smoothstep-reg
|
||||
spline spline-reg splineinverse splineinverse-ident
|
||||
splineinverse-knots-ascend-reg splineinverse-knots-descend-reg
|
||||
spline-boundarybug spline-derivbug
|
||||
split-reg
|
||||
@@ -319,10 +351,10 @@ macro (osl_add_all_tests)
|
||||
trailing-commas
|
||||
transcendental-reg
|
||||
transitive-assign
|
||||
transform transform-reg transformc transformc-reg trig trig-reg
|
||||
transform transform-reg transformc transformc-reg trig trig-reg
|
||||
typecast
|
||||
unknown-instruction
|
||||
userdata userdata-passthrough
|
||||
userdata userdata-custom userdata-passthrough
|
||||
vararray-connect vararray-default
|
||||
vararray-deserialize vararray-param
|
||||
vecctr vector vector-reg
|
||||
@@ -339,10 +371,10 @@ macro (osl_add_all_tests)
|
||||
endif ()
|
||||
|
||||
# Add tests that require the Python bindings if we built them.
|
||||
# We also exclude these tests if this is a sanitizer build on Linux,
|
||||
# because the Python interpreter itself won't be linked with the right asan
|
||||
# We also exclude these tests if this is a sanitizer build, because the
|
||||
# Python interpreter itself won't be linked with the right asan
|
||||
# libraries to run correctly.
|
||||
if (USE_PYTHON AND NOT SANITIZE_ON_LINUX)
|
||||
if (USE_PYTHON AND NOT SANITIZE)
|
||||
TESTSUITE ( python-oslquery )
|
||||
endif ()
|
||||
|
||||
@@ -354,7 +386,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 ()
|
||||
|
||||
@@ -363,11 +395,13 @@ macro (osl_add_all_tests)
|
||||
TESTSUITE ( testoptix testoptix-noise example-cuda)
|
||||
endif ()
|
||||
|
||||
# Some regression tests have alot of combinations and may need more time to finish
|
||||
# Some regression tests have a lot of combinations and may need more time to finish
|
||||
if (BUILD_BATCHED)
|
||||
set_tests_properties (arithmetic-reg.regress.batched.opt PROPERTIES TIMEOUT 800)
|
||||
set_tests_properties (transform-reg.regress.batched.opt PROPERTIES TIMEOUT 800)
|
||||
set_tests_properties (arithmetic-reg.regress.batched.opt
|
||||
PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
set_tests_properties (transform-reg.regress.batched.opt
|
||||
PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endif ()
|
||||
set_tests_properties (matrix-reg.regress.rsbitcode.opt PROPERTIES TIMEOUT 800)
|
||||
|
||||
set_tests_properties (matrix-reg.regress.rsbitcode.opt
|
||||
PROPERTIES TIMEOUT ${OSL_TEST_BIG_TIMEOUT})
|
||||
endmacro()
|
||||
|
||||
+773
-111
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -11,7 +11,7 @@
|
||||
_testshade_ basics
|
||||
==================================================
|
||||
|
||||
The OSL software distribution inculdes `testshade`, a command-line utility
|
||||
The OSL software distribution includes `testshade`, a command-line utility
|
||||
that was written for OSL unit tests, and for a "test harness" in which we
|
||||
can execute shaders for debugging (the shaders or OSL itself) in isolation
|
||||
from any particular rendering system.
|
||||
@@ -28,7 +28,7 @@ itself, it has a number of potential uses in a production studio, including:
|
||||
* Baking procedural patterns into textures.
|
||||
|
||||
* Benchmarking shaders and evaluating their performance, including
|
||||
comparitive tests such as "is it faster to code it this way or that way?"
|
||||
comparative tests such as "is it faster to code it this way or that way?"
|
||||
|
||||
* Exploring the inner workings of OSL's runtime optimizer, to answer
|
||||
questions like: "will this idiom optimize away at runtime when I use
|
||||
@@ -176,7 +176,7 @@ Helpful command line arguments:
|
||||
|
||||
For the sake of simplicity, this document presents almost all examples as if
|
||||
they consisted of just a single shader node. But `testshade` is able to
|
||||
specify and execut entire shader groups (networks of shader nodes). The
|
||||
specify and execute entire shader groups (networks of shader nodes). The
|
||||
remainder of this section will explain how this can be done.
|
||||
|
||||
Let's make a simple shader network as an example.
|
||||
@@ -582,7 +582,7 @@ single texture lookup.
|
||||
|
||||
|
||||
|
||||
## Controling optimization
|
||||
## Controlling optimization
|
||||
|
||||
You can control the optimization level overall:
|
||||
|
||||
@@ -638,7 +638,7 @@ that they are not optimized away so as to lead you to an inaccurate
|
||||
reflection of what optimizations would really happen at render time. At the
|
||||
same time, be careful not to inadvertently set `lockgeom=0` for parameters
|
||||
that will typically be set to default values, instance values, or
|
||||
connections from layers that are likely to be analized and found to emit
|
||||
connections from layers that are likely to be analyzed and found to emit
|
||||
constants for theor outputs -- you also don't want your benchmarks to
|
||||
incorrectly disable optimizations what would typically happen at render
|
||||
time.
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
AccumRule(int outidx, bool toalpha)
|
||||
: m_outidx(outidx), m_save_to_alpha(toalpha) {};
|
||||
|
||||
/// Called to accumulate from AccumAutomata. It will select the right ouput from
|
||||
/// Called to accumulate from AccumAutomata. It will select the right output from
|
||||
/// the given vector based in the AOV index number (they are guaranteed to match)
|
||||
void accum(const Color3& color, std::vector<AovOutput>& outputs) const;
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
#ifdef __CUDA_ARCH__
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
// USAGE NOTES:
|
||||
//
|
||||
// To define a "standard" DeviceString, add a STRDECL to <OSL/strdecls.h>
|
||||
@@ -68,7 +64,10 @@ struct DeviceString {
|
||||
// In OptiX 7 we can't return the string's contents. Make this a compile
|
||||
// time error.
|
||||
#if !(defined(__CUDA_ARCH__) && OPTIX_VERSION >= 70000)
|
||||
OSL_HOSTDEVICE const char* c_str() const { return m_chars; }
|
||||
OSL_HOSTDEVICE const char* c_str() const
|
||||
{
|
||||
return m_chars;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSL_HOSTDEVICE bool operator==(const DeviceString& other) const
|
||||
@@ -93,7 +92,10 @@ struct DeviceString {
|
||||
return hash() != other;
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE operator size_t() const { return hash(); }
|
||||
OSL_HOSTDEVICE operator size_t() const
|
||||
{
|
||||
return hash();
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
// delegating access to element storage to the DualStorage base class
|
||||
template<
|
||||
class T, // Base data type
|
||||
int PARTIALS=1 // Number of dimentions of partial derivs
|
||||
int PARTIALS=1 // Number of dimensions of partial derivs
|
||||
>
|
||||
class Dual : public DualStorage<T, PARTIALS> {
|
||||
static const int elements = PARTIALS+1; // main value + partials
|
||||
|
||||
+40
-23
@@ -223,7 +223,7 @@ public:
|
||||
|
||||
// Look up the TargetISA enum by name. Special names: "host" means
|
||||
// figure out what this host is, "none" or "" mean to use the baseline
|
||||
// or no special ops not availabe on all flavors of this family of CPUs.
|
||||
// or no special ops not available on all flavors of this family of CPUs.
|
||||
static TargetISA lookup_isa_by_name(string_view target_name = "");
|
||||
|
||||
// Name for this TargetISA enum.
|
||||
@@ -383,13 +383,13 @@ public:
|
||||
// vs. relying on a conditional result already in a register.
|
||||
//
|
||||
// To handle 'continue', we allocate a 'continue mask' that is
|
||||
// initially populated with a 0 representing the deactived lanes by
|
||||
// initially populated with a 0 representing the deactivated lanes by
|
||||
// 'continue' operations. We require a location on the stack for each
|
||||
// 'continue mask' in order for a 'continue' statement to modify it and
|
||||
// cause a subset of the lanes to be deactivated. If an continue was
|
||||
// processed, the 'continue mask' is where it will be stored and pulled
|
||||
// from when applying to the unwinding conditional mask stack. When a
|
||||
// loop's scope is exited, the continue mask is popped so it would't be
|
||||
// loop's scope is exited, the continue mask is popped so it wouldn't be
|
||||
// applied to an outer loop.
|
||||
//
|
||||
// The logic of when and how to actually apply these masks is handled
|
||||
@@ -638,6 +638,12 @@ public:
|
||||
/// llvm type.
|
||||
llvm::Type* type_array(llvm::Type* type, int n);
|
||||
|
||||
/// Return the true if the llvm::Type is an array
|
||||
bool is_type_array(llvm::Type* type);
|
||||
|
||||
/// Return the llvm::Type of element that the array_type is made up of
|
||||
llvm::Type* element_type_of(llvm::Type* array_type);
|
||||
|
||||
/// Return an llvm::FunctionType that describes a function with the
|
||||
/// given return types, parameter types (in a cspan), and whether it
|
||||
/// uses varargs conventions.
|
||||
@@ -660,26 +666,26 @@ public:
|
||||
/// Return the human-readable name of the type of the llvm value.
|
||||
std::string llvm_typenameof(llvm::Value* val) const;
|
||||
|
||||
/// Return an llvm::Value holding the given floating point constant.
|
||||
/// Return an llvm::Constant holding the given floating point constant.
|
||||
llvm::Constant* constant(float f);
|
||||
|
||||
/// Return an llvm::Value holding the given integer constant.
|
||||
/// Return an llvm::Constant holding the given integer constant.
|
||||
llvm::Constant* constant(int i);
|
||||
|
||||
/// Return an llvm::Value holding the given integer constant.
|
||||
/// Return an llvm::Constant holding the given integer constant.
|
||||
llvm::Constant* constant8(int i);
|
||||
llvm::Constant* constant16(uint16_t i);
|
||||
llvm::Constant* constant64(uint64_t i);
|
||||
llvm::Constant* constant128(uint64_t i);
|
||||
llvm::Constant* constant128(uint64_t left, uint64_t right);
|
||||
|
||||
// Return an llvm::value holding an explicit signed int64_t constant.
|
||||
// Return an llvm::Constant holding an explicit signed int64_t constant.
|
||||
llvm::Constant* constanti64(int64_t i);
|
||||
|
||||
/// Return an llvm::Value holding the given size_t constant.
|
||||
/// Return an llvm::Constant holding the given size_t constant.
|
||||
llvm::Constant* constant(size_t i);
|
||||
|
||||
/// Return an llvm::Value holding the given bool constant.
|
||||
/// Return an llvm::Constant holding the given bool constant.
|
||||
/// Change the name so it doesn't get mixed up with int.
|
||||
llvm::Constant* constant_bool(bool b);
|
||||
|
||||
@@ -735,19 +741,23 @@ public:
|
||||
|
||||
/// Cast the pointer variable specified by val to the kind of pointer
|
||||
/// described by type (as an llvm pointer type).
|
||||
llvm::Value* ptr_cast(llvm::Value* val, llvm::Type* type);
|
||||
llvm::Value* ptr_cast(llvm::Value* val, llvm::PointerType* type)
|
||||
llvm::Value* ptr_cast(llvm::Value* val, llvm::Type* type,
|
||||
const std::string& llname = {});
|
||||
llvm::Value* ptr_cast(llvm::Value* val, llvm::PointerType* type,
|
||||
const std::string& llname = {})
|
||||
{
|
||||
return ptr_cast(val, (llvm::Type*)type);
|
||||
return ptr_cast(val, (llvm::Type*)type, llname);
|
||||
}
|
||||
|
||||
/// Cast the pointer variable specified by val to a pointer to the type
|
||||
/// described by type (as an llvm data type).
|
||||
llvm::Value* ptr_to_cast(llvm::Value* val, llvm::Type* type);
|
||||
llvm::Value* ptr_to_cast(llvm::Value* val, llvm::Type* type,
|
||||
const std::string& llname = {});
|
||||
|
||||
/// Cast the pointer variable specified by val to a pointer to the given
|
||||
/// data type, return the llvm::Value of the new pointer.
|
||||
llvm::Value* ptr_cast(llvm::Value* val, const OIIO::TypeDesc& type);
|
||||
llvm::Value* ptr_cast(llvm::Value* val, const OIIO::TypeDesc& type,
|
||||
const std::string& llname = {});
|
||||
|
||||
llvm::Value* wide_ptr_cast(llvm::Value* val, const OIIO::TypeDesc& type);
|
||||
|
||||
@@ -757,7 +767,7 @@ public:
|
||||
|
||||
/// Cast the pointer variable specified by val to a pointer of type
|
||||
/// void* return the llvm::Value of the new pointer.
|
||||
llvm::Value* void_ptr(llvm::Value* val);
|
||||
llvm::Value* void_ptr(llvm::Value* val, const std::string& llname = {});
|
||||
|
||||
/// Generate a pointer that is (ptrtype)((char *)ptr + offset).
|
||||
/// If ptrtype is NULL, just return a void*.
|
||||
@@ -865,9 +875,10 @@ public:
|
||||
|
||||
/// Dereference a pointer: return *ptr
|
||||
/// type is the type of the thing being pointed to.
|
||||
llvm::Value* op_load(llvm::Type* type, llvm::Value* ptr);
|
||||
llvm::Value* op_load(llvm::Type* type, llvm::Value* ptr,
|
||||
const std::string& llname = {});
|
||||
// Blind pointer version that's deprecated as of LLVM13:
|
||||
llvm::Value* op_load(llvm::Value* ptr);
|
||||
llvm::Value* op_load(llvm::Value* ptr, const std::string& llname = {});
|
||||
|
||||
llvm::Value* op_gather(llvm::Value* ptr, llvm::Value* index);
|
||||
|
||||
@@ -898,24 +909,30 @@ public:
|
||||
/// llvm::Value, which can be generated from either a constant or a
|
||||
/// runtime-computed integer element index. `type` is the type of the data
|
||||
/// we're retrieving.
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, llvm::Value* elem);
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, llvm::Value* elem,
|
||||
const std::string& llname = {});
|
||||
// Blind pointer version that's deprecated as of LLVM13:
|
||||
llvm::Value* GEP(llvm::Value* ptr, llvm::Value* elem);
|
||||
llvm::Value* GEP(llvm::Value* ptr, llvm::Value* elem,
|
||||
const std::string& llname = {});
|
||||
|
||||
/// Generate a GEP (get element pointer) with an integer element
|
||||
/// offset. `type` is the type of the data we're retrieving.
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, int elem);
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, int elem,
|
||||
const std::string& llname = {});
|
||||
// Blind pointer version that's deprecated as of LLVM13:
|
||||
llvm::Value* GEP(llvm::Value* ptr, int elem);
|
||||
llvm::Value* GEP(llvm::Value* ptr, int elem,
|
||||
const std::string& llname = {});
|
||||
|
||||
/// Generate a GEP (get element pointer) with two integer element
|
||||
/// offsets. This is just a special (and common) case of GEP where
|
||||
/// we have a 2-level hierarchy and we have fixed element indices
|
||||
/// that are known at compile time. `type` is the type of the data we're
|
||||
/// retrieving.
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, int elem1, int elem2);
|
||||
llvm::Value* GEP(llvm::Type* type, llvm::Value* ptr, int elem1, int elem2,
|
||||
const std::string& llname = {});
|
||||
// Blind pointer version that's deprecated as of LLVM13:
|
||||
llvm::Value* GEP(llvm::Value* ptr, int elem1, int elem2);
|
||||
llvm::Value* GEP(llvm::Value* ptr, int elem1, int elem2,
|
||||
const std::string& llname = {});
|
||||
|
||||
// Arithmetic ops. It auto-detects the type (int vs float).
|
||||
// ...
|
||||
|
||||
+38
-10
@@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <type_traits>
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
@@ -23,6 +22,8 @@ using std::countr_zero;
|
||||
|
||||
#elif OSL_INTEL_CLASSIC_COMPILER_VERSION
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
OSL_FORCEINLINE int popcount(uint32_t x) noexcept { return _mm_popcnt_u32(x);}
|
||||
OSL_FORCEINLINE int popcount(uint64_t x) noexcept { return _mm_popcnt_u64(x); }
|
||||
OSL_FORCEINLINE int countr_zero(uint32_t x) noexcept { return _bit_scan_forward(x); }
|
||||
@@ -170,13 +171,22 @@ public:
|
||||
}
|
||||
|
||||
|
||||
OSL_FORCEINLINE ValueType value() const { return m_value; }
|
||||
OSL_FORCEINLINE ValueType value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// count number of active bits
|
||||
OSL_FORCEINLINE int count() const { return OSL::popcount(m_value); }
|
||||
OSL_FORCEINLINE int count() const
|
||||
{
|
||||
return OSL::popcount(m_value);
|
||||
}
|
||||
|
||||
// NOTE: undefined result if no bits are on
|
||||
OSL_FORCEINLINE int first_on() const { return OSL::countr_zero(m_value); }
|
||||
OSL_FORCEINLINE int first_on() const
|
||||
{
|
||||
return OSL::countr_zero(m_value);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE Mask invert() const
|
||||
{
|
||||
@@ -229,7 +239,10 @@ public:
|
||||
return (m_value != static_cast<ValueType>(0));
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE bool any_off() const { return (m_value < valid_bits); }
|
||||
OSL_FORCEINLINE bool any_off() const
|
||||
{
|
||||
return (m_value < valid_bits);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE bool any_off(const Mask& mask) const
|
||||
{
|
||||
@@ -244,27 +257,39 @@ public:
|
||||
// So really only set_on or set_off is required
|
||||
// Choose to not provide a generic set(int lane, bool flag)
|
||||
|
||||
OSL_FORCEINLINE void set_on(int lane) { m_value |= (1 << lane); }
|
||||
OSL_FORCEINLINE void set_on(int lane)
|
||||
{
|
||||
m_value |= (1 << lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set_on_if(int lane, bool cond)
|
||||
{
|
||||
m_value |= (cond << lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set_all_on() { m_value = valid_bits; }
|
||||
OSL_FORCEINLINE void set_all_on()
|
||||
{
|
||||
m_value = valid_bits;
|
||||
}
|
||||
OSL_FORCEINLINE void set_count_on(int count)
|
||||
{
|
||||
m_value = valid_bits >> (width - count);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set_off(int lane) { m_value &= (~(1 << lane)); }
|
||||
OSL_FORCEINLINE void set_off(int lane)
|
||||
{
|
||||
m_value &= (~(1 << lane));
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set_off_if(int lane, bool cond)
|
||||
{
|
||||
m_value &= (~(cond << lane));
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE void set_all_off() { m_value = static_cast<ValueType>(0); }
|
||||
OSL_FORCEINLINE void set_all_off()
|
||||
{
|
||||
m_value = static_cast<ValueType>(0);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE bool operator==(const Mask& other) const
|
||||
{
|
||||
@@ -298,7 +323,10 @@ public:
|
||||
return Mask(m_value | other.m_value);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE Mask operator~() const { return invert(); }
|
||||
OSL_FORCEINLINE Mask operator~() const
|
||||
{
|
||||
return invert();
|
||||
}
|
||||
|
||||
|
||||
template<int MinOccupancyT, int MaxOccupancyT = width, typename FunctorT>
|
||||
|
||||
@@ -109,8 +109,14 @@ OSL_ALIGNAS(16) ClosureComponent : public ClosureColor
|
||||
Vec3 w; ///< Weight of this component
|
||||
|
||||
/// Handy method for getting the parameter memory as a void*.
|
||||
OSL_HOSTDEVICE void* data() { return (char*)(this + 1); }
|
||||
OSL_HOSTDEVICE const void* data() const { return (const char*)(this + 1); }
|
||||
OSL_HOSTDEVICE void* data()
|
||||
{
|
||||
return (char*)(this + 1);
|
||||
}
|
||||
OSL_HOSTDEVICE const void* data() const
|
||||
{
|
||||
return (const char*)(this + 1);
|
||||
}
|
||||
|
||||
/// Handy methods for extracting the underlying parameters as a struct
|
||||
template<typename T> OSL_HOSTDEVICE const T* as() const
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Strings {
|
||||
# if OPTIX_VERSION >= 70000
|
||||
# define STRDECL(str, var_name)
|
||||
# else
|
||||
# define STRDECL(str, var_name) extern __device__ ustring var_name;
|
||||
# define STRDECL(str, var_name) extern __device__ const ustring var_name;
|
||||
# endif
|
||||
#else
|
||||
// Any strings referenced inside of a libsoslexec/wide/*.cpp
|
||||
@@ -432,12 +432,15 @@ 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, it will
|
||||
/// is requested in multiple scopes, or with
|
||||
/// multiple different types, it will
|
||||
/// appear in the array multiple times - once for
|
||||
/// each scope in which is is queried.
|
||||
/// each scope/type 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.
|
||||
@@ -448,6 +451,7 @@ public:
|
||||
/// string entry_layers[] List of entry point layers.
|
||||
/// string pickle Retrieves a serialized representation
|
||||
/// of the shader group declaration.
|
||||
/// int llvm_groupdata_size Size of the GroupData struct.
|
||||
/// Note: the attributes referred to as "string" are actually on the app
|
||||
/// side as ustring or const char* (they have the same data layout), NOT
|
||||
/// std::string!
|
||||
|
||||
+323
-311
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ class OSOReaderQuery; // Just so OSLQuery can friend OSLReaderQuery
|
||||
/// ~~~
|
||||
///
|
||||
/// And the `Parameter` structure will hold all the information you need
|
||||
/// about that paramter. For example:
|
||||
/// about that parameter. For example:
|
||||
///
|
||||
/// ~~~
|
||||
/// std::cout << "Parameter " << p->name
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
}
|
||||
///< Construct an OSLQuery and open a compiled shader from a disk file.
|
||||
/// The `shadername` may be either the name of the `.oso` file, or the
|
||||
/// name of the shader. The optional `searchpath` paramter gives a
|
||||
/// name of the shader. The optional `searchpath` parameter gives a
|
||||
/// colon-separated list of directories to search for compiled shaders.
|
||||
|
||||
OSL_DEPRECATED("Use ShadingSystem::oslquery(group,layernum)")
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <OSL/oslversion.h>
|
||||
@@ -482,15 +483,41 @@
|
||||
# define OSL_DASSERT_MSG(x, ...) ((void)sizeof(x)) /*NOLINT*/
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
||||
#define OSL_STACK_ARRAY(TYPE, NAME, DYNAMIC_COUNT) TYPE * NAME = reinterpret_cast<TYPE *>(alloca(sizeof(TYPE)*(DYNAMIC_COUNT)))
|
||||
|
||||
/// OSL_ALLOCA is used to allocate smallish amount of memory on the stack,
|
||||
/// equivalent of C99 type var_name[size].
|
||||
///
|
||||
/// NOTE: in a debug build, this will assert for allocations >= 1MB, which is
|
||||
/// much too big. Hopefully this will keep us from abusing alloca and having
|
||||
/// stack overflows. The rule of thumb is that it's ok to use alloca for small
|
||||
/// things of bounded size, but not for anything that could be arbitrarily
|
||||
/// big, which should instead use heap allocation.
|
||||
#if defined(__GNUC__)
|
||||
# define OSL_ALLOCA(type, size) (assert(size < (1<<20)), (size) != 0 ? (reinterpret_cast<type*>(__builtin_alloca((size) * sizeof(type)))) : nullptr)
|
||||
#else
|
||||
// Utilize variable length array compiler extension when available
|
||||
#define OSL_STACK_ARRAY(TYPE, NAME, DYNAMIC_COUNT) TYPE NAME[DYNAMIC_COUNT]
|
||||
# define OSL_ALLOCA(type, size) (assert(size < (1<<20)), (size) != 0 ? (reinterpret_cast<type*>(alloca((size) * sizeof(type)))) : nullptr)
|
||||
#endif
|
||||
|
||||
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 OSL_CPLUSPLUS_VERSION >= 20
|
||||
using std::assume_aligned;
|
||||
#else
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace sfm
|
||||
//return static_cast<int>(rintf(x));
|
||||
return rintf(x);
|
||||
#else
|
||||
// emulate rounding by adding/substracting 0.5
|
||||
// emulate rounding by adding/subtracting 0.5
|
||||
return static_cast<int>(x + copysignf(0.5f, x));
|
||||
|
||||
// Other possible factorings
|
||||
@@ -441,7 +441,7 @@ namespace sfm
|
||||
|
||||
// Considering having functionally equivalent versions of Vec3, Color3, Matrix44
|
||||
// with slight modifications to inlining and implementation to avoid aliasing and
|
||||
// improve likelyhood of proper privation of local variables within a SIMD loop
|
||||
// improve likelihood of proper privation of local variables within a SIMD loop
|
||||
|
||||
} // namespace sfm
|
||||
|
||||
|
||||
+69
-26
@@ -194,17 +194,17 @@ template<int WidthT> struct alignas(WidthT * sizeof(float)) VecReg {
|
||||
};
|
||||
|
||||
static_assert(std::alignment_of<VecReg<16>>::value == 64,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
static_assert(std::alignment_of<VecReg<8>>::value == 32,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
static_assert(std::alignment_of<VecReg<4>>::value == 16,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
static_assert(std::alignment_of<VecReg<16>>::value == VecReg<16>::alignment,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
static_assert(std::alignment_of<VecReg<8>>::value == VecReg<8>::alignment,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
static_assert(std::alignment_of<VecReg<4>>::value == VecReg<4>::alignment,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
|
||||
|
||||
template<typename BuiltinT, int WidthT>
|
||||
@@ -1535,7 +1535,7 @@ assume_aligned(Block<DataT, WidthT>* block_ptr)
|
||||
{
|
||||
static_assert(std::alignment_of<Block<DataT, WidthT>>::value
|
||||
== std::alignment_of<VecReg<WidthT>>::value,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
return assume_aligned<VecReg<WidthT>::alignment>(block_ptr);
|
||||
}
|
||||
|
||||
@@ -1545,7 +1545,7 @@ assume_aligned(const Block<DataT, WidthT>* block_ptr)
|
||||
{
|
||||
static_assert(std::alignment_of<Block<DataT, WidthT>>::value
|
||||
== std::alignment_of<VecReg<WidthT>>::value,
|
||||
"Unexepected alignment");
|
||||
"Unexpected alignment");
|
||||
return assume_aligned<VecReg<WidthT>::alignment>(block_ptr);
|
||||
}
|
||||
|
||||
@@ -2089,7 +2089,7 @@ struct UniformAsWide : public pvt::UniformAsWideImpl<DataT, WidthT> {
|
||||
template<typename DataT>
|
||||
struct WideTraits; // undefined, all types used should be specialized
|
||||
//{
|
||||
//static bool mathes(const TypeDesc &) { return false; }
|
||||
//static bool matches(const TypeDesc &) { return false; }
|
||||
//};
|
||||
|
||||
template<> struct WideTraits<float> {
|
||||
@@ -2128,7 +2128,7 @@ template<> struct WideTraits<ustring> {
|
||||
}
|
||||
};
|
||||
|
||||
// We let Vec3 match any vector semantics as we don't have a seperate Point or Normal classes
|
||||
// We let Vec3 match any vector semantics as we don't have a separate Point or Normal classes
|
||||
template<> struct WideTraits<Vec3> {
|
||||
static bool matches(const TypeDesc& type_desc)
|
||||
{
|
||||
@@ -2229,9 +2229,15 @@ template<typename DataT, int WidthT> struct MaskedLaneProxy {
|
||||
// visibility to end user whose IDE
|
||||
// might display these methods vs. free
|
||||
// functions
|
||||
OSL_FORCEINLINE bool is_on() const { return m_mask.is_on(m_lane); }
|
||||
OSL_FORCEINLINE bool is_on() const
|
||||
{
|
||||
return m_mask.is_on(m_lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE bool is_off() const { return m_mask.is_off(m_lane); }
|
||||
OSL_FORCEINLINE bool is_off() const
|
||||
{
|
||||
return m_mask.is_off(m_lane);
|
||||
}
|
||||
|
||||
private:
|
||||
Block<DataT, WidthT>& m_ref_wide_data;
|
||||
@@ -2293,9 +2299,15 @@ struct MaskedArrayLaneProxy {
|
||||
// visibility to end user whose IDE
|
||||
// might display these methods vs. free
|
||||
// functions
|
||||
OSL_FORCEINLINE bool is_on() const { return m_mask.is_on(m_lane); }
|
||||
OSL_FORCEINLINE bool is_on() const
|
||||
{
|
||||
return m_mask.is_on(m_lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE bool is_off() const { return m_mask.is_off(m_lane); }
|
||||
OSL_FORCEINLINE bool is_off() const
|
||||
{
|
||||
return m_mask.is_off(m_lane);
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE MaskedLaneProxy<DataT, WidthT>
|
||||
operator[](int array_index) const
|
||||
@@ -2727,19 +2739,24 @@ foreach_unique(Wide<DataT, WidthT> wdata, Mask<WidthT> data_mask, FunctorT f)
|
||||
do {
|
||||
ActiveLane lead_lane(remaining_mask.first_on());
|
||||
DataT lead_data = wdata[lead_lane];
|
||||
Mask<WidthT> matching_lanes(false);
|
||||
// Use int instead of Mask<> to allow reduction clause in openmp simd declaration
|
||||
int matching_lanes_bits { 0 };
|
||||
OSL_FORCEINLINE_BLOCK
|
||||
{
|
||||
OSL_OMP_PRAGMA(omp simd simdlen(WidthT))
|
||||
OSL_OMP_PRAGMA(omp simd simdlen(WidthT)
|
||||
reduction(|
|
||||
: matching_lanes_bits))
|
||||
for (int lane = 0; lane < WidthT; ++lane) {
|
||||
// NOTE: the comparison ignores the remaining_mask
|
||||
bool lane_matches = (lead_data == wdata[lane]);
|
||||
// NOTE: using bitwise & to avoid branches
|
||||
if (lane_matches & remaining_mask[lane]) {
|
||||
matching_lanes.set_on(lane);
|
||||
// inline of Mask::set_on(lane)
|
||||
matching_lanes_bits |= 1 << lane;
|
||||
}
|
||||
}
|
||||
}
|
||||
Mask<WidthT> matching_lanes { matching_lanes_bits };
|
||||
|
||||
f(lead_data, matching_lanes);
|
||||
remaining_mask &= ~matching_lanes;
|
||||
@@ -2828,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.
|
||||
// Includes value, as well as Dx and Dy when has_derivs() is true
|
||||
// when has_derivs() is true, Dx and Dy will be zeroed
|
||||
OSL_FORCEINLINE void assign_all_from_scalar(const void* ptr_data) const;
|
||||
|
||||
|
||||
@@ -2846,6 +2863,9 @@ private:
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void assign_all_from_scalar_type(const void* ptr_data,
|
||||
int deriv_index) const;
|
||||
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void zero_all_type(int deriv_index) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -3361,6 +3381,33 @@ MaskedData<WidthT>::assign_all_from_scalar_type(const void* ptr_data,
|
||||
}
|
||||
}
|
||||
|
||||
template<int WidthT>
|
||||
template<typename DataT>
|
||||
OSL_NOINLINE void
|
||||
MaskedData<WidthT>::zero_all_type(int deriv_index) const
|
||||
{
|
||||
// We can't just do a memset because some lanes may be masked off
|
||||
// Use a SIMD loop to perform masked assignment.
|
||||
auto* dst_blocks = pvt::block_cast<DataT, WidthT>(m_ptr);
|
||||
int elem_count = static_cast<int>(m_type.numelements());
|
||||
int comp_count = m_type.aggregate;
|
||||
int deriv_offset = deriv_index * elem_count * comp_count;
|
||||
for (int array_index = 0; array_index < elem_count; ++array_index) {
|
||||
int array_offset = array_index * comp_count;
|
||||
for (int comp_index = 0; comp_index < comp_count; ++comp_index) {
|
||||
int combined_index = deriv_offset + array_offset + comp_index;
|
||||
auto& bdst = dst_blocks[combined_index];
|
||||
|
||||
Masked<DataT, WidthT> wdest(bdst, mask());
|
||||
|
||||
OSL_OMP_PRAGMA(omp simd simdlen(WidthT))
|
||||
for (int lane = 0; lane < WidthT; ++lane) {
|
||||
wdest[lane] = DataT {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int WidthT>
|
||||
OSL_FORCEINLINE void
|
||||
MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
|
||||
@@ -3376,16 +3423,12 @@ MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
|
||||
assign_all_from_scalar_type<ustring>(ptr_data, /*deriv_index*/ 0);
|
||||
}
|
||||
if (has_derivs()) {
|
||||
size_t src_size = type().size();
|
||||
const char* dx_src = reinterpret_cast<const char*>(ptr_data) + src_size;
|
||||
const char* dy_src = dx_src + src_size;
|
||||
|
||||
if (isBase32bit) {
|
||||
assign_all_from_scalar_type<int>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<int>(dy_src, /*deriv_index*/ 2);
|
||||
zero_all_type<int>(/*deriv_index*/ 1);
|
||||
zero_all_type<int>(/*deriv_index*/ 2);
|
||||
} else {
|
||||
assign_all_from_scalar_type<ustring>(dx_src, /*deriv_index*/ 1);
|
||||
assign_all_from_scalar_type<ustring>(dy_src, /*deriv_index*/ 2);
|
||||
zero_all_type<ustring>(/*deriv_index*/ 1);
|
||||
zero_all_type<ustring>(/*deriv_index*/ 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace __OSL_WIDE_PVT {
|
||||
|
||||
OSL_USING_DATA_WIDTH(__OSL_WIDTH)
|
||||
|
||||
// Foward declaration, implementation is in liboslnoise/wide_gabornoise.h
|
||||
// Forward declaration, implementation is in liboslnoise/wide_gabornoise.h
|
||||
struct DisabledFilterPolicy {
|
||||
static constexpr bool active = false;
|
||||
};
|
||||
@@ -34,7 +34,7 @@ OSL_NOINLINE void
|
||||
wide_gabor(Masked<Dual2<float>> wResult, Wide<const Dual2<float>> wX,
|
||||
NoiseParams const* opt, Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_gabor(Masked<Dual2<float>> wResult, Wide<const Dual2<float>> wX,
|
||||
@@ -46,20 +46,20 @@ OSL_NOINLINE void
|
||||
wide_gabor(Masked<Dual2<float>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
NoiseParams const* opt, Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_gabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<float>> wX,
|
||||
NoiseParams const* opt, Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_gabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<float>> wX,
|
||||
Wide<const Dual2<float>> wY, NoiseParams const* opt,
|
||||
Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_gabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
@@ -71,14 +71,14 @@ wide_gabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
// Periodic gabor(s)
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor(Masked<Dual2<float>> wResult, Wide<const Dual2<float>> wX,
|
||||
Wide<const float> wXp, NoiseParams const* opt,
|
||||
Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor(Masked<Dual2<float>> wResult, Wide<const Dual2<float>> wX,
|
||||
@@ -86,7 +86,7 @@ wide_pgabor(Masked<Dual2<float>> wResult, Wide<const Dual2<float>> wX,
|
||||
Wide<const float> wYp, NoiseParams const* opt,
|
||||
Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor(Masked<Dual2<float>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
@@ -95,14 +95,14 @@ wide_pgabor(Masked<Dual2<float>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
|
||||
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<float>> wX,
|
||||
Wide<const float> wXp, NoiseParams const* opt,
|
||||
Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<float>> wX,
|
||||
@@ -110,7 +110,7 @@ wide_pgabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<float>> wX,
|
||||
Wide<const float> wYp, NoiseParams const* opt,
|
||||
Block<Vec3>* opt_varying_direction);
|
||||
|
||||
// Foward declaration, implementation is in wide_gabor.h
|
||||
// Forward declaration, implementation is in wide_gabor.h
|
||||
template<int AnisotropicT, typename FilterPolicyT>
|
||||
OSL_NOINLINE void
|
||||
wide_pgabor3(Masked<Dual2<Vec3>> wResult, Wide<const Dual2<Vec3>> wP,
|
||||
|
||||
+225
-55
@@ -386,6 +386,7 @@ public:
|
||||
/// vector-like (and match their array-ness and closure-ness), or
|
||||
/// if both are structures with matching fields.
|
||||
friend bool equivalent(const TypeSpec& a, const TypeSpec& b);
|
||||
friend bool relaxed_equivalent(const TypeSpec& a, const TypeSpec& b);
|
||||
|
||||
/// Is type src is assignable to dst? It is if they are the equivalent(),
|
||||
/// or if dst is a float or float-aggregate and src is a float or int.
|
||||
@@ -558,7 +559,7 @@ public:
|
||||
///
|
||||
void scope(int s) { m_scope = s; }
|
||||
|
||||
/// Return teh AST node containing the declaration of this symbol.
|
||||
/// Return the AST node containing the declaration of this symbol.
|
||||
/// Use with care!
|
||||
ASTNode* node() const { return m_node; }
|
||||
|
||||
@@ -633,55 +634,133 @@ public:
|
||||
}
|
||||
|
||||
|
||||
void dataoffset(int d) { m_dataoffset = d; }
|
||||
int dataoffset() const { return m_dataoffset; }
|
||||
void dataoffset(int d)
|
||||
{
|
||||
m_dataoffset = d;
|
||||
}
|
||||
int dataoffset() const
|
||||
{
|
||||
return m_dataoffset;
|
||||
}
|
||||
|
||||
void wide_dataoffset(int d) { m_wide_dataoffset = d; }
|
||||
int wide_dataoffset() const { return m_wide_dataoffset; }
|
||||
void wide_dataoffset(int d)
|
||||
{
|
||||
m_wide_dataoffset = d;
|
||||
}
|
||||
int wide_dataoffset() const
|
||||
{
|
||||
return m_wide_dataoffset;
|
||||
}
|
||||
|
||||
SymArena arena() const { return static_cast<SymArena>(m_arena); }
|
||||
SymArena arena() const
|
||||
{
|
||||
return static_cast<SymArena>(m_arena);
|
||||
}
|
||||
|
||||
void initializers(int d) { m_initializers = d; }
|
||||
int initializers() const { return m_initializers; }
|
||||
void initializers(int d)
|
||||
{
|
||||
m_initializers = d;
|
||||
}
|
||||
int initializers() const
|
||||
{
|
||||
return m_initializers;
|
||||
}
|
||||
|
||||
bool has_derivs() const { return m_has_derivs; }
|
||||
void has_derivs(bool new_derivs) { m_has_derivs = new_derivs; }
|
||||
int size() const { return m_size; }
|
||||
void size(size_t newsize) { m_size = (int)newsize; }
|
||||
bool has_derivs() const
|
||||
{
|
||||
return m_has_derivs;
|
||||
}
|
||||
void has_derivs(bool new_derivs)
|
||||
{
|
||||
m_has_derivs = new_derivs;
|
||||
}
|
||||
int size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
void size(size_t newsize)
|
||||
{
|
||||
m_size = (int)newsize;
|
||||
}
|
||||
|
||||
/// Return the size for each point, including derivs.
|
||||
///
|
||||
int derivsize() const { return m_has_derivs ? 3 * m_size : m_size; }
|
||||
int derivsize() const
|
||||
{
|
||||
return m_has_derivs ? 3 * m_size : m_size;
|
||||
}
|
||||
|
||||
bool connected() const { return valuesource() == ConnectedVal; }
|
||||
bool connected_down() const { return m_connected_down; }
|
||||
void connected_down(bool c) { m_connected_down = c; }
|
||||
bool connected() const
|
||||
{
|
||||
return valuesource() == ConnectedVal;
|
||||
}
|
||||
bool connected_down() const
|
||||
{
|
||||
return m_connected_down;
|
||||
}
|
||||
void connected_down(bool c)
|
||||
{
|
||||
m_connected_down = c;
|
||||
}
|
||||
|
||||
/// Where did the symbol's value come from?
|
||||
///
|
||||
enum ValueSource { DefaultVal, InstanceVal, GeomVal, ConnectedVal };
|
||||
|
||||
ValueSource valuesource() const { return (ValueSource)m_valuesource; }
|
||||
void valuesource(ValueSource v) { m_valuesource = v; }
|
||||
ValueSource valuesource() const
|
||||
{
|
||||
return (ValueSource)m_valuesource;
|
||||
}
|
||||
void valuesource(ValueSource v)
|
||||
{
|
||||
m_valuesource = v;
|
||||
}
|
||||
const char* valuesourcename() const;
|
||||
static const char* valuesourcename(ValueSource v);
|
||||
|
||||
int fieldid() const { return m_fieldid; }
|
||||
void fieldid(int id) { m_fieldid = id; }
|
||||
int fieldid() const
|
||||
{
|
||||
return m_fieldid;
|
||||
}
|
||||
void fieldid(int id)
|
||||
{
|
||||
m_fieldid = id;
|
||||
}
|
||||
|
||||
int layer() const { return m_layer; }
|
||||
void layer(int id) { m_layer = id; }
|
||||
int layer() const
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
void layer(int id)
|
||||
{
|
||||
m_layer = id;
|
||||
}
|
||||
|
||||
int initbegin() const { return m_initbegin; }
|
||||
void initbegin(int i) { m_initbegin = i; }
|
||||
int initend() const { return m_initend; }
|
||||
void initend(int i) { m_initend = i; }
|
||||
int initbegin() const
|
||||
{
|
||||
return m_initbegin;
|
||||
}
|
||||
void initbegin(int i)
|
||||
{
|
||||
m_initbegin = i;
|
||||
}
|
||||
int initend() const
|
||||
{
|
||||
return m_initend;
|
||||
}
|
||||
void initend(int i)
|
||||
{
|
||||
m_initend = i;
|
||||
}
|
||||
void set_initrange(int b = 0, int e = 0)
|
||||
{
|
||||
m_initbegin = b;
|
||||
m_initend = e;
|
||||
}
|
||||
bool has_init_ops() const { return m_initbegin != m_initend; }
|
||||
bool has_init_ops() const
|
||||
{
|
||||
return m_initbegin != m_initend;
|
||||
}
|
||||
|
||||
/// Clear read/write usage info.
|
||||
///
|
||||
@@ -725,15 +804,42 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int firstread() const { return m_firstread; }
|
||||
int lastread() const { return m_lastread; }
|
||||
int firstwrite() const { return m_firstwrite; }
|
||||
int lastwrite() const { return m_lastwrite; }
|
||||
int firstuse() const { return std::min(firstread(), firstwrite()); }
|
||||
int lastuse() const { return std::max(lastread(), lastwrite()); }
|
||||
bool everread() const { return lastread() >= 0; }
|
||||
bool everwritten() const { return lastwrite() >= 0; }
|
||||
bool everused() const { return everread() || everwritten(); }
|
||||
int firstread() const
|
||||
{
|
||||
return m_firstread;
|
||||
}
|
||||
int lastread() const
|
||||
{
|
||||
return m_lastread;
|
||||
}
|
||||
int firstwrite() const
|
||||
{
|
||||
return m_firstwrite;
|
||||
}
|
||||
int lastwrite() const
|
||||
{
|
||||
return m_lastwrite;
|
||||
}
|
||||
int firstuse() const
|
||||
{
|
||||
return std::min(firstread(), firstwrite());
|
||||
}
|
||||
int lastuse() const
|
||||
{
|
||||
return std::max(lastread(), lastwrite());
|
||||
}
|
||||
bool everread() const
|
||||
{
|
||||
return lastread() >= 0;
|
||||
}
|
||||
bool everwritten() const
|
||||
{
|
||||
return lastwrite() >= 0;
|
||||
}
|
||||
bool everused() const
|
||||
{
|
||||
return everread() || everwritten();
|
||||
}
|
||||
// everused_in_group is an even more stringent test -- not only must
|
||||
// the symbol not be used within the shader but it also must not be
|
||||
// used elsewhere in the group, by being connected to something downstream
|
||||
@@ -754,31 +860,67 @@ public:
|
||||
m_lastwrite = last;
|
||||
}
|
||||
|
||||
bool initialized() const { return m_initialized; }
|
||||
void initialized(bool init) { m_initialized = init; }
|
||||
bool initialized() const
|
||||
{
|
||||
return m_initialized;
|
||||
}
|
||||
void initialized(bool init)
|
||||
{
|
||||
m_initialized = init;
|
||||
}
|
||||
|
||||
bool lockgeom() const { return m_lockgeom; }
|
||||
void lockgeom(bool lock) { m_lockgeom = lock; }
|
||||
bool lockgeom() const
|
||||
{
|
||||
return m_lockgeom;
|
||||
}
|
||||
void lockgeom(bool lock)
|
||||
{
|
||||
m_lockgeom = lock;
|
||||
}
|
||||
|
||||
bool allowconnect() const { return m_allowconnect; }
|
||||
void allowconnect(bool val) { m_allowconnect = val; }
|
||||
bool allowconnect() const
|
||||
{
|
||||
return m_allowconnect;
|
||||
}
|
||||
void allowconnect(bool val)
|
||||
{
|
||||
m_allowconnect = val;
|
||||
}
|
||||
|
||||
int arraylen() const { return m_typespec.arraylength(); }
|
||||
int arraylen() const
|
||||
{
|
||||
return m_typespec.arraylength();
|
||||
}
|
||||
void arraylen(int len)
|
||||
{
|
||||
m_typespec.make_array(len);
|
||||
m_size = m_typespec.simpletype().size();
|
||||
}
|
||||
|
||||
bool renderer_output() const { return m_renderer_output; }
|
||||
void renderer_output(bool v) { m_renderer_output = v; }
|
||||
bool renderer_output() const
|
||||
{
|
||||
return m_renderer_output;
|
||||
}
|
||||
void renderer_output(bool v)
|
||||
{
|
||||
m_renderer_output = v;
|
||||
}
|
||||
|
||||
// When not uniform a symbol will have a varying value under batched
|
||||
// execution and must use a Wide data type to hold different values
|
||||
// for each data lane executing
|
||||
bool is_uniform() const { return m_is_uniform; }
|
||||
bool is_varying() const { return (m_is_uniform == 0); }
|
||||
void make_varying() { m_is_uniform = false; }
|
||||
bool is_uniform() const
|
||||
{
|
||||
return m_is_uniform;
|
||||
}
|
||||
bool is_varying() const
|
||||
{
|
||||
return (m_is_uniform == 0);
|
||||
}
|
||||
void make_varying()
|
||||
{
|
||||
m_is_uniform = false;
|
||||
}
|
||||
|
||||
// Results of a compare_op and other ops with logically boolean
|
||||
// results under certain conditions could be forced to be represented
|
||||
@@ -792,14 +934,32 @@ public:
|
||||
// The value of forced_llvm_bool() is currently only respected during
|
||||
// batched execution. Forced bools should not be coalesced with regular
|
||||
// ints, only other forced bools.
|
||||
bool forced_llvm_bool() const { return m_forced_llvm_bool; }
|
||||
void forced_llvm_bool(bool v) { m_forced_llvm_bool = v; }
|
||||
bool forced_llvm_bool() const
|
||||
{
|
||||
return m_forced_llvm_bool;
|
||||
}
|
||||
void forced_llvm_bool(bool v)
|
||||
{
|
||||
m_forced_llvm_bool = v;
|
||||
}
|
||||
|
||||
bool readonly() const { return m_readonly; }
|
||||
void readonly(bool v) { m_readonly = v; }
|
||||
bool readonly() const
|
||||
{
|
||||
return m_readonly;
|
||||
}
|
||||
void readonly(bool v)
|
||||
{
|
||||
m_readonly = v;
|
||||
}
|
||||
|
||||
bool is_constant() const { return symtype() == SymTypeConst; }
|
||||
bool is_temp() const { return symtype() == SymTypeTemp; }
|
||||
bool is_constant() const
|
||||
{
|
||||
return symtype() == SymTypeConst;
|
||||
}
|
||||
bool is_temp() const
|
||||
{
|
||||
return symtype() == SymTypeTemp;
|
||||
}
|
||||
|
||||
// Retrieve the const float value (must be a const float!)
|
||||
float get_float(int index = 0) const
|
||||
@@ -855,7 +1015,7 @@ public:
|
||||
|
||||
// Stream output. Note that print/print_vals assume that any string
|
||||
// values are "raw" and they will be converted to C source code "escaped
|
||||
// string" notation for printing. For example, a newline characer will
|
||||
// string" notation for printing. For example, a newline character will
|
||||
// be rendered into the stream as the two character sequence '\n'.
|
||||
std::ostream& print(std::ostream& out, int maxvals = 100000000) const;
|
||||
std::ostream& print_vals(std::ostream& out, int maxvals = 100000000) const;
|
||||
@@ -1126,3 +1286,13 @@ typedef std::vector<Opcode> OpcodeVec;
|
||||
|
||||
}; // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
|
||||
|
||||
// Supply a fmtlib compatible custom formatter for TypeSpec.
|
||||
#if FMT_VERSION >= 100000
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template<> struct formatter<OSL::pvt::TypeSpec> : ostream_formatter {
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
+42
-38
@@ -35,7 +35,7 @@ std::atomic<int> node_counts_peak[ASTNode::_last_node];
|
||||
class ScopeExit {
|
||||
public:
|
||||
typedef std::function<void()> Task;
|
||||
explicit ScopeExit(Task&& task) : m_task(std::forward<Task>(task)) {}
|
||||
explicit ScopeExit(Task&& task) : m_task(std::move(task)) {}
|
||||
~ScopeExit() { m_task(); }
|
||||
|
||||
private:
|
||||
@@ -578,8 +578,14 @@ ASTvariable_declaration::ASTvariable_declaration(OSLCompilerImpl* comp,
|
||||
if (symtype == SymTypeLocal && Strutil::starts_with(name, "__debug_tmp__"))
|
||||
symtype = SymTypeTemp;
|
||||
m_sym = new Symbol(name, type, symtype, this);
|
||||
if (!m_ismetadata)
|
||||
if (m_ismetadata) {
|
||||
// Metadata doesn't go in the symbol table, so we need to retain
|
||||
// an owning pointer so it doesn't leak.
|
||||
m_sym_owned.reset(m_sym);
|
||||
} else {
|
||||
// Put in the symbol table, after which symtab is the owner
|
||||
m_compiler->symtab().insert(m_sym);
|
||||
}
|
||||
|
||||
// A struct really makes several subvariables
|
||||
if (type.is_structure() || type.is_structure_array()) {
|
||||
@@ -1110,90 +1116,88 @@ ASTassign_expression::opword() const
|
||||
OSL_ASSERT (0 && "unknown assignment expression");
|
||||
return "assign"; // punt
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
|
||||
ASTunary_expression::ASTunary_expression (OSLCompilerImpl *comp, int op,
|
||||
ASTNode *expr)
|
||||
: ASTNode (unary_expression_node, comp, op, expr)
|
||||
ASTunary_expression::ASTunary_expression(OSLCompilerImpl* comp, int op,
|
||||
ASTNode* expr)
|
||||
: ASTNode(unary_expression_node, comp, op, expr)
|
||||
{
|
||||
// Check for a user-overloaded function for this operator
|
||||
Symbol *sym = comp->symtab().find(ustring::fmtformat("__operator__{}__", opword()));
|
||||
Symbol* sym = comp->symtab().find(
|
||||
ustring::fmtformat("__operator__{}__", opword()));
|
||||
if (sym && sym->symtype() == SymTypeFunction)
|
||||
m_function_overload = (FunctionSymbol *)sym;
|
||||
m_function_overload = (FunctionSymbol*)sym;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTunary_expression::childname (size_t i) const
|
||||
const char*
|
||||
ASTunary_expression::childname(size_t i) const
|
||||
{
|
||||
static const char *name[] = { "expression" };
|
||||
static const char* name[] = { "expression" };
|
||||
return name[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTunary_expression::opname () const
|
||||
const char*
|
||||
ASTunary_expression::opname() const
|
||||
{
|
||||
switch (m_op) {
|
||||
case Add : return "+";
|
||||
case Sub : return "-";
|
||||
case Not : return "!";
|
||||
case Compl : return "~";
|
||||
default:
|
||||
OSL_ASSERT (0 && "unknown unary expression");
|
||||
return "unknown";
|
||||
case Add: return "+";
|
||||
case Sub: return "-";
|
||||
case Not: return "!";
|
||||
case Compl: return "~";
|
||||
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTunary_expression::opword () const
|
||||
const char*
|
||||
ASTunary_expression::opword() const
|
||||
{
|
||||
switch (m_op) {
|
||||
case Add : return "add";
|
||||
case Sub : return "neg";
|
||||
case Not : return "not";
|
||||
case Compl : return "compl";
|
||||
default:
|
||||
OSL_ASSERT (0 && "unknown unary expression");
|
||||
return "unknown";
|
||||
case Add: return "add";
|
||||
case Sub: return "neg";
|
||||
case Not: return "not";
|
||||
case Compl: return "compl";
|
||||
default: OSL_ASSERT(0 && "unknown unary expression"); return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ASTbinary_expression::ASTbinary_expression (OSLCompilerImpl *comp, Operator op,
|
||||
ASTNode *left, ASTNode *right)
|
||||
: ASTNode (binary_expression_node, comp, op, left, right)
|
||||
ASTbinary_expression::ASTbinary_expression(OSLCompilerImpl* comp, Operator op,
|
||||
ASTNode* left, ASTNode* right)
|
||||
: ASTNode(binary_expression_node, comp, op, left, right)
|
||||
{
|
||||
// Check for a user-overloaded function for this operator.
|
||||
// Disallow a few ops from overloading.
|
||||
if (op != And && op != Or) {
|
||||
ustring funcname = ustring::fmtformat("__operator__{}__", opword());
|
||||
Symbol *sym = comp->symtab().find (funcname);
|
||||
Symbol* sym = comp->symtab().find(funcname);
|
||||
if (sym && sym->symtype() == SymTypeFunction)
|
||||
m_function_overload = (FunctionSymbol *)sym;
|
||||
m_function_overload = (FunctionSymbol*)sym;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ASTbinary_expression::childname (size_t i) const
|
||||
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) {
|
||||
|
||||
@@ -375,7 +375,7 @@ protected:
|
||||
void codegen_initlist(ref init, TypeSpec type, Symbol* sym);
|
||||
|
||||
// Special code generation for structure initializers.
|
||||
// It's in the ASTNode base class because it's used from mutiple
|
||||
// It's in the ASTNode base class because it's used from multiple
|
||||
// subclasses.
|
||||
Symbol* codegen_struct_initializers(ref init, Symbol* sym,
|
||||
bool is_constructor = false,
|
||||
@@ -520,7 +520,7 @@ public:
|
||||
|
||||
private:
|
||||
ustring m_name; ///< Name of the symbol (unmangled)
|
||||
Symbol* m_sym; ///< Ptr to the symbol this declares
|
||||
Symbol* m_sym; ///< Ptr to the symbol this declares (non-owning)
|
||||
bool m_isparam; ///< Is this a parameter?
|
||||
bool m_isoutput; ///< Is this an output parameter?
|
||||
bool m_ismetadata; ///< Is this declaration a piece of metadata?
|
||||
@@ -529,6 +529,7 @@ private:
|
||||
// specific initializers.
|
||||
typedef std::pair<ustring, ASTNode*> NamedInit;
|
||||
std::vector<NamedInit> m_struct_field_inits;
|
||||
std::unique_ptr<Symbol> m_sym_owned; // if we own the symbol
|
||||
};
|
||||
|
||||
|
||||
@@ -949,7 +950,7 @@ private:
|
||||
/// return false and call an appropriate error().
|
||||
bool typecheck_printf_args(const char* format, ASTNode* arg);
|
||||
|
||||
/// Handle "funcion calls" that are really struct ctrs.
|
||||
/// Handle "function calls" that are really struct ctrs.
|
||||
TypeSpec typecheck_struct_constructor();
|
||||
|
||||
/// Is the argument number 'arg' read by the op?
|
||||
|
||||
@@ -918,7 +918,7 @@ ASTNode::codegen_initlist(ref init, TypeSpec type, Symbol* sym)
|
||||
}
|
||||
|
||||
if (paraminit) {
|
||||
// Warn early about struct array paramters.
|
||||
// Warn early about struct array parameters.
|
||||
// Handling this will likely need changes to oso format.
|
||||
if (type.is_structure_array()) {
|
||||
errorfmt("array of struct are not allowed as parameters");
|
||||
|
||||
@@ -701,11 +701,12 @@ 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("{}{}", sym->floatval(i), nelements > 1 ? " " : "");
|
||||
osofmt("{:.9g}{}", 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("{} {} {}{}", v.x, v.y, v.z, nelements > 1 ? " " : "");
|
||||
osofmt("{:.9g} {:.9g} {:.9g}{}", v.x, v.y, v.z,
|
||||
nelements > 1 ? " " : "");
|
||||
}
|
||||
else {
|
||||
OSL_ASSERT(0 && "Don't know how to output this constant type");
|
||||
@@ -1305,7 +1306,7 @@ OSLCompilerImpl::track_variable_dependencies()
|
||||
// This naivite will never miss a dependency, but it may
|
||||
// overestimate dependencies. (Hence we call this "conservative"
|
||||
// rather than "wrong.") We deem this acceptable for now, since
|
||||
// it's so much easer to implement the conservative dependency
|
||||
// it's so much easier to implement the conservative dependency
|
||||
// analysis, and it's not yet clear that getting it closer to
|
||||
// optimal will have any performance impact on final shaders. Also
|
||||
// because this is probably no worse than the "dependency slop" that
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#pragma clang diagnostic ignored "-Wparentheses-equality"
|
||||
#endif
|
||||
|
||||
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC visibility push(hidden)
|
||||
#endif
|
||||
|
||||
@@ -397,15 +397,6 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
|
||||
// Thread safety with the lexer/parser
|
||||
std::lock_guard<std::mutex> lock(oslcompiler_mutex);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
// This is not necessary for versions of OIIO that have Strutil::stof,
|
||||
// and we can remove it entirely when OIIO 1.9 is the minimum.
|
||||
std::locale oldlocale = std::locale::global (std::locale::classic());
|
||||
#endif
|
||||
|
||||
yyscan_t scanner;
|
||||
yylex_init(&scanner);
|
||||
YY_BUFFER_STATE buffer = yy_scan_string(preprocessed_buffer.c_str(), scanner);
|
||||
@@ -415,9 +406,6 @@ OSLCompilerImpl::osl_parse_buffer (const std::string &preprocessed_buffer)
|
||||
yy_delete_buffer (buffer, scanner);
|
||||
yylex_destroy(scanner);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
#endif
|
||||
return parseerr;
|
||||
}
|
||||
|
||||
|
||||
@@ -478,7 +478,7 @@ ASTbinary_expression::typecheck(TypeSpec expected)
|
||||
TypeSpec returntype = m_compiler->type_from_code(code, &advance);
|
||||
code += advance;
|
||||
if (code[0] && check_simple_arg(l, code, true) && code[0]
|
||||
&& check_simple_arg(r, code, true) && !code[0]) {
|
||||
&& check_simple_arg(r, code, true) && !code[0]) { // NOSONAR
|
||||
return m_typespec = returntype;
|
||||
}
|
||||
}
|
||||
@@ -618,7 +618,7 @@ ASTternary_expression::typecheck(TypeSpec expected)
|
||||
errorfmt("Cannot use an array as a condition");
|
||||
|
||||
// No arrays
|
||||
if (t.is_array() || t.is_array()) {
|
||||
if (t.is_array() || f.is_array()) {
|
||||
errorfmt("Not allowed: '{} ? {} : {}'", c, t, f);
|
||||
return TypeSpec();
|
||||
}
|
||||
@@ -678,7 +678,7 @@ ASTtype_constructor::typecheck(TypeSpec expected, bool report, bool bind)
|
||||
if (expected.is_float()) {
|
||||
patterns = float_patterns;
|
||||
argexpected = TypeDesc::FLOAT;
|
||||
// ^^^ Since simetimes tht constructor `float(expr)` is used as a
|
||||
// ^^^ Since sometimes the constructor `float(expr)` is used as a
|
||||
// synonym for a cast `(float)expr`, we know that ambiguously typed
|
||||
// expressions should favor disambiguating to a float.
|
||||
} else if (expected.is_triple()) {
|
||||
@@ -762,7 +762,7 @@ public:
|
||||
|
||||
~TypeAdjuster()
|
||||
{
|
||||
// Commit infered types of all ASTcompound_initializers scanned.
|
||||
// Commit inferred types of all ASTcompound_initializers scanned.
|
||||
if (m_success) {
|
||||
for (auto&& initer : m_adjust) {
|
||||
ASTcompound_initializer* ciptr = std::get<0>(initer);
|
||||
@@ -992,9 +992,9 @@ private:
|
||||
const StructSpec::FieldSpec* field = nullptr)
|
||||
{
|
||||
if (node->typecheck(expected) != expected &&
|
||||
// Alllow assignment with comparable type
|
||||
// Allow assignment with comparable type
|
||||
!assignable(expected, node->typespec()) &&
|
||||
// Alllow closure assignments to '0'
|
||||
// Allow closure assignments to '0'
|
||||
!(expected.is_closure() && !node->typespec().is_closure()
|
||||
&& node->typespec().is_int_or_float()
|
||||
&& node->nodetype() == literal_node
|
||||
@@ -1065,6 +1065,8 @@ bool
|
||||
ASTNode::check_arglist(const char* /*funcname*/, ASTNode::ref arg,
|
||||
const char* formals, bool coerce, bool bind)
|
||||
{
|
||||
if (!formals)
|
||||
return false;
|
||||
// std::cerr << "ca " << funcname << " formals='" << formals << "\n";
|
||||
for (; arg; arg = arg->next()) {
|
||||
if (!*formals) // More formal args, but no more actual args
|
||||
@@ -1619,7 +1621,7 @@ class CandidateFunctions {
|
||||
|
||||
default:
|
||||
// TODO: Scoring default function arguments would go here
|
||||
// Curently an unused formal argument, so no match at all.
|
||||
// Currently an unused formal argument, so no match at all.
|
||||
return kNoMatch;
|
||||
}
|
||||
OSL_DASSERT(*formals == 0);
|
||||
@@ -1994,7 +1996,7 @@ ASTfunction_call::typecheck(TypeSpec expected)
|
||||
any_args_are_compound_initializers = true;
|
||||
}
|
||||
|
||||
// Save the currently choosen symbol for error reporting later
|
||||
// Save the currently chosen symbol for error reporting later
|
||||
FunctionSymbol* poly = func();
|
||||
|
||||
CandidateFunctions candidates(m_compiler, expected, args(), poly);
|
||||
|
||||
@@ -209,7 +209,7 @@ macro ( CUDA_SHADEOPS_COMPILE srclist )
|
||||
DEPENDS ${shadeops_bc_list} ${exec_headers} ${PROJECT_PUBLIC_HEADERS} ${shadeops_srcs}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" )
|
||||
|
||||
# Serialize the linked bitcode into a CPP file and add it to the list of liboslexec soures
|
||||
# Serialize the linked bitcode into a CPP file and add it to the list of liboslexec sources
|
||||
add_custom_command ( OUTPUT ${shadeops_bc_cuda_cpp}
|
||||
COMMAND ${Python_EXECUTABLE} "${CMAKE_SOURCE_DIR}/src/build-scripts/serialize-bc.py"
|
||||
${linked_shadeops_bc} ${shadeops_bc_cuda_cpp} "osl_llvm_compiled_ops_cuda"
|
||||
@@ -222,14 +222,14 @@ if (USE_LLVM_BITCODE)
|
||||
set (llvm_ops_srcs llvm_ops.cpp)
|
||||
EMBED_LLVM_BITCODE_IN_CPP ( "${llvm_ops_srcs}" "_host" "osl_llvm_compiled_ops" lib_src "")
|
||||
|
||||
set (rs_dependant_ops_srcs
|
||||
set (rs_dependent_ops_srcs
|
||||
opmatrix.cpp
|
||||
)
|
||||
# Achieve the effect of absorbing osl_llvm_compiled_ops by adding its
|
||||
# sources to rs_dependant_ops_srcs which avoids having to do it at runtime.
|
||||
list (APPEND rs_dependant_ops_srcs ${llvm_ops_srcs})
|
||||
# sources to rs_dependent_ops_srcs which avoids having to do it at runtime.
|
||||
list (APPEND rs_dependent_ops_srcs ${llvm_ops_srcs})
|
||||
|
||||
EMBED_LLVM_BITCODE_IN_CPP ( "${rs_dependant_ops_srcs}" "_host_rs" "osl_llvm_compiled_rs_dependant_ops" lib_src "")
|
||||
EMBED_LLVM_BITCODE_IN_CPP ( "${rs_dependent_ops_srcs}" "_host_rs" "osl_llvm_compiled_rs_dependent_ops" lib_src "")
|
||||
|
||||
# Optionally repeat the bitcode compilation with CUDA-specific options
|
||||
if (CUDA_FOUND)
|
||||
@@ -352,7 +352,7 @@ foreach(batched_target ${BATCHED_TARGET_LIST})
|
||||
endif ()
|
||||
|
||||
if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_APPLECLANG)
|
||||
# REQUIRES CLANG 7+ to use sucessfully vectorize with OpenMP simd
|
||||
# REQUIRES CLANG 7+ to use successfully vectorize with OpenMP simd
|
||||
|
||||
if (${TARGET_OPT_ISA} STREQUAL "AVX512")
|
||||
list (APPEND TARGET_CXX_OPTS "-march=skylake-avx512")
|
||||
@@ -370,7 +370,13 @@ foreach(batched_target ${BATCHED_TARGET_LIST})
|
||||
endif ()
|
||||
|
||||
if (${TARGET_OPT_FMA} STREQUAL "noFMA")
|
||||
list (APPEND TARGET_CXX_OPTS "-mno-fma")
|
||||
# Do NOT use "-mno-fma" as it may lower ISA to one without any FMA
|
||||
# instructions (AVX512->AVX2). Our intent is to not generate
|
||||
# FMA's but still use the available instructions and register
|
||||
# width. However math library calls may use still end up using
|
||||
# FMA's, but lets try turning of fused math ops because many OSL
|
||||
# math functions are from OIIO/IMath headers generate non FMA
|
||||
list (APPEND TARGET_CXX_OPTS "-ffp-contract=off")
|
||||
endif ()
|
||||
|
||||
# large SIMD function loops will exceed llvm's -inline-threshold default of 225.
|
||||
@@ -388,7 +394,8 @@ foreach(batched_target ${BATCHED_TARGET_LIST})
|
||||
list (APPEND TARGET_CXX_OPTS "-fno-unroll-loops")
|
||||
|
||||
if (CMAKE_COMPILER_IS_INTELCLANG)
|
||||
list (APPEND TARGET_CXX_OPTS "-qopenmp-simd")
|
||||
# utilize Intel compiler's optimized openmp simd generation vs. open source "-qopenmp-simd"
|
||||
list (APPEND TARGET_CXX_OPTS "-fiopenmp-simd")
|
||||
else ()
|
||||
list (APPEND TARGET_CXX_OPTS "-fopenmp")
|
||||
endif ()
|
||||
@@ -434,7 +441,13 @@ foreach(batched_target ${BATCHED_TARGET_LIST})
|
||||
endif ()
|
||||
|
||||
if (${TARGET_OPT_FMA} STREQUAL "noFMA")
|
||||
list (APPEND TARGET_CXX_OPTS "-mno-fma")
|
||||
# Do NOT use "-mno-fma" as it may lower ISA to one without any FMA
|
||||
# instructions (AVX512->AVX2). Our intent is to not generate
|
||||
# FMA's but still use the available instructions and register
|
||||
# width. However math library calls may use still end up using
|
||||
# FMA's, but lets try turning of fused math ops because many OSL
|
||||
# math functions are from OIIO/IMath headers generate non FMA
|
||||
list (APPEND TARGET_CXX_OPTS "-ffp-contract=off")
|
||||
endif ()
|
||||
|
||||
list (APPEND TARGET_CXX_OPTS "-fopenmp-simd")
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
MyAov(const TestPath* test, int id)
|
||||
{
|
||||
// Init for the test case array. For each test case set a bool
|
||||
// in m_expected marking wether this AOV should get some color
|
||||
// in m_expected marking whether this AOV should get some color
|
||||
// from that test or not.
|
||||
for (int i = 0; test[i].path[0]; ++i) { // iterate test cases
|
||||
m_expected.push_back(false); // false by default
|
||||
@@ -88,7 +88,7 @@ simulate(Accumulator& accum, const char** events, size_t testno)
|
||||
int
|
||||
main()
|
||||
{
|
||||
// Some constants to avoid refering to AOV's by number
|
||||
// Some constants to avoid referring to AOV's by number
|
||||
const int beauty = 0;
|
||||
const int diffuse2_3 = 1;
|
||||
const int light3 = 2;
|
||||
|
||||
@@ -138,7 +138,7 @@ NdfAutomata::symbolsFrom(const IntSet& states, SymbolSet& out_symbols,
|
||||
{
|
||||
for (IntSet::const_iterator i = states.begin(); i != states.end(); ++i) {
|
||||
const State* state = m_states[*i];
|
||||
// For every state we have to go thorugh all the symbols in the transition table
|
||||
// For every state we have to go through all the symbols in the transition table
|
||||
// m_symbol_trans and add them to the output
|
||||
for (SymbolToIntList::const_iterator j = state->m_symbol_trans.begin();
|
||||
j != state->m_symbol_trans.end(); ++j)
|
||||
|
||||
+199
-195
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
@@ -20,7 +20,8 @@ OSL_NAMESPACE_ENTER
|
||||
// General container for all symbol sets
|
||||
|
||||
// General container for integer sets
|
||||
typedef std::set<int> IntSet; // probably faster to test for equality, unions and so
|
||||
typedef std::set<int>
|
||||
IntSet; // probably faster to test for equality, unions and so
|
||||
|
||||
typedef std::unordered_set<ustring, ustringHash> SymbolSet;
|
||||
// This is for the transition table used in DfAutomata::State
|
||||
@@ -33,7 +34,7 @@ typedef std::unordered_map<int, int> HashIntInt;
|
||||
// For the rules in the deterministic states, we don't need a real set
|
||||
// cause when converting from the NDF automata we will never find the same
|
||||
// rule twice
|
||||
typedef std::vector<void *> RuleSet;
|
||||
typedef std::vector<void*> RuleSet;
|
||||
|
||||
// The lambda symbol (empty word)
|
||||
extern ustring lambda;
|
||||
@@ -45,9 +46,9 @@ extern ustring lambda;
|
||||
/// any symbol which is not listed in its black list (m_minus).
|
||||
struct Wildcard {
|
||||
Wildcard() {};
|
||||
Wildcard(SymbolSet &minus):m_minus(minus) {};
|
||||
Wildcard(SymbolSet& minus) : m_minus(minus) {};
|
||||
|
||||
bool matches(ustring symbol)const
|
||||
bool matches(ustring symbol) const
|
||||
{
|
||||
// true if the given symbol is not in m_minus
|
||||
return (m_minus.find(symbol) == m_minus.end());
|
||||
@@ -63,109 +64,110 @@ struct Wildcard {
|
||||
/// symbol and allowed lambda transitions too. Light path expressions
|
||||
/// build this automata easily. It is later converted to a DF automata.
|
||||
class NdfAutomata {
|
||||
public:
|
||||
// Basic state for NDF automata
|
||||
class State {
|
||||
friend class NdfAutomata;
|
||||
|
||||
public:
|
||||
|
||||
// Basic state for NDF automata
|
||||
class State {
|
||||
friend class NdfAutomata;
|
||||
public:
|
||||
|
||||
State(int id)
|
||||
{
|
||||
m_id = id;
|
||||
m_wildcard_trans = -1;
|
||||
m_wildcard = NULL;
|
||||
m_rule = NULL;
|
||||
};
|
||||
~State() { delete m_wildcard; };
|
||||
|
||||
/// Get the set of state id's reachable by the given symbol
|
||||
///
|
||||
/// It doesn't clean the given result set, so you can use this
|
||||
/// function to accumulate states.
|
||||
void getTransitions (ustring symbol, IntSet &out_states)const;
|
||||
|
||||
/// Get all the lambda transitions
|
||||
///
|
||||
/// Returns the state collection as a pair of iterators [begin, end)
|
||||
std::pair <IntSet::const_iterator, IntSet::const_iterator>
|
||||
getLambdaTransitions ()const;
|
||||
|
||||
/// Add a standar transition (also valid for lambda)
|
||||
void addTransition (ustring symbol, State *state);
|
||||
/// Add a wildcard transition
|
||||
///
|
||||
/// Note that the state is going to take ownership of the wildcard
|
||||
/// pointer. So it should be newly allocated on heap and you don't
|
||||
/// have to delete ir
|
||||
void addWildcardTransition(Wildcard *wildcard, State *state);
|
||||
|
||||
/// For final states, this sets the associated rule. Which
|
||||
/// can be any kind of pointer
|
||||
void setRule(void *rule) { m_rule = rule; };
|
||||
|
||||
void *getRule()const { return m_rule; };
|
||||
int getId()const { return m_id; };
|
||||
|
||||
/// For debuging purposes
|
||||
std::string tostr()const;
|
||||
|
||||
protected:
|
||||
|
||||
// State id (i.e index in the states vector)
|
||||
int m_id;
|
||||
// Transitions by single symbols
|
||||
SymbolToIntList m_symbol_trans;
|
||||
// In case m_wildcard is not NULL this holds the destination
|
||||
// of the wildcard transition
|
||||
int m_wildcard_trans;
|
||||
// Wildcard (NULL if no wildcard transition present)
|
||||
Wildcard *m_wildcard;
|
||||
// Associated rule for final states, NULL if not final
|
||||
void *m_rule;
|
||||
State(int id)
|
||||
{
|
||||
m_id = id;
|
||||
m_wildcard_trans = -1;
|
||||
m_wildcard = NULL;
|
||||
m_rule = NULL;
|
||||
};
|
||||
~State() { delete m_wildcard; };
|
||||
|
||||
|
||||
|
||||
NdfAutomata() { newState(); };
|
||||
~NdfAutomata();
|
||||
|
||||
const State *getInitial()const { return m_states[0]; };
|
||||
State *getInitial() { return m_states[0]; };
|
||||
|
||||
/// Creates a new state qith a valid id
|
||||
State *newState();
|
||||
|
||||
const State *getState(int i)const { return m_states[i]; };
|
||||
size_t size()const { return m_states.size(); };
|
||||
|
||||
/// return all the symbols that lead to other states starting
|
||||
/// in any of the states in the given set. Also if there are
|
||||
/// wildcard transitions, give back a new wildcard that guarantees
|
||||
/// that its matches match all the wildcards in the set.
|
||||
/// So the symbols returned in out_symbols do NOT overlap those that
|
||||
/// match the returned wildcard (if present). And the union of out_symbols
|
||||
/// and those matched by the wildcard, are all the valid transitions from
|
||||
/// the given state set
|
||||
void symbolsFrom(const IntSet &states, SymbolSet &out_symbols, Wildcard *&wildcard)const;
|
||||
|
||||
/// Get the set of states that are reachable from the given state set using the given symbol
|
||||
void transitionsFrom(const IntSet &states, ustring symbol, IntSet &out_states)const;
|
||||
/// Get the set of states that are reachable from the given state set by wildcard
|
||||
void wildcardTransitionsFrom(const IntSet &states, IntSet &out_states)const;
|
||||
|
||||
/// Perform a lambda closure of a state set
|
||||
/// Get the set of state id's reachable by the given symbol
|
||||
///
|
||||
/// In other words, complete the given set so it includes all the additional
|
||||
/// states that are reachable by the lambda symbol
|
||||
void lambdaClosure(IntSet &states)const;
|
||||
/// It doesn't clean the given result set, so you can use this
|
||||
/// function to accumulate states.
|
||||
void getTransitions(ustring symbol, IntSet& out_states) const;
|
||||
|
||||
/// for debuging purposes
|
||||
std::string tostr()const;
|
||||
/// Get all the lambda transitions
|
||||
///
|
||||
/// Returns the state collection as a pair of iterators [begin, end)
|
||||
std::pair<IntSet::const_iterator, IntSet::const_iterator>
|
||||
getLambdaTransitions() const;
|
||||
|
||||
/// Add a standard transition (also valid for lambda)
|
||||
void addTransition(ustring symbol, State* state);
|
||||
/// Add a wildcard transition
|
||||
///
|
||||
/// Note that the state is going to take ownership of the wildcard
|
||||
/// pointer. So it should be newly allocated on heap and you don't
|
||||
/// have to delete ir
|
||||
void addWildcardTransition(Wildcard* wildcard, State* state);
|
||||
|
||||
/// For final states, this sets the associated rule. Which
|
||||
/// can be any kind of pointer
|
||||
void setRule(void* rule) { m_rule = rule; };
|
||||
|
||||
void* getRule() const { return m_rule; };
|
||||
int getId() const { return m_id; };
|
||||
|
||||
/// For debugging purposes
|
||||
std::string tostr() const;
|
||||
|
||||
protected:
|
||||
/// Vector of states
|
||||
std::vector<State *> m_states;
|
||||
// State id (i.e index in the states vector)
|
||||
int m_id;
|
||||
// Transitions by single symbols
|
||||
SymbolToIntList m_symbol_trans;
|
||||
// In case m_wildcard is not NULL this holds the destination
|
||||
// of the wildcard transition
|
||||
int m_wildcard_trans;
|
||||
// Wildcard (NULL if no wildcard transition present)
|
||||
Wildcard* m_wildcard;
|
||||
// Associated rule for final states, NULL if not final
|
||||
void* m_rule;
|
||||
};
|
||||
|
||||
|
||||
|
||||
NdfAutomata() { newState(); };
|
||||
~NdfAutomata();
|
||||
|
||||
const State* getInitial() const { return m_states[0]; };
|
||||
State* getInitial() { return m_states[0]; };
|
||||
|
||||
/// Creates a new state with a valid id
|
||||
State* newState();
|
||||
|
||||
const State* getState(int i) const { return m_states[i]; };
|
||||
size_t size() const { return m_states.size(); };
|
||||
|
||||
/// return all the symbols that lead to other states starting
|
||||
/// in any of the states in the given set. Also if there are
|
||||
/// wildcard transitions, give back a new wildcard that guarantees
|
||||
/// that its matches match all the wildcards in the set.
|
||||
/// So the symbols returned in out_symbols do NOT overlap those that
|
||||
/// match the returned wildcard (if present). And the union of out_symbols
|
||||
/// and those matched by the wildcard, are all the valid transitions from
|
||||
/// the given state set
|
||||
void symbolsFrom(const IntSet& states, SymbolSet& out_symbols,
|
||||
Wildcard*& wildcard) const;
|
||||
|
||||
/// Get the set of states that are reachable from the given state set using the given symbol
|
||||
void transitionsFrom(const IntSet& states, ustring symbol,
|
||||
IntSet& out_states) const;
|
||||
/// Get the set of states that are reachable from the given state set by wildcard
|
||||
void wildcardTransitionsFrom(const IntSet& states,
|
||||
IntSet& out_states) const;
|
||||
|
||||
/// Perform a lambda closure of a state set
|
||||
///
|
||||
/// In other words, complete the given set so it includes all the additional
|
||||
/// states that are reachable by the lambda symbol
|
||||
void lambdaClosure(IntSet& states) const;
|
||||
|
||||
/// for debugging purposes
|
||||
std::string tostr() const;
|
||||
|
||||
protected:
|
||||
/// Vector of states
|
||||
std::vector<State*> m_states;
|
||||
};
|
||||
|
||||
|
||||
@@ -177,7 +179,8 @@ class NdfAutomata {
|
||||
typedef std::vector<int> StateSetKey;
|
||||
|
||||
// Compute the unique key for the given set of states
|
||||
void keyFromStateSet(const IntSet &states, StateSetKey &out_key);
|
||||
void
|
||||
keyFromStateSet(const IntSet& states, StateSetKey& out_key);
|
||||
|
||||
|
||||
|
||||
@@ -188,84 +191,83 @@ void keyFromStateSet(const IntSet &states, StateSetKey &out_key);
|
||||
/// time parsing of light path expressions
|
||||
class DfAutomata {
|
||||
friend class DfOptimizedAutomata;
|
||||
|
||||
public:
|
||||
/// Simple state for a deterministic automata
|
||||
class State {
|
||||
friend class DfAutomata;
|
||||
friend class DfOptimizedAutomata;
|
||||
|
||||
public:
|
||||
/// Simple state for a deterministic automata
|
||||
class State {
|
||||
friend class DfAutomata;
|
||||
friend class DfOptimizedAutomata;
|
||||
public:
|
||||
State(int id)
|
||||
{
|
||||
m_id = id;
|
||||
m_wildcard_trans = -1;
|
||||
}
|
||||
|
||||
State(int id)
|
||||
{
|
||||
m_id = id;
|
||||
m_wildcard_trans = -1;
|
||||
}
|
||||
/// Get the transition for a symbol
|
||||
//
|
||||
/// Returns -1 if no transitions with that symbol. That means the
|
||||
/// symbol is not recognized at this point of the automata
|
||||
int getTransition(ustring symbol) const;
|
||||
|
||||
/// Get the transition for a symbol
|
||||
//
|
||||
/// Returns -1 if no transitions with that symbol. That means the
|
||||
/// symbol is not recognized at this point of the automata
|
||||
int getTransition(ustring symbol)const;
|
||||
// Same semantics as in NdfAutomata::State
|
||||
void addTransition(ustring symbol, State* state);
|
||||
// WARNING: this has an optimized representation and has to be called
|
||||
// always AFTER all the normal transitions have been added
|
||||
void addWildcardTransition(Wildcard* wildcard, State* state);
|
||||
|
||||
// Same semantics as in NdfAutomata::State
|
||||
void addTransition(ustring symbol, State *state);
|
||||
// WARNING: this has an optimized representation and has to be called
|
||||
// always AFTER all the normal transitions have been added
|
||||
void addWildcardTransition(Wildcard *wildcard, State *state);
|
||||
|
||||
/// Optimize transitions
|
||||
///
|
||||
/// Sometimes the existing wildcard can be extended to wrap some of
|
||||
/// the single symbol transitions. This function performs that optimization
|
||||
void removeUselessTransitions();
|
||||
|
||||
void addRule(void *rule) { m_rules.push_back(rule); };
|
||||
const RuleSet &getRules()const { return m_rules; };
|
||||
int getId()const { return m_id; };
|
||||
std::string tostr()const;
|
||||
|
||||
protected:
|
||||
|
||||
int m_id;
|
||||
// Only one transition per symbol here
|
||||
SymbolToInt m_symbol_trans;
|
||||
int m_wildcard_trans;
|
||||
// A final state here might contain several final states
|
||||
// from the original NDF automata. Therefore, we need a list
|
||||
// of rules here
|
||||
RuleSet m_rules;
|
||||
};
|
||||
|
||||
|
||||
DfAutomata() {};
|
||||
~DfAutomata();
|
||||
|
||||
State *newState();
|
||||
const State *getState(int i)const { return m_states[i]; };
|
||||
size_t size()const { return m_states.size(); };
|
||||
// In case somebody wants to reuse the same object and recreate
|
||||
// an automata, we provide this method
|
||||
void clear();
|
||||
|
||||
/// Colapse all the equivalent states into single ones
|
||||
void removeEquivalentStates();
|
||||
/// Go through all the states and perform removeUselessTransitions
|
||||
/// method call on them
|
||||
/// Optimize transitions
|
||||
///
|
||||
/// Sometimes the existing wildcard can be extended to wrap some of
|
||||
/// the single symbol transitions. This function performs that optimization
|
||||
void removeUselessTransitions();
|
||||
|
||||
/// For debuging purposes
|
||||
std::string tostr()const;
|
||||
void addRule(void* rule) { m_rules.push_back(rule); };
|
||||
const RuleSet& getRules() const { return m_rules; };
|
||||
int getId() const { return m_id; };
|
||||
std::string tostr() const;
|
||||
|
||||
protected:
|
||||
int m_id;
|
||||
// Only one transition per symbol here
|
||||
SymbolToInt m_symbol_trans;
|
||||
int m_wildcard_trans;
|
||||
// A final state here might contain several final states
|
||||
// from the original NDF automata. Therefore, we need a list
|
||||
// of rules here
|
||||
RuleSet m_rules;
|
||||
};
|
||||
|
||||
/// Return true if two states are equivalent
|
||||
///
|
||||
/// Two states are equivalent if their transition tables lead
|
||||
/// to the same states for the same symbols
|
||||
bool equivalent(const State *dfstateA, const State *dfstateB);
|
||||
|
||||
// State vector with the automata
|
||||
std::vector<State *> m_states;
|
||||
DfAutomata() {};
|
||||
~DfAutomata();
|
||||
|
||||
State* newState();
|
||||
const State* getState(int i) const { return m_states[i]; };
|
||||
size_t size() const { return m_states.size(); };
|
||||
// In case somebody wants to reuse the same object and recreate
|
||||
// an automata, we provide this method
|
||||
void clear();
|
||||
|
||||
/// Colapse all the equivalent states into single ones
|
||||
void removeEquivalentStates();
|
||||
/// Go through all the states and perform removeUselessTransitions
|
||||
/// method call on them
|
||||
void removeUselessTransitions();
|
||||
|
||||
/// For debugging purposes
|
||||
std::string tostr() const;
|
||||
|
||||
protected:
|
||||
/// Return true if two states are equivalent
|
||||
///
|
||||
/// Two states are equivalent if their transition tables lead
|
||||
/// to the same states for the same symbols
|
||||
bool equivalent(const State* dfstateA, const State* dfstateB);
|
||||
|
||||
// State vector with the automata
|
||||
std::vector<State*> m_states;
|
||||
};
|
||||
|
||||
|
||||
@@ -274,40 +276,42 @@ class DfAutomata {
|
||||
/// of state sets that have already been found to be new states of the
|
||||
/// deterministic automata
|
||||
class StateSetRecord {
|
||||
public:
|
||||
StateSetRecord(const NdfAutomata &ndfautomata, DfAutomata &dfautomata):
|
||||
m_ndfautomata(ndfautomata), m_dfautomata(dfautomata)
|
||||
{};
|
||||
public:
|
||||
StateSetRecord(const NdfAutomata& ndfautomata, DfAutomata& dfautomata)
|
||||
: m_ndfautomata(ndfautomata), m_dfautomata(dfautomata) {};
|
||||
|
||||
// A new found state is defined by the deterministic state created
|
||||
// for it and the state(int) set in the original automata
|
||||
typedef std::pair<DfAutomata::State *, IntSet> Discovery;
|
||||
// The type that will index our new created states indexed by the set key
|
||||
typedef std::map<StateSetKey, DfAutomata::State *> StateSetMap;
|
||||
// A new found state is defined by the deterministic state created
|
||||
// for it and the state(int) set in the original automata
|
||||
typedef std::pair<DfAutomata::State*, IntSet> Discovery;
|
||||
// The type that will index our new created states indexed by the set key
|
||||
typedef std::map<StateSetKey, DfAutomata::State*> StateSetMap;
|
||||
|
||||
/// Take a state set and build a new df state (or return existing one)
|
||||
/// Also, if it was newly created, append it to the discovered list so we
|
||||
/// can iterate over it later
|
||||
DfAutomata::State *ensureState(const IntSet &newstates, std::list<Discovery> &discovered);
|
||||
/// Take a state set and build a new df state (or return existing one)
|
||||
/// Also, if it was newly created, append it to the discovered list so we
|
||||
/// can iterate over it later
|
||||
DfAutomata::State* ensureState(const IntSet& newstates,
|
||||
std::list<Discovery>& discovered);
|
||||
|
||||
private:
|
||||
private:
|
||||
/// Gather all the rules from the original automata in the given sets (if any)
|
||||
/// and put them in the dfstate rule set
|
||||
void getRulesFromSet(DfAutomata::State* dfstate,
|
||||
const NdfAutomata& ndfautomata,
|
||||
const IntSet& ndfstates);
|
||||
|
||||
/// Gather all the rules from the original automata in the given sets (if any)
|
||||
/// and put them in the dfstate rule set
|
||||
void getRulesFromSet(DfAutomata::State *dfstate, const NdfAutomata &ndfautomata, const IntSet &ndfstates);
|
||||
|
||||
const NdfAutomata &m_ndfautomata;
|
||||
DfAutomata &m_dfautomata;
|
||||
StateSetMap m_key_to_dfstate;
|
||||
const NdfAutomata& m_ndfautomata;
|
||||
DfAutomata& m_dfautomata;
|
||||
StateSetMap m_key_to_dfstate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// NDF to DF automata convertion
|
||||
/// NDF to DF automata conversion
|
||||
///
|
||||
/// This function is the most important pice of the whole process. It takes
|
||||
/// a non-deterministic finite automata and computes an equivalent deterministic
|
||||
/// one. It is equivalente in the sense that they both recognize the same language
|
||||
void ndfautoToDfauto(const NdfAutomata &ndfautomata, DfAutomata &dfautomata);
|
||||
void
|
||||
ndfautoToDfauto(const NdfAutomata& ndfautomata, DfAutomata& dfautomata);
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#include <OpenImageIO/filesystem.h>
|
||||
#include <OpenImageIO/strutil.h>
|
||||
|
||||
#ifdef OSL_USE_OPTIX
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
#include "backendllvm.h"
|
||||
|
||||
@@ -259,7 +255,8 @@ BackendLLVM::llvm_global_symbol_ptr(ustring name)
|
||||
// the ShaderGlobals struct.
|
||||
int sg_index = ShaderGlobalNameToIndex(name);
|
||||
OSL_ASSERT(sg_index >= 0);
|
||||
return ll.void_ptr(ll.GEP(sg_ptr(), 0, sg_index));
|
||||
return ll.void_ptr(ll.GEP(sg_ptr(), 0, sg_index),
|
||||
fmtformat("glob_{}_voidptr", name));
|
||||
}
|
||||
|
||||
|
||||
@@ -651,7 +648,7 @@ BackendLLVM::llvm_load_value(const Symbol& sym, int deriv,
|
||||
}
|
||||
|
||||
return llvm_load_value(llvm_get_pointer(sym), sym.typespec(), deriv,
|
||||
arrayindex, component, cast);
|
||||
arrayindex, component, cast, sym.name().string());
|
||||
}
|
||||
|
||||
|
||||
@@ -659,7 +656,7 @@ BackendLLVM::llvm_load_value(const Symbol& sym, int deriv,
|
||||
llvm::Value*
|
||||
BackendLLVM::llvm_load_value(llvm::Value* ptr, const TypeSpec& type, int deriv,
|
||||
llvm::Value* arrayindex, int component,
|
||||
TypeDesc cast)
|
||||
TypeDesc cast, const std::string& llname)
|
||||
{
|
||||
if (!ptr)
|
||||
return NULL; // Error
|
||||
@@ -681,7 +678,7 @@ BackendLLVM::llvm_load_value(llvm::Value* ptr, const TypeSpec& type, int deriv,
|
||||
ptr = ll.GEP(ptr, 0, component);
|
||||
|
||||
// Now grab the value
|
||||
llvm::Value* result = ll.op_load(ptr);
|
||||
llvm::Value* result = ll.op_load(ptr, llname);
|
||||
|
||||
if (type.is_closure_based())
|
||||
return result;
|
||||
|
||||
+199
-173
@@ -4,15 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
using namespace OSL;
|
||||
using namespace OSL::pvt;
|
||||
|
||||
#include "runtimeoptimize.h"
|
||||
#include <OSL/llvm_util.h>
|
||||
#include "runtimeoptimize.h"
|
||||
|
||||
// additional includes for creating global OptiX variables
|
||||
#include "llvm/IR/Constants.h"
|
||||
@@ -22,7 +22,7 @@ using namespace OSL::pvt;
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
namespace pvt { // OSL::pvt
|
||||
namespace pvt { // OSL::pvt
|
||||
|
||||
|
||||
|
||||
@@ -30,16 +30,16 @@ namespace pvt { // OSL::pvt
|
||||
/// code to implement a shader group.
|
||||
class BackendLLVM final : public OSOProcessorBase {
|
||||
public:
|
||||
BackendLLVM (ShadingSystemImpl &shadingsys, ShaderGroup &group,
|
||||
ShadingContext *context);
|
||||
BackendLLVM(ShadingSystemImpl& shadingsys, ShaderGroup& group,
|
||||
ShadingContext* context);
|
||||
|
||||
virtual ~BackendLLVM ();
|
||||
virtual ~BackendLLVM();
|
||||
|
||||
virtual void set_inst (int layer);
|
||||
virtual void set_inst(int layer);
|
||||
|
||||
/// Create an llvm function for the whole shader group, JIT it,
|
||||
/// and store the llvm::Function* handle to it with the ShaderGroup.
|
||||
virtual void run ();
|
||||
virtual void run();
|
||||
|
||||
|
||||
/// What LLVM debug level are we at?
|
||||
@@ -47,33 +47,33 @@ public:
|
||||
|
||||
/// Set up a bunch of static things we'll need for the whole group.
|
||||
///
|
||||
void initialize_llvm_group ();
|
||||
void initialize_llvm_group();
|
||||
|
||||
int layer_remap (int origlayer) const { return m_layer_remap[origlayer]; }
|
||||
int layer_remap(int origlayer) const { return m_layer_remap[origlayer]; }
|
||||
|
||||
/// Create an llvm function for the current shader instance.
|
||||
/// This will end up being the group entry if 'groupentry' is true.
|
||||
llvm::Function* build_llvm_instance (bool groupentry);
|
||||
llvm::Function* build_llvm_instance(bool groupentry);
|
||||
|
||||
/// Create an llvm function for group initialization code.
|
||||
llvm::Function* build_llvm_init ();
|
||||
llvm::Function* build_llvm_init();
|
||||
|
||||
/// Build up LLVM IR code for the given range [begin,end) or
|
||||
/// opcodes, putting them (initially) into basic block bb (or the
|
||||
/// current basic block if bb==NULL).
|
||||
bool build_llvm_code (int beginop, int endop, llvm::BasicBlock *bb=NULL);
|
||||
bool build_llvm_code(int beginop, int endop, llvm::BasicBlock* bb = NULL);
|
||||
|
||||
typedef std::map<std::string, llvm::Value*> AllocationMap;
|
||||
|
||||
void llvm_assign_initial_value (const Symbol& sym, bool force = false);
|
||||
llvm::LLVMContext &llvm_context () const { return ll.context(); }
|
||||
AllocationMap &named_values () { return m_named_values; }
|
||||
void llvm_assign_initial_value(const Symbol& sym, bool force = false);
|
||||
llvm::LLVMContext& llvm_context() const { return ll.context(); }
|
||||
AllocationMap& named_values() { return m_named_values; }
|
||||
|
||||
/// Return an llvm::Value* corresponding to the address of the given
|
||||
/// symbol element, with derivative (0=value, 1=dx, 2=dy) and array
|
||||
/// index (NULL if it's not an array).
|
||||
llvm::Value *llvm_get_pointer (const Symbol& sym, int deriv=0,
|
||||
llvm::Value *arrayindex=NULL);
|
||||
llvm::Value* llvm_get_pointer(const Symbol& sym, int deriv = 0,
|
||||
llvm::Value* arrayindex = NULL);
|
||||
|
||||
/// Return the llvm::Value* corresponding to the given element
|
||||
/// value, with derivative (0=value, 1=dx, 2=dy), array index (NULL
|
||||
@@ -83,9 +83,9 @@ public:
|
||||
/// return the scalar -- this allows automatic casting to triples.
|
||||
/// Finally, auto-cast int<->float if requested (no conversion is
|
||||
/// performed if cast is the default of UNKNOWN).
|
||||
llvm::Value *llvm_load_value (const Symbol& sym, int deriv,
|
||||
llvm::Value *arrayindex, int component,
|
||||
TypeDesc cast=TypeDesc::UNKNOWN);
|
||||
llvm::Value* llvm_load_value(const Symbol& sym, int deriv,
|
||||
llvm::Value* arrayindex, int component,
|
||||
TypeDesc cast = TypeDesc::UNKNOWN);
|
||||
|
||||
|
||||
/// Given an llvm::Value* of a pointer (and the type of the data
|
||||
@@ -97,62 +97,68 @@ public:
|
||||
/// and it's a scalar, return the scalar -- this allows automatic
|
||||
/// casting to triples. Finally, auto-cast int<->float if requested
|
||||
/// (no conversion is performed if cast is the default of UNKNOWN).
|
||||
llvm::Value *llvm_load_value (llvm::Value *ptr, const TypeSpec &type,
|
||||
int deriv, llvm::Value *arrayindex,
|
||||
int component, TypeDesc cast=TypeDesc::UNKNOWN);
|
||||
llvm::Value* llvm_load_value(llvm::Value* ptr, const TypeSpec& type,
|
||||
int deriv, llvm::Value* arrayindex,
|
||||
int component,
|
||||
TypeDesc cast = TypeDesc::UNKNOWN,
|
||||
const std::string& llname = {});
|
||||
|
||||
/// Just like llvm_load_value, but when both the symbol and the
|
||||
/// array index are known to be constants. This can even handle
|
||||
/// pulling constant-indexed elements out of constant arrays. Use
|
||||
/// arrayindex==-1 to indicate that it's not an array dereference.
|
||||
llvm::Value *llvm_load_constant_value (const Symbol& sym,
|
||||
int arrayindex, int component,
|
||||
TypeDesc cast=TypeDesc::UNKNOWN);
|
||||
llvm::Value* llvm_load_constant_value(const Symbol& sym, int arrayindex,
|
||||
int component,
|
||||
TypeDesc cast = TypeDesc::UNKNOWN);
|
||||
|
||||
/// llvm_load_value with non-constant component designation. Does
|
||||
/// not work with arrays or do type casts!
|
||||
llvm::Value *llvm_load_component_value (const Symbol& sym, int deriv,
|
||||
llvm::Value *component);
|
||||
llvm::Value* llvm_load_component_value(const Symbol& sym, int deriv,
|
||||
llvm::Value* component);
|
||||
|
||||
/// Non-array version of llvm_load_value, with default deriv &
|
||||
/// component.
|
||||
llvm::Value *llvm_load_value (const Symbol& sym, int deriv = 0,
|
||||
int component = 0,
|
||||
TypeDesc cast=TypeDesc::UNKNOWN) {
|
||||
return (use_optix() && ! sym.typespec().is_closure() && sym.typespec().is_string())
|
||||
? llvm_load_device_string (sym, /*follow*/ true)
|
||||
: llvm_load_value (sym, deriv, NULL, component, cast);
|
||||
llvm::Value* llvm_load_value(const Symbol& sym, int deriv = 0,
|
||||
int component = 0,
|
||||
TypeDesc cast = TypeDesc::UNKNOWN)
|
||||
{
|
||||
return (use_optix() && !sym.typespec().is_closure()
|
||||
&& sym.typespec().is_string())
|
||||
? llvm_load_device_string(sym, /*follow*/ true)
|
||||
: llvm_load_value(sym, deriv, NULL, component, cast);
|
||||
}
|
||||
|
||||
/// Load the address of a global device-side string pointer, which may
|
||||
/// reside in a global variable, the groupdata struct, or a local value.
|
||||
llvm::Value *llvm_load_device_string (const Symbol& sym, bool follow);
|
||||
llvm::Value* llvm_load_device_string(const Symbol& sym, bool follow);
|
||||
|
||||
/// Convenience function to load a string for CPU or GPU device
|
||||
llvm::Value *llvm_load_string (const Symbol& sym) {
|
||||
llvm::Value* llvm_load_string(const Symbol& sym)
|
||||
{
|
||||
OSL_DASSERT(sym.typespec().is_string());
|
||||
return use_optix()
|
||||
? llvm_load_device_string(sym, /*follow*/ true)
|
||||
: llvm_load_value(sym);
|
||||
return use_optix() ? llvm_load_device_string(sym, /*follow*/ true)
|
||||
: llvm_load_value(sym);
|
||||
}
|
||||
|
||||
/// Legacy version
|
||||
///
|
||||
llvm::Value *loadLLVMValue (const Symbol& sym, int component=0,
|
||||
int deriv=0, TypeDesc cast=TypeDesc::UNKNOWN) {
|
||||
return llvm_load_value (sym, deriv, NULL, component, cast);
|
||||
llvm::Value* loadLLVMValue(const Symbol& sym, int component = 0,
|
||||
int deriv = 0, TypeDesc cast = TypeDesc::UNKNOWN)
|
||||
{
|
||||
return llvm_load_value(sym, deriv, NULL, component, cast);
|
||||
}
|
||||
|
||||
/// Return an llvm::Value* that is either a scalar and derivs is
|
||||
/// false, or a pointer to sym's values (if sym is an aggregate or
|
||||
/// derivs == true). Furthermore, if deriv == true and sym doesn't
|
||||
/// have derivs, coerce it into a variable with zero derivs.
|
||||
llvm::Value *llvm_load_arg (const Symbol& sym, bool derivs);
|
||||
llvm::Value* llvm_load_arg(const Symbol& sym, bool derivs);
|
||||
|
||||
/// Just like llvm_load_arg(sym,deriv), except use use sym's derivs
|
||||
/// as-is, no coercion.
|
||||
llvm::Value *llvm_load_arg (const Symbol& sym) {
|
||||
return llvm_load_arg (sym, sym.has_derivs());
|
||||
llvm::Value* llvm_load_arg(const Symbol& sym)
|
||||
{
|
||||
return llvm_load_arg(sym, sym.has_derivs());
|
||||
}
|
||||
|
||||
/// Store new_val into the given symbol, given the derivative
|
||||
@@ -161,8 +167,8 @@ public:
|
||||
/// symbol doesn't have a deriv, it's a nop. If the component >0
|
||||
/// and it's a scalar, set the scalar. Returns true if ok, false
|
||||
/// upon failure.
|
||||
bool llvm_store_value (llvm::Value *new_val, const Symbol& sym, int deriv,
|
||||
llvm::Value *arrayindex, int component);
|
||||
bool llvm_store_value(llvm::Value* new_val, const Symbol& sym, int deriv,
|
||||
llvm::Value* arrayindex, int component);
|
||||
|
||||
/// Store new_val into the memory pointed to by dst_ptr, given the
|
||||
/// derivative (0=value, 1=dx, 2=dy), array index (NULL if it's not
|
||||
@@ -170,150 +176,156 @@ public:
|
||||
/// and the symbol doesn't have a deriv, it's a nop. If the
|
||||
/// component >0 and it's a scalar, set the scalar. Returns true if
|
||||
/// ok, false upon failure.
|
||||
bool llvm_store_value (llvm::Value* new_val, llvm::Value* dst_ptr,
|
||||
const TypeSpec &type, int deriv,
|
||||
llvm::Value* arrayindex, int component);
|
||||
bool llvm_store_value(llvm::Value* new_val, llvm::Value* dst_ptr,
|
||||
const TypeSpec& type, int deriv,
|
||||
llvm::Value* arrayindex, int component);
|
||||
|
||||
/// Non-array version of llvm_store_value, with default deriv &
|
||||
/// component.
|
||||
bool llvm_store_value (llvm::Value *new_val, const Symbol& sym,
|
||||
int deriv=0, int component=0) {
|
||||
return llvm_store_value (new_val, sym, deriv, NULL, component);
|
||||
bool llvm_store_value(llvm::Value* new_val, const Symbol& sym,
|
||||
int deriv = 0, int component = 0)
|
||||
{
|
||||
return llvm_store_value(new_val, sym, deriv, NULL, component);
|
||||
}
|
||||
|
||||
/// llvm_store_value with non-constant component designation. Does
|
||||
/// not work with arrays or do type casts!
|
||||
bool llvm_store_component_value (llvm::Value *new_val, const Symbol& sym,
|
||||
int deriv, llvm::Value *component);
|
||||
bool llvm_store_component_value(llvm::Value* new_val, const Symbol& sym,
|
||||
int deriv, llvm::Value* component);
|
||||
|
||||
/// Legacy version
|
||||
///
|
||||
bool storeLLVMValue (llvm::Value* new_val, const Symbol& sym,
|
||||
int component=0, int deriv=0) {
|
||||
return llvm_store_value (new_val, sym, deriv, component);
|
||||
bool storeLLVMValue(llvm::Value* new_val, const Symbol& sym,
|
||||
int component = 0, int deriv = 0)
|
||||
{
|
||||
return llvm_store_value(new_val, sym, deriv, component);
|
||||
}
|
||||
|
||||
/// Generate an alloca instruction to allocate space for the given
|
||||
/// type, with derivs if derivs==true, and return the its pointer.
|
||||
llvm::Value *llvm_alloca (const TypeSpec &type, bool derivs,
|
||||
const std::string &name="", int align=0);
|
||||
llvm::Value* llvm_alloca(const TypeSpec& type, bool derivs,
|
||||
const std::string& name = "", int align = 0);
|
||||
|
||||
/// Given the OSL symbol, return the llvm::Value* corresponding to the
|
||||
/// address of the start of that symbol (first element, first component,
|
||||
/// and just the plain value if it has derivatives). This is retrieved
|
||||
/// from the allocation map if already there; and if not yet in the
|
||||
/// map, the symbol is alloca'd and placed in the map.
|
||||
llvm::Value *getOrAllocateLLVMSymbol (const Symbol& sym);
|
||||
llvm::Value* getOrAllocateLLVMSymbol(const Symbol& sym);
|
||||
|
||||
/// 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.
|
||||
llvm::Value *getOrAllocateCUDAVariable (const Symbol& sym, bool addMetadata=false);
|
||||
llvm::Value* getOrAllocateCUDAVariable(const Symbol& sym,
|
||||
bool addMetadata = false);
|
||||
|
||||
/// Create a CUDA global variable and add it to the current Module
|
||||
llvm::Value *addCUDAVariable (const std::string& name, int size, int alignment,
|
||||
const void* data, TypeDesc type=TypeDesc::UNKNOWN);
|
||||
llvm::Value* addCUDAVariable(const std::string& name, int size,
|
||||
int alignment, const void* data,
|
||||
TypeDesc type = TypeDesc::UNKNOWN);
|
||||
|
||||
/// Create the extra semantic information needed for OptiX variables
|
||||
void createOptixMetadata (const std::string& name, const Symbol& sym );
|
||||
void createOptixMetadata(const std::string& name, const Symbol& sym);
|
||||
|
||||
/// Retrieve an llvm::Value that is a pointer holding the start address
|
||||
/// of the specified symbol. This always works for globals and params;
|
||||
/// for stack variables (locals/temps) is succeeds only if the symbol is
|
||||
/// already in the allocation table (will fail otherwise). This method
|
||||
/// is not designed to retrieve constants.
|
||||
llvm::Value *getLLVMSymbolBase (const Symbol &sym);
|
||||
llvm::Value* getLLVMSymbolBase(const Symbol& sym);
|
||||
|
||||
/// Retrieve the named global ("P", "N", etc.).
|
||||
llvm::Value *llvm_global_symbol_ptr (ustring name);
|
||||
llvm::Value* llvm_global_symbol_ptr(ustring name);
|
||||
|
||||
/// Test whether val is nonzero, return the llvm::Value* that's the
|
||||
/// result of a CreateICmpNE or CreateFCmpUNE (depending on the
|
||||
/// type). If test_derivs is true, it it also tests whether the
|
||||
/// derivs are zero.
|
||||
llvm::Value *llvm_test_nonzero (Symbol &val, bool test_derivs = false);
|
||||
llvm::Value* llvm_test_nonzero(Symbol& val, bool test_derivs = false);
|
||||
|
||||
/// Implementaiton of Simple assignment. If arrayindex >= 0, in
|
||||
/// Implementation of Simple assignment. If arrayindex >= 0, in
|
||||
/// designates a particular array index to assign.
|
||||
bool llvm_assign_impl (Symbol &Result, Symbol &Src, int arrayindex = -1,
|
||||
int srccomp = -1, int dstcomp = -1);
|
||||
bool llvm_assign_impl(Symbol& Result, Symbol& Src, int arrayindex = -1,
|
||||
int srccomp = -1, int dstcomp = -1);
|
||||
|
||||
|
||||
/// Convert the name of a global (and its derivative index) into the
|
||||
/// field number of the ShaderGlobals struct.
|
||||
int ShaderGlobalNameToIndex (ustring name);
|
||||
int ShaderGlobalNameToIndex(ustring name);
|
||||
|
||||
/// Return the LLVM type handle for the ShaderGlobals struct.
|
||||
///
|
||||
llvm::Type *llvm_type_sg ();
|
||||
llvm::Type* llvm_type_sg();
|
||||
|
||||
/// Return the LLVM type handle for a pointer to a
|
||||
/// ShaderGlobals struct.
|
||||
llvm::Type *llvm_type_sg_ptr ();
|
||||
llvm::Type* llvm_type_sg_ptr();
|
||||
|
||||
/// 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 ();
|
||||
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); }
|
||||
|
||||
llvm::Value* llvm_ptr_cast(llvm::Value* val, const TypeSpec& type)
|
||||
{
|
||||
return ll.ptr_cast(val, type.simpletype());
|
||||
}
|
||||
|
||||
llvm::Value *llvm_ptr_cast (llvm::Value* val, const TypeSpec &type) {
|
||||
return ll.ptr_cast (val, type.simpletype());
|
||||
}
|
||||
|
||||
llvm::Value *llvm_void_ptr (const Symbol &sym, int deriv=0) {
|
||||
return ll.void_ptr (llvm_get_pointer(sym, deriv));
|
||||
llvm::Value* llvm_void_ptr(const Symbol& sym, int deriv = 0)
|
||||
{
|
||||
return ll.void_ptr(llvm_get_pointer(sym, deriv));
|
||||
}
|
||||
|
||||
/// Return the LLVM type handle for a structure of the common group
|
||||
/// data that holds all the shader params.
|
||||
llvm::Type *llvm_type_groupdata ();
|
||||
llvm::Type* llvm_type_groupdata();
|
||||
|
||||
/// Return the LLVM type handle for a pointer to the common group
|
||||
/// data that holds all the shader params.
|
||||
llvm::Type *llvm_type_groupdata_ptr ();
|
||||
llvm::Type* llvm_type_groupdata_ptr();
|
||||
|
||||
/// 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*.
|
||||
///
|
||||
llvm::Value *groupdata_void_ptr () {
|
||||
return ll.void_ptr (m_llvm_groupdata_ptr);
|
||||
llvm::Value* groupdata_void_ptr()
|
||||
{
|
||||
return ll.void_ptr(m_llvm_groupdata_ptr);
|
||||
}
|
||||
|
||||
/// Return a reference to the specified field within the group data.
|
||||
llvm::Value *groupdata_field_ref (int fieldnum);
|
||||
llvm::Value* groupdata_field_ref(int fieldnum);
|
||||
|
||||
/// Return a pointer to the specified field within the group data,
|
||||
/// optionally cast to pointer to a particular data type.
|
||||
llvm::Value *groupdata_field_ptr (int fieldnum,
|
||||
TypeDesc type = TypeDesc::UNKNOWN);
|
||||
llvm::Value* groupdata_field_ptr(int fieldnum,
|
||||
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`
|
||||
// (which should already be a i64, or if nullptr, then use
|
||||
// m_llvm_shadeindex and convert it to i64).
|
||||
llvm::Value *symloc_ptr(const SymLocationDesc* symloc,
|
||||
llvm::Value* symloc_ptr(const SymLocationDesc* symloc,
|
||||
llvm::Value* base_ptr,
|
||||
llvm::Value* sindex = nullptr) {
|
||||
llvm::Value* sindex = nullptr)
|
||||
{
|
||||
llvm::Value* offset = ll.constanti64(symloc->offset);
|
||||
llvm::Value* stride = ll.constanti64(symloc->stride);
|
||||
if (!sindex)
|
||||
@@ -324,47 +336,47 @@ public:
|
||||
|
||||
/// Return a ref to the bool where the "layer_run" flag is stored for
|
||||
/// the specified layer.
|
||||
llvm::Value *layer_run_ref (int layer);
|
||||
llvm::Value* layer_run_ref(int layer);
|
||||
|
||||
/// Return a ref to the bool where the "userdata_initialized" flag is
|
||||
/// stored for the specified userdata index.
|
||||
llvm::Value *userdata_initialized_ref (int userdata_index=0);
|
||||
llvm::Value* userdata_initialized_ref(int userdata_index = 0);
|
||||
|
||||
/// Generate LLVM code to zero out the variable (including derivs)
|
||||
///
|
||||
void llvm_assign_zero (const Symbol &sym);
|
||||
void llvm_assign_zero(const Symbol& sym);
|
||||
|
||||
/// Generate LLVM code to zero out the derivatives of sym.
|
||||
///
|
||||
void llvm_zero_derivs (const Symbol &sym);
|
||||
void llvm_zero_derivs(const Symbol& sym);
|
||||
|
||||
/// Generate LLVM code to zero out the derivatives of an array
|
||||
/// only for the first count elements of it.
|
||||
///
|
||||
void llvm_zero_derivs (const Symbol &sym, llvm::Value *count);
|
||||
void llvm_zero_derivs(const Symbol& sym, llvm::Value* count);
|
||||
|
||||
/// Generate a debugging printf at shader execution time.
|
||||
void llvm_gen_debug_printf (string_view message);
|
||||
void llvm_gen_debug_printf(string_view message);
|
||||
|
||||
/// Generate a warning message at shader execution time.
|
||||
void llvm_gen_warning (string_view message);
|
||||
void llvm_gen_warning(string_view message);
|
||||
|
||||
/// Generate an error message at shader execution time.
|
||||
void llvm_gen_error (string_view message);
|
||||
void llvm_gen_error(string_view message);
|
||||
|
||||
/// Generate code to call the given layer. If 'unconditional' is
|
||||
/// true, call it without even testing if the layer has already been
|
||||
/// called.
|
||||
void llvm_call_layer (int layer, bool unconditional = false);
|
||||
void llvm_call_layer(int layer, bool unconditional = false);
|
||||
|
||||
/// Execute the upstream connection (if any, and if not yet run) that
|
||||
/// establishes the value of symbol sym, which has index 'symindex'
|
||||
/// within the current layer rop.inst(). If already_run is not NULL,
|
||||
/// it points to a vector of layer indices that are known to have been
|
||||
/// it points to a vector of layer indices that are known to have been
|
||||
/// run -- those can be skipped without dynamically checking their
|
||||
/// execution status.
|
||||
void llvm_run_connected_layers (Symbol &sym, int symindex, int opnum = -1,
|
||||
std::set<int> *already_run = NULL);
|
||||
void llvm_run_connected_layers(Symbol& sym, int symindex, int opnum = -1,
|
||||
std::set<int>* already_run = NULL);
|
||||
|
||||
/// Generate code for a call to the named function with the given
|
||||
/// arg list as symbols -- float & ints will be passed by value,
|
||||
@@ -372,133 +384,147 @@ public:
|
||||
/// is true, pass pointers even for floats if they have derivs.
|
||||
/// Return an llvm::Value* corresponding to the return value of the
|
||||
/// function, if any.
|
||||
llvm::Value *llvm_call_function (const char *name, cspan<const Symbol *> args,
|
||||
bool deriv_ptrs=false);
|
||||
llvm::Value *llvm_call_function (const char *name, const Symbol &A,
|
||||
bool deriv_ptrs=false) {
|
||||
return llvm_call_function (name, { &A }, deriv_ptrs);
|
||||
llvm::Value* llvm_call_function(const char* name, cspan<const Symbol*> args,
|
||||
bool deriv_ptrs = false);
|
||||
llvm::Value* llvm_call_function(const char* name, const Symbol& A,
|
||||
bool deriv_ptrs = false)
|
||||
{
|
||||
return llvm_call_function(name, { &A }, deriv_ptrs);
|
||||
}
|
||||
llvm::Value *llvm_call_function (const char *name, const Symbol &A,
|
||||
const Symbol &B, bool deriv_ptrs=false) {
|
||||
return llvm_call_function (name, { &A, &B }, deriv_ptrs);
|
||||
llvm::Value* llvm_call_function(const char* name, const Symbol& A,
|
||||
const Symbol& B, bool deriv_ptrs = false)
|
||||
{
|
||||
return llvm_call_function(name, { &A, &B }, deriv_ptrs);
|
||||
}
|
||||
llvm::Value *llvm_call_function (const char *name, const Symbol &A,
|
||||
const Symbol &B, const Symbol &C,
|
||||
bool deriv_ptrs=false) {
|
||||
return llvm_call_function (name, { &A, &B, &C }, deriv_ptrs);
|
||||
llvm::Value* llvm_call_function(const char* name, const Symbol& A,
|
||||
const Symbol& B, const Symbol& C,
|
||||
bool deriv_ptrs = false)
|
||||
{
|
||||
return llvm_call_function(name, { &A, &B, &C }, deriv_ptrs);
|
||||
}
|
||||
|
||||
TypeDesc llvm_typedesc (const TypeSpec &typespec) {
|
||||
TypeDesc llvm_typedesc(const TypeSpec& typespec)
|
||||
{
|
||||
return typespec.is_closure_based()
|
||||
? TypeDesc(TypeDesc::PTR, typespec.arraylength())
|
||||
: typespec.simpletype();
|
||||
? TypeDesc(TypeDesc::PTR, typespec.arraylength())
|
||||
: typespec.simpletype();
|
||||
}
|
||||
|
||||
/// Generate the appropriate llvm type definition for a TypeSpec
|
||||
/// (this is the actual type, for example when we allocate it).
|
||||
/// Allocates ptrs for closures.
|
||||
llvm::Type *llvm_type (const TypeSpec &typespec) {
|
||||
return ll.llvm_type (llvm_typedesc(typespec));
|
||||
llvm::Type* llvm_type(const TypeSpec& typespec)
|
||||
{
|
||||
return 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);
|
||||
llvm::Type* llvm_pass_type(const TypeSpec& typespec);
|
||||
|
||||
llvm::PointerType *llvm_type_prepare_closure_func() { return m_llvm_type_prepare_closure_func; }
|
||||
llvm::PointerType *llvm_type_setup_closure_func() { return m_llvm_type_setup_closure_func; }
|
||||
|
||||
/// Return the basic block of the exit for the whole instance.
|
||||
///
|
||||
bool llvm_has_exit_instance_block () const {
|
||||
return m_exit_instance_block;
|
||||
llvm::PointerType* llvm_type_prepare_closure_func()
|
||||
{
|
||||
return m_llvm_type_prepare_closure_func;
|
||||
}
|
||||
llvm::PointerType* llvm_type_setup_closure_func()
|
||||
{
|
||||
return m_llvm_type_setup_closure_func;
|
||||
}
|
||||
|
||||
/// Return the basic block of the exit for the whole instance.
|
||||
///
|
||||
llvm::BasicBlock *llvm_exit_instance_block () {
|
||||
if (! 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.
|
||||
///
|
||||
llvm::BasicBlock* llvm_exit_instance_block()
|
||||
{
|
||||
if (!m_exit_instance_block) {
|
||||
std::string name = fmtformat("{}_{}_exit_", inst()->layername(),
|
||||
inst()->id());
|
||||
m_exit_instance_block = ll.new_basic_block (name);
|
||||
m_exit_instance_block = ll.new_basic_block(name);
|
||||
}
|
||||
return m_exit_instance_block;
|
||||
}
|
||||
|
||||
/// Check for inf/nan in all written-to arguments of the op
|
||||
void llvm_generate_debugnan (const Opcode &op);
|
||||
void llvm_generate_debugnan(const Opcode& op);
|
||||
/// Check for uninitialized values in all read-from arguments to the op
|
||||
void llvm_generate_debug_uninit (const Opcode &op);
|
||||
void llvm_generate_debug_uninit(const Opcode& op);
|
||||
/// Print debugging line for the op
|
||||
void llvm_generate_debug_op_printf (const Opcode &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) {
|
||||
void generated_texture_call(bool handle)
|
||||
{
|
||||
shadingsys().m_stat_tex_calls_codegened += 1;
|
||||
if (handle)
|
||||
shadingsys().m_stat_tex_calls_as_handles += 1;
|
||||
}
|
||||
|
||||
/// Return the mapping from symbol names to GlobalVariables.
|
||||
std::map<std::string,llvm::GlobalVariable*>& get_const_map() { return m_const_map; }
|
||||
std::map<std::string, llvm::GlobalVariable*>& get_const_map()
|
||||
{
|
||||
return m_const_map;
|
||||
}
|
||||
|
||||
/// Return whether or not we are compiling for an OptiX-based renderer.
|
||||
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
|
||||
/// entry in the groupdata struct.
|
||||
int find_userdata_index (const Symbol& sym);
|
||||
int find_userdata_index(const Symbol& sym);
|
||||
|
||||
LLVM_Util ll;
|
||||
|
||||
private:
|
||||
std::vector<int> m_layer_remap; ///< Remapping of layer ordering
|
||||
std::set<int> m_layers_already_run; ///< List of layers run
|
||||
int m_num_used_layers; ///< Number of layers actually used
|
||||
std::vector<int> m_layer_remap; ///< Remapping of layer ordering
|
||||
std::set<int> m_layers_already_run; ///< List of layers run
|
||||
int m_num_used_layers; ///< Number of layers actually used
|
||||
|
||||
double m_stat_total_llvm_time; ///< total time spent on LLVM
|
||||
double m_stat_llvm_setup_time; ///< llvm setup time
|
||||
double m_stat_llvm_irgen_time; ///< llvm IR generation time
|
||||
double m_stat_llvm_opt_time; ///< llvm IR optimization time
|
||||
double m_stat_llvm_jit_time; ///< llvm JIT time
|
||||
double m_stat_total_llvm_time; ///< total time spent on LLVM
|
||||
double m_stat_llvm_setup_time; ///< llvm setup time
|
||||
double m_stat_llvm_irgen_time; ///< llvm IR generation time
|
||||
double m_stat_llvm_opt_time; ///< llvm IR optimization time
|
||||
double m_stat_llvm_jit_time; ///< llvm JIT time
|
||||
|
||||
// LLVM stuff
|
||||
AllocationMap m_named_values;
|
||||
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_userdata_base_ptr;
|
||||
llvm::Value *m_llvm_output_base_ptr;
|
||||
llvm::Value *m_llvm_shadeindex;
|
||||
llvm::BasicBlock * m_exit_instance_block; // exit point for the instance
|
||||
llvm::Type *m_llvm_type_sg; // LLVM type of ShaderGlobals struct
|
||||
llvm::Type *m_llvm_type_groupdata; // LLVM type of group data
|
||||
llvm::Type *m_llvm_type_closure_component; // LLVM type for ClosureComponent
|
||||
llvm::PointerType *m_llvm_type_prepare_closure_func;
|
||||
llvm::PointerType *m_llvm_type_setup_closure_func;
|
||||
int m_llvm_local_mem; // Amount of memory we use for locals
|
||||
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_userdata_base_ptr;
|
||||
llvm::Value* m_llvm_output_base_ptr;
|
||||
llvm::Value* m_llvm_shadeindex;
|
||||
llvm::BasicBlock* m_exit_instance_block; // exit point for the instance
|
||||
llvm::Type* m_llvm_type_sg; // LLVM type of ShaderGlobals struct
|
||||
llvm::Type* m_llvm_type_groupdata; // LLVM type of group data
|
||||
llvm::Type* m_llvm_type_closure_component; // LLVM type for ClosureComponent
|
||||
llvm::PointerType* m_llvm_type_prepare_closure_func;
|
||||
llvm::PointerType* m_llvm_type_setup_closure_func;
|
||||
int m_llvm_local_mem; // Amount of memory we use for locals
|
||||
|
||||
// A mapping from symbol names to llvm::GlobalVariables
|
||||
std::map<std::string,llvm::GlobalVariable*> m_const_map;
|
||||
std::map<std::string, llvm::GlobalVariable*> m_const_map;
|
||||
|
||||
// A mapping from canonical strings to string variable names, used to
|
||||
// detect collisions that might occur due to using the string hash to
|
||||
// create variable names.
|
||||
std::map<std::string,std::string> m_varname_map;
|
||||
std::map<std::string, std::string> m_varname_map;
|
||||
|
||||
bool m_use_optix; ///< Compile for OptiX?
|
||||
bool m_use_optix; ///< Compile for OptiX?
|
||||
|
||||
bool m_use_rs_bitcode; /// To use free function versions of Renderer Service functions.
|
||||
bool m_use_rs_bitcode; /// To use free function versions of Renderer Service functions.
|
||||
|
||||
friend class ShadingSystemImpl;
|
||||
};
|
||||
|
||||
|
||||
}; // namespace pvt
|
||||
}; // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -185,7 +185,7 @@ struct Symbols4ProtectedShaderGlobals {
|
||||
|
||||
SymbolPtrVec varying_symbols;
|
||||
|
||||
void check_if_varing(Symbol& s)
|
||||
void check_if_varying(Symbol& s)
|
||||
{
|
||||
if (!is_shader_global_uniform_by_name(s.name())) {
|
||||
s.make_varying();
|
||||
@@ -202,13 +202,13 @@ struct Symbols4ProtectedShaderGlobals {
|
||||
, surfacearea(Strings::op_surfacearea, TypeSpec(), SymTypeGlobal)
|
||||
, time(Strings::time, TypeSpec(), SymTypeGlobal)
|
||||
{
|
||||
check_if_varing(shader2common);
|
||||
check_if_varing(object2common);
|
||||
check_if_varing(flipHandedness);
|
||||
check_if_varing(raytype);
|
||||
check_if_varing(backfacing);
|
||||
check_if_varing(surfacearea);
|
||||
check_if_varing(time);
|
||||
check_if_varying(shader2common);
|
||||
check_if_varying(object2common);
|
||||
check_if_varying(flipHandedness);
|
||||
check_if_varying(raytype);
|
||||
check_if_varying(backfacing);
|
||||
check_if_varying(surfacearea);
|
||||
check_if_varying(time);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -620,6 +620,20 @@ public:
|
||||
}
|
||||
|
||||
Position common_ancestor_between(Position read_pos, Position write_pos)
|
||||
{
|
||||
// Early out when read and write are at the same position
|
||||
if (read_pos == write_pos)
|
||||
return read_pos;
|
||||
// Early out if either position is the root of the dependency tree
|
||||
if (read_pos == end_pos() || write_pos == end_pos())
|
||||
return end_pos();
|
||||
return search_for_common_ancestor_between(read_pos, write_pos);
|
||||
}
|
||||
|
||||
// Because this function makes use of stack arrays, ensure is NOT inlined
|
||||
// inside a loop to avoid repeatedly reserve stack space each iteration
|
||||
OSL_NOINLINE Position search_for_common_ancestor_between(Position read_pos,
|
||||
Position write_pos)
|
||||
{
|
||||
// To find common anscenstor
|
||||
// Walk up both paths building 2 stacks of positions
|
||||
@@ -629,8 +643,8 @@ public:
|
||||
auto write_iter = begin_at(write_pos);
|
||||
|
||||
const int read_count = read_iter.depth() + 1;
|
||||
OSL_STACK_ARRAY(Position, read_path, read_count);
|
||||
int read_depth = 0;
|
||||
Position* read_path = OSL_ALLOCA(Position, read_count);
|
||||
int read_depth = 0;
|
||||
{
|
||||
// Loop structure is to allow
|
||||
// writing the end position into the read path
|
||||
@@ -644,8 +658,8 @@ public:
|
||||
}
|
||||
|
||||
const int writeCount = write_iter.depth() + 1;
|
||||
OSL_STACK_ARRAY(Position, write_path, writeCount);
|
||||
int write_depth = 0;
|
||||
Position* write_path = OSL_ALLOCA(Position, writeCount);
|
||||
int write_depth = 0;
|
||||
{
|
||||
// Loop structure is to allow
|
||||
// writing the end position into the write path
|
||||
@@ -657,29 +671,53 @@ public:
|
||||
++write_iter;
|
||||
}
|
||||
}
|
||||
const int levelCount = std::min(read_depth, write_depth);
|
||||
const int read_level = read_depth - 1;
|
||||
const int write_level = write_depth - 1;
|
||||
OSL_ASSERT(write_path[write_level] == end_pos());
|
||||
OSL_ASSERT(read_path[read_level] == end_pos());
|
||||
|
||||
int level = 0;
|
||||
OSL_ASSERT(read_path[read_level - level]
|
||||
== write_path[write_level - level]);
|
||||
do {
|
||||
++level;
|
||||
if (read_path[read_level - level]()
|
||||
!= write_path[write_level - level]())
|
||||
const int walkCount = std::min(read_depth, write_depth);
|
||||
const int read_top = read_depth - 1;
|
||||
const int write_top = write_depth - 1;
|
||||
OSL_DASSERT(write_top < writeCount);
|
||||
OSL_DASSERT(write_path[write_top] == end_pos());
|
||||
OSL_DASSERT(read_top < read_count);
|
||||
OSL_DASSERT(read_path[read_top] == end_pos());
|
||||
|
||||
int walkDepth = 0;
|
||||
// Verify top of read and write stacks match positions
|
||||
OSL_DASSERT((read_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((read_top - walkDepth) < read_count);
|
||||
OSL_DASSERT((write_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((write_top - walkDepth) < writeCount);
|
||||
OSL_DASSERT(read_path[read_top - walkDepth]
|
||||
== write_path[write_top - walkDepth]);
|
||||
// That position should technically be the root (no conditions in the dependency tree)
|
||||
OSL_DASSERT(read_path[read_top - walkDepth] == end_pos());
|
||||
// Because we know walkDepth 0 never differs, we can start iterating
|
||||
// at walkDepth 1
|
||||
|
||||
// Walk down the read and write paths until they differ
|
||||
for (walkDepth = 1; walkDepth < walkCount; ++walkDepth) {
|
||||
OSL_DASSERT((read_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((read_top - walkDepth) < read_count);
|
||||
OSL_DASSERT((write_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((write_top - walkDepth) < writeCount);
|
||||
if (read_path[read_top - walkDepth]()
|
||||
!= write_path[write_top - walkDepth]()) {
|
||||
break;
|
||||
} while (level < levelCount);
|
||||
--level;
|
||||
OSL_ASSERT(read_path[read_level - level]
|
||||
== write_path[write_level - level]);
|
||||
OSL_ASSERT(read_level - level >= 0);
|
||||
return read_path[read_level - level];
|
||||
}
|
||||
}
|
||||
// The previous walk depth's position was the common ancestor
|
||||
--walkDepth;
|
||||
OSL_DASSERT((read_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((read_top - walkDepth) < read_count);
|
||||
OSL_DASSERT((write_top - walkDepth) >= 0);
|
||||
OSL_DASSERT((write_top - walkDepth) < writeCount);
|
||||
OSL_DASSERT(read_path[read_top - walkDepth]
|
||||
== write_path[write_top - walkDepth]);
|
||||
return read_path[read_top - walkDepth];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Historically tracks stack of functions
|
||||
// The Position returned by top_pos changes and function scopes are pushed and popped.
|
||||
// However any given position is invariant as scopes change
|
||||
@@ -1053,8 +1091,10 @@ typedef std::vector<WriteEvent> WriteChronology;
|
||||
|
||||
class ReadEvent {
|
||||
DependencyTreeTracker::Position m_pos_in_tree;
|
||||
#ifdef OSL_DEV
|
||||
int m_op_num;
|
||||
int m_loop_op_index;
|
||||
#endif
|
||||
|
||||
public:
|
||||
ReadEvent(DependencyTreeTracker::Position pos_in_tree_
|
||||
@@ -1077,9 +1117,15 @@ public:
|
||||
}
|
||||
|
||||
#ifdef OSL_DEV
|
||||
OSL_FORCEINLINE int op_num() const { return m_op_num; }
|
||||
OSL_FORCEINLINE int op_num() const
|
||||
{
|
||||
return m_op_num;
|
||||
}
|
||||
|
||||
OSL_FORCEINLINE int loop_op_index() const { return m_loop_op_index; }
|
||||
OSL_FORCEINLINE int loop_op_index() const
|
||||
{
|
||||
return m_loop_op_index;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1595,7 +1641,7 @@ struct Analyzer {
|
||||
// Process arguments written to to handle early outs, cyclical reads,
|
||||
// and record a WriteEvent to a potentially unmasked operations remembering
|
||||
// the exact stack of conditional dependencies at that point.
|
||||
// When we processed reads (above), we ensured that any reads occuring at a higher that on the stoCheck for
|
||||
// When we processed reads (above), we ensured that any reads occurring at a higher that on the stoCheck for
|
||||
for (int write_index = 0; write_index < write_count;
|
||||
++write_index) {
|
||||
const Symbol* symbolWrittenTo
|
||||
@@ -1642,7 +1688,7 @@ struct Analyzer {
|
||||
}
|
||||
}
|
||||
|
||||
// Special case for op_getattribute which normaly would be
|
||||
// Special case for op_getattribute which normally would be
|
||||
// implicitly varying unless BatchedRendererServices says it
|
||||
// is uniform.
|
||||
if (opcode.opname() == Strings::op_getattribute) {
|
||||
@@ -2257,6 +2303,17 @@ struct Analyzer {
|
||||
}
|
||||
}
|
||||
|
||||
void make_closures_varying()
|
||||
{
|
||||
// We assume that closures are always stored as varying pointers
|
||||
FOREACH_PARAM(Symbol & s, inst())
|
||||
{
|
||||
if (s.typespec().is_closure()) {
|
||||
recursively_mark_varying(&s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_varying_of_upstream_connections()
|
||||
{
|
||||
OSL_DEV_ONLY(std::cout << "connections to layer begin" << std::endl);
|
||||
@@ -2349,6 +2406,7 @@ BatchedAnalysis::analyze_layer(ShaderInstance* inst)
|
||||
analyzer.push_varying_of_shader_globals();
|
||||
analyzer.make_interpolated_parameters_varying();
|
||||
analyzer.make_renderer_outputs_varying();
|
||||
analyzer.make_closures_varying();
|
||||
analyzer.push_varying_of_upstream_connections();
|
||||
analyzer.push_varying_of_implicitly_varying_ops();
|
||||
|
||||
|
||||
@@ -1846,7 +1846,7 @@ BatchedBackendLLVM::llvm_assign_impl(const Symbol& Result, const Symbol& Src,
|
||||
return true;
|
||||
}
|
||||
|
||||
// memcpy complicated by promotion of uniform to wide during assignment, dissallow
|
||||
// memcpy complicated by promotion of uniform to wide during assignment, disallow
|
||||
|
||||
// The following code handles f=f, f=i, v=v, v=f, v=i, m=m, s=s.
|
||||
// Remember that llvm_load_value will automatically convert scalar->triple.
|
||||
@@ -1904,7 +1904,7 @@ BatchedBackendLLVM::llvm_assign_impl(const Symbol& Result, const Symbol& Src,
|
||||
// The llvm_load_value above should have handled bool to int conversions
|
||||
// when the basetype == Typedesc::INT
|
||||
|
||||
// write source float into all compnents when dstcomp == -1, otherwise
|
||||
// write source float into all components when dstcomp == -1, otherwise
|
||||
// the single element requested.
|
||||
if (dstcomp == -1) {
|
||||
for (int i = 0; i < num_components; ++i)
|
||||
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
llvm::Value* llvm_load_mask(const Symbol& cond);
|
||||
|
||||
/// Return an llvm::Value* that is either a scalar and derivs is
|
||||
/// false, or a pointer to sym's values (if sym is an aggreate or
|
||||
/// false, or a pointer to sym's values (if sym is an aggregate or
|
||||
/// derivs == true). Furthermore, if deriv == true and sym doesn't
|
||||
/// have derivs, coerce it into a variable with zero derivs.
|
||||
llvm::Value* llvm_load_arg(const Symbol& sym, bool derivs,
|
||||
@@ -278,9 +278,9 @@ public:
|
||||
|
||||
public:
|
||||
TempScope(BatchedBackendLLVM& backend);
|
||||
TempScope(const TempScope& other) = delete;
|
||||
TempScope(const TempScope&& other) = delete;
|
||||
TempScope& operator=(const TempScope& other) = delete;
|
||||
TempScope(const TempScope& other) = delete;
|
||||
TempScope(const TempScope&& other) = delete;
|
||||
TempScope& operator=(const TempScope& other) = delete;
|
||||
TempScope& operator=(const TempScope&& other) = delete;
|
||||
~TempScope();
|
||||
};
|
||||
@@ -331,7 +331,7 @@ public:
|
||||
/// derivs are zero.
|
||||
llvm::Value* llvm_test_nonzero(const Symbol& val, bool test_derivs = false);
|
||||
|
||||
/// Implementaiton of Simple assignment. If arrayindex >= 0, in
|
||||
/// Implementation of Simple assignment. If arrayindex >= 0, in
|
||||
/// designates a particular array index to assign.
|
||||
bool llvm_assign_impl(const Symbol& Result, const Symbol& Src,
|
||||
int arrayindex = -1, int srccomp = -1,
|
||||
@@ -489,7 +489,7 @@ public:
|
||||
|
||||
// Encapsulate creation of function names that encode parameter types,
|
||||
// including if each is varying or uniform, and if a mask is required.
|
||||
// Utilize llvm::Twine to efficently combine multiple strings
|
||||
// Utilize llvm::Twine to efficiently combine multiple strings
|
||||
// Usage is to start with the function name then append arguments,
|
||||
// and at any point masking can be turned on/off as well as batching.
|
||||
// The effect of disabling batching would be the function name is
|
||||
@@ -533,7 +533,7 @@ public:
|
||||
ArgVector m_args;
|
||||
|
||||
public:
|
||||
FuncSpec(const FuncSpec&) = delete;
|
||||
FuncSpec(const FuncSpec&) = delete;
|
||||
FuncSpec& operator=(const FuncSpec&) = delete;
|
||||
|
||||
FuncSpec(const llvm::Twine& name)
|
||||
|
||||
@@ -557,7 +557,7 @@ LLVMGEN(llvm_gen_arraylength)
|
||||
int len = A.typespec().is_unsized_array() ? A.initializers()
|
||||
: A.typespec().arraylength();
|
||||
|
||||
// Even thought the array's size should be uniform accross all lanes,
|
||||
// Even thought the array's size should be uniform across all lanes,
|
||||
// the symbol its being stored in maybe varying
|
||||
llvm::Value* const_length = Result.is_uniform() ? rop.ll.constant(len)
|
||||
: rop.ll.wide_constant(len);
|
||||
@@ -605,7 +605,7 @@ LLVMGEN(llvm_gen_aref)
|
||||
} else {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -687,7 +687,7 @@ LLVMGEN(llvm_gen_aassign)
|
||||
}
|
||||
} else {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -1110,10 +1110,10 @@ LLVMGEN(llvm_gen_if)
|
||||
// contain a call to a lower level, those must not be executed
|
||||
// if the mask is all off
|
||||
//#define SKIP_TESTING_IF_ANY_LANES_ACTIVE_TO_AVOID_BRANCH 1
|
||||
// NOTE: if SKIP_TESTING_IF_ANY_LANES_ACTIVE_TO_AVOID_BRANCH is defineed then
|
||||
// NOTE: if SKIP_TESTING_IF_ANY_LANES_ACTIVE_TO_AVOID_BRANCH is defined then
|
||||
// library and layer functions may get called with an entirely empty mask
|
||||
#ifndef SKIP_TESTING_IF_ANY_LANES_ACTIVE_TO_AVOID_BRANCH
|
||||
// We use the combined mask stack + the if condition's mask we aready pushed
|
||||
// We use the combined mask stack + the if condition's mask we already pushed
|
||||
llvm::Value* anyThenLanesActive = rop.ll.test_if_mask_is_non_zero(
|
||||
rop.ll.current_mask());
|
||||
#endif
|
||||
@@ -1263,6 +1263,7 @@ LLVMGEN(llvm_gen_add)
|
||||
OSL_ASSERT(!A.typespec().is_array() && !B.typespec().is_array());
|
||||
if (Result.typespec().is_closure()) {
|
||||
OSL_ASSERT(A.typespec().is_closure() && B.typespec().is_closure());
|
||||
OSL_ASSERT(!A.is_uniform() && !B.is_uniform() && !result_is_uniform);
|
||||
llvm::Value* valargs[] = { rop.sg_void_ptr(), rop.llvm_void_ptr(Result),
|
||||
rop.llvm_void_ptr(A), rop.llvm_void_ptr(B),
|
||||
rop.ll.mask_as_int(rop.ll.current_mask()) };
|
||||
@@ -1676,6 +1677,7 @@ LLVMGEN(llvm_gen_modulus)
|
||||
|
||||
int num_components = type.aggregate;
|
||||
|
||||
#if 0
|
||||
if (is_float && !op_is_uniform) {
|
||||
// llvm 5.0.1 did not do a good job with op_mod when its
|
||||
// parameters were <16xf32>. So we will go ahead
|
||||
@@ -1702,7 +1704,9 @@ LLVMGEN(llvm_gen_modulus)
|
||||
}
|
||||
|
||||
rop.ll.call_function(rop.build_name(func_spec), call_args);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (int i = 0; i < num_components; i++) {
|
||||
llvm::Value* a = rop.loadLLVMValue(A, i, 0, type, op_is_uniform);
|
||||
llvm::Value* b = rop.loadLLVMValue(B, i, 0, type, op_is_uniform);
|
||||
@@ -2302,7 +2306,7 @@ LLVMGEN(llvm_gen_compref)
|
||||
if (rop.inst()->master()->range_checking()) {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -2418,7 +2422,7 @@ LLVMGEN(llvm_gen_compassign)
|
||||
if (rop.inst()->master()->range_checking()) {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -2534,7 +2538,7 @@ LLVMGEN(llvm_gen_mxcompref)
|
||||
}
|
||||
} else {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -2636,7 +2640,7 @@ LLVMGEN(llvm_gen_mxcompassign)
|
||||
}
|
||||
} else {
|
||||
BatchedBackendLLVM::TempScope temp_scope(rop);
|
||||
// We need a copy of the indices incase the range check clamps them
|
||||
// We need a copy of the indices in case the range check clamps them
|
||||
llvm::Value* loc_clamped_wide_index = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::INT), false /*derivs*/, false /*is_uniform*/,
|
||||
false /*forceBool*/,
|
||||
@@ -2955,7 +2959,7 @@ LLVMGEN(llvm_gen_compare_op)
|
||||
if ((typeOfA == rop.ll.type_bool() && typeOfB == rop.ll.type_int())
|
||||
|| (typeOfA == rop.ll.type_wide_bool()
|
||||
&& typeOfB == rop.ll.type_wide_int())) {
|
||||
// TODO: could optimize for contant 0 and 1 and skip the comparison
|
||||
// TODO: could optimize for constant 0 and 1 and skip the comparison
|
||||
a = rop.ll.op_bool_to_int(a);
|
||||
}
|
||||
if ((typeOfB == rop.ll.type_bool() && typeOfA == rop.ll.type_int())
|
||||
@@ -3547,7 +3551,7 @@ LLVMGEN(llvm_gen_transform)
|
||||
|
||||
FuncSpec func_spec("build_transform_matrix");
|
||||
func_spec.arg_varying(TypeDesc::TypeMatrix44);
|
||||
// Ignore derivatives if uneeded or unsupplied
|
||||
// Ignore derivatives if unneeded or unsupplied
|
||||
func_spec.arg(*From, from_is_uniform);
|
||||
func_spec.arg(*To, to_is_uniform);
|
||||
func_spec.mask();
|
||||
@@ -3570,7 +3574,7 @@ LLVMGEN(llvm_gen_transform)
|
||||
FuncSpec func_spec(op.opname().c_str());
|
||||
func_spec.unbatch();
|
||||
//std::string func_name = std::string("osl_") + op.opname().c_str() + "_";
|
||||
// Ignore derivatives if uneeded or unsupplied
|
||||
// Ignore derivatives if unneeded or unsupplied
|
||||
bool has_derivs = (Result->has_derivs() && P->has_derivs());
|
||||
func_spec.arg(*P, has_derivs, P_is_uniform);
|
||||
// The matrix is always varying if we looked it up,
|
||||
@@ -5750,7 +5754,7 @@ llvm_batched_noise_options(BatchedBackendLLVM& rop, int opnum,
|
||||
rop.ll.call_function("osl_noiseparams_set_do_filter", opt,
|
||||
rop.llvm_load_value(Val));
|
||||
} else if (name == Strings::direction && Val.typespec().is_triple()) {
|
||||
// We are not going to bin by varing direction
|
||||
// We are not going to bin by varying direction
|
||||
// instead we will pass a pointer to its wide value
|
||||
// as an extra parameter.
|
||||
// If it is null, then the uniform value from noise options
|
||||
@@ -7064,7 +7068,8 @@ LLVMGEN(llvm_gen_spline)
|
||||
static void
|
||||
llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
|
||||
const ClosureRegistry::ClosureEntry* clentry,
|
||||
ustring clname, llvm::Value* mem_void_ptr, int argsoffset)
|
||||
ustring clname, llvm::Value* mem_void_ptr, int argsoffset,
|
||||
int lane_index)
|
||||
{
|
||||
OSL_DASSERT(((op.nargs() - argsoffset) % 2) == 0);
|
||||
|
||||
@@ -7088,10 +7093,45 @@ llvm_gen_keyword_fill(BatchedBackendLLVM& rop, Opcode& op,
|
||||
if (equivalent(p.type, ValueType) && !strcmp(key->c_str(), p.key)) {
|
||||
// store data
|
||||
OSL_DASSERT(p.offset + p.field_size <= clentry->struct_size);
|
||||
llvm::Value* dst = rop.ll.offset_ptr(mem_void_ptr, p.offset);
|
||||
llvm::Value* src = rop.llvm_void_ptr(Value);
|
||||
rop.ll.op_memcpy(dst, src, (int)p.type.size(),
|
||||
4 /* use 4 byte alignment for now */);
|
||||
|
||||
bool arg_is_uniform = Value.is_uniform();
|
||||
|
||||
TypeDesc simpletype(Value.typespec().simpletype());
|
||||
|
||||
// We don't currently offer a helper macro in genclosure.h for creating
|
||||
// keyword array parameters, so perhaps we can assume we don't need to
|
||||
// support them
|
||||
OSL_DASSERT(simpletype.arraylen == 0);
|
||||
|
||||
int num_components = simpletype.aggregate;
|
||||
|
||||
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr,
|
||||
p.offset);
|
||||
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
|
||||
|
||||
for (int c = 0; c < num_components; c++) {
|
||||
llvm::Value* dest_elem;
|
||||
if (num_components > 1)
|
||||
dest_elem = rop.ll.GEP(dest_base, 0, c);
|
||||
else
|
||||
dest_elem = dest_base;
|
||||
|
||||
// NOTE: We don't want any uniform arguments to be
|
||||
// widened, so our typical op_is_uniform doesn't do what we
|
||||
// want for this when loading. So just pass arg_is_uniform
|
||||
// which will avoid widening any uniform arguments.
|
||||
llvm::Value* loaded
|
||||
= rop.llvm_load_value(Value, 0, NULL, c,
|
||||
TypeDesc::UNKNOWN,
|
||||
/*op_is_uniform*/ arg_is_uniform,
|
||||
/*index_is_uniform*/ true);
|
||||
|
||||
if (!arg_is_uniform) {
|
||||
loaded = rop.ll.op_extract(loaded, lane_index);
|
||||
}
|
||||
rop.ll.op_unmasked_store(loaded, dest_elem);
|
||||
}
|
||||
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
@@ -7180,8 +7220,9 @@ 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 compiliation
|
||||
// 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
|
||||
for (int lane_index = 0; lane_index < rop.vector_width(); ++lane_index) {
|
||||
llvm::Value* comp_ptr = rop.ll.op_extract(comp_wide_ptr, lane_index);
|
||||
@@ -7193,14 +7234,16 @@ LLVMGEN(llvm_gen_closure)
|
||||
// For the weighted closures, we need a surrounding "if" so that it's safe
|
||||
// for osl_allocate_weighted_closure_component to return NULL (unless we
|
||||
// know for sure that it's constant weighted and that the weight is
|
||||
// not zero).
|
||||
// not zero). We also need the surrounding "if" to reject writing
|
||||
// to closures that aren't masked.
|
||||
llvm::BasicBlock* next_block = NULL;
|
||||
llvm::BasicBlock* notnull_block = rop.ll.new_basic_block(
|
||||
"non_null_closure");
|
||||
next_block = rop.ll.new_basic_block("");
|
||||
llvm::Value* cond
|
||||
= rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
|
||||
rop.ll.void_ptr_null());
|
||||
"non_null_and_masked_closure");
|
||||
next_block = rop.ll.new_basic_block("");
|
||||
llvm::Value* cond = rop.ll.op_and(
|
||||
rop.ll.op_ne(rop.ll.ptr_cast(comp_ptr, rop.ll.type_void_ptr()),
|
||||
rop.ll.void_ptr_null()),
|
||||
rop.ll.test_mask_lane(mask, lane_index));
|
||||
rop.ll.op_branch(cond, notnull_block, next_block);
|
||||
|
||||
// If the closure has a "prepare" method, call
|
||||
@@ -7233,7 +7276,30 @@ LLVMGEN(llvm_gen_closure)
|
||||
int num_components = simpletype.aggregate;
|
||||
|
||||
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr, p.offset);
|
||||
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
|
||||
llvm::Type* dest_type = rop.ll.llvm_type(
|
||||
static_cast<const TypeSpec&>(p.type).simpletype());
|
||||
dest_base = rop.ll.ptr_to_cast(dest_base, dest_type);
|
||||
|
||||
if (num_elements > 1) {
|
||||
OSL_DASSERT(rop.ll.is_type_array(dest_type));
|
||||
|
||||
// The type is an array type,
|
||||
// which means our pointer is to an array type,
|
||||
// not to &[0] (the address of the 1st element).
|
||||
// IE: typedef int Int5Array[5];
|
||||
// Int5Array *dest_base;
|
||||
// in contrast to what most of use might consider an array pointer
|
||||
// int *dest_base;
|
||||
// So if we dereference Int5Array* to with [4], the 5th element,
|
||||
// we would be really be pointing to ((int *)dest_base)[5*4] which is
|
||||
// out of bounds of our 1 instance of Int5Array.
|
||||
// Thus when dealing with arrays we will just dereference it and get the address to get
|
||||
// the address of the 1st element.
|
||||
|
||||
dest_base = rop.ll.GEP(dest_type, dest_base, 0, 0);
|
||||
llvm::Type* element_type = rop.ll.element_type_of(dest_type);
|
||||
dest_type = element_type;
|
||||
}
|
||||
|
||||
for (int a = 0; a < num_elements; ++a) {
|
||||
llvm::Value* arrind = simpletype.arraylen ? rop.ll.constant(a)
|
||||
@@ -7241,7 +7307,9 @@ LLVMGEN(llvm_gen_closure)
|
||||
for (int c = 0; c < num_components; c++) {
|
||||
llvm::Value* dest_elem;
|
||||
if (num_components > 1)
|
||||
dest_elem = rop.ll.GEP(dest_base, a, c);
|
||||
dest_elem = rop.ll.GEP(dest_type, dest_base, a, c);
|
||||
else if (num_elements > 1)
|
||||
dest_elem = rop.ll.GEP(dest_type, dest_base, a);
|
||||
else
|
||||
dest_elem = dest_base;
|
||||
|
||||
@@ -7275,7 +7343,7 @@ LLVMGEN(llvm_gen_closure)
|
||||
}
|
||||
|
||||
llvm_gen_keyword_fill(rop, op, clentry, closure_name, mem_void_ptr,
|
||||
2 + weighted + clentry->nformal);
|
||||
2 + weighted + clentry->nformal, lane_index);
|
||||
|
||||
if (next_block)
|
||||
rop.ll.op_branch(next_block);
|
||||
@@ -8191,7 +8259,7 @@ LLVMGEN(llvm_gen_split)
|
||||
llvm::Value* wide_sep = rop.ll.wide_constant("");
|
||||
llvm::Value* temp_wide_sep = rop.getOrAllocateTemp(
|
||||
TypeSpec(TypeDesc::STRING), false /*derivs*/,
|
||||
false /*op_is_uniform*/, false /*forceBool*/, "wide seperator");
|
||||
false /*op_is_uniform*/, false /*forceBool*/, "wide separator");
|
||||
rop.ll.op_unmasked_store(wide_sep, temp_wide_sep);
|
||||
args.push_back(rop.ll.void_ptr(temp_wide_sep));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "batched_backendllvm.h"
|
||||
#include "oslexec_pvt.h"
|
||||
|
||||
// Create extrenal declarations for all built-in funcs we may call from LLVM
|
||||
// Create external declarations for all built-in funcs we may call from LLVM
|
||||
#define DECL(name, signature) extern "C" void name();
|
||||
#include "builtindecl.h"
|
||||
#undef DECL
|
||||
@@ -894,7 +894,7 @@ BatchedBackendLLVM::llvm_type_groupdata()
|
||||
fields.push_back(llvm_wide_type(ts));
|
||||
|
||||
// Alignment
|
||||
// TODO: this isn't quite right, cant rely on batch size to == ISA SIMD requirements
|
||||
// TODO: this isn't quite right, can't rely on batch size to == ISA SIMD requirements
|
||||
size_t base_size = sym.typespec().is_closure_based()
|
||||
? sizeof(void*)
|
||||
: sym.typespec().simpletype().basesize();
|
||||
@@ -1126,7 +1126,7 @@ BatchedBackendLLVM::llvm_assign_initial_value(
|
||||
// For ISA without a native mask (AVX & AVX2), this gather op will
|
||||
// clamp the indices of masked off lanes to 0.
|
||||
// This means the user data base pointer + sym_offset
|
||||
// must be dereferencable with a shadeindex of 0.
|
||||
// must be dereferenceable with a shadeindex of 0.
|
||||
llvm::Value* wide_val
|
||||
= ll.op_gather(userdata_sym_base_ptr, wide_index);
|
||||
|
||||
@@ -1815,6 +1815,7 @@ BatchedBackendLLVM::build_llvm_init()
|
||||
FOREACH_PARAM(Symbol & sym, gi)
|
||||
{
|
||||
if (sym.typespec().is_closure_based()) {
|
||||
OSL_ASSERT(sym.is_varying());
|
||||
int arraylen = std::max(1, sym.typespec().arraylength());
|
||||
llvm::Value* val = ll.constant_ptr(NULL, ll.type_void_ptr());
|
||||
if (!sym.is_uniform())
|
||||
|
||||
+282
-278
@@ -11,119 +11,118 @@
|
||||
|
||||
|
||||
#ifndef DECL
|
||||
#error Do not include this file unless DECL is defined
|
||||
# error Do not include this file unless DECL is defined
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define NOISE_IMPL(name) \
|
||||
DECL (osl_ ## name ## _ff, "ff") \
|
||||
DECL (osl_ ## name ## _fff, "fff") \
|
||||
DECL (osl_ ## name ## _fv, "fv") \
|
||||
DECL (osl_ ## name ## _fvf, "fvf") \
|
||||
DECL (osl_ ## name ## _vf, "xvf") \
|
||||
DECL (osl_ ## name ## _vff, "xvff") \
|
||||
DECL (osl_ ## name ## _vv, "xvv") \
|
||||
DECL (osl_ ## name ## _vvf, "xvvf")
|
||||
#define NOISE_IMPL(name) \
|
||||
DECL(osl_##name##_ff, "ff") \
|
||||
DECL(osl_##name##_fff, "fff") \
|
||||
DECL(osl_##name##_fv, "fv") \
|
||||
DECL(osl_##name##_fvf, "fvf") \
|
||||
DECL(osl_##name##_vf, "xvf") \
|
||||
DECL(osl_##name##_vff, "xvff") \
|
||||
DECL(osl_##name##_vv, "xvv") \
|
||||
DECL(osl_##name##_vvf, "xvvf")
|
||||
|
||||
#define NOISE_DERIV_IMPL(name) \
|
||||
DECL (osl_ ## name ## _dfdf, "xXX") \
|
||||
DECL (osl_ ## name ## _dfdff, "xXXf") \
|
||||
DECL (osl_ ## name ## _dffdf, "xXfX") \
|
||||
DECL (osl_ ## name ## _dfdfdf, "xXXX") \
|
||||
DECL (osl_ ## name ## _dfdv, "xXv") \
|
||||
DECL (osl_ ## name ## _dfdvf, "xXvf") \
|
||||
DECL (osl_ ## name ## _dfvdf, "xXvX") \
|
||||
DECL (osl_ ## name ## _dfdvdf, "xXvX") \
|
||||
DECL (osl_ ## name ## _dvdf, "xvX") \
|
||||
DECL (osl_ ## name ## _dvdff, "xvXf") \
|
||||
DECL (osl_ ## name ## _dvfdf, "xvfX") \
|
||||
DECL (osl_ ## name ## _dvdfdf, "xvXX") \
|
||||
DECL (osl_ ## name ## _dvdv, "xvv") \
|
||||
DECL (osl_ ## name ## _dvdvf, "xvvf") \
|
||||
DECL (osl_ ## name ## _dvvdf, "xvvX") \
|
||||
DECL (osl_ ## name ## _dvdvdf, "xvvX")
|
||||
#define NOISE_DERIV_IMPL(name) \
|
||||
DECL(osl_##name##_dfdf, "xXX") \
|
||||
DECL(osl_##name##_dfdff, "xXXf") \
|
||||
DECL(osl_##name##_dffdf, "xXfX") \
|
||||
DECL(osl_##name##_dfdfdf, "xXXX") \
|
||||
DECL(osl_##name##_dfdv, "xXv") \
|
||||
DECL(osl_##name##_dfdvf, "xXvf") \
|
||||
DECL(osl_##name##_dfvdf, "xXvX") \
|
||||
DECL(osl_##name##_dfdvdf, "xXvX") \
|
||||
DECL(osl_##name##_dvdf, "xvX") \
|
||||
DECL(osl_##name##_dvdff, "xvXf") \
|
||||
DECL(osl_##name##_dvfdf, "xvfX") \
|
||||
DECL(osl_##name##_dvdfdf, "xvXX") \
|
||||
DECL(osl_##name##_dvdv, "xvv") \
|
||||
DECL(osl_##name##_dvdvf, "xvvf") \
|
||||
DECL(osl_##name##_dvvdf, "xvvX") \
|
||||
DECL(osl_##name##_dvdvdf, "xvvX")
|
||||
|
||||
#define GENERIC_NOISE_DERIV_IMPL(name) \
|
||||
DECL (osl_ ## name ## _dfdf, "xsXXXX") \
|
||||
DECL (osl_ ## name ## _dfdfdf, "xsXXXXX") \
|
||||
DECL (osl_ ## name ## _dfdv, "xsXXXX") \
|
||||
DECL (osl_ ## name ## _dfdvdf, "xsXXXXX") \
|
||||
DECL (osl_ ## name ## _dvdf, "xsXXXX") \
|
||||
DECL (osl_ ## name ## _dvdfdf, "xsXXXXX") \
|
||||
DECL (osl_ ## name ## _dvdv, "xsXXXX") \
|
||||
DECL (osl_ ## name ## _dvdvdf, "xsXXXXX")
|
||||
#define GENERIC_NOISE_DERIV_IMPL(name) \
|
||||
DECL(osl_##name##_dfdf, "xsXXXX") \
|
||||
DECL(osl_##name##_dfdfdf, "xsXXXXX") \
|
||||
DECL(osl_##name##_dfdv, "xsXXXX") \
|
||||
DECL(osl_##name##_dfdvdf, "xsXXXXX") \
|
||||
DECL(osl_##name##_dvdf, "xsXXXX") \
|
||||
DECL(osl_##name##_dvdfdf, "xsXXXXX") \
|
||||
DECL(osl_##name##_dvdv, "xsXXXX") \
|
||||
DECL(osl_##name##_dvdvdf, "xsXXXXX")
|
||||
|
||||
#define PNOISE_IMPL(name) \
|
||||
DECL (osl_ ## name ## _fff, "fff") \
|
||||
DECL (osl_ ## name ## _fffff, "fffff") \
|
||||
DECL (osl_ ## name ## _fvv, "fvv") \
|
||||
DECL (osl_ ## name ## _fvfvf, "fvfvf") \
|
||||
DECL (osl_ ## name ## _vff, "xvff") \
|
||||
DECL (osl_ ## name ## _vffff, "xvffff") \
|
||||
DECL (osl_ ## name ## _vvv, "xvvv") \
|
||||
DECL (osl_ ## name ## _vvfvf, "xvvfvf")
|
||||
#define PNOISE_IMPL(name) \
|
||||
DECL(osl_##name##_fff, "fff") \
|
||||
DECL(osl_##name##_fffff, "fffff") \
|
||||
DECL(osl_##name##_fvv, "fvv") \
|
||||
DECL(osl_##name##_fvfvf, "fvfvf") \
|
||||
DECL(osl_##name##_vff, "xvff") \
|
||||
DECL(osl_##name##_vffff, "xvffff") \
|
||||
DECL(osl_##name##_vvv, "xvvv") \
|
||||
DECL(osl_##name##_vvfvf, "xvvfvf")
|
||||
|
||||
#define PNOISE_DERIV_IMPL(name) \
|
||||
DECL (osl_ ## name ## _dfdff, "xXXf") \
|
||||
DECL (osl_ ## name ## _dfdffff, "xXXfff") \
|
||||
DECL (osl_ ## name ## _dffdfff, "xXfXff") \
|
||||
DECL (osl_ ## name ## _dfdfdfff, "xXXXff") \
|
||||
DECL (osl_ ## name ## _dfdvv, "xXXv") \
|
||||
DECL (osl_ ## name ## _dfdvfvf, "xXvfvf") \
|
||||
DECL (osl_ ## name ## _dfvdfvf, "xXvXvf") \
|
||||
DECL (osl_ ## name ## _dfdvdfvf, "xXvXvf") \
|
||||
DECL (osl_ ## name ## _dvdff, "xvXf") \
|
||||
DECL (osl_ ## name ## _dvdffff, "xvXfff") \
|
||||
DECL (osl_ ## name ## _dvfdfff, "xvfXff") \
|
||||
DECL (osl_ ## name ## _dvdfdfff, "xvXXff") \
|
||||
DECL (osl_ ## name ## _dvdvv, "xvvv") \
|
||||
DECL (osl_ ## name ## _dvdvfvf, "xvvfvf") \
|
||||
DECL (osl_ ## name ## _dvvdfvf, "xvvXvf") \
|
||||
DECL (osl_ ## name ## _dvdvdfvf, "xvvXvf")
|
||||
#define PNOISE_DERIV_IMPL(name) \
|
||||
DECL(osl_##name##_dfdff, "xXXf") \
|
||||
DECL(osl_##name##_dfdffff, "xXXfff") \
|
||||
DECL(osl_##name##_dffdfff, "xXfXff") \
|
||||
DECL(osl_##name##_dfdfdfff, "xXXXff") \
|
||||
DECL(osl_##name##_dfdvv, "xXXv") \
|
||||
DECL(osl_##name##_dfdvfvf, "xXvfvf") \
|
||||
DECL(osl_##name##_dfvdfvf, "xXvXvf") \
|
||||
DECL(osl_##name##_dfdvdfvf, "xXvXvf") \
|
||||
DECL(osl_##name##_dvdff, "xvXf") \
|
||||
DECL(osl_##name##_dvdffff, "xvXfff") \
|
||||
DECL(osl_##name##_dvfdfff, "xvfXff") \
|
||||
DECL(osl_##name##_dvdfdfff, "xvXXff") \
|
||||
DECL(osl_##name##_dvdvv, "xvvv") \
|
||||
DECL(osl_##name##_dvdvfvf, "xvvfvf") \
|
||||
DECL(osl_##name##_dvvdfvf, "xvvXvf") \
|
||||
DECL(osl_##name##_dvdvdfvf, "xvvXvf")
|
||||
|
||||
#define GENERIC_PNOISE_DERIV_IMPL(name) \
|
||||
DECL (osl_ ## name ## _dfdff, "xsXXfXX") \
|
||||
DECL (osl_ ## name ## _dfdfdfff, "xsXXXffXX") \
|
||||
DECL (osl_ ## name ## _dfdvv, "xsXXvXX") \
|
||||
DECL (osl_ ## name ## _dfdvdfvf, "xsXvXvfXX") \
|
||||
DECL (osl_ ## name ## _dvdff, "xsvXfXX") \
|
||||
DECL (osl_ ## name ## _dvdfdfff, "xsvXXffXX") \
|
||||
DECL (osl_ ## name ## _dvdvv, "xsvvvXX") \
|
||||
DECL (osl_ ## name ## _dvdvdfvf, "xsvvXvfXX")
|
||||
#define GENERIC_PNOISE_DERIV_IMPL(name) \
|
||||
DECL(osl_##name##_dfdff, "xsXXfXX") \
|
||||
DECL(osl_##name##_dfdfdfff, "xsXXXffXX") \
|
||||
DECL(osl_##name##_dfdvv, "xsXXvXX") \
|
||||
DECL(osl_##name##_dfdvdfvf, "xsXvXvfXX") \
|
||||
DECL(osl_##name##_dvdff, "xsvXfXX") \
|
||||
DECL(osl_##name##_dvdfdfff, "xsvXXffXX") \
|
||||
DECL(osl_##name##_dvdvv, "xsvvvXX") \
|
||||
DECL(osl_##name##_dvdvdfvf, "xsvvXvfXX")
|
||||
|
||||
#define UNARY_OP_IMPL(name) \
|
||||
DECL (osl_ ## name ## _ff, "ff") \
|
||||
DECL (osl_ ## name ## _dfdf, "xXX") \
|
||||
DECL (osl_ ## name ## _vv, "xXX") \
|
||||
DECL (osl_ ## name ## _dvdv, "xXX")
|
||||
#define UNARY_OP_IMPL(name) \
|
||||
DECL(osl_##name##_ff, "ff") \
|
||||
DECL(osl_##name##_dfdf, "xXX") \
|
||||
DECL(osl_##name##_vv, "xXX") \
|
||||
DECL(osl_##name##_dvdv, "xXX")
|
||||
|
||||
#define BINARY_OP_IMPL(name) \
|
||||
DECL (osl_ ## name ## _fff, "fff") \
|
||||
DECL (osl_ ## name ## _dfdfdf, "xXXX") \
|
||||
DECL (osl_ ## name ## _dffdf, "xXfX") \
|
||||
DECL (osl_ ## name ## _dfdff, "xXXf") \
|
||||
DECL (osl_ ## name ## _vvv, "xXXX") \
|
||||
DECL (osl_ ## name ## _dvdvdv, "xXXX") \
|
||||
DECL (osl_ ## name ## _dvvdv, "xXXX") \
|
||||
DECL (osl_ ## name ## _dvdvv, "xXXX")
|
||||
#define BINARY_OP_IMPL(name) \
|
||||
DECL(osl_##name##_fff, "fff") \
|
||||
DECL(osl_##name##_dfdfdf, "xXXX") \
|
||||
DECL(osl_##name##_dffdf, "xXfX") \
|
||||
DECL(osl_##name##_dfdff, "xXXf") \
|
||||
DECL(osl_##name##_vvv, "xXXX") \
|
||||
DECL(osl_##name##_dvdvdv, "xXXX") \
|
||||
DECL(osl_##name##_dvvdv, "xXXX") \
|
||||
DECL(osl_##name##_dvdvv, "xXXX")
|
||||
|
||||
|
||||
|
||||
|
||||
DECL (osl_add_closure_closure, "CXCC")
|
||||
DECL (osl_mul_closure_float, "CXCf")
|
||||
DECL (osl_mul_closure_color, "CXCc")
|
||||
DECL (osl_allocate_closure_component, "CXii")
|
||||
DECL (osl_allocate_weighted_closure_component, "CXiiX")
|
||||
DECL (osl_closure_to_string, "sXC")
|
||||
DECL (osl_format, "ss*")
|
||||
DECL (osl_printf, "xXs*")
|
||||
DECL (osl_fprintf, "xXss*")
|
||||
DECL (osl_error, "xXs*")
|
||||
DECL (osl_warning, "xXs*")
|
||||
DECL (osl_split, "isXsii")
|
||||
DECL (osl_incr_layers_executed, "xX")
|
||||
DECL(osl_add_closure_closure, "CXCC")
|
||||
DECL(osl_mul_closure_float, "CXCf")
|
||||
DECL(osl_mul_closure_color, "CXCc")
|
||||
DECL(osl_allocate_closure_component, "CXii")
|
||||
DECL(osl_allocate_weighted_closure_component, "CXiiX")
|
||||
DECL(osl_closure_to_string, "sXC")
|
||||
DECL(osl_format, "ss*")
|
||||
DECL(osl_printf, "xXs*")
|
||||
DECL(osl_fprintf, "xXss*")
|
||||
DECL(osl_error, "xXs*")
|
||||
DECL(osl_warning, "xXs*")
|
||||
DECL(osl_split, "isXsii")
|
||||
DECL(osl_incr_layers_executed, "xX")
|
||||
|
||||
NOISE_IMPL(cellnoise)
|
||||
//NOISE_DERIV_IMPL(cellnoise)
|
||||
@@ -151,70 +150,70 @@ PNOISE_IMPL(psnoise)
|
||||
PNOISE_DERIV_IMPL(psnoise)
|
||||
GENERIC_PNOISE_DERIV_IMPL(gaborpnoise)
|
||||
GENERIC_PNOISE_DERIV_IMPL(genericpnoise)
|
||||
DECL (osl_noiseparams_set_anisotropic, "xXi")
|
||||
DECL (osl_noiseparams_set_do_filter, "xXi")
|
||||
DECL (osl_noiseparams_set_direction, "xXv")
|
||||
DECL (osl_noiseparams_set_bandwidth, "xXf")
|
||||
DECL (osl_noiseparams_set_impulses, "xXf")
|
||||
DECL (osl_count_noise, "xX")
|
||||
DECL (osl_hash_ii, "ii")
|
||||
DECL (osl_hash_if, "if")
|
||||
DECL (osl_hash_iff, "iff")
|
||||
DECL (osl_hash_iv, "iX")
|
||||
DECL (osl_hash_ivf, "iXf")
|
||||
DECL(osl_noiseparams_set_anisotropic, "xXi")
|
||||
DECL(osl_noiseparams_set_do_filter, "xXi")
|
||||
DECL(osl_noiseparams_set_direction, "xXv")
|
||||
DECL(osl_noiseparams_set_bandwidth, "xXf")
|
||||
DECL(osl_noiseparams_set_impulses, "xXf")
|
||||
DECL(osl_count_noise, "xX")
|
||||
DECL(osl_hash_ii, "ii")
|
||||
DECL(osl_hash_if, "if")
|
||||
DECL(osl_hash_iff, "iff")
|
||||
DECL(osl_hash_iv, "iX")
|
||||
DECL(osl_hash_ivf, "iXf")
|
||||
|
||||
DECL (osl_spline_fff, "xXXXXii")
|
||||
DECL (osl_spline_dfdfdf, "xXXXXii")
|
||||
DECL (osl_spline_dfdff, "xXXXXii")
|
||||
DECL (osl_spline_dffdf, "xXXXXii")
|
||||
DECL (osl_spline_vfv, "xXXXXii")
|
||||
DECL (osl_spline_dvdfdv, "xXXXXii")
|
||||
DECL (osl_spline_dvdfv, "xXXXXii")
|
||||
DECL (osl_spline_dvfdv, "xXXXXii")
|
||||
DECL (osl_splineinverse_fff, "xXXXXii")
|
||||
DECL (osl_splineinverse_dfdfdf, "xXXXXii")
|
||||
DECL (osl_splineinverse_dfdff, "xXXXXii")
|
||||
DECL (osl_splineinverse_dffdf, "xXXXXii")
|
||||
DECL (osl_setmessage, "xXsLXisi")
|
||||
DECL (osl_getmessage, "iXssLXiisi")
|
||||
DECL (osl_pointcloud_search, "iXsXfiiXXii*")
|
||||
DECL (osl_pointcloud_get, "iXsXisLX")
|
||||
DECL (osl_pointcloud_write, "iXsXiXXX")
|
||||
DECL (osl_pointcloud_write_helper, "xXXXisLX")
|
||||
DECL (osl_blackbody_vf, "xXXf")
|
||||
DECL (osl_wavelength_color_vf, "xXXf")
|
||||
DECL (osl_luminance_fv, "xXXX")
|
||||
DECL (osl_luminance_dfdv, "xXXX")
|
||||
DECL (osl_prepend_color_from, "xXXs")
|
||||
DECL (osl_prepend_matrix_from, "iXXs")
|
||||
DECL (osl_get_matrix, "iXXs")
|
||||
DECL (osl_get_inverse_matrix, "iXXs")
|
||||
DECL (osl_transform_triple, "iXXiXiXXi")
|
||||
DECL (osl_transform_triple_nonlinear, "iXXiXiXXi")
|
||||
DECL (osl_transform_vmv, "xXXX")
|
||||
DECL (osl_transform_dvmdv, "xXXX")
|
||||
DECL (osl_transformv_vmv, "xXXX")
|
||||
DECL (osl_transformv_dvmdv, "xXXX")
|
||||
DECL (osl_transformn_vmv, "xXXX")
|
||||
DECL (osl_transformn_dvmdv, "xXXX")
|
||||
DECL (osl_transformc, "iXXiXiXX")
|
||||
DECL(osl_spline_fff, "xXXXXii")
|
||||
DECL(osl_spline_dfdfdf, "xXXXXii")
|
||||
DECL(osl_spline_dfdff, "xXXXXii")
|
||||
DECL(osl_spline_dffdf, "xXXXXii")
|
||||
DECL(osl_spline_vfv, "xXXXXii")
|
||||
DECL(osl_spline_dvdfdv, "xXXXXii")
|
||||
DECL(osl_spline_dvdfv, "xXXXXii")
|
||||
DECL(osl_spline_dvfdv, "xXXXXii")
|
||||
DECL(osl_splineinverse_fff, "xXXXXii")
|
||||
DECL(osl_splineinverse_dfdfdf, "xXXXXii")
|
||||
DECL(osl_splineinverse_dfdff, "xXXXXii")
|
||||
DECL(osl_splineinverse_dffdf, "xXXXXii")
|
||||
DECL(osl_setmessage, "xXsLXisi")
|
||||
DECL(osl_getmessage, "iXssLXiisi")
|
||||
DECL(osl_pointcloud_search, "iXsXfiiXXii*")
|
||||
DECL(osl_pointcloud_get, "iXsXisLX")
|
||||
DECL(osl_pointcloud_write, "iXsXiXXX")
|
||||
DECL(osl_pointcloud_write_helper, "xXXXisLX")
|
||||
DECL(osl_blackbody_vf, "xXXf")
|
||||
DECL(osl_wavelength_color_vf, "xXXf")
|
||||
DECL(osl_luminance_fv, "xXXX")
|
||||
DECL(osl_luminance_dfdv, "xXXX")
|
||||
DECL(osl_prepend_color_from, "xXXs")
|
||||
DECL(osl_prepend_matrix_from, "iXXs")
|
||||
DECL(osl_get_matrix, "iXXs")
|
||||
DECL(osl_get_inverse_matrix, "iXXs")
|
||||
DECL(osl_transform_triple, "iXXiXiXXi")
|
||||
DECL(osl_transform_triple_nonlinear, "iXXiXiXXi")
|
||||
DECL(osl_transform_vmv, "xXXX")
|
||||
DECL(osl_transform_dvmdv, "xXXX")
|
||||
DECL(osl_transformv_vmv, "xXXX")
|
||||
DECL(osl_transformv_dvmdv, "xXXX")
|
||||
DECL(osl_transformn_vmv, "xXXX")
|
||||
DECL(osl_transformn_dvmdv, "xXXX")
|
||||
DECL(osl_transformc, "iXXiXiXX")
|
||||
|
||||
DECL (osl_dict_find_iis, "iXiX")
|
||||
DECL (osl_dict_find_iss, "iXXX")
|
||||
DECL (osl_dict_next, "iXi")
|
||||
DECL (osl_dict_value, "iXiXLX")
|
||||
DECL (osl_raytype_name, "iXs")
|
||||
DECL(osl_dict_find_iis, "iXiX")
|
||||
DECL(osl_dict_find_iss, "iXXX")
|
||||
DECL(osl_dict_next, "iXi")
|
||||
DECL(osl_dict_value, "iXiXLX")
|
||||
DECL(osl_raytype_name, "iXs")
|
||||
#ifdef OSL_LLVM_NO_BITCODE
|
||||
DECL (osl_range_check, "iiiXXXiXiXX")
|
||||
DECL(osl_range_check, "iiiXXXiXiXX")
|
||||
#endif
|
||||
DECL (osl_range_check_err, "iiiXXXiXiXX")
|
||||
DECL (osl_naninf_check, "xiXiXXiXiiX")
|
||||
DECL (osl_uninit_check, "xLXXXiXiXXiXiXii")
|
||||
DECL (osl_get_attribute, "iXiXXiiLX")
|
||||
DECL (osl_bind_interpolated_param, "iXXLiXiXiXi")
|
||||
DECL (osl_get_texture_options, "XX");
|
||||
DECL (osl_get_noise_options, "XX");
|
||||
DECL (osl_get_trace_options, "XX");
|
||||
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");
|
||||
|
||||
|
||||
// The following are defined inside llvm_ops.cpp. Only include these
|
||||
@@ -231,17 +230,17 @@ UNARY_OP_IMPL(sinh)
|
||||
UNARY_OP_IMPL(cosh)
|
||||
UNARY_OP_IMPL(tanh)
|
||||
|
||||
DECL (osl_safe_div_iii, "iii")
|
||||
DECL (osl_safe_div_fff, "fff")
|
||||
DECL (osl_safe_mod_iii, "iii")
|
||||
DECL (osl_sincos_fff, "xfXX")
|
||||
DECL (osl_sincos_dfdff, "xXXX")
|
||||
DECL (osl_sincos_dffdf, "xXXX")
|
||||
DECL (osl_sincos_dfdfdf, "xXXX")
|
||||
DECL (osl_sincos_vvv, "xXXX")
|
||||
DECL (osl_sincos_dvdvv, "xXXX")
|
||||
DECL (osl_sincos_dvvdv, "xXXX")
|
||||
DECL (osl_sincos_dvdvdv, "xXXX")
|
||||
DECL(osl_safe_div_iii, "iii")
|
||||
DECL(osl_safe_div_fff, "fff")
|
||||
DECL(osl_safe_mod_iii, "iii")
|
||||
DECL(osl_sincos_fff, "xfXX")
|
||||
DECL(osl_sincos_dfdff, "xXXX")
|
||||
DECL(osl_sincos_dffdf, "xXXX")
|
||||
DECL(osl_sincos_dfdfdf, "xXXX")
|
||||
DECL(osl_sincos_vvv, "xXXX")
|
||||
DECL(osl_sincos_dvdvv, "xXXX")
|
||||
DECL(osl_sincos_dvvdv, "xXXX")
|
||||
DECL(osl_sincos_dvdvdv, "xXXX")
|
||||
|
||||
UNARY_OP_IMPL(log)
|
||||
UNARY_OP_IMPL(log2)
|
||||
@@ -249,142 +248,147 @@ 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)
|
||||
|
||||
DECL (osl_pow_vvf, "xXXf")
|
||||
DECL (osl_pow_dvdvdf, "xXXX")
|
||||
DECL (osl_pow_dvvdf, "xXXX")
|
||||
DECL (osl_pow_dvdvf, "xXXf")
|
||||
BINARY_OP_IMPL(pow)
|
||||
DECL(osl_pow_vvf, "xXXf")
|
||||
DECL(osl_pow_dvdvdf, "xXXX")
|
||||
DECL(osl_pow_dvvdf, "xXXX")
|
||||
DECL(osl_pow_dvdvf, "xXXf")
|
||||
|
||||
UNARY_OP_IMPL(sqrt)
|
||||
UNARY_OP_IMPL(inversesqrt)
|
||||
UNARY_OP_IMPL(cbrt)
|
||||
|
||||
DECL (osl_logb_ff, "ff")
|
||||
DECL (osl_logb_vv, "xXX")
|
||||
DECL(osl_logb_ff, "ff")
|
||||
DECL(osl_logb_vv, "xXX")
|
||||
|
||||
DECL (osl_floor_ff, "ff")
|
||||
DECL (osl_floor_vv, "xXX")
|
||||
DECL (osl_ceil_ff, "ff")
|
||||
DECL (osl_ceil_vv, "xXX")
|
||||
DECL (osl_round_ff, "ff")
|
||||
DECL (osl_round_vv, "xXX")
|
||||
DECL (osl_trunc_ff, "ff")
|
||||
DECL (osl_trunc_vv, "xXX")
|
||||
DECL (osl_sign_ff, "ff")
|
||||
DECL (osl_sign_vv, "xXX")
|
||||
DECL (osl_step_fff, "fff")
|
||||
DECL (osl_step_vvv, "xXXX")
|
||||
DECL(osl_floor_ff, "ff")
|
||||
DECL(osl_floor_vv, "xXX")
|
||||
DECL(osl_ceil_ff, "ff")
|
||||
DECL(osl_ceil_vv, "xXX")
|
||||
DECL(osl_round_ff, "ff")
|
||||
DECL(osl_round_vv, "xXX")
|
||||
DECL(osl_trunc_ff, "ff")
|
||||
DECL(osl_trunc_vv, "xXX")
|
||||
DECL(osl_sign_ff, "ff")
|
||||
DECL(osl_sign_vv, "xXX")
|
||||
DECL(osl_step_fff, "fff")
|
||||
DECL(osl_step_vvv, "xXXX")
|
||||
|
||||
DECL (osl_isnan_if, "if")
|
||||
DECL (osl_isinf_if, "if")
|
||||
DECL (osl_isfinite_if, "if")
|
||||
DECL (osl_abs_ii, "ii")
|
||||
DECL (osl_fabs_ii, "ii")
|
||||
DECL(osl_isnan_if, "if")
|
||||
DECL(osl_isinf_if, "if")
|
||||
DECL(osl_isfinite_if, "if")
|
||||
DECL(osl_abs_ii, "ii")
|
||||
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")
|
||||
DECL (osl_smoothstep_dffdff, "xXfXf")
|
||||
DECL (osl_smoothstep_dffdfdf, "xXfXX")
|
||||
DECL (osl_smoothstep_dfdfff, "xXXff")
|
||||
DECL (osl_smoothstep_dfdffdf, "xXXfX")
|
||||
DECL (osl_smoothstep_dfdfdff, "xXXXf")
|
||||
DECL (osl_smoothstep_dfdfdfdf, "xXXXX")
|
||||
DECL(osl_smoothstep_ffff, "ffff")
|
||||
DECL(osl_smoothstep_dfffdf, "xXffX")
|
||||
DECL(osl_smoothstep_dffdff, "xXfXf")
|
||||
DECL(osl_smoothstep_dffdfdf, "xXfXX")
|
||||
DECL(osl_smoothstep_dfdfff, "xXXff")
|
||||
DECL(osl_smoothstep_dfdffdf, "xXXfX")
|
||||
DECL(osl_smoothstep_dfdfdff, "xXXXf")
|
||||
DECL(osl_smoothstep_dfdfdfdf, "xXXXX")
|
||||
|
||||
DECL (osl_dot_fvv, "fXX")
|
||||
DECL (osl_dot_dfdvdv, "xXXX")
|
||||
DECL (osl_dot_dfdvv, "xXXX")
|
||||
DECL (osl_dot_dfvdv, "xXXX")
|
||||
DECL (osl_cross_vvv, "xXXX")
|
||||
DECL (osl_cross_dvdvdv, "xXXX")
|
||||
DECL (osl_cross_dvdvv, "xXXX")
|
||||
DECL (osl_cross_dvvdv, "xXXX")
|
||||
DECL (osl_length_fv, "fX")
|
||||
DECL (osl_length_dfdv, "xXX")
|
||||
DECL (osl_distance_fvv, "fXX")
|
||||
DECL (osl_distance_dfdvdv, "xXXX")
|
||||
DECL (osl_distance_dfdvv, "xXXX")
|
||||
DECL (osl_distance_dfvdv, "xXXX")
|
||||
DECL (osl_normalize_vv, "xXX")
|
||||
DECL (osl_normalize_dvdv, "xXX")
|
||||
DECL(osl_dot_fvv, "fXX")
|
||||
DECL(osl_dot_dfdvdv, "xXXX")
|
||||
DECL(osl_dot_dfdvv, "xXXX")
|
||||
DECL(osl_dot_dfvdv, "xXXX")
|
||||
DECL(osl_cross_vvv, "xXXX")
|
||||
DECL(osl_cross_dvdvdv, "xXXX")
|
||||
DECL(osl_cross_dvdvv, "xXXX")
|
||||
DECL(osl_cross_dvvdv, "xXXX")
|
||||
DECL(osl_length_fv, "fX")
|
||||
DECL(osl_length_dfdv, "xXX")
|
||||
DECL(osl_distance_fvv, "fXX")
|
||||
DECL(osl_distance_dfdvdv, "xXXX")
|
||||
DECL(osl_distance_dfdvv, "xXXX")
|
||||
DECL(osl_distance_dfvdv, "xXXX")
|
||||
DECL(osl_normalize_vv, "xXX")
|
||||
DECL(osl_normalize_dvdv, "xXX")
|
||||
#endif
|
||||
|
||||
|
||||
DECL (osl_mul_mmm, "xXXX")
|
||||
DECL (osl_mul_mmf, "xXXf")
|
||||
DECL(osl_mul_mmm, "xXXX")
|
||||
DECL(osl_mul_mmf, "xXXf")
|
||||
|
||||
DECL (osl_div_mmm, "xXXX")
|
||||
DECL (osl_div_mmf, "xXXf")
|
||||
DECL (osl_div_mfm, "xXfX")
|
||||
DECL(osl_div_mmm, "xXXX")
|
||||
DECL(osl_div_mmf, "xXXf")
|
||||
DECL(osl_div_mfm, "xXfX")
|
||||
|
||||
DECL (osl_get_from_to_matrix, "iXXss")
|
||||
DECL (osl_transpose_mm, "xXX")
|
||||
DECL (osl_determinant_fm, "fX")
|
||||
DECL(osl_get_from_to_matrix, "iXXss")
|
||||
DECL(osl_transpose_mm, "xXX")
|
||||
DECL(osl_determinant_fm, "fX")
|
||||
|
||||
DECL (osl_concat_sss, "sss")
|
||||
DECL (osl_strlen_is, "is")
|
||||
DECL (osl_hash_is, "is")
|
||||
DECL (osl_getchar_isi, "isi");
|
||||
DECL (osl_startswith_iss, "iss")
|
||||
DECL (osl_endswith_iss, "iss")
|
||||
DECL (osl_stoi_is, "is")
|
||||
DECL (osl_stof_fs, "fs")
|
||||
DECL (osl_substr_ssii, "ssii")
|
||||
DECL (osl_regex_impl, "iXsXisi")
|
||||
DECL(osl_concat_sss, "sss")
|
||||
DECL(osl_strlen_is, "is")
|
||||
DECL(osl_hash_is, "is")
|
||||
DECL(osl_getchar_isi, "isi");
|
||||
DECL(osl_startswith_iss, "iss")
|
||||
DECL(osl_endswith_iss, "iss")
|
||||
DECL(osl_stoi_is, "is")
|
||||
DECL(osl_stof_fs, "fs")
|
||||
DECL(osl_substr_ssii, "ssii")
|
||||
DECL(osl_regex_impl, "iXsXisi")
|
||||
|
||||
// Used by wide code generator, but are uniform calls
|
||||
DECL (osl_texture_decode_wrapmode, "iX");
|
||||
DECL (osl_texture_decode_interpmode, "iX");
|
||||
DECL(osl_texture_decode_wrapmode, "iX");
|
||||
DECL(osl_texture_decode_interpmode, "iX");
|
||||
|
||||
DECL (osl_texture_set_firstchannel, "xXi")
|
||||
DECL (osl_texture_set_swrap, "xXs")
|
||||
DECL (osl_texture_set_twrap, "xXs")
|
||||
DECL (osl_texture_set_rwrap, "xXs")
|
||||
DECL (osl_texture_set_stwrap, "xXs")
|
||||
DECL (osl_texture_set_swrap_code, "xXi")
|
||||
DECL (osl_texture_set_twrap_code, "xXi")
|
||||
DECL (osl_texture_set_rwrap_code, "xXi")
|
||||
DECL (osl_texture_set_stwrap_code, "xXi")
|
||||
DECL (osl_texture_set_sblur, "xXf")
|
||||
DECL (osl_texture_set_tblur, "xXf")
|
||||
DECL (osl_texture_set_rblur, "xXf")
|
||||
DECL (osl_texture_set_stblur, "xXf")
|
||||
DECL (osl_texture_set_swidth, "xXf")
|
||||
DECL (osl_texture_set_twidth, "xXf")
|
||||
DECL (osl_texture_set_rwidth, "xXf")
|
||||
DECL (osl_texture_set_stwidth, "xXf")
|
||||
DECL (osl_texture_set_fill, "xXf")
|
||||
DECL (osl_texture_set_time, "xXf")
|
||||
DECL (osl_texture_set_interp, "xXs")
|
||||
DECL (osl_texture_set_interp_code, "xXi")
|
||||
DECL (osl_texture_set_subimage, "xXi")
|
||||
DECL (osl_texture_set_subimagename, "xXs")
|
||||
DECL (osl_texture_set_missingcolor_arena, "xXX")
|
||||
DECL (osl_texture_set_missingcolor_alpha, "xXif")
|
||||
DECL (osl_texture, "iXXXXffffffiXXXXXXX")
|
||||
DECL (osl_texture3d, "iXXXXXXXXiXXXXXXX")
|
||||
DECL (osl_environment, "iXXXXXXXiXXXXXXX")
|
||||
DECL (osl_get_textureinfo, "iXXXXiiiXX")
|
||||
DECL (osl_get_textureinfo_st, "iXXXffXiiiXX")
|
||||
DECL(osl_texture_set_firstchannel, "xXi")
|
||||
DECL(osl_texture_set_swrap, "xXs")
|
||||
DECL(osl_texture_set_twrap, "xXs")
|
||||
DECL(osl_texture_set_rwrap, "xXs")
|
||||
DECL(osl_texture_set_stwrap, "xXs")
|
||||
DECL(osl_texture_set_swrap_code, "xXi")
|
||||
DECL(osl_texture_set_twrap_code, "xXi")
|
||||
DECL(osl_texture_set_rwrap_code, "xXi")
|
||||
DECL(osl_texture_set_stwrap_code, "xXi")
|
||||
DECL(osl_texture_set_sblur, "xXf")
|
||||
DECL(osl_texture_set_tblur, "xXf")
|
||||
DECL(osl_texture_set_rblur, "xXf")
|
||||
DECL(osl_texture_set_stblur, "xXf")
|
||||
DECL(osl_texture_set_swidth, "xXf")
|
||||
DECL(osl_texture_set_twidth, "xXf")
|
||||
DECL(osl_texture_set_rwidth, "xXf")
|
||||
DECL(osl_texture_set_stwidth, "xXf")
|
||||
DECL(osl_texture_set_fill, "xXf")
|
||||
DECL(osl_texture_set_time, "xXf")
|
||||
DECL(osl_texture_set_interp, "xXs")
|
||||
DECL(osl_texture_set_interp_code, "xXi")
|
||||
DECL(osl_texture_set_subimage, "xXi")
|
||||
DECL(osl_texture_set_subimagename, "xXs")
|
||||
DECL(osl_texture_set_missingcolor_arena, "xXX")
|
||||
DECL(osl_texture_set_missingcolor_alpha, "xXif")
|
||||
DECL(osl_texture, "iXXXXffffffiXXXXXXX")
|
||||
DECL(osl_texture3d, "iXXXXXXXXiXXXXXXX")
|
||||
DECL(osl_environment, "iXXXXXXXiXXXXXXX")
|
||||
DECL(osl_get_textureinfo, "iXXXXiiiXX")
|
||||
DECL(osl_get_textureinfo_st, "iXXXffXiiiXX")
|
||||
|
||||
DECL (osl_trace_set_mindist, "xXf")
|
||||
DECL (osl_trace_set_maxdist, "xXf")
|
||||
DECL (osl_trace_set_shade, "xXi")
|
||||
DECL (osl_trace_set_traceset, "xXs")
|
||||
DECL (osl_trace, "iXXXXXXXX")
|
||||
DECL(osl_trace_set_mindist, "xXf")
|
||||
DECL(osl_trace_set_maxdist, "xXf")
|
||||
DECL(osl_trace_set_shade, "xXi")
|
||||
DECL(osl_trace_set_traceset, "xXs")
|
||||
DECL(osl_trace, "iXXXXXXXX")
|
||||
|
||||
#ifdef OSL_LLVM_NO_BITCODE
|
||||
DECL (osl_calculatenormal, "xXXX")
|
||||
DECL (osl_area, "fX")
|
||||
DECL (osl_filterwidth_fdf, "fX")
|
||||
DECL (osl_filterwidth_vdv, "xXX")
|
||||
DECL (osl_raytype_bit, "iXi")
|
||||
DECL(osl_calculatenormal, "xXXX")
|
||||
DECL(osl_area, "fX")
|
||||
DECL(osl_filterwidth_fdf, "fX")
|
||||
DECL(osl_filterwidth_vdv, "xXX")
|
||||
DECL(osl_raytype_bit, "iXi")
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ DECL(__OSL_MASKED_OP2(hash, Wi, Wv), "xXXi")
|
||||
DECL(__OSL_MASKED_OP3(hash, Wi, Wv, Wf), "xXXXi")
|
||||
|
||||
// Need wide for combinations of the 3 parameters allowed to be uniform
|
||||
// caveat, some combos are unreachable/uneeded
|
||||
// caveat, some combos are unreachable/unneeded
|
||||
// When result has a derivative, there is
|
||||
// no "easy" have a input parameter be non-derivative based on code
|
||||
// analysis promoting all inputs to be derivative base.
|
||||
@@ -381,7 +381,7 @@ 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), "iXXLiXiXiXii")
|
||||
|
||||
//DECL (osl_get_texture_options, "XX") // uneeded
|
||||
//DECL (osl_get_texture_options, "XX") // unneeded
|
||||
DECL(__OSL_OP(get_noise_options), "XX")
|
||||
|
||||
// The following are defined inside llvm_ops.cpp. Only include these
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
#include <OpenImageIO/sysutil.h>
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/genclosure.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
#include "oslexec_pvt.h"
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include <OpenImageIO/thread.h>
|
||||
|
||||
@@ -27,48 +27,48 @@ namespace pvt {
|
||||
/// a new allocation tries to fit it in one of the allocated blocks, but
|
||||
/// if it won't fit anywhere, it makes a new block and adds it to the
|
||||
/// head of the list.
|
||||
template<class T>
|
||||
class ConstantPool {
|
||||
template<class T> class ConstantPool {
|
||||
public:
|
||||
/// Allocate a new pool of T's. The quanta, if supplied, is the
|
||||
/// number of T's to malloc at a time.
|
||||
ConstantPool (size_t quanta = 1000000) : m_quanta(quanta), m_total(0) { }
|
||||
ConstantPool(size_t quanta = 1000000) : m_quanta(quanta), m_total(0) {}
|
||||
|
||||
~ConstantPool () { }
|
||||
~ConstantPool() {}
|
||||
|
||||
/// Allocate space enough for n T's, and return a pointer to the
|
||||
/// start of that space.
|
||||
T * alloc (size_t n) {
|
||||
OIIO::lock_guard lock (m_mutex);
|
||||
T* alloc(size_t n)
|
||||
{
|
||||
OIIO::lock_guard lock(m_mutex);
|
||||
// Check each block in the block list to see if it has enough space
|
||||
for (auto&& block : m_block_list) {
|
||||
size_t s = block.size();
|
||||
if ((s+n) <= block.capacity()) {
|
||||
if ((s + n) <= block.capacity()) {
|
||||
// Enough space in this block. Use it.
|
||||
block.resize (s+n);
|
||||
block.resize(s + n);
|
||||
return &block[s];
|
||||
}
|
||||
}
|
||||
// If we got here, there were no mini-blocks in the list with enough
|
||||
// space. Make a new one.
|
||||
m_block_list.push_front (block_t());
|
||||
block_t &block (m_block_list.front());
|
||||
size_t s = std::max (m_quanta, n);
|
||||
block.reserve (s);
|
||||
m_block_list.push_front(block_t());
|
||||
block_t& block(m_block_list.front());
|
||||
size_t s = std::max(m_quanta, n);
|
||||
block.reserve(s);
|
||||
m_total += s * sizeof(T);
|
||||
block.resize (n);
|
||||
block.resize(n);
|
||||
return &block[0];
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<T> block_t; ///< Type of block
|
||||
std::list<block_t> m_block_list; ///< List of memory blocks
|
||||
size_t m_quanta; ///< How big each memory block is (in T's, not bytes)
|
||||
size_t m_total; ///< Total memory allocated (bytes!)
|
||||
size_t m_quanta; ///< How big each memory block is (in T's, not bytes)
|
||||
size_t m_total; ///< Total memory allocated (bytes!)
|
||||
OIIO::mutex m_mutex; ///< Thread-safe lock
|
||||
};
|
||||
|
||||
|
||||
|
||||
}; // namespace OSL::pvt
|
||||
}; // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -2410,7 +2410,7 @@ DECLFOLDER(constfold_gettextureinfo)
|
||||
ustring filename = Filename.get_string();
|
||||
ustring dataname = Dataname.get_string();
|
||||
TypeDesc t = Data.typespec().simpletype();
|
||||
void* mydata = OIIO_ALLOCA(char, t.size());
|
||||
void* mydata = OSL_ALLOCA(char, t.size());
|
||||
// FIXME(ptex) -- exclude folding of ptex, since these things
|
||||
// can vary per face.
|
||||
ustring errormessage;
|
||||
@@ -2424,7 +2424,7 @@ DECLFOLDER(constfold_gettextureinfo)
|
||||
// assign data [retrieved values]
|
||||
// assign result 1
|
||||
// into this for failure:
|
||||
// error "%s" errormesage
|
||||
// error "%s" errormessage
|
||||
// assign result 0
|
||||
if (result) {
|
||||
int oldresultarg = rop.inst()->args()[op.firstarg() + 0];
|
||||
@@ -2776,7 +2776,7 @@ DECLFOLDER(constfold_pointcloud_get)
|
||||
return 0;
|
||||
|
||||
// Must transfer to size_t array
|
||||
size_t* indices = OIIO_ALLOCA(size_t, count);
|
||||
size_t* indices = OSL_ALLOCA(size_t, count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
indices[i] = Indices.get_int(i);
|
||||
|
||||
|
||||
+14
-24
@@ -244,22 +244,7 @@ ShaderInstance::parameters(const ParamValueList& params)
|
||||
valuetype = TypeDesc::FLOAT;
|
||||
}
|
||||
|
||||
// Relaxed rules just look to see that the types are isomorphic to each other (ie: same number of base values)
|
||||
// Note that:
|
||||
// * basetypes must match exactly (int vs float vs string)
|
||||
// * valuetype cannot be unsized (we must know the concrete number of values)
|
||||
// * if paramtype is sized (or not an array) just check for the total number of entries
|
||||
// * if paramtype is unsized (shader writer is flexible about how many values come in) -- make sure we are a multiple of the target type
|
||||
// * allow a single float setting a vec3 (or equivalent)
|
||||
if (!(valuetype.basetype == paramtype.basetype
|
||||
&& !valuetype.is_unsized_array()
|
||||
&& ((!paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() == paramtype.basevalues())
|
||||
|| (paramtype.is_unsized_array()
|
||||
&& valuetype.basevalues() % paramtype.aggregate
|
||||
== 0)
|
||||
|| (paramtype.is_vec3()
|
||||
&& valuetype == TypeDesc::FLOAT)))) {
|
||||
if (!relaxed_equivalent(sm_typespec, valuetype)) {
|
||||
// We are being very relaxed in this mode, so if the user _still_ got it wrong
|
||||
// something more serious is at play and we should treat it as an error.
|
||||
shadingsys().errorfmt(
|
||||
@@ -301,7 +286,7 @@ ShaderInstance::parameters(const ParamValueList& params)
|
||||
if (paramtype.arraylen < 0) {
|
||||
// An array of definite size was supplied to a parameter
|
||||
// that was an array of indefinite size. Magic! The trick
|
||||
// here is that we need to allocate paramter space at the
|
||||
// here is that we need to allocate parameter space at the
|
||||
// END of the ordinary param storage, since when we assigned
|
||||
// data offsets to each parameter, we didn't know the length
|
||||
// needed to allocate this param in its proper spot.
|
||||
@@ -330,12 +315,19 @@ ShaderInstance::parameters(const ParamValueList& params)
|
||||
// definite length in subsequent rerenders. Don't do that.
|
||||
} else {
|
||||
// If the instance value is the same as the master's default,
|
||||
// just skip the parameter, let it "keep" the default.
|
||||
// Note that this can't/shouldn't happen for the indefinite-
|
||||
// sized array case, which is why we have it in the 'else'
|
||||
// clause of that test.
|
||||
// just skip the parameter, let it "keep" the default by
|
||||
// marking the source as DefaultVal.
|
||||
//
|
||||
// N.B. Beware the situation where it has init ops, and so the
|
||||
// "default value" slot only coincidentally has the same value
|
||||
// as the instance value. We can't mark it as DefaultVal in
|
||||
// that case, because the init ops need to be run.
|
||||
//
|
||||
// Note that this case also can't/shouldn't happen for the
|
||||
// indefinite- sized array case, which is why we have it in
|
||||
// the 'else' clause of that test.
|
||||
void* defaultdata = m_master->param_default_storage(i);
|
||||
if (lockgeom
|
||||
if (lockgeom && !sm->has_init_ops()
|
||||
&& memcmp(defaultdata, data, valuetype.size()) == 0) {
|
||||
// Must reset valuesource to default, in case the parameter
|
||||
// was set already, and now is being changed back to default.
|
||||
@@ -459,11 +451,9 @@ ShaderInstance::evaluate_writes_globals_and_userdata_params()
|
||||
// userdata_params as accurately as we can based on what we know from
|
||||
// the symbol overrides. This is very important to get instance merging
|
||||
// working correctly.
|
||||
int p = 0;
|
||||
for (auto&& s : m_instoverrides) {
|
||||
if (!s.lockgeom())
|
||||
userdata_params(true);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1853
-1752
File diff suppressed because it is too large
Load Diff
+614
-539
File diff suppressed because it is too large
Load Diff
+522
-391
File diff suppressed because it is too large
Load Diff
+159
-85
@@ -6,14 +6,14 @@
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
|
||||
#include <llvm/Pass.h>
|
||||
#include <llvm/IR/Constants.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/Function.h>
|
||||
#include <llvm/IR/Type.h>
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/IR/Function.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/Instruction.h>
|
||||
#include <llvm/IR/Instructions.h>
|
||||
#include <llvm/IR/Type.h>
|
||||
#include <llvm/Pass.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
@@ -37,16 +37,18 @@ namespace {
|
||||
// how instruction lowering happens then this pass may not be necessary.
|
||||
// Also if future LLVM version takes on the work of this optimization pass,
|
||||
// then it may be removed.
|
||||
template <int WidthT>
|
||||
template<int WidthT>
|
||||
class PreventBitMasksFromBeingLiveinsToBasicBlocks final
|
||||
: public llvm::FunctionPass
|
||||
{
|
||||
typedef llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter> IRBuilder;
|
||||
: public llvm::FunctionPass {
|
||||
typedef llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>
|
||||
IRBuilder;
|
||||
llvm::Type* m_llvm_mask_type;
|
||||
llvm::Type* m_native_mask_type;
|
||||
llvm::Constant* m_wide_zero_initializer;
|
||||
std::unordered_map<llvm::Instruction*, llvm::Value*> m_native_mask_by_producing_inst;
|
||||
std::unordered_map<llvm::Value*, llvm::Value*> m_llvm_mask_from_livein_by_native_mask;
|
||||
std::unordered_map<llvm::Instruction*, llvm::Value*>
|
||||
m_native_mask_by_producing_inst;
|
||||
std::unordered_map<llvm::Value*, llvm::Value*>
|
||||
m_llvm_mask_from_livein_by_native_mask;
|
||||
std::vector<llvm::Instruction*> m_phiNodesWithNativeMasks;
|
||||
|
||||
public:
|
||||
@@ -57,11 +59,13 @@ public:
|
||||
, m_llvm_mask_type(nullptr)
|
||||
, m_native_mask_type(nullptr)
|
||||
, m_wide_zero_initializer(nullptr)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
bool doInitialization (llvm::Module &M) override {
|
||||
llvm::Type* llvm_type_bool = llvm::Type::getInt1Ty (M.getContext());
|
||||
llvm::Type* llvm_type_int32 = llvm::Type::getInt32Ty (M.getContext());
|
||||
bool doInitialization(llvm::Module& M) override
|
||||
{
|
||||
llvm::Type* llvm_type_bool = llvm::Type::getInt1Ty(M.getContext());
|
||||
llvm::Type* llvm_type_int32 = llvm::Type::getInt32Ty(M.getContext());
|
||||
|
||||
#if OSL_LLVM_VERSION >= 110
|
||||
m_llvm_mask_type = llvm::FixedVectorType::get(llvm_type_bool, WidthT);
|
||||
@@ -72,39 +76,45 @@ public:
|
||||
// what the native mask type should be. And if necessary maintain a
|
||||
// 16 bit and 32 bit native mask representation to be passed as a
|
||||
// livein.
|
||||
m_native_mask_type = llvm::FixedVectorType::get(llvm_type_int32, WidthT);
|
||||
# if OSL_LLVM_VERSION >= 112
|
||||
m_wide_zero_initializer = llvm::ConstantDataVector::getSplat(WidthT,
|
||||
llvm::ConstantInt::get(M.getContext(), llvm::APInt(32,0)));
|
||||
# else
|
||||
m_native_mask_type = llvm::FixedVectorType::get(llvm_type_int32,
|
||||
WidthT);
|
||||
# if OSL_LLVM_VERSION >= 112
|
||||
m_wide_zero_initializer = llvm::ConstantDataVector::getSplat(
|
||||
WidthT, llvm::ConstantInt::get(M.getContext(), llvm::APInt(32, 0)));
|
||||
# else
|
||||
m_wide_zero_initializer = llvm::ConstantVector::getSplat(
|
||||
llvm::ElementCount(WidthT, false),
|
||||
llvm::ConstantInt::get (M.getContext(), llvm::APInt(32,0)));
|
||||
# endif
|
||||
llvm::ElementCount(WidthT, false),
|
||||
llvm::ConstantInt::get(M.getContext(), llvm::APInt(32, 0)));
|
||||
# endif
|
||||
#else
|
||||
m_llvm_mask_type = llvm::VectorType::get(llvm_type_bool, WidthT);
|
||||
m_llvm_mask_type = llvm::VectorType::get(llvm_type_bool, WidthT);
|
||||
m_native_mask_type = llvm::VectorType::get(llvm_type_int32, WidthT);
|
||||
m_wide_zero_initializer = llvm::ConstantVector::getSplat(WidthT, llvm::ConstantInt::get (M.getContext(), llvm::APInt(32,0)));
|
||||
m_wide_zero_initializer = llvm::ConstantVector::getSplat(
|
||||
WidthT, llvm::ConstantInt::get(M.getContext(), llvm::APInt(32, 0)));
|
||||
#endif
|
||||
return false; // I don't think we modified the module
|
||||
return false; // I don't think we modified the module
|
||||
}
|
||||
|
||||
bool runOnFunction(llvm::Function &F) override {
|
||||
OSL_DEV_ONLY(llvm::errs() << ">>>>>>>>>>>>>>>>>>PreventBitMasksFromBeingLiveinsToBasicBlocks<" << WidthT << ">:");
|
||||
bool runOnFunction(llvm::Function& F) override
|
||||
{
|
||||
OSL_DEV_ONLY(
|
||||
llvm::errs()
|
||||
<< ">>>>>>>>>>>>>>>>>>PreventBitMasksFromBeingLiveinsToBasicBlocks<"
|
||||
<< WidthT << ">:");
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(F.getName()) << '\n');
|
||||
|
||||
m_native_mask_by_producing_inst.clear();
|
||||
|
||||
bool changed = false;
|
||||
|
||||
for (llvm::BasicBlock &bb : F) {
|
||||
for (llvm::BasicBlock& bb : F) {
|
||||
OSL_DEV_ONLY(llvm::errs() << ">>>>>>>>>Basic Block: ");
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(bb.getName()) << '\n');
|
||||
|
||||
m_phiNodesWithNativeMasks.clear();
|
||||
m_llvm_mask_from_livein_by_native_mask.clear();
|
||||
|
||||
for (llvm::Instruction &inst : bb) {
|
||||
for (llvm::Instruction& inst : bb) {
|
||||
// We could possibly identify all the instruction types that
|
||||
// we "think" could be using a mask, but feel just looking
|
||||
// at the operand types is cheaper.
|
||||
@@ -120,21 +130,24 @@ public:
|
||||
// back to llvm masks.
|
||||
IRBuilder builder(&bb);
|
||||
builder.SetInsertPoint(&inst);
|
||||
for (llvm::Instruction* phiNodeWithNativeMask : m_phiNodesWithNativeMasks) {
|
||||
llvm::Value* llvm_mask = builder.CreateICmpSLT (phiNodeWithNativeMask,m_wide_zero_initializer);
|
||||
for (llvm::Instruction* phiNodeWithNativeMask :
|
||||
m_phiNodesWithNativeMasks) {
|
||||
llvm::Value* llvm_mask
|
||||
= builder.CreateICmpSLT(phiNodeWithNativeMask,
|
||||
m_wide_zero_initializer);
|
||||
// Now we need to replace all uses of phiNodeWithNativeMask with our converted llvm mask
|
||||
auto use_iter = phiNodeWithNativeMask->use_begin(),
|
||||
use_end = phiNodeWithNativeMask->use_end();
|
||||
for (; use_iter != use_end;)
|
||||
{
|
||||
llvm::Use &use = *use_iter;
|
||||
use_end = phiNodeWithNativeMask->use_end();
|
||||
for (; use_iter != use_end;) {
|
||||
llvm::Use& use = *use_iter;
|
||||
++use_iter;
|
||||
auto *user = llvm::dyn_cast<llvm::Instruction>(use.getUser());
|
||||
// We need to skip the use wher the user is our conversion to a llvm_mask
|
||||
auto* user = llvm::dyn_cast<llvm::Instruction>(
|
||||
use.getUser());
|
||||
// We need to skip the use where the user is our conversion to a llvm_mask
|
||||
if (user && user == llvm_mask)
|
||||
continue;
|
||||
use.set(llvm_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_phiNodesWithNativeMasks.clear();
|
||||
@@ -151,7 +164,8 @@ public:
|
||||
bool phiNodeHadOperandReplacedInLastPassOverOperands;
|
||||
|
||||
OSL_DEV_ONLY(llvm::errs() << ">>>>Op: ");
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(inst.getOpcodeName()) << '\n');
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(inst.getOpcodeName())
|
||||
<< '\n');
|
||||
|
||||
// As we may have multiple operands that need to be replaced
|
||||
// for a phi node, once we discover a qualifying replacement
|
||||
@@ -167,25 +181,32 @@ public:
|
||||
|
||||
// As we could be replacing operands, but not the number of operands
|
||||
// we use index vs. iterator based loop construct
|
||||
for (unsigned operand_i = 0, num_operands = inst.getNumOperands();
|
||||
operand_i != num_operands;
|
||||
++operand_i) {
|
||||
|
||||
llvm::Value *op_val = inst.getOperand (operand_i);
|
||||
for (unsigned operand_i = 0,
|
||||
num_operands = inst.getNumOperands();
|
||||
operand_i != num_operands; ++operand_i) {
|
||||
llvm::Value* op_val = inst.getOperand(operand_i);
|
||||
if (op_val != nullptr) {
|
||||
llvm::Type* op_type = op_val->getType();
|
||||
llvm::Type* op_type = op_val->getType();
|
||||
if (op_type == m_llvm_mask_type) {
|
||||
// See if the value came from an instruction
|
||||
auto *producing_instr = llvm::dyn_cast<llvm::Instruction>(op_val);
|
||||
auto* producing_instr
|
||||
= llvm::dyn_cast<llvm::Instruction>(op_val);
|
||||
if (producing_instr != nullptr) {
|
||||
llvm::BasicBlock* producing_bb = producing_instr->getParent();
|
||||
llvm::BasicBlock* producing_bb
|
||||
= producing_instr->getParent();
|
||||
|
||||
// If a phi node needs to have one operand promoted,
|
||||
// it will need all operands promoted even if they were
|
||||
// produced in the same basic block, so the types match
|
||||
if (phiNodeHadOperandReplaced || producing_bb != &bb) {
|
||||
OSL_DEV_ONLY(llvm::errs() << "Uses llvm mask <" <<WidthT << "xi1> from different Basic Block: ");
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(op_val->getName()) << '\n');
|
||||
if (phiNodeHadOperandReplaced
|
||||
|| producing_bb != &bb) {
|
||||
OSL_DEV_ONLY(
|
||||
llvm::errs()
|
||||
<< "Uses llvm mask <" << WidthT
|
||||
<< "xi1> from different Basic Block: ");
|
||||
OSL_DEV_ONLY(llvm::errs().write_escaped(
|
||||
op_val->getName())
|
||||
<< '\n');
|
||||
changed = true;
|
||||
|
||||
// We can't let an unrepresentable data type of <16xi1>, <8xi1> or <4xi1>
|
||||
@@ -195,37 +216,68 @@ public:
|
||||
llvm::Value* native_mask = nullptr;
|
||||
{
|
||||
// We may have already created a native mask for this instruction
|
||||
auto search_result = m_native_mask_by_producing_inst.find(producing_instr);
|
||||
if (search_result == m_native_mask_by_producing_inst.end()) {
|
||||
|
||||
auto search_result
|
||||
= m_native_mask_by_producing_inst
|
||||
.find(producing_instr);
|
||||
if (search_result
|
||||
== m_native_mask_by_producing_inst
|
||||
.end()) {
|
||||
// Scan producing basic block for an existing sign extend instruction
|
||||
// for the producing_instr. As the existence of a basic block means
|
||||
// we most likely have a branch higher up whose test required a sign extend
|
||||
for (llvm::Instruction &other_inst : *producing_bb) {
|
||||
auto *existing_sign_ext = llvm::dyn_cast<llvm::SExtInst>(&other_inst);
|
||||
for (llvm::Instruction&
|
||||
other_inst :
|
||||
*producing_bb) {
|
||||
auto* existing_sign_ext
|
||||
= llvm::dyn_cast<
|
||||
llvm::SExtInst>(
|
||||
&other_inst);
|
||||
if (existing_sign_ext) {
|
||||
OSL_ASSERT(existing_sign_ext->getNumOperands() == 1);
|
||||
llvm::Value *existing_operand = existing_sign_ext->getOperand (0);
|
||||
if (existing_operand == producing_instr) {
|
||||
OSL_ASSERT(existing_sign_ext->getType() == m_native_mask_type);
|
||||
OSL_DEV_ONLY(llvm::errs() << "Using existing sign ext in producing bb\n");
|
||||
OSL_ASSERT(
|
||||
existing_sign_ext
|
||||
->getNumOperands()
|
||||
== 1);
|
||||
llvm::Value*
|
||||
existing_operand
|
||||
= existing_sign_ext
|
||||
->getOperand(
|
||||
0);
|
||||
if (existing_operand
|
||||
== producing_instr) {
|
||||
OSL_ASSERT(
|
||||
existing_sign_ext
|
||||
->getType()
|
||||
== m_native_mask_type);
|
||||
OSL_DEV_ONLY(
|
||||
llvm::errs()
|
||||
<< "Using existing sign ext in producing bb\n");
|
||||
|
||||
native_mask = existing_sign_ext;
|
||||
native_mask
|
||||
= existing_sign_ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nullptr == native_mask) {
|
||||
IRBuilder builder(producing_bb);
|
||||
builder.SetInsertPoint(&producing_bb->back());
|
||||
IRBuilder builder(
|
||||
producing_bb);
|
||||
builder.SetInsertPoint(
|
||||
&producing_bb->back());
|
||||
|
||||
native_mask = builder.CreateSExt(producing_instr, m_native_mask_type);
|
||||
native_mask
|
||||
= builder.CreateSExt(
|
||||
producing_instr,
|
||||
m_native_mask_type);
|
||||
// NOTE: we did add instructions, but not to the BB we are currently
|
||||
// iterating over instructions
|
||||
}
|
||||
m_native_mask_by_producing_inst.insert(std::make_pair(producing_instr,native_mask));
|
||||
m_native_mask_by_producing_inst
|
||||
.insert(std::make_pair(
|
||||
producing_instr,
|
||||
native_mask));
|
||||
} else {
|
||||
native_mask = search_result->second;
|
||||
native_mask
|
||||
= search_result->second;
|
||||
}
|
||||
}
|
||||
OSL_ASSERT(native_mask);
|
||||
@@ -239,16 +291,26 @@ public:
|
||||
llvm::Value* llvm_mask = nullptr;
|
||||
{
|
||||
// We may have already created a llvm mask in this basic block for the native mask
|
||||
auto search_result = m_llvm_mask_from_livein_by_native_mask.find(native_mask);
|
||||
if (search_result == m_llvm_mask_from_livein_by_native_mask.end()) {
|
||||
auto search_result
|
||||
= m_llvm_mask_from_livein_by_native_mask
|
||||
.find(native_mask);
|
||||
if (search_result
|
||||
== m_llvm_mask_from_livein_by_native_mask
|
||||
.end()) {
|
||||
// Insert the conversion from native to llvm mask
|
||||
// somewhere before the 1st instruction that needs to use it in this basic block
|
||||
IRBuilder builder(&bb);
|
||||
builder.SetInsertPoint(&inst);
|
||||
builder.SetInsertPoint(
|
||||
&inst);
|
||||
|
||||
llvm_mask = builder.CreateICmpSLT (native_mask,m_wide_zero_initializer);
|
||||
llvm_mask = builder.CreateICmpSLT(
|
||||
native_mask,
|
||||
m_wide_zero_initializer);
|
||||
|
||||
m_llvm_mask_from_livein_by_native_mask.insert(std::make_pair(native_mask,llvm_mask));
|
||||
m_llvm_mask_from_livein_by_native_mask
|
||||
.insert(std::make_pair(
|
||||
native_mask,
|
||||
llvm_mask));
|
||||
|
||||
// NOTE: we did add instructions to this bb,
|
||||
// but the should be inserted before the current inst.
|
||||
@@ -257,12 +319,13 @@ public:
|
||||
// iterator should not invalidate the iterator
|
||||
|
||||
} else {
|
||||
llvm_mask = search_result->second;
|
||||
llvm_mask
|
||||
= search_result->second;
|
||||
}
|
||||
}
|
||||
inst.setOperand (operand_i, llvm_mask);
|
||||
inst.setOperand(operand_i,
|
||||
llvm_mask);
|
||||
} else {
|
||||
|
||||
// Phi nodes have to exist at the top of a basic block which precludes
|
||||
// our basic algorithm from just converting the native mask back to a llvm mask
|
||||
// before the phi node.
|
||||
@@ -270,24 +333,37 @@ public:
|
||||
// and insert an instruction to convert it after the block of phi nodes
|
||||
// However, this now means we will need to find all uses of the phi node's
|
||||
// result and replace them with our converted llvm_mask
|
||||
inst.setOperand (operand_i, native_mask);
|
||||
inst.setOperand(operand_i,
|
||||
native_mask);
|
||||
phiNodeHadOperandReplaced = true;
|
||||
phiNodeHadOperandReplacedInLastPassOverOperands = true;
|
||||
phiNodeHadOperandReplacedInLastPassOverOperands
|
||||
= true;
|
||||
}
|
||||
// We should be able to continue iterating over the rest of the operands
|
||||
}
|
||||
} else if (phiNodeHadOperandReplaced) {
|
||||
auto *constant = llvm::dyn_cast<llvm::Constant>(op_val);
|
||||
auto* constant
|
||||
= llvm::dyn_cast<llvm::Constant>(
|
||||
op_val);
|
||||
if (constant) {
|
||||
OSL_DEV_ONLY(llvm::errs() << "Uses constant llvm mask <" <<WidthT << "xi1> \n");
|
||||
OSL_DEV_ONLY(
|
||||
llvm::errs()
|
||||
<< "Uses constant llvm mask <"
|
||||
<< WidthT << "xi1> \n");
|
||||
|
||||
// Should handle promoting whatever the constant value is (most likely zeroinitializer)
|
||||
llvm::ConstantFolder Folder;
|
||||
auto *signExtConstant = Folder.CreateCast(llvm::Instruction::SExt, constant, m_native_mask_type);
|
||||
auto* signExtConstant
|
||||
= Folder.CreateCast(
|
||||
llvm::Instruction::SExt,
|
||||
constant, m_native_mask_type);
|
||||
|
||||
inst.setOperand (operand_i, signExtConstant);
|
||||
inst.setOperand(operand_i,
|
||||
signExtConstant);
|
||||
} else {
|
||||
OSL_ASSERT(0 && "Unhandled/Unexpected llvm mask type");
|
||||
OSL_ASSERT(
|
||||
0
|
||||
&& "Unhandled/Unexpected llvm mask type");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,11 +397,9 @@ public:
|
||||
// including this file will need its own static members defined. LLVM will
|
||||
// assign IDs when they get registered, so this initialization value is not
|
||||
// important.
|
||||
template<>
|
||||
char PreventBitMasksFromBeingLiveinsToBasicBlocks<8>::ID = 0;
|
||||
template<> char PreventBitMasksFromBeingLiveinsToBasicBlocks<8>::ID = 0;
|
||||
|
||||
template<>
|
||||
char PreventBitMasksFromBeingLiveinsToBasicBlocks<16>::ID = 0;
|
||||
template<> char PreventBitMasksFromBeingLiveinsToBasicBlocks<16>::ID = 0;
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
||||
+2442
-2138
File diff suppressed because it is too large
Load Diff
+141
-125
@@ -12,23 +12,23 @@ OSL_NAMESPACE_ENTER
|
||||
|
||||
static ustring udot(".");
|
||||
|
||||
Parser::Parser(const std::vector<ustring> *user_events,
|
||||
const std::vector<ustring> *user_scatterings)
|
||||
Parser::Parser(const std::vector<ustring>* user_events,
|
||||
const std::vector<ustring>* user_scatterings)
|
||||
{
|
||||
m_ingroup = false;
|
||||
m_error = "";
|
||||
m_error = "";
|
||||
|
||||
m_label_position[Labels::CAMERA] = 0;
|
||||
m_label_position[Labels::LIGHT] = 0;
|
||||
m_label_position[Labels::CAMERA] = 0;
|
||||
m_label_position[Labels::LIGHT] = 0;
|
||||
m_label_position[Labels::BACKGROUND] = 0;
|
||||
m_label_position[Labels::VOLUME] = 0;
|
||||
m_label_position[Labels::TRANSMIT] = 0;
|
||||
m_label_position[Labels::REFLECT] = 0;
|
||||
m_label_position[Labels::OBJECT] = 0;
|
||||
m_label_position[Labels::DIFFUSE] = 1;
|
||||
m_label_position[Labels::GLOSSY] = 1;
|
||||
m_label_position[Labels::SINGULAR] = 1;
|
||||
m_label_position[Labels::STRAIGHT] = 1;
|
||||
m_label_position[Labels::VOLUME] = 0;
|
||||
m_label_position[Labels::TRANSMIT] = 0;
|
||||
m_label_position[Labels::REFLECT] = 0;
|
||||
m_label_position[Labels::OBJECT] = 0;
|
||||
m_label_position[Labels::DIFFUSE] = 1;
|
||||
m_label_position[Labels::GLOSSY] = 1;
|
||||
m_label_position[Labels::SINGULAR] = 1;
|
||||
m_label_position[Labels::STRAIGHT] = 1;
|
||||
|
||||
m_basic_labels.insert(Labels::CAMERA);
|
||||
m_basic_labels.insert(Labels::LIGHT);
|
||||
@@ -47,42 +47,40 @@ Parser::Parser(const std::vector<ustring> *user_events,
|
||||
m_minus_stop.insert(Labels::STOP);
|
||||
|
||||
if (user_events)
|
||||
for (size_t i = 0; i < user_events->size(); ++i)
|
||||
{
|
||||
m_label_position[(*user_events)[i]] = 0;
|
||||
m_basic_labels.insert((*user_events)[i]);
|
||||
}
|
||||
if (user_scatterings)
|
||||
for (size_t i = 0; i < user_scatterings->size(); ++i)
|
||||
{
|
||||
m_label_position[(*user_scatterings)[i]] = 1;
|
||||
m_basic_labels.insert((*user_scatterings)[i]);
|
||||
}
|
||||
for (auto&& e : *user_events) {
|
||||
m_label_position[e] = 0;
|
||||
m_basic_labels.insert(e);
|
||||
}
|
||||
if (user_scatterings)
|
||||
for (auto&& s : *user_scatterings) {
|
||||
m_label_position[s] = 1;
|
||||
m_basic_labels.insert(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LPexp *
|
||||
Parser::buildStop(LPexp *etype, LPexp *scatter, const std::list<LPexp*> &custom)
|
||||
LPexp*
|
||||
Parser::buildStop(LPexp* etype, LPexp* scatter, const std::list<LPexp*>& custom)
|
||||
{
|
||||
lpexp::Cat *cat = new lpexp::Cat();
|
||||
lpexp::Cat* cat = new lpexp::Cat();
|
||||
cat->append(etype);
|
||||
cat->append(scatter);
|
||||
for (std::list<LPexp*>::const_iterator i = custom.begin(); i != custom.end(); ++i)
|
||||
cat->append(*i);
|
||||
for (const auto& p : custom)
|
||||
cat->append(p);
|
||||
|
||||
if (custom.size() < 5)
|
||||
cat->append (new lpexp::Repeat (new lpexp::Wildexp (m_basic_labels)));
|
||||
cat->append(new lpexp::Repeat(new lpexp::Wildexp(m_basic_labels)));
|
||||
cat->append(new lpexp::Symbol(Labels::STOP));
|
||||
return cat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::parseSymbol()
|
||||
{
|
||||
bool iscustom = false;
|
||||
ustring sym = parseRawSymbol(iscustom);
|
||||
ustring sym = parseRawSymbol(iscustom);
|
||||
if (m_ingroup) {
|
||||
if (sym == udot)
|
||||
return new lpexp::Wildexp(m_minus_stop);
|
||||
@@ -90,25 +88,26 @@ Parser::parseSymbol()
|
||||
return new lpexp::Symbol(sym);
|
||||
} else {
|
||||
if (iscustom) {
|
||||
std::list<LPexp *> custom;
|
||||
std::list<LPexp*> custom;
|
||||
custom.push_back(new lpexp::Symbol(sym));
|
||||
return buildStop(new lpexp::Wildexp(m_minus_stop), new lpexp::Wildexp(m_minus_stop), custom);
|
||||
return buildStop(new lpexp::Wildexp(m_minus_stop),
|
||||
new lpexp::Wildexp(m_minus_stop), custom);
|
||||
} else {
|
||||
LPexp *basics[2] = {NULL, NULL};
|
||||
LPexp* basics[2] = { NULL, NULL };
|
||||
if (sym != ".") {
|
||||
SymbolToInt::const_iterator i = m_label_position.find(sym);
|
||||
if (i == m_label_position.end()) {
|
||||
m_error = std::string("Unrecognized basic label: ") + sym.c_str();
|
||||
return NULL;
|
||||
m_error = fmtformat("Unrecognized basic label: {}", sym);
|
||||
return nullptr;
|
||||
}
|
||||
int pos = i->second;
|
||||
int pos = i->second;
|
||||
basics[pos] = new lpexp::Symbol(sym);
|
||||
}
|
||||
for (int k = 0; k < 2; ++k)
|
||||
if (!basics[k])
|
||||
basics[k] = new lpexp::Wildexp(m_minus_stop);
|
||||
std::list<LPexp *> empty;
|
||||
return buildStop (basics[0], basics[1], empty);
|
||||
std::list<LPexp*> empty;
|
||||
return buildStop(basics[0], basics[1], empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +115,7 @@ Parser::parseSymbol()
|
||||
|
||||
|
||||
ustring
|
||||
Parser::parseRawSymbol(bool &iscustom)
|
||||
Parser::parseRawSymbol(bool& iscustom)
|
||||
{
|
||||
std::string sym;
|
||||
if (head() == '\'') {
|
||||
@@ -144,47 +143,49 @@ Parser::parseRawSymbol(bool &iscustom)
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::parseCat()
|
||||
{
|
||||
//lpexp::Cat *cat = new lpexp::Cat();
|
||||
std::vector<LPexp *> explist;
|
||||
std::vector<LPexp*> explist;
|
||||
char endchar;
|
||||
if (head() == '(') {
|
||||
next();
|
||||
endchar = ')';
|
||||
}
|
||||
else endchar = 0;
|
||||
} else
|
||||
endchar = 0;
|
||||
|
||||
while (hasInput() && head() != endchar) {
|
||||
while (hasInput() && head() != endchar) {
|
||||
if (head() == '|') {
|
||||
if (!explist.size()) {
|
||||
m_error = "No left expression to or with |";
|
||||
for (size_t i=0; i < explist.size(); ++i)
|
||||
delete explist[i];
|
||||
return NULL;
|
||||
for (auto& exp : explist)
|
||||
delete exp;
|
||||
return nullptr;
|
||||
}
|
||||
next();
|
||||
LPexp *e = _parse();
|
||||
LPexp* e = _parse();
|
||||
if (error()) {
|
||||
for (size_t i=0; i < explist.size(); ++i)
|
||||
delete explist[i];
|
||||
return NULL;
|
||||
delete e;
|
||||
for (auto& exp : explist)
|
||||
delete exp;
|
||||
return nullptr;
|
||||
}
|
||||
if (explist.back()->getType() == lpexp::OR)
|
||||
((lpexp::Orlist*)explist.back())->append(e);
|
||||
else {
|
||||
lpexp::Orlist *orexp = new lpexp::Orlist();
|
||||
lpexp::Orlist* orexp = new lpexp::Orlist();
|
||||
orexp->append(explist.back());
|
||||
orexp->append(e);
|
||||
explist[explist.size() - 1] = orexp;
|
||||
}
|
||||
} else {
|
||||
LPexp *e = _parse();
|
||||
LPexp* e = _parse();
|
||||
if (error()) {
|
||||
for (size_t i=0; i < explist.size(); ++i)
|
||||
delete explist[i];
|
||||
return NULL;
|
||||
delete e;
|
||||
for (auto& exp : explist)
|
||||
delete exp;
|
||||
return nullptr;
|
||||
}
|
||||
explist.push_back(e);
|
||||
}
|
||||
@@ -193,41 +194,47 @@ Parser::parseCat()
|
||||
next();
|
||||
else if (endchar != 0) {
|
||||
m_error = "Reached end of line looking for )";
|
||||
for (size_t i=0; i < explist.size(); ++i)
|
||||
delete explist[i];
|
||||
return NULL;
|
||||
for (auto& exp : explist)
|
||||
delete exp;
|
||||
return nullptr;
|
||||
}
|
||||
lpexp::Cat *cat = new lpexp::Cat();
|
||||
for (size_t i=0; i < explist.size(); ++i)
|
||||
cat->append(explist[i]);
|
||||
lpexp::Cat* cat = new lpexp::Cat();
|
||||
for (auto& exp : explist)
|
||||
cat->append(exp);
|
||||
return cat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::parseGroup()
|
||||
{
|
||||
OSL_DASSERT(head() == '<');
|
||||
if (m_ingroup) {
|
||||
m_error = "No groups allowed inside of groups";
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
int basicpos = 0;
|
||||
LPexp *basics[2] = {NULL, NULL};
|
||||
std::list<LPexp *> custom;
|
||||
#define THROWAWAY() do{\
|
||||
for (int i=0;i<2;++i) if(basics[i]) delete basics[i];\
|
||||
for (std::list<LPexp *>::iterator i = custom.begin();i!=custom.end();++i) delete *i;\
|
||||
m_ingroup = false;\
|
||||
return NULL;\
|
||||
}while(0)
|
||||
int basicpos = 0;
|
||||
LPexp* basics[2] = { nullptr, nullptr };
|
||||
std::list<LPexp*> custom;
|
||||
#define THROWAWAY() \
|
||||
do { \
|
||||
delete basics[0]; \
|
||||
delete basics[1]; \
|
||||
for (auto& p : custom) \
|
||||
delete p; \
|
||||
m_ingroup = false; \
|
||||
return nullptr; \
|
||||
} while (0)
|
||||
|
||||
m_ingroup = true;
|
||||
next();
|
||||
while (hasInput() && head() != '>') {
|
||||
LPexp *e = _parse();
|
||||
if (error()) THROWAWAY();
|
||||
LPexp* e = _parse();
|
||||
if (error()) {
|
||||
delete e;
|
||||
THROWAWAY();
|
||||
}
|
||||
if (basicpos < 2)
|
||||
basics[basicpos++] = e;
|
||||
else
|
||||
@@ -247,65 +254,69 @@ Parser::parseGroup()
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::parseNegor()
|
||||
{
|
||||
OSL_DASSERT (head() == '^');
|
||||
OSL_DASSERT(head() == '^');
|
||||
SymbolSet symlist;
|
||||
symlist.insert(Labels::STOP); // never allowed
|
||||
symlist.insert(Labels::STOP); // never allowed
|
||||
int pos = -1;
|
||||
next();
|
||||
while (hasInput() && head() != ']') {
|
||||
bool iscustom = false;
|
||||
ustring sym = parseRawSymbol(iscustom);
|
||||
if (error()) return NULL;
|
||||
ustring sym = parseRawSymbol(iscustom);
|
||||
if (error())
|
||||
return nullptr;
|
||||
symlist.insert(sym);
|
||||
if (iscustom) {
|
||||
if (symlist.size() > 2 && pos != -1)
|
||||
std::cerr << "[pathexp] you are mixing labels of different type in [...]" << std::endl;
|
||||
if (symlist.size() > 2 && pos != -1)
|
||||
std::cerr
|
||||
<< "[pathexp] you are mixing labels of different type in [...]"
|
||||
<< std::endl;
|
||||
pos = -1;
|
||||
} else {
|
||||
SymbolToInt::const_iterator found = m_label_position.find(sym);
|
||||
if (found == m_label_position.end()) {
|
||||
m_error = "Unrecognized basic label";
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if (symlist.size() > 2 && found->second != pos)
|
||||
std::cerr << "[pathexp] you are mixing labels of different type in [...]" << std::endl;
|
||||
if (symlist.size() > 2 && found->second != pos)
|
||||
std::cerr
|
||||
<< "[pathexp] you are mixing labels of different type in [...]"
|
||||
<< std::endl;
|
||||
pos = found->second;
|
||||
}
|
||||
}
|
||||
if (!hasInput()) {
|
||||
m_error = "Reached end of line looking for ] to end an negative or list'";
|
||||
return NULL;
|
||||
m_error
|
||||
= "Reached end of line looking for ] to end an negative or list'";
|
||||
return nullptr;
|
||||
}
|
||||
if (symlist.size() < 2) {
|
||||
m_error = "Empty or list [^] not allowed";
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
next();
|
||||
lpexp::Wildexp *wildcard = new lpexp::Wildexp(symlist);
|
||||
lpexp::Wildexp* wildcard = new lpexp::Wildexp(symlist);
|
||||
if (m_ingroup)
|
||||
return wildcard;
|
||||
else {
|
||||
std::list<LPexp *> custom;
|
||||
if (pos < 0) { // is a custom label
|
||||
std::list<LPexp*> custom;
|
||||
if (pos < 0) { // is a custom label
|
||||
custom.push_back(wildcard);
|
||||
return buildStop(new lpexp::Wildexp(m_minus_stop), new lpexp::Wildexp(m_minus_stop), custom);
|
||||
return buildStop(new lpexp::Wildexp(m_minus_stop),
|
||||
new lpexp::Wildexp(m_minus_stop), custom);
|
||||
} else {
|
||||
LPexp *basics[2] = {NULL, NULL};
|
||||
basics[pos] = wildcard;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
if (!basics[i])
|
||||
basics[i] = new lpexp::Wildexp(m_minus_stop);
|
||||
return buildStop(basics[0], basics[1], custom);
|
||||
LPexp* w2 = new lpexp::Wildexp(m_minus_stop);
|
||||
return buildStop(pos == 0 ? wildcard : w2, pos == 0 ? w2 : wildcard,
|
||||
custom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::parseOrlist()
|
||||
{
|
||||
OSL_DASSERT(head() == '[');
|
||||
@@ -313,19 +324,20 @@ Parser::parseOrlist()
|
||||
if (hasInput() && head() == '^')
|
||||
return parseNegor();
|
||||
else {
|
||||
lpexp::Orlist *orlist = new lpexp::Orlist();
|
||||
lpexp::Orlist* orlist = new lpexp::Orlist();
|
||||
while (hasInput() && head() != ']') {
|
||||
LPexp *e = _parse();
|
||||
LPexp* e = _parse();
|
||||
if (error()) {
|
||||
delete e;
|
||||
delete orlist;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
orlist->append(e);
|
||||
}
|
||||
if (!hasInput()) {
|
||||
m_error = "Reached end of line looking for ] to end an or list";
|
||||
delete orlist;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
next();
|
||||
return orlist;
|
||||
@@ -360,29 +372,32 @@ Parser::parseRange()
|
||||
}
|
||||
next();
|
||||
if (secondnum.size())
|
||||
return std::pair<int, int>(atoi(firstnum.c_str()), atoi(secondnum.c_str()));
|
||||
return std::pair<int, int>(OIIO::Strutil::stoi(firstnum),
|
||||
OIIO::Strutil::stoi(secondnum));
|
||||
else
|
||||
return std::pair<int, int>(atoi(firstnum.c_str()), atoi(firstnum.c_str()));
|
||||
return std::pair<int, int>(OIIO::Strutil::stoi(firstnum),
|
||||
OIIO::Strutil::stoi(firstnum));
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
Parser::parseModifier(LPexp *e)
|
||||
LPexp*
|
||||
Parser::parseModifier(LPexp* e)
|
||||
{
|
||||
if (hasInput()) {
|
||||
if (m_ingroup && (head() == '*' || head() == '{' || head() == '+')) {
|
||||
m_error = std::string("Repetitions not allowed inside '<...>'");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if (head() == '*') {
|
||||
next();
|
||||
return new lpexp::Repeat(e);
|
||||
} else if (head() == '{') {
|
||||
std::pair<int, int> range = parseRange();
|
||||
if (error()) return NULL;
|
||||
if (error())
|
||||
return nullptr;
|
||||
if (range.second < 0) {
|
||||
lpexp::Cat *cat = new lpexp::Cat();
|
||||
lpexp::Cat* cat = new lpexp::Cat();
|
||||
cat->append(new lpexp::NRepeat(e, range.first, range.first));
|
||||
cat->append(new lpexp::Repeat(e->clone()));
|
||||
return cat;
|
||||
@@ -390,23 +405,22 @@ Parser::parseModifier(LPexp *e)
|
||||
return new lpexp::NRepeat(e, range.first, range.second);
|
||||
} else if (head() == '+') {
|
||||
next();
|
||||
lpexp::Cat *cat = new lpexp::Cat();
|
||||
lpexp::Cat* cat = new lpexp::Cat();
|
||||
cat->append(e);
|
||||
cat->append(new lpexp::Repeat(e->clone()));
|
||||
return cat;
|
||||
} else
|
||||
return e;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
LPexp*
|
||||
Parser::_parse()
|
||||
{
|
||||
LPexp *e;
|
||||
LPexp* e = nullptr;
|
||||
if (head() == '(')
|
||||
e = parseCat();
|
||||
else if (head() == '[')
|
||||
@@ -415,24 +429,26 @@ Parser::_parse()
|
||||
e = parseGroup();
|
||||
else
|
||||
e = parseSymbol();
|
||||
if (error())
|
||||
return NULL;
|
||||
if (error()) {
|
||||
delete e;
|
||||
return nullptr;
|
||||
}
|
||||
return parseModifier(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LPexp *
|
||||
Parser::parse(const char *text)
|
||||
LPexp*
|
||||
Parser::parse(const char* text)
|
||||
{
|
||||
m_error = "";
|
||||
m_text = text;
|
||||
m_pos = 0;
|
||||
m_error = "";
|
||||
m_text = text;
|
||||
m_pos = 0;
|
||||
m_ingroup = false;
|
||||
if (hasInput())
|
||||
return parseCat();
|
||||
else
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+79
-80
@@ -33,92 +33,91 @@ using lpexp::LPexp;
|
||||
/// exp := wildexp | borexp | sorexp | catexp | group | repeat | repeat+ | mnrepeat
|
||||
/// topexp := exp | topexp exp
|
||||
///
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
class Parser {
|
||||
public:
|
||||
Parser(const std::vector<ustring>* user_events = NULL,
|
||||
const std::vector<ustring>* user_scatterings = NULL);
|
||||
|
||||
Parser(const std::vector<ustring> *user_events = NULL,
|
||||
const std::vector<ustring> *user_scatterings = NULL);
|
||||
/// Parse a string and return the resulting light path expression tree or NULL if failed
|
||||
LPexp* parse(const char* text);
|
||||
|
||||
/// Parse a string and return the resulting light path expression tree or NULL if failed
|
||||
LPexp *parse(const char *text);
|
||||
/// Check for error in the last parsed string
|
||||
bool error() const { return m_error.size() > 0; };
|
||||
/// Get the error string
|
||||
const char* getErrorMsg() const { return m_error.c_str(); };
|
||||
/// Get the position of the string where the error appeared
|
||||
int getErrorPos() const { return m_pos; };
|
||||
|
||||
/// Check for error in the last parsed string
|
||||
bool error()const { return m_error.size() > 0; };
|
||||
/// Get the error string
|
||||
const char *getErrorMsg()const { return m_error.c_str(); };
|
||||
/// Get the position of the string where the error appeared
|
||||
int getErrorPos()const { return m_pos; };
|
||||
private:
|
||||
/// Current char being parsed
|
||||
char head() const { return m_text[m_pos]; };
|
||||
/// Any input (including head) left?
|
||||
bool hasInput() const { return m_text.size() > m_pos; };
|
||||
/// Go to the next char in the string
|
||||
void next() { m_pos++; };
|
||||
|
||||
private:
|
||||
/// build the complete pattern for a pathtracing stop
|
||||
///
|
||||
/// That means the three basic label match expressions, plus those for the custom labels (if any),
|
||||
/// plus an additional wildcard to eat extra custom labels at the end, and finally the stop mark.
|
||||
/// So you provide the regexps for the basic three labels:
|
||||
///
|
||||
/// \param etype Event type (CFVL)
|
||||
/// \param dir Direction (RD)
|
||||
/// \param scatter Scattering type (DGSs)
|
||||
///
|
||||
/// That of course can be wildcards or any other expression willing to match them. And then you can
|
||||
/// provide extra expressions to match the custom labels:
|
||||
///
|
||||
/// \param custom Custom label regexps
|
||||
///
|
||||
/// And the function will automatically add a "[^stop_mark]*stop_mark" at the end.
|
||||
///
|
||||
LPexp* buildStop(LPexp* etype, LPexp* scatter,
|
||||
const std::list<LPexp*>& custom);
|
||||
/// Given that a symbol is ready in head() to parse, parse it
|
||||
LPexp* parseSymbol();
|
||||
/// Given that a symbol is ready in head() to parse, parse it as a ustring
|
||||
/// and report it was a custom symbol in the iscustom flag
|
||||
ustring parseRawSymbol(bool& iscustom);
|
||||
/// Given that the beginning of a concatenation of regexps is ready to
|
||||
/// parse, parse it and it can be optionally be enclosed in parentheses ()
|
||||
LPexp* parseCat();
|
||||
/// Given that a fully qualified group like <.RD'custom'> is ready to parse, parse it
|
||||
LPexp* parseGroup();
|
||||
/// Given that a ^abcde] (note missing [) is ready to parse, parse it
|
||||
LPexp* parseNegor();
|
||||
/// Given that [abcde] is ready to parse, parse it, but if it finds that it was actually
|
||||
/// [^abcd], fall back to parseNegor
|
||||
LPexp* parseOrlist();
|
||||
/// Given that a range like {5,7} or {2,} or {3} is ready to parse, parse it and return
|
||||
/// the range. Second number being -1 if if was {2,} and equals the first if it was {3}
|
||||
std::pair<int, int> parseRange();
|
||||
/// Take an already parsed lpexp and parse its possible modifier (*={}) if present and
|
||||
/// return the new lpexp
|
||||
LPexp* parseModifier(LPexp* e);
|
||||
/// Generic parse whatever comes next (just one item)
|
||||
LPexp* _parse();
|
||||
|
||||
/// Current char being parsed
|
||||
char head()const { return m_text[m_pos]; };
|
||||
/// Any input (including head) left?
|
||||
bool hasInput()const { return m_text.size() > m_pos; };
|
||||
/// Go to the next char in the string
|
||||
void next() { m_pos++; };
|
||||
// error string
|
||||
std::string m_error;
|
||||
// True if we are actually parsing a group <>, since otherwise everything gets
|
||||
// automatically converted to a group, this prevents that happening
|
||||
bool m_ingroup;
|
||||
// maps each basic label to its expected position in the appearance order,
|
||||
// for instance the direction label can't be in the first pos of a group.
|
||||
// This way we know where to put the expression when the user writes just
|
||||
// S, which translates to <..S>
|
||||
SymbolToInt m_label_position;
|
||||
// The set of the basic labels
|
||||
SymbolSet m_basic_labels;
|
||||
// The black list for our wildcards, that have to exclude always the stop mark
|
||||
SymbolSet m_minus_stop;
|
||||
|
||||
/// build the complete pattern for a pathtracing stop
|
||||
///
|
||||
/// That means the three basic label match expressions, plus those for the custom labels (if any),
|
||||
/// plus an additional wildcard to eat extra custom labels at the end, and finally the stop mark.
|
||||
/// So you provide the regexps for the basic three labels:
|
||||
///
|
||||
/// \param etype Event type (CFVL)
|
||||
/// \param dir Direction (RD)
|
||||
/// \param scatter Scattering type (DGSs)
|
||||
///
|
||||
/// That of course can be wildcards or any other expression willing to match them. And then you can
|
||||
/// provide extra expressions to match the custom labels:
|
||||
///
|
||||
/// \param custom Custom label regexps
|
||||
///
|
||||
/// And the function will automatically add a "[^stop_mark]*stop_mark" at the end.
|
||||
///
|
||||
LPexp *buildStop(LPexp *etype, LPexp *scatter, const std::list<LPexp*> &custom);
|
||||
/// Gicen that a symbol is ready in head() to parse, parse it
|
||||
LPexp *parseSymbol();
|
||||
/// Gicen that a symbol is ready in head() to parse, parse it as a ustring
|
||||
/// and report it was a custom symbol in the iscustom flag
|
||||
ustring parseRawSymbol(bool &iscustom);
|
||||
/// Given that the begining of a concatenation of regexps is ready to parse, parse it
|
||||
/// and it can be optionally be enclosed in parentheses ()
|
||||
LPexp *parseCat();
|
||||
/// Given that a fully qualified group like <.RD'custom'> is ready to parse, parse it
|
||||
LPexp *parseGroup();
|
||||
/// Given that a ^abcde] (note missing [) is ready to parse, parse it
|
||||
LPexp *parseNegor();
|
||||
/// Given that [abcde] is ready to parse, parse it, but if it finds that it was actually
|
||||
/// [^abcd], fall back to parseNegor
|
||||
LPexp *parseOrlist();
|
||||
/// Given that a range like {5,7} or {2,} or {3} is ready to parse, parse it and return
|
||||
/// the range. Second number being -1 if if was {2,} and equals the first if it was {3}
|
||||
std::pair<int, int> parseRange();
|
||||
/// Take an already parsed lpexp and parse its possible modifier (*={}) if present and
|
||||
/// return the new lpexp
|
||||
LPexp *parseModifier(LPexp *e);
|
||||
/// Generic parse whatever comes next (just one item)
|
||||
LPexp *_parse();
|
||||
|
||||
// error string
|
||||
std::string m_error;
|
||||
// True if we are actually parsing a group <>, since otherwise everything gets
|
||||
// automatically converted to a group, this prevents that happening
|
||||
bool m_ingroup;
|
||||
// maps each basic label to its expected possition in the appearance order, for instance
|
||||
// the direction label can't be in the first pos of a group. This way we know where to put the
|
||||
// expression when the user writes just S, which translates to <..S>
|
||||
SymbolToInt m_label_position;
|
||||
// The set of the basic labels
|
||||
SymbolSet m_basic_labels;
|
||||
// The black list for our wildcards, that have to exclude always the stop mark
|
||||
SymbolSet m_minus_stop;
|
||||
|
||||
// Current text being parsed
|
||||
std::string m_text;
|
||||
// Current position in the text for head()
|
||||
size_t m_pos;
|
||||
// Current text being parsed
|
||||
std::string m_text;
|
||||
// Current position in the text for head()
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ lpexp::Symbol::genAuto(NdfAutomata& automata) const
|
||||
lpexp::FirstLast
|
||||
lpexp::Wildexp::genAuto(NdfAutomata& automata) const
|
||||
{
|
||||
// Same as the Symbol lpexp but with a wildcard insted of a symbol
|
||||
// Same as the Symbol lpexp but with a wildcard instead of a symbol
|
||||
NdfAutomata::State* begin = automata.newState();
|
||||
NdfAutomata::State* end = automata.newState();
|
||||
begin->addWildcardTransition(new Wildcard(m_wildcard), end);
|
||||
|
||||
+84
-88
@@ -13,17 +13,10 @@ namespace lpexp {
|
||||
|
||||
// This is just a pair of states, see the use of the function genAuto in LPexp
|
||||
// for a justification of this type that we use throughout all the regexp code
|
||||
typedef std::pair<NdfAutomata::State *, NdfAutomata::State *> FirstLast;
|
||||
typedef std::pair<NdfAutomata::State*, NdfAutomata::State*> FirstLast;
|
||||
|
||||
/// LPexp atom type for the getType method
|
||||
typedef enum {
|
||||
CAT,
|
||||
OR,
|
||||
SYMBOL,
|
||||
WILDCARD,
|
||||
REPEAT,
|
||||
NREPEAT
|
||||
}Regtype;
|
||||
typedef enum { CAT, OR, SYMBOL, WILDCARD, REPEAT, NREPEAT } Regtype;
|
||||
|
||||
|
||||
|
||||
@@ -42,56 +35,56 @@ typedef enum {
|
||||
/// NREPEAT Bounded repetition of the child expression like (exp){n,m}
|
||||
///
|
||||
class LPexp {
|
||||
public:
|
||||
virtual ~LPexp() {};
|
||||
public:
|
||||
virtual ~LPexp() {};
|
||||
|
||||
/// Generate automata states for this subtree
|
||||
///
|
||||
/// This method recursively builds all the needed automata states of
|
||||
/// the tree rooted by this node and returns the begin and end states
|
||||
/// for it. That means that if it were the only thing in the automata,
|
||||
/// making retvalue.first initial state and retvalue.second final state,
|
||||
/// would be the right thing to do.
|
||||
///
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const = 0;
|
||||
/// Get the type for this node
|
||||
virtual Regtype getType()const = 0;
|
||||
/// For the parser's convenience. It is easy to implement things like a+
|
||||
/// as aa*. So the amount of regexp classes gets reduced. For doing that
|
||||
/// it needs an abstract clone function
|
||||
virtual LPexp * clone()const = 0;
|
||||
/// Generate automata states for this subtree
|
||||
///
|
||||
/// This method recursively builds all the needed automata states of
|
||||
/// the tree rooted by this node and returns the begin and end states
|
||||
/// for it. That means that if it were the only thing in the automata,
|
||||
/// making retvalue.first initial state and retvalue.second final state,
|
||||
/// would be the right thing to do.
|
||||
///
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const = 0;
|
||||
/// Get the type for this node
|
||||
virtual Regtype getType() const = 0;
|
||||
/// For the parser's convenience. It is easy to implement things like a+
|
||||
/// as aa*. So the amount of regexp classes gets reduced. For doing that
|
||||
/// it needs an abstract clone function
|
||||
virtual LPexp* clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// LPexp concatenation
|
||||
class Cat final : public LPexp {
|
||||
public:
|
||||
virtual ~Cat();
|
||||
void append(LPexp *regexp);
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return CAT; };
|
||||
virtual LPexp * clone()const;
|
||||
public:
|
||||
virtual ~Cat();
|
||||
void append(LPexp* regexp);
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return CAT; };
|
||||
virtual LPexp* clone() const;
|
||||
|
||||
protected:
|
||||
std::list<LPexp *> m_children;
|
||||
protected:
|
||||
std::list<LPexp*> m_children;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Basic symbol like G or 'customlabel'
|
||||
class Symbol final : public LPexp {
|
||||
public:
|
||||
Symbol(ustring sym) { m_sym = sym; };
|
||||
virtual ~Symbol() {};
|
||||
public:
|
||||
Symbol(ustring sym) { m_sym = sym; };
|
||||
virtual ~Symbol() {};
|
||||
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return SYMBOL; };
|
||||
virtual LPexp * clone()const { return new Symbol(*this); };
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return SYMBOL; };
|
||||
virtual LPexp* clone() const { return new Symbol(*this); };
|
||||
|
||||
protected:
|
||||
// All symbols are unique ustrings
|
||||
ustring m_sym;
|
||||
protected:
|
||||
// All symbols are unique ustrings
|
||||
ustring m_sym;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,63 +93,67 @@ class Symbol final : public LPexp {
|
||||
///
|
||||
/// Named like this to avoid confusion with the automata Wildcard class
|
||||
class Wildexp final : public LPexp {
|
||||
public:
|
||||
Wildexp(SymbolSet &minus):m_wildcard(minus) {};
|
||||
virtual ~Wildexp() {};
|
||||
public:
|
||||
Wildexp(SymbolSet& minus) : m_wildcard(minus) {};
|
||||
virtual ~Wildexp() {};
|
||||
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return WILDCARD; };
|
||||
virtual LPexp * clone()const { return new Wildexp(*this); };
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return WILDCARD; };
|
||||
virtual LPexp* clone() const { return new Wildexp(*this); };
|
||||
|
||||
protected:
|
||||
// And internally we use the automata's Wildcard type
|
||||
Wildcard m_wildcard;
|
||||
protected:
|
||||
// And internally we use the automata's Wildcard type
|
||||
Wildcard m_wildcard;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Ored list of expressions
|
||||
class Orlist final : public LPexp {
|
||||
public:
|
||||
virtual ~Orlist();
|
||||
void append(LPexp *regexp);
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return OR; };
|
||||
virtual LPexp * clone()const;
|
||||
public:
|
||||
virtual ~Orlist();
|
||||
void append(LPexp* regexp);
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return OR; };
|
||||
virtual LPexp* clone() const;
|
||||
|
||||
protected:
|
||||
std::list<LPexp *> m_children;
|
||||
protected:
|
||||
std::list<LPexp*> m_children;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Unlimited repeat: (exp)*
|
||||
class Repeat final : public LPexp {
|
||||
public:
|
||||
Repeat(LPexp *child):m_child(child) {};
|
||||
virtual ~Repeat() { delete m_child; };
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return REPEAT; };
|
||||
virtual LPexp * clone()const { return new Repeat(m_child->clone()); };
|
||||
public:
|
||||
Repeat(LPexp* child) : m_child(child) {};
|
||||
virtual ~Repeat() { delete m_child; };
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return REPEAT; };
|
||||
virtual LPexp* clone() const { return new Repeat(m_child->clone()); };
|
||||
|
||||
protected:
|
||||
LPexp *m_child;
|
||||
protected:
|
||||
LPexp* m_child;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Bounded repeat: (exp){m,n}
|
||||
class NRepeat final : public LPexp {
|
||||
public:
|
||||
NRepeat(LPexp *child, int min, int max):m_child(child),m_min(min),m_max(max) {};
|
||||
virtual ~NRepeat() { delete m_child; };
|
||||
virtual FirstLast genAuto(NdfAutomata &automata)const;
|
||||
virtual Regtype getType()const { return NREPEAT; };
|
||||
virtual LPexp * clone()const { return new NRepeat(m_child->clone(), m_min, m_max); };
|
||||
public:
|
||||
NRepeat(LPexp* child, int min, int max)
|
||||
: m_child(child), m_min(min), m_max(max) {};
|
||||
virtual ~NRepeat() { delete m_child; };
|
||||
virtual FirstLast genAuto(NdfAutomata& automata) const;
|
||||
virtual Regtype getType() const { return NREPEAT; };
|
||||
virtual LPexp* clone() const
|
||||
{
|
||||
return new NRepeat(m_child->clone(), m_min, m_max);
|
||||
};
|
||||
|
||||
protected:
|
||||
LPexp *m_child;
|
||||
int m_min, m_max;
|
||||
protected:
|
||||
LPexp* m_child;
|
||||
int m_min, m_max;
|
||||
};
|
||||
|
||||
|
||||
@@ -167,19 +164,18 @@ class NRepeat final : public LPexp {
|
||||
/// a LPexp. It actually binds a light path expression to a certain rule.
|
||||
/// Making the begin state initial and the end state final. It can't be
|
||||
/// nested in other light path expressions, it is the root of the tree.
|
||||
class Rule
|
||||
{
|
||||
public:
|
||||
Rule(LPexp *child, void *rule):m_child(child), m_rule(rule) {};
|
||||
virtual ~Rule() { delete m_child; };
|
||||
void genAuto(NdfAutomata &automata)const;
|
||||
class Rule {
|
||||
public:
|
||||
Rule(LPexp* child, void* rule) : m_child(child), m_rule(rule) {};
|
||||
virtual ~Rule() { delete m_child; };
|
||||
void genAuto(NdfAutomata& automata) const;
|
||||
|
||||
protected:
|
||||
LPexp *m_child;
|
||||
// Anonymous pointer to the associated object for this rule
|
||||
void *m_rule;
|
||||
protected:
|
||||
LPexp* m_child;
|
||||
// Anonymous pointer to the associated object for this rule
|
||||
void* m_rule;
|
||||
};
|
||||
|
||||
} // namespace regexp
|
||||
} // namespace lpexp
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#ifdef __CUDACC__
|
||||
# include <optix.h>
|
||||
#endif
|
||||
|
||||
#include "opcolor.h"
|
||||
|
||||
#include "opcolor_impl.h"
|
||||
@@ -38,6 +34,7 @@ namespace pvt {
|
||||
#define IlluminantE 0.33333333, 0.33333333 /* CIE equal-energy illuminant */
|
||||
#define IlluminantACES 0.32168, 0.33767 /* For ACES, approximate D60 */
|
||||
|
||||
namespace { // anon namespace to avoid duplicate OptiX symbols
|
||||
OSL_CONSTANT_DATA const static ColorSystem::Chroma k_color_systems[13] = {
|
||||
// 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 },
|
||||
@@ -54,6 +51,7 @@ OSL_CONSTANT_DATA const static ColorSystem::Chroma k_color_systems[13] = {
|
||||
/* 11 ACES2065-1 */ { 0.7347, 0.2653, 0.0, 1.0, 0.0001, -0.077, IlluminantACES },
|
||||
/* 12 ACEScg */ { 0.713, 0.293, 0.165, 0.83, 0.128, 0.044, IlluminantACES },
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
+64
-52
@@ -11,10 +11,10 @@
|
||||
///
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <OSL/dual.h>
|
||||
#include <OSL/dual_vec.h>
|
||||
#include <OSL/Imathx/Imathx.h>
|
||||
#include <OSL/device_string.h>
|
||||
#include <OSL/dual.h>
|
||||
#include <OSL/dual_vec.h>
|
||||
|
||||
#include <OpenImageIO/color.h>
|
||||
|
||||
@@ -37,96 +37,107 @@ public:
|
||||
// A colour system is defined by the CIE x and y coordinates of its
|
||||
// three primary illuminants and its white point.
|
||||
struct Chroma {
|
||||
float xRed, yRed,
|
||||
xGreen, yGreen,
|
||||
xBlue, yBlue,
|
||||
xWhite, yWhite;
|
||||
float xRed, yRed, xGreen, yGreen, xBlue, yBlue, xWhite, yWhite;
|
||||
};
|
||||
|
||||
OSL_HOSTDEVICE static const Chroma* fromString(StringParam colorspace);
|
||||
|
||||
/// Convert an XYZ color to RGB in our preferred color space.
|
||||
template <typename T> OSL_HOSTDEVICE T
|
||||
XYZ_to_RGB (const T &XYZ) const { return XYZ * m_XYZ2RGB; }
|
||||
template<typename T> OSL_HOSTDEVICE T XYZ_to_RGB(const T& XYZ) const
|
||||
{
|
||||
return XYZ * m_XYZ2RGB;
|
||||
}
|
||||
|
||||
/// Convert an RGB color in our preferred color space to XYZ.
|
||||
template <typename T> OSL_HOSTDEVICE T
|
||||
RGB_to_XYZ (const T &RGB) const { return RGB * m_RGB2XYZ; }
|
||||
template<typename T> OSL_HOSTDEVICE T RGB_to_XYZ(const T& RGB) const
|
||||
{
|
||||
return RGB * m_RGB2XYZ;
|
||||
}
|
||||
|
||||
/// Return the luminance of an RGB color in the current color space.
|
||||
OSL_HOSTDEVICE float
|
||||
luminance (const Color3 &RGB) const { return RGB.dot(m_luminance_scale); }
|
||||
OSL_HOSTDEVICE float luminance(const Color3& RGB) const
|
||||
{
|
||||
return RGB.dot(m_luminance_scale);
|
||||
}
|
||||
|
||||
/// Return the luminance scale of the current color space.
|
||||
const Color3 & luminance_scale() const { return m_luminance_scale; }
|
||||
const Color3& luminance_scale() const
|
||||
{
|
||||
return m_luminance_scale;
|
||||
}
|
||||
|
||||
/// Return the RGB in the current color space for blackbody radiation
|
||||
/// at temperature T (in Kelvin).
|
||||
OSL_HOSTDEVICE inline Color3
|
||||
blackbody_rgb (float T /*Kelvin*/) const;
|
||||
OSL_HOSTDEVICE inline Color3 blackbody_rgb(float T /*Kelvin*/) const;
|
||||
|
||||
// Interface to access underlying optimized lookup table for blackbody
|
||||
// When can_lookup_blackbody() returns true,
|
||||
// then lookup_blackbody_rgb can be safely called,
|
||||
// otherwise the compute_blackbody_rgb is required.
|
||||
OSL_HOSTDEVICE inline bool
|
||||
can_lookup_blackbody(float T /*Kelvin*/) const;
|
||||
OSL_HOSTDEVICE inline bool can_lookup_blackbody(float T /*Kelvin*/) const;
|
||||
|
||||
OSL_HOSTDEVICE inline Color3
|
||||
lookup_blackbody_rgb (float T /*Kelvin*/) const;
|
||||
OSL_HOSTDEVICE inline Color3 lookup_blackbody_rgb(float T /*Kelvin*/) const;
|
||||
|
||||
// Expensive real computation without lookup table
|
||||
OSL_HOSTDEVICE inline Color3
|
||||
compute_blackbody_rgb (float T /*Kelvin*/) const;
|
||||
OSL_HOSTDEVICE inline Color3 compute_blackbody_rgb(float T /*Kelvin*/) const;
|
||||
|
||||
|
||||
/// Set the current color space.
|
||||
OSL_HOSTDEVICE bool
|
||||
set_colorspace (StringParam colorspace);
|
||||
OSL_HOSTDEVICE bool set_colorspace(StringParam colorspace);
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
to_rgb (StringParam fromspace, const Color3& C, Context) const;
|
||||
OSL_HOSTDEVICE Color3 to_rgb(StringParam fromspace, const Color3& C,
|
||||
Context) const;
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
from_rgb (StringParam fromspace, const Color3& C, Context) const;
|
||||
OSL_HOSTDEVICE Color3 from_rgb(StringParam fromspace, const Color3& C,
|
||||
Context) const;
|
||||
|
||||
OSL_HOSTDEVICE Dual2<Color3>
|
||||
transformc (StringParam fromspace, StringParam tospace,
|
||||
const Dual2<Color3>& color, Context ctx) const;
|
||||
OSL_HOSTDEVICE Dual2<Color3> transformc(StringParam fromspace,
|
||||
StringParam tospace,
|
||||
const Dual2<Color3>& color,
|
||||
Context ctx) const;
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
transformc (StringParam fromspace, StringParam tospace,
|
||||
const Color3& color, Context ctx) const;
|
||||
OSL_HOSTDEVICE Color3 transformc(StringParam fromspace, StringParam tospace,
|
||||
const Color3& color, Context ctx) const;
|
||||
|
||||
OSL_HOSTDEVICE Dual2<Color3>
|
||||
ocio_transform (StringParam fromspace, StringParam tospace, const Dual2<Color3>& C, Context) const;
|
||||
OSL_HOSTDEVICE Dual2<Color3> ocio_transform(StringParam fromspace,
|
||||
StringParam tospace,
|
||||
const Dual2<Color3>& C,
|
||||
Context) const;
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
ocio_transform (StringParam fromspace, StringParam tospace, const Color3& C, Context) const;
|
||||
OSL_HOSTDEVICE Color3 ocio_transform(StringParam fromspace,
|
||||
StringParam tospace, const Color3& C,
|
||||
Context) const;
|
||||
|
||||
|
||||
OSL_HOSTDEVICE const StringParam& colorspace() const { return m_colorspace; }
|
||||
OSL_HOSTDEVICE const StringParam& colorspace() const
|
||||
{
|
||||
return m_colorspace;
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE void error(StringParam src, StringParam dst, Context) const;
|
||||
|
||||
private:
|
||||
template <typename Color> OSL_HOSTDEVICE inline Color
|
||||
transformc (StringParam fromspace, StringParam tospace, const Color& C, Context) const;
|
||||
template<typename Color>
|
||||
OSL_HOSTDEVICE inline Color transformc(StringParam fromspace,
|
||||
StringParam tospace, const Color& C,
|
||||
Context) const;
|
||||
|
||||
template <typename Color> OSL_HOSTDEVICE inline Color
|
||||
ocio_transform (StringParam fromspace, StringParam tospace, const Color& C, Context) const;
|
||||
template<typename Color>
|
||||
OSL_HOSTDEVICE inline Color ocio_transform(StringParam fromspace,
|
||||
StringParam tospace,
|
||||
const Color& C, Context) const;
|
||||
|
||||
|
||||
// Derived/cached calculations from options:
|
||||
Color3 m_Red, m_Green, m_Blue; ///< Color primaries (xyY)
|
||||
Color3 m_White; ///< White point (xyY)
|
||||
Matrix33 m_XYZ2RGB; ///< XYZ to RGB conversion matrix
|
||||
Matrix33 m_RGB2XYZ; ///< RGB to XYZ conversion matrix
|
||||
Color3 m_luminance_scale; ///< Scaling for RGB->luma
|
||||
Color3 m_blackbody_table[317]; ///< Precomputed blackbody table
|
||||
Color3 m_Red, m_Green, m_Blue; ///< Color primaries (xyY)
|
||||
Color3 m_White; ///< White point (xyY)
|
||||
Matrix33 m_XYZ2RGB; ///< XYZ to RGB conversion matrix
|
||||
Matrix33 m_RGB2XYZ; ///< RGB to XYZ conversion matrix
|
||||
Color3 m_luminance_scale; ///< Scaling for RGB->luma
|
||||
Color3 m_blackbody_table[317]; ///< Precomputed blackbody table
|
||||
|
||||
// Keep this last so the CUDA device string can be easily set
|
||||
StringParam m_colorspace; ///< What RGB colors mean
|
||||
StringParam m_colorspace; ///< What RGB colors mean
|
||||
};
|
||||
|
||||
|
||||
@@ -138,9 +149,10 @@ public:
|
||||
ShadingSystemImpl* shadingsys);
|
||||
|
||||
private:
|
||||
const OIIO::ColorConfig& colorconfig (ShadingSystemImpl* shadingsys);
|
||||
const OIIO::ColorConfig& colorconfig(ShadingSystemImpl* shadingsys);
|
||||
|
||||
std::shared_ptr<OIIO::ColorConfig> m_colorconfig; ///< OIIO/OCIO color configuration
|
||||
std::shared_ptr<OIIO::ColorConfig>
|
||||
m_colorconfig; ///< OIIO/OCIO color configuration
|
||||
|
||||
// 1-item cache for the last requested custom color conversion processor
|
||||
OIIO::ColorProcessorHandle m_last_colorproc;
|
||||
@@ -149,7 +161,7 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace pvt
|
||||
} // namespace pvt
|
||||
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
+205
-173
@@ -22,15 +22,16 @@
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
#ifdef __OSL_WIDE_PVT
|
||||
namespace __OSL_WIDE_PVT {
|
||||
namespace __OSL_WIDE_PVT {
|
||||
#else
|
||||
namespace pvt {
|
||||
namespace pvt {
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
OSL_HOSTDEVICE inline void clamp_zero (Color3 &c)
|
||||
OSL_HOSTDEVICE inline void
|
||||
clamp_zero(Color3& c)
|
||||
{
|
||||
if (c.x < 0.0f)
|
||||
c.x = 0.0f;
|
||||
@@ -48,7 +49,13 @@ OSL_HOSTDEVICE inline void clamp_zero (Color3 &c)
|
||||
// cie_colour_match[(lambda - 380) / 5][2] = zBar
|
||||
//OSL_CONSTANT_DATA const float cie_colour_match[81][3] =
|
||||
// Choose to access 1d array vs 2d to allow better code generation of gathers
|
||||
OSL_CONSTANT_DATA const float cie_colour_match[81*3] OSL_ALIGNAS(64) =
|
||||
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
|
||||
{
|
||||
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,
|
||||
@@ -78,21 +85,22 @@ OSL_CONSTANT_DATA const float cie_colour_match[81*3] OSL_ALIGNAS(64) =
|
||||
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
|
||||
} // namespace
|
||||
|
||||
|
||||
// For a given wavelength lambda (in nm), return the XYZ triple giving the
|
||||
// XYZ color corresponding to that single wavelength;
|
||||
OSL_HOSTDEVICE static Color3
|
||||
wavelength_color_XYZ (float lambda_nm)
|
||||
wavelength_color_XYZ(float lambda_nm)
|
||||
{
|
||||
float ii = (lambda_nm-380.0f) / 5.0f; // scaled 0..80
|
||||
int i = (int) ii;
|
||||
float ii = (lambda_nm - 380.0f) / 5.0f; // scaled 0..80
|
||||
int i = (int)ii;
|
||||
// NOTE: bitwise OR to avoid branchiness logical OR introduces.
|
||||
// Also when left as logical OR, vectorizing with clang 11 did not
|
||||
// mask off gathering of out of range index values causing segfaults
|
||||
if ((i < 0) | (i >= 80))
|
||||
return Color3(0.0f,0.0f,0.0f);
|
||||
return Color3(0.0f, 0.0f, 0.0f);
|
||||
float remainder = ii - i;
|
||||
// Do not separate address calculation so that compiler can see that the
|
||||
// base pointer is uniform for all data lanes and 32bit indices can be
|
||||
@@ -101,10 +109,15 @@ wavelength_color_XYZ (float lambda_nm)
|
||||
// Furthermore, have all gathers use the same indices by having different
|
||||
// base registers for each of the 6 components to avoid need to manipulate
|
||||
// indices between gathers.
|
||||
constexpr int stride = sizeof(Color3)/sizeof(float);
|
||||
const int si = stride*i;
|
||||
Color3 XYZ = OIIO::lerp (Color3((cie_colour_match+0)[si], (cie_colour_match+1)[si], (cie_colour_match+2)[si]),
|
||||
Color3((cie_colour_match+3)[si], (cie_colour_match+4)[si], (cie_colour_match+5)[si]), remainder);
|
||||
constexpr int stride = sizeof(Color3) / sizeof(float);
|
||||
const int si = stride * i;
|
||||
Color3 XYZ = OIIO::lerp(Color3((cie_colour_match + 0)[si],
|
||||
(cie_colour_match + 1)[si],
|
||||
(cie_colour_match + 2)[si]),
|
||||
Color3((cie_colour_match + 3)[si],
|
||||
(cie_colour_match + 4)[si],
|
||||
(cie_colour_match + 5)[si]),
|
||||
remainder);
|
||||
#if 0
|
||||
float n = (XYZ.x + XYZ.y + XYZ.z);
|
||||
float n_inv = (n >= 1.0e-6f ? 1.0f/n : 0.0f);
|
||||
@@ -130,27 +143,32 @@ wavelength_color_XYZ (float lambda_nm)
|
||||
// I tuned this a bit, and with the current values we can have all
|
||||
// blackbody results accurate to within 0.1% with a table size of 317
|
||||
// (about 5 KB of data).
|
||||
#define BB_DRAPER 800.0f /* really 798K, below this visible BB is negligible */
|
||||
#define BB_DRAPER 800.0f /* really 798K, below this visible BB is negligible */
|
||||
#define BB_MAX_TABLE_RANGE 12000.0f /* max temp for which we use the table */
|
||||
#define BB_TABLE_XPOWER 1.5f // NOTE: not used, hardcoded into expressions below
|
||||
#define BB_TABLE_YPOWER 5.0f // NOTE: decode is hardcoded
|
||||
#define BB_TABLE_XPOWER \
|
||||
1.5f // NOTE: not used, hardcoded into expressions below
|
||||
#define BB_TABLE_YPOWER 5.0f // NOTE: decode is hardcoded
|
||||
#define BB_TABLE_SPACING 2.0f
|
||||
|
||||
OSL_HOSTDEVICE inline float BB_TABLE_MAP(float i) {
|
||||
OSL_HOSTDEVICE inline float
|
||||
BB_TABLE_MAP(float i)
|
||||
{
|
||||
// return powf (i, BB_TABLE_XPOWER) * BB_TABLE_SPACING + BB_DRAPER;
|
||||
float is = sqrtf(i);
|
||||
float ip = is * is * is; // ^3/2
|
||||
float ip = is * is * is; // ^3/2
|
||||
return ip * BB_TABLE_SPACING + BB_DRAPER;
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE inline float BB_TABLE_UNMAP(float T) {
|
||||
OSL_HOSTDEVICE inline float
|
||||
BB_TABLE_UNMAP(float T)
|
||||
{
|
||||
// return powf ((T - BB_DRAPER) / BB_TABLE_SPACING, 1.0f/BB_TABLE_XPOWER);
|
||||
float t = (T - BB_DRAPER) / BB_TABLE_SPACING;
|
||||
float t = (T - BB_DRAPER) / BB_TABLE_SPACING;
|
||||
// Clang doesn't have vectorizing version of cbrtf,
|
||||
// so use OIIO's instead
|
||||
float ic = OIIO::fast_cbrt(t);
|
||||
|
||||
return ic * ic; // ^2/3
|
||||
return ic * ic; // ^2/3
|
||||
}
|
||||
|
||||
|
||||
@@ -173,26 +191,31 @@ OSL_HOSTDEVICE inline float BB_TABLE_UNMAP(float T) {
|
||||
// W/m^2 in the range [wavelength,wavelength+dwavelength].
|
||||
class bb_spectrum {
|
||||
public:
|
||||
OSL_HOSTDEVICE bb_spectrum (float temperature=5000) : m_temp(temperature) { }
|
||||
OSL_HOSTDEVICE bb_spectrum(float temperature = 5000) : m_temp(temperature)
|
||||
{
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE float operator() (float wavelength_nm) const {
|
||||
OSL_HOSTDEVICE float operator()(float wavelength_nm) const
|
||||
{
|
||||
// Testing showed < .0000534058f differences between single and double
|
||||
// precision. So choose to perform math using single precision.
|
||||
float wlm = wavelength_nm * 1e-9f; // Wavelength in meters
|
||||
const float c1 = 3.74183e-16f; // 2*pi*h*c^2, W*m^2
|
||||
const float c2 = 1.4388e-2f; // h*c/k, m*K
|
||||
// h is Planck's const, k is Boltzmann's
|
||||
float wlm = wavelength_nm * 1e-9f; // Wavelength in meters
|
||||
const float c1 = 3.74183e-16f; // 2*pi*h*c^2, W*m^2
|
||||
const float c2 = 1.4388e-2f; // h*c/k, m*K
|
||||
// h is Planck's const, k is Boltzmann's
|
||||
//const float inverse_of_wlm5 = std::pow(wlm,-5.0f);
|
||||
// Rather than calling powf, just implement exact power and inverse
|
||||
// directly here. Confirmed with ICC that identical optimized assembly
|
||||
// is produced to std::powf and more SIMD friendly to other compilers.
|
||||
const float wlm2 = wlm*wlm;
|
||||
const float wlm4 = wlm2*wlm2;
|
||||
const float wlm5 = wlm4*wlm;
|
||||
const float inverse_of_wlm5 = 1.0f/wlm5;
|
||||
const float wlm2 = wlm * wlm;
|
||||
const float wlm4 = wlm2 * wlm2;
|
||||
const float wlm5 = wlm4 * wlm;
|
||||
const float inverse_of_wlm5 = 1.0f / wlm5;
|
||||
// Clang doesn't have vectorizing version of expm1, so use OIIO::fast_expm1
|
||||
return float((c1 * inverse_of_wlm5) / OIIO::fast_expm1(c2 / (wlm * m_temp)));
|
||||
return float((c1 * inverse_of_wlm5)
|
||||
/ OIIO::fast_expm1(c2 / (wlm * m_temp)));
|
||||
}
|
||||
|
||||
private:
|
||||
float m_temp;
|
||||
};
|
||||
@@ -200,9 +223,9 @@ private:
|
||||
|
||||
// Integrate the CIE color matching values, weighted by function
|
||||
// spec_intens(lambda_nm), returning the aggregate XYZ color.
|
||||
template<class SPECTRUM> OSL_HOSTDEVICE
|
||||
static Color3
|
||||
spectrum_to_XYZ (const SPECTRUM &spec_intens)
|
||||
template<class SPECTRUM>
|
||||
OSL_HOSTDEVICE static Color3
|
||||
spectrum_to_XYZ(const SPECTRUM& spec_intens)
|
||||
{
|
||||
float X = 0, Y = 0, Z = 0;
|
||||
const float dlambda = 5.0f * 1e-9; // in meters
|
||||
@@ -210,80 +233,81 @@ spectrum_to_XYZ (const SPECTRUM &spec_intens)
|
||||
float lambda = 380.0f + 5.0f * i;
|
||||
// N.B. spec_intens returns result in W/m^2 but it's a differential,
|
||||
// needs to be scaled by dlambda!
|
||||
float Me = spec_intens(lambda) * dlambda;
|
||||
constexpr int stride = sizeof(Color3)/sizeof(float);
|
||||
const int si = stride*i;
|
||||
float Me = spec_intens(lambda) * dlambda;
|
||||
constexpr int stride = sizeof(Color3) / sizeof(float);
|
||||
const int si = stride * i;
|
||||
X += Me * (cie_colour_match + 0)[si];
|
||||
Y += Me * (cie_colour_match + 1)[si];
|
||||
Z += Me * (cie_colour_match + 2)[si];
|
||||
}
|
||||
return Color3 (X, Y, Z);
|
||||
return Color3(X, Y, Z);
|
||||
}
|
||||
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
hsv_to_rgb (const COLOR3& hsv)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
hsv_to_rgb(const COLOR3& hsv)
|
||||
{
|
||||
// Reference for this technique: Foley & van Dam
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
FLOAT h = comp_x(hsv), s = comp_y(hsv), v = comp_z(hsv);
|
||||
if (s < 0.0001f) {
|
||||
return make_Color3 (v, v, v);
|
||||
return make_Color3(v, v, v);
|
||||
} else {
|
||||
using std::floor; // to pick up the float one
|
||||
using OIIO::ifloor;
|
||||
h = 6.0f * (h - floor(h)); // expand to [0..6)
|
||||
int hi = ifloor(h);
|
||||
using std::floor; // to pick up the float one
|
||||
h = 6.0f * (h - floor(h)); // expand to [0..6)
|
||||
int hi = ifloor(h);
|
||||
FLOAT f = h - FLOAT(hi);
|
||||
FLOAT p = v * (1.0f-s);
|
||||
FLOAT q = v * (1.0f-s*f);
|
||||
FLOAT t = v * (1.0f-s*(1.0f-f));
|
||||
FLOAT p = v * (1.0f - s);
|
||||
FLOAT q = v * (1.0f - s * f);
|
||||
FLOAT t = v * (1.0f - s * (1.0f - f));
|
||||
#ifdef __OSL_WIDE_PVT
|
||||
// Avoid switch statement vectorizor doesn't like
|
||||
// Also avoid if/else nest which some optimizers might
|
||||
// convert back into a switch statement
|
||||
# if OSL_ANY_CLANG && !OSL_INTEL_CLASSIC_COMPILER_VERSION && !OSL_INTEL_LLVM_COMPILER_VERSION
|
||||
# if OSL_ANY_CLANG && !OSL_INTEL_CLASSIC_COMPILER_VERSION \
|
||||
&& !OSL_INTEL_LLVM_COMPILER_VERSION
|
||||
// Clang was still transforming series of if's back into a switch.
|
||||
// Alternate between == and <= comparisons to avoid
|
||||
# define __OSL_ASC_EQ <=
|
||||
# else
|
||||
# define __OSL_ASC_EQ ==
|
||||
# endif
|
||||
# define __OSL_ASC_EQ <=
|
||||
# else
|
||||
# define __OSL_ASC_EQ ==
|
||||
# endif
|
||||
if (hi == 0) {
|
||||
return make_Color3 (v, t, p);
|
||||
return make_Color3(v, t, p);
|
||||
}
|
||||
if (hi __OSL_ASC_EQ 1) {
|
||||
return make_Color3 (q, v, p);
|
||||
return make_Color3(q, v, p);
|
||||
}
|
||||
if (hi == 2) {
|
||||
return make_Color3 (p, v, t);
|
||||
return make_Color3(p, v, t);
|
||||
}
|
||||
if (hi __OSL_ASC_EQ 3) {
|
||||
return make_Color3 (p, q, v);
|
||||
return make_Color3(p, q, v);
|
||||
}
|
||||
if (hi == 4) {
|
||||
return make_Color3 (t, p, v);
|
||||
return make_Color3(t, p, v);
|
||||
}
|
||||
return make_Color3 (v, p, q);
|
||||
return make_Color3(v, p, q);
|
||||
# undef __OSL_ASC_EQ
|
||||
#else
|
||||
// serial execution might be faster with switch
|
||||
switch (hi) {
|
||||
case 0 : return make_Color3 (v, t, p);
|
||||
case 1 : return make_Color3 (q, v, p);
|
||||
case 2 : return make_Color3 (p, v, t);
|
||||
case 3 : return make_Color3 (p, q, v);
|
||||
case 4 : return make_Color3 (t, p, v);
|
||||
default: return make_Color3 (v, p, q);
|
||||
case 0: return make_Color3(v, t, p);
|
||||
case 1: return make_Color3(q, v, p);
|
||||
case 2: return make_Color3(p, v, t);
|
||||
case 3: return make_Color3(p, q, v);
|
||||
case 4: return make_Color3(t, p, v);
|
||||
default: return make_Color3(v, p, q);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static inline COLOR3
|
||||
rgb_to_hsv (const COLOR3& rgb)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static inline COLOR3
|
||||
rgb_to_hsv(const COLOR3& rgb)
|
||||
{
|
||||
// See Foley & van Dam
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
@@ -291,17 +315,16 @@ rgb_to_hsv (const COLOR3& rgb)
|
||||
// NOTE: use sfm::min_val and sfm::max_val instead of std::min and
|
||||
// std::max which return references
|
||||
// that can interfere with vectorization
|
||||
FLOAT mincomp = sfm::min_val (r, sfm::min_val (g, b));
|
||||
FLOAT maxcomp = sfm::max_val (r, sfm::max_val (g, b));
|
||||
FLOAT delta = maxcomp - mincomp; // chroma
|
||||
FLOAT v = maxcomp;
|
||||
FLOAT s = 0.0f;
|
||||
FLOAT mincomp = sfm::min_val(r, sfm::min_val(g, b));
|
||||
FLOAT maxcomp = sfm::max_val(r, sfm::max_val(g, b));
|
||||
FLOAT delta = maxcomp - mincomp; // chroma
|
||||
FLOAT v = maxcomp;
|
||||
FLOAT s = 0.0f;
|
||||
if (maxcomp > 0.0f)
|
||||
s = delta / maxcomp;
|
||||
FLOAT h = 0.0f;
|
||||
if (s > 0.0f)
|
||||
{
|
||||
#if 0 // Reference version
|
||||
if (s > 0.0f) {
|
||||
#if 0 // Reference version
|
||||
if (r >= maxcomp) h = (g-b) / delta;
|
||||
else if (g >= maxcomp) h = 2.0f + (b-r) / delta;
|
||||
else h = 4.0f + (r-g) / delta;
|
||||
@@ -314,57 +337,67 @@ rgb_to_hsv (const COLOR3& rgb)
|
||||
// which was already going to be a divisor.
|
||||
float k;
|
||||
FLOAT x, y;
|
||||
if (r >= maxcomp) { k = 0.0f/6.0f; x = g; y = b; }
|
||||
else if (g >= maxcomp) { k = 2.0f/6.0f; x = b; y = r; }
|
||||
else { k = 4.0f/6.0f; x = r; y = g; }
|
||||
h = k + (x-y) / (6.0f*delta);
|
||||
if (r >= maxcomp) {
|
||||
k = 0.0f / 6.0f;
|
||||
x = g;
|
||||
y = b;
|
||||
} else if (g >= maxcomp) {
|
||||
k = 2.0f / 6.0f;
|
||||
x = b;
|
||||
y = r;
|
||||
} else {
|
||||
k = 4.0f / 6.0f;
|
||||
x = r;
|
||||
y = g;
|
||||
}
|
||||
h = k + (x - y) / (6.0f * delta);
|
||||
#endif
|
||||
if (h < 0.0f)
|
||||
h += 1.0f;
|
||||
}
|
||||
return make_Color3 (h, s, v);
|
||||
return make_Color3(h, s, v);
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
hsl_to_rgb (const COLOR3& hsl)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
hsl_to_rgb(const COLOR3& hsl)
|
||||
{
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
FLOAT h = comp_x(hsl), s = comp_y(hsl), l = comp_z(hsl);
|
||||
// Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
|
||||
FLOAT v = (l <= 0.5f) ? (l * (1.0f + s)) : (l * (1.0f - s) + s);
|
||||
if (v <= 0.0f) {
|
||||
return make_Color3 (0.0f, 0.0f, 0.0f);
|
||||
return make_Color3(0.0f, 0.0f, 0.0f);
|
||||
} else {
|
||||
FLOAT min = 2.0f * l - v;
|
||||
s = (v - min) / v;
|
||||
return hsv_to_rgb (make_Color3(h, s, v));
|
||||
s = (v - min) / v;
|
||||
return hsv_to_rgb(make_Color3(h, s, v));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
rgb_to_hsl (const COLOR3& rgb)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
rgb_to_hsl(const COLOR3& rgb)
|
||||
{
|
||||
// See Foley & van Dam
|
||||
// First convert rgb to hsv, then to hsl
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
// NOTE: use sfm::min_val instead of std::min which returns references
|
||||
// that can interfere with vectorization
|
||||
FLOAT minval = sfm::min_val (comp_x(rgb), sfm::min_val (comp_y(rgb), comp_z(rgb)));
|
||||
COLOR3 hsv = rgb_to_hsv (rgb);
|
||||
FLOAT maxval = comp_z(hsv); // v == maxval
|
||||
FLOAT h = comp_x(hsv), s, l = (minval+maxval) / 2.0f;
|
||||
if (equalVal (minval, maxval))
|
||||
FLOAT minval = sfm::min_val(comp_x(rgb),
|
||||
sfm::min_val(comp_y(rgb), comp_z(rgb)));
|
||||
COLOR3 hsv = rgb_to_hsv(rgb);
|
||||
FLOAT maxval = comp_z(hsv); // v == maxval
|
||||
FLOAT h = comp_x(hsv), s, l = (minval + maxval) / 2.0f;
|
||||
if (equalVal(minval, maxval))
|
||||
s = 0.0f; // special 'achromatic' case, hue is 0
|
||||
#if 0 // reference version
|
||||
#if 0 // reference version
|
||||
else if (l <= 0.5f)
|
||||
s = (maxval - minval) / (maxval + minval);
|
||||
else
|
||||
s = (maxval - minval) / (2.0f - maxval - minval)
|
||||
#else
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Share computation of min2max and divide vs. repeating in 2 branches
|
||||
// which both could execute masked
|
||||
FLOAT min2max = (maxval - minval);
|
||||
@@ -376,90 +409,90 @@ rgb_to_hsl (const COLOR3& rgb)
|
||||
s = min2max / divisor;
|
||||
}
|
||||
#endif
|
||||
return make_Color3 (h, s, l);
|
||||
return make_Color3(h, s, l);
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
YIQ_to_rgb (const COLOR3& YIQ)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
YIQ_to_rgb(const COLOR3& YIQ)
|
||||
{
|
||||
return YIQ * Matrix33(1.0000, 1.0000, 1.0000,
|
||||
0.9557, -0.2716, -1.1082,
|
||||
0.6199, -0.6469, 1.7051);
|
||||
return YIQ
|
||||
* Matrix33(1.0000, 1.0000, 1.0000, 0.9557, -0.2716, -1.1082, 0.6199,
|
||||
-0.6469, 1.7051);
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
rgb_to_YIQ (const COLOR3& rgb)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
rgb_to_YIQ(const COLOR3& rgb)
|
||||
{
|
||||
return rgb * Matrix33(0.299, 0.596, 0.212,
|
||||
0.587, -0.275, -0.523,
|
||||
0.114, -0.321, 0.311);
|
||||
return rgb
|
||||
* Matrix33(0.299, 0.596, 0.212, 0.587, -0.275, -0.523, 0.114, -0.321,
|
||||
0.311);
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
XYZ_to_xyY (const COLOR3 &XYZ)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
XYZ_to_xyY(const COLOR3& XYZ)
|
||||
{
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
FLOAT n = (comp_x(XYZ) + comp_y(XYZ) + comp_z(XYZ));
|
||||
FLOAT n_inv = (n >= 1.0e-6f ? 1.0f/n : 0.0f);
|
||||
return make_Color3 (comp_x(XYZ)*n_inv, comp_y(XYZ)*n_inv, comp_y(XYZ));
|
||||
FLOAT n = (comp_x(XYZ) + comp_y(XYZ) + comp_z(XYZ));
|
||||
FLOAT n_inv = (n >= 1.0e-6f ? 1.0f / n : 0.0f);
|
||||
return make_Color3(comp_x(XYZ) * n_inv, comp_y(XYZ) * n_inv, comp_y(XYZ));
|
||||
// N.B. http://brucelindbloom.com/ suggests returning xy of the
|
||||
// reference white in the X+Y+Z==0 case.
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
xyY_to_XYZ (const COLOR3 &xyY)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
xyY_to_XYZ(const COLOR3& xyY)
|
||||
{
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
FLOAT Y = comp_z(xyY);
|
||||
FLOAT Y_y = (comp_y(xyY) > 1.0e-6f ? Y/comp_y(xyY) : 0.0f);
|
||||
FLOAT X = Y_y * comp_x(xyY);
|
||||
FLOAT Z = Y_y * (1.0f - comp_x(xyY) - comp_y(xyY));
|
||||
return make_Color3 (X, Y, Z);
|
||||
FLOAT Y = comp_z(xyY);
|
||||
FLOAT Y_y = (comp_y(xyY) > 1.0e-6f ? Y / comp_y(xyY) : 0.0f);
|
||||
FLOAT X = Y_y * comp_x(xyY);
|
||||
FLOAT Z = Y_y * (1.0f - comp_x(xyY) - comp_y(xyY));
|
||||
return make_Color3(X, Y, Z);
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
sRGB_to_linear (const COLOR3& srgb)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
sRGB_to_linear(const COLOR3& srgb)
|
||||
{
|
||||
// See Foley & van Dam
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
using namespace OIIO;
|
||||
//using safe_pow = std::conditional<is_Dual<COLOR3>::value, OSL::safe_pow, OIIO::safe_pow>::type;
|
||||
FLOAT r = comp_x(srgb), g = comp_y(srgb), b = comp_z(srgb);
|
||||
auto convert = [] (FLOAT x) -> FLOAT {
|
||||
return (x <= 0.04045f) ?
|
||||
(x * (1.0f / 12.92f)) :
|
||||
safe_pow((x + 0.055f) * (1.0f / 1.055f), FLOAT(2.4f));
|
||||
auto convert = [](FLOAT x) -> FLOAT {
|
||||
return (x <= 0.04045f)
|
||||
? (x * (1.0f / 12.92f))
|
||||
: safe_pow((x + 0.055f) * (1.0f / 1.055f), FLOAT(2.4f));
|
||||
};
|
||||
return make_Color3 (convert(r), convert(g), convert(b));
|
||||
return make_Color3(convert(r), convert(g), convert(b));
|
||||
}
|
||||
|
||||
template <typename COLOR3> OSL_HOSTDEVICE
|
||||
static COLOR3
|
||||
linear_to_sRGB (const COLOR3& rgb)
|
||||
template<typename COLOR3>
|
||||
OSL_HOSTDEVICE static COLOR3
|
||||
linear_to_sRGB(const COLOR3& rgb)
|
||||
{
|
||||
// See Foley & van Dam
|
||||
using FLOAT = typename ScalarFromVec<COLOR3>::type;
|
||||
using namespace OIIO;
|
||||
//using safe_pow = std::conditional<is_Dual<COLOR3>::value, OSL::safe_pow, OIIO::safe_pow>::type;
|
||||
FLOAT r = comp_x(rgb), g = comp_y(rgb), b = comp_z(rgb);
|
||||
auto convert = [] (FLOAT x) -> FLOAT {
|
||||
return (x <= 0.0031308f) ?
|
||||
(12.92f * x) :
|
||||
(1.055f * safe_pow(x, FLOAT(1.f / 2.4f)) - 0.055f);
|
||||
auto convert = [](FLOAT x) -> FLOAT {
|
||||
return (x <= 0.0031308f)
|
||||
? (12.92f * x)
|
||||
: (1.055f * safe_pow(x, FLOAT(1.f / 2.4f)) - 0.055f);
|
||||
};
|
||||
|
||||
return make_Color3 (convert(r), convert(g), convert(b));
|
||||
return make_Color3(convert(r), convert(g), convert(b));
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE inline Color3
|
||||
colpow (const Color3 &c, float p)
|
||||
colpow(const Color3& c, float p)
|
||||
{
|
||||
return Color3 (powf(c.x,p), powf(c.y,p), powf(c.z,p));
|
||||
return Color3(powf(c.x, p), powf(c.y, p), powf(c.z, p));
|
||||
}
|
||||
|
||||
} // namespace __OSL_WIDE_PVT or pvt
|
||||
@@ -468,11 +501,11 @@ namespace pvt {
|
||||
|
||||
|
||||
#ifdef __OSL_WIDE_PVT
|
||||
using __OSL_WIDE_PVT::clamp_zero;
|
||||
using __OSL_WIDE_PVT::bb_spectrum;
|
||||
using __OSL_WIDE_PVT::spectrum_to_XYZ;
|
||||
using __OSL_WIDE_PVT::BB_TABLE_MAP;
|
||||
using __OSL_WIDE_PVT::BB_TABLE_UNMAP;
|
||||
using __OSL_WIDE_PVT::bb_spectrum;
|
||||
using __OSL_WIDE_PVT::BB_TABLE_MAP;
|
||||
using __OSL_WIDE_PVT::BB_TABLE_UNMAP;
|
||||
using __OSL_WIDE_PVT::clamp_zero;
|
||||
using __OSL_WIDE_PVT::spectrum_to_XYZ;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -483,15 +516,15 @@ ColorSystem::can_lookup_blackbody(float T /*Kelvin*/) const
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
ColorSystem::lookup_blackbody_rgb (float T /*Kelvin*/) const
|
||||
ColorSystem::lookup_blackbody_rgb(float T /*Kelvin*/) const
|
||||
{
|
||||
if (T < BB_DRAPER)
|
||||
return Color3(1.0e-6f,0.0f,0.0f); // very very dim red
|
||||
return Color3(1.0e-6f, 0.0f, 0.0f); // very very dim red
|
||||
|
||||
// can_lookup_blackbody() should have checked before now
|
||||
OSL_DASSERT(T < BB_MAX_TABLE_RANGE);
|
||||
float t = BB_TABLE_UNMAP(T);
|
||||
int ti = static_cast<int>(t);
|
||||
float t = BB_TABLE_UNMAP(T);
|
||||
int ti = static_cast<int>(t);
|
||||
float remainder = t - ti;
|
||||
#ifdef __OSL_WIDE_PVT
|
||||
// Choose to access Color3 lookup table as 3 float components.
|
||||
@@ -500,40 +533,40 @@ ColorSystem::lookup_blackbody_rgb (float T /*Kelvin*/) const
|
||||
// dereferencing Color3 which was using 64bit gathers which can take
|
||||
// multiple registers to hold the 64bit offsets and multiple gather
|
||||
// instructions who's results need to be merged into a single register.
|
||||
const float *blackbody_components = reinterpret_cast<const float *>(m_blackbody_table);
|
||||
constexpr int stride = sizeof(Color3)/sizeof(float);
|
||||
int sti = stride*ti;
|
||||
Color3 rgb = OIIO::lerp (
|
||||
// Have all gathers use the same indices by having different base registers
|
||||
const float* blackbody_components = reinterpret_cast<const float*>(
|
||||
m_blackbody_table);
|
||||
constexpr int stride = sizeof(Color3) / sizeof(float);
|
||||
int sti = stride * ti;
|
||||
Color3 rgb = OIIO::lerp(
|
||||
// Have all gathers use the same indices by having different base registers
|
||||
// for each of the 6 components
|
||||
Color3((blackbody_components+0)[sti],
|
||||
(blackbody_components+1)[sti],
|
||||
(blackbody_components+2)[sti]),
|
||||
Color3((blackbody_components+3)[sti],
|
||||
(blackbody_components+4)[sti],
|
||||
(blackbody_components+5)[sti]),
|
||||
remainder);
|
||||
Color3((blackbody_components + 0)[sti], (blackbody_components + 1)[sti],
|
||||
(blackbody_components + 2)[sti]),
|
||||
Color3((blackbody_components + 3)[sti], (blackbody_components + 4)[sti],
|
||||
(blackbody_components + 5)[sti]),
|
||||
remainder);
|
||||
#else
|
||||
Color3 rgb = OIIO::lerp (m_blackbody_table[ti], m_blackbody_table[ti+1], remainder);
|
||||
Color3 rgb = OIIO::lerp(m_blackbody_table[ti], m_blackbody_table[ti + 1],
|
||||
remainder);
|
||||
#endif
|
||||
//return colpow(rgb, BB_TABLE_YPOWER);
|
||||
Color3 rgb2 = rgb * rgb;
|
||||
Color3 rgb4 = rgb2 * rgb2;
|
||||
return rgb4 * rgb; // ^5
|
||||
return rgb4 * rgb; // ^5
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
ColorSystem::compute_blackbody_rgb (float T /*Kelvin*/) const
|
||||
ColorSystem::compute_blackbody_rgb(float T /*Kelvin*/) const
|
||||
{
|
||||
// compute for real
|
||||
bb_spectrum spec (T);
|
||||
Color3 rgb = XYZ_to_RGB (spectrum_to_XYZ (spec));
|
||||
clamp_zero (rgb);
|
||||
bb_spectrum spec(T);
|
||||
Color3 rgb = XYZ_to_RGB(spectrum_to_XYZ(spec));
|
||||
clamp_zero(rgb);
|
||||
return rgb;
|
||||
}
|
||||
|
||||
OSL_HOSTDEVICE Color3
|
||||
ColorSystem::blackbody_rgb (float T) const
|
||||
ColorSystem::blackbody_rgb(float T) const
|
||||
{
|
||||
if (can_lookup_blackbody(T)) {
|
||||
return lookup_blackbody_rgb(T);
|
||||
@@ -544,4 +577,3 @@ ColorSystem::blackbody_rgb (float T) const
|
||||
|
||||
} // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ osl_getmessage(ShaderGlobals* sg, const char* source_, const char* name_,
|
||||
sg->context->errorfmt(
|
||||
"message \"{}\" was set by layer #{} ({}:{})"
|
||||
" but is being queried by layer #{} ({}:{})"
|
||||
" - messages may only be transfered from nodes "
|
||||
" - messages may only be transferred from nodes "
|
||||
"that appear earlier in the shading network",
|
||||
name, m->layeridx, m->sourcefile, m->sourceline, layeridx,
|
||||
sourcefile, sourceline);
|
||||
|
||||
@@ -224,7 +224,7 @@ osl_texture(void* sg_, const char* name, void* handle, void* opt_, float s,
|
||||
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::float4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd;
|
||||
bool ok = sg->renderer->texture(
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(), *opt, sg, s, t, dsdx, dtdx, dsdy,
|
||||
@@ -240,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::float4 dresultdx_simd = dresultds_simd * dsdx
|
||||
+ dresultdt_simd * dtdx;
|
||||
OIIO::simd::float4 dresultdy_simd = dresultds_simd * dsdy
|
||||
+ dresultdt_simd * dtdy;
|
||||
OIIO::simd::vfloat4 dresultdx_simd = dresultds_simd * dsdx
|
||||
+ dresultdt_simd * dtdx;
|
||||
OIIO::simd::vfloat4 dresultdy_simd = dresultds_simd * dsdy
|
||||
+ dresultdt_simd * dtdy;
|
||||
if (dresultdx) {
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)dresultdx)[i] = dresultdx_simd[i];
|
||||
@@ -281,7 +281,7 @@ 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::float4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
OIIO::simd::vfloat4 result_simd, dresultds_simd, dresultdt_simd,
|
||||
dresultdr_simd;
|
||||
bool ok = sg->renderer->texture3d(
|
||||
USTR(name), (TextureSystem::TextureHandle*)handle,
|
||||
@@ -297,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::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;
|
||||
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;
|
||||
if (dresultdx) {
|
||||
for (int i = 0; i < chans; ++i)
|
||||
((float*)dresultdx)[i] = dresultdx_simd[i];
|
||||
@@ -335,7 +335,7 @@ 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::float4 local_result;
|
||||
OIIO::simd::vfloat4 local_result;
|
||||
bool ok = sg->renderer->environment(USTR(name),
|
||||
(TextureSystem::TextureHandle*)handle,
|
||||
sg->context->texture_thread_info(),
|
||||
|
||||
+1237
-946
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,10 @@
|
||||
#pragma clang diagnostic ignored "-Wparentheses-equality"
|
||||
#endif
|
||||
|
||||
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC visibility push(hidden)
|
||||
#endif
|
||||
|
||||
+2
-21
@@ -288,7 +288,8 @@ public:
|
||||
}
|
||||
|
||||
// TODO: This is really the only part of parsing that needs the lock still.
|
||||
// But the calling code setting locale complicates this.
|
||||
// The calling code no longer sets the global locale, so it would
|
||||
// likely be simple to clean this up.
|
||||
//
|
||||
bool parse(OSOReader* reader, const char* what) {
|
||||
yy_switch_to_buffer(m_buffer, m_scanner);
|
||||
@@ -310,12 +311,6 @@ OSOReader::parse_file (const std::string &filename)
|
||||
// can actually be reading a .oso file at a time.
|
||||
std::lock_guard<std::mutex> guard (osoread_mutex);
|
||||
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
std::locale oldlocale; // save the previous native locale
|
||||
std::locale::global (std::locale::classic());
|
||||
|
||||
FILE* osoin = OIIO::Filesystem::fopen (filename, "r");
|
||||
if (! osoin) {
|
||||
m_err.errorfmt("File {} not found", filename);
|
||||
@@ -326,7 +321,6 @@ OSOReader::parse_file (const std::string &filename)
|
||||
bool ok = scope.parse(this, filename.c_str());
|
||||
|
||||
fclose (osoin);
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -339,22 +333,9 @@ OSOReader::parse_memory (const std::string &buffer)
|
||||
// can actually be reading a .oso file at a time.
|
||||
std::lock_guard<std::mutex> guard (osoread_mutex);
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
// Force classic "C" locale for correct '.' decimal parsing.
|
||||
// N.B. This is not safe in a multi-threaded program where another
|
||||
// application thread is expecting the native locale to work properly.
|
||||
// This is not necessary for versions of OIIO that have Strutil::stof,
|
||||
// and we can remove it entirely when OIIO 1.9 is the minimum.
|
||||
std::locale oldlocale = std::locale::global (std::locale::classic());
|
||||
#endif
|
||||
|
||||
Scope scope(buffer);
|
||||
bool ok = scope.parse(this, "preloaded OSO code");
|
||||
|
||||
#ifndef OIIO_STRUTIL_HAS_STOF
|
||||
std::locale::global (oldlocale); // Restore the original locale.
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
+33
-33
@@ -4,11 +4,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OSL/platform.h>
|
||||
#include "osl_pvt.h"
|
||||
#include <OSL/platform.h>
|
||||
|
||||
#include <OpenImageIO/thread.h>
|
||||
#include <OpenImageIO/string_view.h>
|
||||
#include <OpenImageIO/thread.h>
|
||||
|
||||
|
||||
|
||||
@@ -26,107 +26,107 @@ OSL_GCC_PRAGMA(GCC diagnostic ignored "-Wunused-parameter")
|
||||
///
|
||||
class OSOReader {
|
||||
public:
|
||||
OSOReader (ErrorHandler *errhandler = NULL)
|
||||
: m_err (errhandler ? *errhandler : ErrorHandler::default_handler()),
|
||||
m_lineno(1)
|
||||
{ }
|
||||
virtual ~OSOReader () { }
|
||||
OSOReader(ErrorHandler* errhandler = NULL)
|
||||
: m_err(errhandler ? *errhandler : ErrorHandler::default_handler())
|
||||
, m_lineno(1)
|
||||
{
|
||||
}
|
||||
virtual ~OSOReader() {}
|
||||
|
||||
/// Read in the oso file, parse it, call the various callbacks.
|
||||
/// Return true if the file was correctly parsed, false if there was
|
||||
/// an unrecoverable error reading the file.
|
||||
virtual bool parse_file (const std::string &filename);
|
||||
virtual bool parse_file(const std::string& filename);
|
||||
|
||||
/// Read in OSO from memory, parse, call the various callbacks.
|
||||
/// Return true if the OSO code was correctly parsed, false if there was
|
||||
/// an unrecoverable error reading.
|
||||
virtual bool parse_memory (const std::string &buffer);
|
||||
virtual bool parse_memory(const std::string& buffer);
|
||||
|
||||
/// Declare the shader version.
|
||||
///
|
||||
virtual void version (const char *specid, int major, int minor) { }
|
||||
virtual void version(const char* specid, int major, int minor) {}
|
||||
|
||||
/// Set the name and type of the shader
|
||||
///
|
||||
virtual void shader (const char *shadertype, const char *name) { }
|
||||
virtual void shader(const char* shadertype, const char* name) {}
|
||||
|
||||
/// Register a new symbol.
|
||||
///
|
||||
virtual void symbol (SymType symtype, TypeSpec typespec, const char *name)
|
||||
{ }
|
||||
virtual void symbol(SymType symtype, TypeSpec typespec, const char* name) {}
|
||||
|
||||
/// Add a default integer value to the last declared symbol.
|
||||
///
|
||||
virtual void symdefault (int def) { }
|
||||
virtual void symdefault(int def) {}
|
||||
|
||||
/// Add a default float value to the last declared symbol.
|
||||
///
|
||||
virtual void symdefault (float def) { }
|
||||
virtual void symdefault(float def) {}
|
||||
|
||||
/// Add a default string value to the last declared symbol.
|
||||
///
|
||||
virtual void symdefault (const char *def) { }
|
||||
virtual void symdefault(const char* def) {}
|
||||
|
||||
/// Called when we're done with all information related to a parameter
|
||||
/// symbol.
|
||||
virtual void parameter_done () { }
|
||||
virtual void parameter_done() {}
|
||||
|
||||
/// Return true for parsers whose only purpose is to read the header up
|
||||
/// to params, to stop parsing as soon as we start encountering temps in
|
||||
/// the symbol table.
|
||||
virtual bool stop_parsing_at_temp_symbols () { return false; }
|
||||
virtual bool stop_parsing_at_temp_symbols() { return false; }
|
||||
|
||||
/// Add a hint.
|
||||
///
|
||||
virtual void hint (string_view hintstring) { }
|
||||
virtual void hint(string_view hintstring) {}
|
||||
|
||||
/// Return true if this parser cares about the code, false if parsing
|
||||
/// of oso may terminate once the symbol table has been parsed.
|
||||
virtual bool parse_code_section () { return true; }
|
||||
virtual bool parse_code_section() { return true; }
|
||||
|
||||
/// New code section marker designating subsequent instructions.
|
||||
///
|
||||
virtual void codemarker (const char *name) { }
|
||||
virtual void codemarker(const char* name) {}
|
||||
|
||||
/// Mark the end of the code section
|
||||
///
|
||||
virtual void codeend () { }
|
||||
virtual void codeend() {}
|
||||
|
||||
/// Add an instruction.
|
||||
///
|
||||
virtual void instruction (int label, const char *opcode) { }
|
||||
virtual void instruction(int label, const char* opcode) {}
|
||||
|
||||
/// Add an argument to the last instruction.
|
||||
///
|
||||
virtual void instruction_arg (const char *name) { }
|
||||
virtual void instruction_arg(const char* name) {}
|
||||
|
||||
/// Add a jump target to the last instruction.
|
||||
///
|
||||
virtual void instruction_jump (int target) { }
|
||||
virtual void instruction_jump(int target) {}
|
||||
|
||||
/// Called after an instruction (after args and hints)
|
||||
///
|
||||
virtual void instruction_end () { }
|
||||
virtual void instruction_end() {}
|
||||
|
||||
/// Increment the line number (for error reporting). Should only
|
||||
/// be called by the lexer.
|
||||
void incr_lineno () { ++m_lineno; }
|
||||
void incr_lineno() { ++m_lineno; }
|
||||
|
||||
/// Return the line number (for error reporting). Should only
|
||||
/// be called by the lexer.
|
||||
int lineno () const { return m_lineno; }
|
||||
int lineno() const { return m_lineno; }
|
||||
|
||||
/// Return a reference to the error handler
|
||||
ErrorHandler& errhandler () { return m_err; }
|
||||
ErrorHandler& errhandler() { return m_err; }
|
||||
|
||||
/// Store and retrieve the current typespec
|
||||
///
|
||||
void current_typespec (TypeSpec t) { m_current_typespec = std::move(t); }
|
||||
TypeSpec current_typespec () const { return m_current_typespec; }
|
||||
void current_typespec(TypeSpec t) { m_current_typespec = std::move(t); }
|
||||
TypeSpec current_typespec() const { return m_current_typespec; }
|
||||
|
||||
private:
|
||||
class Scope;
|
||||
ErrorHandler &m_err;
|
||||
ErrorHandler& m_err;
|
||||
int m_lineno;
|
||||
TypeSpec m_current_typespec;
|
||||
};
|
||||
@@ -134,5 +134,5 @@ private:
|
||||
OSL_PRAGMA_WARNING_POP
|
||||
|
||||
|
||||
}; // namespace pvt
|
||||
}; // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
@@ -255,7 +255,7 @@ RendererServices::pointcloud_get(ShaderGlobals* sg, ustring filename,
|
||||
// Actual data query
|
||||
if (partio_type == TypeString) {
|
||||
// strings are special cases because they are stored as int index
|
||||
int* strindices = OIIO_ALLOCA(int, count);
|
||||
int* strindices = OSL_ALLOCA(int, count);
|
||||
const_cast<Partio::ParticlesData*>(cloud)->data(
|
||||
*attr, count, (const Partio::ParticleIndex*)indices,
|
||||
/*sorted=*/false, (void*)strindices);
|
||||
@@ -385,7 +385,7 @@ osl_pointcloud_search(ShaderGlobals* sg, const char* filename, void* center,
|
||||
if (sizeof(int) == sizeof(size_t) && out_indices)
|
||||
indices = (size_t*)out_indices;
|
||||
else
|
||||
indices = OIIO_ALLOCA(size_t, max_points);
|
||||
indices = OSL_ALLOCA(size_t, max_points);
|
||||
|
||||
int count
|
||||
= sg->renderer->pointcloud_search(sg, USTR(filename), *((Vec3*)center),
|
||||
@@ -425,7 +425,7 @@ osl_pointcloud_get(ShaderGlobals* sg, const char* filename, void* in_indices,
|
||||
if (shadingsys.no_pointcloud()) // Debug mode to skip pointcloud expense
|
||||
return 0;
|
||||
|
||||
size_t* indices = OIIO_ALLOCA(size_t, count);
|
||||
size_t* indices = OSL_ALLOCA(size_t, count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
indices[i] = ((int*)in_indices)[i];
|
||||
|
||||
|
||||
+40
-33
@@ -3,9 +3,9 @@
|
||||
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
|
||||
|
||||
#ifdef USE_PARTIO
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <Partio.h>
|
||||
# include <Partio.h>
|
||||
# include <memory>
|
||||
# include <unordered_map>
|
||||
#endif
|
||||
|
||||
#include <OSL/oslconfig.h>
|
||||
@@ -17,41 +17,54 @@ namespace pvt {
|
||||
|
||||
class PointCloud {
|
||||
public:
|
||||
PointCloud (ustring filename, Partio::ParticlesDataMutable *partio_cloud, bool write);
|
||||
~PointCloud ();
|
||||
static PointCloud *get (ustring filename, bool write = false);
|
||||
PointCloud(ustring filename, Partio::ParticlesDataMutable* partio_cloud,
|
||||
bool write);
|
||||
~PointCloud();
|
||||
static PointCloud* get(ustring filename, bool write = false);
|
||||
|
||||
typedef std::unordered_map<ustring, std::unique_ptr<Partio::ParticleAttribute>, ustringHash> AttributeMap;
|
||||
typedef std::unordered_map<
|
||||
ustring, std::unique_ptr<Partio::ParticleAttribute>, ustringHash>
|
||||
AttributeMap;
|
||||
|
||||
const Partio::ParticlesData* read_access() const { OSL_DASSERT(!m_write); return m_partio_cloud; }
|
||||
Partio::ParticlesDataMutable* write_access() const { OSL_DASSERT(m_write); return m_partio_cloud; }
|
||||
const Partio::ParticlesData* read_access() const
|
||||
{
|
||||
OSL_DASSERT(!m_write);
|
||||
return m_partio_cloud;
|
||||
}
|
||||
Partio::ParticlesDataMutable* write_access() const
|
||||
{
|
||||
OSL_DASSERT(m_write);
|
||||
return m_partio_cloud;
|
||||
}
|
||||
|
||||
ustring m_filename;
|
||||
|
||||
private:
|
||||
// hide just this field, because we want to control how it is accessed
|
||||
Partio::ParticlesDataMutable *m_partio_cloud;
|
||||
public:
|
||||
Partio::ParticlesDataMutable* m_partio_cloud;
|
||||
|
||||
public:
|
||||
AttributeMap m_attributes;
|
||||
bool m_write;
|
||||
Partio::ParticleAttribute m_position_attribute;
|
||||
OIIO::spin_mutex m_mutex;
|
||||
};
|
||||
|
||||
namespace { // anon
|
||||
namespace { // anon
|
||||
|
||||
static ustring u_position ("position");
|
||||
static ustring u_position("position");
|
||||
|
||||
// some helper classes to make the sort easy
|
||||
typedef std::pair<float,int> SortedPointRecord; // dist,index
|
||||
typedef std::pair<float, int> SortedPointRecord; // dist,index
|
||||
struct SortedPointCompare {
|
||||
bool operator() (const SortedPointRecord &a, const SortedPointRecord &b) {
|
||||
bool operator()(const SortedPointRecord& a, const SortedPointRecord& b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
}
|
||||
};
|
||||
|
||||
inline Partio::ParticleAttributeType
|
||||
PartioType (TypeDesc t)
|
||||
PartioType(TypeDesc t)
|
||||
{
|
||||
if (t == TypeDesc::TypeFloat)
|
||||
return Partio::FLOAT;
|
||||
@@ -68,7 +81,7 @@ PartioType (TypeDesc t)
|
||||
|
||||
// Helper: number of base values
|
||||
inline int
|
||||
basevals (TypeDesc t)
|
||||
basevals(TypeDesc t)
|
||||
{
|
||||
return t.numelements() * int(t.aggregate);
|
||||
}
|
||||
@@ -76,16 +89,16 @@ basevals (TypeDesc t)
|
||||
|
||||
|
||||
bool
|
||||
compatiblePartioType (TypeDesc partio_type, TypeDesc osl_element_type)
|
||||
compatiblePartioType(TypeDesc partio_type, TypeDesc osl_element_type)
|
||||
{
|
||||
// Matching types (treating all VEC3 aggregates as equivalent)...
|
||||
if (equivalent (partio_type, osl_element_type))
|
||||
if (equivalent(partio_type, osl_element_type))
|
||||
return true;
|
||||
|
||||
// Consider arrays and aggregates as interchangeable, as long as the
|
||||
// totals are the same.
|
||||
if (partio_type.basetype == osl_element_type.basetype &&
|
||||
basevals(partio_type) == basevals(osl_element_type))
|
||||
if (partio_type.basetype == osl_element_type.basetype
|
||||
&& basevals(partio_type) == basevals(osl_element_type))
|
||||
return true;
|
||||
|
||||
// The Partio file may contain an array size that OSL can't exactly
|
||||
@@ -102,7 +115,7 @@ compatiblePartioType (TypeDesc partio_type, TypeDesc osl_element_type)
|
||||
|
||||
|
||||
TypeDesc
|
||||
TypeDescOfPartioType (const Partio::ParticleAttribute *ptype)
|
||||
TypeDescOfPartioType(const Partio::ParticleAttribute* ptype)
|
||||
{
|
||||
TypeDesc type; // default to UNKNOWN
|
||||
switch (ptype->type) {
|
||||
@@ -117,25 +130,19 @@ TypeDescOfPartioType (const Partio::ParticleAttribute *ptype)
|
||||
type.arraylen = ptype->count;
|
||||
break;
|
||||
case Partio::VECTOR:
|
||||
type = TypeDesc (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::NOSEMANTICS);
|
||||
type = TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::NOSEMANTICS);
|
||||
if (ptype->count != 3)
|
||||
type = TypeDesc::UNKNOWN; // Must be 3: punt
|
||||
break;
|
||||
case Partio::INDEXEDSTR:
|
||||
type = TypeDesc::STRING;
|
||||
break;
|
||||
default:
|
||||
break; // Any other future types -- return UNKNOWN
|
||||
case Partio::INDEXEDSTR: type = TypeDesc::STRING; break;
|
||||
default: break; // Any other future types -- return UNKNOWN
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace pvt
|
||||
} // namespace pvt
|
||||
OSL_NAMESPACE_EXIT
|
||||
|
||||
|
||||
|
||||
|
||||
+1253
-1132
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user