Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fcb306c91 | ||
|
|
67a6f40c6c | ||
|
|
aad183b993 | ||
|
|
3759bb572d | ||
|
|
28f5fa9d07 | ||
|
|
dcb283e279 | ||
|
|
e087eefe5a | ||
|
|
6ac6171b54 | ||
|
|
b37b536253 | ||
|
|
658f94ab6c | ||
|
|
8ddad2a3f5 | ||
|
|
36d36e5b6e | ||
|
|
02d0038a99 | ||
|
|
113239e8aa | ||
|
|
53e8e0047d | ||
|
|
2080cc0543 | ||
|
|
bdae2bdd04 | ||
|
|
8a72fb41fd | ||
|
|
627ac7ba2c | ||
|
|
71a9563cd8 | ||
|
|
f8bcaa2001 | ||
|
|
d439076261 | ||
|
|
5db1005e8d | ||
|
|
8c881fb01a | ||
|
|
eb5f9fc707 | ||
|
|
7c7e3eed8b | ||
|
|
9e2ca6d4e4 | ||
|
|
d7eb0d2a44 | ||
|
|
2f7f118105 | ||
|
|
90ae80b5fe | ||
|
|
d8e955002f | ||
|
|
d29232b282 | ||
|
|
272f5feb2a | ||
|
|
7723b92932 | ||
|
|
8251272aaf | ||
|
|
ee1c56c6bc | ||
|
|
c819f3bacd | ||
|
|
570d59289c | ||
|
|
c9ee19a5d2 | ||
|
|
f59c6d3ef1 | ||
|
|
b2234567b7 | ||
|
|
619b0e5ea2 | ||
|
|
9ef2018879 | ||
|
|
8de6a5fdf8 | ||
|
|
baa030dd36 | ||
|
|
8b63714aca | ||
|
|
dac55b1974 | ||
|
|
be3e00be56 | ||
|
|
403818c7c0 | ||
|
|
1bc8b94bbd | ||
|
|
8918ed32db | ||
|
|
6008fdf64e | ||
|
|
cbf9a336f8 | ||
|
|
0ee27e4af1 | ||
|
|
66e3f8af2b | ||
|
|
957ae983df | ||
|
|
df51d78be8 | ||
|
|
e22d74ec07 | ||
|
|
b498e2b87e | ||
|
|
825c513d9c | ||
|
|
f4a0f38636 | ||
|
|
02192dc3f9 |
@@ -6,7 +6,6 @@ name: continuous
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
|
||||
####################################################################
|
||||
# Setup dpcpp and gfx if not already on NAS
|
||||
####################################################################
|
||||
@@ -63,62 +62,6 @@ jobs:
|
||||
################################################################################
|
||||
###############################################################################
|
||||
|
||||
########################################
|
||||
# ze_raytracing
|
||||
########################################
|
||||
|
||||
linux-ze_raytracing:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
needs: [setup_gfx, setup_dpcpp]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
runs-on: '[ "Linux", "docker", "build" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-ubuntu22-internal.env
|
||||
artifact-out: linux-ze_raytracing
|
||||
artifact-path: ./build
|
||||
cmd: |
|
||||
source $DPCPP_ROOT/startup.sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang ../kernels/rthwif
|
||||
cmake --build . --target package
|
||||
|
||||
linux-ze_raytracing-test-DG2:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
needs: ["linux-ze_raytracing"]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
options: --device=/dev/dri:/dev/dri
|
||||
runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-ubuntu22-internal.env
|
||||
artifact-in: linux-ze_raytracing
|
||||
cmd: |
|
||||
cd build
|
||||
ctest
|
||||
|
||||
windows-ze_raytracing:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows_gpu.yml@devel
|
||||
needs: [setup_gfx, setup_dpcpp]
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-windows-internal.env
|
||||
artifact-path: ./build
|
||||
artifact-out: windows-ze_raytracing
|
||||
shell: cmd
|
||||
cmd: |
|
||||
call %DPCPP_ROOT%\\startup.bat
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang ../kernels/rthwif
|
||||
cmake --build . --target package
|
||||
ctest
|
||||
|
||||
########################################
|
||||
# Linux DG2
|
||||
########################################
|
||||
@@ -135,7 +78,7 @@ jobs:
|
||||
artifact-out: linux-DG2-JIT-INTERNAL
|
||||
artifact-path: ./build .ctest_conf
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 compiler:dpcpp ispc:ispc1.18.1 isa:SSE2 build:RelWithAssert EMBREE_SYCL_SUPPORT:ON sycl:none tasking:TBB2021.7.0 intensity:4
|
||||
scripts/test.py configure platform:x64 compiler:dpcpp ispc:ispc1.18.1 isa:SSE2 build:RelWithAssert EMBREE_SYCL_SUPPORT:ON LEVEL_ZERO:ON sycl:none tasking:TBB2021.7.0 intensity:4
|
||||
scripts/test.py build --debug
|
||||
scripts/test.py build
|
||||
|
||||
@@ -201,54 +144,20 @@ jobs:
|
||||
scripts/test.py build --debug
|
||||
scripts/test.py build
|
||||
|
||||
linux-DG2-JIT-GPU-BVH-BUILDER:
|
||||
linux-DG2-JIT-EMBARGO-test:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
needs: [setup_gfx, setup_dpcpp]
|
||||
needs: ["linux-DG2-JIT-EMBARGO"]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
runs-on: '[ "Linux", "docker", "build" ]'
|
||||
options: --device=/dev/dri:/dev/dri
|
||||
runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-ubuntu22-embargo.env
|
||||
artifact-out: linux-DG2-JIT-GPU-BVH-BUILDER
|
||||
artifact-path: ./build .ctest_conf
|
||||
artifact-in: linux-DG2-JIT-EMBARGO
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 compiler:dpcpp ispc:ispc1.18.1 isa:SSE2 build:RelWithAssert EMBREE_SYCL_SUPPORT:ON EMBREE_SYCL_GPU_BVH_BUILDER:ON USERGEOM:CONTEXT FILTER_FUNCTION:CONTEXT gfx:EMBARGO sycl:none tasking:TBB2021.7.0 intensity:4
|
||||
scripts/test.py build --debug
|
||||
scripts/test.py build
|
||||
|
||||
linux-DG2-JIT-PUBLIC-GPU-BVH-BUILDER:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
needs: [setup_gfx, setup_dpcpp]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
runs-on: '[ "Linux", "docker", "build" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-ubuntu22-public.env
|
||||
install-gfx-driver: false
|
||||
artifact-out: linux-DG2-JIT-PUBLIC-GPU-BVH-BUILDER
|
||||
artifact-path: ./build .ctest_conf
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 compiler:dpcpp ispc:ispc1.18.1 isa:AVX512 build:RelWithAssert EMBREE_SYCL_SUPPORT:ON EMBREE_SYCL_GPU_BVH_BUILDER:ON USERGEOM:CONTEXT FILTER_FUNCTION:CONTEXT gfx:PUBLIC sycl:none tasking:TBB2021.7.0 intensity:4
|
||||
scripts/test.py build --debug
|
||||
scripts/test.py build
|
||||
|
||||
|
||||
# linux-DG2-AOT-INTERNAL-test:
|
||||
# secrets: inherit
|
||||
# uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
# needs: ["linux-DG2-AOT-INTERNAL"]
|
||||
# with:
|
||||
# image: embree/ubuntu:22.04
|
||||
# options: --device=/dev/dri:/dev/dri
|
||||
# runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
# project: embree
|
||||
# env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env ./.github/workflows/gfx-ubuntu22-internal.env
|
||||
# artifact-in: linux-DG2-AOT-INTERNAL
|
||||
# cmd: |
|
||||
# scripts/test.py test --debug
|
||||
# scripts/test.py test
|
||||
scripts/test.py test --debug
|
||||
scripts/test.py test
|
||||
|
||||
linux-DG2-JIT-PUBLIC-ICX:
|
||||
secrets: inherit
|
||||
@@ -542,7 +451,7 @@ jobs:
|
||||
########################################
|
||||
windows-V140:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@devel
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build" ]'
|
||||
cmd: |
|
||||
@@ -552,7 +461,7 @@ jobs:
|
||||
|
||||
windows-V141:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@devel
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build" ]'
|
||||
cmd: |
|
||||
@@ -562,7 +471,7 @@ jobs:
|
||||
|
||||
windows-V142:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@devel
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build" ]'
|
||||
cmd: |
|
||||
@@ -572,7 +481,7 @@ jobs:
|
||||
|
||||
windows-ICX:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@devel
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build", "avx512" ]'
|
||||
cmd: |
|
||||
@@ -586,15 +495,16 @@ jobs:
|
||||
################################################################################
|
||||
################################################################################
|
||||
|
||||
|
||||
########################################
|
||||
# MacOS
|
||||
########################################
|
||||
|
||||
macosx-ARM-NEON-AVX2:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@devel
|
||||
with:
|
||||
runs-on: '[ "macOS", "arm", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "arm" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:arm64 build:Debug compiler:CLANG ispc:ispc1.17.0 isa:NEON2X tasking:TBB_HOMEBREW intensity:2
|
||||
scripts/test.py build
|
||||
@@ -602,15 +512,14 @@ jobs:
|
||||
|
||||
macosx-x64-CLANG:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@devel
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:CLANG ispc:ispc1.18.1 isa:SSE2 tasking:TBB2021.1.1 intensity:2
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
|
||||
########################################
|
||||
# Klockwork
|
||||
########################################
|
||||
@@ -632,17 +541,11 @@ jobs:
|
||||
|
||||
success:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Success
|
||||
run: echo Success
|
||||
needs:
|
||||
- linux-ze_raytracing
|
||||
- linux-ze_raytracing-test-DG2
|
||||
- windows-ze_raytracing
|
||||
- linux-DG2-JIT-INTERNAL-test
|
||||
- linux-DG2-JIT-PUBLIC-test
|
||||
- linux-ATSM-JIT-PUBLIC-test
|
||||
- linux-DG2-JIT-EMBARGO
|
||||
- linux-DG2-JIT-EMBARGO-test
|
||||
- linux-DG2-JIT-PUBLIC-ICX-test
|
||||
- linux-PVC-1T-JIT-INTERNAL-test
|
||||
- linux-PVC-2T-JIT-INTERNAL-test
|
||||
@@ -665,3 +568,10 @@ jobs:
|
||||
- macosx-ARM-NEON-AVX2
|
||||
- macosx-x64-CLANG
|
||||
- linux-GCC-KLOCWORK
|
||||
if: failure() || cancelled()
|
||||
steps:
|
||||
- name: Failure
|
||||
run: |
|
||||
echo "::notice title=Success::Workflow failed"
|
||||
exit 1
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
DPCPP_VERSION=sycl-nightly/20230304
|
||||
DPCPP_VERSION=sycl-nightly/20230417
|
||||
@@ -0,0 +1 @@
|
||||
DPCPP_VERSION=intel-llvm/sycl-nightly/20230304
|
||||
@@ -1 +1 @@
|
||||
GFX_DRIVER_VERSION=neo-builds/ci/master/ci-neo-master-025813/artifacts/linux/ubuntu/22.04
|
||||
GFX_DRIVER_VERSION=neo-builds/ci/master/ci-neo-master-025905/artifacts/linux/ubuntu/22.04
|
||||
|
||||
@@ -562,7 +562,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-V140-ISPC1_9_2-SSE2-INT:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:V140 ispc:ispc1.16.1 isa:SSE2 tasking:INT intensity:2
|
||||
@@ -571,7 +571,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-V140-ISPC1_9_2-AVX-TBB2019_2:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:V140 ispc:ispc1.16.1 isa:AVX tasking:TBB2019.2 intensity:4
|
||||
@@ -580,7 +580,7 @@ jobs:
|
||||
|
||||
nightly-windows-Win32-RelWithDebInfo-V140-ISPC1_12_0-SSE2-TBB2020_2:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:Win32 build:RelWithDebInfo compiler:V140 ispc:ispc1.12.0 isa:SSE2 tasking:TBB2020.2 intensity:2
|
||||
@@ -589,7 +589,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-V140-ISPC1_12_0-AVX2-PPL:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:V140 ispc:ispc1.12.0 isa:AVX2 frequency_level:simd256 tasking:PPL intensity:2
|
||||
@@ -598,7 +598,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-V141-ISPC1_13_0-AVX2-TBB2019_9-STATIC:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:V141 ispc:ispc1.13.0 isa:AVX2 frequency_level:simd128 tasking:TBB2019.9 intensity:2 STATIC_LIB:ON
|
||||
@@ -607,7 +607,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-V142-ISPC1_13_0-AVX2-TBB2020_2-STATIC:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:V142 ispc:ispc1.13.0 isa:AVX2 tasking:TBB2020.2 intensity:2
|
||||
@@ -616,7 +616,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-LLVM-CLANG-ISPC1_13_0-AVX2-TBB2019_9-NAMESPACE:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:LLVM_CLANG ispc:ispc1.13.0 isa:AVX2 tasking:TBB2019.9 intensity:4 api_namespace:myembree
|
||||
@@ -625,7 +625,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-ICX2023_0_0-ISPC1_13_0-AVX2-TBB2021_5_0:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:RelWithDebInfo compiler:ICX2023.0.0 ispc:ispc1.13.0 isa:AVX2 frequency_level:simd128 tasking:TBB2021.5.0 intensity:4
|
||||
@@ -634,7 +634,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-ICX2023_0_0-ISPC1_13_0-AVX512-TBB2019_9:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build", "avx512" ]'
|
||||
cmd: |
|
||||
@@ -644,7 +644,7 @@ jobs:
|
||||
|
||||
nightly-windows-x64-RelWithDebInfo-ICX2023_0_0-ISPC1_14_1-AVX2-TBB2021_2_0:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.14.1 isa:AVX2 tasking:TBB2021.2.0 intensity:2
|
||||
@@ -658,7 +658,7 @@ jobs:
|
||||
|
||||
macosx-ARM-NEON:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "arm", "build" ]'
|
||||
cmd: |
|
||||
@@ -668,9 +668,9 @@ jobs:
|
||||
|
||||
macosx-x64-ICX:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "build", "embree" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:ICX2023.0.0 ispc:ispc1.17.0 isa:SSE2 tasking:TBB2021.7.0 intensity:2
|
||||
scripts/test.py build
|
||||
@@ -680,9 +680,9 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-CLANG-ISPC1_12_0-SSE2-TBB2021_1_1-NAMESPACE:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:CLANG ispc:ispc1.12.0 isa:SSE2 tasking:TBB2021.1.1 intensity:4 api_namespace:myembree maxinstancelevelcount:4
|
||||
scripts/test.py build
|
||||
@@ -690,9 +690,9 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-CLANG-ISPC1_13_0-AVX-INT:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:CLANG ispc:ispc1.13.0 isa:AVX tasking:INT intensity:4
|
||||
scripts/test.py build
|
||||
@@ -700,9 +700,9 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-CLANG-ISPC1_13_0-SSE2-TBB2021_1_1-STATIC:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:CLANG ispc:ispc1.13.0 isa:SSE2 tasking:TBB2021.1.1 intensity:4 STATIC_LIB:ON
|
||||
scripts/test.py build
|
||||
@@ -712,9 +712,9 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-ICX2023_0_0-ISPC1_13_0-AVX-INT:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:ICX2023.0.0 ispc:ispc1.13.0 isa:AVX tasking:INT intensity:4
|
||||
scripts/test.py build
|
||||
@@ -722,9 +722,9 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-ICX2023_0_0-ISPC1_13_0-AVX2-TBB2021_1_1:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "avx2", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "avx2", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:ICX2023.0.0 ispc:ispc1.13.0 isa:AVX2 frequency_level:simd256 tasking:TBB2021.1.1 intensity:4
|
||||
scripts/test.py build
|
||||
@@ -732,10 +732,25 @@ jobs:
|
||||
|
||||
nightly-macosx-x64-Debug-ICX2023_0_0-ISPC1_17_0-AVX2-TBB2021_1_1:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "avx2", "embree", "build" ]'
|
||||
runs-on: '[ "macOS", "avx2", "build", "x86_64" ]'
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Debug compiler:ICX2023.0.0 ispc:ispc1.17.0 isa:AVX2 frequency_level:simd128 tasking:TBB2021.1.1 intensity:4
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
########################################
|
||||
# ARM EMULATION
|
||||
########################################
|
||||
|
||||
linux-ubuntu22_04-arm64:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
with:
|
||||
image: embree/arm64v8-ubuntu:22.04
|
||||
runs-on: '[ "Linux", "docker-arm", "ARM64" ]'
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:Debug compiler:GCC isa:NONE tasking:INT intensity:2
|
||||
python scripts/test.py build
|
||||
python scripts/test.py test
|
||||
@@ -3,30 +3,33 @@
|
||||
|
||||
name: performance
|
||||
|
||||
on: [workflow_dispatch]
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 01 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
|
||||
########################################
|
||||
# Linux build
|
||||
########################################
|
||||
|
||||
linux-build-DG2-DPCPP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
with:
|
||||
image: embree/ubuntu:20.04
|
||||
options: --device=/dev/dri:/dev/dri
|
||||
runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-none.env ./.github/workflows/gfx-ubuntu22-release.env
|
||||
artifact-out: linux-DG2-DPCPP
|
||||
artifact-path: ./build/*.tar.gz .ctest_conf
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP EMBREE_USE_GOOGLE_BENCHMARK:ON EMBREE_BUILD_GOOGLE_BENCHMARK_FROM_SOURCE:ON EMBREE_NO_SPLASH:ON
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
|
||||
linux-build-x86-ICX-ISPC:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
@@ -36,104 +39,103 @@ jobs:
|
||||
artifact-out: linux-build-x86-ICX-ISPC
|
||||
artifact-path: ./build/*.tar.gz .ctest_conf
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP EMBREE_USE_GOOGLE_BENCHMARK:ON EMBREE_BUILD_GOOGLE_BENCHMARK_FROM_SOURCE:ON EMBREE_NO_SPLASH:ON
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
|
||||
|
||||
linux-test-DG2-A750-not_perf:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@main
|
||||
needs: ["linux-build-DG2-DPCPP"]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
options: --device=/dev/dri:/dev/dri
|
||||
runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-none.env ./.github/workflows/gfx-ubuntu22-release.env
|
||||
artifact-in: linux-DG2-DPCPP
|
||||
cmd: |
|
||||
source <(scripts/test.py env --debug)
|
||||
cd build
|
||||
tar -xf embree-4.0.0.sycl.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.sycl.x86_64.linux
|
||||
chmod +x embree-vars.sh
|
||||
./embree-vars.sh
|
||||
tar -xf embree-?.?.?-beta.sycl.x86_64.linux.tar.gz
|
||||
cd bin
|
||||
chmod +x ../embree-vars.sh
|
||||
../embree-vars.sh
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh gpu
|
||||
|
||||
linux-test-DG2-A770:
|
||||
linux-test-DG2-A770-perf:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@main
|
||||
needs: ["linux-build-DG2-DPCPP"]
|
||||
with:
|
||||
image: embree/ubuntu:22.04
|
||||
options: --device=/dev/dri:/dev/dri
|
||||
runs-on: '[ "Linux", "docker", "A770", "perf" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-none.env ./.github/workflows/gfx-ubuntu22-release.env
|
||||
artifact-in: linux-DG2-DPCPP
|
||||
cmd: |
|
||||
source <(scripts/test.py env --debug)
|
||||
cd build
|
||||
tar -xf embree-4.0.0.sycl.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.sycl.x86_64.linux
|
||||
chmod +x embree-vars.sh
|
||||
./embree-vars.sh
|
||||
tar -xf embree-?.?.?-beta.sycl.x86_64.linux.tar.gz
|
||||
cd bin
|
||||
chmod +x ../embree-vars.sh
|
||||
../embree-vars.sh
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh gpu
|
||||
|
||||
|
||||
linux-test-i9-12900k:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@devel
|
||||
needs: ["linux-build-x86-ICX-ISPC"]
|
||||
with:
|
||||
runs-on: '[ "Linux", "perf", "vis-perf-i9-12900k-1" ]'
|
||||
artifact-in: linux-build-x86-ICX-ISPC
|
||||
cmd: |
|
||||
cd build
|
||||
tar -xf embree-4.0.0.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.x86_64.linux
|
||||
cd bin
|
||||
tar -xf embree-?.?.?.x86_64.linux.tar.gz
|
||||
cd embree-*.linux/bin
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh cpu
|
||||
|
||||
|
||||
linux-test-x8380-1:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@devel
|
||||
needs: ["linux-build-x86-ICX-ISPC"]
|
||||
with:
|
||||
runs-on: '[ "Linux", "perf", "vis-perf-x8380-1" ]'
|
||||
artifact-in: linux-build-x86-ICX-ISPC
|
||||
cmd: |
|
||||
cd build
|
||||
tar -xf embree-4.0.0.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.x86_64.linux
|
||||
cd bin
|
||||
tar -xf embree-?.?.?.x86_64.linux.tar.gz
|
||||
cd embree-*.linux/bin
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh cpu
|
||||
|
||||
|
||||
linux-test-x8280-1:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@devel
|
||||
needs: ["linux-build-x86-ICX-ISPC"]
|
||||
with:
|
||||
runs-on: '[ "Linux", "perf", "vis-perf-x8280-1" ]'
|
||||
artifact-in: linux-build-x86-ICX-ISPC
|
||||
cmd: |
|
||||
cd build
|
||||
tar -xf embree-4.0.0.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.x86_64.linux
|
||||
cd bin
|
||||
tar -xf embree-?.?.?.x86_64.linux.tar.gz
|
||||
cd embree-*.linux/bin
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh cpu
|
||||
|
||||
|
||||
linux-test-a3970x-1:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/perf.yml@devel
|
||||
needs: ["linux-build-x86-ICX-ISPC"]
|
||||
with:
|
||||
runs-on: '[ "Linux", "perf", "vis-perf-a3970x-1" ]'
|
||||
artifact-in: linux-build-x86-ICX-ISPC
|
||||
cmd: |
|
||||
cd build
|
||||
tar -xf embree-4.0.0.x86_64.linux.tar.gz
|
||||
cd embree-4.0.0.x86_64.linux
|
||||
cd bin
|
||||
tar -xf embree-?.?.?.x86_64.linux.tar.gz
|
||||
cd embree-*.linux/bin
|
||||
$GITHUB_WORKSPACE/scripts/run-perf.sh cpu
|
||||
|
||||
|
||||
@@ -14,40 +14,40 @@ jobs:
|
||||
# Release Builds
|
||||
####################################################################
|
||||
|
||||
release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP:
|
||||
release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_windows.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "build", "avx512" ]'
|
||||
artifact-out: release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-out: release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-path: ./build/*.zip
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
python scripts/test.py configure platform:x64 build:Release compiler:ICX2023.1.0 ispc:ispc1.19.0 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.9.0 intensity:4 package:ZIP
|
||||
python scripts/test.py build
|
||||
python scripts/test.py test
|
||||
|
||||
release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP:
|
||||
release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_macos.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/macos.yml@main
|
||||
with:
|
||||
runs-on: '[ "macOS", "embree", "sign", "avx2" ]'
|
||||
artifact-out: release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
runs-on: '[ "macOS", "sign", "avx2", "x86_64" ]'
|
||||
artifact-out: release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-path: ./build/*.zip
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
scripts/test.py configure platform:x64 build:Release compiler:CLANG ispc:ispc1.19.0 isas:SSE2-SSE42-AVX-AVX2 tasking:TBB2021.9.0 intensity:4 package:ZIP
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP:
|
||||
release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/embree_docker.yml@main
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main
|
||||
with:
|
||||
image: embree/rockylinux:8.7
|
||||
runs-on: '[ "Linux", "docker", "avx512" ]'
|
||||
artifact-out: release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-out: release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-path: ./build/*.tar.gz
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.1.0 ispc:ispc1.19.0 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.9.0 intensity:4 package:ZIP
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
@@ -56,17 +56,17 @@ jobs:
|
||||
# DPC++ Release Builds
|
||||
####################################################################
|
||||
|
||||
release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP:
|
||||
release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows_gpu.yml@devel
|
||||
with:
|
||||
runs-on: '[ "Windows", "NAS", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-none.env ./.github/workflows/gfx-windows-internal.env
|
||||
artifact-out: release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-out: release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-path: ./build/*.zip
|
||||
cmd: |
|
||||
python scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
python scripts/test.py configure platform:x64 build:Release compiler:ICX2023.1.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.19.0 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.9.0 intensity:4 package:ZIP
|
||||
python scripts/test.py build
|
||||
python scripts/test.py test
|
||||
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
# python scripts/test.py build
|
||||
# python scripts/test.py test
|
||||
|
||||
release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP:
|
||||
release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP:
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@devel
|
||||
with:
|
||||
@@ -92,10 +92,10 @@ jobs:
|
||||
runs-on: '[ "Linux", "docker", "dg2" ]'
|
||||
project: embree
|
||||
env-from-files: ./.github/workflows/dpcpp-none.env ./.github/workflows/gfx-ubuntu22-release.env
|
||||
artifact-out: release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-out: release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-path: ./build/*.tar.gz
|
||||
cmd: |
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.0.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.18.1 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.7.0 intensity:4 package:ZIP
|
||||
scripts/test.py configure platform:x64 build:Release compiler:ICX2023.1.0 EMBREE_SYCL_SUPPORT:ON sycl:none gfx:RELEASE ispc:ispc1.19.0 isas:SSE2-SSE42-AVX-AVX2-AVX512 tasking:TBB2021.9.0 intensity:4 package:ZIP
|
||||
scripts/test.py build
|
||||
scripts/test.py test
|
||||
|
||||
@@ -105,54 +105,54 @@ jobs:
|
||||
#####################################################################
|
||||
binary-analysis:
|
||||
needs:
|
||||
- release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/binary_analysis.yml@main
|
||||
with:
|
||||
project: embree
|
||||
artifact-in-windows: release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-macos: release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-windows: release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-macos: release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
path: "build/*.zip build/*.gz"
|
||||
|
||||
antivirus-scan:
|
||||
needs:
|
||||
- release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/antivirus_scan.yml@main
|
||||
with:
|
||||
project: embree
|
||||
artifact-in-windows: release-windows-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-macos: release-macosx-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-windows: release-windows-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-macos: release-macosx-x64-Release-CLANG-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
path: "build/*.zip build/*.gz"
|
||||
|
||||
binary-analysis-dpcpp:
|
||||
needs:
|
||||
- release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/binary_analysis.yml@main
|
||||
with:
|
||||
project: embree
|
||||
artifact-in-windows: release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-windows: release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
path: "build/*.zip build/*.gz"
|
||||
artifact-out-name: "binary-analysis-dpcpp"
|
||||
|
||||
antivirus-scan-dpcpp:
|
||||
needs:
|
||||
- release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
- release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
- release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
secrets: inherit
|
||||
uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/antivirus_scan.yml@main
|
||||
with:
|
||||
project: embree
|
||||
artifact-in-windows: release-windows-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-SYCL-ICX2023_0_0-ISPC1_18_1-TBB2021_7_0-PACKAGE-ZIP
|
||||
artifact-in-windows: release-windows-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
artifact-in-linux: release-linux-x64-Release-SYCL-ICX2023_1_0-ISPC1_19_0-TBB2021_9_0-PACKAGE-ZIP
|
||||
path: "build/*.zip build/*.gz"
|
||||
artifact-out-name: "antivirus-scan-dpcpp"
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
Version History
|
||||
---------------
|
||||
|
||||
### Embree 4.1.0
|
||||
- Added support for Intel® Data Center GPU Max Series.
|
||||
- Added ARM64 Linux support.
|
||||
- Added EMBREE_BACKFACE_CULLING_SPHERES cmake option. The new cmake option defaults to OFF.
|
||||
|
||||
### Embree 4.0.1
|
||||
- Improved performance for Tiger Lake, Comet Lake, Cannon Lake, Kaby Lake,
|
||||
and Skylake client CPUs by using 256 bit SIMD instructions by default.
|
||||
- Fixed broken motion blur of RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE geometry type.
|
||||
- Fixed bvh build retry issue for TBB 2020.3
|
||||
- Added support for Intel® Data Center GPU Flex Series
|
||||
- Fixed issue on systems without a SYCL platform.
|
||||
|
||||
### Embree 4.0.0
|
||||
- This Embree release adds support for Intel® Arc™ GPUs through SYCL.
|
||||
- The SYCL support of Embree is in beta phase. Current functionality, quality,
|
||||
|
||||
+13
-14
@@ -4,8 +4,8 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0)
|
||||
|
||||
SET(EMBREE_VERSION_MAJOR 4)
|
||||
SET(EMBREE_VERSION_MINOR 0)
|
||||
SET(EMBREE_VERSION_PATCH 1)
|
||||
SET(EMBREE_VERSION_MINOR 1)
|
||||
SET(EMBREE_VERSION_PATCH 0)
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
SET(EMBREE_VERSION_NOTE "-beta") # Embree SYCL version is in beta phase
|
||||
ELSE()
|
||||
@@ -89,9 +89,7 @@ MARK_AS_ADVANCED(CLEAR CMAKE_CXX_COMPILER)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/common/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
IF (BUILD_TESTING)
|
||||
INCLUDE(test)
|
||||
ENDIF()
|
||||
INCLUDE(test)
|
||||
|
||||
set(BUILD_DOC OFF CACHE INTERNAL "build documentation (internal only)")
|
||||
IF (BUILD_DOC)
|
||||
@@ -145,7 +143,8 @@ OPTION(EMBREE_STACK_PROTECTOR "When enabled Embree compiles with stack protectio
|
||||
|
||||
IF (NOT APPLE)
|
||||
OPTION(EMBREE_SYCL_SUPPORT "Enables SYCL GPU support." OFF)
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
OPTION(EMBREE_NO_SPLASH "Enables/Disables the Embree splash." OFF)
|
||||
IF (EMBREE_SYCL_SUPPORT AND NOT EMBREE_NO_SPLASH)
|
||||
MESSAGE(WARNING
|
||||
"==================================================================================\n"
|
||||
" The SYCL support of Embree is in beta phase. Current functionality, quality, \n"
|
||||
@@ -169,11 +168,8 @@ ENDIF()
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_SUPPORT") # FIXME: only use define from rtcore_config.h
|
||||
ENDIF()
|
||||
|
||||
OPTION(EMBREE_SYCL_GPU_BVH_BUILDER "Using fast GPU-based BVH builder" OFF)
|
||||
IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
SET(EMBREE_STATIC_LIB ON)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_GPU_BVH_BUILDER")
|
||||
IF (EMBREE_NO_SPLASH)
|
||||
ADD_DEFINITIONS("-DEMBREE_NO_SPLASH") # FIXME: only use define from rtcore_config.h
|
||||
ENDIF()
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_SYCL_RT_SIMULATION "Using hardware simulation" OFF "EMBREE_SYCL_SUPPORT" OFF)
|
||||
@@ -186,13 +182,12 @@ IF (EMBREE_SYCL_RT_SIMULATION)
|
||||
ENDIF()
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_SYCL_RT_VALIDATION_API "Use rt_validation API instead of IGC provided rt_production API" OFF "EMBREE_SYCL_SUPPORT" OFF)
|
||||
|
||||
IF (EMBREE_SYCL_RT_VALIDATION_API)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_RT_VALIDATION_API")
|
||||
ENDIF()
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS "Using L0 allocated Dispatch Globals" ON "EMBREE_SYCL_RT_VALIDATION_API" OFF)
|
||||
IF (NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
IF (EMBREE_SYCL_RT_VALIDATION_API AND NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS")
|
||||
ENDIF()
|
||||
|
||||
@@ -211,6 +206,8 @@ ENDIF()
|
||||
|
||||
OPTION(EMBREE_RAY_MASK "Enables ray mask support." ON)
|
||||
OPTION(EMBREE_BACKFACE_CULLING "Enables backface culling.")
|
||||
OPTION(EMBREE_BACKFACE_CULLING_CURVES "Enables backface culling for curve primitives." OFF)
|
||||
OPTION(EMBREE_BACKFACE_CULLING_SPHERES "Enables backface culling for sphere primitives." OFF)
|
||||
|
||||
OPTION(EMBREE_FILTER_FUNCTION "Enables filter functions." ON)
|
||||
OPTION(EMBREE_IGNORE_INVALID_RAYS "Ignores invalid rays." OFF) # FIXME: enable by default?
|
||||
@@ -418,6 +415,9 @@ IF (EMBREE_MAX_ISA STREQUAL "NONE")
|
||||
ELSE()
|
||||
OPTION(EMBREE_ISA_AVX512 "Enables AVX512 ISA." ${COMPILER_SUPPORTS_AVX512})
|
||||
ENDIF()
|
||||
# Don't use OPTION, but still set them to OFF, so that embree-config.cmake is consisten with its definitions
|
||||
SET(EMBREE_ISA_NEON OFF)
|
||||
SET(EMBREE_ISA_NEON2X OFF)
|
||||
ENDIF()
|
||||
|
||||
ELSEIF (EMBREE_MAX_ISA STREQUAL "DEFAULT")
|
||||
@@ -715,4 +715,3 @@ ENDIF()
|
||||
##############################################################
|
||||
|
||||
INCLUDE(CPack)
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions") # enable exceptions
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") # enable threads
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msimd128") # enable SIMD intrinsics
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
|
||||
|
||||
@@ -22,6 +22,7 @@ SET(EMBREE_ISA_AVX2 @EMBREE_ISA_AVX2@)
|
||||
SET(EMBREE_ISA_AVX512 @EMBREE_ISA_AVX512@)
|
||||
SET(EMBREE_ISA_AVX512SKX @EMBREE_ISA_AVX512@) # just for compatibility
|
||||
SET(EMBREE_ISA_NEON @EMBREE_ISA_NEON@)
|
||||
SET(EMBREE_ISA_NEON2X @EMBREE_ISA_NEON2X@)
|
||||
|
||||
SET(EMBREE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
|
||||
SET(EMBREE_ISPC_SUPPORT @EMBREE_ISPC_SUPPORT@)
|
||||
@@ -52,8 +53,6 @@ SET(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR @EMBREE_CURVE_SELF_INTERSECT
|
||||
SET(EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE @EMBREE_DISC_POINT_SELF_INTERSECTION_AVOIDANCE@)
|
||||
SET(EMBREE_MIN_WIDTH @EMBREE_MIN_WIDTH@)
|
||||
|
||||
SET(EMBREE_SYCL_GPU_BVH_BUILDER @EMBREE_SYCL_GPU_BVH_BUILDER@)
|
||||
|
||||
IF (EMBREE_STATIC_LIB AND (EMBREE_TASKING_SYSTEM STREQUAL "TBB"))
|
||||
INCLUDE(CMakeFindDependencyMacro)
|
||||
FIND_DEPENDENCY(TBB)
|
||||
@@ -101,3 +100,8 @@ IF (EMBREE_SYCL_SUPPORT)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE("${EMBREE_ROOT_DIR}/@EMBREE_CMAKEEXPORT_DIR@/embree-targets.cmake")
|
||||
|
||||
|
||||
SET(EMBREE_TESTING_INTENSITY @EMBREE_TESTING_INTENSITY@)
|
||||
SET(EMBREE_TESTING_MEMCHECK @EMBREE_TESTING_MEMCHECK@)
|
||||
SET(EMBREE_TESTING_BENCHMARK @EMBREE_TESTING_BENCHMARK@)
|
||||
@@ -245,14 +245,25 @@ SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Intel(R) Embree implements high performan
|
||||
SET(CPACK_PACKAGE_VENDOR "Intel Corporation")
|
||||
SET(CPACK_PACKAGE_CONTACT embree_support@intel.com)
|
||||
|
||||
|
||||
SET(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
SET(CPACK_COMPONENTS_GROUPING ONE_PER_GROUP)
|
||||
|
||||
SET(CPACK_COMPONENT_LIB_DISPLAY_NAME "Library")
|
||||
SET(CPACK_COMPONENT_LIB_DESCRIPTION "The Embree library including documentation.")
|
||||
SET(CPACK_COMPONENT_LIB_GROUP "embree")
|
||||
|
||||
SET(CPACK_COMPONENT_DEVEL_DISPLAY_NAME "Development")
|
||||
SET(CPACK_COMPONENT_DEVEL_DESCRIPTION "Header Files for C and ISPC required to develop applications with Embree.")
|
||||
SET(CPACK_COMPONENT_DEVEL_GROUP "embree")
|
||||
|
||||
SET(CPACK_COMPONENT_EXAMPLES_DISPLAY_NAME "Examples")
|
||||
SET(CPACK_COMPONENT_EXAMPLES_DESCRIPTION "Tutorials demonstrating how to use Embree.")
|
||||
SET(CPACK_COMPONENT_EXAMPLES_GROUP "embree")
|
||||
|
||||
SET(CPACK_COMPONENT_TESTING_DISPLAY_NAME "Testing")
|
||||
SET(CPACK_COMPONENT_TESTING_DESCRIPTION "Models and reference images for tests")
|
||||
SET(CPACK_COMPONENT_TESTING_GROUP "embree-testing")
|
||||
|
||||
# dependencies between components
|
||||
#SET(CPACK_COMPONENT_DEVEL_DEPENDS lib)
|
||||
@@ -275,11 +286,12 @@ IF(WIN32)
|
||||
ENDIF()
|
||||
|
||||
SET(CPACK_GENERATOR ZIP)
|
||||
SET(PACKAGE_BASE_NAME "${CPACK_PACKAGE_FILE_NAME}")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${ARCH}.windows")
|
||||
SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
#SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
IF (EMBREE_TESTING_PACKAGE)
|
||||
SET(PACKAGE_SCRIPT "${PROJECT_SOURCE_DIR}/scripts/package_win.bat")
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND ${PACKAGE_SCRIPT} ${CMAKE_BUILD_TYPE} "${CPACK_PACKAGE_FILE_NAME}.zip")
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND ${PACKAGE_SCRIPT} ${CMAKE_BUILD_TYPE} "${PACKAGE_BASE_NAME}" "${ARCH}")
|
||||
ENDIF()
|
||||
|
||||
# MacOSX specific settings
|
||||
@@ -289,10 +301,11 @@ ELSEIF(APPLE)
|
||||
SET(CPACK_RESOURCE_FILE_README "${PROJECT_BINARY_DIR}/README.txt")
|
||||
|
||||
SET(CPACK_GENERATOR ZIP)
|
||||
SET(PACKAGE_BASE_NAME "${CPACK_PACKAGE_FILE_NAME}")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.macosx")
|
||||
SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
#SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
IF (EMBREE_TESTING_PACKAGE)
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/package_macosx.sh" ${CMAKE_BUILD_TYPE} "${CPACK_PACKAGE_FILE_NAME}.zip" "${EMBREE_SIGN_FILE}")
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/package_macosx.sh" ${CMAKE_BUILD_TYPE} "${PACKAGE_BASE_NAME}" "${EMBREE_SIGN_FILE}")
|
||||
ENDIF()
|
||||
|
||||
# Linux specific settings
|
||||
@@ -300,7 +313,7 @@ ELSE()
|
||||
|
||||
SET(CPACK_GENERATOR TGZ)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux")
|
||||
SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
#SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
IF (EMBREE_TESTING_PACKAGE)
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
SET(PACKAGE_SCRIPT "${PROJECT_SOURCE_DIR}/scripts/package_linux_dpcpp.sh")
|
||||
|
||||
+510
-246
@@ -1,267 +1,531 @@
|
||||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
if (BUILD_TESTING OR EMBREE_TESTING_INSTALL_TESTS)
|
||||
|
||||
INCLUDE(CTest)
|
||||
INCLUDE(CTest)
|
||||
|
||||
IF (WIN32)
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC")
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
|
||||
if (EMBREE_TESTING_INSTALL_TESTS)
|
||||
SET(EMBREE_INSTALL_CTESTTESTFILE "${CMAKE_CURRENT_BINARY_DIR}/embree-addtests.cmake")
|
||||
file(WRITE "${EMBREE_INSTALL_CTESTTESTFILE}" "")
|
||||
endif()
|
||||
|
||||
if (NOT EMBREE_TESTING_PACKAGE_TEST_PROJECT)
|
||||
IF (WIN32)
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC")
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
|
||||
ELSE()
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
ENDIF()
|
||||
else()
|
||||
SET(MY_PROJECT_BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${EMBREE_INSTALL_BINDIR}")
|
||||
endif()
|
||||
|
||||
FIND_PATH(EMBREE_TESTING_MODEL_DIR
|
||||
NAMES test-models-intensity2.txt
|
||||
PATHS "${PROJECT_SOURCE_DIR}/models"
|
||||
DOC "Path to the folder containing the Embree models for regression testing."
|
||||
NO_DEFAULT_PATHS)
|
||||
if (NOT EMBREE_TESTING_PACKAGE_TEST_PROJECT)
|
||||
SET(EMBREE_TESTING_INTENSITY 1 CACHE STRING "Intensity of testing (0 = no testing, 1 = verify and tutorials, 2 = light testing, 3 = intensive testing, 4 = very intensive testing.")
|
||||
SET_PROPERTY(CACHE EMBREE_TESTING_INTENSITY PROPERTY STRINGS 0 1 2 3 4)
|
||||
SET(EMBREE_TESTING_ONLY_SYCL_TESTS OFF CACHE BOOL "Run only tests with the sycl support.")
|
||||
SET(EMBREE_TESTING_MEMCHECK OFF CACHE BOOL "Turns on memory checking for some tests.")
|
||||
SET(EMBREE_TESTING_BENCHMARK OFF CACHE BOOL "Turns benchmarking on.")
|
||||
SET(EMBREE_TESTING_BENCHMARK_DATABASE "${PROJECT_BINARY_DIR}" CACHE PATH "Path to database for benchmarking.")
|
||||
SET(EMBREE_TESTING_PACKAGE OFF CACHE BOOL "Packages release as test.")
|
||||
SET(EMBREE_TESTING_KLOCWORK OFF CACHE BOOL "Runs Kocwork as test.")
|
||||
SET(EMBREE_TESTING_SDE OFF CACHE STRING "Uses SDE to run tests for specified CPU.")
|
||||
SET_PROPERTY(CACHE EMBREE_TESTING_SDE PROPERTY STRINGS OFF pnr nhm wsm snb ivb hsw bdw knl skl skx cnl)
|
||||
endif()
|
||||
|
||||
SET(EMBREE_TESTING_INTENSITY 1 CACHE STRING "Intensity of testing (0 = no testing, 1 = verify and tutorials, 2 = light testing, 3 = intensive testing, 4 = very intensive testing.")
|
||||
SET_PROPERTY(CACHE EMBREE_TESTING_INTENSITY PROPERTY STRINGS 0 1 2 3 4)
|
||||
SET(EMBREE_TESTING_ONLY_SYCL_TESTS OFF CACHE BOOL "Run only tests with the sycl support.")
|
||||
SET(EMBREE_TESTING_MEMCHECK OFF CACHE BOOL "Turns on memory checking for some tests.")
|
||||
SET(EMBREE_TESTING_BENCHMARK OFF CACHE BOOL "Turns benchmarking on.")
|
||||
SET(EMBREE_TESTING_BENCHMARK_DATABASE "${PROJECT_BINARY_DIR}" CACHE PATH "Path to database for benchmarking.")
|
||||
SET(EMBREE_TESTING_PACKAGE OFF CACHE BOOL "Packages release as test.")
|
||||
SET(EMBREE_TESTING_KLOCWORK OFF CACHE BOOL "Runs Kocwork as test.")
|
||||
SET(EMBREE_TESTING_SDE OFF CACHE STRING "Uses SDE to run tests for specified CPU.")
|
||||
SET_PROPERTY(CACHE EMBREE_TESTING_SDE PROPERTY STRINGS OFF pnr nhm wsm snb ivb hsw bdw knl skl skx cnl)
|
||||
FUNCTION (SET_EMBREE_TEST_PROPERTIES testname)
|
||||
SET(variants "_cpp;_ispc;_sycl")
|
||||
foreach(v ${variants})
|
||||
if (v STREQUAL "_cpp")
|
||||
SET(v "")
|
||||
endif()
|
||||
set(testnamedef "EMBREE_TEST_${testname}${v}_DEFINED")
|
||||
if(${testnamedef})
|
||||
SET_TESTS_PROPERTIES(${testname}${v} ${ARGN})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# checks if the current cmake configuration is compatible with the requirements declared in the optionsfile
|
||||
MACRO (EMBREE_TEST_CHECK_OPTIONS optionsfile out)
|
||||
if (EMBREE_TESTING_INSTALL_TESTS)
|
||||
file(APPEND "${EMBREE_INSTALL_CTESTTESTFILE}" "SET_EMBREE_TEST_PROPERTIES(${testname} ${ARGN}) \n")
|
||||
endif()
|
||||
ENDFUNCTION()
|
||||
|
||||
# if no optionsfile is found return true (no requirements defined)
|
||||
SET(${out} 1)
|
||||
MACRO (ADD_EMBREE_GENERIC_CPP_TEST testname executable)
|
||||
if((NOT ${EMBREE_SYCL_SUPPORT}) OR (NOT ${EMBREE_TESTING_ONLY_SYCL_TESTS}))
|
||||
ADD_TEST(NAME ${testname}
|
||||
WORKING_DIRECTORY "${MY_PROJECT_BINARY_DIR}"
|
||||
COMMAND ${executable} ${ARGN})
|
||||
SET(testnamedef EMBREE_TEST_${testname}_DEFINED)
|
||||
SET(${testnamedef} "1" CACHE INTERNAL "")
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
IF(EXISTS "${optionsfile}")
|
||||
FILE(READ "${optionsfile}" lines)
|
||||
STRING(REGEX REPLACE "\n" ";" lines "${lines}")
|
||||
MACRO (ADD_EMBREE_GENERIC_ISPC_TEST testname executable)
|
||||
if((NOT ${EMBREE_SYCL_SUPPORT}) OR (NOT ${EMBREE_TESTING_ONLY_SYCL_TESTS}))
|
||||
IF (EMBREE_ISPC_SUPPORT AND EMBREE_RAY_PACKETS)
|
||||
ADD_TEST(NAME ${testname}_ispc
|
||||
WORKING_DIRECTORY "${MY_PROJECT_BINARY_DIR}"
|
||||
COMMAND ${executable}_ispc ${ARGN})
|
||||
SET(testnamedef EMBREE_TEST_${testname}_ispc_DEFINED)
|
||||
SET(${testnamedef} "1" CACHE INTERNAL "")
|
||||
ENDIF()
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
FOREACH (line ${lines})
|
||||
MACRO (ADD_EMBREE_GENERIC_SYCL_TEST testname executable)
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
ADD_TEST(NAME ${testname}_sycl
|
||||
WORKING_DIRECTORY ${MY_PROJECT_BINARY_DIR}
|
||||
COMMAND ${executable}_sycl ${ARGN})
|
||||
SET(testnamedef EMBREE_TEST_${testname}_sycl_DEFINED)
|
||||
SET(${testnamedef} 1 CACHE INTERNAL "")
|
||||
SET_TESTS_PROPERTIES(${testname}_sycl PROPERTIES TIMEOUT 50)
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
# parse line into list
|
||||
string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" tokens "${line}")
|
||||
LIST(LENGTH tokens token_count)
|
||||
IF (NOT ${token_count} EQUAL 3)
|
||||
message(FATAL_ERROR "illegal .embree_opitons in ${optionsfile} at line ${line}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
# we require every line to follow the scheme "option [==/!=] value"
|
||||
LIST(GET tokens 0 option)
|
||||
LIST(GET tokens 1 comp)
|
||||
LIST(GET tokens 2 value)
|
||||
|
||||
STRING(STRIP ${option} option)
|
||||
STRING(STRIP ${comp} comp)
|
||||
STRING(STRIP ${value} value)
|
||||
|
||||
IF ("${comp}" STREQUAL "==")
|
||||
IF (NOT "${${option}}" STREQUAL "${value}")
|
||||
SET(${out} 0)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
IF ("${${option}}" STREQUAL "${value}")
|
||||
SET(${out} 0)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (${out} EQUAL 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Checks if the current cmake configuration is compatible with <condition>
|
||||
# condition may be a triple of CMAKE_VARIABLE_NAME op VALUE
|
||||
# supported operators for op are: ==, !=, <, <=, >, >=
|
||||
FUNCTION (EMBREE_TESTING_CHECK_OPTION out condition)
|
||||
# parse condition into list
|
||||
string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" tokens "${condition}")
|
||||
LIST(LENGTH tokens token_count)
|
||||
IF (NOT ${token_count} EQUAL 3)
|
||||
message(FATAL_ERROR "illegal embree_opitons condition: ${condition}")
|
||||
ENDIF()
|
||||
|
||||
# we require every condition to follow the scheme "variable_name op value"
|
||||
LIST(GET tokens 0 option)
|
||||
LIST(GET tokens 1 comp)
|
||||
LIST(GET tokens 2 value)
|
||||
|
||||
STRING(STRIP ${option} option)
|
||||
STRING(STRIP ${comp} comp)
|
||||
STRING(STRIP ${value} value)
|
||||
|
||||
SET(${out} 0 PARENT_SCOPE)
|
||||
if ("${comp}" STREQUAL "==")
|
||||
if ("${${option}}" STREQUAL "${value}")
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
elseif ("${comp}" STREQUAL "!=")
|
||||
if (NOT ("${${option}}" STREQUAL "${value}"))
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
elseif ("${comp}" STREQUAL ">")
|
||||
if ("${${option}}" GREATER "${value}")
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
elseif ("${comp}" STREQUAL ">=")
|
||||
if ("${${option}}" GREATER_EQUAL "${value}")
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
elseif ("${comp}" STREQUAL "<")
|
||||
if ("${${option}}" LESS "${value}")
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
elseif ("${comp}" STREQUAL "<=")
|
||||
if ("${${option}}" LESS_EQUAL "${value}")
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Could not parse embree_option condition: ${condition}")
|
||||
endif()
|
||||
|
||||
ENDFUNCTION()
|
||||
|
||||
# Checks multiple options from a list with EMBREE_TESTING_CHECK_OPTION
|
||||
FUNCTION (EMBREE_TESTING_CHECK_OPTIONS_LIST out conditions)
|
||||
SET(${out} 1 PARENT_SCOPE)
|
||||
FOREACH (c ${conditions})
|
||||
EMBREE_TESTING_CHECK_OPTION(myout ${c})
|
||||
|
||||
IF (myout EQUAL 0)
|
||||
SET(${out} 0 PARENT_SCOPE)
|
||||
BREAK()
|
||||
ENDIF()
|
||||
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_GENERIC_CPP_TEST testname executable args)
|
||||
IF (BUILD_TESTING)
|
||||
ADD_TEST(NAME ${testname}
|
||||
WORKING_DIRECTORY "${MY_PROJECT_BINARY_DIR}"
|
||||
COMMAND ${executable} ${args})
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_GENERIC_ISPC_TEST testname executable args)
|
||||
IF (BUILD_TESTING AND EMBREE_ISPC_SUPPORT AND EMBREE_RAY_PACKETS)
|
||||
ADD_TEST(NAME ${testname}_ispc
|
||||
WORKING_DIRECTORY "${MY_PROJECT_BINARY_DIR}"
|
||||
COMMAND ${executable}_ispc ${args})
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_GENERIC_SYCL_TEST testname executable args)
|
||||
IF (BUILD_TESTING AND EMBREE_SYCL_SUPPORT)
|
||||
ADD_TEST(NAME ${testname}_sycl
|
||||
WORKING_DIRECTORY ${MY_PROJECT_BINARY_DIR}
|
||||
COMMAND ${executable}_sycl ${args})
|
||||
SET_TESTS_PROPERTIES(${testname}_sycl PROPERTIES TIMEOUT 50)
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_TEST testname executable args)
|
||||
# Check if we should dump the output of this tests
|
||||
LIST(FIND EMBREE_TESTING_DUMPTESTS ${testname} dumptest)
|
||||
if (NOT(EMBREE_TESTING_DUMPFORMAT))
|
||||
SET(EMBREE_TESTING_DUMPFORMAT "tga")
|
||||
endif()
|
||||
set(DUMP_ARG "")
|
||||
IF(NOT(${dumptest} EQUAL -1))
|
||||
file(MAKE_DIRECTORY "${PROJECT_SOURCE_DIR}/tests/dump")
|
||||
set(argsx "${args} -o ${PROJECT_SOURCE_DIR}/tests/dump/${testname}.${EMBREE_TESTING_DUMPFORMAT}")
|
||||
ELSE()
|
||||
set(argsx ${args})
|
||||
ENDIF()
|
||||
|
||||
# By default add tests for all executables
|
||||
SET (extra_args ${ARGN})
|
||||
LIST(APPEND extra_args cpp)
|
||||
LIST(APPEND extra_args ispc)
|
||||
LIST(APPEND extra_args sycl)
|
||||
LIST(REMOVE_DUPLICATES extra_args)
|
||||
|
||||
# Exclude exe with '!'
|
||||
LIST(FIND extra_args "!cpp" p)
|
||||
if (NOT (${p} EQUAL -1))
|
||||
LIST(REMOVE_ITEM extra_args "!cpp")
|
||||
LIST(REMOVE_ITEM extra_args "cpp")
|
||||
endif()
|
||||
|
||||
LIST(FIND extra_args "!ispc" p)
|
||||
if (NOT (${p} EQUAL -1))
|
||||
LIST(REMOVE_ITEM extra_args "!ispc")
|
||||
LIST(REMOVE_ITEM extra_args "ispc")
|
||||
endif()
|
||||
|
||||
LIST(FIND extra_args "!sycl" p)
|
||||
if (NOT (${p} EQUAL -1))
|
||||
LIST(REMOVE_ITEM extra_args "!sycl")
|
||||
LIST(REMOVE_ITEM extra_args "sycl")
|
||||
endif()
|
||||
|
||||
# Add the tests
|
||||
FOREACH(loopvar ${extra_args})
|
||||
if((NOT ${EMBREE_SYCL_SUPPORT}) OR (NOT ${EMBREE_TESTING_ONLY_SYCL_TESTS}))
|
||||
if(${loopvar} STREQUAL "cpp")
|
||||
ADD_EMBREE_GENERIC_CPP_TEST(${testname} ${executable} ${argsx})
|
||||
ENDIF()
|
||||
if(${loopvar} STREQUAL "ispc")
|
||||
ADD_EMBREE_GENERIC_ISPC_TEST(${testname} ${executable} ${argsx})
|
||||
ENDIF()
|
||||
endif()
|
||||
if(${loopvar} STREQUAL "sycl")
|
||||
ADD_EMBREE_GENERIC_SYCL_TEST(${testname} ${executable} ${argsx})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_TUTORIAL_TEST name args)
|
||||
ADD_EMBREE_TEST(${name} embree_${name} "--compare ${PROJECT_SOURCE_DIR}/tests/models/reference/${name}.exr ${args}" ${ARGN})
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_PRIMITIVE_TEST xml shader)
|
||||
EMBREE_TEST_CHECK_OPTIONS("${xml}.embree_options" out)
|
||||
IF (${out} EQUAL 1)
|
||||
|
||||
GET_FILENAME_COMPONENT(FN ${xml} NAME_WE)
|
||||
SET(testname "prim_${FN}_${shader}")
|
||||
SET(compare_threshold "55")
|
||||
|
||||
# TODO: APPLE with AVX2 enabled have a sphere cap intersection problem with linear curves
|
||||
IF ((testname MATCHES "prim_curves_linear_flat.*") AND ((testname MATCHES ".*uv") OR testname MATCHES ".*Ng"))
|
||||
IF (APPLE AND (EMBREE_ISA_AVX2 OR EMBREE_ISA_AVX512))
|
||||
SET(compare_threshold "200")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(args "-i ${xml} --shader ${shader} --time 0.5 --compare ${PROJECT_SOURCE_DIR}/tests/primitives/reference/${testname}.exr --compare-threshold ${compare_threshold}")
|
||||
ADD_EMBREE_TEST(${testname} embree_viewer ${args})
|
||||
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_MODEL_TEST testname executable model reference args)
|
||||
EMBREE_TEST_CHECK_OPTIONS("${PROJECT_SOURCE_DIR}/tests/models/${model}.embree_options" out)
|
||||
IF (${out} EQUAL 1)
|
||||
|
||||
SET(extra_args ${ARGN})
|
||||
IF ("${testname}" MATCHES ".*subdiv.*") # skip subdiv models for SYCL mode
|
||||
LIST(APPEND extra_args !sycl)
|
||||
ENDIF()
|
||||
|
||||
SET(argsx "-c ${PROJECT_SOURCE_DIR}/tests/models/${model} --compare ${PROJECT_SOURCE_DIR}/tests/models/reference/${reference}.exr ${args}")
|
||||
ADD_EMBREE_TEST(${testname} ${executable} ${argsx} ${extra_args})
|
||||
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO (ADD_EMBREE_MODELS_TEST model_list_file testname executable reference args)
|
||||
IF (BUILD_TESTING)
|
||||
|
||||
SET(full_model_list_file "${PROJECT_SOURCE_DIR}/tests/models/${model_list_file}")
|
||||
|
||||
IF(NOT EXISTS "${full_model_list_file}")
|
||||
MESSAGE(FATAL_ERROR "File ${PROJECT_SOURCE_DIR}/tests/models/${model_list_file} does not exist!")
|
||||
ENDIF()
|
||||
|
||||
FILE(READ "${full_model_list_file}" models)
|
||||
STRING(REGEX REPLACE "\n" ";" models "${models}")
|
||||
|
||||
FOREACH (model ${models})
|
||||
IF (model MATCHES "^#")
|
||||
CONTINUE()
|
||||
ENDIF()
|
||||
IF (model MATCHES ".*mblur.*" OR model MATCHES ".*motion_blur.*") # skip mblur models if motion blur is not enabled
|
||||
IF (NOT EMBREE_SYCL_MBLUR)
|
||||
CONTINUE()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
STRING(REGEX REPLACE " .*" "" modelname "${model}")
|
||||
STRING(REGEX REPLACE "/" "_" modelname "${modelname}")
|
||||
STRING(REGEX REPLACE ".ecs" "" modelname "${modelname}")
|
||||
|
||||
ADD_EMBREE_MODEL_TEST(${testname}_${modelname} ${executable} ${model} ${reference}_${modelname} "${args}")
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# add klocwork test
|
||||
IF (EMBREE_TESTING_KLOCWORK)
|
||||
ADD_TEST(NAME Klocwork-Build WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/klocwork_build.sh")
|
||||
ADD_TEST(NAME Klocwork-Check WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/klocwork_check.sh")
|
||||
SET_TESTS_PROPERTIES(Klocwork-Build PROPERTIES TIMEOUT 2400)
|
||||
SET_TESTS_PROPERTIES(Klocwork-Check PROPERTIES TIMEOUT 300)
|
||||
ENDIF()
|
||||
|
||||
# add valgrind test
|
||||
IF (EMBREE_TESTING_MEMCHECK)
|
||||
find_program( EMBREE_MEMORYCHECK_COMMAND valgrind )
|
||||
set( EMBREE_MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full --show-leak-kinds=definite --errors-for-leak-kinds=definite --error-exitcode=1" )
|
||||
IF (NOT EMBREE_MEMORYCHECK_COMMAND)
|
||||
MESSAGE(FATAL_ERROR "valgrind not found")
|
||||
ENDIF()
|
||||
FUNCTION(ADD_MEMCHECK_TEST name binary)
|
||||
set(memcheck_command "${EMBREE_MEMORYCHECK_COMMAND} ${EMBREE_MEMORYCHECK_COMMAND_OPTIONS}")
|
||||
separate_arguments(memcheck_command)
|
||||
add_test(NAME ${name} COMMAND ${memcheck_command} "${MY_PROJECT_BINARY_DIR}/${binary}" ${ARGN})
|
||||
ENDFUNCTION()
|
||||
ENDIF()
|
||||
|
||||
|
||||
# looks for ifile in multiple possible locations and outputs a file with absolute path in ofile
|
||||
FUNCTION (EMBREE_FIND_TEST_FILE ifile ofile errmsgflavor)
|
||||
if (EXISTS "${ifile}") # abs path, use get_filename_component because it could also be relative to cwd
|
||||
get_filename_component(absifile "${ifile}" ABSOLUTE)
|
||||
SET(${ofile} ${absifile} PARENT_SCOPE)
|
||||
elseif(EXISTS "${PROJECT_SOURCE_DIR}/tests/${ifile}") # testing dir
|
||||
set(${ofile} "${PROJECT_SOURCE_DIR}/tests/${ifile}" PARENT_SCOPE)
|
||||
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ifile}") # relative to source folder
|
||||
set(${ofile} "${CMAKE_CURRENT_SOURCE_DIR}/${ifile}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${ofile} "" PARENT_SCOPE)
|
||||
if (errmsgflavor)
|
||||
message(FATAL_ERROR
|
||||
"Could not find ${errmsgflavor} \"${ifile}\"\n"
|
||||
"looked for:\n"
|
||||
" ${inputfile}\n"
|
||||
" ${PROJECT_SOURCE_DIR}/tests/${ifile}\n"
|
||||
" ${CMAKE_CURRENT_SOURCE_DIR}/${ifile}\n"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
ENDFUNCTION()
|
||||
|
||||
|
||||
FUNCTION (EMBREE_ADD_TEST_PARSE_SUBLIST args keyword sublist)
|
||||
SET(myargs ${args})
|
||||
SET(mysublist "")
|
||||
SET(keywords "ECS;XML;NO_REFERENCE;REFERENCE;REFERENCE_SUFFIX;INTENSITY;CONDITION_FILE;CONDITION;ARGS;NO_CPP;NO_ISPC;NO_SYCL;GEN_REFERENCE;")
|
||||
|
||||
list(FIND nargs ${keyword} istart)
|
||||
if (NOT(istart EQUAL -1))
|
||||
list(LENGTH myargs iend)
|
||||
foreach(k ${keywords})
|
||||
list(FIND myargs ${k} i)
|
||||
if (NOT(i EQUAL -1) AND (i GREATER istart) AND (i LESS iend))
|
||||
SET(iend ${i})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
MATH(EXPR i "${istart}+1")
|
||||
while (i LESS iend)
|
||||
list(GET myargs ${i} elem)
|
||||
list(APPEND mysublist ${elem})
|
||||
MATH(EXPR i "${i}+1")
|
||||
endwhile()
|
||||
endif()
|
||||
|
||||
SET(${sublist} ${mysublist} PARENT_SCOPE)
|
||||
ENDFUNCTION()
|
||||
|
||||
FUNCTION (EMBREE_ADD_TEST_PARSE_FLAG args keyword value)
|
||||
SET(myargs ${args})
|
||||
SET(${value} OFF PARENT_SCOPE)
|
||||
list(FIND nargs ${keyword} i)
|
||||
if (NOT(i EQUAL -1))
|
||||
SET(${value} ON PARENT_SCOPE)
|
||||
endif()
|
||||
ENDFUNCTION()
|
||||
|
||||
# ADD_EMBREE_TEST_ECS(testname exename [ECS <file> | XML <file>] [NO_REFERENCE | REFERENCE <path> | REFERENCE_SUFFIX <suffix>] [INTENSITY <i>] [CONDITION <conds>] [ARGS <args>] [GEN_REFERENCE])
|
||||
# [ECS <file> | XML <inputfile> | OPTIONS <inputfile>]
|
||||
# - looks for file and calls the test command with either "-c <inputfile>.ecs" or "-i <inputfile>.xml"
|
||||
#
|
||||
# [NO_REFERENCE | REFERENCE <path> | REFERENCE_SUFFIX <suffix>]
|
||||
# - if not found a reference is will be expected in the same folder as *.ecs with name *.ecs.exename.exr
|
||||
# - NO_REFERENCE: don't look for a reference (no --compare in test command)
|
||||
# - REFERENCE <path>: use the reference located in <path>. Same rules aplly as for finding ecs files: absolute or relative to CMAKE_CURRENT_SOURCE_DIR path, must not be located outside the embree root dir.
|
||||
# - REFERENCE_SUFFIX <suffix>: use the default reference location and name with a suffix before the last file extension, e.g. *.ecs.exename<suffix>.exr
|
||||
# - if this argument is not specified, looks for
|
||||
# 1. <inputfile>.exename.exr, or
|
||||
# 2. <testname>.exr, if no <inputfile> was given
|
||||
#
|
||||
# [INTENSITY <i>]
|
||||
# - default i = 1
|
||||
# - sets the intensity level for the test, test is only run if ${EMBREE_TESTING_INTENSITY} GREATER_EQUAL i
|
||||
# - could be done with an *.embree_options file, but this is more flexible, e.g. you can easier share reference images without specifying an absolute path
|
||||
# - DOES NOT overrite EMBREE_TESTING_INTENSITY, if specified in *.embree_options
|
||||
#
|
||||
# [CONDITION_FILE <file>]
|
||||
# - file containing additional conditions
|
||||
# - conditions are specified linewise in form of: EMBREE_OPTION op VALUE, where EMBREE_OPTION is a cmake variable used during embree configuration and op is one of ==, !=, <, <=, >, >=
|
||||
# - if this argument is not specified, looks for
|
||||
# 1. <inputfile>.embree_options, or
|
||||
# 2. <testname>.embree_options, if no <inputfile> was given
|
||||
#
|
||||
# [CONDITION <conds>]
|
||||
# - cmake list of additional conditions, specified the same way as in an embree_options file
|
||||
#
|
||||
# [ARGS <args>]
|
||||
# - additional arguments for the test command
|
||||
#
|
||||
# [GEN_REFERENCE]
|
||||
# - writes the reference to the expected location
|
||||
# - could also be done with the ARGS parameter, but this way we don't have to deal with paths
|
||||
#
|
||||
# EXAMPLES
|
||||
#
|
||||
# all optional arguments default,
|
||||
# - looks for points.ecs.embree_options to filter out test by configured options, if not found no restrictions
|
||||
# - runs for EMBREE_TESTING_INTENSITY >= 1
|
||||
# - reference will be expected in the same folder as points.ecs with name points.ecs.embree_viewer.exr
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "models/xxx/points.ecs") # 1)
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "${PROJECT_SOURCE_DIR}/models/xxx/points.ecs") # 2) same as 1) but with absolute path to ecs
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "points.ecs") # 3) same as 1) but looks for points.ecs in the ${CMAKE_CURRENT_SOURCE_DIR} i.e. <embree_root>/tutorials/viewer/points.ecs
|
||||
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "models/xxx/points.ecs" ARGS --coherent INTENSITY 2) # 4) same as 1) but runs only at EMBREE_TESTING_INTENSITY >= 2
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "models/xxx/points.ecs" REFERENCE_SUFFIX "_quads" ARGS
|
||||
# --coherent
|
||||
# --convert-triangles-to-quads INTENSITY 2) # 5) same as 4) but expects reference name points.ecr.embree_viewer_quads.ecs
|
||||
#ADD_EMBREE_TEST_ECS(viewer_points embree_viewer "models/xxx/points.ecs" REFERENCE "special.exr" ARGS
|
||||
# --coherent
|
||||
# --convert-triangles-to-quads INTENSITY 2) # 5) same as 4) but expects reference <embree-root>/tutorials/viewer/special.exr
|
||||
## 1) - 5) all share the same base input arguments defined in points.ecs as well as the points.ecs.embree_options
|
||||
|
||||
#ADD_EMBREE_TEST_ECS(point_geometry embree_point_geometry) # 6) no ecs file, uses point_geometry.embree_options if exists, expects reference ${CMAKE_CURRENT_SOURCE_DIR}/point_geometry.exr
|
||||
#ADD_EMBREE_TEST_ECS(verify verify NO_REFERENCE) # 7) no ecs file, uses verify.embree_options if exists, no reference
|
||||
#ADD_EMBREE_TEST_ECS(verify_memcheck verify NO_REFERENCE CONDITIONS "EMBREE_TESTING_MEMCHECK == ON") # 8) same as 7) but with extra condition
|
||||
|
||||
FUNCTION (ADD_EMBREE_TEST_ECS testname executable)
|
||||
SET(nargs ${ARGN})
|
||||
|
||||
# disable everything
|
||||
SET(testnamedef EMBREE_TEST_${testname}_DEFINED)
|
||||
SET(${testnamedef} "0" CACHE INTERNAL "")
|
||||
SET(testnamedef EMBREE_TEST_${testname}_ispc_DEFINED)
|
||||
SET(${testnamedef} "0" CACHE INTERNAL "")
|
||||
SET(testnamedef EMBREE_TEST_${testname}_sycl_DEFINED)
|
||||
SET(${testnamedef} "0" CACHE INTERNAL "")
|
||||
|
||||
# parsing input file
|
||||
# ECS mode -> single parameter with filename after ECS keyword
|
||||
list(FIND nargs "ECS" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
SET(inputtype "-c")
|
||||
MATH(EXPR i "${i}+1")
|
||||
list(GET nargs ${i} out)
|
||||
EMBREE_FIND_TEST_FILE("${out}" inputfile "test file")
|
||||
endif()
|
||||
# XML mode -> single parameter with filename after XML keyword
|
||||
list(FIND nargs "XML" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
SET(inputtype "-i")
|
||||
MATH(EXPR i "${i}+1")
|
||||
list(GET nargs ${i} out)
|
||||
EMBREE_FIND_TEST_FILE("${out}" inputfile "test file")
|
||||
endif()
|
||||
# no filetype keyword -> look for <testname>.ecs/xml
|
||||
# does not need to be specified
|
||||
if (NOT inputtype)
|
||||
EMBREE_FIND_TEST_FILE("${testname}.ecs" inputfile "")
|
||||
if(inputfile)
|
||||
SET(inputtype "-c")
|
||||
endif()
|
||||
EMBREE_FIND_TEST_FILE("${testname}.ecs" inputfile "")
|
||||
if(inputfile)
|
||||
SET(inputtype "-i")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# parsing refernce image
|
||||
# no reference image mode -> no additional parameter to parse
|
||||
list(FIND nargs "NO_REFERENCE" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
SET(no_reference ON)
|
||||
endif()
|
||||
# reference suffix mode -> singe parameter with suffix to default reference file name
|
||||
list(FIND nargs "REFERENCE_SUFFIX" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
MATH(EXPR i "${i}+1")
|
||||
list(GET nargs ${i} out)
|
||||
EMBREE_FIND_TEST_FILE("${inputfile}.${executable}${out}.exr" referencefile "reference image")
|
||||
endif()
|
||||
# reference mode -> singe parameter with absolute path to reference image
|
||||
list(FIND nargs "REFERENCE" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
MATH(EXPR i "${i}+1")
|
||||
list(GET nargs ${i} out)
|
||||
EMBREE_FIND_TEST_FILE("${out}" referencefile "reference image")
|
||||
endif()
|
||||
# no reference keyword -> look for <testname>.exr and <inputfile>.<executable>.exr respectively
|
||||
if ((NOT no_reference) AND (NOT referencefile))
|
||||
if (NOT inputfile)
|
||||
EMBREE_FIND_TEST_FILE("${testname}.exr" referencefile "reference image")
|
||||
else()
|
||||
EMBREE_FIND_TEST_FILE("${inputfile}.${executable}.exr" referencefile "reference image")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# parsing intensity
|
||||
# single integer parameter
|
||||
SET(intensity 1)
|
||||
list(FIND nargs "INTENSITY" i)
|
||||
if (NOT(i EQUAL -1))
|
||||
MATH(EXPR i "${i}+1")
|
||||
list(GET nargs ${i} intensity)
|
||||
endif()
|
||||
|
||||
# parsing condition
|
||||
SET(conditions "")
|
||||
SET(conditionsfile)
|
||||
list(FIND nargs "CONDITION_FILE" i)
|
||||
# condition file -> single parameter to absolute path of conditions file
|
||||
if (NOT(i EQUAL -1))
|
||||
list(GET nargs ${i} conditionsfile)
|
||||
EMBREE_FIND_TEST_FILE("${conditionsfile}" conditionsfile "")
|
||||
# no <inputfile> specified -> look for <testname>.embree_options
|
||||
elseif (NOT inputtype)
|
||||
EMBREE_FIND_TEST_FILE("${testname}.embree_options" conditionsfile "")
|
||||
# <inputfile> specified -> look for <inputfile>.embree_options
|
||||
else()
|
||||
EMBREE_FIND_TEST_FILE("${inputfile}.embree_options" conditionsfile "")
|
||||
endif()
|
||||
if (conditionsfile)
|
||||
file(READ "${conditionsfile}" lines)
|
||||
string(REGEX REPLACE "\n" ";" conditions "${lines}")
|
||||
endif()
|
||||
|
||||
# parsing additional conditions
|
||||
EMBREE_ADD_TEST_PARSE_SUBLIST("${nargs}" "CONDITION" extra_conditions)
|
||||
list(APPEND conditions ${extra_conditions})
|
||||
|
||||
# parsing extra args
|
||||
EMBREE_ADD_TEST_PARSE_SUBLIST("${nargs}" "ARGS" extraargs)
|
||||
|
||||
EMBREE_ADD_TEST_PARSE_FLAG("${nargs}" "MEMCHECK" memcheck)
|
||||
EMBREE_ADD_TEST_PARSE_FLAG("${nargs}" "NO_CPP" no_cpp)
|
||||
EMBREE_ADD_TEST_PARSE_FLAG("${nargs}" "NO_ISPC" no_ispc)
|
||||
EMBREE_ADD_TEST_PARSE_FLAG("${nargs}" "NO_SYCL" no_sycl)
|
||||
EMBREE_ADD_TEST_PARSE_FLAG("${nargs}" "GEN_REFERENCE" gen_reference)
|
||||
|
||||
# add the test, if the conditions are met
|
||||
SET(matchconditions ON)
|
||||
if (conditions)
|
||||
EMBREE_TESTING_CHECK_OPTIONS_LIST(out "${conditions}")
|
||||
if (out EQUAL 0)
|
||||
SET(matchconditions OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# LESS_EQUAL not supported on all CI runners
|
||||
if (matchconditions AND ((intensity LESS EMBREE_TESTING_INTENSITY) OR (intensity EQUAL EMBREE_TESTING_INTENSITY)))
|
||||
SET(args "")
|
||||
if (inputfile)
|
||||
list(APPEND args "${inputtype} ${inputfile}")
|
||||
endif()
|
||||
if (NOT no_reference)
|
||||
list(APPEND args "--compare ${referencefile}")
|
||||
endif()
|
||||
if (gen_reference)
|
||||
list(APPEND args "-o ${referencefile}")
|
||||
endif()
|
||||
foreach(a ${extraargs})
|
||||
list(APPEND args "${a}")
|
||||
endforeach()
|
||||
|
||||
if (memcheck)
|
||||
list(PREPEND args "${MY_PROJECT_BINARY_DIR}/${executable}")
|
||||
list(PREPEND args "${EMBREE_MEMORYCHECK_COMMAND_OPTIONS}")
|
||||
if((NOT ${EMBREE_SYCL_SUPPORT}) OR (NOT ${EMBREE_TESTING_ONLY_SYCL_TESTS}))
|
||||
if (NOT(no_cpp))
|
||||
ADD_EMBREE_GENERIC_CPP_TEST(${testname} ${EMBREE_MEMORYCHECK_COMMAND} ${args})
|
||||
endif()
|
||||
if (NOT(no_ispc))
|
||||
ADD_EMBREE_GENERIC_ISPC_TEST(${testname} ${EMBREE_MEMORYCHECK_COMMAND} ${args})
|
||||
endif()
|
||||
endif()
|
||||
if (NOT(no_sycl))
|
||||
ADD_EMBREE_GENERIC_SYCL_TEST(${testname} ${EMBREE_MEMORYCHECK_COMMAND} ${args})
|
||||
endif()
|
||||
else()
|
||||
if((NOT ${EMBREE_SYCL_SUPPORT}) OR (NOT ${EMBREE_TESTING_ONLY_SYCL_TESTS}))
|
||||
if (NOT(no_cpp))
|
||||
ADD_EMBREE_GENERIC_CPP_TEST(${testname} ${executable} ${args})
|
||||
endif()
|
||||
if (NOT(no_ispc))
|
||||
ADD_EMBREE_GENERIC_ISPC_TEST(${testname} ${executable} ${args})
|
||||
endif()
|
||||
endif()
|
||||
if (NOT(no_sycl))
|
||||
ADD_EMBREE_GENERIC_SYCL_TEST(${testname} ${executable} ${args})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if (EMBREE_TESTING_INSTALL_TESTS)
|
||||
if (inputfile)
|
||||
get_filename_component(inputpath ${inputfile} DIRECTORY)
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" inputpath "${inputpath}")
|
||||
INSTALL(FILES "${inputfile}"
|
||||
DESTINATION "${CMAKE_INSTALL_TESTDIR}/${inputpath}"
|
||||
COMPONENT testing)
|
||||
endif()
|
||||
|
||||
if (conditionsfile)
|
||||
get_filename_component(conditionspath ${conditionsfile} DIRECTORY)
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" conditionspath "${conditionspath}")
|
||||
INSTALL(FILES "${conditionsfile}"
|
||||
DESTINATION "${CMAKE_INSTALL_TESTDIR}/${conditionspath}"
|
||||
COMPONENT testing)
|
||||
endif()
|
||||
|
||||
if (referencefile)
|
||||
get_filename_component(referencepath ${referencefile} DIRECTORY)
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" referencepath "${referencepath}")
|
||||
INSTALL(FILES "${referencefile}"
|
||||
DESTINATION "${CMAKE_INSTALL_TESTDIR}/${referencepath}"
|
||||
COMPONENT testing)
|
||||
endif()
|
||||
|
||||
SET(testcall "ADD_EMBREE_TEST_ECS(${testname} ${executable}")
|
||||
if (inputfile)
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" inputfile "${inputfile}")
|
||||
if (inputtype STREQUAL "-c")
|
||||
SET(testcall "${testcall} \n ECS ${inputfile}")
|
||||
elseif (inputtype STREQUAL "-i")
|
||||
SET(testcall "${testcall} \n XML ${inputfile}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (no_reference)
|
||||
SET(testcall "${testcall} \n NO_REFERENCE")
|
||||
else()
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" referencefile "${referencefile}")
|
||||
SET(testcall "${testcall} \n REFERENCE ${referencefile}")
|
||||
endif()
|
||||
|
||||
SET(testcall "${testcall} \n INTENSITY ${intensity}")
|
||||
STRING(REPLACE "${PROJECT_SOURCE_DIR}/" "" conditionsfile "${conditionsfile}")
|
||||
SET(testcall "${testcall} \n CONDITION_FILE ${conditionsfile}")
|
||||
SET(testcall "${testcall} \n CONDITION ")
|
||||
foreach(c ${conditions})
|
||||
SET(testcall "${testcall} \"${c}\"")
|
||||
endforeach()
|
||||
SET(testcall "${testcall} \n ARGS ")
|
||||
foreach(a ${extraargs})
|
||||
SET(testcall "${testcall} ${a}")
|
||||
endforeach()
|
||||
|
||||
SET(testcall "${testcall})\n\n")
|
||||
file(APPEND "${EMBREE_INSTALL_CTESTTESTFILE}" "${testcall}")
|
||||
endif()
|
||||
ENDFUNCTION()
|
||||
|
||||
# add klocwork test
|
||||
IF (EMBREE_TESTING_KLOCWORK)
|
||||
ADD_TEST(NAME Klocwork-Build WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/klocwork_build.sh")
|
||||
ADD_TEST(NAME Klocwork-Check WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND "${PROJECT_SOURCE_DIR}/scripts/klocwork_check.sh")
|
||||
SET_TESTS_PROPERTIES(Klocwork-Build PROPERTIES TIMEOUT 2400)
|
||||
SET_TESTS_PROPERTIES(Klocwork-Check PROPERTIES TIMEOUT 300)
|
||||
ENDIF()
|
||||
|
||||
else()
|
||||
FUNCTION(ADD_EMBREE_TEST_ECS testname executable)
|
||||
ENDFUNCTION()
|
||||
FUNCTION(SET_EMBREE_TEST_PROPERTIES testname)
|
||||
ENDFUNCTION()
|
||||
endif()
|
||||
+2
-25
@@ -212,15 +212,11 @@
|
||||
#define PRINT2(x,y) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << embree_endl
|
||||
#define PRINT3(x,y,z) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << embree_endl
|
||||
#define PRINT4(x,y,z,w) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl
|
||||
#define PRINT5(x,y,z,w,a) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << ", " << STRING(a) << " = " << (a) << embree_endl
|
||||
#define PRINT6(x,y,z,w,a,b) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << ", " << STRING(a) << " = " << (a) << ", " << STRING(b) << " = " << (b) << embree_endl
|
||||
|
||||
#define UPRINT(x) embree_cout_uniform << STRING(x) << " = " << (x) << embree_endl
|
||||
#define UPRINT2(x,y) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << embree_endl
|
||||
#define UPRINT3(x,y,z) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << embree_endl
|
||||
#define UPRINT4(x,y,z,w) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl
|
||||
#define UPRINT5(x,y,z,w,a) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << ", " << STRING(a) << " = " << (a) << embree_endl
|
||||
#define UPRINT6(x,y,z,w,a,b) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << ", " << STRING(a) << " = " << (a) << ", " << STRING(b) << " = " << (b) << embree_endl
|
||||
|
||||
#if defined(DEBUG) // only report file and line in debug mode
|
||||
#define THROW_RUNTIME_ERROR(str) \
|
||||
@@ -365,15 +361,9 @@ __forceinline std::string toString(long long value) {
|
||||
/// SYCL specific
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__SYCL_DEVICE_ONLY__)
|
||||
# define EMBREE_SYCL_SIMD(N) [[intel::reqd_sub_group_size(N)]]
|
||||
#else
|
||||
# define EMBREE_SYCL_SIMD(N)
|
||||
#endif
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
|
||||
#define sycl_printf0(format, ...) { \
|
||||
static const CONSTANT char fmt[] = format; \
|
||||
if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) \
|
||||
@@ -447,20 +437,7 @@ namespace embree
|
||||
|
||||
return cout;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) and defined(__INTEL_LLVM_COMPILER)
|
||||
inline sycl_ostream_ operator <<(sycl_ostream_ cout, size_t i)
|
||||
{
|
||||
if (cout.uniform) {
|
||||
if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true)))
|
||||
sycl_printf("%i",i);
|
||||
} else {
|
||||
sycl_printf("%i ",i);
|
||||
}
|
||||
return cout;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
inline sycl_ostream_ operator <<(sycl_ostream_ cout, float f)
|
||||
{
|
||||
if (cout.uniform) {
|
||||
@@ -483,7 +460,7 @@ namespace embree
|
||||
return cout;
|
||||
}
|
||||
|
||||
inline sycl_ostream_ operator <<(sycl_ostream_ cout, ulong l)
|
||||
inline sycl_ostream_ operator <<(sycl_ostream_ cout, uint64_t l)
|
||||
{
|
||||
if (cout.uniform) {
|
||||
if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true)))
|
||||
|
||||
+40
-44
@@ -20,20 +20,16 @@ using sycl::uint8;
|
||||
using sycl::uint4;
|
||||
using sycl::uint3;
|
||||
using sycl::uint2;
|
||||
using sycl::uint;
|
||||
using sycl::ulong;
|
||||
using sycl::uchar16;
|
||||
using sycl::uchar8;
|
||||
using sycl::uchar4;
|
||||
using sycl::uchar3;
|
||||
using sycl::uchar2;
|
||||
using sycl::uchar;
|
||||
using sycl::ushort16;
|
||||
using sycl::ushort8;
|
||||
using sycl::ushort4;
|
||||
using sycl::ushort3;
|
||||
using sycl::ushort2;
|
||||
using sycl::ushort;
|
||||
|
||||
using sycl::fmax;
|
||||
using sycl::fmin;
|
||||
@@ -51,7 +47,7 @@ SYCL_EXTERNAL extern float atomic_min(volatile LOCAL float *p, float val);
|
||||
SYCL_EXTERNAL extern float atomic_max(volatile GLOBAL float *p, float val);
|
||||
SYCL_EXTERNAL extern float atomic_max(volatile LOCAL float *p, float val);
|
||||
|
||||
SYCL_EXTERNAL extern "C" uint intel_sub_group_ballot(bool valid);
|
||||
SYCL_EXTERNAL extern "C" unsigned int intel_sub_group_ballot(bool valid);
|
||||
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_assume_uniform(void *p);
|
||||
|
||||
@@ -91,32 +87,32 @@ SYCL_EXTERNAL extern "C" void __builtin_IB_assume_uniform(void *p);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL /* extern "C" */ uint __builtin_IB_lsc_load_global_uchar_to_uint (const GLOBAL sycl::uchar *base, int elemOff, enum LSC_LDCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL /* extern "C" */ uint __builtin_IB_lsc_load_global_ushort_to_uint(const GLOBAL sycl::ushort *base, int elemOff, enum LSC_LDCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL /* extern "C" */ uint __builtin_IB_lsc_load_global_uint (const GLOBAL sycl::uint *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint2 __builtin_IB_lsc_load_global_uint2 (const GLOBAL sycl::uint2 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint3 __builtin_IB_lsc_load_global_uint3 (const GLOBAL sycl::uint3 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint4 __builtin_IB_lsc_load_global_uint4 (const GLOBAL sycl::uint4 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint8 __builtin_IB_lsc_load_global_uint8 (const GLOBAL sycl::uint8 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong __builtin_IB_lsc_load_global_ulong (const GLOBAL sycl::ulong *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong2 __builtin_IB_lsc_load_global_ulong2(const GLOBAL sycl::ulong2 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V2
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong3 __builtin_IB_lsc_load_global_ulong3(const GLOBAL sycl::ulong3 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V3
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong4 __builtin_IB_lsc_load_global_ulong4(const GLOBAL sycl::ulong4 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V4
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong8 __builtin_IB_lsc_load_global_ulong8(const GLOBAL sycl::ulong8 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V8
|
||||
SYCL_EXTERNAL /* extern "C" */ uint32_t __builtin_IB_lsc_load_global_uchar_to_uint (const GLOBAL uint8_t *base, int elemOff, enum LSC_LDCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL /* extern "C" */ uint32_t __builtin_IB_lsc_load_global_ushort_to_uint(const GLOBAL uint16_t *base, int elemOff, enum LSC_LDCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL /* extern "C" */ uint32_t __builtin_IB_lsc_load_global_uint (const GLOBAL uint32_t *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint2 __builtin_IB_lsc_load_global_uint2 (const GLOBAL sycl::uint2 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint3 __builtin_IB_lsc_load_global_uint3 (const GLOBAL sycl::uint3 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint4 __builtin_IB_lsc_load_global_uint4 (const GLOBAL sycl::uint4 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::uint8 __builtin_IB_lsc_load_global_uint8 (const GLOBAL sycl::uint8 *base, int elemOff, enum LSC_LDCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL /* extern "C" */ uint64_t __builtin_IB_lsc_load_global_ulong (const GLOBAL uint64_t *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong2 __builtin_IB_lsc_load_global_ulong2 (const GLOBAL sycl::ulong2 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V2
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong3 __builtin_IB_lsc_load_global_ulong3 (const GLOBAL sycl::ulong3 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V3
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong4 __builtin_IB_lsc_load_global_ulong4 (const GLOBAL sycl::ulong4 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V4
|
||||
SYCL_EXTERNAL /* extern "C" */ sycl::ulong8 __builtin_IB_lsc_load_global_ulong8 (const GLOBAL sycl::ulong8 *base, int elemOff, enum LSC_LDCC cacheOpt); //D64V8
|
||||
|
||||
// global address space
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uchar_from_uint (GLOBAL sycl::uchar *base, int immElemOff, uint val, enum LSC_STCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ushort_from_uint(GLOBAL sycl::ushort *base, int immElemOff, uint val, enum LSC_STCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint (GLOBAL sycl::uint *base, int immElemOff, uint val, enum LSC_STCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint2 (GLOBAL sycl::uint2 *base, int immElemOff, sycl::uint2 val, enum LSC_STCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint3 (GLOBAL sycl::uint3 *base, int immElemOff, sycl::uint3 val, enum LSC_STCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint4 (GLOBAL sycl::uint4 *base, int immElemOff, sycl::uint4 val, enum LSC_STCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint8 (GLOBAL sycl::uint8 *base, int immElemOff, sycl::uint8 val, enum LSC_STCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong (GLOBAL sycl::ulong *base, int immElemOff, sycl::ulong val, enum LSC_STCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong2(GLOBAL sycl::ulong2 *base, int immElemOff, sycl::ulong2 val, enum LSC_STCC cacheOpt); //D64V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong3(GLOBAL sycl::ulong3 *base, int immElemOff, sycl::ulong3 val, enum LSC_STCC cacheOpt); //D64V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong4(GLOBAL sycl::ulong4 *base, int immElemOff, sycl::ulong4 val, enum LSC_STCC cacheOpt); //D64V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong8(GLOBAL sycl::ulong8 *base, int immElemOff, sycl::ulong8 val, enum LSC_STCC cacheOpt); //D64V8
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uchar_from_uint (GLOBAL uint8_t *base, int immElemOff, uint32_t val, enum LSC_STCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ushort_from_uint(GLOBAL uint16_t *base, int immElemOff, uint32_t val, enum LSC_STCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint (GLOBAL uint32_t *base, int immElemOff, uint32_t val, enum LSC_STCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint2 (GLOBAL sycl::uint2 *base, int immElemOff, sycl::uint2 val, enum LSC_STCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint3 (GLOBAL sycl::uint3 *base, int immElemOff, sycl::uint3 val, enum LSC_STCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint4 (GLOBAL sycl::uint4 *base, int immElemOff, sycl::uint4 val, enum LSC_STCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_uint8 (GLOBAL sycl::uint8 *base, int immElemOff, sycl::uint8 val, enum LSC_STCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong (GLOBAL uint64_t *base, int immElemOff, uint64_t val, enum LSC_STCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong2 (GLOBAL sycl::ulong2 *base, int immElemOff, sycl::ulong2 val, enum LSC_STCC cacheOpt); //D64V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong3 (GLOBAL sycl::ulong3 *base, int immElemOff, sycl::ulong3 val, enum LSC_STCC cacheOpt); //D64V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong4 (GLOBAL sycl::ulong4 *base, int immElemOff, sycl::ulong4 val, enum LSC_STCC cacheOpt); //D64V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong8 (GLOBAL sycl::ulong8 *base, int immElemOff, sycl::ulong8 val, enum LSC_STCC cacheOpt); //D64V8
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// prefetching
|
||||
@@ -124,14 +120,14 @@ SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_store_global_ulong8(GLOBAL sycl
|
||||
//
|
||||
// LSC Pre-Fetch Load functions with CacheControls
|
||||
// global address space
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uchar (const GLOBAL sycl::uchar *base, int immElemOff, enum LSC_LDCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ushort(const GLOBAL sycl::ushort *base, int immElemOff, enum LSC_LDCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint (const GLOBAL sycl::uint *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint2 (const GLOBAL sycl::uint2 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint3 (const GLOBAL sycl::uint3 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint4 (const GLOBAL sycl::uint4 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint8 (const GLOBAL sycl::uint8 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ulong (const GLOBAL sycl::ulong *base, int immElemOff, enum LSC_LDCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uchar (const GLOBAL uint8_t *base, int immElemOff, enum LSC_LDCC cacheOpt); //D8U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ushort(const GLOBAL uint16_t *base, int immElemOff, enum LSC_LDCC cacheOpt); //D16U32
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint (const GLOBAL uint32_t *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint2 (const GLOBAL sycl::uint2 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint3 (const GLOBAL sycl::uint3 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint4 (const GLOBAL sycl::uint4 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V4
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_uint8 (const GLOBAL sycl::uint8 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D32V8
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ulong (const GLOBAL uint64_t *base, int immElemOff, enum LSC_LDCC cacheOpt); //D64V1
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ulong2(const GLOBAL sycl::ulong2 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D64V2
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ulong3(const GLOBAL sycl::ulong3 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D64V3
|
||||
SYCL_EXTERNAL extern "C" void __builtin_IB_lsc_prefetch_global_ulong4(const GLOBAL sycl::ulong4 *base, int immElemOff, enum LSC_LDCC cacheOpt); //D64V4
|
||||
@@ -150,14 +146,14 @@ inline float work_group_reduce_max(float x) { return x; }
|
||||
inline float atomic_min(volatile float *p, float val) { return val; };
|
||||
inline float atomic_max(volatile float *p, float val) { return val; };
|
||||
|
||||
inline uint intel_sub_group_ballot(bool valid) { return 0; }
|
||||
inline uint32_t intel_sub_group_ballot(bool valid) { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
/* creates a temporary that is enforced to be uniform */
|
||||
#define SYCL_UNIFORM_VAR(Ty,tmp,k) \
|
||||
Ty tmp##_data; \
|
||||
Ty* p##tmp##_data = (Ty*) sub_group_broadcast((ulong)&tmp##_data,k); \
|
||||
Ty* p##tmp##_data = (Ty*) sub_group_broadcast((uint64_t)&tmp##_data,k); \
|
||||
Ty& tmp = *p##tmp##_data;
|
||||
|
||||
#if !defined(__forceinline)
|
||||
@@ -192,23 +188,23 @@ namespace embree
|
||||
return SYCL_EXPERIMENTAL::this_sub_group();
|
||||
}
|
||||
|
||||
__forceinline const uint get_sub_group_local_id() {
|
||||
__forceinline const uint32_t get_sub_group_local_id() {
|
||||
return this_sub_group().get_local_id()[0];
|
||||
}
|
||||
|
||||
__forceinline const uint get_sub_group_size() {
|
||||
__forceinline const uint32_t get_sub_group_size() {
|
||||
return this_sub_group().get_max_local_range().size();
|
||||
}
|
||||
|
||||
__forceinline const uint get_sub_group_id() {
|
||||
__forceinline const uint32_t get_sub_group_id() {
|
||||
return this_sub_group().get_group_id()[0];
|
||||
}
|
||||
|
||||
__forceinline const uint get_num_sub_groups() {
|
||||
__forceinline const uint32_t get_num_sub_groups() {
|
||||
return this_sub_group().get_group_range().size();
|
||||
}
|
||||
|
||||
__forceinline uint sub_group_ballot(bool pred) {
|
||||
__forceinline uint32_t sub_group_ballot(bool pred) {
|
||||
return intel_sub_group_ballot(pred);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ endif()
|
||||
|
||||
string(REGEX REPLACE "\n$" "" intelstyle_url "${intelstyle_url}")
|
||||
string(REPLACE "embree" "intelstyle" intelstyle_url "${intelstyle_url}")
|
||||
string(REPLACE "libraries" "documentation" intelstyle_url "${intelstyle_url}")
|
||||
|
||||
message(STATUS "Fetch intelstyle repository ${intelstyle_url}")
|
||||
include(FetchContent)
|
||||
|
||||
@@ -224,21 +224,6 @@ Embree SYCL Known Issues
|
||||
quality, and GPU performance may not reflect that of the final
|
||||
product.
|
||||
|
||||
- Currently only the following Intel® Arc™ GPUs are support:
|
||||
|
||||
- Intel® Arc™ A770 Graphics
|
||||
- Intel® Arc™ A750 Graphics
|
||||
- Intel® Arc™ A770M Graphics
|
||||
- Intel® Arc™ A730M Graphics
|
||||
- Intel® Arc™ A550M Graphics
|
||||
|
||||
- Intel® Data Center GPU Max Series is currently not supported.
|
||||
|
||||
- Ahead of time compilation is currently not working properly and you
|
||||
will get this error during compilation:
|
||||
|
||||
llvm-foreach: Floating point exception (core dumped)
|
||||
|
||||
- Compilation with build configuration "debug" is currently not working on
|
||||
Windows.
|
||||
|
||||
|
||||
@@ -63,6 +63,14 @@ Possible properties to query are:
|
||||
back face culling is enabled. This is only the case if Embree is
|
||||
compiled with `EMBREE_BACKFACE_CULLING` enabled.
|
||||
|
||||
+ `RTC_DEVICE_PROPERTY_BACKFACE_CULLING_CURVES_ENABLED`: Queries whether
|
||||
back face culling for curves is enabled. This is only the case if Embree is
|
||||
compiled with `EMBREE_BACKFACE_CULLING_CURVES` enabled.
|
||||
|
||||
+ `RTC_DEVICE_PROPERTY_BACKFACE_CULLING_SPHERES_ENABLED`: Queries whether
|
||||
back face culling for spheres is enabled. This is only the case if Embree is
|
||||
compiled with `EMBREE_BACKFACE_CULLING_SPHERES` enabled.
|
||||
|
||||
+ `RTC_DEVICE_PROPERTY_COMPACT_POLYS_ENABLED`: Queries whether
|
||||
compact polys is enabled. This is only the case if Embree is
|
||||
compiled with `EMBREE_COMPACT_POLYS` enabled.
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
Version History
|
||||
---------------
|
||||
|
||||
### Embree 4.1.0
|
||||
- Added support for Intel® Data Center GPU Max Series.
|
||||
- Added ARM64 Linux support.
|
||||
- Added EMBREE_BACKFACE_CULLING_SPHERES cmake option. The new cmake option defaults to OFF.
|
||||
|
||||
### Embree 4.0.1
|
||||
- Improved performance for Tiger Lake, Comet Lake, Cannon Lake, Kaby Lake,
|
||||
and Skylake client CPUs by using 256 bit SIMD instructions by default.
|
||||
|
||||
+23
-10
@@ -17,8 +17,9 @@ C++11. Embree is tested with the following compilers:
|
||||
|
||||
Linux
|
||||
|
||||
- Intel® oneAPI DPC++/C++ Compiler 2023.1.0
|
||||
- Intel® oneAPI DPC++/C++ Compiler 2023.0.0
|
||||
- oneAPI DPC++/C++ Compiler 2022-12-14
|
||||
- oneAPI DPC++/C++ Compiler 2023-04-17
|
||||
- Clang 5.0.0
|
||||
- Clang 4.0.0
|
||||
- GCC 10.0.1 (Fedora 32) AVX512 support
|
||||
@@ -26,6 +27,7 @@ Linux
|
||||
- GCC 7.3.1 (Fedora 27) AVX2 support
|
||||
- GCC 7.3.1 (Fedora 26) AVX2 support
|
||||
- GCC 6.4.1 (Fedora 25) AVX2 support
|
||||
- Intel® Implicit SPMD Program Compiler 1.19.0
|
||||
- Intel® Implicit SPMD Program Compiler 1.18.1
|
||||
- Intel® Implicit SPMD Program Compiler 1.17.0
|
||||
- Intel® Implicit SPMD Program Compiler 1.16.1
|
||||
@@ -36,6 +38,7 @@ Linux
|
||||
|
||||
macOS x86
|
||||
|
||||
- Intel® C++ Classic Compiler 2023.1.0
|
||||
- Intel® C++ Classic Compiler 2023.0.0
|
||||
- Apple Clang 12.0.5 (macOS 11.7.1)
|
||||
|
||||
@@ -141,13 +144,13 @@ The "oneAPI DPC++ Compiler" is more up-to-date than the "Intel(R) oneAPI
|
||||
DPC++/C++ Compiler" but less stable. The current tested version of the "oneAPI
|
||||
DPC++ compiler is
|
||||
|
||||
- [oneAPI DPC++ Compiler 2022-12-14](https://github.com/intel/llvm/releases/download/sycl-nightly%2F20221214/dpcpp-compiler.tar.gz)
|
||||
- [oneAPI DPC++ Compiler 2023-04-17](https://github.com/intel/llvm/releases/download/sycl-nightly%2F20230417/dpcpp-compiler.tar.gz)
|
||||
|
||||
The compiler can be downloaded and simply extracted. The oneAPI DPC++ compiler
|
||||
2022-12-14 can be set up executing the following command in a Linux (bash)
|
||||
shell:
|
||||
|
||||
wget https://github.com/intel/llvm/releases/download/sycl-nightly%2F20221214/dpcpp-compiler.tar.gz
|
||||
wget https://github.com/intel/llvm/releases/download/sycl-nightly%2F20230417/dpcpp-compiler.tar.gz
|
||||
tar xzf dpcpp-compiler.tar.gz
|
||||
source ./dpcpp_compiler/startup.sh
|
||||
|
||||
@@ -171,7 +174,7 @@ through `EMBREE_SYCL_SUPPORT=ON`.
|
||||
|
||||
Alternatively, you can download and run the installer of the
|
||||
|
||||
- [Intel(R) oneAPI DPC++/C++ Compiler 2023.0.0](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp).
|
||||
- [Intel(R) oneAPI DPC++/C++ Compiler 2023.1.0](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp).
|
||||
|
||||
After installation, you can set up the compiler by sourcing the
|
||||
`vars.sh` script in the `env` directory of the compiler install directory, for example,
|
||||
@@ -215,7 +218,7 @@ We tested Embree with the latest GPGPU driver Devel Release from
|
||||
and OpenCL(TM) Driver from that release is too old for Embree to work
|
||||
properly. Thus if no newer version of the GPGPU driver is available,
|
||||
you need to additionally install the latest compute runtime from here
|
||||
[22.43.24595](https://github.com/intel/compute-runtime/releases/tag/22.43.24595.30).
|
||||
[23.09.25812.14](https://github.com/intel/compute-runtime/releases/tag/23.09.25812.14).
|
||||
|
||||
Unfortunately, these compute runtime packages are only available for
|
||||
Ubuntu 22.04. You can also install a newer version of the compute
|
||||
@@ -227,11 +230,13 @@ Windows
|
||||
|
||||
Embree is tested using the following compilers under Windows:
|
||||
|
||||
- Intel® oneAPI DPC++/C++ Compiler 2023.1.0
|
||||
- Intel® oneAPI DPC++/C++ Compiler 2023.0.0
|
||||
- oneAPI DPC++/C++ Compiler 2022-12-14
|
||||
- oneAPI DPC++/C++ Compiler 2023-04-17
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2015 (Update\ 1)
|
||||
- Intel® Implicit SPMD Program Compiler 1.19.0
|
||||
- Intel® Implicit SPMD Program Compiler 1.18.1
|
||||
- Intel® Implicit SPMD Program Compiler 1.17.0
|
||||
- Intel® Implicit SPMD Program Compiler 1.16.1
|
||||
@@ -356,7 +361,7 @@ The "oneAPI DPC++ Compiler" is more up-to-date than the "Intel(R) oneAPI
|
||||
DPC++/C++ Compiler" but less stable. The current tested version of the oneAPI
|
||||
DPC++ compiler is
|
||||
|
||||
- [oneAPI DPC++ Compiler 2022-12-14](https://github.com/intel/llvm/releases/download/sycl-nightly%2F20221214/dpcpp-compiler-win.tar.gz)
|
||||
- [oneAPI DPC++ Compiler 2023-04-17](https://github.com/intel/llvm/releases/download/sycl-nightly%2F20230417/dpcpp-compiler-win.tar.gz)
|
||||
|
||||
Download and unpack the archive and open the "x64 Native Tools Command Prompt"
|
||||
of Visual Studio and execute the following lines to properly configure the
|
||||
@@ -442,9 +447,9 @@ your application with such an Embree package.
|
||||
### Windows Graphics Driver Installation
|
||||
|
||||
In order to run the SYCL tutorials on HPG hardware, you first need to
|
||||
install the proper graphics drivers for your graphics card from
|
||||
[https://www.intel.com](https://www.intel.com). Embree will work with
|
||||
graphics driver version 101.4027 or later.
|
||||
install the graphics drivers for your graphics card from
|
||||
[https://www.intel.com](https://www.intel.com). Please make sure to
|
||||
have installed version 31.0.101.4314 or newer.
|
||||
|
||||
|
||||
CMake Configuration
|
||||
@@ -513,6 +518,14 @@ parameters that can be configured in CMake:
|
||||
surfaces facing a ray can be hit. This option is turned OFF by
|
||||
default.
|
||||
|
||||
+ `EMBREE_BACKFACE_CULLING_CURVES`: Enables backface culling for curves,
|
||||
i.e. only surfaces facing a ray can be hit. This option is turned OFF
|
||||
by default.
|
||||
|
||||
+ `EMBREE_BACKFACE_CULLING_SPHERES`: Enables backface culling for spheres,
|
||||
i.e. only surfaces facing a ray can be hit. This option is turned OFF
|
||||
by default.
|
||||
|
||||
+ `EMBREE_COMPACT_POLYS`: Enables compact tris/quads, i.e. only
|
||||
geomIDs and primIDs are stored inside the leaf nodes.
|
||||
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ Intel® Embree Overview
|
||||
Intel® Embree is a high-performance ray tracing library developed at
|
||||
Intel, which is released as open source under the [Apache 2.0
|
||||
license](http://www.apache.org/licenses/LICENSE-2.0). Intel® Embree
|
||||
supports x86 CPUs under Linux, macOS, and Windows; ARM CPUs on macOS;
|
||||
as well as Intel® GPUs under Linux and Windows.
|
||||
supports x86 CPUs under Linux, macOS, and Windows; ARM CPUs on Linux
|
||||
and macOS; as well as Intel® GPUs under Linux and Windows.
|
||||
|
||||
Intel® Embree targets graphics application developers to improve the
|
||||
performance of photo-realistic rendering applications. Embree is
|
||||
|
||||
+2
-12
@@ -3,24 +3,14 @@ Supported Platforms
|
||||
|
||||
Embree supports Windows (32-bit and 64-bit), Linux (64-bit), and macOS
|
||||
(64-bit). Under Windows, Linux and macOS x86 based CPUs are supported,
|
||||
while ARM CPUs are currently only supported under macOS (e.g. Apple
|
||||
M1). ARM support for Windows and Linux is experimental.
|
||||
while ARM CPUs are currently only supported under Linux and macOS (e.g.
|
||||
Apple M1). ARM support for Windows experimental.
|
||||
|
||||
Embree supports Intel GPUs based on the Xe HPG microarchitecture
|
||||
(Intel® Arc™ GPU) under Linux and Windows and Xe HPC microarchitecture
|
||||
(Intel® Data Center GPU Flex Series and Intel® Data Center GPU Max
|
||||
Series) under Linux.
|
||||
|
||||
Currently the following products are supported and further products
|
||||
will get enabled soon:
|
||||
|
||||
- Intel® Arc™ A770 Graphics
|
||||
- Intel® Arc™ A750 Graphics
|
||||
- Intel® Arc™ A770M Graphics
|
||||
- Intel® Arc™ A730M Graphics
|
||||
- Intel® Arc™ A550M Graphics
|
||||
- Intel® Data Center GPU Flex 170
|
||||
|
||||
The code compiles with the Intel® Compiler, Intel® oneAPI DPC++
|
||||
Compiler, GCC, Clang, and the Microsoft Compiler. To use Embree on the
|
||||
GPU the Intel® oneAPI DPC++ Compiler must be used. Please see section
|
||||
|
||||
@@ -49,6 +49,7 @@ enum RTCDeviceProperty
|
||||
RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED = 33,
|
||||
RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED = 34,
|
||||
|
||||
RTC_DEVICE_PROPERTY_BACKFACE_CULLING_SPHERES_ENABLED = 62,
|
||||
RTC_DEVICE_PROPERTY_BACKFACE_CULLING_CURVES_ENABLED = 63,
|
||||
RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED = 64,
|
||||
RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED = 65,
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace embree
|
||||
|
||||
__forceinline bool split_pos(const PrimRef& prim, unsigned int& dim_o, float& fsplit_o) const
|
||||
{
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
/* compute morton code */
|
||||
const Vec3fa lower = prim.lower;
|
||||
const Vec3fa upper = prim.upper;
|
||||
@@ -73,7 +72,6 @@ namespace embree
|
||||
|
||||
dim_o = dim;
|
||||
fsplit_o = fsplit;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,11 +83,10 @@ namespace embree
|
||||
const Vec3fa gupper = (upper-base)*Vec3fa(scale)-Vec3fa(0.2f);
|
||||
Vec3ia ilower(floor(glower));
|
||||
Vec3ia iupper(floor(gupper));
|
||||
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
/* this ignores dimensions that are empty */
|
||||
iupper = (Vec3ia)select(vint4(glower) >= vint4(gupper),vint4(ilower),vint4(iupper));
|
||||
#endif
|
||||
|
||||
/* compute a morton code for the lower and upper grid coordinates. */
|
||||
const unsigned int lower_code = bitInterleave(ilower.x,ilower.y,ilower.z);
|
||||
const unsigned int upper_code = bitInterleave(iupper.x,iupper.y,iupper.z);
|
||||
|
||||
@@ -170,6 +170,9 @@ namespace embree
|
||||
#if defined (EMBREE_BACKFACE_CULLING_CURVES)
|
||||
v += "backfacecullingcurves ";
|
||||
#endif
|
||||
#if defined (EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
v += "backfacecullingspheres ";
|
||||
#endif
|
||||
#if defined(EMBREE_FILTER_FUNCTION)
|
||||
v += "intersection_filter ";
|
||||
#endif
|
||||
@@ -477,6 +480,12 @@ namespace embree
|
||||
case RTC_DEVICE_PROPERTY_BACKFACE_CULLING_CURVES_ENABLED: return 0;
|
||||
#endif
|
||||
|
||||
#if defined(EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
case RTC_DEVICE_PROPERTY_BACKFACE_CULLING_SPHERES_ENABLED: return 1;
|
||||
#else
|
||||
case RTC_DEVICE_PROPERTY_BACKFACE_CULLING_SPHERES_ENABLED: return 0;
|
||||
#endif
|
||||
|
||||
#if defined(EMBREE_COMPACT_POLYS)
|
||||
case RTC_DEVICE_PROPERTY_COMPACT_POLYS_ENABLED: return 1;
|
||||
#else
|
||||
@@ -594,7 +603,7 @@ namespace embree
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
dispatchGlobalsPtr = rthwifInit(gpu_device, gpu_context);
|
||||
dispatchGlobalsPtr = zeRTASInitExp(gpu_device, gpu_context);
|
||||
}
|
||||
|
||||
DeviceGPU::~DeviceGPU()
|
||||
|
||||
+10
-11
@@ -38,17 +38,16 @@ RTC_NAMESPACE_BEGIN;
|
||||
RTC_TRACE(rtcNewSYCLDevice);
|
||||
Lock<MutexSys> lock(g_mutex);
|
||||
|
||||
if (!getenv("EMBREE_NO_SPLASH"))
|
||||
{
|
||||
std::cout << std::endl;
|
||||
std::cout << "==================================================================================" << std::endl;
|
||||
std::cout << " The SYCL support of Embree is in beta phase. Current functionality, quality, " << std::endl;
|
||||
std::cout << " and GPU performance may not reflect that of the final product. Please read the " << std::endl;
|
||||
std::cout << " documentation section \"Embree SYCL Known Issues\" for known limitations. " << std::endl;
|
||||
std::cout << "==================================================================================" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
#if !defined(EMBREE_NO_SPLASH)
|
||||
std::cout << std::endl;
|
||||
std::cout << "==================================================================================" << std::endl;
|
||||
std::cout << " The SYCL support of Embree is in beta phase. Current functionality, quality, " << std::endl;
|
||||
std::cout << " and GPU performance may not reflect that of the final product. Please read the " << std::endl;
|
||||
std::cout << " documentation section \"Embree SYCL Known Issues\" for known limitations. " << std::endl;
|
||||
std::cout << "==================================================================================" << std::endl;
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
DeviceGPU* device = new DeviceGPU(sycl_context,config);
|
||||
return (RTCDevice) device->refInc();
|
||||
RTC_CATCH_END(nullptr);
|
||||
|
||||
@@ -685,10 +685,7 @@ namespace embree
|
||||
{
|
||||
/* select acceleration structures to build */
|
||||
unsigned int new_enabled_geometry_types = world.enabledGeometryTypesMask();
|
||||
// #if defined(EMBREE_SYCL_SUPPORT)
|
||||
// if (!dynamic_cast<DeviceGPU*>(device)) // do not build software accel for GPU if not required
|
||||
// #endif
|
||||
|
||||
|
||||
if (flags_modified || new_enabled_geometry_types != enabled_geometry_types)
|
||||
{
|
||||
accels_init();
|
||||
@@ -726,18 +723,6 @@ namespace embree
|
||||
/* build all hierarchies of this scene */
|
||||
accels_build();
|
||||
|
||||
/* build acceleration structure for rthw */
|
||||
// #if defined(EMBREE_SYCL_SUPPORT)
|
||||
// if (DeviceGPU* gpu_device = dynamic_cast<DeviceGPU*>(device))
|
||||
// //if (gpu_device->rthw_support())
|
||||
// // bounds = LBBox<embree::Vec3fa>(rthwifBuild(this,quality_flags,hwaccel,device->gpu_build));
|
||||
// if (gpu_device->rthw_support()) {
|
||||
// const BBox3f aabb = rthwifBuild(this,quality_flags,hwaccel,device->gpu_build);
|
||||
// bounds = LBBox<embree::Vec3fa>(aabb);
|
||||
// hwaccel_bounds = aabb;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
/* make static geometry immutable */
|
||||
if (!isDynamicAccel()) {
|
||||
accels_immutable();
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace embree
|
||||
const Grid& g = grid(primID);
|
||||
for (ssize_t y=0; y<ssize_t(g.resY)-1; y++)
|
||||
for (ssize_t x=0; x<ssize_t(g.resX)-1; x++)
|
||||
quadID_to_primID_xy[quadID++] = { primID, (ushort) x, (ushort) y };
|
||||
quadID_to_primID_xy[quadID++] = { primID, (uint16_t) x, (uint16_t) y };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace embree
|
||||
#if defined(EMBREE_SYCL_SUPPORT)
|
||||
|
||||
public:
|
||||
struct PrimID_XY { uint32_t primID; ushort x,y; };
|
||||
struct PrimID_XY { uint32_t primID; uint16_t x,y; };
|
||||
Device::vector<PrimID_XY> quadID_to_primID_xy = device; //!< maps a quad to the primitive ID and grid coordinates
|
||||
#endif
|
||||
};
|
||||
|
||||
+43
-44
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "stat.h"
|
||||
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Stat Stat::instance;
|
||||
@@ -25,16 +24,16 @@ namespace embree
|
||||
//Counters::Data& data = instance.cntrs.active;
|
||||
|
||||
/* print absolute numbers */
|
||||
cout << "--------- ABSOLUTE ---------" << embree_endl;
|
||||
cout << " #normal_travs = " << float(data.normal.travs )*1E-6f << "M" << embree_endl;
|
||||
cout << " #nodes = " << float(data.normal.trav_nodes )*1E-6f << "M" << embree_endl;
|
||||
cout << " #nodes_xfm = " << float(data.normal.trav_xfm_nodes )*1E-6f << "M" << embree_endl;
|
||||
cout << " #leaves = " << float(data.normal.trav_leaves )*1E-6f << "M" << embree_endl;
|
||||
cout << " #prims = " << float(data.normal.trav_prims )*1E-6f << "M" << embree_endl;
|
||||
cout << " #prim_hits = " << float(data.normal.trav_prim_hits )*1E-6f << "M" << embree_endl;
|
||||
cout << "--------- ABSOLUTE ---------" << std::endl;
|
||||
cout << " #normal_travs = " << float(data.normal.travs )*1E-6 << "M" << std::endl;
|
||||
cout << " #nodes = " << float(data.normal.trav_nodes )*1E-6 << "M" << std::endl;
|
||||
cout << " #nodes_xfm = " << float(data.normal.trav_xfm_nodes )*1E-6 << "M" << std::endl;
|
||||
cout << " #leaves = " << float(data.normal.trav_leaves )*1E-6 << "M" << std::endl;
|
||||
cout << " #prims = " << float(data.normal.trav_prims )*1E-6 << "M" << std::endl;
|
||||
cout << " #prim_hits = " << float(data.normal.trav_prim_hits )*1E-6 << "M" << std::endl;
|
||||
|
||||
cout << " #stack nodes = " << float(data.normal.trav_stack_nodes )*1E-6f << "M" << embree_endl;
|
||||
cout << " #stack pop = " << float(data.normal.trav_stack_pop )*1E-6f << "M" << embree_endl;
|
||||
cout << " #stack nodes = " << float(data.normal.trav_stack_nodes )*1E-6 << "M" << std::endl;
|
||||
cout << " #stack pop = " << float(data.normal.trav_stack_pop )*1E-6 << "M" << std::endl;
|
||||
|
||||
size_t normal_box_hits = 0;
|
||||
size_t weighted_box_hits = 0;
|
||||
@@ -50,20 +49,20 @@ namespace embree
|
||||
cout << "[" << i << "] " << value << " ";
|
||||
average += (float)i*data.normal.trav_hit_boxes[i] / normal_box_hits;
|
||||
}
|
||||
cout << " average = " << average << embree_endl;
|
||||
cout << " average = " << average << std::endl;
|
||||
for (size_t i=0;i<SIZE_HISTOGRAM;i++) cout << "[" << i << "] " << 100.0f * data.normal.trav_hit_boxes[i]*i / weighted_box_hits << " ";
|
||||
cout << embree_endl;
|
||||
cout << std::endl;
|
||||
|
||||
if (data.shadow.travs) {
|
||||
cout << " #shadow_travs = " << float(data.shadow.travs )*1E-6f << "M" << embree_endl;
|
||||
cout << " #nodes = " << float(data.shadow.trav_nodes )*1E-6f << "M" << embree_endl;
|
||||
cout << " #nodes_xfm = " << float(data.shadow.trav_xfm_nodes)*1E-6f << "M" << embree_endl;
|
||||
cout << " #leaves = " << float(data.shadow.trav_leaves )*1E-6f << "M" << embree_endl;
|
||||
cout << " #prims = " << float(data.shadow.trav_prims )*1E-6f << "M" << embree_endl;
|
||||
cout << " #prim_hits = " << float(data.shadow.trav_prim_hits)*1E-6f << "M" << embree_endl;
|
||||
cout << " #shadow_travs = " << float(data.shadow.travs )*1E-6 << "M" << std::endl;
|
||||
cout << " #nodes = " << float(data.shadow.trav_nodes )*1E-6 << "M" << std::endl;
|
||||
cout << " #nodes_xfm = " << float(data.shadow.trav_xfm_nodes)*1E-6 << "M" << std::endl;
|
||||
cout << " #leaves = " << float(data.shadow.trav_leaves )*1E-6 << "M" << std::endl;
|
||||
cout << " #prims = " << float(data.shadow.trav_prims )*1E-6 << "M" << std::endl;
|
||||
cout << " #prim_hits = " << float(data.shadow.trav_prim_hits)*1E-6 << "M" << std::endl;
|
||||
|
||||
cout << " #stack nodes = " << float(data.shadow.trav_stack_nodes )*1E-6f << "M" << embree_endl;
|
||||
cout << " #stack pop = " << float(data.shadow.trav_stack_pop )*1E-6f << "M" << embree_endl;
|
||||
cout << " #stack nodes = " << float(data.shadow.trav_stack_nodes )*1E-6 << "M" << std::endl;
|
||||
cout << " #stack pop = " << float(data.shadow.trav_stack_pop )*1E-6 << "M" << std::endl;
|
||||
|
||||
size_t shadow_box_hits = 0;
|
||||
size_t weighted_shadow_box_hits = 0;
|
||||
@@ -74,14 +73,14 @@ namespace embree
|
||||
}
|
||||
cout << " #hit_boxes = ";
|
||||
for (size_t i=0;i<SIZE_HISTOGRAM;i++) cout << "[" << i << "] " << 100.0f * data.shadow.trav_hit_boxes[i] / shadow_box_hits << " ";
|
||||
cout << embree_endl;
|
||||
cout << std::endl;
|
||||
for (size_t i=0;i<SIZE_HISTOGRAM;i++) cout << "[" << i << "] " << 100.0f * data.shadow.trav_hit_boxes[i]*i / weighted_shadow_box_hits << " ";
|
||||
cout << embree_endl;
|
||||
cout << std::endl;
|
||||
}
|
||||
cout << embree_endl;
|
||||
cout << std::endl;
|
||||
|
||||
/* print per traversal numbers */
|
||||
cout << "--------- PER TRAVERSAL ---------" << embree_endl;
|
||||
cout << "--------- PER TRAVERSAL ---------" << std::endl;
|
||||
float active_normal_travs = float(cntrs.active.normal.travs )/float(cntrs.all.normal.travs );
|
||||
float active_normal_trav_nodes = float(cntrs.active.normal.trav_nodes )/float(cntrs.all.normal.trav_nodes );
|
||||
float active_normal_trav_xfm_nodes = float(cntrs.active.normal.trav_xfm_nodes )/float(cntrs.all.normal.trav_xfm_nodes );
|
||||
@@ -90,13 +89,13 @@ namespace embree
|
||||
float active_normal_trav_prim_hits = float(cntrs.active.normal.trav_prim_hits )/float(cntrs.all.normal.trav_prim_hits );
|
||||
float active_normal_trav_stack_pop = float(cntrs.active.normal.trav_stack_pop )/float(cntrs.all.normal.trav_stack_pop );
|
||||
|
||||
cout << " #normal_travs = " << float(cntrs.code.normal.travs )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_travs << "% active" << embree_endl;
|
||||
cout << " #nodes = " << float(cntrs.code.normal.trav_nodes )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_nodes << "% active" << embree_endl;
|
||||
cout << " #node_xfm = " << float(cntrs.code.normal.trav_xfm_nodes )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_xfm_nodes << "% active" << embree_endl;
|
||||
cout << " #leaves = " << float(cntrs.code.normal.trav_leaves)/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_leaves << "% active" << embree_endl;
|
||||
cout << " #prims = " << float(cntrs.code.normal.trav_prims )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_prims << "% active" << embree_endl;
|
||||
cout << " #prim_hits = " << float(cntrs.code.normal.trav_prim_hits )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_prim_hits << "% active" << embree_endl;
|
||||
cout << " #stack_pop = " << float(cntrs.code.normal.trav_stack_pop )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_stack_pop << "% active" << embree_endl;
|
||||
cout << " #normal_travs = " << float(cntrs.code.normal.travs )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_travs << "% active" << std::endl;
|
||||
cout << " #nodes = " << float(cntrs.code.normal.trav_nodes )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_nodes << "% active" << std::endl;
|
||||
cout << " #node_xfm = " << float(cntrs.code.normal.trav_xfm_nodes )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_xfm_nodes << "% active" << std::endl;
|
||||
cout << " #leaves = " << float(cntrs.code.normal.trav_leaves)/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_leaves << "% active" << std::endl;
|
||||
cout << " #prims = " << float(cntrs.code.normal.trav_prims )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_prims << "% active" << std::endl;
|
||||
cout << " #prim_hits = " << float(cntrs.code.normal.trav_prim_hits )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_prim_hits << "% active" << std::endl;
|
||||
cout << " #stack_pop = " << float(cntrs.code.normal.trav_stack_pop )/float(cntrs.code.normal.travs) << ", " << 100.0f*active_normal_trav_stack_pop << "% active" << std::endl;
|
||||
|
||||
if (cntrs.all.shadow.travs) {
|
||||
float active_shadow_travs = float(cntrs.active.shadow.travs )/float(cntrs.all.shadow.travs );
|
||||
@@ -106,24 +105,24 @@ namespace embree
|
||||
float active_shadow_trav_prims = float(cntrs.active.shadow.trav_prims )/float(cntrs.all.shadow.trav_prims );
|
||||
float active_shadow_trav_prim_hits = float(cntrs.active.shadow.trav_prim_hits )/float(cntrs.all.shadow.trav_prim_hits );
|
||||
|
||||
cout << " #shadow_travs = " << float(cntrs.code.shadow.travs )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_travs << "% active" << embree_endl;
|
||||
cout << " #nodes = " << float(cntrs.code.shadow.trav_nodes )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_nodes << "% active" << embree_endl;
|
||||
cout << " #nodes_xfm = " << float(cntrs.code.shadow.trav_xfm_nodes )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_xfm_nodes << "% active" << embree_endl;
|
||||
cout << " #leaves = " << float(cntrs.code.shadow.trav_leaves)/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_leaves << "% active" << embree_endl;
|
||||
cout << " #prims = " << float(cntrs.code.shadow.trav_prims )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_prims << "% active" << embree_endl;
|
||||
cout << " #prim_hits = " << float(cntrs.code.shadow.trav_prim_hits )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_prim_hits << "% active" << embree_endl;
|
||||
cout << " #shadow_travs = " << float(cntrs.code.shadow.travs )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_travs << "% active" << std::endl;
|
||||
cout << " #nodes = " << float(cntrs.code.shadow.trav_nodes )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_nodes << "% active" << std::endl;
|
||||
cout << " #nodes_xfm = " << float(cntrs.code.shadow.trav_xfm_nodes )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_xfm_nodes << "% active" << std::endl;
|
||||
cout << " #leaves = " << float(cntrs.code.shadow.trav_leaves)/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_leaves << "% active" << std::endl;
|
||||
cout << " #prims = " << float(cntrs.code.shadow.trav_prims )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_prims << "% active" << std::endl;
|
||||
cout << " #prim_hits = " << float(cntrs.code.shadow.trav_prim_hits )/float(cntrs.code.shadow.travs) << ", " << 100.0f*active_shadow_trav_prim_hits << "% active" << std::endl;
|
||||
|
||||
}
|
||||
cout << embree_endl;
|
||||
cout << std::endl;
|
||||
|
||||
/* print user counters for performance tuning */
|
||||
cout << "--------- USER ---------" << embree_endl;
|
||||
cout << "--------- USER ---------" << std::endl;
|
||||
for (size_t i=0; i<10; i++)
|
||||
cout << "#user" << i << " = " << float(cntrs.user[i])/float(cntrs.all.normal.travs+cntrs.all.shadow.travs) << " per traversal" << embree_endl;
|
||||
cout << "#user" << i << " = " << float(cntrs.user[i])/float(cntrs.all.normal.travs+cntrs.all.shadow.travs) << " per traversal" << std::endl;
|
||||
|
||||
cout << "#user5/user3 " << 100.0f*float(cntrs.user[5])/float(cntrs.user[3]) << "%" << embree_endl;
|
||||
cout << "#user6/user3 " << 100.0f*float(cntrs.user[6])/float(cntrs.user[3]) << "%" << embree_endl;
|
||||
cout << "#user7/user3 " << 100.0f*float(cntrs.user[7])/float(cntrs.user[3]) << "%" << embree_endl;
|
||||
cout << embree_endl;
|
||||
cout << "#user5/user3 " << 100.0f*float(cntrs.user[5])/float(cntrs.user[3]) << "%" << std::endl;
|
||||
cout << "#user6/user3 " << 100.0f*float(cntrs.user[6])/float(cntrs.user[3]) << "%" << std::endl;
|
||||
cout << "#user7/user3 " << 100.0f*float(cntrs.user[7])/float(cntrs.user[3]) << "%" << std::endl;
|
||||
cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ namespace embree
|
||||
object_accel_mb_min_leaf_size = 1;
|
||||
object_accel_mb_max_leaf_size = 1;
|
||||
|
||||
gpu_build = 0;
|
||||
max_spatial_split_replications = 1.2f;
|
||||
useSpatialPreSplits = false;
|
||||
|
||||
@@ -421,15 +420,6 @@ namespace embree
|
||||
}
|
||||
}
|
||||
|
||||
else if (tok == Token::Id("gpu_build"))
|
||||
{
|
||||
if (cin->trySymbol("=")) {
|
||||
Token flag = cin->get();
|
||||
if (flag == Token::Id("ploc")) gpu_build = 1;
|
||||
else if (flag == Token::Id("ploc_twolevel")) gpu_build = 2;
|
||||
}
|
||||
}
|
||||
|
||||
else if (tok == Token::Id("max_spatial_split_replications") && cin->trySymbol("="))
|
||||
max_spatial_split_replications = cin->get().Float();
|
||||
|
||||
|
||||
@@ -105,12 +105,7 @@ namespace embree
|
||||
std::string grid_accel_mb; //!< acceleration structure to use for motion blur grids
|
||||
std::string grid_builder_mb; //!< builder for motion blur grids
|
||||
|
||||
//public:
|
||||
//std::string rthw_builder = "internal"; //!< ray tracing hardware builder to use
|
||||
|
||||
public:
|
||||
int gpu_build; //!< enabled if BVH build should happen on GPU
|
||||
|
||||
float max_spatial_split_replications; //!< maximally replications*N many primitives in accel for spatial splits
|
||||
bool useSpatialPreSplits; //!< use spatial pre-splits instead of the full spatial split builder
|
||||
size_t tessellation_cache_size; //!< size of the shared tessellation cache
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#cmakedefine EMBREE_STAT_COUNTERS
|
||||
#cmakedefine EMBREE_BACKFACE_CULLING
|
||||
#cmakedefine EMBREE_BACKFACE_CULLING_CURVES
|
||||
#cmakedefine EMBREE_BACKFACE_CULLING_SPHERES
|
||||
#cmakedefine EMBREE_FILTER_FUNCTION
|
||||
#cmakedefine EMBREE_IGNORE_INVALID_RAYS
|
||||
#cmakedefine EMBREE_GEOMETRY_TRIANGLE
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
global:
|
||||
rtc*;
|
||||
_ZN?rtc*;
|
||||
_ZN??rtc*;
|
||||
_ZN???rtc*;
|
||||
_ZN????rtc*;
|
||||
_ZN??rtc*;
|
||||
_ZN???rtc*;
|
||||
_ZN????rtc*;
|
||||
_ZN?????rtc*;
|
||||
_ZN???rtc*;
|
||||
_ZN????rtc*;
|
||||
_ZN?????rtc*;
|
||||
_ZN??????rtc*;
|
||||
_ZN6embree13TaskScheduler*;
|
||||
_ZN6embree?13TaskScheduler*;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
_rtc*
|
||||
__ZN?rtc*
|
||||
__ZN??rtc*
|
||||
__ZN???rtc*
|
||||
__ZN????rtc*
|
||||
__ZN??rtc*
|
||||
__ZN???rtc*
|
||||
__ZN????rtc*
|
||||
__ZN?????rtc*
|
||||
__ZN???rtc*
|
||||
__ZN????rtc*
|
||||
__ZN?????rtc*
|
||||
__ZN??????rtc*
|
||||
__ZN6embree13TaskScheduler*
|
||||
__ZN6embree?13TaskScheduler*
|
||||
@@ -104,10 +104,15 @@ namespace embree
|
||||
const vfloat<M> t_back = projC0 + td;
|
||||
|
||||
const vbool<M> valid_front = valid & (ray.tnear() <= t_front) & (t_front <= ray.tfar);
|
||||
const vbool<M> valid_back = valid & (ray.tnear() <= t_back ) & (t_back <= ray.tfar);
|
||||
|
||||
/* check if there is a first hit */
|
||||
#if defined (EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
/* check if there is a first hit */
|
||||
const vbool<M> valid_first = valid_front;
|
||||
#else
|
||||
const vbool<M> valid_back = valid & (ray.tnear() <= t_back ) & (t_back <= ray.tfar);
|
||||
const vbool<M> valid_first = valid_front | valid_back;
|
||||
#endif
|
||||
if (unlikely(none(valid_first)))
|
||||
return false;
|
||||
|
||||
@@ -120,7 +125,10 @@ namespace embree
|
||||
|
||||
/* invoke intersection filter for first hit */
|
||||
const bool is_hit_first = epilog(valid_first, hit);
|
||||
|
||||
|
||||
#if defined (EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
return is_hit_first;
|
||||
#else
|
||||
/* check for possible second hits before potentially accepted hit */
|
||||
const vfloat<M> t_second = t_back;
|
||||
const vbool<M> valid_second = valid_front & valid_back & (t_second <= ray.tfar);
|
||||
@@ -131,8 +139,8 @@ namespace embree
|
||||
const Vec3vf<M> Ng_second = td_back * ray_dir - perp;
|
||||
hit = SphereIntersectorHitM<M> (t_second, Ng_second);
|
||||
const bool is_hit_second = epilog(valid_second, hit);
|
||||
|
||||
return is_hit_first | is_hit_second;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Epilog>
|
||||
@@ -184,10 +192,14 @@ namespace embree
|
||||
const vfloat<M> t_back = projC0 + td;
|
||||
|
||||
const vbool<M> valid_front = valid & (ray.tnear()[k] <= t_front) & (t_front <= ray.tfar[k]);
|
||||
const vbool<M> valid_back = valid & (ray.tnear()[k] <= t_back ) & (t_back <= ray.tfar[k]);
|
||||
|
||||
/* check if there is a first hit */
|
||||
#if defined (EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
const vbool<M> valid_first = valid_front;
|
||||
#else
|
||||
const vbool<M> valid_back = valid & (ray.tnear()[k] <= t_back ) & (t_back <= ray.tfar[k]);
|
||||
const vbool<M> valid_first = valid_front | valid_back;
|
||||
#endif
|
||||
if (unlikely(none(valid_first)))
|
||||
return false;
|
||||
|
||||
@@ -200,7 +212,10 @@ namespace embree
|
||||
|
||||
/* invoke intersection filter for first hit */
|
||||
const bool is_hit_first = epilog(valid_first, hit);
|
||||
|
||||
|
||||
#if defined (EMBREE_BACKFACE_CULLING_SPHERES)
|
||||
return is_hit_first;
|
||||
#else
|
||||
/* check for possible second hits before potentially accepted hit */
|
||||
const vfloat<M> t_second = t_back;
|
||||
const vbool<M> valid_second = valid_front & valid_back & (t_second <= ray.tfar[k]);
|
||||
@@ -213,6 +228,7 @@ namespace embree
|
||||
const bool is_hit_second = epilog(valid_second, hit);
|
||||
|
||||
return is_hit_first | is_hit_second;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // namespace isa
|
||||
|
||||
@@ -68,8 +68,8 @@ ELSE()
|
||||
option(EMBREE_BUILDER_TBB_STATIC "Use a staticaly compiled TBB version for the Embree builder for GPU." OFF)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS")
|
||||
IF (EMBREE_SYCL_RT_VALIDATION_API AND NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-bitwise-instead-of-logical") # disables "use of bitwise '&' with boolean operands" warning
|
||||
@@ -154,45 +154,29 @@ IF (RTHWIF_STANDALONE)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_SYCL_RT_VALIDATION_API)
|
||||
ADD_LIBRARY(embree_rthwif_sycl STATIC rttrace/rthwif_production.cpp)
|
||||
ADD_LIBRARY(embree_rthwif_sycl STATIC rttrace/rttrace_validation.cpp)
|
||||
SET_PROPERTY(TARGET embree_rthwif_sycl APPEND PROPERTY COMPILE_FLAGS "-DEMBREE_SYCL_SUPPORT")
|
||||
SET_TARGET_PROPERTIES(embree_rthwif_sycl PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS_SYCL})
|
||||
|
||||
|
||||
INSTALL(TARGETS embree_rthwif_sycl EXPORT embree_rthwif_sycl-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib)
|
||||
INSTALL(EXPORT embree_rthwif_sycl-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel)
|
||||
|
||||
SET(EMBREE_RTHWIF_SYCL embree_rthwif_sycl)
|
||||
ENDIF()
|
||||
|
||||
ADD_LIBRARY(embree_rthwif ${RTHWIF_LIB_TYPE} rtbuild/rthwif_builder.cpp rtbuild/qbvh6.cpp rtbuild/statistics.cpp)
|
||||
ADD_LIBRARY(embree_rthwif ${RTHWIF_LIB_TYPE} rtbuild/rtbuild.cpp rtbuild/qbvh6.cpp rtbuild/statistics.cpp)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif PUBLIC ${EMBREE_RTHWIF_SYCL} PRIVATE ${TBB_TARGET} simd sys)
|
||||
SET_TARGET_PROPERTIES(embree_rthwif PROPERTIES OUTPUT_NAME ${RTHWIF_NAME})
|
||||
IF (EMBREE_RTHWIF_STATIC_LIB)
|
||||
TARGET_COMPILE_DEFINITIONS(embree_rthwif PUBLIC EMBREE_RTHWIF_STATIC_LIB)
|
||||
TARGET_COMPILE_DEFINITIONS(embree_rthwif PUBLIC EMBREE_RTHWIF_STATIC_LIB)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
ADD_LIBRARY(embree_rthwif_gpu STATIC rtbuild/rthwif_embree_builder_ploc.cpp rtbuild/qbvh6.cpp rtbuild/statistics.cpp)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif_gpu PUBLIC tbb simd sys -lze_loader)
|
||||
SET_TARGET_PROPERTIES(embree_rthwif_gpu PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS_SYCL})
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif PUBLIC ${EMBREE_RTHWIF_SYCL} PRIVATE ${TBB_TARGET} simd sys)
|
||||
|
||||
|
||||
if (EMBREE_LEVEL_ZERO)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif PUBLIC -lze_loader)
|
||||
TARGET_COMPILE_DEFINITIONS(embree_rthwif PUBLIC EMBREE_LEVEL_ZERO)
|
||||
TARGET_COMPILE_DEFINITIONS(embree_rthwif PUBLIC EMBREE_SYCL_SUPPORT)
|
||||
endif()
|
||||
|
||||
IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif PUBLIC embree_rthwif_gpu)
|
||||
ENDIF()
|
||||
|
||||
SET_PROPERTY(TARGET embree_rthwif APPEND PROPERTY COMPILE_FLAGS "-DEMBREE_SYCL_SUPPORT")
|
||||
|
||||
|
||||
IF (EMBREE_STATIC_LIB OR NOT EMBREE_RTHWIF_STATIC_LIB)
|
||||
INSTALL(TARGETS embree_rthwif EXPORT ${RTHWIF_NAME}-targets
|
||||
LIBRARY NAMELINK_SKIP DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
|
||||
@@ -201,11 +185,6 @@ IF (EMBREE_STATIC_LIB OR NOT EMBREE_RTHWIF_STATIC_LIB)
|
||||
INSTALL(EXPORT ${RTHWIF_NAME}-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
INSTALL(TARGETS embree_rthwif_gpu EXPORT embree_rthwif_gpu-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib)
|
||||
INSTALL(EXPORT embree_rthwif_gpu-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_LEVEL_ZERO OR RTHWIF_STANDALONE)
|
||||
ADD_SUBDIRECTORY(testing)
|
||||
ENDIF()
|
||||
|
||||
@@ -1,507 +0,0 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT)
|
||||
|
||||
#include "common.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace gpu
|
||||
{
|
||||
class AABB3f {
|
||||
public:
|
||||
float lower_x,lower_y,lower_z;
|
||||
float upper_x,upper_y,upper_z;
|
||||
|
||||
__forceinline AABB3f() = default;
|
||||
|
||||
__forceinline AABB3f(const AABB3f &aabb) : lower_x(aabb.lower_x),
|
||||
lower_y(aabb.lower_y),
|
||||
lower_z(aabb.lower_z),
|
||||
upper_x(aabb.upper_x),
|
||||
upper_y(aabb.upper_y),
|
||||
upper_z(aabb.upper_z)
|
||||
{}
|
||||
|
||||
__forceinline AABB3f(const float3 &v) : lower_x(v.x()),
|
||||
lower_y(v.y()),
|
||||
lower_z(v.z()),
|
||||
upper_x(v.x()),
|
||||
upper_y(v.y()),
|
||||
upper_z(v.z())
|
||||
{}
|
||||
|
||||
__forceinline AABB3f(const float3 &lower, const float3 &upper) : lower_x(lower.x()),
|
||||
lower_y(lower.y()),
|
||||
lower_z(lower.z()),
|
||||
upper_x(upper.x()),
|
||||
upper_y(upper.y()),
|
||||
upper_z(upper.z())
|
||||
|
||||
{}
|
||||
|
||||
__forceinline AABB3f(const BBox3fa &aabb) : lower_x(aabb.lower.x),
|
||||
lower_y(aabb.lower.y),
|
||||
lower_z(aabb.lower.z),
|
||||
upper_x(aabb.upper.x),
|
||||
upper_y(aabb.upper.y),
|
||||
upper_z(aabb.upper.z)
|
||||
{}
|
||||
|
||||
__forceinline AABB3f(const float lower_x, const float lower_y, const float lower_z, const float upper_x, const float upper_y, const float upper_z) : lower_x(lower_x),
|
||||
lower_y(lower_y),
|
||||
lower_z(lower_z),
|
||||
upper_x(upper_x),
|
||||
upper_y(upper_y),
|
||||
upper_z(upper_z)
|
||||
{}
|
||||
|
||||
__forceinline bool empty()
|
||||
{
|
||||
if (lower_x > upper_x ||
|
||||
lower_y > upper_y ||
|
||||
lower_z > upper_z) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
__forceinline void init()
|
||||
{
|
||||
const float _pos_inf = INFINITY;
|
||||
const float _neg_inf = -INFINITY;
|
||||
lower_x = _pos_inf;
|
||||
lower_y = _pos_inf;
|
||||
lower_z = _pos_inf;
|
||||
upper_x = _neg_inf;
|
||||
upper_y = _neg_inf;
|
||||
upper_z = _neg_inf;
|
||||
}
|
||||
|
||||
__forceinline void setZero()
|
||||
{
|
||||
lower_x = 0.0f;
|
||||
lower_y = 0.0f;
|
||||
lower_z = 0.0f;
|
||||
upper_x = 0.0f;
|
||||
upper_y = 0.0f;
|
||||
upper_z = 0.0f;
|
||||
}
|
||||
|
||||
__forceinline bool encloses(const AABB3f &other)
|
||||
{
|
||||
if ( other.lower_x < lower_x ||
|
||||
other.lower_y < lower_y ||
|
||||
other.lower_z < lower_z )
|
||||
return false;
|
||||
if ( other.upper_x > upper_x ||
|
||||
other.upper_y > upper_y ||
|
||||
other.upper_z > upper_z )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline void extend(const class AABB3f &aabb)
|
||||
{
|
||||
lower_x = min(lower_x,aabb.lower_x);
|
||||
lower_y = min(lower_y,aabb.lower_y);
|
||||
lower_z = min(lower_z,aabb.lower_z);
|
||||
upper_x = max(upper_x,aabb.upper_x);
|
||||
upper_y = max(upper_y,aabb.upper_y);
|
||||
upper_z = max(upper_z,aabb.upper_z);
|
||||
}
|
||||
|
||||
|
||||
__forceinline void extend(const class AABB3f &aabb, const uint slot)
|
||||
{
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const bool cmp = subgroupLocalID == slot;
|
||||
lower_x = cselect(cmp,min(lower_x,aabb.lower_x),lower_x);
|
||||
lower_y = cselect(cmp,min(lower_y,aabb.lower_y),lower_y);
|
||||
lower_z = cselect(cmp,min(lower_z,aabb.lower_z),lower_z);
|
||||
upper_x = cselect(cmp,max(upper_x,aabb.upper_x),upper_x);
|
||||
upper_y = cselect(cmp,max(upper_y,aabb.upper_y),upper_y);
|
||||
upper_z = cselect(cmp,max(upper_z,aabb.upper_z),upper_z);
|
||||
}
|
||||
|
||||
|
||||
__forceinline void extend(const float3 &v)
|
||||
{
|
||||
lower_x = min(lower_x,v.x());
|
||||
lower_y = min(lower_y,v.y());
|
||||
lower_z = min(lower_z,v.z());
|
||||
upper_x = max(upper_x,v.x());
|
||||
upper_y = max(upper_y,v.y());
|
||||
upper_z = max(upper_z,v.z());
|
||||
}
|
||||
|
||||
__forceinline void extend(const float4 &v)
|
||||
{
|
||||
lower_x = min(lower_x,v.x());
|
||||
lower_y = min(lower_y,v.y());
|
||||
lower_z = min(lower_z,v.z());
|
||||
upper_x = max(upper_x,v.x());
|
||||
upper_y = max(upper_y,v.y());
|
||||
upper_z = max(upper_z,v.z());
|
||||
}
|
||||
|
||||
__forceinline void extend(const BBox3fa &aabb)
|
||||
{
|
||||
lower_x = min(lower_x,aabb.lower.x);
|
||||
lower_y = min(lower_y,aabb.lower.y);
|
||||
lower_z = min(lower_z,aabb.lower.z);
|
||||
upper_x = max(upper_x,aabb.upper.x);
|
||||
upper_y = max(upper_y,aabb.upper.y);
|
||||
upper_z = max(upper_z,aabb.upper.z);
|
||||
}
|
||||
|
||||
__forceinline void enlarge(const float &v)
|
||||
{
|
||||
lower_x -= v;
|
||||
lower_y -= v;
|
||||
lower_z -= v;
|
||||
upper_x += v;
|
||||
upper_y += v;
|
||||
upper_z += v;
|
||||
}
|
||||
|
||||
__forceinline void add(const class AABB3f &aabb)
|
||||
{
|
||||
lower_x += aabb.lower_x;
|
||||
lower_y += aabb.lower_y;
|
||||
lower_z += aabb.lower_z;
|
||||
upper_x += aabb.upper_x;
|
||||
upper_y += aabb.upper_y;
|
||||
upper_z += aabb.upper_z;
|
||||
}
|
||||
|
||||
__forceinline void mul(const float f)
|
||||
{
|
||||
lower_x *= f;
|
||||
lower_y *= f;
|
||||
lower_z *= f;
|
||||
upper_x *= f;
|
||||
upper_y *= f;
|
||||
upper_z *= f;
|
||||
}
|
||||
|
||||
__forceinline float3 lower() const { return float3(lower_x,lower_y,lower_z); }
|
||||
__forceinline float3 upper() const { return float3(upper_x,upper_y,upper_z); }
|
||||
|
||||
__forceinline float3 size() const
|
||||
{
|
||||
return upper() - lower();
|
||||
}
|
||||
|
||||
__forceinline float3 diag() const
|
||||
{
|
||||
return upper() - lower();
|
||||
}
|
||||
|
||||
__forceinline float3 centroid2() const
|
||||
{
|
||||
return upper() + lower();
|
||||
}
|
||||
|
||||
__forceinline float3 centroid() const
|
||||
{
|
||||
return (upper() + lower())*0.5f;
|
||||
}
|
||||
|
||||
__forceinline float length2() const
|
||||
{
|
||||
const float3 diag = size();
|
||||
return sycl::fma(diag.x(),diag.x(),
|
||||
sycl::fma(diag.y(),diag.y(),
|
||||
diag.z() * diag.z()));
|
||||
|
||||
}
|
||||
|
||||
__forceinline float maxDiagDim() const
|
||||
{
|
||||
const float3 d = diag();
|
||||
return max(max(d.x(),d.y()),d.z());
|
||||
}
|
||||
|
||||
__forceinline void atomic_merge_global(AABB3f &dest) const
|
||||
{
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _lower_x(dest.lower_x);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _lower_y(dest.lower_y);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _lower_z(dest.lower_z);
|
||||
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _upper_x(dest.upper_x);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _upper_y(dest.upper_y);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> _upper_z(dest.upper_z);
|
||||
|
||||
_lower_x.fetch_min(lower_x);
|
||||
_lower_y.fetch_min(lower_y);
|
||||
_lower_z.fetch_min(lower_z);
|
||||
|
||||
_upper_x.fetch_max(upper_x);
|
||||
_upper_y.fetch_max(upper_y);
|
||||
_upper_z.fetch_max(upper_z);
|
||||
}
|
||||
|
||||
__forceinline void atomic_merge_local(AABB3f &dest) const
|
||||
{
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _lower_x(dest.lower_x);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _lower_y(dest.lower_y);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _lower_z(dest.lower_z);
|
||||
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _upper_x(dest.upper_x);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _upper_y(dest.upper_y);
|
||||
sycl::atomic_ref<float, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> _upper_z(dest.upper_z);
|
||||
|
||||
_lower_x.fetch_min(lower_x);
|
||||
_lower_y.fetch_min(lower_y);
|
||||
_lower_z.fetch_min(lower_z);
|
||||
|
||||
_upper_x.fetch_max(upper_x);
|
||||
_upper_y.fetch_max(upper_y);
|
||||
_upper_z.fetch_max(upper_z);
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_reduce() const
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = embree::sub_group_reduce(lower_x, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_y = embree::sub_group_reduce(lower_y, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_z = embree::sub_group_reduce(lower_z, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.upper_x = embree::sub_group_reduce(upper_x, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_y = embree::sub_group_reduce(upper_y, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_z = embree::sub_group_reduce(upper_z, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
return result;
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_broadcast(const sycl::id<1> &localID) const
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = embree::sub_group_broadcast<float>(lower_x,localID);
|
||||
result.lower_y = embree::sub_group_broadcast<float>(lower_y,localID);
|
||||
result.lower_z = embree::sub_group_broadcast<float>(lower_z,localID);
|
||||
result.upper_x = embree::sub_group_broadcast<float>(upper_x,localID);
|
||||
result.upper_y = embree::sub_group_broadcast<float>(upper_y,localID);
|
||||
result.upper_z = embree::sub_group_broadcast<float>(upper_z,localID);
|
||||
return result;
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_shuffle(const sycl::id<1> &localID) const
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = embree::sub_group_shuffle<float>(lower_x,localID);
|
||||
result.lower_y = embree::sub_group_shuffle<float>(lower_y,localID);
|
||||
result.lower_z = embree::sub_group_shuffle<float>(lower_z,localID);
|
||||
result.upper_x = embree::sub_group_shuffle<float>(upper_x,localID);
|
||||
result.upper_y = embree::sub_group_shuffle<float>(upper_y,localID);
|
||||
result.upper_z = embree::sub_group_shuffle<float>(upper_z,localID);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
__forceinline AABB3f sub_group_scan_exclusive_min_max() const
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = embree::sub_group_exclusive_scan(lower_x, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_y = embree::sub_group_exclusive_scan(lower_y, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_z = embree::sub_group_exclusive_scan(lower_z, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.upper_x = embree::sub_group_exclusive_scan(upper_x, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_y = embree::sub_group_exclusive_scan(upper_y, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_z = embree::sub_group_exclusive_scan(upper_z, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
return result;
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_scan_inclusive_min_max() const
|
||||
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = embree::sub_group_inclusive_scan(lower_x, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_y = embree::sub_group_inclusive_scan(lower_y, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.lower_z = embree::sub_group_inclusive_scan(lower_z, SYCL_EXT_ONEAPI::minimum<float>());
|
||||
result.upper_x = embree::sub_group_inclusive_scan(upper_x, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_y = embree::sub_group_inclusive_scan(upper_y, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
result.upper_z = embree::sub_group_inclusive_scan(upper_z, SYCL_EXT_ONEAPI::maximum<float>());
|
||||
return result;
|
||||
}
|
||||
|
||||
__forceinline AABB3f work_group_reduce() const
|
||||
{
|
||||
AABB3f result;
|
||||
result.lower_x = work_group_reduce_min(lower_x);
|
||||
result.lower_y = work_group_reduce_min(lower_y);
|
||||
result.lower_z = work_group_reduce_min(lower_z);
|
||||
result.upper_x = work_group_reduce_max(upper_x);
|
||||
result.upper_y = work_group_reduce_max(upper_y);
|
||||
result.upper_z = work_group_reduce_max(upper_z);
|
||||
return result;
|
||||
}
|
||||
|
||||
__forceinline float halfArea() const
|
||||
{
|
||||
const float3 d = size();
|
||||
return halfarea(d);
|
||||
}
|
||||
|
||||
__forceinline float area() const
|
||||
{
|
||||
return halfArea() * 2.0f;
|
||||
}
|
||||
|
||||
__forceinline float maxAbsElement() const
|
||||
{
|
||||
const float3 abs_l = abs(lower());
|
||||
const float3 abs_h = abs(upper());
|
||||
const float max_abs_l = max(max(abs_l.x(),abs_l.y()),abs_l.z());
|
||||
const float max_abs_h = max(max(abs_h.x(),abs_h.y()),abs_h.z());
|
||||
return max(max_abs_l,max_abs_h);
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_masked_reduce(const bool cmp) const
|
||||
{
|
||||
AABB3f result;
|
||||
const float _pos_inf = INFINITY;
|
||||
const float _neg_inf = -INFINITY;
|
||||
result.lower_x = cselect(cmp,lower_x,_pos_inf);
|
||||
result.lower_y = cselect(cmp,lower_y,_pos_inf);
|
||||
result.lower_z = cselect(cmp,lower_z,_pos_inf);
|
||||
result.upper_x = cselect(cmp,upper_x,_neg_inf);
|
||||
result.upper_y = cselect(cmp,upper_y,_neg_inf);
|
||||
result.upper_z = cselect(cmp,upper_z,_neg_inf);
|
||||
return result.sub_group_reduce();
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_invalidate_reduce_left(const uint pos) const
|
||||
{
|
||||
AABB3f result;
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const bool cmp = subgroupLocalID <= pos;
|
||||
const float _pos_inf = INFINITY;
|
||||
const float _neg_inf = -INFINITY;
|
||||
result.lower_x = cselect(cmp,lower_x,_pos_inf);
|
||||
result.lower_y = cselect(cmp,lower_y,_pos_inf);
|
||||
result.lower_z = cselect(cmp,lower_z,_pos_inf);
|
||||
result.upper_x = cselect(cmp,upper_x,_neg_inf);
|
||||
result.upper_y = cselect(cmp,upper_y,_neg_inf);
|
||||
result.upper_z = cselect(cmp,upper_z,_neg_inf);
|
||||
return result.sub_group_reduce();
|
||||
}
|
||||
|
||||
__forceinline AABB3f sub_group_invalidate_reduce_right(const uint pos) const
|
||||
{
|
||||
AABB3f result;
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const bool cmp = subgroupLocalID > pos;
|
||||
const float _pos_inf = INFINITY;
|
||||
const float _neg_inf = -INFINITY;
|
||||
result.lower_x = cselect(cmp,lower_x,_pos_inf);
|
||||
result.lower_y = cselect(cmp,lower_y,_pos_inf);
|
||||
result.lower_z = cselect(cmp,lower_z,_pos_inf);
|
||||
result.upper_x = cselect(cmp,upper_x,_neg_inf);
|
||||
result.upper_y = cselect(cmp,upper_y,_neg_inf);
|
||||
result.upper_z = cselect(cmp,upper_z,_neg_inf);
|
||||
return result.sub_group_reduce();
|
||||
}
|
||||
|
||||
__forceinline AABB3f conservativeBounds() const {
|
||||
const float ulps = 1.0f;
|
||||
const float3 abs_l = abs(lower());
|
||||
const float3 abs_h = abs(upper());
|
||||
const float max_abs_l = max(max(abs_l.x(),abs_l.y()),abs_l.z());
|
||||
const float max_abs_h = max(max(abs_h.x(),abs_h.y()),abs_h.z());
|
||||
const float err = ulps*std::numeric_limits<float>::epsilon() * max(max_abs_l,max_abs_h);
|
||||
AABB3f bounds(lower(),upper());
|
||||
bounds.enlarge(err);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
__forceinline BBox3f convert() const
|
||||
{
|
||||
return BBox3f(Vec3f(lower_x,lower_y,lower_z),Vec3f(upper_x,upper_y,upper_z));
|
||||
}
|
||||
|
||||
__forceinline bool checkNumericalBounds() const
|
||||
{
|
||||
const static float FLT_LARGE = 1.844E18f;
|
||||
if (lower_x < -FLT_LARGE || upper_x > FLT_LARGE) return false;
|
||||
if (lower_y < -FLT_LARGE || upper_y > FLT_LARGE) return false;
|
||||
if (lower_z < -FLT_LARGE || upper_z > FLT_LARGE) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline uint numEqualDims() const
|
||||
{
|
||||
uint equal_dims = lower_x == upper_x ? 1 : 0;
|
||||
equal_dims += lower_y == upper_y ? 1 : 0;
|
||||
equal_dims += lower_z == upper_z ? 1 : 0;
|
||||
return equal_dims;
|
||||
}
|
||||
|
||||
|
||||
friend __forceinline embree_ostream operator<<(embree_ostream cout, const AABB3f &aabb)
|
||||
{
|
||||
cout << "AABB3f { ";
|
||||
cout << " lower = (" << aabb.lower_x << ", " << aabb.lower_y << ", " << aabb.lower_z << ") ";
|
||||
cout << " upper = (" << aabb.upper_x << ", " << aabb.upper_y << ", " << aabb.upper_z << ") ";
|
||||
return cout << "}";
|
||||
}
|
||||
};
|
||||
|
||||
__forceinline AABB3f merge(const AABB3f &a, const AABB3f &b)
|
||||
{
|
||||
AABB3f bounds;
|
||||
bounds.lower_x = min(a.lower_x,b.lower_x);
|
||||
bounds.lower_y = min(a.lower_y,b.lower_y);
|
||||
bounds.lower_z = min(a.lower_z,b.lower_z);
|
||||
bounds.upper_x = max(a.upper_x,b.upper_x);
|
||||
bounds.upper_y = max(a.upper_y,b.upper_y);
|
||||
bounds.upper_z = max(a.upper_z,b.upper_z);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
__forceinline AABB3f intersect(const AABB3f &a, const AABB3f &b)
|
||||
{
|
||||
AABB3f bounds;
|
||||
bounds.lower_x = max(a.lower_x,b.lower_x);
|
||||
bounds.lower_y = max(a.lower_y,b.lower_y);
|
||||
bounds.lower_z = max(a.lower_z,b.lower_z);
|
||||
bounds.upper_x = min(a.upper_x,b.upper_x);
|
||||
bounds.upper_y = min(a.upper_y,b.upper_y);
|
||||
bounds.upper_z = min(a.upper_z,b.upper_z);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__forceinline float distance(const AABB3f &a, const AABB3f &b)
|
||||
{
|
||||
const float3 dist_lower = a.lower() - b.lower();
|
||||
const float3 dist_upper = a.upper() - b.upper();
|
||||
return sycl::fma(dist_lower.x(),dist_lower.x(),
|
||||
sycl::fma(dist_lower.y(),dist_lower.y(),
|
||||
sycl::fma(dist_lower.z(),dist_lower.z(),
|
||||
sycl::fma(dist_upper.x(),dist_upper.x(),
|
||||
sycl::fma(dist_upper.y(), dist_upper.y(), dist_upper.z() * dist_upper.z())))));
|
||||
}
|
||||
|
||||
__forceinline bool operator ==(const AABB3f& a, const AABB3f& b) {
|
||||
if (a.lower_x != b.lower_x ||
|
||||
a.lower_y != b.lower_y ||
|
||||
a.lower_z != b.lower_z ||
|
||||
a.upper_x != b.upper_x ||
|
||||
a.upper_y != b.upper_y ||
|
||||
a.upper_z != b.upper_z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline bool operator !=(const AABB3f& a, const AABB3f& b) {
|
||||
return !(a==b);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,348 +0,0 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../../common/sys/sycl.h"
|
||||
|
||||
using sycl::float16;
|
||||
using sycl::float8;
|
||||
using sycl::float4;
|
||||
using sycl::float3;
|
||||
using sycl::float2;
|
||||
using sycl::int16;
|
||||
using sycl::int8;
|
||||
using sycl::int4;
|
||||
using sycl::int3;
|
||||
using sycl::int2;
|
||||
using sycl::uint16;
|
||||
using sycl::uint8;
|
||||
using sycl::uint4;
|
||||
using sycl::uint3;
|
||||
using sycl::uint2;
|
||||
using sycl::uchar16;
|
||||
using sycl::uchar8;
|
||||
using sycl::uchar4;
|
||||
using sycl::uchar3;
|
||||
using sycl::uchar2;
|
||||
using sycl::uchar;
|
||||
using sycl::ushort16;
|
||||
using sycl::ushort8;
|
||||
using sycl::ushort4;
|
||||
using sycl::ushort3;
|
||||
using sycl::ushort2;
|
||||
|
||||
using sycl::fmax;
|
||||
using sycl::fmin;
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace gpu
|
||||
{
|
||||
__forceinline size_t alignTo(const size_t size, const size_t alignment)
|
||||
{
|
||||
return ((size+alignment-1)/alignment)*alignment;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
__forceinline T cfma(const T &a, const T &b, const T &c)
|
||||
{
|
||||
return sycl::fma(a,b,c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__forceinline T lerp(const T &a, const T &b, const float t) {
|
||||
return sycl::fma(T(1.0f-t),a,T(t)*b);
|
||||
}
|
||||
|
||||
__forceinline float halfarea(const sycl::float3 &d)
|
||||
{
|
||||
return sycl::fma(d.x(),d.y(),sycl::fma(d.x(),d.z(),d.y()*d.z()));
|
||||
}
|
||||
|
||||
__forceinline float halfarea(const sycl::float4 &d)
|
||||
{
|
||||
return sycl::fma((float)d.x(),((float)d.y()+(float)d.z()),(float)d.y()*(float)d.z());
|
||||
}
|
||||
|
||||
__forceinline float area(const sycl::float3 &d)
|
||||
{
|
||||
return halfarea(d) * 2.0f;
|
||||
}
|
||||
|
||||
__forceinline float area(const sycl::float4 &d)
|
||||
{
|
||||
return halfarea(d) * 2.0f;
|
||||
}
|
||||
|
||||
__forceinline float dot3(const float3 &a,
|
||||
const float3 &b)
|
||||
{
|
||||
return sycl::dot(a,b);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_add_global(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> counter(*dest);
|
||||
return counter.fetch_add(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_min_global(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> counter(*dest);
|
||||
return counter.fetch_min(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_max_global(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> counter(*dest);
|
||||
return counter.fetch_max(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_or_global(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> counter(*dest);
|
||||
return counter.fetch_or(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_add_local(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> counter(*dest);
|
||||
return counter.fetch_add(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_min_local(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> counter(*dest);
|
||||
return counter.fetch_min(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_max_local(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> counter(*dest);
|
||||
return counter.fetch_max(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint atomic_or_local(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> counter(*dest);
|
||||
return counter.fetch_or(count);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint as_uint(T t)
|
||||
{
|
||||
return __builtin_bit_cast(uint,t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline uint as_int(T t)
|
||||
{
|
||||
return __builtin_bit_cast(int,t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline float as_float(T t)
|
||||
{
|
||||
return __builtin_bit_cast(float,t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline void* as_void(T t)
|
||||
{
|
||||
return __builtin_bit_cast(void*,t);
|
||||
}
|
||||
|
||||
__forceinline uint bitInterleave3D(const uint3 &in)
|
||||
{
|
||||
uint x = in.x(), y = in.y(), z = in.z();
|
||||
x = (x | (x << 16)) & 0x030000FF;
|
||||
x = (x | (x << 8)) & 0x0300F00F;
|
||||
x = (x | (x << 4)) & 0x030C30C3;
|
||||
x = (x | (x << 2)) & 0x09249249;
|
||||
|
||||
y = (y | (y << 16)) & 0x030000FF;
|
||||
y = (y | (y << 8)) & 0x0300F00F;
|
||||
y = (y | (y << 4)) & 0x030C30C3;
|
||||
y = (y | (y << 2)) & 0x09249249;
|
||||
|
||||
z = (z | (z << 16)) & 0x030000FF;
|
||||
z = (z | (z << 8)) & 0x0300F00F;
|
||||
z = (z | (z << 4)) & 0x030C30C3;
|
||||
z = (z | (z << 2)) & 0x09249249;
|
||||
|
||||
return x | (y << 1) | (z << 2);
|
||||
}
|
||||
|
||||
|
||||
__forceinline uint bitInterleave4D(const uint4 &in)
|
||||
{
|
||||
uint x = in.x(), y = in.y(), z = in.z(), w = in.w();
|
||||
|
||||
x = x & 0x000000ff;
|
||||
x = (x ^ (x << 16)) & 0x00c0003f;
|
||||
x = (x ^ (x << 8)) & 0x00c03807;
|
||||
x = (x ^ (x << 4)) & 0x08530853;
|
||||
x = (x ^ (x << 2)) & 0x09090909;
|
||||
x = (x ^ (x << 1)) & 0x11111111;
|
||||
|
||||
y = y & 0x000000ff;
|
||||
y = (y ^ (y << 16)) & 0x00c0003f;
|
||||
y = (y ^ (y << 8)) & 0x00c03807;
|
||||
y = (y ^ (y << 4)) & 0x08530853;
|
||||
y = (y ^ (y << 2)) & 0x09090909;
|
||||
y = (y ^ (y << 1)) & 0x11111111;
|
||||
|
||||
z = z & 0x000000ff;
|
||||
z = (z ^ (z << 16)) & 0x00c0003f;
|
||||
z = (z ^ (z << 8)) & 0x00c03807;
|
||||
z = (z ^ (z << 4)) & 0x08530853;
|
||||
z = (z ^ (z << 2)) & 0x09090909;
|
||||
z = (z ^ (z << 1)) & 0x11111111;
|
||||
|
||||
w = w & 0x000000ff;
|
||||
w = (w ^ (w << 16)) & 0x00c0003f;
|
||||
w = (w ^ (w << 8)) & 0x00c03807;
|
||||
w = (w ^ (w << 4)) & 0x08530853;
|
||||
w = (w ^ (w << 2)) & 0x09090909;
|
||||
w = (w ^ (w << 1)) & 0x11111111;
|
||||
|
||||
return (x | (y << 1) | (z << 2) | (w << 3));
|
||||
}
|
||||
|
||||
__forceinline uint64_t splitBy3(const uint a){
|
||||
uint64_t x = a & 0x1fffff;
|
||||
x = (x | x << 32) & 0x1f00000000ffff;
|
||||
x = (x | x << 16) & 0x1f0000ff0000ff;
|
||||
x = (x | x << 8) & 0x100f00f00f00f00f;
|
||||
x = (x | x << 4) & 0x10c30c30c30c30c3;
|
||||
x = (x | x << 2) & 0x1249249249249249;
|
||||
return x;
|
||||
}
|
||||
|
||||
__forceinline uint64_t bitInterleave3D_64bits(const uint3 v){
|
||||
return splitBy3(v.x()) | splitBy3(v.y()) << 1 | splitBy3(v.z()) << 2;
|
||||
}
|
||||
|
||||
__forceinline uint64_t bitInterleave4D_64bits(const uint4 &v){
|
||||
const uint low = bitInterleave4D(v>>0);
|
||||
const uint high = bitInterleave4D(v>>8);
|
||||
return (((uint64_t)high)<<32) | low;
|
||||
}
|
||||
|
||||
|
||||
__forceinline uint atomic_add_global_sub_group_shared(sycl::atomic_ref<uint, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> &counter, const uint add)
|
||||
{
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const uint ballot = sub_group_ballot(true);
|
||||
const uint first = sycl::ctz(ballot);
|
||||
const uint popc = sycl::popcount(ballot);
|
||||
const uint prefix = sycl::popcount(ballot & (((uint)1 << subgroupLocalID)-1));
|
||||
uint index = 0;
|
||||
if (subgroupLocalID == first)
|
||||
index = counter.fetch_add(popc * add);
|
||||
index = sub_group_broadcast(index,first);
|
||||
return index + prefix;
|
||||
}
|
||||
|
||||
__forceinline uint atomic_add_local_sub_group_shared(sycl::atomic_ref<uint, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> &counter, const uint add)
|
||||
{
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const uint ballot = sub_group_ballot(true);
|
||||
const uint first = sycl::ctz(ballot);
|
||||
const uint popc = sycl::popcount(ballot);
|
||||
const uint prefix = sycl::popcount(ballot & (((uint)1 << subgroupLocalID)-1));
|
||||
uint index = 0;
|
||||
if (subgroupLocalID == first)
|
||||
index = counter.fetch_add(popc * add);
|
||||
index = sub_group_broadcast(index,first);
|
||||
return index + prefix;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__forceinline uint atomic_add_global_sub_group_varying(sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> &counter, const T add)
|
||||
{
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const uint ballot = sub_group_ballot(true);
|
||||
const uint first = sycl::ctz(ballot);
|
||||
const T total = sub_group_reduce(add, SYCL_EXT_ONEAPI::plus<T>());
|
||||
const T prefix = sub_group_exclusive_scan(add, SYCL_EXT_ONEAPI::plus<T>());
|
||||
uint index = 0;
|
||||
if (subgroupLocalID == first)
|
||||
index = counter.fetch_add(total);
|
||||
index = sub_group_broadcast(index,first);
|
||||
return index + prefix;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline T atomic_add_global_sub_group_varying(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::global_space> counter(*dest);
|
||||
return atomic_add_global_sub_group_varying(counter,count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__forceinline uint atomic_add_local_sub_group_varying(sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::local_space> &counter, const T add)
|
||||
{
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
const uint ballot = sub_group_ballot(true);
|
||||
const uint first = sycl::ctz(ballot);
|
||||
const T total = sub_group_reduce(add, SYCL_EXT_ONEAPI::plus<T>());
|
||||
const T prefix = sub_group_exclusive_scan(add, SYCL_EXT_ONEAPI::plus<T>());
|
||||
uint index = 0;
|
||||
if (subgroupLocalID == first)
|
||||
index = counter.fetch_add(total);
|
||||
index = sub_group_broadcast(index,first);
|
||||
return index + prefix;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static __forceinline T atomic_add_local_sub_group_varying(T *dest, const T count=1)
|
||||
{
|
||||
sycl::atomic_ref<T, sycl::memory_order::relaxed, sycl::memory_scope::device,sycl::access::address_space::local_space> counter(*dest);
|
||||
return sub_group_shared_varying_local_atomic(counter,count);
|
||||
}
|
||||
|
||||
__forceinline void waitOnQueueAndCatchException(sycl::queue &gpu_queue)
|
||||
{
|
||||
try {
|
||||
gpu_queue.wait_and_throw();
|
||||
} catch (sycl::exception const& e) {
|
||||
std::cout << "Caught synchronous SYCL exception:\n"
|
||||
<< e.what() << std::endl;
|
||||
FATAL("SYCL Exception");
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void waitOnEventAndCatchException(sycl::event &event)
|
||||
{
|
||||
try {
|
||||
event.wait_and_throw();
|
||||
} catch (sycl::exception const& e) {
|
||||
std::cout << "Caught synchronous SYCL exception:\n"
|
||||
<< e.what() << std::endl;
|
||||
FATAL("SYCL Exception");
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline double getDeviceExecutionTiming(sycl::event &queue_event)
|
||||
{
|
||||
const auto t0 = queue_event.template get_profiling_info<sycl::info::event_profiling::command_start>();
|
||||
const auto t1 = queue_event.template get_profiling_info<sycl::info::event_profiling::command_end>();
|
||||
return (t1-t0)*1E-6;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT)
|
||||
#include "common.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace gpu
|
||||
{
|
||||
|
||||
struct Range {
|
||||
uint start;
|
||||
uint end;
|
||||
__forceinline Range()
|
||||
{}
|
||||
|
||||
__forceinline Range(const uint start, const uint end) : start(start), end(end)
|
||||
{}
|
||||
|
||||
__forceinline uint size() const { return end-start; }
|
||||
|
||||
__forceinline uint center() const { return (end+start)>>1; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ================================================================================================================================================================================
|
||||
// ============================================================================= MORTON CODES =====================================================================================
|
||||
// ================================================================================================================================================================================
|
||||
|
||||
|
||||
struct __aligned(8) MortonCodePrimitive40x24Bits3D
|
||||
{
|
||||
static const uint GRID_SHIFT = 13; // * 3 = 30
|
||||
|
||||
static const uint CODE_SHIFT = 64-(3*GRID_SHIFT+1);
|
||||
static const uint64_t INDEX_MASK = ((uint64_t)1 << CODE_SHIFT)-1;
|
||||
|
||||
uint64_t index_code; // 64bit code + index combo
|
||||
|
||||
__forceinline MortonCodePrimitive40x24Bits3D() {}
|
||||
__forceinline MortonCodePrimitive40x24Bits3D(const uint64_t code, const uint index) { index_code = (code << CODE_SHIFT) | (uint64_t)index; }
|
||||
__forceinline MortonCodePrimitive40x24Bits3D(const uint3 &v, const uint index)
|
||||
{
|
||||
const uint64_t code = gpu::bitInterleave3D(v);
|
||||
MortonCodePrimitive40x24Bits3D(code,index);
|
||||
}
|
||||
|
||||
__forceinline uint getIndex() const { return (uint)(index_code & INDEX_MASK); }
|
||||
__forceinline uint64_t getCode() const { return index_code; }
|
||||
|
||||
__forceinline uint64_t getMCode() const { return index_code & (~INDEX_MASK); }
|
||||
|
||||
__forceinline operator const uint64_t&() const { return index_code; }
|
||||
|
||||
__forceinline bool operator < (const MortonCodePrimitive40x24Bits3D& mc) const
|
||||
{
|
||||
return index_code < mc.index_code;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct __aligned(8) MortonCodePrimitive40x24Bits4D
|
||||
{
|
||||
static const uint GRID_SHIFT = 10; // * 4 = 40
|
||||
static const uint CODE_SHIFT = 64-4*GRID_SHIFT;
|
||||
static const uint64_t INDEX_MASK = ((uint64_t)1 << CODE_SHIFT)-1;
|
||||
|
||||
uint64_t index_code; // 64bit code + index combo
|
||||
|
||||
__forceinline MortonCodePrimitive40x24Bits4D() {}
|
||||
__forceinline MortonCodePrimitive40x24Bits4D(const uint64_t code, const uint index) { index_code = (code << CODE_SHIFT) | (uint64_t)index; }
|
||||
__forceinline MortonCodePrimitive40x24Bits4D(const uint4 &v, const uint index)
|
||||
{
|
||||
const uint64_t code = gpu::bitInterleave4D(v);
|
||||
MortonCodePrimitive40x24Bits4D(code,index);
|
||||
}
|
||||
|
||||
__forceinline uint getIndex() const { return (uint)(index_code & INDEX_MASK); }
|
||||
__forceinline uint64_t getCode() const { return index_code; }
|
||||
__forceinline uint64_t getMCode() const { return index_code & (~INDEX_MASK); }
|
||||
__forceinline operator const uint64_t&() const { return index_code; }
|
||||
__forceinline bool operator < (const MortonCodePrimitive40x24Bits4D& mc) const
|
||||
{
|
||||
return index_code < mc.index_code;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* used by PLOC in a two phase process */
|
||||
struct __aligned(8) MortonCodePrimitive64Bit_2x
|
||||
{
|
||||
static const uint GRID_SHIFT = 21; // * 3 = 63
|
||||
|
||||
static const uint CODE_SHIFT = 32;
|
||||
static const uint64_t INDEX_MASK = ((uint64_t)1 << CODE_SHIFT)-1;
|
||||
|
||||
uint64_t index_code; // 64bit code + index combo
|
||||
|
||||
__forceinline MortonCodePrimitive64Bit_2x() {}
|
||||
__forceinline MortonCodePrimitive64Bit_2x(const uint64_t code, const uint index) { index_code = (code << CODE_SHIFT) | (uint64_t)index; }
|
||||
|
||||
__forceinline uint getIndex() const { return (uint)(index_code & INDEX_MASK); }
|
||||
__forceinline uint64_t getCode() const { return index_code; }
|
||||
|
||||
__forceinline uint64_t getMCode() const { return index_code & (~INDEX_MASK); }
|
||||
|
||||
__forceinline operator const uint64_t&() const { return index_code; }
|
||||
|
||||
__forceinline bool operator < (const MortonCodePrimitive64Bit_2x& mc) const
|
||||
{
|
||||
return index_code < mc.index_code;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct MortonCodePrimitive64x32Bits3D
|
||||
{
|
||||
static const uint GRID_SHIFT = 21; // * 3 = 63
|
||||
static const uint KEY_BITS = 64;
|
||||
|
||||
uint64_t code;
|
||||
uint index;
|
||||
|
||||
__forceinline MortonCodePrimitive64x32Bits3D() {}
|
||||
__forceinline MortonCodePrimitive64x32Bits3D(const uint64_t code, const uint index) : code(code), index(index) {}
|
||||
__forceinline MortonCodePrimitive64x32Bits3D(const uint3 &v, const uint index) : code(gpu::bitInterleave3D_64bits(v)), index(index)
|
||||
{
|
||||
}
|
||||
|
||||
__forceinline bool operator < (const MortonCodePrimitive64x32Bits3D& emc) const
|
||||
{
|
||||
|
||||
if (code < emc.code)
|
||||
return true;
|
||||
else if (code == emc.code)
|
||||
return index < emc.index;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
__forceinline uint64_t getCode() const { return code; }
|
||||
__forceinline uint64_t getMCode() const { return code; }
|
||||
__forceinline uint getIndex() const { return index; }
|
||||
__forceinline operator const uint64_t&() const { return code; }
|
||||
};
|
||||
|
||||
struct MortonCodePrimitive64x32Bits4D
|
||||
{
|
||||
static const uint GRID_SHIFT = 16; // * 4 = 64
|
||||
static const uint KEY_BITS = 64;
|
||||
|
||||
uint64_t code;
|
||||
uint index;
|
||||
|
||||
__forceinline MortonCodePrimitive64x32Bits4D() {}
|
||||
__forceinline MortonCodePrimitive64x32Bits4D(const uint64_t code, const uint index) : code(code), index(index) {}
|
||||
__forceinline MortonCodePrimitive64x32Bits4D(const uint4 &v, const uint index) : code( gpu::bitInterleave4D_64bits(v)), index(index)
|
||||
{
|
||||
}
|
||||
|
||||
__forceinline bool operator < (const MortonCodePrimitive64x32Bits4D& emc) const
|
||||
{
|
||||
|
||||
if (code < emc.code)
|
||||
return true;
|
||||
else if (code == emc.code)
|
||||
return index < emc.index;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
__forceinline uint64_t getCode() const { return code; }
|
||||
__forceinline uint64_t getMCode() const { return code; }
|
||||
__forceinline uint getIndex() const { return index; }
|
||||
__forceinline operator const uint64_t&() const { return code; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename type>
|
||||
__forceinline unsigned int findSplit64Bit(const gpu::Range ¤t, const type *const morton)
|
||||
{
|
||||
const uint64_t code_start = morton[current.start].getCode();
|
||||
const uint64_t code_end = morton[current.end-1].getCode();
|
||||
|
||||
if (code_start != code_end)
|
||||
{
|
||||
uint64_t bitpos = sycl::clz(code_start^code_end);
|
||||
|
||||
/* split the items at the topmost different morton code bit */
|
||||
const uint64_t bitpos_diff = 63-bitpos;
|
||||
const uint64_t bitmask = (uint64_t)1 << bitpos_diff;
|
||||
|
||||
/* find location where bit differs using binary search */
|
||||
unsigned int begin = current.start;
|
||||
unsigned int end = current.end;
|
||||
while (begin + 1 != end) {
|
||||
const unsigned int mid = (begin+end)/2;
|
||||
const uint64_t bit = morton[mid].getCode() & bitmask;
|
||||
if (bit == 0) begin = mid; else end = mid;
|
||||
}
|
||||
unsigned int center = end;
|
||||
return center;
|
||||
}
|
||||
else /* if all items mapped to same morton code */
|
||||
{
|
||||
uint bitpos = sycl::clz(morton[current.start].getIndex()^morton[current.end-1].getIndex());
|
||||
|
||||
/* split the items at the topmost different morton code bit */
|
||||
const uint bitpos_diff = 31-bitpos;
|
||||
const uint bitmask = (uint)1 << bitpos_diff;
|
||||
|
||||
/* find location where bit differs using binary search */
|
||||
unsigned int begin = current.start;
|
||||
unsigned int end = current.end;
|
||||
while (begin + 1 != end) {
|
||||
const unsigned int mid = (begin+end)/2;
|
||||
const uint bit = morton[mid].getIndex() & bitmask;
|
||||
if (bit == 0) begin = mid; else end = mid;
|
||||
}
|
||||
unsigned int center = end;
|
||||
return center;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename type>
|
||||
__forceinline uint delta(const type& m0, const type& m1)
|
||||
{
|
||||
return m0.getCode() != m1 .getCode() ? (m0.getCode()^m1.getCode()) : m0.getIndex()^m1.getIndex(); //sycl::ext::intel::ctz(m0.index_code^m1.index_code);
|
||||
}
|
||||
|
||||
|
||||
template<typename type>
|
||||
__forceinline void splitRange(const gpu::Range ¤t, const type *const morton, gpu::Range &left, gpu::Range &right)
|
||||
{
|
||||
const uint split = findSplit64Bit(current,morton);
|
||||
left.start = current.start;
|
||||
left.end = split;
|
||||
right.start = split;
|
||||
right.end = current.end;
|
||||
}
|
||||
|
||||
|
||||
template<typename type>
|
||||
__forceinline int sigma(const int i1, const int i2, const type *const morton, const uint numPrimitives)
|
||||
{
|
||||
const int left = min(i1, i2);
|
||||
const int right = max(i1, i2);
|
||||
if (left < 0 || right >= numPrimitives) return -1;
|
||||
const ulong left_code = morton[left].getCode();
|
||||
const ulong right_code = morton[right].getCode();
|
||||
if (left_code != right_code)
|
||||
return sycl::clz(left_code ^ right_code);
|
||||
else
|
||||
return 64 + sycl::clz(morton[left].getIndex() ^ morton[right].getIndex());
|
||||
}
|
||||
|
||||
template<typename type>
|
||||
__forceinline struct gpu::Range findSegment(const unsigned int idx, const type *const mc, uint const numPrimitives)
|
||||
{
|
||||
const int delta = sigma(idx, idx+1, mc, numPrimitives) >= sigma(idx, idx-1, mc, numPrimitives) ? 1 : -1;
|
||||
const int sigma_min = sigma(idx, idx-delta, mc, numPrimitives);
|
||||
int max_range = 2;
|
||||
while (sigma(idx,idx + max_range * delta, mc, numPrimitives) > sigma_min)
|
||||
max_range <<= 1;
|
||||
int step = 0;
|
||||
int r = max_range;
|
||||
do
|
||||
{
|
||||
r >>= 1;
|
||||
if(sigma(idx, idx + (step + r)*delta, mc, numPrimitives) > sigma_min)
|
||||
step += r;
|
||||
}
|
||||
while (r > 1);
|
||||
struct gpu::Range range;
|
||||
range.start = min(idx, idx + step*delta);
|
||||
range.end = max(idx, idx + step*delta) + 1;
|
||||
return range;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,379 +0,0 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT)
|
||||
#include "common.h"
|
||||
|
||||
#define RADIX_SORT_BINS 256
|
||||
#define RADIX_SORT_MAX_NUM_DSS 128
|
||||
#define RADIX_SORT_WG_SIZE 512
|
||||
#define RADIX_ITERATIONS_64BIT 8
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace gpu
|
||||
{
|
||||
|
||||
__forceinline uint getNumWGsScratchSize(const ssize_t scratch_size)
|
||||
{
|
||||
return min(max( (int)floorf(scratch_size / (sizeof(uint)*RADIX_SORT_BINS))-1,(int)1),RADIX_SORT_MAX_NUM_DSS);
|
||||
}
|
||||
|
||||
__forceinline void localAtomicBallot(uint *const histogram, const uint ID, const uint add)
|
||||
{
|
||||
uint mask = sub_group_ballot(true);
|
||||
while(mask)
|
||||
{
|
||||
const uint first = sycl::ctz(mask);
|
||||
const uint index = sub_group_broadcast(ID,first);
|
||||
const bool cmp = ID == index;
|
||||
const uint cmp_mask = sub_group_ballot(cmp);
|
||||
const uint reduced_count = sycl::popcount(cmp_mask) * add;
|
||||
mask &= ~cmp_mask;
|
||||
|
||||
sycl::atomic_ref<uint, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> hist(histogram[ID]);
|
||||
if (get_sub_group_local_id() == first)
|
||||
hist += reduced_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__forceinline void radix_sort_single_workgroup(sycl::queue &gpu_queue, uint64_t *_input, uint64_t *_output, const uint numPrimitives, const uint start_iteration, const uint stop_iteration)
|
||||
{
|
||||
static const uint RADIX_SORT_SINGLE_WG_SIZE = 256;
|
||||
|
||||
struct __aligned(RADIX_SORT_SINGLE_WG_SIZE/32 * sizeof(uint)) BinFlags
|
||||
{
|
||||
uint flags[RADIX_SORT_SINGLE_WG_SIZE/32];
|
||||
};
|
||||
|
||||
const sycl::nd_range<1> nd_range1(RADIX_SORT_SINGLE_WG_SIZE,sycl::range<1>(RADIX_SORT_SINGLE_WG_SIZE));
|
||||
sycl::event event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
sycl::local_accessor< uint, 1> histogram(sycl::range<1>(RADIX_SORT_SINGLE_WG_SIZE),cgh);
|
||||
sycl::local_accessor< uint, 1> sums(sycl::range<1>(RADIX_SORT_SINGLE_WG_SIZE),cgh);
|
||||
sycl::local_accessor< uint, 1> prefix_sums(sycl::range<1>(RADIX_SORT_SINGLE_WG_SIZE),cgh);
|
||||
sycl::local_accessor< uint, 1> local_offset(sycl::range<1>(RADIX_SORT_SINGLE_WG_SIZE),cgh);
|
||||
sycl::local_accessor< BinFlags, 1> bin_flags(sycl::range<1>(RADIX_SORT_BINS),cgh);
|
||||
|
||||
cgh.parallel_for(nd_range1,[=](sycl::nd_item<1> item) EMBREE_SYCL_SIMD(16)
|
||||
{
|
||||
const uint localID = item.get_local_id(0);
|
||||
const uint step_local = item.get_local_range().size();
|
||||
const uint subgroupID = get_sub_group_id();
|
||||
const uint subgroupSize = get_sub_group_size();
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
|
||||
for (uint iter = start_iteration;iter<stop_iteration;iter++)
|
||||
{
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
const uint shift = iter*8;
|
||||
|
||||
const uint64_t *const input = (iter % 2) == 0 ? _input : _output;
|
||||
uint64_t *const output = (iter % 2) == 1 ? _input : _output;
|
||||
|
||||
// ==== bin key into global histogram =====
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
histogram[localID] = 0;
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
for (uint ID = localID; ID < numPrimitives; ID += step_local)
|
||||
{
|
||||
const uint bin = ((uint)(input[ID] >> shift)) & (RADIX_SORT_BINS - 1);
|
||||
//localAtomicBallot(histogram.get_pointer(),bin,1);
|
||||
gpu::atomic_add_local((uint*)histogram.get_pointer() + bin,(uint)1);
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
// ==== reduce global histogram =====
|
||||
|
||||
SYCL_EXT_ONEAPI::sub_group sub_group = this_sub_group();
|
||||
sub_group.barrier();
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
{
|
||||
const uint count = histogram[localID];
|
||||
const uint sum = sub_group_reduce(count, std::plus<uint>());
|
||||
const uint prefix_sum = sub_group_exclusive_scan(count, std::plus<uint>());
|
||||
|
||||
sums[localID] = sum;
|
||||
prefix_sums[localID] = prefix_sum;
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
|
||||
if (subgroupID == 0)
|
||||
{
|
||||
uint off = 0;
|
||||
for (int i = subgroupLocalID; i < RADIX_SORT_BINS; i += subgroupSize)
|
||||
{
|
||||
local_offset[i] = off + prefix_sums[i];
|
||||
off += sums[i];
|
||||
}
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
// ==== scatter key/value pairs according to global historgram =====
|
||||
|
||||
const uint flags_bin = localID / 32;
|
||||
const uint flags_bit = 1 << (localID % 32);
|
||||
|
||||
for (uint blockID = 0; blockID < numPrimitives; blockID += step_local)
|
||||
{
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
const uint ID = blockID + localID;
|
||||
|
||||
uint binID = 0;
|
||||
uint binOffset = 0;
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
for (int i=0;i<RADIX_SORT_SINGLE_WG_SIZE/32;i++)
|
||||
bin_flags[localID].flags[i] = 0;
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
|
||||
uint64_t in;
|
||||
if (ID < numPrimitives)
|
||||
{
|
||||
in = input[ID];
|
||||
binID = (in >> shift) & (RADIX_SORT_BINS - 1);
|
||||
binOffset = local_offset[binID];
|
||||
|
||||
sycl::atomic_ref<uint, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> bflags(bin_flags[binID].flags[flags_bin]);
|
||||
bflags.fetch_add(flags_bit);
|
||||
|
||||
}
|
||||
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
if (ID < numPrimitives)
|
||||
{
|
||||
uint prefix = 0;
|
||||
uint count = 0;
|
||||
for (uint i = 0; i < RADIX_SORT_SINGLE_WG_SIZE / 32; i++)
|
||||
{
|
||||
const uint bits = bin_flags[binID].flags[i];
|
||||
const uint full_count = sycl::popcount(bits);
|
||||
const uint partial_count = sycl::popcount(bits & (flags_bit - 1));
|
||||
prefix += (i < flags_bin) ? full_count : 0;
|
||||
prefix += (i == flags_bin) ? partial_count : 0;
|
||||
count += full_count;
|
||||
}
|
||||
|
||||
output[binOffset + prefix] = in;
|
||||
if (prefix == count - 1)
|
||||
local_offset[binID] += count;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
event.wait_and_throw();
|
||||
} catch (sycl::exception const& e) {
|
||||
std::cout << "Caught synchronous SYCL exception:\n"
|
||||
<< e.what() << std::endl;
|
||||
FATAL("SYCL Exception");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename sort_type>
|
||||
sycl::event radix_sort_iteration_type(sycl::queue &gpu_queue, sycl::event &input_event, sort_type *input, sort_type *output, const uint primitives, uint *global_histogram, const uint iter, const uint RADIX_SORT_NUM_DSS=256)
|
||||
{
|
||||
const uint shift = iter*8;
|
||||
|
||||
|
||||
// ==== bin key into global histogram =====
|
||||
|
||||
const sycl::nd_range<1> nd_range_binning(sycl::range<1>(RADIX_SORT_WG_SIZE*RADIX_SORT_NUM_DSS),sycl::range<1>(RADIX_SORT_WG_SIZE));
|
||||
sycl::event bin_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.depends_on(input_event);
|
||||
sycl::local_accessor< uint, 1> histogram(sycl::range<1>(RADIX_SORT_BINS),cgh);
|
||||
cgh.parallel_for(nd_range_binning,[=](sycl::nd_item<1> item) EMBREE_SYCL_SIMD(16)
|
||||
{
|
||||
const uint localID = item.get_local_id(0);
|
||||
const uint step_local = item.get_local_range().size();
|
||||
const uint groupID = item.get_group(0);
|
||||
|
||||
const uint startID = ((size_t)groupID + 0)*(size_t)primitives / RADIX_SORT_NUM_DSS;
|
||||
const uint endID = ((size_t)groupID + 1)*(size_t)primitives / RADIX_SORT_NUM_DSS;
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
histogram[localID] = 0;
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
for (uint ID = startID + localID; ID < endID; ID += step_local)
|
||||
{
|
||||
const uint64_t key = input[ID];
|
||||
const uint bin = ((uint)(key >> shift)) & (RADIX_SORT_BINS - 1);
|
||||
//gpu::localAtomicBallot(histogram.get_pointer(),bin,1);
|
||||
gpu::atomic_add_local((uint*)histogram.get_pointer() + bin,(uint)1);
|
||||
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
global_histogram[RADIX_SORT_BINS*groupID + localID] = histogram[localID];
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// ==== scatter key/value pairs according to global historgram =====
|
||||
|
||||
struct __aligned(64) BinFlags
|
||||
{
|
||||
uint flags[RADIX_SORT_WG_SIZE/32];
|
||||
};
|
||||
|
||||
const sycl::nd_range<1> nd_range_scatter(sycl::range<1>(RADIX_SORT_WG_SIZE*RADIX_SORT_NUM_DSS),sycl::range<1>(RADIX_SORT_WG_SIZE));
|
||||
sycl::event scatter_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.depends_on(bin_event);
|
||||
sycl::local_accessor< uint, 1> local_offset(sycl::range<1>(RADIX_SORT_BINS),cgh);
|
||||
sycl::local_accessor< uint, 1> sums(sycl::range<1>(RADIX_SORT_BINS),cgh);
|
||||
sycl::local_accessor< BinFlags, 1> bin_flags(sycl::range<1>(RADIX_SORT_BINS),cgh);
|
||||
cgh.parallel_for(nd_range_scatter,[=](sycl::nd_item<1> item) EMBREE_SYCL_SIMD(16)
|
||||
{
|
||||
const uint groupID = item.get_group(0);
|
||||
const uint localID = item.get_local_id(0);
|
||||
const uint step_local = item.get_local_range().size();
|
||||
const uint subgroupID = get_sub_group_id();
|
||||
const uint subgroupLocalID = get_sub_group_local_id();
|
||||
|
||||
|
||||
const uint startID = ((size_t)groupID + 0)*(size_t)primitives / RADIX_SORT_NUM_DSS;
|
||||
const uint endID = ((size_t)groupID + 1)*(size_t)primitives / RADIX_SORT_NUM_DSS;
|
||||
|
||||
|
||||
/* --- reduce global histogram --- */
|
||||
uint local_hist = 0;
|
||||
uint prefix_sum = 0;
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
{
|
||||
uint t = 0;
|
||||
for (uint j = 0; j < RADIX_SORT_NUM_DSS; j++)
|
||||
{
|
||||
const uint count = global_histogram[RADIX_SORT_BINS*j + localID];
|
||||
local_hist = (j == groupID) ? t : local_hist;
|
||||
t += count;
|
||||
}
|
||||
|
||||
const uint count = t;
|
||||
const uint sum = sub_group_reduce(count, std::plus<uint>());
|
||||
prefix_sum = sub_group_exclusive_scan(count, std::plus<uint>());
|
||||
|
||||
sums[subgroupID] = sum;
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
{
|
||||
const uint sums_prefix_sum = sub_group_broadcast(sub_group_exclusive_scan(sums[subgroupLocalID], std::plus<uint>()),subgroupID);
|
||||
const uint global_hist = sums_prefix_sum + prefix_sum;
|
||||
local_offset[localID] = global_hist + local_hist;
|
||||
}
|
||||
|
||||
// === barrier comes later ===
|
||||
|
||||
const uint flags_bin = localID / 32;
|
||||
const uint flags_bit = 1 << (localID % 32);
|
||||
|
||||
for (uint blockID = startID; blockID < endID; blockID += step_local)
|
||||
{
|
||||
|
||||
const uint ID = blockID + localID;
|
||||
|
||||
uint binID = 0;
|
||||
uint binOffset = 0;
|
||||
|
||||
#if 0
|
||||
if (localID < RADIX_SORT_BINS)
|
||||
for (int i=0;i<RADIX_SORT_WG_SIZE/32;i++)
|
||||
bin_flags[localID].flags[i] = 0;
|
||||
#else
|
||||
uint *const bflags = (uint*)&bin_flags.get_pointer()[0];
|
||||
for (uint i=localID;i<RADIX_SORT_BINS*RADIX_SORT_WG_SIZE/32;i+=step_local)
|
||||
bflags[i] = 0;
|
||||
#endif
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
sort_type key_value;
|
||||
uint64_t key;
|
||||
if (ID < endID)
|
||||
{
|
||||
key_value = input[ID];
|
||||
key = key_value;
|
||||
binID = (key >> shift) & (RADIX_SORT_BINS - 1);
|
||||
binOffset = local_offset[binID];
|
||||
sycl::atomic_ref<uint, sycl::memory_order::relaxed, sycl::memory_scope::work_group,sycl::access::address_space::local_space> bflags(bin_flags[binID].flags[flags_bin]);
|
||||
bflags += flags_bit;
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
if (ID < endID)
|
||||
{
|
||||
uint prefix = 0;
|
||||
uint count = 0;
|
||||
for (uint i = 0; i < RADIX_SORT_WG_SIZE / 32; i++)
|
||||
{
|
||||
const uint bits = bin_flags[binID].flags[i];
|
||||
const uint full_count = sycl::popcount(bits);
|
||||
const uint partial_count = sycl::popcount(bits & (flags_bit - 1));
|
||||
prefix += (i < flags_bin) ? full_count : 0;
|
||||
prefix += (i == flags_bin) ? partial_count : 0;
|
||||
count += full_count;
|
||||
}
|
||||
output[binOffset + prefix] = key_value;
|
||||
if (prefix == count - 1)
|
||||
local_offset[binID] += count;
|
||||
}
|
||||
|
||||
item.barrier(sycl::access::fence_space::local_space);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
return scatter_event;
|
||||
}
|
||||
|
||||
|
||||
template<typename sort_type>
|
||||
sycl::event radix_sort_Nx8Bit(sycl::queue &gpu_queue, sort_type *input, sort_type *output, const uint items, uint *global_histogram, const uint start_iteration, const uint end_iteration, sycl::event &initial, const uint RADIX_SORT_NUM_DSS=256)
|
||||
{
|
||||
sycl::event events[8]; // 8x8=64bit maximum
|
||||
for (uint i=start_iteration;i<end_iteration;i++)
|
||||
{
|
||||
events[i] = radix_sort_iteration_type<sort_type>(gpu_queue,i == start_iteration ? initial : events[i-1],input,output,items,global_histogram,i,RADIX_SORT_NUM_DSS);
|
||||
std::swap(input,output);
|
||||
}
|
||||
|
||||
return events[end_iteration-1];
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ZE_RAYTRACING)
|
||||
#include "sys/sysinfo.h"
|
||||
#include "sys/vector.h"
|
||||
#include "math/vec2.h"
|
||||
#include "math/vec3.h"
|
||||
#include "math/bbox.h"
|
||||
#include "math/affinespace.h"
|
||||
#else
|
||||
#include "../../../common/sys/sysinfo.h"
|
||||
#include "../../../common/sys/vector.h"
|
||||
#include "../../../common/math/vec2.h"
|
||||
@@ -10,6 +18,7 @@
|
||||
#include "../../../common/math/bbox.h"
|
||||
#include "../../../common/math/lbbox.h"
|
||||
#include "../../../common/math/affinespace.h"
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <bitset>
|
||||
@@ -81,13 +90,11 @@ namespace embree
|
||||
PrimLeafDesc(uint32_t shaderIndex, uint32_t geomIndex, GeometryFlags gflags, uint32_t geomMask, Type type = TYPE_NONE)
|
||||
: shaderIndex(shaderIndex), geomMask(geomMask), geomIndex(geomIndex), type(type), geomFlags((uint32_t)gflags)
|
||||
{
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
if (shaderIndex > MAX_SHADER_INDEX)
|
||||
throw std::runtime_error("too large shader ID");
|
||||
|
||||
if (geomIndex > MAX_GEOM_INDEX)
|
||||
throw std::runtime_error("too large geometry ID");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compares two PrimLeafDesc's for equality */
|
||||
@@ -139,7 +146,6 @@ namespace embree
|
||||
public:
|
||||
uint32_t shaderIndex : 24; // shader index used for shader record calculations
|
||||
uint32_t geomMask : 8; // geometry mask used for ray masking
|
||||
|
||||
|
||||
uint32_t geomIndex : 29; // the geometry index specifies the n'th geometry of the scene
|
||||
/*Type*/ uint32_t type : 1; // enable/disable culling for procedurals and instances
|
||||
@@ -159,10 +165,6 @@ namespace embree
|
||||
{
|
||||
QuadLeaf() {}
|
||||
|
||||
QuadLeaf(const QuadLeaf &q) {
|
||||
memcpy( this,&q, sizeof(QuadLeaf) );
|
||||
}
|
||||
|
||||
QuadLeaf (Vec3f v0, Vec3f v1, Vec3f v2, Vec3f v3,
|
||||
uint8_t j0, uint8_t j1, uint8_t j2,
|
||||
uint32_t shaderIndex, uint32_t geomIndex, uint32_t primIndex0, uint32_t primIndex1,
|
||||
@@ -179,9 +181,6 @@ namespace embree
|
||||
* distance between them can be at most 0xFFFF as we use 16 bits
|
||||
* to encode that difference. */
|
||||
assert(primIndex0 <= primIndex1 && primIndex1 - primIndex0 < 0xFFFF);
|
||||
// #if !defined(__SYCL_DEVICE_ONLY__)
|
||||
// print(std::cout,0);
|
||||
// #endif
|
||||
}
|
||||
|
||||
/* returns the i'th vertex */
|
||||
@@ -283,26 +282,22 @@ namespace embree
|
||||
}
|
||||
|
||||
public:
|
||||
union {
|
||||
struct {
|
||||
PrimLeafDesc leafDesc; // the leaf header
|
||||
uint32_t primIndex0; // primitive index of first triangle
|
||||
struct {
|
||||
uint32_t primIndex1Delta : 16; // delta encoded primitive index of second triangle
|
||||
uint32_t j0 : 2; // specifies first vertex of second triangle
|
||||
uint32_t j1 : 2; // specified second vertex of second triangle
|
||||
uint32_t j2 : 2; // specified third vertex of second triangle
|
||||
uint32_t last : 1; // true if the second triangle is the last triangle in a leaf list
|
||||
uint32_t pad : 9; // unused bits
|
||||
};
|
||||
};
|
||||
uint header[4];
|
||||
PrimLeafDesc leafDesc; // the leaf header
|
||||
|
||||
uint32_t primIndex0; // primitive index of first triangle
|
||||
struct {
|
||||
uint32_t primIndex1Delta : 16; // delta encoded primitive index of second triangle
|
||||
uint32_t j0 : 2; // specifies first vertex of second triangle
|
||||
uint32_t j1 : 2; // specified second vertex of second triangle
|
||||
uint32_t j2 : 2; // specified third vertex of second triangle
|
||||
uint32_t last : 1; // true if the second triangle is the last triangle in a leaf list
|
||||
uint32_t pad : 9; // unused bits
|
||||
};
|
||||
|
||||
Vec3f v0; // first vertex of first triangle
|
||||
Vec3f v1; // second vertex of first triangle
|
||||
Vec3f v2; // third vertex of first triangle
|
||||
Vec3f v3; // forth vertex used for second triangle
|
||||
Vec3f v3; // forth vertex used for second triangle
|
||||
};
|
||||
|
||||
static_assert(sizeof(QuadLeaf) == 64, "QuadLeaf must be 64 bytes large");
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace embree
|
||||
{
|
||||
template<typename InternalNode>
|
||||
void computeInternalNodeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area, size_t depth)
|
||||
void computeInternalNodeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area)
|
||||
{
|
||||
InternalNode* inner = node.innerNode<InternalNode>();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace embree
|
||||
if (inner->valid(i))
|
||||
{
|
||||
size++;
|
||||
computeStatistics(stats, inner->child(i), time_range, area(inner->bounds(i)), root_bounds_area, InternalNode::NUM_CHILDREN, depth+1);
|
||||
computeStatistics(stats, inner->child(i), time_range, area(inner->bounds(i)), root_bounds_area, InternalNode::NUM_CHILDREN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ namespace embree
|
||||
stats.internalNode.numChildrenTotal += InternalNode::NUM_CHILDREN;
|
||||
stats.internalNode.nodeSAH += time_range.size() * node_bounds_area / root_bounds_area;
|
||||
stats.internalNode.numBytes += sizeof(InternalNode);
|
||||
stats.depth = max(stats.depth, depth);
|
||||
}
|
||||
|
||||
void computeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area, uint32_t numChildren, size_t depth)
|
||||
void computeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area, uint32_t numChildren)
|
||||
{
|
||||
switch (node.type)
|
||||
{
|
||||
@@ -109,7 +108,7 @@ namespace embree
|
||||
}
|
||||
case NODE_TYPE_INTERNAL:
|
||||
{
|
||||
computeInternalNodeStatistics<QBVH6::InternalNode6>(stats, node, time_range, node_bounds_area, root_bounds_area, depth);
|
||||
computeInternalNodeStatistics<QBVH6::InternalNode6>(stats, node, time_range, node_bounds_area, root_bounds_area);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -120,15 +119,14 @@ namespace embree
|
||||
BVHStatistics QBVH6::computeStatistics() const
|
||||
{
|
||||
BVHStatistics stats;
|
||||
if (empty()) return stats;
|
||||
embree::computeStatistics(stats,root(),BBox1f(0,1),area(bounds),area(bounds),6,1);
|
||||
if (empty()) return stats;
|
||||
embree::computeStatistics(stats,root(),BBox1f(0,1),area(bounds),area(bounds),6);
|
||||
return stats;
|
||||
}
|
||||
|
||||
template<typename QInternalNode>
|
||||
void QBVH6::printInternalNodeStatistics(std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren)
|
||||
{
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
QInternalNode* inner = node.innerNode<QInternalNode>();
|
||||
inner->print(cout, depth, false);
|
||||
std::cout << std::endl;
|
||||
@@ -140,14 +138,10 @@ namespace embree
|
||||
}
|
||||
|
||||
cout << tab(depth) << "}" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBVH6::print( std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren)
|
||||
{
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
if (depth == 1) return;
|
||||
|
||||
switch (node.type)
|
||||
{
|
||||
case NODE_TYPE_INSTANCE: {
|
||||
@@ -220,7 +214,6 @@ namespace embree
|
||||
std::cout << "{ INVALID_NODE }" << std::endl;
|
||||
//assert(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned* getBackPointersData(const QBVH6* base) { // FIXME: should be member function
|
||||
@@ -241,7 +234,7 @@ namespace embree
|
||||
|
||||
void QBVH6::print ( std::ostream& cout ) const
|
||||
{
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
cout << "QBVH @ "<< this <<" header: {\n";
|
||||
cout << " rootNodeOffset = " << rootNodeOffset << std::endl;
|
||||
cout << " bounds = " << bounds << std::endl;
|
||||
@@ -268,7 +261,6 @@ namespace embree
|
||||
}
|
||||
cout << "}\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename QInternalNode>
|
||||
|
||||
@@ -6,12 +6,20 @@
|
||||
#include "qbvh6.h"
|
||||
#include "statistics.h"
|
||||
#include "quadifier.h"
|
||||
#include "rthwif_builder.h"
|
||||
#include "rtbuild.h"
|
||||
#include <atomic>
|
||||
|
||||
#if defined(ZE_RAYTRACING)
|
||||
#include "builders/priminfo.h"
|
||||
#include "builders/primrefgen_presplit.h"
|
||||
#include "builders/heuristic_binning_array_aligned.h"
|
||||
#include "algorithms/parallel_for_for_prefix_sum.h"
|
||||
#else
|
||||
#include "../../builders/priminfo.h"
|
||||
#include "../../builders/primrefgen_presplit.h"
|
||||
#include "../../builders/heuristic_binning_array_aligned.h"
|
||||
#include "../../../common/algorithms/parallel_for_for_prefix_sum.h"
|
||||
#endif
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -25,6 +33,11 @@ namespace embree
|
||||
/* the type of primitive that is referenced */
|
||||
enum Type { TRIANGLE=0, QUAD=1, PROCEDURAL=2, INSTANCE=3, UNKNOWN=4, NUM_TYPES=5 };
|
||||
|
||||
/* check when we use spatial splits */
|
||||
static bool useSpatialSplits(ze_rtas_builder_build_quality_hint_exp_t build_quality, ze_rtas_builder_build_op_exp_flags_t build_flags) {
|
||||
return build_quality == ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH && !(build_flags & ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION);
|
||||
}
|
||||
|
||||
/* BVH allocator */
|
||||
struct Allocator
|
||||
{
|
||||
@@ -42,22 +55,22 @@ namespace embree
|
||||
|
||||
__forceinline void* malloc(size_t bytes, size_t align = 16)
|
||||
{
|
||||
assert(align <= RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT);
|
||||
if (likely(cur.load() >= end)) throw std::bad_alloc();
|
||||
assert(align <= 128); //ZE_RAYTRACING_ACCELERATION_STRUCTURE_ALIGNMENT_EXT
|
||||
if (unlikely(cur.load() >= end)) return nullptr;
|
||||
const size_t extra = (align - cur) & (align-1);
|
||||
const size_t bytes_align = bytes + extra;
|
||||
const size_t cur_old = cur.fetch_add(bytes_align);
|
||||
const size_t cur_new = cur_old + bytes_align;
|
||||
if (likely(cur_new > end)) throw std::bad_alloc();
|
||||
if (unlikely(cur_new >= end)) return nullptr;
|
||||
return &ptr[cur_old + extra];
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
char* ptr; // data buffer pointer
|
||||
size_t end; // size of data buffer in bytes
|
||||
__aligned(64) std::atomic<size_t> cur; // current pointer to allocate next data block from
|
||||
};
|
||||
|
||||
|
||||
/* triangle data for leaf creation */
|
||||
struct Triangle
|
||||
{
|
||||
@@ -191,12 +204,10 @@ namespace embree
|
||||
__forceinline size_t end () const { return prims.end(); }
|
||||
__forceinline size_t size () const { return prims.size(); }
|
||||
__forceinline bool equalType() const { return type != UNKNOWN; }
|
||||
|
||||
#if !defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
friend inline std::ostream& operator<<(std::ostream& cout, const BuildRecord& r) {
|
||||
return cout << "BuildRecord { depth = " << r.depth << ", pinfo = " << r.prims << ", type = " << r.type << " }";
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
size_t depth; //!< Depth of the root of this subtree.
|
||||
@@ -226,10 +237,12 @@ namespace embree
|
||||
|
||||
struct ReductionTy
|
||||
{
|
||||
ReductionTy() {}
|
||||
ReductionTy() : node(nullptr) {}
|
||||
ReductionTy (void* node, NodeType type, uint8_t nodeMask, PrimRange primRange)
|
||||
: node((char*)node), type(type), nodeMask(nodeMask), primRange(primRange) {}
|
||||
|
||||
|
||||
inline bool valid() { return node != nullptr; }
|
||||
|
||||
public:
|
||||
char* node;
|
||||
NodeType type;
|
||||
@@ -308,7 +321,8 @@ namespace embree
|
||||
const getProceduralFunc& getProcedural,
|
||||
const getInstanceFunc& getInstance,
|
||||
void* scratch_ptr, size_t scratch_bytes,
|
||||
RTHWIF_BUILD_QUALITY build_quality,
|
||||
ze_rtas_builder_build_quality_hint_exp_t build_quality,
|
||||
ze_rtas_builder_build_op_exp_flags_t build_flags,
|
||||
bool verbose)
|
||||
: getSize(getSize),
|
||||
getType(getType),
|
||||
@@ -320,6 +334,7 @@ namespace embree
|
||||
getInstance(getInstance),
|
||||
prims(scratch_ptr,scratch_bytes),
|
||||
build_quality(build_quality),
|
||||
build_flags(build_flags),
|
||||
verbose(verbose) {}
|
||||
|
||||
ReductionTy setInternalNode(char* curAddr, size_t curBytes, NodeType nodeTy, char* childAddr,
|
||||
@@ -395,7 +410,7 @@ namespace embree
|
||||
return QuadLeaf(quad.p0,quad.p1,quad.p3,quad.p2, 3,2,1, 0, geomID, primID, primID, quad.gflags, quad.gmask, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const ReductionTy createQuads(Type ty, const BuildRecord& curRecord, char* curAddr_)
|
||||
{
|
||||
QuadLeaf* curAddr = (QuadLeaf*) curAddr_;
|
||||
@@ -414,17 +429,20 @@ namespace embree
|
||||
{
|
||||
/*! allocate data for all children */
|
||||
char* childData = (char*) allocator.malloc(curRecord.prims.size()*sizeof(QuadLeaf), 64);
|
||||
|
||||
|
||||
if (!childData)
|
||||
return ReductionTy();
|
||||
|
||||
/* create each child */
|
||||
ReductionTy values[BVH_WIDTH];
|
||||
for (size_t i=0, j=0; i<numChildren; i++) {
|
||||
values[i] = createQuads(ty,children[i],childData+j*sizeof(QuadLeaf));
|
||||
j += children[i].size();
|
||||
}
|
||||
|
||||
|
||||
return setNode(curAddr,curBytes,NODE_TYPE_QUAD,childData,children,values,numChildren);
|
||||
}
|
||||
|
||||
|
||||
const ReductionTy createProcedurals(const BuildRecord& curRecord, char* curAddr, size_t curBytes)
|
||||
{
|
||||
const uint32_t numPrims MAYBE_UNUSED = curRecord.size();
|
||||
@@ -442,9 +460,12 @@ namespace embree
|
||||
numGeometries += desc0 != desc1;
|
||||
desc0 = desc1;
|
||||
}
|
||||
|
||||
|
||||
char* childData = (char*) allocator.malloc(numGeometries*sizeof(ProceduralLeaf), 64);
|
||||
|
||||
|
||||
if (!childData)
|
||||
return ReductionTy();
|
||||
|
||||
ProceduralLeafBuilder procedural_leaf_builder(childData, numGeometries);
|
||||
ProceduralLeaf* first_procedural = procedural_leaf_builder.getCurProcedural();
|
||||
|
||||
@@ -476,7 +497,10 @@ namespace embree
|
||||
|
||||
/* allocate data for all children */
|
||||
InstanceLeaf* childData = (InstanceLeaf*) allocator.malloc(numPrimitives*sizeof(InstanceLeaf), 64);
|
||||
|
||||
|
||||
if (!childData)
|
||||
return ReductionTy();
|
||||
|
||||
QBVH6::InternalNode6* qnode = new (curAddr) QBVH6::InternalNode6(curRecord.bounds(),NODE_TYPE_INSTANCE);
|
||||
qnode->setChildOffset(childData);
|
||||
|
||||
@@ -683,10 +707,10 @@ namespace embree
|
||||
return createInstances(curRecord,curAddr,curBytes);
|
||||
else
|
||||
assert(false);
|
||||
|
||||
|
||||
return ReductionTy();
|
||||
}
|
||||
|
||||
|
||||
const ReductionTy createLargeLeaf(const BuildRecord& curRecord, char* curAddr, size_t curBytes)
|
||||
{
|
||||
/* this should never occur but is a fatal error */
|
||||
@@ -719,21 +743,25 @@ namespace embree
|
||||
/*! allocate data for all children */
|
||||
size_t childrenBytes = numChildren*sizeof(QBVH6::InternalNode6);
|
||||
char* childBase = (char*) allocator.malloc(childrenBytes, 64);
|
||||
|
||||
|
||||
if (!childBase)
|
||||
return ReductionTy();
|
||||
|
||||
/* recurse into each child and perform reduction */
|
||||
char* childPtr = childBase;
|
||||
for (size_t i=0; i<numChildren; i++) {
|
||||
values[i] = createLargeLeaf(children[i],childPtr,sizeof(QBVH6::InternalNode6));
|
||||
if (!values[i].valid()) return ReductionTy();
|
||||
childPtr += sizeof(QBVH6::InternalNode6);
|
||||
}
|
||||
|
||||
|
||||
return setNode(curAddr,curBytes,NODE_TYPE_INTERNAL,childBase,children,values,numChildren);
|
||||
}
|
||||
|
||||
const ReductionTy createInternalNode(BuildRecord& curRecord, char* curAddr, size_t curBytes)
|
||||
{
|
||||
/* create leaf when threshold reached or we are too deep */
|
||||
bool createLeaf = curRecord.prims.size() <= cfg.leafSize[curRecord.type] ||
|
||||
bool createLeaf = curRecord.prims.size() <= cfg.leafSize[curRecord.type] ||
|
||||
curRecord.depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth;
|
||||
|
||||
bool performTypeSplit = !curRecord.equalType() && (createLeaf || curRecord.size() <= cfg.typeSplitSize);
|
||||
@@ -787,28 +815,41 @@ namespace embree
|
||||
/*! allocate data for all children */
|
||||
size_t childrenBytes = numChildren*sizeof(QBVH6::InternalNode6);
|
||||
char* childBase = (char*) allocator.malloc(childrenBytes, 64);
|
||||
|
||||
|
||||
if (!childBase)
|
||||
return ReductionTy();
|
||||
|
||||
/* spawn tasks */
|
||||
if (curRecord.size() > 1024) // cfg.singleThreadThreshold
|
||||
{
|
||||
std::atomic<bool> success = true;
|
||||
parallel_for(size_t(0), numChildren, [&] (const range<size_t>& r) {
|
||||
if (!success) return;
|
||||
for (size_t i=r.begin(); i<r.end(); i++) {
|
||||
values[i] = createInternalNode(/*nullptr,*/children[i],childBase+i*sizeof(QBVH6::InternalNode6),sizeof(QBVH6::InternalNode6));
|
||||
values[i] = createInternalNode(children[i],childBase+i*sizeof(QBVH6::InternalNode6),sizeof(QBVH6::InternalNode6));
|
||||
if (!values[i].valid()) {
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!success)
|
||||
return ReductionTy();
|
||||
|
||||
/* create node */
|
||||
return setNode(curAddr,curBytes,NODE_TYPE_INTERNAL,childBase,children,values,numChildren);
|
||||
}
|
||||
|
||||
|
||||
/* recurse into each child */
|
||||
else
|
||||
{
|
||||
/* recurse into each child */
|
||||
for (size_t i=0; i<numChildren; i++) {
|
||||
values[i] = createInternalNode(children[i],childBase+i*sizeof(QBVH6::InternalNode6),sizeof(QBVH6::InternalNode6));
|
||||
if (!values[i].valid()) return ReductionTy();
|
||||
}
|
||||
|
||||
|
||||
/* create node */
|
||||
return setNode(curAddr,curBytes,NODE_TYPE_INTERNAL,childBase,children,values,numChildren);
|
||||
}
|
||||
@@ -1013,9 +1054,6 @@ namespace embree
|
||||
|
||||
ReductionTy build(uint32_t numGeometries, PrimInfo& pinfo_o, char* root)
|
||||
{
|
||||
//PING;
|
||||
//PRINT(numGeometries);
|
||||
|
||||
double t1 = verbose ? getSeconds() : 0.0;
|
||||
|
||||
/* quadify all triangles */
|
||||
@@ -1043,7 +1081,7 @@ namespace embree
|
||||
}, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
|
||||
|
||||
double t3 = verbose ? getSeconds() : 0.0;
|
||||
if (verbose) std::cout << "primrefgen : " << numPrimitives << " " << std::setw(10) << (t3-t2)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t3-t2) << " Mprims/s" << std::endl;
|
||||
if (verbose) std::cout << "primrefgen : " << std::setw(10) << (t3-t2)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t3-t2) << " Mprims/s" << std::endl;
|
||||
|
||||
/* if we need to filter out geometry, run again */
|
||||
if (pinfo.size() != numPrimitives)
|
||||
@@ -1064,10 +1102,8 @@ namespace embree
|
||||
if (verbose) std::cout << "primrefgen2 : " << std::setw(10) << (t4-t3)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t4-t3) << " Mprims/s" << std::endl;
|
||||
|
||||
/* perform pre-splitting */
|
||||
if ((build_quality == RTHWIF_BUILD_QUALITY_HIGH) && numPrimitives)
|
||||
if (useSpatialSplits(build_quality,build_flags) && numPrimitives)
|
||||
{
|
||||
PRINT("PRE-SPLITTING DISABLED");
|
||||
|
||||
auto splitter = [this] (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) {
|
||||
splitTriangleOrQuad(prim,dim,pos,left_o,right_o);
|
||||
};
|
||||
@@ -1109,7 +1145,7 @@ namespace embree
|
||||
return r;
|
||||
}
|
||||
|
||||
void build(size_t numGeometries, char* accel, size_t bytes, BBox3f* boundsOut, size_t* accelBufferBytesOut, void* dispatchGlobalsPtr)
|
||||
bool build(size_t numGeometries, char* accel, size_t bytes, BBox3f* boundsOut, size_t* accelBufferBytesOut, void* dispatchGlobalsPtr)
|
||||
{
|
||||
double t0 = verbose ? getSeconds() : 0.0;
|
||||
|
||||
@@ -1159,6 +1195,12 @@ namespace embree
|
||||
/* build BVH static BVH */
|
||||
QBVH6::InternalNode6* root = roots+0;
|
||||
ReductionTy r = build(numGeometries,pinfo,(char*)root);
|
||||
|
||||
/* check if build failed */
|
||||
if (!r.valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bounds.extend(pinfo.geomBounds);
|
||||
|
||||
if (boundsOut) *boundsOut = bounds;
|
||||
@@ -1175,14 +1217,6 @@ namespace embree
|
||||
qbvh->numTimeSegments = 1;
|
||||
qbvh->dispatchGlobalsPtr = (uint64_t) dispatchGlobalsPtr;
|
||||
|
||||
|
||||
#if 0
|
||||
BVHStatistics stats2 = qbvh->computeStatistics();
|
||||
stats2.print(std::cout);
|
||||
stats2.print_raw(std::cout);
|
||||
qbvh->print();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
BVHStatistics stats = qbvh->computeStatistics();
|
||||
stats.print(std::cout);
|
||||
@@ -1194,44 +1228,10 @@ namespace embree
|
||||
for (size_t i=0; i<bytes; i++) {
|
||||
if (i % 32 == 0) std::cout << std::endl << " ";
|
||||
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (unsigned)((unsigned char*)accel)[i] << ", ";
|
||||
=======
|
||||
/* fill QBVH6 header */
|
||||
allocator.clear();
|
||||
QBVH6* qbvh = new (accel.data()) QBVH6(QBVH6::SizeEstimate());
|
||||
qbvh->numPrims = numPrimitives;
|
||||
uint64_t rootNodeOffset = QBVH6::Node((char*)(r0.node - (char*)qbvh), r0.type, r0.primRange.cur_prim);
|
||||
assert(rootNodeOffset == QBVH6::rootNodeOffset);
|
||||
qbvh->bounds = bounds;
|
||||
qbvh->numTimeSegments = max(1u,maxTimeSegments);
|
||||
qbvh->dispatchGlobalsPtr = (uint64_t) dispatchGlobalsPtr;
|
||||
break;
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
if (verbose) {
|
||||
allocator.cleanup();
|
||||
FastAllocator::AllStatistics stats1(&allocator);
|
||||
stats1.print(numPrimitives);
|
||||
}
|
||||
|
||||
if (bytes >= worst_case_bytes) {
|
||||
throw std::runtime_error("BVH build failed");
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print BVH statistics in verbose mode */
|
||||
if (verbose)
|
||||
{
|
||||
QBVH6* qbvh = (QBVH6*) accel.data();
|
||||
BVHStatistics stats = qbvh->computeStatistics();
|
||||
stats.print(std::cout);
|
||||
stats.print_raw(std::cout);
|
||||
qbvh->print();
|
||||
}
|
||||
std::cout << std::endl << "};" << std::endl;*/
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1247,18 +1247,20 @@ namespace embree
|
||||
evector<PrimRef> prims;
|
||||
Allocator allocator;
|
||||
std::vector<std::vector<uint16_t>> quadification;
|
||||
RTHWIF_BUILD_QUALITY build_quality;
|
||||
ze_rtas_builder_build_quality_hint_exp_t build_quality;
|
||||
ze_rtas_builder_build_op_exp_flags_t build_flags;
|
||||
bool verbose;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename getSizeFunc,
|
||||
typename getTypeFunc>
|
||||
|
||||
static void estimateSize(size_t numGeometries,
|
||||
const getSizeFunc& getSize,
|
||||
const getTypeFunc& getType,
|
||||
RTHWIF_BUILD_QUALITY build_quality,
|
||||
ze_rtas_builder_build_quality_hint_exp_t build_quality,
|
||||
ze_rtas_builder_build_op_exp_flags_t build_flags,
|
||||
size_t& expectedBytes,
|
||||
size_t& worstCaseBytes,
|
||||
size_t& scratchBytes)
|
||||
@@ -1278,7 +1280,7 @@ namespace embree
|
||||
};
|
||||
}
|
||||
|
||||
if (build_quality == RTHWIF_BUILD_QUALITY_HIGH)
|
||||
if (useSpatialSplits(build_quality,build_flags))
|
||||
stats.estimate_presplits(1.2);
|
||||
|
||||
worstCaseBytes = stats.worst_case_bvh_bytes();
|
||||
@@ -1296,7 +1298,7 @@ namespace embree
|
||||
typename getProceduralFunc,
|
||||
typename getInstanceFunc>
|
||||
|
||||
static void build(size_t numGeometries,
|
||||
static bool build(size_t numGeometries,
|
||||
Device* device,
|
||||
const getSizeFunc& getSize,
|
||||
const getTypeFunc& getType,
|
||||
@@ -1310,7 +1312,8 @@ namespace embree
|
||||
void* scratch_ptr, size_t scratch_bytes,
|
||||
BBox3f* boundsOut,
|
||||
size_t* accelBufferBytesOut,
|
||||
RTHWIF_BUILD_QUALITY build_quality,
|
||||
ze_rtas_builder_build_quality_hint_exp_t build_quality,
|
||||
ze_rtas_builder_build_op_exp_flags_t build_flags,
|
||||
bool verbose,
|
||||
void* dispatchGlobalsPtr)
|
||||
{
|
||||
@@ -1320,10 +1323,10 @@ namespace embree
|
||||
throw std::runtime_error("scratch buffer cannot get aligned");
|
||||
|
||||
BuilderT<getSizeFunc, getTypeFunc, createPrimRefArrayFunc, getTriangleFunc, getTriangleIndicesFunc, getQuadFunc, getProceduralFunc, getInstanceFunc> builder
|
||||
(device, getSize, getType, createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance, scratch_ptr, scratch_bytes, build_quality, verbose);
|
||||
(device, getSize, getType, createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance, scratch_ptr, scratch_bytes, build_quality, build_flags, verbose);
|
||||
|
||||
builder.build(numGeometries, accel_ptr, accel_bytes, boundsOut, accelBufferBytesOut, dispatchGlobalsPtr);
|
||||
}
|
||||
return builder.build(numGeometries, accel_ptr, accel_bytes, boundsOut, accelBufferBytesOut, dispatchGlobalsPtr);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,12 +183,12 @@ namespace embree
|
||||
|
||||
NodeType nodeType; // the type of the node
|
||||
uint8_t pad; // unused byte
|
||||
|
||||
|
||||
int8_t exp_x; // 2^exp_x is the size of the grid in x dimension
|
||||
int8_t exp_y; // 2^exp_y is the size of the grid in y dimension
|
||||
int8_t exp_z; // 2^exp_z is the size of the grid in z dimension
|
||||
uint8_t nodeMask; // mask used for ray filtering
|
||||
|
||||
|
||||
struct ChildData
|
||||
{
|
||||
uint8_t blockIncr : 2; // size of child in 64 byte blocks
|
||||
@@ -196,14 +196,12 @@ namespace embree
|
||||
uint8_t pad : 2; // unused bits
|
||||
} childData[NUM_CHILDREN];
|
||||
|
||||
struct {
|
||||
uint8_t lower_x[NUM_CHILDREN]; // the quantized lower bounds in x-dimension
|
||||
uint8_t upper_x[NUM_CHILDREN]; // the quantized upper bounds in x-dimension
|
||||
uint8_t lower_y[NUM_CHILDREN]; // the quantized lower bounds in y-dimension
|
||||
uint8_t upper_y[NUM_CHILDREN]; // the quantized upper bounds in y-dimension
|
||||
uint8_t lower_z[NUM_CHILDREN]; // the quantized lower bounds in z-dimension
|
||||
uint8_t upper_z[NUM_CHILDREN]; // the quantized upper bounds in z-dimension
|
||||
};
|
||||
uint8_t lower_x[NUM_CHILDREN]; // the quantized lower bounds in x-dimension
|
||||
uint8_t upper_x[NUM_CHILDREN]; // the quantized upper bounds in x-dimension
|
||||
uint8_t lower_y[NUM_CHILDREN]; // the quantized lower bounds in y-dimension
|
||||
uint8_t upper_y[NUM_CHILDREN]; // the quantized upper bounds in y-dimension
|
||||
uint8_t lower_z[NUM_CHILDREN]; // the quantized lower bounds in z-dimension
|
||||
uint8_t upper_z[NUM_CHILDREN]; // the quantized upper bounds in z-dimension
|
||||
};
|
||||
|
||||
static_assert(sizeof(InternalNode6Data) == 64, "InternalNode6Data must be 64 bytes large");
|
||||
@@ -372,7 +370,6 @@ namespace embree
|
||||
int64_t getChildOffset(uint32_t childID) const
|
||||
{
|
||||
int64_t ofs = this->childOffset;
|
||||
if (ofs == 0) FATAL("OFFSET == 0");
|
||||
for (uint32_t j = 0; j < childID; j++)
|
||||
ofs += this->childData[j].blockIncr;
|
||||
return 64 * ofs;
|
||||
@@ -488,7 +485,7 @@ namespace embree
|
||||
dst->setChildOffset((char*)this + getChildOffset(0));
|
||||
}
|
||||
|
||||
#if !defined(__RTRT_GSIM) && !defined(__SYCL_DEVICE_ONLY__)
|
||||
#if !defined(__RTRT_GSIM)
|
||||
|
||||
/* output of internal node */
|
||||
void print(std::ostream& cout, uint32_t depth, bool close) const
|
||||
@@ -498,6 +495,7 @@ namespace embree
|
||||
cout << tab(depth) << " childOffset = " << 64 * int64_t(this->childOffset) << std::endl;
|
||||
cout << tab(depth) << " nodeType = " << NodeType(this->nodeType) << std::endl;
|
||||
cout << tab(depth) << " nodeMask = " << std::bitset<8>(this->nodeMask) << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_CHILDREN; i++)
|
||||
{
|
||||
cout << tab(depth) << " child" << i << " = { ";
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ZE_RAYTRACING)
|
||||
#include "sys/sysinfo.h"
|
||||
#include "sys/vector.h"
|
||||
#include "math/vec2.h"
|
||||
#include "math/vec3.h"
|
||||
#include "math/bbox.h"
|
||||
#include "math/affinespace.h"
|
||||
#else
|
||||
#include "../../common/default.h"
|
||||
|
||||
#define WINDOW_SIZE 32
|
||||
#endif
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -80,7 +87,7 @@ namespace embree
|
||||
}
|
||||
|
||||
template<typename GetTriangleFunc>
|
||||
__forceinline void merge_triangle_window( uint32_t geomID, static_deque<uint32_t,WINDOW_SIZE>& triangleWindow, QuadifierType* quads_o, const GetTriangleFunc& getTriangle )
|
||||
__forceinline void merge_triangle_window( uint32_t geomID, static_deque<uint32_t,32>& triangleWindow, QuadifierType* quads_o, const GetTriangleFunc& getTriangle )
|
||||
{
|
||||
uint32_t primID0 = triangleWindow.pop_front();
|
||||
|
||||
@@ -120,7 +127,7 @@ namespace embree
|
||||
template<typename GetTriangleFunc>
|
||||
inline size_t pair_triangles( uint32_t geomID, QuadifierType* quads_o, uint32_t primID0, uint32_t primID1, const GetTriangleFunc& getTriangle )
|
||||
{
|
||||
static_deque<uint32_t, WINDOW_SIZE> triangleWindow;
|
||||
static_deque<uint32_t, 32> triangleWindow;
|
||||
|
||||
size_t numTrianglePairs = 0;
|
||||
for (uint32_t primID=primID0; primID<primID1; primID++)
|
||||
@@ -131,11 +138,13 @@ namespace embree
|
||||
merge_triangle_window(geomID, triangleWindow,quads_o,getTriangle);
|
||||
numTrianglePairs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (triangleWindow.size()) {
|
||||
merge_triangle_window(geomID, triangleWindow,quads_o,getTriangle);
|
||||
numTrianglePairs++;
|
||||
}
|
||||
|
||||
return numTrianglePairs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,807 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#define RTHWIF_EXPORT_API
|
||||
|
||||
#include "rtbuild.h"
|
||||
#include "qbvh6_builder_sah.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
using namespace embree::isa;
|
||||
|
||||
static std::unique_ptr<tbb::task_arena> g_arena;
|
||||
|
||||
typedef enum _ze_raytracing_accel_format_internal_t {
|
||||
ZE_RTAS_DEVICE_FORMAT_EXP_INVALID = 0, // invalid acceleration structure format
|
||||
ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1 = 1, // acceleration structure format version 1
|
||||
ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_2 = 2, // acceleration structure format version 2
|
||||
ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_MAX = 2
|
||||
} ze_raytracing_accel_format_internal_t;
|
||||
|
||||
inline ze_rtas_triangle_indices_uint32_exp_t getPrimitive(const ze_rtas_builder_triangles_geometry_info_exp_t* geom, uint32_t primID) {
|
||||
assert(primID < geom->triangleCount);
|
||||
return *(ze_rtas_triangle_indices_uint32_exp_t*)((char*)geom->pTriangleBuffer + uint64_t(primID)*geom->triangleStride);
|
||||
}
|
||||
|
||||
inline Vec3f getVertex(const ze_rtas_builder_triangles_geometry_info_exp_t* geom, uint32_t vertexID) {
|
||||
assert(vertexID < geom->vertexCount);
|
||||
return *(Vec3f*)((char*)geom->pVertexBuffer + uint64_t(vertexID)*geom->vertexStride);
|
||||
}
|
||||
|
||||
inline ze_rtas_quad_indices_uint32_exp_t getPrimitive(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t primID) {
|
||||
assert(primID < geom->quadCount);
|
||||
return *(ze_rtas_quad_indices_uint32_exp_t*)((char*)geom->pQuadBuffer + uint64_t(primID)*geom->quadStride);
|
||||
}
|
||||
|
||||
inline Vec3f getVertex(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t vertexID) {
|
||||
assert(vertexID < geom->vertexCount);
|
||||
return *(Vec3f*)((char*)geom->pVertexBuffer + uint64_t(vertexID)*geom->vertexStride);
|
||||
}
|
||||
|
||||
inline AffineSpace3fa getTransform(const ze_rtas_builder_instance_geometry_info_exp_t* geom)
|
||||
{
|
||||
switch (geom->transformFormat)
|
||||
{
|
||||
case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_COLUMN_MAJOR: {
|
||||
const ze_rtas_transform_float3x4_column_major_exp_t* xfm = (const ze_rtas_transform_float3x4_column_major_exp_t*) geom->pTransform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR: {
|
||||
const ze_rtas_transform_float3x4_aligned_column_major_exp_t* xfm = (const ze_rtas_transform_float3x4_aligned_column_major_exp_t*) geom->pTransform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ROW_MAJOR: {
|
||||
const ze_rtas_transform_float3x4_row_major_exp_t* xfm = (const ze_rtas_transform_float3x4_row_major_exp_t*) geom->pTransform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("invalid transform format");
|
||||
}
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const ze_rtas_builder_triangles_geometry_info_exp_t* geom)
|
||||
{
|
||||
if (geom->triangleFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32)
|
||||
throw std::runtime_error("triangle format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32");
|
||||
|
||||
if (geom->vertexFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3)
|
||||
throw std::runtime_error("vertex format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3");
|
||||
|
||||
if (geom->triangleCount && geom->pTriangleBuffer == nullptr) throw std::runtime_error("no triangle buffer specified");
|
||||
if (geom->vertexCount && geom->pVertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const ze_rtas_builder_quads_geometry_info_exp_t* geom)
|
||||
{
|
||||
if (geom->quadFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32)
|
||||
throw std::runtime_error("quad format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32");
|
||||
|
||||
if (geom->vertexFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3)
|
||||
throw std::runtime_error("vertex format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3");
|
||||
|
||||
if (geom->quadCount && geom->pQuadBuffer == nullptr) throw std::runtime_error("no quad buffer specified");
|
||||
if (geom->vertexCount && geom->pVertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const ze_rtas_builder_procedural_geometry_info_exp_t* geom)
|
||||
{
|
||||
if (geom->primCount && geom->pfnGetBoundsCb == nullptr) throw std::runtime_error("no bounds function specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const ze_rtas_builder_instance_geometry_info_exp_t* geom)
|
||||
{
|
||||
if (geom->pTransform == nullptr) throw std::runtime_error("no instance transformation specified");
|
||||
if (geom->pBounds == nullptr) throw std::runtime_error("no acceleration structure bounds specified");
|
||||
if (geom->pAccelerationStructure == nullptr) throw std::runtime_error("no acceleration structure to instanciate specified");
|
||||
}
|
||||
|
||||
inline bool buildBounds(const ze_rtas_builder_triangles_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->triangleCount) return false;
|
||||
const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return false;
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
if (unlikely(!isvalid(p0))) return false;
|
||||
if (unlikely(!isvalid(p1))) return false;
|
||||
if (unlikely(!isvalid(p2))) return false;
|
||||
|
||||
bbox = BBox3fa(min(p0,p1,p2),max(p0,p1,p2));
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->quadCount) return false;
|
||||
const ze_rtas_quad_indices_uint32_exp_t tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v3 >= geom->vertexCount)) return false;
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
const Vec3f p3 = getVertex(geom,tri.v3);
|
||||
if (unlikely(!isvalid(p0))) return false;
|
||||
if (unlikely(!isvalid(p1))) return false;
|
||||
if (unlikely(!isvalid(p2))) return false;
|
||||
if (unlikely(!isvalid(p3))) return false;
|
||||
|
||||
bbox = BBox3fa(min(p0,p1,p2,p3),max(p0,p1,p2,p3));
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const ze_rtas_builder_procedural_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->primCount) return false;
|
||||
if (geom->pfnGetBoundsCb == nullptr) return false;
|
||||
|
||||
BBox3f bounds;
|
||||
ze_rtas_geometry_aabbs_exp_cb_params_t params = { ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS };
|
||||
params.primID = primID;
|
||||
params.primIDCount = 1;
|
||||
params.pGeomUserPtr = geom->pGeomUserPtr;
|
||||
params.pBuildUserPtr = buildUserPtr;
|
||||
params.pBoundsOut = (ze_rtas_aabb_exp_t*) &bounds;
|
||||
(geom->pfnGetBoundsCb)(¶ms);
|
||||
|
||||
if (unlikely(!isvalid(bounds.lower))) return false;
|
||||
if (unlikely(!isvalid(bounds.upper))) return false;
|
||||
if (unlikely(bounds.empty())) return false;
|
||||
|
||||
bbox = (BBox3f&) bounds;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const ze_rtas_builder_instance_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= 1) return false;
|
||||
if (geom->pAccelerationStructure == nullptr) return false;
|
||||
if (geom->pTransform == nullptr) return false;
|
||||
|
||||
const AffineSpace3fa local2world = getTransform(geom);
|
||||
const Vec3fa lower(geom->pBounds->lower.x,geom->pBounds->lower.y,geom->pBounds->lower.z);
|
||||
const Vec3fa upper(geom->pBounds->upper.x,geom->pBounds->upper.y,geom->pBounds->upper.z);
|
||||
const BBox3fa bounds = xfmBounds(local2world,BBox3fa(lower,upper));
|
||||
|
||||
if (unlikely(!isvalid(bounds.lower))) return false;
|
||||
if (unlikely(!isvalid(bounds.upper))) return false;
|
||||
if (unlikely(bounds.empty())) return false;
|
||||
|
||||
bbox = bounds;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename GeometryType>
|
||||
PrimInfo createGeometryPrimRefArray(const GeometryType* geom, void* buildUserPtr, evector<PrimRef>& prims, const range<size_t>& r, size_t k, unsigned int geomID)
|
||||
{
|
||||
PrimInfo pinfo(empty);
|
||||
for (uint32_t primID=r.begin(); primID<r.end(); primID++)
|
||||
{
|
||||
BBox3fa bounds = empty;
|
||||
if (!buildBounds(geom,primID,bounds,buildUserPtr)) continue;
|
||||
const PrimRef prim(bounds,geomID,primID);
|
||||
pinfo.add_center2(prim);
|
||||
prims[k++] = prim;
|
||||
}
|
||||
return pinfo;
|
||||
}
|
||||
|
||||
RTHWIF_API void zeRTASInitExp()
|
||||
{
|
||||
uint32_t numThreads = tbb::this_task_arena::max_concurrency();
|
||||
g_arena.reset(new tbb::task_arena(numThreads,numThreads));
|
||||
}
|
||||
|
||||
RTHWIF_API void zeRTASExitExp()
|
||||
{
|
||||
g_arena.reset();
|
||||
}
|
||||
|
||||
typedef struct _zet_base_desc_t
|
||||
{
|
||||
/** [in] type of this structure */
|
||||
ze_structure_type_t stype;
|
||||
|
||||
/** [in,out][optional] must be null or a pointer to an extension-specific structure */
|
||||
const void* pNext;
|
||||
|
||||
} zet_base_desc_t_;
|
||||
|
||||
#define VALIDATE(arg) \
|
||||
{\
|
||||
ze_result_t result = validate(arg);\
|
||||
if (result != ZE_RESULT_SUCCESS) return result; \
|
||||
}
|
||||
|
||||
#define VALIDATE_PTR(arg) \
|
||||
{ \
|
||||
if ((arg) == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; \
|
||||
} \
|
||||
|
||||
ze_result_t validate(ze_driver_handle_t hDriver)
|
||||
{
|
||||
if (hDriver == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(ze_device_handle_t hDevice)
|
||||
{
|
||||
if (hDevice == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
bool checkDescChain(zet_base_desc_t_* desc)
|
||||
{
|
||||
/* supporting maximal 1024 to also detect cycles */
|
||||
for (size_t i=0; i<1024; i++) {
|
||||
if (desc->pNext == nullptr) return true;
|
||||
desc = (zet_base_desc_t_*) desc->pNext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ze_rtas_builder
|
||||
{
|
||||
ze_rtas_builder () {
|
||||
}
|
||||
|
||||
~ze_rtas_builder() {
|
||||
magick = 0x0;
|
||||
}
|
||||
|
||||
bool verify() const {
|
||||
return magick == MAGICK;
|
||||
}
|
||||
|
||||
enum { MAGICK = 0x45FE67E1 };
|
||||
uint32_t magick = MAGICK;
|
||||
};
|
||||
|
||||
ze_result_t validate(ze_rtas_builder_exp_handle_t hBuilder)
|
||||
{
|
||||
if (hBuilder == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
|
||||
|
||||
if (!((ze_rtas_builder*)hBuilder)->verify())
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
struct ze_rtas_parallel_operation_t
|
||||
{
|
||||
//ze_rtas_parallel_operation_t(ze_rtas_builder_exp_handle_t hBuilder)
|
||||
//: hBuilder(hBuilder) {}
|
||||
|
||||
ze_rtas_parallel_operation_t() {
|
||||
}
|
||||
|
||||
~ze_rtas_parallel_operation_t() {
|
||||
magick = 0x0;
|
||||
//hBuilder = nullptr;
|
||||
}
|
||||
|
||||
bool verify() const {
|
||||
//return (magick == MAGICK) && (validate(hBuilder) == ZE_RESULT_SUCCESS);
|
||||
return (magick == MAGICK);
|
||||
}
|
||||
|
||||
enum { MAGICK = 0xE84567E1 };
|
||||
uint32_t magick = MAGICK;
|
||||
//ze_rtas_builder_exp_handle_t hBuilder = nullptr;
|
||||
ze_result_t errorCode = ZE_RESULT_SUCCESS;
|
||||
tbb::task_group group;
|
||||
};
|
||||
|
||||
ze_result_t validate(ze_rtas_parallel_operation_exp_handle_t hParallelOperation)
|
||||
{
|
||||
if (hParallelOperation == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
|
||||
|
||||
if (!((ze_rtas_parallel_operation_t*)hParallelOperation)->verify())
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(const ze_rtas_builder_exp_desc_t* pDescriptor)
|
||||
{
|
||||
if (pDescriptor == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
if (pDescriptor->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
if (!checkDescChain((zet_base_desc_t_*)pDescriptor))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
if (uint32_t(ZE_RTAS_BUILDER_EXP_VERSION_CURRENT) < uint32_t(pDescriptor->builderVersion))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(ze_rtas_device_exp_properties_t* pProperties)
|
||||
{
|
||||
if (pProperties == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
if (pProperties->stype != ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
if (!checkDescChain((zet_base_desc_t_*)pProperties))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(ze_rtas_format_exp_t rtasFormat)
|
||||
{
|
||||
if (uint32_t(rtasFormat) > uint32_t(ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_MAX))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(const ze_rtas_builder_build_op_exp_desc_t* args)
|
||||
{
|
||||
/* check for valid pointers */
|
||||
if (args == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
/* check if input descriptor has proper type */
|
||||
if (args->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
/* check valid pNext chain */
|
||||
if (!checkDescChain((zet_base_desc_t_*)args))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
/* check if acceleration structure format is supported */
|
||||
VALIDATE(args->rtasFormat);
|
||||
|
||||
/* check for valid geometries array */
|
||||
if (args->ppGeometries == nullptr && args->numGeometries > 0)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
/* validate build quality */
|
||||
if (args->buildQuality < 0 || ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < args->buildQuality)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
/* validate build flags */
|
||||
if (args->buildFlags >= (ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION<<1))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(ze_rtas_builder_exp_properties_t* pProp)
|
||||
{
|
||||
/* check for valid pointers */
|
||||
if (pProp == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
/* check if return property has proper type */
|
||||
if (pProp->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
/* check valid pNext chain */
|
||||
if (!checkDescChain((zet_base_desc_t_*)pProp))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t validate(ze_rtas_parallel_operation_exp_properties_t* pProperties)
|
||||
{
|
||||
/* check for valid pointer */
|
||||
if (pProperties == nullptr)
|
||||
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
|
||||
|
||||
/* check for proper property */
|
||||
if (pProperties->stype != ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES)
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
/* check valid pNext chain */
|
||||
if (!checkDescChain((zet_base_desc_t_*)pProperties))
|
||||
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderCreateExp(ze_driver_handle_t hDriver, const ze_rtas_builder_exp_desc_t *pDescriptor, ze_rtas_builder_exp_handle_t *phBuilder)
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hDriver);
|
||||
VALIDATE(pDescriptor);
|
||||
VALIDATE_PTR(phBuilder);
|
||||
|
||||
*phBuilder = (ze_rtas_builder_exp_handle_t) new ze_rtas_builder();
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderDestroyExp(ze_rtas_builder_exp_handle_t hBuilder)
|
||||
{
|
||||
VALIDATE(hBuilder);
|
||||
delete (ze_rtas_builder*) hBuilder;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeDeviceGetRTASPropertiesExp( const ze_device_handle_t hDevice, ze_rtas_device_exp_properties_t* pProperties )
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hDevice);
|
||||
VALIDATE(pProperties);
|
||||
|
||||
/* fill properties */
|
||||
pProperties->flags = 0;
|
||||
pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_INVALID;
|
||||
pProperties->rtasBufferAlignment = 128;
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
|
||||
/* check for supported device ID */
|
||||
ze_device_properties_t device_props{ ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES };
|
||||
ze_result_t status = zeDeviceGetProperties(hDevice, &device_props);
|
||||
if (status != ZE_RESULT_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* check for Intel vendor */
|
||||
const uint32_t vendor_id = device_props.vendorId;
|
||||
const uint32_t device_id = device_props.deviceId;
|
||||
if (vendor_id != 0x8086) return ZE_RESULT_ERROR_UNKNOWN;
|
||||
|
||||
bool dg2 =
|
||||
(0x4F80 <= device_id && device_id <= 0x4F88) ||
|
||||
(0x5690 <= device_id && device_id <= 0x5698) ||
|
||||
(0x56A0 <= device_id && device_id <= 0x56A6) ||
|
||||
(0x56B0 <= device_id && device_id <= 0x56B3) ||
|
||||
(0x56C0 <= device_id && device_id <= 0x56C1);
|
||||
|
||||
bool pvc =
|
||||
(0x0BD0 <= device_id && device_id <= 0x0BDB) ||
|
||||
(device_id == 0x0BE5 );
|
||||
|
||||
if (dg2 || pvc) {
|
||||
pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
|
||||
#else
|
||||
|
||||
pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderDeviceFormatCompatibilityCheckExp( ze_rtas_builder_exp_handle_t hBuilder,
|
||||
const ze_rtas_format_exp_t accelFormat,
|
||||
const ze_rtas_format_exp_t otherAccelFormat )
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hBuilder);
|
||||
VALIDATE(accelFormat);
|
||||
VALIDATE(otherAccelFormat);
|
||||
|
||||
/* check if rtas formats are compatible */
|
||||
if (accelFormat == otherAccelFormat)
|
||||
return ZE_RESULT_SUCCESS;
|
||||
|
||||
/* report incompatible format */
|
||||
return ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
uint32_t getNumPrimitives(const ze_rtas_builder_geometry_info_exp_t* geom)
|
||||
{
|
||||
switch (geom->geometryType) {
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return ((ze_rtas_builder_triangles_geometry_info_exp_t*) geom)->triangleCount;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL : return ((ze_rtas_builder_procedural_geometry_info_exp_t*) geom)->primCount;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return ((ze_rtas_builder_quads_geometry_info_exp_t*) geom)->quadCount;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : return 1;
|
||||
default : return 0;
|
||||
};
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderGetBuildPropertiesExp(ze_rtas_builder_exp_handle_t hBuilder,
|
||||
const ze_rtas_builder_build_op_exp_desc_t* args,
|
||||
ze_rtas_builder_exp_properties_t* pProp)
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hBuilder);
|
||||
VALIDATE(args);
|
||||
VALIDATE(pProp);
|
||||
|
||||
const ze_rtas_builder_geometry_info_exp_t** geometries = args->ppGeometries;
|
||||
const size_t numGeometries = args->numGeometries;
|
||||
|
||||
auto getSize = [&](uint32_t geomID) -> size_t {
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
if (geom == nullptr) return 0;
|
||||
return getNumPrimitives(geom);
|
||||
};
|
||||
|
||||
auto getType = [&](unsigned int geomID)
|
||||
{
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
switch (geom->geometryType) {
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS: return QBVH6BuilderSAH::QUAD;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return QBVH6BuilderSAH::PROCEDURAL;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return QBVH6BuilderSAH::INSTANCE;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
/* query memory requirements from builder */
|
||||
size_t expectedBytes = 0;
|
||||
size_t worstCaseBytes = 0;
|
||||
size_t scratchBytes = 0;
|
||||
QBVH6BuilderSAH::estimateSize(numGeometries, getSize, getType, args->buildQuality, args->buildFlags, expectedBytes, worstCaseBytes, scratchBytes);
|
||||
|
||||
/* fill return struct */
|
||||
pProp->flags = 0;
|
||||
pProp->rtasBufferSizeBytesExpected = expectedBytes;
|
||||
pProp->rtasBufferSizeBytesMaxRequired = worstCaseBytes;
|
||||
pProp->scratchBufferSizeBytes = scratchBytes;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderBuildExpInternal(const ze_rtas_builder_build_op_exp_desc_t* args,
|
||||
void *pScratchBuffer, size_t scratchBufferSizeBytes,
|
||||
void *pRtasBuffer, size_t rtasBufferSizeBytes,
|
||||
void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes) try
|
||||
{
|
||||
const ze_rtas_builder_geometry_info_exp_t** geometries = args->ppGeometries;
|
||||
const uint32_t numGeometries = args->numGeometries;
|
||||
|
||||
/* verify input descriptors */
|
||||
parallel_for(numGeometries,[&](uint32_t geomID) {
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
if (geom == nullptr) return;
|
||||
|
||||
switch (geom->geometryType) {
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : verifyGeometryDesc((ze_rtas_builder_triangles_geometry_info_exp_t*)geom); break;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : verifyGeometryDesc((ze_rtas_builder_quads_geometry_info_exp_t* )geom); break;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL : verifyGeometryDesc((ze_rtas_builder_procedural_geometry_info_exp_t*)geom); break;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : verifyGeometryDesc((ze_rtas_builder_instance_geometry_info_exp_t* )geom); break;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
});
|
||||
|
||||
auto getSize = [&](uint32_t geomID) -> size_t {
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
if (geom == nullptr) return 0;
|
||||
return getNumPrimitives(geom);
|
||||
};
|
||||
|
||||
auto getType = [&](unsigned int geomID)
|
||||
{
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
switch (geom->geometryType) {
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS: return QBVH6BuilderSAH::QUAD;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return QBVH6BuilderSAH::PROCEDURAL;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return QBVH6BuilderSAH::INSTANCE;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
auto createPrimRefArray = [&] (evector<PrimRef>& prims, BBox1f time_range, const range<size_t>& r, size_t k, unsigned int geomID) -> PrimInfo
|
||||
{
|
||||
const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
switch (geom->geometryType) {
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return createGeometryPrimRefArray((ze_rtas_builder_triangles_geometry_info_exp_t*)geom,pBuildUserPtr,prims,r,k,geomID);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return createGeometryPrimRefArray((ze_rtas_builder_quads_geometry_info_exp_t* )geom,pBuildUserPtr,prims,r,k,geomID);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return createGeometryPrimRefArray((ze_rtas_builder_procedural_geometry_info_exp_t*)geom,pBuildUserPtr,prims,r,k,geomID);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return createGeometryPrimRefArray((ze_rtas_builder_instance_geometry_info_exp_t* )geom,pBuildUserPtr,prims,r,k,geomID);
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
auto convertGeometryFlags = [&] (ze_rtas_builder_packed_geometry_exp_flags_t flags) -> GeometryFlags {
|
||||
return (flags & ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE) ? GeometryFlags::NONE : GeometryFlags::OPAQUE;
|
||||
};
|
||||
|
||||
auto getTriangle = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
const ze_rtas_builder_triangles_geometry_info_exp_t* geom = (const ze_rtas_builder_triangles_geometry_info_exp_t*) geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
if (unlikely(!isvalid(p0))) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(!isvalid(p1))) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(!isvalid(p2))) return QBVH6BuilderSAH::Triangle();
|
||||
|
||||
const GeometryFlags gflags = convertGeometryFlags(geom->geometryFlags);
|
||||
return QBVH6BuilderSAH::Triangle(tri.v0,tri.v1,tri.v2,p0,p1,p2,gflags,geom->geometryMask);
|
||||
};
|
||||
|
||||
auto getTriangleIndices = [&] (uint32_t geomID, uint32_t primID) {
|
||||
const ze_rtas_builder_triangles_geometry_info_exp_t* geom = (const ze_rtas_builder_triangles_geometry_info_exp_t*) geometries[geomID];
|
||||
assert(geom);
|
||||
const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID);
|
||||
return Vec3<uint32_t>(tri.v0,tri.v1,tri.v2);
|
||||
};
|
||||
|
||||
auto getQuad = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
const ze_rtas_builder_quads_geometry_info_exp_t* geom = (const ze_rtas_builder_quads_geometry_info_exp_t*) geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
const ze_rtas_quad_indices_uint32_exp_t quad = getPrimitive(geom,primID);
|
||||
const Vec3f p0 = getVertex(geom,quad.v0);
|
||||
const Vec3f p1 = getVertex(geom,quad.v1);
|
||||
const Vec3f p2 = getVertex(geom,quad.v2);
|
||||
const Vec3f p3 = getVertex(geom,quad.v3);
|
||||
|
||||
const GeometryFlags gflags = convertGeometryFlags(geom->geometryFlags);
|
||||
return QBVH6BuilderSAH::Quad(p0,p1,p2,p3,gflags,geom->geometryMask);
|
||||
};
|
||||
|
||||
auto getProcedural = [&](unsigned int geomID, unsigned int primID) {
|
||||
const ze_rtas_builder_procedural_geometry_info_exp_t* geom = (const ze_rtas_builder_procedural_geometry_info_exp_t*) geometries[geomID];
|
||||
assert(geom);
|
||||
return QBVH6BuilderSAH::Procedural(geom->geometryMask); // FIXME: pass gflags
|
||||
};
|
||||
|
||||
auto getInstance = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
assert(geometries[geomID]);
|
||||
assert(geometries[geomID]->geometryType == ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE);
|
||||
const ze_rtas_builder_instance_geometry_info_exp_t* geom = (const ze_rtas_builder_instance_geometry_info_exp_t*) geometries[geomID];
|
||||
void* accel = geom->pAccelerationStructure;
|
||||
const AffineSpace3fa local2world = getTransform(geom);
|
||||
return QBVH6BuilderSAH::Instance(local2world,accel,geom->geometryMask,geom->instanceUserID); // FIXME: pass instance flags
|
||||
};
|
||||
|
||||
/* dispatch globals ptr for debugging purposes */
|
||||
void* dispatchGlobalsPtr = nullptr;
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
dispatchGlobalsPtr = args->dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
bool verbose = false;
|
||||
bool success = QBVH6BuilderSAH::build(numGeometries, nullptr,
|
||||
getSize, getType,
|
||||
createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance,
|
||||
(char*)pRtasBuffer, rtasBufferSizeBytes,
|
||||
pScratchBuffer, scratchBufferSizeBytes,
|
||||
(BBox3f*) pBounds, pRtasBufferSizeBytes,
|
||||
args->buildQuality, args->buildFlags, verbose, dispatchGlobalsPtr);
|
||||
if (!success) {
|
||||
return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
std::cerr << "caught exception during BVH build: " << e.what() << std::endl;
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASBuilderBuildExp(ze_rtas_builder_exp_handle_t hBuilder,
|
||||
const ze_rtas_builder_build_op_exp_desc_t* args,
|
||||
void *pScratchBuffer, size_t scratchBufferSizeBytes,
|
||||
void *pRtasBuffer, size_t rtasBufferSizeBytes,
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation,
|
||||
void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes)
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hBuilder);
|
||||
VALIDATE(args);
|
||||
VALIDATE_PTR(pScratchBuffer);
|
||||
VALIDATE_PTR(pRtasBuffer);
|
||||
|
||||
/* if parallel operation is provided then execute using thread arena inside task group ... */
|
||||
if (hParallelOperation)
|
||||
{
|
||||
VALIDATE(hParallelOperation);
|
||||
|
||||
ze_rtas_parallel_operation_t* op = (ze_rtas_parallel_operation_t*) hParallelOperation;
|
||||
//if (op->hBuilder != hBuilder)
|
||||
// return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
g_arena->execute([&](){ op->group.run([=](){
|
||||
op->errorCode = zeRTASBuilderBuildExpInternal(args,
|
||||
pScratchBuffer, scratchBufferSizeBytes,
|
||||
pRtasBuffer, rtasBufferSizeBytes,
|
||||
pBuildUserPtr, pBounds, pRtasBufferSizeBytes);
|
||||
});
|
||||
});
|
||||
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
|
||||
}
|
||||
/* ... otherwise we just execute inside task arena to avoid spawning of TBB worker threads */
|
||||
else
|
||||
{
|
||||
ze_result_t errorCode = ZE_RESULT_SUCCESS;
|
||||
g_arena->execute([&](){ errorCode = zeRTASBuilderBuildExpInternal(args,
|
||||
pScratchBuffer, scratchBufferSizeBytes,
|
||||
pRtasBuffer, rtasBufferSizeBytes,
|
||||
pBuildUserPtr, pBounds, pRtasBufferSizeBytes);
|
||||
});
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASParallelOperationCreateExp(ze_driver_handle_t hDriver, ze_rtas_parallel_operation_exp_handle_t* phParallelOperation)
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hDriver);
|
||||
VALIDATE_PTR(phParallelOperation);
|
||||
|
||||
/* create parallel operation object */
|
||||
*phParallelOperation = (ze_rtas_parallel_operation_exp_handle_t) new ze_rtas_parallel_operation_t();
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASParallelOperationDestroyExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation )
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hParallelOperation);
|
||||
|
||||
/* delete parallel operation */
|
||||
delete (ze_rtas_parallel_operation_t*) hParallelOperation;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASParallelOperationGetPropertiesExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ze_rtas_parallel_operation_exp_properties_t* pProperties )
|
||||
{
|
||||
/* input validation */
|
||||
VALIDATE(hParallelOperation);
|
||||
VALIDATE(pProperties);
|
||||
|
||||
/* return properties */
|
||||
pProperties->flags = 0;
|
||||
pProperties->maxConcurrency = tbb::this_task_arena::max_concurrency();
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
RTHWIF_API ze_result_t zeRTASParallelOperationJoinExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation)
|
||||
{
|
||||
/* check for valid handle */
|
||||
VALIDATE(hParallelOperation);
|
||||
|
||||
ze_rtas_parallel_operation_t* op = (ze_rtas_parallel_operation_t*) hParallelOperation;
|
||||
g_arena->execute([&](){ op->group.wait(); });
|
||||
return op->errorCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// Copyright 2009-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# define RTHWIF_API_EXTERN_C extern "C"
|
||||
#else
|
||||
# define RTHWIF_API_EXTERN_C
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(EMBREE_RTHWIF_STATIC_LIB)
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C
|
||||
#else
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C __declspec(dllimport)
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
|
||||
#if defined(RTHWIF_EXPORT_API)
|
||||
# define RTHWIF_API RTHWIF_API_EXPORT
|
||||
#else
|
||||
# define RTHWIF_API RTHWIF_API_IMPORT
|
||||
#endif
|
||||
|
||||
#define ZE_APICALL_
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
#include <level_zero/ze_api.h>
|
||||
#else
|
||||
typedef struct _ze_driver_handle_t *ze_driver_handle_t;
|
||||
typedef struct _ze_device_handle_t *ze_device_handle_t;
|
||||
typedef enum _ze_result_t
|
||||
{
|
||||
ZE_RESULT_SUCCESS = 0, ///< [Core] success
|
||||
ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY = 0x70000002,///< [Core] insufficient host memory to satisfy call
|
||||
ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE = 0x7ff00004, ///< [Core, Experimental] operands of comparison are not compatible
|
||||
ZE_RESULT_ERROR_INVALID_ARGUMENT = 0x78000004, ///< [Validation] generic error code for invalid arguments
|
||||
ZE_RESULT_ERROR_INVALID_NULL_HANDLE = 0x78000005, ///< [Validation] handle argument is not valid
|
||||
ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE = 0x78000006, ///< [Validation] object pointed to by handle still in-use by device
|
||||
ZE_RESULT_ERROR_INVALID_NULL_POINTER = 0x78000007, ///< [Validation] pointer argument may not be nullptr
|
||||
ZE_RESULT_ERROR_INVALID_ENUMERATION = 0x7800000c, ///< [Validation] enumerator argument is not valid
|
||||
ZE_RESULT_ERROR_UNKNOWN = 0x7ffffffe, ///< [Core] unknown or internal error
|
||||
ZE_RESULT_FORCE_UINT32 = 0x7fffffff
|
||||
} ze_result_t;
|
||||
typedef enum _ze_structure_type_t {} ze_structure_type_t;
|
||||
#ifndef ZE_MAKE_VERSION
|
||||
# define ZE_MAKE_VERSION( _major, _minor ) (( _major << 16 )|( _minor & 0x0000ffff))
|
||||
#endif // ZE_MAKE_VERSION
|
||||
#ifndef ZE_BIT
|
||||
# define ZE_BIT( _i ) ( 1 << _i )
|
||||
#endif // ZE_BIT
|
||||
#define ZE_APICALL
|
||||
#endif
|
||||
|
||||
#if !defined(ZE_RTAS_BUILDER_EXP_NAME)
|
||||
#undef ZE_APIEXPORT
|
||||
#define ZE_APIEXPORT RTHWIF_API_EXPORT
|
||||
#include "ze_rtas.h"
|
||||
#endif
|
||||
|
||||
RTHWIF_API ze_result_t ZE_APICALL_ zeDeviceGetRTASPropertiesExp( const ze_device_handle_t hDevice, ze_rtas_device_exp_properties_t* pRtasProp );
|
||||
|
||||
|
||||
/*
|
||||
* Initializes the library.
|
||||
*/
|
||||
|
||||
RTHWIF_API void zeRTASInitExp();
|
||||
|
||||
/*
|
||||
* Cleans up the library.
|
||||
*/
|
||||
|
||||
RTHWIF_API void zeRTASExitExp();
|
||||
@@ -1,507 +0,0 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#define RTHWIF_EXPORT_API
|
||||
#include "../../../common/tasking/taskscheduler.h"
|
||||
|
||||
#include "rthwif_builder.h"
|
||||
#include "qbvh6_builder_sah.h"
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
#include <level_zero/ze_api.h>
|
||||
#endif
|
||||
|
||||
namespace embree
|
||||
{
|
||||
using namespace embree::isa;
|
||||
|
||||
static std::unique_ptr<tbb::task_arena> g_arena;
|
||||
|
||||
inline RTHWIF_TRIANGLE_INDICES getPrimitive(const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom, uint32_t primID) {
|
||||
assert(primID < geom->triangleCount);
|
||||
return *(RTHWIF_TRIANGLE_INDICES*)((char*)geom->triangleBuffer + uint64_t(primID)*geom->triangleStride);
|
||||
}
|
||||
|
||||
inline Vec3f getVertex(const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom, uint32_t vertexID) {
|
||||
assert(vertexID < geom->vertexCount);
|
||||
return *(Vec3f*)((char*)geom->vertexBuffer + uint64_t(vertexID)*geom->vertexStride);
|
||||
}
|
||||
|
||||
inline RTHWIF_QUAD_INDICES getPrimitive(const RTHWIF_GEOMETRY_QUADS_DESC* geom, uint32_t primID) {
|
||||
assert(primID < geom->quadCount);
|
||||
return *(RTHWIF_QUAD_INDICES*)((char*)geom->quadBuffer + uint64_t(primID)*geom->quadStride);
|
||||
}
|
||||
|
||||
inline Vec3f getVertex(const RTHWIF_GEOMETRY_QUADS_DESC* geom, uint32_t vertexID) {
|
||||
assert(vertexID < geom->vertexCount);
|
||||
return *(Vec3f*)((char*)geom->vertexBuffer + uint64_t(vertexID)*geom->vertexStride);
|
||||
}
|
||||
|
||||
inline AffineSpace3fa getTransform(const RTHWIF_GEOMETRY_INSTANCE_DESC* geom)
|
||||
{
|
||||
switch (geom->transformFormat)
|
||||
{
|
||||
case RTHWIF_TRANSFORM_FORMAT_FLOAT3X4_COLUMN_MAJOR: {
|
||||
const RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR* xfm = (const RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR*) geom->transform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
case RTHWIF_TRANSFORM_FORMAT_FLOAT4X4_COLUMN_MAJOR: {
|
||||
const RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR* xfm = (const RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR*) geom->transform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
case RTHWIF_TRANSFORM_FORMAT_FLOAT3X4_ROW_MAJOR: {
|
||||
const RTHWIF_TRANSFORM_FLOAT3X4_ROW_MAJOR* xfm = (const RTHWIF_TRANSFORM_FLOAT3X4_ROW_MAJOR*) geom->transform;
|
||||
return {
|
||||
{ xfm->vx_x, xfm->vx_y, xfm->vx_z },
|
||||
{ xfm->vy_x, xfm->vy_y, xfm->vy_z },
|
||||
{ xfm->vz_x, xfm->vz_y, xfm->vz_z },
|
||||
{ xfm-> p_x, xfm-> p_y, xfm-> p_z }
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("invalid transform format");
|
||||
}
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom)
|
||||
{
|
||||
if (geom->reserved0 != 0) throw std::runtime_error("reserved member must be 0");
|
||||
if (geom->reserved1 != 0) throw std::runtime_error("reserved member must be 0");
|
||||
if (geom->triangleCount && geom->triangleBuffer == nullptr) throw std::runtime_error("no triangle buffer specified");
|
||||
if (geom->vertexCount && geom->vertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const RTHWIF_GEOMETRY_QUADS_DESC* geom)
|
||||
{
|
||||
if (geom->reserved0 != 0) throw std::runtime_error("reserved member must be 0");
|
||||
if (geom->reserved1 != 0) throw std::runtime_error("reserved member must be 0");
|
||||
if (geom->quadCount && geom->quadBuffer == nullptr) throw std::runtime_error("no quad buffer specified");
|
||||
if (geom->vertexCount && geom->vertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const RTHWIF_GEOMETRY_AABBS_FPTR_DESC* geom)
|
||||
{
|
||||
if (geom->reserved != 0) throw std::runtime_error("reserved member must be 0");
|
||||
if (geom->primCount && geom->getBounds == nullptr) throw std::runtime_error("no bounds function specified");
|
||||
}
|
||||
|
||||
inline void verifyGeometryDesc(const RTHWIF_GEOMETRY_INSTANCE_DESC* geom)
|
||||
{
|
||||
if (geom->transform == nullptr) throw std::runtime_error("no instance transformation specified");
|
||||
if (geom->bounds == nullptr) throw std::runtime_error("no acceleration structure bounds specified");
|
||||
if (geom->accel == nullptr) throw std::runtime_error("no acceleration structure to instanciate specified");
|
||||
}
|
||||
|
||||
inline bool buildBounds(const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->triangleCount) return false;
|
||||
const RTHWIF_TRIANGLE_INDICES tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return false;
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
if (unlikely(!isvalid(p0))) return false;
|
||||
if (unlikely(!isvalid(p1))) return false;
|
||||
if (unlikely(!isvalid(p2))) return false;
|
||||
|
||||
bbox = BBox3fa(min(p0,p1,p2),max(p0,p1,p2));
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const RTHWIF_GEOMETRY_QUADS_DESC* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->quadCount) return false;
|
||||
const RTHWIF_QUAD_INDICES tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return false;
|
||||
if (unlikely(tri.v3 >= geom->vertexCount)) return false;
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
const Vec3f p3 = getVertex(geom,tri.v3);
|
||||
if (unlikely(!isvalid(p0))) return false;
|
||||
if (unlikely(!isvalid(p1))) return false;
|
||||
if (unlikely(!isvalid(p2))) return false;
|
||||
if (unlikely(!isvalid(p3))) return false;
|
||||
|
||||
bbox = BBox3fa(min(p0,p1,p2,p3),max(p0,p1,p2,p3));
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const RTHWIF_GEOMETRY_AABBS_FPTR_DESC* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= geom->primCount) return false;
|
||||
if (geom->getBounds == nullptr) return false;
|
||||
|
||||
BBox3f bounds;
|
||||
(geom->getBounds)(primID,1,geom->geomUserPtr,buildUserPtr,(RTHWIF_AABB*)&bounds);
|
||||
if (unlikely(!isvalid(bounds.lower))) return false;
|
||||
if (unlikely(!isvalid(bounds.upper))) return false;
|
||||
if (unlikely(bounds.empty())) return false;
|
||||
|
||||
bbox = (BBox3f&) bounds;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buildBounds(const RTHWIF_GEOMETRY_INSTANCE_DESC* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr)
|
||||
{
|
||||
if (primID >= 1) return false;
|
||||
if (geom->accel == nullptr) return false;
|
||||
if (geom->transform == nullptr) return false;
|
||||
|
||||
const AffineSpace3fa local2world = getTransform(geom);
|
||||
const Vec3fa lower(geom->bounds->lower.x,geom->bounds->lower.y,geom->bounds->lower.z);
|
||||
const Vec3fa upper(geom->bounds->upper.x,geom->bounds->upper.y,geom->bounds->upper.z);
|
||||
const BBox3fa bounds = xfmBounds(local2world,BBox3fa(lower,upper));
|
||||
|
||||
if (unlikely(!isvalid(bounds.lower))) return false;
|
||||
if (unlikely(!isvalid(bounds.upper))) return false;
|
||||
if (unlikely(bounds.empty())) return false;
|
||||
|
||||
bbox = bounds;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename GeometryType>
|
||||
PrimInfo createGeometryPrimRefArray(const GeometryType* geom, void* buildUserPtr, evector<PrimRef>& prims, const range<size_t>& r, size_t k, unsigned int geomID)
|
||||
{
|
||||
PrimInfo pinfo(empty);
|
||||
for (uint32_t primID=r.begin(); primID<r.end(); primID++)
|
||||
{
|
||||
BBox3fa bounds = empty;
|
||||
if (!buildBounds(geom,primID,bounds,buildUserPtr)) continue;
|
||||
const PrimRef prim(bounds,geomID,primID);
|
||||
pinfo.add_center2(prim);
|
||||
prims[k++] = prim;
|
||||
}
|
||||
return pinfo;
|
||||
}
|
||||
|
||||
RTHWIF_API void rthwifInit()
|
||||
{
|
||||
uint32_t numThreads = tbb::this_task_arena::max_concurrency();
|
||||
g_arena.reset(new tbb::task_arena(numThreads,numThreads));
|
||||
}
|
||||
|
||||
RTHWIF_API void rthwifExit()
|
||||
{
|
||||
g_arena.reset();
|
||||
}
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
|
||||
RTHWIF_API RTHWIF_FEATURES rthwifGetSupportedFeatures(ze_device_handle_t hDevice)
|
||||
{
|
||||
/* check for supported device ID */
|
||||
ze_device_properties_t device_props{ ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES };
|
||||
ze_result_t status = zeDeviceGetProperties(hDevice, &device_props);
|
||||
if (status != ZE_RESULT_SUCCESS)
|
||||
return RTHWIF_FEATURES_NONE;
|
||||
|
||||
/* check for Intel vendor */
|
||||
const uint32_t vendor_id = device_props.vendorId;
|
||||
const uint32_t device_id = device_props.deviceId;
|
||||
if (vendor_id != 0x8086) return RTHWIF_FEATURES_NONE;
|
||||
|
||||
/* return supported features */
|
||||
uint32_t features_xe = RTHWIF_FEATURES_NONE;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_TRIANGLES;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_QUADS;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_INSTANCE;
|
||||
|
||||
// DG2
|
||||
if (0x4F80 <= device_id && device_id <= 0x4F88) return (RTHWIF_FEATURES) features_xe;
|
||||
if (0x5690 <= device_id && device_id <= 0x5698) return (RTHWIF_FEATURES) features_xe;
|
||||
if (0x56A0 <= device_id && device_id <= 0x56A6) return (RTHWIF_FEATURES) features_xe;
|
||||
if (0x56B0 <= device_id && device_id <= 0x56B3) return (RTHWIF_FEATURES) features_xe;
|
||||
if (0x56C0 <= device_id && device_id <= 0x56C1) return (RTHWIF_FEATURES) features_xe;
|
||||
|
||||
// PVC
|
||||
if (0x0BD0 <= device_id && device_id <= 0x0BDB) return (RTHWIF_FEATURES) features_xe;
|
||||
if (device_id == 0x0BE5 ) return (RTHWIF_FEATURES) features_xe;
|
||||
|
||||
return RTHWIF_FEATURES_NONE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
RTHWIF_API RTHWIF_FEATURES rthwifGetSupportedFeatures(ze_device_handle_t hDevice)
|
||||
{
|
||||
uint32_t features_xe = RTHWIF_FEATURES_NONE;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_TRIANGLES;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_QUADS;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
features_xe |= RTHWIF_FEATURES_GEOMETRY_TYPE_INSTANCE;
|
||||
return RTHWIF_FEATURES(features_xe);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t getNumPrimitives(const RTHWIF_GEOMETRY_DESC* geom)
|
||||
{
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return ((RTHWIF_GEOMETRY_TRIANGLES_DESC*) geom)->triangleCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR : return ((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*) geom)->primCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return ((RTHWIF_GEOMETRY_QUADS_DESC*) geom)->quadCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : return 1;
|
||||
default : return 0;
|
||||
};
|
||||
}
|
||||
|
||||
/* fill all arg members that app did not know of yet */
|
||||
RTHWIF_BUILD_ACCEL_ARGS rthwifPrepareBuildAccelArgs(const RTHWIF_BUILD_ACCEL_ARGS& args_i)
|
||||
{
|
||||
RTHWIF_BUILD_ACCEL_ARGS args;
|
||||
memset(&args,0,sizeof(RTHWIF_BUILD_ACCEL_ARGS));
|
||||
memcpy(&args,&args_i,std::min(sizeof(RTHWIF_BUILD_ACCEL_ARGS),args_i.structBytes));
|
||||
args.structBytes = sizeof(RTHWIF_BUILD_ACCEL_ARGS);
|
||||
return args;
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifGetAccelSize(const RTHWIF_BUILD_ACCEL_ARGS& args_i, RTHWIF_ACCEL_SIZE& size_o)
|
||||
{
|
||||
RTHWIF_BUILD_ACCEL_ARGS args = rthwifPrepareBuildAccelArgs(args_i);
|
||||
const RTHWIF_GEOMETRY_DESC** geometries = args.geometries;
|
||||
const size_t numGeometries = args.numGeometries;
|
||||
|
||||
auto getSize = [&](uint32_t geomID) -> size_t {
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
if (geom == nullptr) return 0;
|
||||
return getNumPrimitives(geom);
|
||||
};
|
||||
|
||||
auto getType = [&](unsigned int geomID)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS: return QBVH6BuilderSAH::QUAD;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return QBVH6BuilderSAH::PROCEDURAL;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE: return QBVH6BuilderSAH::INSTANCE;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
/* query memory requirements from builder */
|
||||
size_t expectedBytes = 0;
|
||||
size_t worstCaseBytes = 0;
|
||||
size_t scratchBytes = 0;
|
||||
QBVH6BuilderSAH::estimateSize(numGeometries, getSize, getType, args.quality, expectedBytes, worstCaseBytes, scratchBytes);
|
||||
|
||||
/* return size to user */
|
||||
RTHWIF_ACCEL_SIZE size;
|
||||
memset(&size,0,sizeof(RTHWIF_ACCEL_SIZE));
|
||||
size.accelBufferExpectedBytes = expectedBytes;
|
||||
size.accelBufferWorstCaseBytes = worstCaseBytes;
|
||||
size.scratchBufferBytes = scratchBytes;
|
||||
size_t bytes_o = size_o.structBytes;
|
||||
memset(&size_o,0,bytes_o);
|
||||
memcpy(&size_o,&size,bytes_o);
|
||||
size_o.structBytes = bytes_o;
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifBuildAccelInternal(const RTHWIF_BUILD_ACCEL_ARGS& args_i) try
|
||||
{
|
||||
/* prepare input arguments */
|
||||
const RTHWIF_BUILD_ACCEL_ARGS args = rthwifPrepareBuildAccelArgs(args_i);
|
||||
const RTHWIF_GEOMETRY_DESC** geometries = args.geometries;
|
||||
const uint32_t numGeometries = args.numGeometries;
|
||||
|
||||
if (args.accelBuffer == nullptr) return RTHWIF_ERROR_OTHER;
|
||||
|
||||
/* verify input descriptors */
|
||||
parallel_for(numGeometries,[&](uint32_t geomID) {
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
if (geom == nullptr) return;
|
||||
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : verifyGeometryDesc((RTHWIF_GEOMETRY_TRIANGLES_DESC*)geom); break;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : verifyGeometryDesc((RTHWIF_GEOMETRY_QUADS_DESC* )geom); break;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR : verifyGeometryDesc((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*)geom); break;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : verifyGeometryDesc((RTHWIF_GEOMETRY_INSTANCE_DESC* )geom); break;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
});
|
||||
|
||||
auto getSize = [&](uint32_t geomID) -> size_t {
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
if (geom == nullptr) return 0;
|
||||
return getNumPrimitives(geom);
|
||||
};
|
||||
|
||||
auto getType = [&](unsigned int geomID)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS: return QBVH6BuilderSAH::QUAD;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return QBVH6BuilderSAH::PROCEDURAL;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE: return QBVH6BuilderSAH::INSTANCE;
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
auto createPrimRefArray = [&] (evector<PrimRef>& prims, BBox1f time_range, const range<size_t>& r, size_t k, unsigned int geomID) -> PrimInfo
|
||||
{
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return createGeometryPrimRefArray((RTHWIF_GEOMETRY_TRIANGLES_DESC*)geom,args.buildUserPtr,prims,r,k,geomID);
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return createGeometryPrimRefArray((RTHWIF_GEOMETRY_QUADS_DESC* )geom,args.buildUserPtr,prims,r,k,geomID);
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return createGeometryPrimRefArray((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*)geom,args.buildUserPtr,prims,r,k,geomID);
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE: return createGeometryPrimRefArray((RTHWIF_GEOMETRY_INSTANCE_DESC* )geom,args.buildUserPtr,prims,r,k,geomID);
|
||||
default: throw std::runtime_error("invalid geometry type");
|
||||
};
|
||||
};
|
||||
|
||||
auto getTriangle = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom = (const RTHWIF_GEOMETRY_TRIANGLES_DESC*) geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
const RTHWIF_TRIANGLE_INDICES tri = getPrimitive(geom,primID);
|
||||
if (unlikely(tri.v0 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(tri.v1 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(tri.v2 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle();
|
||||
|
||||
const Vec3f p0 = getVertex(geom,tri.v0);
|
||||
const Vec3f p1 = getVertex(geom,tri.v1);
|
||||
const Vec3f p2 = getVertex(geom,tri.v2);
|
||||
if (unlikely(!isvalid(p0))) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(!isvalid(p1))) return QBVH6BuilderSAH::Triangle();
|
||||
if (unlikely(!isvalid(p2))) return QBVH6BuilderSAH::Triangle();
|
||||
|
||||
const GeometryFlags gflags = (GeometryFlags) geom->geometryFlags;
|
||||
return QBVH6BuilderSAH::Triangle(tri.v0,tri.v1,tri.v2,p0,p1,p2,gflags,geom->geometryMask);
|
||||
};
|
||||
|
||||
auto getTriangleIndices = [&] (uint32_t geomID, uint32_t primID) {
|
||||
const RTHWIF_GEOMETRY_TRIANGLES_DESC* geom = (const RTHWIF_GEOMETRY_TRIANGLES_DESC*) geometries[geomID];
|
||||
assert(geom);
|
||||
const RTHWIF_TRIANGLE_INDICES tri = getPrimitive(geom,primID);
|
||||
return Vec3<uint32_t>(tri.v0,tri.v1,tri.v2);
|
||||
};
|
||||
|
||||
auto getQuad = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_QUADS_DESC* geom = (const RTHWIF_GEOMETRY_QUADS_DESC*) geometries[geomID];
|
||||
assert(geom);
|
||||
|
||||
const RTHWIF_QUAD_INDICES quad = getPrimitive(geom,primID);
|
||||
const Vec3f p0 = getVertex(geom,quad.v0);
|
||||
const Vec3f p1 = getVertex(geom,quad.v1);
|
||||
const Vec3f p2 = getVertex(geom,quad.v2);
|
||||
const Vec3f p3 = getVertex(geom,quad.v3);
|
||||
|
||||
const GeometryFlags gflags = (GeometryFlags) geom->geometryFlags;
|
||||
return QBVH6BuilderSAH::Quad(p0,p1,p2,p3,gflags,geom->geometryMask);
|
||||
};
|
||||
|
||||
auto getProcedural = [&](unsigned int geomID, unsigned int primID) {
|
||||
const RTHWIF_GEOMETRY_AABBS_FPTR_DESC* geom = (const RTHWIF_GEOMETRY_AABBS_FPTR_DESC*) geometries[geomID];
|
||||
assert(geom);
|
||||
return QBVH6BuilderSAH::Procedural(geom->geometryMask); // FIXME: pass gflags
|
||||
};
|
||||
|
||||
auto getInstance = [&](unsigned int geomID, unsigned int primID)
|
||||
{
|
||||
assert(geometries[geomID]);
|
||||
assert(geometries[geomID]->geometryType == RTHWIF_GEOMETRY_TYPE_INSTANCE);
|
||||
const RTHWIF_GEOMETRY_INSTANCE_DESC* geom = (const RTHWIF_GEOMETRY_INSTANCE_DESC*) geometries[geomID];
|
||||
void* accel = geom->accel;
|
||||
const AffineSpace3fa local2world = getTransform(geom);
|
||||
return QBVH6BuilderSAH::Instance(local2world,accel,geom->geometryMask,geom->instanceUserID); // FIXME: pass instance flags
|
||||
};
|
||||
|
||||
/* dispatch globals ptr for debugging purposes */
|
||||
void* dispatchGlobalsPtr = nullptr;
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
dispatchGlobalsPtr = args.dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
bool verbose = false;
|
||||
QBVH6BuilderSAH::build(numGeometries, nullptr,
|
||||
getSize, getType,
|
||||
createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance,
|
||||
(char*)args.accelBuffer, args.accelBufferBytes,
|
||||
args.scratchBuffer, args.scratchBufferBytes,
|
||||
(BBox3f*) args.boundsOut, args.accelBufferBytesOut,
|
||||
args.quality, verbose, dispatchGlobalsPtr);
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
|
||||
catch (std::exception& e) {
|
||||
if (std::string(e.what()) == std::string(std::bad_alloc().what())) {
|
||||
return RTHWIF_ERROR_RETRY;
|
||||
}
|
||||
else {
|
||||
return RTHWIF_ERROR_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
struct RTHWIF_PARALLEL_OPERATION_IMPL
|
||||
{
|
||||
RTHWIF_ERROR errorCode = RTHWIF_ERROR_NONE;
|
||||
tbb::task_group group;
|
||||
};
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifBuildAccel(const RTHWIF_BUILD_ACCEL_ARGS& args_i)
|
||||
{
|
||||
/* if parallel operation is provided then execute using thread arena inside task group ... */
|
||||
if (args_i.parallelOperation)
|
||||
{
|
||||
RTHWIF_PARALLEL_OPERATION_IMPL* op = (RTHWIF_PARALLEL_OPERATION_IMPL*) args_i.parallelOperation;
|
||||
g_arena->execute([&](){ op->group.run([=](){ op->errorCode = rthwifBuildAccelInternal(args_i); }); });
|
||||
return RTHWIF_ERROR_PARALLEL_OPERATION;
|
||||
}
|
||||
/* ... otherwise we just execute inside task arena to avoid spawning of TBB worker threads */
|
||||
else
|
||||
{
|
||||
RTHWIF_ERROR errorCode = RTHWIF_ERROR_NONE;
|
||||
g_arena->execute([&](){ errorCode = rthwifBuildAccelInternal(args_i); });
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_PARALLEL_OPERATION rthwifNewParallelOperation()
|
||||
{
|
||||
return (RTHWIF_PARALLEL_OPERATION) new RTHWIF_PARALLEL_OPERATION_IMPL;
|
||||
}
|
||||
|
||||
RTHWIF_API void rthwifDeleteParallelOperation( RTHWIF_PARALLEL_OPERATION parallelOperation )
|
||||
{
|
||||
delete (RTHWIF_PARALLEL_OPERATION_IMPL*) parallelOperation;
|
||||
}
|
||||
|
||||
RTHWIF_API uint32_t rthwifGetParallelOperationMaxConcurrency( RTHWIF_PARALLEL_OPERATION parallelOperation )
|
||||
{
|
||||
return tbb::this_task_arena::max_concurrency();
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifJoinParallelOperation( RTHWIF_PARALLEL_OPERATION parallelOperation)
|
||||
{
|
||||
RTHWIF_PARALLEL_OPERATION_IMPL* op = (RTHWIF_PARALLEL_OPERATION_IMPL*) parallelOperation;
|
||||
g_arena->execute([&](){ op->group.wait(); });
|
||||
return op->errorCode;
|
||||
}
|
||||
}
|
||||
@@ -1,474 +0,0 @@
|
||||
// Copyright 2009-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(EMBREE_LEVEL_ZERO)
|
||||
struct _ze_device_handle_t {};
|
||||
#else
|
||||
struct _ze_device_handle_t;
|
||||
#endif
|
||||
|
||||
typedef struct _ze_device_handle_t *ze_device_handle_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# define RTHWIF_API_EXTERN_C extern "C"
|
||||
#else
|
||||
# define RTHWIF_API_EXTERN_C
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(EMBREE_RTHWIF_STATIC_LIB)
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C
|
||||
#else
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C __declspec(dllimport)
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
# define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C
|
||||
# define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
|
||||
#if defined(RTHWIF_EXPORT_API)
|
||||
# define RTHWIF_API RTHWIF_API_EXPORT
|
||||
#else
|
||||
# define RTHWIF_API RTHWIF_API_IMPORT
|
||||
#endif
|
||||
|
||||
/* Required alignment of acceleration structure buffers. */
|
||||
#define RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT 128
|
||||
|
||||
/* Geometry flags supported (identical to DXR spec). */
|
||||
typedef enum RTHWIF_GEOMETRY_FLAGS : uint8_t
|
||||
{
|
||||
RTHWIF_GEOMETRY_FLAG_NONE = 0,
|
||||
RTHWIF_GEOMETRY_FLAG_OPAQUE = 0x1, // Opaque geometries do not invoke an anyhit shader
|
||||
RTHWIF_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 0x2 // Guarantees single anyhit shader invokation for primitives.
|
||||
} RTHWIF_GEOMETRY_FLAGS;
|
||||
|
||||
|
||||
/* A 3-component short vector type. */
|
||||
typedef struct RTHWIF_FLOAT3 {
|
||||
float x, y, z;
|
||||
} RTHWIF_FLOAT3;
|
||||
|
||||
|
||||
/* A 3x4 affine transformation with column vectors vx, vy, vz, and p
|
||||
* transforming a point (x,y,z) to x*vx + y*vy + z*vz + p. */
|
||||
typedef struct RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR {
|
||||
float vx_x, vx_y, vx_z; // column 0
|
||||
float vy_x, vy_y, vy_z; // column 1
|
||||
float vz_x, vz_y, vz_z; // column 2
|
||||
float p_x, p_y, p_z; // column 3
|
||||
} RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR;
|
||||
|
||||
|
||||
/* Same as RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR, with ignored 4th
|
||||
* component of column vectors. */
|
||||
typedef struct RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR {
|
||||
float vx_x, vx_y, vx_z, pad0; // column 0
|
||||
float vy_x, vy_y, vy_z, pad1; // column 1
|
||||
float vz_x, vz_y, vz_z, pad2; // column 2
|
||||
float p_x, p_y, p_z, pad3; // column 3
|
||||
} RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR;
|
||||
|
||||
|
||||
/* Same as RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR, but using row major
|
||||
* layout. */
|
||||
typedef struct RTHWIF_TRANSFORM_FLOAT3X4_ROW_MAJOR {
|
||||
float vx_x, vy_x, vz_x, p_x; // row 0
|
||||
float vx_y, vy_y, vz_y, p_y; // row 1
|
||||
float vx_z, vy_z, vz_z, p_z; // row 2
|
||||
} RTHWIF_TRANSFORM_FLOAT3X4_ROW_MAJOR;
|
||||
|
||||
|
||||
/* An axis aligned bounding box with lower and upper bounds in each
|
||||
* dimension. */
|
||||
typedef struct RTHWIF_AABB
|
||||
{
|
||||
RTHWIF_FLOAT3 lower; // lower bounds
|
||||
RTHWIF_FLOAT3 upper; // upper bounds
|
||||
} RTHWIF_AABB;
|
||||
|
||||
|
||||
/* A triangle represented using 3 vertex indices. */
|
||||
typedef struct RTHWIF_TRIANGLE_INDICES {
|
||||
uint32_t v0, v1, v2; // 3 triangle indices pointing into vertex array
|
||||
} RTHWIF_TRIANGLE_INDICES;
|
||||
|
||||
|
||||
/* A quad (triangle pair) represented using 4 vertex indices. */
|
||||
typedef struct RTHWIF_QUAD_INDICES {
|
||||
uint32_t v0, v1, v2, v3; // 4 quad indices pointing into vertex array
|
||||
} RTHWIF_QUAD_INDICES;
|
||||
|
||||
|
||||
/* The types of geometries supported. */
|
||||
typedef enum RTHWIF_GEOMETRY_TYPE : uint8_t
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE_TRIANGLES = 0, // triangle mesh geometry type
|
||||
RTHWIF_GEOMETRY_TYPE_QUADS = 1, // quad mesh geometry type
|
||||
RTHWIF_GEOMETRY_TYPE_AABBS_FPTR = 2, // procedural geometry with AABB bounds per primitive
|
||||
RTHWIF_GEOMETRY_TYPE_INSTANCE = 3, // instance geometry
|
||||
} RTHWIF_GEOMETRY_TYPE;
|
||||
|
||||
/* The format of transformations supported. */
|
||||
typedef enum RTHWIF_TRANSFORM_FORMAT : uint8_t
|
||||
{
|
||||
RTHWIF_TRANSFORM_FORMAT_FLOAT3X4_COLUMN_MAJOR = 0, // 3x4 affine transformation in column major format (see RTHWIF_TRANSFORM_FLOAT3X4_COLUMN_MAJOR layout)
|
||||
RTHWIF_TRANSFORM_FORMAT_FLOAT4X4_COLUMN_MAJOR = 1, // 4x4 affine transformation in column major format (see RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR layout)
|
||||
RTHWIF_TRANSFORM_FORMAT_FLOAT3X4_ROW_MAJOR = 2, // 3x4 affine transformation in row major format (see RTHWIF_TRANSFORM_FLOAT3X4_ROW_MAJOR layout)
|
||||
|
||||
} RTHWIF_TRANSFORM_FORMAT;
|
||||
|
||||
|
||||
/* Instance flags supported (identical to DXR spec) */
|
||||
typedef enum RTHWIF_INSTANCE_FLAGS : uint8_t
|
||||
{
|
||||
RTHWIF_INSTANCE_FLAG_NONE = 0,
|
||||
RTHWIF_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE = 0x1,
|
||||
RTHWIF_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2,
|
||||
RTHWIF_INSTANCE_FLAG_FORCE_OPAQUE = 0x4,
|
||||
RTHWIF_INSTANCE_FLAG_FORCE_NON_OPAQUE = 0x8
|
||||
} RTHWIF_INSTANCE_FLAGS;
|
||||
|
||||
|
||||
/* Triangle mesh geometry descriptor. */
|
||||
typedef struct RTHWIF_GEOMETRY_TRIANGLES_DESC // 40 bytes
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE geometryType; // must be RTHWIF_GEOMETRY_TYPE_TRIANGLES
|
||||
RTHWIF_GEOMETRY_FLAGS geometryFlags; // geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; // 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; // must be zero
|
||||
uint32_t reserved1; // must be zero
|
||||
unsigned int triangleCount; // number of triangles in triangleBuffer
|
||||
unsigned int triangleStride; // stride in bytes of triangles in triangleBuffer
|
||||
unsigned int vertexCount; // number of vertices in vertexBuffer
|
||||
unsigned int vertexStride; // stride in bytes of vertices in vertexBuffer
|
||||
RTHWIF_TRIANGLE_INDICES* triangleBuffer; // pointer to array of triangle indices
|
||||
RTHWIF_FLOAT3* vertexBuffer; // pointer to array of triangle vertices
|
||||
|
||||
} RTHWIF_RAYTRACING_GEOMETRY_TRIANGLES_DESC;
|
||||
|
||||
|
||||
/* Quad mesh geometry descriptor. A quad with vertices v0,v1,v2,v3 is
|
||||
* rendered as a pair of triangles (v0,v1,v3) and (v2,v3,v1), with
|
||||
* barycentric coordinates u/v of the second triangle corrected by
|
||||
* u=1-u, and v=1-v to make a u/v parametrization of the entire
|
||||
* [0,1]x[0,1] uv space. */
|
||||
typedef struct RTHWIF_GEOMETRY_QUADS_DESC // 40 bytes
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE geometryType; // must be RTHWIF_GEOMETRY_TYPE_QUADS
|
||||
RTHWIF_GEOMETRY_FLAGS geometryFlags; // geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; // 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; // must be zero
|
||||
uint32_t reserved1; // must be zero
|
||||
unsigned int quadCount; // number of quads in quadBuffer
|
||||
unsigned int quadStride; // stride in bytes of quads in quadBuffer
|
||||
unsigned int vertexCount; // number of vertices in vertexBuffer
|
||||
unsigned int vertexStride; // stride in bytes of vertices in vertexBuffer
|
||||
RTHWIF_QUAD_INDICES* quadBuffer; // pointer to array of quad indices
|
||||
RTHWIF_FLOAT3* vertexBuffer; // pointer to array of quad vertices
|
||||
|
||||
} RTHWIF_RAYTRACING_GEOMETRY_QUADS_DESC;
|
||||
|
||||
|
||||
/* Function pointer type to return AABBs for a range of procedural primitives. */
|
||||
typedef void (*RTHWIF_GEOMETRY_AABBS_FPTR)(const uint32_t primID, // first primitive to return bounds for
|
||||
const uint32_t primIDCount, // number of primitives to return bounds for
|
||||
void* geomUserPtr, // pointer provided through geometry descriptor
|
||||
void* buildUserPtr, // pointer provided through rthwifBuildAccel function
|
||||
RTHWIF_AABB* boundsOut // destination buffer to write AABB bounds to
|
||||
);
|
||||
|
||||
/* Geometry with procedural primitives bound by AABBs. */
|
||||
typedef struct RTHWIF_GEOMETRY_AABBS_FPTR_DESC // 24 bytes
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE geometryType; // must be RTHWIF_GEOMETRY_TYPE_AABBS_FPTR
|
||||
RTHWIF_GEOMETRY_FLAGS geometryFlags; // geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; // 8-bit geometry mask for ray masking
|
||||
uint8_t reserved; // must be zero
|
||||
unsigned int primCount; // number of primitives in geometry
|
||||
RTHWIF_GEOMETRY_AABBS_FPTR getBounds; // function pointer to return bounds for a range of primitives
|
||||
void* geomUserPtr; // geometry user pointer passed to callback
|
||||
|
||||
} RTHWIF_GEOMETRY_AABBS_DESC;
|
||||
|
||||
|
||||
/* Instance geometry descriptor. */
|
||||
typedef struct RTHWIF_GEOMETRY_INSTANCE_DESC // 32 bytes
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE geometryType; // must be RTHWIF_GEOMETRY_TYPE_INSTANCE
|
||||
RTHWIF_INSTANCE_FLAGS instanceFlags; // flags for the instance (see RTHWIF_INSTANCE_FLAGS)
|
||||
uint8_t geometryMask; // 8-bit geometry mask for ray masking
|
||||
RTHWIF_TRANSFORM_FORMAT transformFormat; // format of the specified transformation
|
||||
unsigned int instanceUserID; // a user specified identifier for the instance
|
||||
float* transform; // local to world instance transformation in specified format
|
||||
RTHWIF_AABB* bounds; // AABB of the instanced acceleration structure
|
||||
void* accel; // pointer to acceleration structure to instantiate
|
||||
|
||||
} RTHWIF_GEOMETRY_INSTANCE_DESC;
|
||||
|
||||
|
||||
/* A geometry descriptor. */
|
||||
typedef struct RTHWIF_GEOMETRY_DESC {
|
||||
RTHWIF_GEOMETRY_TYPE geometryType; // the first byte of a geometry descriptor is always its type and user can case to geometry descriptor structs above
|
||||
} RTHWIF_GEOMETRY_DESC;
|
||||
|
||||
|
||||
/* Bitmask with features supported. */
|
||||
typedef enum RTHWIF_FEATURES {
|
||||
RTHWIF_FEATURES_NONE = 0,
|
||||
RTHWIF_FEATURES_GEOMETRY_TYPE_TRIANGLES = 1 << 0, // support for RTHWIF_GEOMETRY_TYPE_TRIANGLES geometries
|
||||
RTHWIF_FEATURES_GEOMETRY_TYPE_QUADS = 1 << 1, // support for RTHWIF_GEOMETRY_TYPE_QUADS geometries
|
||||
RTHWIF_FEATURES_GEOMETRY_TYPE_AABBS_FPTR = 1 << 2, // support for RTHWIF_GEOMETRY_TYPE_AABBS_FPTR geometries
|
||||
RTHWIF_FEATURES_GEOMETRY_TYPE_INSTANCE = 1 << 3, // support for RTHWIF_GEOMETRY_TYPE_INSTANCE geometries
|
||||
|
||||
} RTHWIF_FEATURES;
|
||||
|
||||
|
||||
/* Return errors from API functions. */
|
||||
typedef enum RTHWIF_ERROR
|
||||
{
|
||||
RTHWIF_ERROR_NONE = 0x0, // no error occured
|
||||
RTHWIF_ERROR_RETRY = 0x1, // build ran out of memory, app should re-try with more memory
|
||||
RTHWIF_ERROR_OTHER = 0x2, // some unspecified error occured
|
||||
RTHWIF_ERROR_PARALLEL_OPERATION = 0x3, // task executing in parallel operation
|
||||
|
||||
} RTHWIF_ERROR;
|
||||
|
||||
|
||||
/* Build quality hint for acceleration structure build. */
|
||||
typedef enum RTHWIF_BUILD_QUALITY
|
||||
{
|
||||
RTHWIF_BUILD_QUALITY_LOW = 0, // build low quality acceleration structure (fast)
|
||||
RTHWIF_BUILD_QUALITY_MEDIUM = 1, // build medium quality acceleration structure (slower)
|
||||
RTHWIF_BUILD_QUALITY_HIGH = 2, // build high quality acceleration structure (slow)
|
||||
|
||||
} RTHWIF_BUILD_QUALITY;
|
||||
|
||||
|
||||
/* Some additional hints for acceleration structure build. */
|
||||
typedef enum RTHWIF_BUILD_FLAGS
|
||||
{
|
||||
RTHWIF_BUILD_FLAG_NONE = 0,
|
||||
RTHWIF_BUILD_FLAG_DYNAMIC = (1 << 0), // optimize for dynamic content
|
||||
RTHWIF_BUILD_FLAG_COMPACT = (1 << 1), // build more compact acceleration structure
|
||||
|
||||
} RTHWIF_BUILD_FLAGS;
|
||||
|
||||
|
||||
/* A handle of a parallel operation that can get joined with worker threads. */
|
||||
typedef void* RTHWIF_PARALLEL_OPERATION;
|
||||
|
||||
|
||||
/* Structure returned by rthwifGetAccelSize that contains acceleration
|
||||
* structure size estimates. */
|
||||
typedef struct RTHWIF_ACCEL_SIZE
|
||||
{
|
||||
/* The size of this structure in bytes. */
|
||||
size_t structBytes;
|
||||
|
||||
/* The expected number of bytes required for the acceleration
|
||||
* structure. When using an acceleration structure buffer of that
|
||||
* size, the build is expected to succeed mostly, but it may fail
|
||||
* with RTHWIF_ERROR_RETRY. */
|
||||
size_t accelBufferExpectedBytes;
|
||||
|
||||
/* The worst number of bytes required for the acceleration
|
||||
* structure. When using an acceleration structure buffer of that
|
||||
* size, the build is guaranteed to not run out of memory. */
|
||||
size_t accelBufferWorstCaseBytes;
|
||||
|
||||
/* The scratch buffer bytes required for the acceleration structure
|
||||
* build. */
|
||||
size_t scratchBufferBytes;
|
||||
|
||||
} RTHWIF_ACCEL_SIZE;
|
||||
|
||||
|
||||
/* Argument structure passed to rthwifBuildAccel function. */
|
||||
typedef struct RTHWIF_BUILD_ACCEL_ARGS
|
||||
{
|
||||
/* The size of this structure in bytes */
|
||||
size_t structBytes;
|
||||
|
||||
/* Array of pointers to geometry descriptors. This array and the
|
||||
* geometry descriptors themselves can be standard host memory
|
||||
* allocations. A pointer to a geometry descriptor can be null, in
|
||||
* which case the geometry is treated as empty. */
|
||||
const RTHWIF_GEOMETRY_DESC** geometries;
|
||||
|
||||
/* Number of geometries in geometry descriptor array. */
|
||||
uint32_t numGeometries;
|
||||
|
||||
/* Destination buffer for acceleration structure. This has to be a
|
||||
* shared memory allocation aligned to
|
||||
* RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT bytes and using the ray
|
||||
* tracing allocation descriptor
|
||||
* (ze_raytracing_mem_alloc_ext_desc_t) in the zeMemAllocShared
|
||||
* call. */
|
||||
void* accelBuffer;
|
||||
|
||||
/* Number of allocated bytes of the acceleration structure
|
||||
* buffer. This can be 0 in which case the build implementation may
|
||||
* just return an improved accel buffer expected size estimate by
|
||||
* looking at the scene data. */
|
||||
size_t accelBufferBytes;
|
||||
|
||||
/* Scratch space buffer to be used during accleration structure
|
||||
* construction. Can be a standard host allocation. */
|
||||
void* scratchBuffer;
|
||||
|
||||
/* Number of allocated bytes of the scratch space buffer. */
|
||||
size_t scratchBufferBytes;
|
||||
|
||||
/* Build quality to use (see RTHWIF_BUILD_QUALITY) */
|
||||
RTHWIF_BUILD_QUALITY quality;
|
||||
|
||||
/* Some hints for acceleration structure build (see RTHWIF_BUILD_FLAGS) */
|
||||
RTHWIF_BUILD_FLAGS flags;
|
||||
|
||||
/* When parallelOperation is NULL, the build is executed
|
||||
* sequentially on the current thread. If a parallelOperation is
|
||||
* specified, then the parallel operation gets attached to the
|
||||
* parallel build handle. This handle can then get joined with
|
||||
* worker threads to perform the parallel build operation. Only a
|
||||
* single build operation can be attached to a parallel build
|
||||
* operation at a given time. */
|
||||
RTHWIF_PARALLEL_OPERATION parallelOperation;
|
||||
|
||||
/* A pointer passed to callbacks. */
|
||||
void* buildUserPtr;
|
||||
|
||||
/* When the pointer is NULL no data is returned. When the build
|
||||
* fails with RTHWIF_ERROR_RETRY, this returns new expected
|
||||
* acceleration structure bytes to be used for re-build. When build
|
||||
* succeeds this returns the number of bytes used in the
|
||||
* acceleration structure buffer. */
|
||||
size_t* accelBufferBytesOut;
|
||||
|
||||
/* Destination address to write acceleration structure bounds to (can be NULL). */
|
||||
RTHWIF_AABB* boundsOut;
|
||||
|
||||
/* for debugging purposes use only */
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
void* dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
} RTHWIF_BUILD_ACCEL_ARGS;
|
||||
|
||||
/*
|
||||
* Initializes the library.
|
||||
*/
|
||||
|
||||
RTHWIF_API void rthwifInit();
|
||||
|
||||
/*
|
||||
* Cleans up the library.
|
||||
*/
|
||||
|
||||
RTHWIF_API void rthwifExit();
|
||||
|
||||
/*
|
||||
* Returns features supported by the implementation.
|
||||
*/
|
||||
|
||||
RTHWIF_API RTHWIF_FEATURES rthwifGetSupportedFeatures(ze_device_handle_t hDevice);
|
||||
|
||||
/*
|
||||
* The rthwifGetAccelSize function calculates the size of buffers
|
||||
* required for the acceleration structure build.
|
||||
|
||||
args: Specifies the build operation to estimate the buffer sizes
|
||||
for. The rthwifGetAccelSize function may look at the number
|
||||
of geometries, the geometry descriptors (but not referenced
|
||||
data), the existence of an acceleration structure to link,
|
||||
the build quality, and build flags.
|
||||
|
||||
sizeOut: A structure that contains the size information returned,
|
||||
see RTHWIF_ACCEL_SIZE for more details.
|
||||
|
||||
*/
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifGetAccelSize(const RTHWIF_BUILD_ACCEL_ARGS& args, RTHWIF_ACCEL_SIZE& sizeOut);
|
||||
|
||||
|
||||
/*
|
||||
* The rthwifBuildAccel function builds an acceleration structure of
|
||||
* the scene consisting of the specified geometry descriptors and
|
||||
* writes the acceleration structure to the provided destination
|
||||
* buffer. The build happens on the CPU and is synchronous, thus after
|
||||
* the function returns the acceleration structure can get used.
|
||||
*
|
||||
* It is the users responsibility to manage the acceleration structure
|
||||
* buffer allocation, deallocation, and potential prefetching to the
|
||||
* device memory. The required size of the accleration structure
|
||||
* buffer can be queried with the rthwifGetAccelSize function. The
|
||||
* acceleration structure buffer must be a shared USM allocation and
|
||||
* should be present on the host at build time. The referenced scene
|
||||
* data (index and vertex buffers) can be standard host allocations,
|
||||
* and will not be referenced into by the build acceleration
|
||||
* structure.
|
||||
*
|
||||
* Before an accleration structure is build, the user has to query the
|
||||
* size of the acceleration structure and scratch space buffer to
|
||||
* allocate using the rthwifGetAccelSize. When using the worst case
|
||||
* size to allocate the acceleration structure buffer, then the
|
||||
* rthwifGetAccelSize function will never fail with an out of memory
|
||||
* error. When using the expected size for the acceleration structure
|
||||
* buffer, then the build may fail with RTHWIF_ERROR_RETRY and
|
||||
* should then get re-tried with a larger amount of data. Using the
|
||||
* AccelBufferBytesExpected pointer, the build itself returns an
|
||||
* improved size estimate which the user can use to re-try the build.
|
||||
*
|
||||
* The parallelization of the acceleration structure is abstracted,
|
||||
* such that the user can decide which tasking library to use,
|
||||
* e.g. Intel(R) oneAPI Threading Building Blocks. Therefore, the user
|
||||
* specifies a function pointer to the parallelFor implementation of
|
||||
* its tasking system. The parallelFor function pointer gets invoked
|
||||
* by the implementation using the parallel_for body to
|
||||
* parallelize. The tasking system has to support nested parallelism
|
||||
* (thus parallel_for can get invoked inside a parallel_for) and C++
|
||||
* exceptions have to get properly propagated to a parent task to be
|
||||
* potentially catched by the user.
|
||||
*/
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifBuildAccel(const RTHWIF_BUILD_ACCEL_ARGS& args);
|
||||
|
||||
/*
|
||||
* Creates a new parallel operation that can get attached to a build
|
||||
* operation. Only a single build operation can be attached to a
|
||||
* parallel operation at a given time.
|
||||
*/
|
||||
|
||||
RTHWIF_API RTHWIF_PARALLEL_OPERATION rthwifNewParallelOperation();
|
||||
|
||||
/*
|
||||
* Destroys a parallel operation.
|
||||
*/
|
||||
|
||||
RTHWIF_API void rthwifDeleteParallelOperation( RTHWIF_PARALLEL_OPERATION parallelOperation );
|
||||
|
||||
/*
|
||||
* Returns the maximal number of threads that can join the parallel operation.
|
||||
*/
|
||||
|
||||
RTHWIF_API uint32_t rthwifGetParallelOperationMaxConcurrency( RTHWIF_PARALLEL_OPERATION parallelOperation );
|
||||
|
||||
|
||||
/*
|
||||
* Called by worker threads to join a parallel build operation. When
|
||||
* the build finished, all worker threads return from this function
|
||||
* with the same error code for the build.
|
||||
*/
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifJoinParallelOperation( RTHWIF_PARALLEL_OPERATION parallelOperation );
|
||||
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
RTHWIF_API RTHWIF_ERROR rthwifGetAccelSizeGPU(const RTHWIF_BUILD_ACCEL_ARGS& args_i, RTHWIF_ACCEL_SIZE& size_o, void *sycl_queue, uint verbose_level=0);
|
||||
RTHWIF_API RTHWIF_ERROR rthwifBuildAccelGPU(const RTHWIF_BUILD_ACCEL_ARGS& args, void *sycl_queue, uint verbose_level=0);
|
||||
RTHWIF_API RTHWIF_ERROR rthwifPrefetchAccelGPU(const RTHWIF_BUILD_ACCEL_ARGS& args, void *sycl_queue, uint verbose_level=0);
|
||||
#endif
|
||||
@@ -1,970 +0,0 @@
|
||||
// Copyright 2009-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <level_zero/ze_api.h>
|
||||
|
||||
|
||||
/**
|
||||
\file
|
||||
|
||||
\brief This file contains a Level Zero API extension to build ray
|
||||
tracing acceleration structures to be used with an OpenCL ray
|
||||
tracing API extension.
|
||||
|
||||
|
||||
Ray Tracing Acceleration Structure Build API
|
||||
============================================
|
||||
|
||||
The L0 ray tracing acceleration structure build API provides
|
||||
functionality to build acceleration structures for 3D scenes on the
|
||||
host, which can get used for ray tracing on GPU devices.
|
||||
|
||||
It is the users responsibility to manage the acceleration structure
|
||||
buffer allocation and deallocation. The required size of the
|
||||
accleration structure buffer can be queried with the
|
||||
zeRaytracingGetAccelSizeExt function and the acceleration structure
|
||||
an get build on the host using the zeRaytracingBuildAccelExt
|
||||
function.
|
||||
|
||||
To build an acceleration structure one first has to setup a scene
|
||||
that consists of multiple geometry descriptors, such as
|
||||
ze_raytracing_geometry_triangles_ext_desc_t for triangle meshes,
|
||||
ze_raytracing_geometry_quads_ext_desc_t for quad meshes,
|
||||
ze_raytracing_geometry_aabbs_fptr_ext_desc_t for procedural
|
||||
primitives with attached axis aligned bounding box, and
|
||||
ze_raytracing_geometry_instance_ext_desc_t for instances of other
|
||||
acceleration structures.
|
||||
|
||||
The followign example creates an
|
||||
ze_raytracing_geometry_triangles_ext_desc_t descriptor to specify
|
||||
a triangle mesh with triangles indices and vertices stored
|
||||
inside two vectors:
|
||||
|
||||
ze_raytracing_geometry_triangles_ext_desc_t mesh;
|
||||
memset(&mesh,0,sizeof(mesh));
|
||||
mesh.geometryType = ZE_RAYTRACING_GEOMETRY_TYPE_EXT_TRIANGLES;
|
||||
mesh.geometryFlags = ZE_RAYTRACING_GEOMETRY_EXT_FLAG_OPAQUE;
|
||||
mesh.geometryMask = 0xFF;
|
||||
|
||||
mesh.triangleFormat = ZE_RAYTRACING_FORMAT_EXT_TRIANGLE_INDICES_UINT32;
|
||||
mesh.triangleCount = triangles.size();
|
||||
mesh.triangleStride = 12;
|
||||
mesh.triangleBuffer = triangles.data();
|
||||
|
||||
mesh.vertexFormat = ZE_RAYTRACING_FORMAT_EXT_FLOAT3;
|
||||
mesh.vertexCount = vertices.size();
|
||||
mesh.vertexStride = 12;
|
||||
mesh.vertexBuffer = vertices.data();
|
||||
|
||||
The specified geometry flag ZE_RAYTRACING_GEOMETRY_EXT_FLAG_OPAQUE
|
||||
enables a fast mode where traveral does not return to the caller of
|
||||
ray tracing for each hit. The proper data formats of the triangle
|
||||
and vertex buffer is specified, including the strides, and pointer
|
||||
to first elements in these buffers.
|
||||
|
||||
To refer to multiple of these geometries that make a scene, pointers to
|
||||
these descriptors can be put into an array as follows:
|
||||
|
||||
std::vector<ze_raytracing_geometry_ext_desc_t*> geometries;
|
||||
geometries.push_back((ze_raytracing_geometry_ext_desc_t*)&mesh);
|
||||
geometries.push_back((ze_raytracing_geometry_ext_desc_t*)&mesh1);
|
||||
...
|
||||
|
||||
This completes the definition of the geometry for the scene to
|
||||
construct the acceleration structure for. To initiate the BVH build
|
||||
one first fills the ze_raytracing_build_accel_ext_desc_t structure
|
||||
with all arguments required for the acceleration structure build as
|
||||
in the following example:
|
||||
|
||||
ze_raytracing_build_accel_ext_desc_t build_desc;
|
||||
memset(&build_desc,0,sizeof(build_desc));
|
||||
build_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_BUILD_ACCEL_EXT_DESC;
|
||||
build_desc.pNext = nullptr;
|
||||
build_desc.hDevice = hDevice;
|
||||
build_desc.geometries = geometries.data();
|
||||
build_desc.numGeometries = geometries.size();
|
||||
build_desc.quality = ZE_RAYTRACING_BUILD_QUALITY_EXT_MEDIUM;
|
||||
build_desc.flags = ZE_RAYTRACING_BUILD_EXT_FLAG_NONE;
|
||||
|
||||
Besides just passing a pointer to the geometries array this sets
|
||||
some default build flags for a medium quality acceleration
|
||||
structure. Next the application has to query the buffer sizes
|
||||
required for the acceleration strucuture and scratch memory required
|
||||
for the build like in this example:
|
||||
|
||||
ze_raytracing_accel_size_ext_properties_t accel_size;
|
||||
memset(&accel_size,0,sizeof(accel_size));
|
||||
accel_size.stype = ZE_STRUCTURE_TYPE_RAYTRACING_ACCEL_SIZE_EXT_PROPERTIES;
|
||||
accel_size.pNext = nullptr;
|
||||
|
||||
ze_result_t result = zeRaytracingGetAccelSizeExt( &build_desc, &accel_size );
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
This queries the buffer sizes for the build operation specified in
|
||||
the provided build descriptor. Note that the sizes are only correct
|
||||
for the provided build descriptor, thus if parameters such as the
|
||||
build quality get changed for the actual build, calculated sizes are
|
||||
invalid.
|
||||
|
||||
Now we allocate the scratch buffer:
|
||||
|
||||
void* scratchBuffer = malloc(accel_size.scratchBufferBytes);
|
||||
|
||||
and the acceleration structure buffer using the worst cast
|
||||
estimates:
|
||||
|
||||
ze_raytracing_mem_alloc_ext_desc_t rt_desc;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_RAYTRACING_EXT_PROPERTIES;
|
||||
rt_desc.pNext = nullptr;
|
||||
rt_desc.flags = 0;
|
||||
|
||||
ze_device_mem_alloc_desc_t device_desc;
|
||||
device_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
|
||||
device_desc.pNext = &rt_desc;
|
||||
device_desc.flags = ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_CACHED;
|
||||
device_desc.ordinal = 0;
|
||||
|
||||
ze_host_mem_alloc_desc_t host_desc;
|
||||
host_desc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC;
|
||||
host_desc.pNext = nullptr;
|
||||
host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED;
|
||||
|
||||
void* accelBuffer = nullptr;
|
||||
ze_result_t result = zeMemAllocShared(hContext,
|
||||
&device_desc, &host_desc,
|
||||
accel_size.accelBufferWorstCaseBytes,
|
||||
ZE_RAYTRACING_ACCELERATION_STRUCTURE_ALIGNMENT_EXT,
|
||||
hDevice,&accelBuffer);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
|
||||
When using worst case estimate for the acceleration structure
|
||||
buffer, the build of the acceleration structure is guaranteed not to
|
||||
run out of memory.
|
||||
|
||||
To initiate the build operation we need to additionally specify the
|
||||
just created buffers in the build descriptor:
|
||||
|
||||
build_desc.accelBuffer = accelBuffer;
|
||||
build_desc.accelBufferBytes = accel_size.accelBufferWorstCaseBytes;
|
||||
|
||||
build_desc.scratchBuffer = scratchBuffer;
|
||||
build_desc.scratchBufferBytes = accelsize.scratchBufferBytes;
|
||||
|
||||
|
||||
Now a single threaded build on the host CPU can get initiated using
|
||||
the zeRaytracingBuildAccelExt function:
|
||||
|
||||
ze_result_t result = zeRaytracingBuildAccelExt( &build_desc );
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
When the build completes successfully the acceleration structure
|
||||
buffer can get used as acceleration structure by the ray tracing
|
||||
API.
|
||||
|
||||
|
||||
Parallel Build
|
||||
--------------
|
||||
|
||||
In order to speed up the build operation with multiple worker
|
||||
thread, some parallel operation object can get attached to the build
|
||||
and joined with application provided worker threads as in the
|
||||
following example:
|
||||
|
||||
ze_raytracing_parallel_operation_ext_handle_t hParallelOperation;
|
||||
ze_result_t result = zeRaytracingParallelOperationCreateExt(&hParallelOperation);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
build_desc.parallelOperation = hParallelOperation;
|
||||
|
||||
result = zeRaytracingBuildAccelExt( &build_desc );
|
||||
assert(result == ZE_RESULT_RAYTRACING_EXT_OPERATION_DEFERRED);
|
||||
|
||||
uint32_t pMaxConcurrency = 0;
|
||||
result = zeRaytracingParallelOperationGetMaxConcurrencyExt( hParallelOperation, &MaxConcurrency );
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
tbb::parallel_for(0u,pMaxConcurrency,1u,[&](uint32_t i) {
|
||||
ze_result_t result = zeRaytracingParallelOperationJoinExt(hParallelOperation);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
});
|
||||
|
||||
result = zeRaytracingParallelOperationDestroyExt(hParallelOperation);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
|
||||
|
||||
Conservative Acceleration Buffer Size
|
||||
-------------------------------------
|
||||
|
||||
While using the conservative size estimate of the acceleration
|
||||
structure guarantees a successfull build, the memory requirements
|
||||
are larger than typically required. To reduce memory usage the
|
||||
application can also use the expected acceleration buffer size and
|
||||
re-try the build operation in case it ran out of memory. The
|
||||
following code illustrates this concept:
|
||||
|
||||
void* accelBuffer = nullptr;
|
||||
size_t accel_bytes = accel_size.accelBufferExpectedBytes;
|
||||
|
||||
while (true)
|
||||
{
|
||||
accelBuffer = allocate_accel_buffer(accel_bytes);
|
||||
|
||||
build_desc.accelBuffer = accelBuffer;
|
||||
build_desc.accelBufferBytes = accel_bytes;
|
||||
build_desc.accelBufferBytesOut = &accel_bytes;
|
||||
|
||||
ze_result_t result = zeRaytracingBuildAccelExt( &build_desc );
|
||||
if (result == ZE_RESULT_SUCCESS) break;
|
||||
|
||||
assert(result == ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL);
|
||||
// accel_bytes got increased to a larger estimate for a next try
|
||||
|
||||
free_accel_buffer(accelBuffer);
|
||||
}
|
||||
|
||||
The loop starts with the expected acceleration buffer size, for
|
||||
which the build will mostly succeed. If the build runs out of memory
|
||||
the ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL result is returned
|
||||
and the build can get re-tried with a larger acceleration structure
|
||||
buffer.
|
||||
|
||||
The example above passes a pointer to the accel_bytes variable as
|
||||
accelBufferBytesOut input to the build operation. This causes the
|
||||
builder to write a larger acceleration structure size estimate to be
|
||||
used in the next try into the accel_bytes variable. Alternatively,
|
||||
the application can also increase the acceleration buffer size for
|
||||
the next try by some percentage, or just use the worst case size for
|
||||
a second try.
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Additional ze_result_t enum fields.
|
||||
|
||||
*/
|
||||
typedef enum _ze_result_t
|
||||
{
|
||||
ZE_RESULT_SUCCESS, ///< operation was successfull
|
||||
ZE_RESULT_ERROR_UNKNOWN, ///< unknown error occurred
|
||||
|
||||
ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL, ///< acceleration structure build ran out of memory, app should re-try with more memory
|
||||
ZE_RESULT_RAYTRACING_EXT_OPERATION_DEFERRED, ///< operation is deferred to a parallel operation
|
||||
ZE_RESULT_RAYTRACING_EXT_ACCEL_INCOMPATIBLE, ///< the tested devices have incompatible acceleration structures
|
||||
|
||||
} ze_result_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Additional ze_structure_type_t enum fields.
|
||||
|
||||
*/
|
||||
|
||||
typedef enum _ze_structure_type_t
|
||||
{
|
||||
ZE_STRUCTURE_TYPE_RAYTRACING_ACCEL_SIZE_EXT_PROPERTIES, ///< ze_raytracing_accel_size_ext_properties_t
|
||||
ZE_STRUCTURE_TYPE_RAYTRACING_BUILD_ACCEL_EXT_DESC, ///< ze_raytracing_build_accel_ext_desc_t
|
||||
|
||||
} ze_structure_type_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief Feature bit for acceleration structure build API
|
||||
*/
|
||||
typedef enum _ze_device_raytracing_ext_flag_t {
|
||||
ZE_DEVICE_RAYTRACING_EXT_FLAG_ACCEL_BUILD, ///< support for ray tracing acceleration structure build API
|
||||
} ze_device_raytracing_ext_flag_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief A handle of a parallel operation that can get joined with worker threads.
|
||||
|
||||
A parallel operation object can get used to perform acceleration
|
||||
structure build operations in parallel on multiple hardware
|
||||
thread. Therefore, a parallel build operation attached to an
|
||||
acceleration strucutre build can get joined by application manged
|
||||
threads to assist in building the acceleration structure.
|
||||
|
||||
*/
|
||||
typedef _ze_raytracing_parallel_operation_ext_handle_t* ze_raytracing_parallel_operation_ext_handle_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Create new parallel operation
|
||||
|
||||
Creates a new parallel operation that can get attached to a build
|
||||
operation. Only a single build operation can be attached to a
|
||||
parallel operation at a given time.
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL zeRaytracingParallelOperationCreateExt( ze_raytracing_parallel_operation_ext_handle_t* phParallelOperation );
|
||||
|
||||
|
||||
/**
|
||||
\brief Destroy parallel operation.
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result ZE_APICALL zeRaytracingParallelOperationDestroyExt( ze_raytracing_parallel_operation_ext_handle_t hParallelOperation );
|
||||
|
||||
|
||||
/**
|
||||
\brief Returns the maximal number of threads that can join the parallel operation.
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result ZE_APICALL zeRaytracingParallelOperationGetMaxConcurrencyExt( ze_raytracing_parallel_operation_ext_handle_t hParallelOperation, uint32_t* pMaxConcurrency );
|
||||
|
||||
|
||||
/**
|
||||
\brief Join parallel operation
|
||||
|
||||
Called by worker threads to join a parallel build operation. When
|
||||
the build finished, all worker threads return from this function
|
||||
with the same error code of the build.
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL zeRaytracingParallelOperationJoinExt( ze_raytracing_parallel_operation_ext_handle_t hParallelOperation );
|
||||
|
||||
|
||||
|
||||
/** Required alignment of acceleration structure buffer. */
|
||||
#define ZE_RAYTRACING_ACCELERATION_STRUCTURE_ALIGNMENT_EXT 128
|
||||
|
||||
|
||||
/**
|
||||
\brief Enumeration of geometry flags supported by the geometries.
|
||||
*/
|
||||
typedef uint8_t ze_raytracing_geometry_ext_flags_t;
|
||||
typedef enum _ze_raytracing_geometry_ext_flag_t : uint8_t
|
||||
{
|
||||
ZE_RAYTRACING_GEOMETRY_EXT_FLAG_NONE = 0, ///< Default geometry flags
|
||||
ZE_RAYTRACING_GEOMETRY_EXT_FLAG_OPAQUE = 1, ///< Opaque geometries do not invoke an anyhit shader
|
||||
} ze_raytracing_geometry_ext_flag_t;
|
||||
|
||||
/**
|
||||
|
||||
|
||||
\brief Format of elements in data buffers.
|
||||
|
||||
The format is used to specify the format of elements of data buffer,
|
||||
such as the format of transformation used for instancing, or index
|
||||
format for triangles and quads.
|
||||
|
||||
*/
|
||||
typedef enum _ze_raytracing_format_ext_t : uint8_t
|
||||
{
|
||||
ZE_RAYTRACING_FORMAT_EXT_FLOAT3, ///< 3 component float vector (see ze_raytracing_float3_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_FLOAT3X4_COLUMN_MAJOR, ///< 3x4 affine transformation in column major format (see ze_raytracing_transform_float3x4_column_major_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_FLOAT3X4_ALIGNED_COLUMN_MAJOR, ///< 3x4 affine transformation in column major format (see ze_raytracing_transform_float3x4_aligned_column_major_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_FLOAT3X4_ROW_MAJOR, ///< 3x4 affine transformation in row major format (see ze_raytracing_transform_float3x4_row_major_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_AABB, ///< 3 dimensional axis aligned bounding box (see ze_raytracing_aabb_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_TRIANGLE_INDICES_UINT32, ///< triangle indices of uint32 type (see ze_raytracing_triangle_indices_uint32_ext_t layout)
|
||||
ZE_RAYTRACING_FORMAT_EXT_QUAD_INDICES_UINT32, ///< quad indices of uint32 type (see ze_raytracing_quad_indices_uint32_ext_t layout)
|
||||
} ze_raytracing_format_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief A 3-component short vector type.
|
||||
*/
|
||||
typedef struct _ze_raytracing_float3_ext_t {
|
||||
float x; ///< x coordinate of float3 vector
|
||||
float y; ///< y coordinate of float3 vector
|
||||
float z; ///< z coordinate of float3 vector
|
||||
} ze_raytracing_float3_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief 3x4 affine transformation in column major layout
|
||||
|
||||
A 3x4 affine transformation in column major layout, consisting of
|
||||
vectors vx=(vx_x,vx_y,vx_z), vy=(vy_x,vy_y,vy_z),
|
||||
vz=(vz_x,vz_y,vz_z), and p=(p_x,p_y,p_z). The transformation
|
||||
transforms a point (x,y,z) to x*vx + y*vy + z*vz + * p.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_transform_float3x4_column_major_ext_t {
|
||||
float vx_x, vx_y, vx_z; ///< column 0 of 3x4 matrix
|
||||
float vy_x, vy_y, vy_z; ///< column 1 of 3x4 matrix
|
||||
float vz_x, vz_y, vz_z; ///< column 2 of 3x4 matrix
|
||||
float p_x, p_y, p_z; ///< column 3 of 3x4 matrix
|
||||
} ze_raytracing_transform_float3x4_column_major_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief 3x4 affine transformation in column major layout with aligned column vectors
|
||||
|
||||
A 3x4 affine transformation in column major layout, consisting of
|
||||
vectors vx=(vx_x,vx_y,vx_z), vy=(vy_x,vy_y,vy_z),
|
||||
vz=(vz_x,vz_y,vz_z), and p=(p_x,p_y,p_z). The transformation
|
||||
transforms a point (x,y,z) to x*vx + y*vy + z*vz + p. The column
|
||||
vectors are aligned to 16 bytes and pad members are ignored.
|
||||
*/
|
||||
typedef struct _ze_raytracing_transform_float3x4_aligned_column_major_ext_t
|
||||
{
|
||||
float vx_x, vx_y, vx_z, pad0; ///< column 0 of 3x4 matrix with ignored padding
|
||||
float vy_x, vy_y, vy_z, pad1; ///< column 1 of 3x4 matrix with ignored padding
|
||||
float vz_x, vz_y, vz_z, pad2; ///< column 2 of 3x4 matrix with ignored padding
|
||||
float p_x, p_y, p_z, pad3; ///< column 3 of 3x4 matrix with ignored padding
|
||||
} ze_raytracing_transform_float3x4_aligned_column_major_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief 3x4 affine transformation in row major layout
|
||||
|
||||
A 3x4 affine transformation in row major layout, consisting of
|
||||
vectors vx=(vx_x,vx_y,vx_z), vy=(vy_x,vy_y,vy_z),
|
||||
vz=(vz_x,vz_y,vz_z), and p=(p_x,p_y,p_z). The transformation
|
||||
transforms a point (x,y,z) to x*vx + y*vy + z*vz + p.
|
||||
*/
|
||||
typedef struct _ze_raytracing_transform_float3x4_row_major_ext_t
|
||||
{
|
||||
float vx_x, vy_x, vz_x, p_x; ///< row 0 of 3x4 matrix
|
||||
float vx_y, vy_y, vz_y, p_y; ///< row 1 of 3x4 matrix
|
||||
float vx_z, vy_z, vz_z, p_z; ///< row 2 of 3x4 matrix
|
||||
} ze_raytracing_transform_float3x4_row_major_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Axis aligned 3-dimensional bounding box (AABB) with lower and
|
||||
upper bounds in each dimension.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_aabb_ext_t
|
||||
{
|
||||
ze_raytracing_float3_ext_t lower; ///< lower bounds of AABB
|
||||
ze_raytracing_float3_ext_t upper; ///< upper bounds of AABB
|
||||
} ze_raytracing_aabb_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Triangle represented using 3 vertex indices
|
||||
|
||||
This strucure represents a triangle using 3 vertex indices that
|
||||
index into a vertex array that needs to be provided together with
|
||||
the index array.
|
||||
|
||||
The linear barycentric u/v parametrization of the triangle is
|
||||
defined to be (u=0, v=0) at v0, (u=1, v=0) at v1, and (u=0, v=1) at
|
||||
v2.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_triangle_indices_uint32_ext_t
|
||||
{
|
||||
uint32_t v0; ///< first index pointing to the first triangle vertex in vertex array
|
||||
uint32_t v1; ///< second index pointing to the second triangle vertex in vertex array
|
||||
uint32_t v2; ///< third index pointing to the third triangle vertex in vertex array
|
||||
} ze_raytracing_triangle_indices_uint32_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Quad represented using 4 vertex indices
|
||||
|
||||
Represents a quad composed of 4 indices that index into a vertex
|
||||
array that needs to be provided together with the index array.
|
||||
|
||||
A quad is a triangle pair represented using 4 vertex indices
|
||||
v0,v1,v2,v3. The first triangle is made out of indices v0,v1,v3 and
|
||||
the second triangle from indices v2,v3,v1. The piecewise linear
|
||||
barycentric u/v pametrization of the quad is defined to be (u=0,
|
||||
v=0) at v0, (u=1, v=0) at v1, (u=0, v=1) at v3, and (u=1, v=1) at
|
||||
v2. This is achieved by correcting the u'/v' coordinates of the
|
||||
second triangle by u = 1-u' and v = 1-v', yielding a piecewise
|
||||
linear parametrization.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_quad_indices_uint32_ext_t
|
||||
{
|
||||
uint32_t v0; ///< first index pointing to the first quad vertex in vertex array
|
||||
uint32_t v1; ///< second index pointing to the second quad vertex in vertex array
|
||||
uint32_t v2; ///< third index pointing to the third quad vertex in vertex array
|
||||
uint32_t v3; ///< forth index pointing to the forth quad vertex in vertex array
|
||||
} ze_raytracing_quad_indices_uint32_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief The types of geometries supported.
|
||||
|
||||
A type that identifies the various geometry descriptors supported by
|
||||
the API. Each geometry descriptor has this type stored as it first
|
||||
member at offset 0 to identify the type of the descriptor.
|
||||
|
||||
*/
|
||||
typedef enum _ze_raytracing_geometry_type_ext_t : uint8_t
|
||||
{
|
||||
ZE_RAYTRACING_GEOMETRY_TYPE_EXT_TRIANGLES = 0, ///< triangle mesh geometry type identifying ze_raytracing_geometry_triangles_ext_desc_t
|
||||
ZE_RAYTRACING_GEOMETRY_TYPE_EXT_QUADS = 1, ///< quad mesh geometry type identifying ze_raytracing_geometry_quads_ext_desc_t
|
||||
ZE_RAYTRACING_GEOMETRY_TYPE_EXT_AABBS_FPTR = 2, ///< procedural geometry type identifying ze_raytracing_geometry_aabbs_fptr_ext_desc_t
|
||||
ZE_RAYTRACING_GEOMETRY_TYPE_EXT_INSTANCE = 3, ///< instance geometry type identifying ze_raytracing_geometry_instance_ext_desc_t
|
||||
} ze_raytracing_geometry_type_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Instance flags supported
|
||||
|
||||
This enumation lists flags to be used to specify instances.
|
||||
|
||||
*/
|
||||
typedef uint8_t ze_raytracing_instance_ext_flags_t;
|
||||
typedef enum _ze_raytracing_instance_ext_flag_t : uint8_t
|
||||
{
|
||||
ZE_RAYTRACING_INSTANCE_EXT_FLAG_NONE = 0, ///< default instance flag
|
||||
ZE_RAYTRACING_INSTANCE_EXT_FLAG_TRIANGLE_CULL_DISABLE = 0x1, ///< disables culling of front and backfacing triangles
|
||||
ZE_RAYTRACING_INSTANCE_EXT_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2, ///< reverses front and back face of triangles
|
||||
ZE_RAYTRACING_INSTANCE_EXT_FLAG_FORCE_OPAQUE = 0x4, ///< forces instanced geometry to be opaque, unless ray flag forces it to be non-opaque
|
||||
ZE_RAYTRACING_INSTANCE_EXT_FLAG_FORCE_NON_OPAQUE = 0x8 ///< forces instanced geometry to be non-opaque, unless ray flag forces it to be opaque
|
||||
} ze_raytracing_instance_ext_flag_ext_t;
|
||||
|
||||
/**
|
||||
|
||||
\brief Base structure for all geometry descriptors.
|
||||
|
||||
Each geometry descriptor has a geometry type as it's first argument
|
||||
that identifies which geometry is represented. See
|
||||
ze_raytracing_geometry_type_ext_t for details.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_geometry_ext_desc_t {
|
||||
ze_raytracing_geometry_type_ext_t geometryType; ///< type of geometry descriptor
|
||||
} ze_raytracing_geometry_ext_desc_t;
|
||||
|
||||
/**
|
||||
|
||||
\brief Geometry descriptor of a triangle mesh
|
||||
|
||||
This geometry descriptor describes a triangle mesh consisting of an
|
||||
triangle buffer (index buffer), and a vertex buffer.
|
||||
|
||||
The linear barycentric u/v parametrization of the triangle is
|
||||
defined to be (u=0, v=0) at v0, (u=1, v=0) at v1, and (u=0, v=1) at
|
||||
v2.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_geometry_triangles_ext_desc_t // 40 bytes
|
||||
{
|
||||
ze_raytracing_geometry_type_ext_t geometryType; ///< must be ZE_RAYTRACING_GEOMETRY_TYPE_EXT_TRIANGLES
|
||||
ze_raytracing_geometry_ext_flags_t geometryFlags; ///< geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; ///< 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; ///< must be zero
|
||||
uint8_t reserved1; ///< must be zero
|
||||
uint8_t reserved2; ///< must be zero
|
||||
ze_raytracing_format_ext_t triangleFormat; ///< format of triangleBuffer (must be ZE_RAYTRACING_FORMAT_EXT_TRIANGLE_INDICES_UINT32)
|
||||
ze_raytracing_format_ext_t vertexFormat; ///< format of vertexBuffer (must be ZE_RAYTRACING_FORMAT_EXT_FLOAT3)
|
||||
unsigned int triangleCount; ///< number of triangles in triangleBuffer
|
||||
unsigned int vertexCount; ///< number of vertices in vertexBuffer
|
||||
unsigned int triangleStride; ///< stride in bytes of triangles in triangleBuffer
|
||||
unsigned int vertexStride; ///< stride in bytes of vertices in vertexBuffer
|
||||
void* triangleBuffer; ///< pointer to array of triangle indices in specified format
|
||||
void* vertexBuffer; ///< pointer to array of triangle vertices in specified format
|
||||
|
||||
} ze_raytracing_geometry_triangles_ext_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Geometry descriptor of a quad mesh
|
||||
|
||||
This geometry descriptor describes a quad mesh consisting of a quad
|
||||
buffer (index buffer), and vertex buffer. The indices index
|
||||
respective vertices in the vertex array.
|
||||
|
||||
A quad is a triangle pair represented using 4 vertex indices
|
||||
v0,v1,v2,v3. The first triangle is made out of indices v0,v1,v3 and
|
||||
the second triangle from indices v2,v3,v1. The piecewise linear
|
||||
barycentric u/v pametrization of the quad is defined to be (u=0,
|
||||
v=0) at v0, (u=1, v=0) at v1, (u=0, v=1) at v3, and (u=1, v=1) at
|
||||
v2. This is achieved by correcting the u'/v' coordinates of the
|
||||
second triangle by u = 1-u' and v = 1-v', yielding a piecewise
|
||||
linear parametrization.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_geometry_quads_ext_desc_t // 40 bytes
|
||||
{
|
||||
ze_raytracing_geometry_type_ext_t geometryType; ///< must be ZE_RAYTRACING_GEOMETRY_TYPE_EXT_QUADS
|
||||
ze_raytracing_geometry_ext_flags_t geometryFlags; ///< geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; ///< 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; ///< must be zero
|
||||
uint8_t reserved1; ///< must be zero
|
||||
uint8_t reserved2; ///< must be zero
|
||||
ze_raytracing_format_ext_t quadFormat; ///< format of quadBuffer (must be ZE_RAYTRACING_FORMAT_EXT_QUAD_INDICES_UINT32)
|
||||
ze_raytracing_format_ext_t vertexFormat; ///< format of vertexBuffer (must be ZE_RAYTRACING_FORMAT_EXT_FLOAT3)
|
||||
unsigned int quadCount; ///< number of quads in quadBuffer
|
||||
unsigned int vertexCount; ///< number of vertices in vertexBuffer
|
||||
unsigned int quadStride; ///< stride in bytes of quads in quadBuffer
|
||||
unsigned int vertexStride; ///< stride in bytes of vertices in vertexBuffer
|
||||
void* quadBuffer; ///< pointer to an array of quad indices in specified format
|
||||
void* vertexBuffer; ///< pointer to an array of quad vertices in specified format
|
||||
|
||||
} ze_raytracing_geometry_quads_ext_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief Function pointer type to return AABBs for a range of procedural primitives.
|
||||
*/
|
||||
typedef void (*ze_raytracing_geometry_aabbs_fptr_ext_t)(const uint32_t primID, ///< [in] first primitive to return bounds for
|
||||
const uint32_t primIDCount, ///< [in] number of primitives to return bounds for
|
||||
void* geomUserPtr, ///< [in] pointer provided through geometry descriptor
|
||||
void* buildUserPtr, ///< [in] pointer provided through zeRaytracingBuildAccelExt function
|
||||
ze_raytracing_aabb_ext_t* pBoundsOut ///< [out] destination buffer to write AABB bounds to
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
\brief Geometry descriptor of procedural primitives
|
||||
|
||||
Geometry with procedural primitives bound by AABBs. A host side
|
||||
bounds function is provided that is invoked by the acceleration
|
||||
structure builder to query bounds of procedural primitives on
|
||||
demand. The callback is passed some geomUserPtr provided with the
|
||||
geometry that can point to an application side representation of the
|
||||
procedural primitives. Futher, a second buildUserPtr pointer is
|
||||
passed to the callback, that can get set through the
|
||||
zeRaytracingBuildAccel function. This allows the build to change the
|
||||
bounds of the procedural geometry, e.g. to build a BVH only over a
|
||||
short time range to implement multi-segment motion blur.
|
||||
|
||||
*/
|
||||
typedef struct _ze_raytracing_geometry_aabbs_fptr_ext_desc_t // 24 bytes
|
||||
{
|
||||
ze_raytracing_geometry_type_ext_t geometryType; ///< must be ZE_RAYTRACING_GEOMETRY_TYPE_EXT_AABBS_FPTR
|
||||
ze_raytracing_geometry_ext_flags_t geometryFlags; ///< geometry flags for all primitives of this geometry
|
||||
uint8_t geometryMask; ///< 8-bit geometry mask for ray masking
|
||||
uint8_t reserved; ///< must be zero
|
||||
unsigned int primCount; ///< number of primitives in geometry
|
||||
ze_raytracing_geometry_aabbs_fptr_ext_t getBounds; ///< function pointer to return bounds for a range of primitives
|
||||
void* geomUserPtr; ///< geometry user pointer passed to callback
|
||||
|
||||
} ze_raytracing_geometry_aabbs_fptr_ext_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Geometry descriptor of an instance
|
||||
|
||||
Instance geometry descriptor which contains a pointer to an
|
||||
acceleration structure to instantiate, a pointer to the object to
|
||||
world transformation used for instancing, and a pointer to the
|
||||
object space bounding box of the instantiated acceleration
|
||||
structure.
|
||||
*/
|
||||
typedef struct _ze_raytracing_geometry_instance_ext_desc_t // 32 bytes
|
||||
{
|
||||
ze_raytracing_geometry_type_ext_t geometryType; ///< must be ZE_RAYTRACING_GEOMETRY_TYPE_EXT_INSTANCE
|
||||
ze_raytracing_instance_ext_flags_t instanceFlags; ///< flags for the instance (see ze_raytracing_instance_ext_flags_t)
|
||||
uint8_t geometryMask; ///< 8-bit geometry mask for ray masking
|
||||
ze_raytracing_format_ext_t transformFormat; ///< format of the specified transformation
|
||||
unsigned int instanceUserID; ///< a user specified identifier for the instance
|
||||
void* transform; ///< object to world instance transformation in specified format
|
||||
ze_raytracing_aabb_ext_t* bounds; ///< AABB of the instanced acceleration structure
|
||||
void* accel; ///< pointer to acceleration structure to instantiate
|
||||
|
||||
} ze_raytracing_geometry_instance_ext_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Build quality hint for acceleration structure build.
|
||||
|
||||
Depending on use case different quality modes for acceleration structure build are supported.
|
||||
|
||||
A low quality build builds an accelertion structure fast, but at
|
||||
some reduction in ray tracing performance. This mode is recommended
|
||||
for dynamic content, such as animated characters.
|
||||
|
||||
A medium quality build uses a compromise between build quality and
|
||||
ray tracing performance. This mode should be used by default.
|
||||
|
||||
Higher ray tracing performance can get achieved by using a high
|
||||
quality build, but acceleration structure build performance might
|
||||
be significantly reduced.
|
||||
|
||||
*/
|
||||
typedef enum _ze_raytracing_build_quality_ext_t
|
||||
{
|
||||
ZE_RAYTRACING_BUILD_QUALITY_EXT_LOW = 0, ///< build low quality acceleration structure (fast)
|
||||
ZE_RAYTRACING_BUILD_QUALITY_EXT_MEDIUM = 1, ///< build medium quality acceleration structure (slower)
|
||||
ZE_RAYTRACING_BUILD_QUALITY_EXT_HIGH = 2, ///< build high quality acceleration structure (slow)
|
||||
|
||||
} ze_raytracing_build_quality_ext_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Flags for acceleration structure build.
|
||||
|
||||
These flags allow the application to tune the accelertion structure
|
||||
build.
|
||||
|
||||
Using the ZE_RAYTRACING_BUILD_EXT_FLAG_COMPACT flag causes the
|
||||
acceleration strucuture to create more compact acceleration
|
||||
structures.
|
||||
|
||||
The acceleration structure build implementation might choose to use
|
||||
spatial splitting to split large or long primitives into smaller
|
||||
pieces. This results in any-hit shaders being invoked multiple
|
||||
times for non-opaque primitives. If the application requires only a
|
||||
single any-hit shader invokation per primitive, the
|
||||
ZE_RAYTRACING_BUILD_EXT_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION build flag
|
||||
should get used.
|
||||
|
||||
Usage of any of these flags may reduce ray tracing performance.
|
||||
|
||||
*/
|
||||
typedef uint32_t ze_raytracing_build_ext_flags_t;
|
||||
typedef enum _ze_raytracing_build_ext_flag_t
|
||||
{
|
||||
ZE_RAYTRACING_BUILD_EXT_FLAG_NONE = 0, ///< default build flags
|
||||
ZE_RAYTRACING_BUILD_EXT_FLAG_COMPACT = (1 << 0), ///< build more compact acceleration structure
|
||||
ZE_RAYTRACING_BUILD_EXT_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = (1 << 1), ///< guarantees single any hit shader invokation per primitive
|
||||
|
||||
} ze_raytracing_build_ext_flag_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Returns information about acceleration structure size estimates
|
||||
|
||||
This structure is returned by zeRaytracingGetAccelSizeExt and
|
||||
contains acceleration structure size estimates.
|
||||
*/
|
||||
typedef struct _ze_raytracing_accel_size_ext_properties_t
|
||||
{
|
||||
/** [in] type of this structure */
|
||||
ze_structure_type_t stype;
|
||||
|
||||
/** [in,out][optional] must be null or a pointer to an extension-specific structure */
|
||||
void* pNext;
|
||||
|
||||
/**
|
||||
[out] The expected number of bytes required for the acceleration
|
||||
structure. When using an acceleration structure buffer of that
|
||||
size, the build is expected to succeed mostly, but it may fail
|
||||
with ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL.
|
||||
*/
|
||||
size_t accelBufferExpectedBytes;
|
||||
|
||||
/**
|
||||
[out] The worst case number of bytes required for the acceleration
|
||||
structure. When using an acceleration structure buffer of that
|
||||
size, the build is guaranteed to not run out of memory.
|
||||
*/
|
||||
size_t accelBufferWorstCaseBytes;
|
||||
|
||||
/**
|
||||
[out] The scratch buffer bytes required for the acceleration
|
||||
structure build.
|
||||
*/
|
||||
size_t scratchBufferBytes;
|
||||
|
||||
} ze_raytracing_accel_size_ext_properties_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief Argument structure passed to zeRaytracingBuildAccelExt function.
|
||||
*/
|
||||
typedef struct _ze_raytracing_build_accel_ext_desc_t
|
||||
{
|
||||
/** [in] type of this structure */
|
||||
ze_structure_type_t stype;
|
||||
|
||||
/** [in,out][optional] must be null or a pointer to an extension-specific structure */
|
||||
void* pNext;
|
||||
|
||||
/** [in] The device to build the acceleration structure for. The
|
||||
* acceleration structure can also get used on other devices whose
|
||||
* acceleration structure is compatible with the device specified
|
||||
* here (see zeRaytracingAccelCompatibilityExt function). */
|
||||
ze_device_handle_t hDevice;
|
||||
|
||||
/**
|
||||
[in] Array of pointers to geometry descriptors. This array and
|
||||
the geometry descriptors themselves have to be standard host
|
||||
memory allocations. A pointer to a geometry descriptor can be
|
||||
NULL, in which case the geometry is treated as empty.
|
||||
*/
|
||||
const ze_raytracing_geometry_ext_desc_t** geometries;
|
||||
|
||||
/**
|
||||
[in] Number of geometries in geometry descriptor array.
|
||||
*/
|
||||
uint32_t numGeometries;
|
||||
|
||||
/**
|
||||
[out] Destination buffer for acceleration structure. This has to
|
||||
be a shared memory allocation aligned to
|
||||
ZE_RAYTRACING_ACCELERATION_STRUCTURE_ALIGNMENT bytes and using
|
||||
the ray tracing allocation descriptor
|
||||
ze_raytracing_mem_alloc_ext_desc_t in the zeMemAllocShared
|
||||
call.
|
||||
*/
|
||||
void* accelBuffer;
|
||||
|
||||
/**
|
||||
[in] Number of allocated bytes of the acceleration structure
|
||||
buffer. This can be 0 in which case the build implementation may
|
||||
just return an improved accel buffer expected size estimate by
|
||||
looking at the scene data.
|
||||
*/
|
||||
size_t accelBufferBytes;
|
||||
|
||||
/**
|
||||
[scratch] Scratch space buffer to be used during accleration structure
|
||||
construction. This buffer has to be a standard host memory allocation.
|
||||
*/
|
||||
void* scratchBuffer;
|
||||
|
||||
/**
|
||||
[in] Number of allocated bytes of the scratch space buffer.
|
||||
*/
|
||||
size_t scratchBufferBytes;
|
||||
|
||||
/**
|
||||
[in] Build quality to use (see ze_raytracing_build_quality_ext_t)
|
||||
*/
|
||||
ze_raytracing_build_quality_ext_t quality;
|
||||
|
||||
/**
|
||||
[in] Some build flags for acceleration structure build (see ze_raytracing_build_ext_flags_t)
|
||||
*/
|
||||
ze_raytracing_build_ext_flags_t flags;
|
||||
|
||||
/**
|
||||
[in][optional] When parallelOperation is NULL, the build is
|
||||
executed sequentially on the current thread. If a
|
||||
parallelOperation is specified, then the parallel operation gets
|
||||
attached to the parallel build handle. This handle can then get
|
||||
joined with worker threads to perform the parallel build
|
||||
operation. Only a single build operation can be attached to a
|
||||
parallel build operation at a given time.
|
||||
*/
|
||||
ze_raytracing_parallel_operation_ext_handle_t parallelOperation;
|
||||
|
||||
/**
|
||||
[in,optional] A pointer passed to callbacks.
|
||||
*/
|
||||
void* buildUserPtr;
|
||||
|
||||
/**
|
||||
[out][optional] When the pointer is NULL no data is
|
||||
returned. When the build fails with
|
||||
ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL, this returns the new
|
||||
expected acceleration structure bytes to be used for
|
||||
re-build. When the build succeeds this returns the number of
|
||||
bytes actually used in the acceleration structure buffer.
|
||||
*/
|
||||
size_t* accelBufferBytesOut;
|
||||
|
||||
/**
|
||||
[out][optional] Destination address to write acceleration
|
||||
structure bounds to. When set to NULL no data is returned.
|
||||
*/
|
||||
ze_raytracing_aabb_ext_t* boundsOut;
|
||||
|
||||
} ze_raytracing_build_accel_ext_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Calculates size of buffers required for acceleration structure build.
|
||||
|
||||
The zeRaytracingGetAccelSize function calculates the size of buffers
|
||||
required for the acceleration structure build. The function may look
|
||||
at the number of geometries, the geometry descriptors (but not
|
||||
referenced data), the existence of an acceleration structure to
|
||||
link, the build quality, and build flags of the build operation.
|
||||
|
||||
\param args: Specifies the build operation to estimate the buffer sizes for.
|
||||
\param pAccelSizeOut: A structure that is filled with the returned size information.
|
||||
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL zeRaytracingGetAccelSizeExt( const ze_raytracing_build_accel_ext_desc_t* args, ze_raytracing_accel_size_ext_properties_t* pAccelSizeOut );
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Builds a ray tracing acceleration structure
|
||||
|
||||
The zeRaytracingBuildAccelExt function builds an acceleration
|
||||
structure of the scene consisting of the specified geometry
|
||||
descriptors and writes the acceleration structure to the provided
|
||||
destination buffer. All types of geometries can get freely mixed
|
||||
inside a scene. Please see ze_raytracing_build_accel_ext_desc_t for
|
||||
a description of all input arguments.
|
||||
|
||||
It is the users responsibility to manage the acceleration structure
|
||||
buffer allocation, deallocation, and potential prefetching to the
|
||||
device memory. The required size of the accleration structure
|
||||
buffer can be queried with the zeRaytracingGetAccelSizeExt
|
||||
function. The acceleration structure buffer must be a shared USM
|
||||
allocation and should be present on the host at build time. The
|
||||
referenced scene data (index and vertex buffers) can be standard
|
||||
host allocations, and will not be referenced into by the build
|
||||
acceleration structure.
|
||||
|
||||
Before an accleration structure is build, the user has to use the
|
||||
zeRaytracingGetAccelSize function to query the size of the
|
||||
acceleration structure and scratch space buffer to allocate. When
|
||||
using the worst case size to allocate the acceleration structure
|
||||
buffer, then the zeRaytracingBuildAccelExt function will never fail
|
||||
with an out of memory error. When using the expected size for the
|
||||
acceleration structure buffer, then the build may fail with
|
||||
ZE_RESULT_RAYTRACING_EXT_RETRY_BUILD_ACCEL and should then get
|
||||
re-tried with a larger amount of data. Using the
|
||||
accelBufferBytesOut argument, the build itself returns an improved
|
||||
size estimate which the user can use to re-try the build.
|
||||
|
||||
The acceleration structure build is executed on the host CPU and is
|
||||
synchronous, thus after the function returns with ZE_RESULT_SUCCESS
|
||||
the acceleration structure can get used. All provided data buffers
|
||||
have to be accessible from the host, thus no device memory can get
|
||||
passed. Unified shared memory has to get used for the acceleration
|
||||
structure buffer, for the builder to be able to write to it and the
|
||||
device to read from that buffer.
|
||||
|
||||
The constructed accleration structure is self contained, thus does
|
||||
not require the provided build data to be present after the build
|
||||
is done.
|
||||
|
||||
The constructed acceleration structure cannot get copied into a
|
||||
different memory buffer as it may contain pointers.
|
||||
|
||||
The acceleration build operation can get parallelized by passing a
|
||||
parallel operation and joining that parallel operation using the
|
||||
zeRaytracingParallelOperationJoinExt call with user provided worker
|
||||
threads. When a parallel operation is provided the
|
||||
zeRaytracingGetAccelSizeExt function returns with result
|
||||
ZE_RESULT_RAYTRACING_EXT_OPERATION_DEFERRED to indicate that the
|
||||
build operation is still in progress. The return value of the
|
||||
zeRaytracingParallelOperationJoinExt function determines the status
|
||||
of the parallel acceleration structure build.
|
||||
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL zeRaytracingBuildAccelExt( const ze_raytracing_build_accel_ext_desc_t* args );
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\brief Checks if the acceleration structure build for hDevice can be used on hDeviceOther.
|
||||
|
||||
\param hDevice: device the acceleration structure is build for
|
||||
\param hDeviceOther: device to check acceleration structure compatibility with
|
||||
|
||||
If the acceleration structures are compatible the function returns
|
||||
ZE_RESULT_SUCCESS, otherwise
|
||||
ZE_RESULT_RAYTRACING_EXT_ACCEL_INCOMPATIBLE.
|
||||
|
||||
*/
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL zeRaytracingAccelCompatibilityExt( const ze_device_handle_t hDevice, ze_device_handle_t hDeviceOther );
|
||||
|
||||
@@ -1,978 +0,0 @@
|
||||
#include "../../sycl/rthwif_embree.h"
|
||||
#include "../../sycl/rthwif_embree_builder.h"
|
||||
#include "../rttrace/rthwif_internal.h"
|
||||
#include "rthwif_embree_builder_ploc.h"
|
||||
#include "qbvh6.h"
|
||||
#include "../common/algorithms/parallel_reduce.h"
|
||||
|
||||
// === less than threshold, a single workgroup is used to perform all PLOC iterations in a single kernel launch ===
|
||||
#define SINGLE_WG_SWITCH_THRESHOLD 4*1024
|
||||
|
||||
// === less than threshold, 40bits morton code + 24bits index are used, otherwise 64bit morton code + 32bit index ===
|
||||
#define FAST_MC_NUM_PRIMS_THRESHOLD 1024*1024
|
||||
|
||||
// === max number of primitives fitting in 24bits ===
|
||||
#define FAST_MC_MAX_NUM_PRIMS ((uint)1<<24)
|
||||
|
||||
// === less than threshold, a single workgroup is used for all radix sort iterations ===
|
||||
#define SMALL_SORT_THRESHOLD 1024*4
|
||||
|
||||
// === maximum number of workgroups with 1024 elements, DG2/PVC perform best with 64 ===
|
||||
#define MAX_LARGE_WGS 256
|
||||
|
||||
// === rebalance if BVH2 subtrees are degenerated ===
|
||||
#define BVH2_REBALANCE 1
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
|
||||
namespace embree
|
||||
{
|
||||
using namespace embree::isa;
|
||||
|
||||
__forceinline size_t estimateSizeInternalNodes(const size_t numQuads, const size_t numInstances, const size_t numProcedurals, const bool conservative)
|
||||
{
|
||||
const size_t N = numQuads + numInstances + numProcedurals;
|
||||
// === conservative estimate ===
|
||||
size_t numFatLeaves = 0;
|
||||
if (conservative)
|
||||
numFatLeaves = ceilf( (float)N/2 ) + ceilf( (float)numInstances/2 ); // FIXME : better upper bound for instance case
|
||||
else
|
||||
numFatLeaves = ceilf( (float)N/3 ) + ceilf( (float)numInstances/2 ); // FIXME : better upper bound for instance case
|
||||
const size_t numInnerNodes = ceilf( (float)numFatLeaves/4 );
|
||||
return gpu::alignTo(std::max( ((numFatLeaves + numInnerNodes) * 64) , N * 16),64);
|
||||
}
|
||||
|
||||
__forceinline size_t estimateSizeLeafNodes(const size_t numQuads, const size_t numInstances, const size_t numProcedurals)
|
||||
{
|
||||
return (numQuads + numProcedurals + 2 * numInstances) * 64;
|
||||
}
|
||||
|
||||
__forceinline size_t estimateAccelBufferSize(const size_t numQuads, const size_t numInstances, const size_t numProcedurals, const bool conservative)
|
||||
{
|
||||
const size_t header = 128;
|
||||
const size_t node_size = estimateSizeInternalNodes(numQuads,numInstances,numProcedurals,conservative);
|
||||
const size_t leaf_size = estimateSizeLeafNodes(numQuads,numInstances,numProcedurals);
|
||||
const size_t totalSize = header + node_size + leaf_size;
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
__forceinline size_t estimateScratchBufferSize(const size_t numPrimitives)
|
||||
{
|
||||
// === sizeof(size_t)*MAX_LARGE_WGS for prefix sums across large work groups ===
|
||||
return sizeof(PLOCGlobals) + sizeof(size_t)*MAX_LARGE_WGS + numPrimitives * sizeof(LeafGenerationData);
|
||||
}
|
||||
|
||||
uint getBVH2Depth(BVH2Ploc *bvh2, uint index, const uint numPrimitives)
|
||||
{
|
||||
if (BVH2Ploc::getIndex(index) < numPrimitives) //isLeaf
|
||||
return 1;
|
||||
else
|
||||
return 1 + std::max(getBVH2Depth(bvh2,bvh2[index].leftIndex(),numPrimitives),getBVH2Depth(bvh2,bvh2[index].rightIndex(),numPrimitives));
|
||||
}
|
||||
|
||||
uint getNumLeaves(BVH2Ploc *bvh2, uint index, const uint numPrimitives)
|
||||
{
|
||||
if (BVH2Ploc::getIndex(index) < numPrimitives) //isLeaf
|
||||
return 1;
|
||||
else
|
||||
return getNumLeaves(bvh2,bvh2[index].leftIndex(),numPrimitives) + getNumLeaves(bvh2,bvh2[index].rightIndex(),numPrimitives);
|
||||
}
|
||||
|
||||
|
||||
uint getNumFatLeaves(BVH2Ploc *bvh2, uint index, const uint numPrimitives)
|
||||
{
|
||||
if (BVH2Ploc::isFatLeaf(index,numPrimitives)) //isLeaf
|
||||
return 1;
|
||||
else
|
||||
return getNumFatLeaves(bvh2,bvh2[index].leftIndex(),numPrimitives) + getNumFatLeaves(bvh2,bvh2[index].rightIndex(),numPrimitives);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void printBVH2Path(BVH2Ploc *bvh2, uint index, const uint numPrimitives)
|
||||
{
|
||||
if (BVH2Ploc::getIndex(index) < numPrimitives) //isLeaf
|
||||
{
|
||||
PRINT2(index,"LEAF");
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint depth = getBVH2Depth(bvh2,index,numPrimitives);
|
||||
const uint leftIndex = bvh2[index].leftIndex();
|
||||
const uint rightIndex = bvh2[index].rightIndex();
|
||||
const bool isFatLeafLeft = BVH2Ploc::isFatLeaf(bvh2[index].left,numPrimitives);
|
||||
const bool isFatLeafRight = BVH2Ploc::isFatLeaf(bvh2[index].right,numPrimitives);
|
||||
const uint numLeavesLeft = getNumLeaves(bvh2,leftIndex,numPrimitives);
|
||||
const uint numLeavesRight = getNumLeaves(bvh2,rightIndex,numPrimitives);
|
||||
PRINT6(index,depth,leftIndex,rightIndex,isFatLeafLeft,isFatLeafRight);
|
||||
PRINT2(leftIndex,numLeavesLeft);
|
||||
PRINT2(rightIndex,numLeavesRight);
|
||||
|
||||
if (!isFatLeafLeft)
|
||||
printBVH2Path(bvh2, leftIndex,numPrimitives);
|
||||
if (!isFatLeafRight)
|
||||
printBVH2Path(bvh2,rightIndex,numPrimitives);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkBVH2PlocHW(BVH2Ploc *bvh2, uint index,uint &nodes,uint &leaves,float &nodeSAH, float &leafSAH, uint &maxDepth,const uint numPrimitives, const uint bvh2_max_allocations, const uint depth)
|
||||
{
|
||||
if (bvh2[index].bounds.empty()) {
|
||||
PRINT2(index,bvh2[index]);
|
||||
FATAL("invalid bounds in BVH2");
|
||||
}
|
||||
if (!bvh2[index].bounds.checkNumericalBounds())
|
||||
{
|
||||
PRINT2(index,bvh2[index]);
|
||||
FATAL("Numerical Bounds in BVH2");
|
||||
}
|
||||
|
||||
if (BVH2Ploc::getIndex(index) < numPrimitives) //isLeaf
|
||||
{
|
||||
leaves++;
|
||||
leafSAH += bvh2[index].bounds.area();
|
||||
assert(bvh2[index].getLeafIndex() < numPrimitives);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxDepth = max(maxDepth,depth+1);
|
||||
uint indices[BVH_BRANCHING_FACTOR];
|
||||
const uint numChildren = openBVH2MaxAreaSortChildren(BVH2Ploc::getIndex(index),indices,bvh2,numPrimitives);
|
||||
for (uint i=0;i<numChildren;i++)
|
||||
if (BVH2Ploc::getIndex(indices[i]) > bvh2_max_allocations)
|
||||
FATAL("OPENING ERROR");
|
||||
|
||||
nodes++;
|
||||
nodeSAH += bvh2[index].bounds.area();
|
||||
|
||||
if (!bvh2[index].bounds.encloses( bvh2[ bvh2[index].leftIndex() ].bounds )) PRINT2("ENCLOSING ERROR LEFT",index);
|
||||
checkBVH2PlocHW(bvh2,bvh2[index].leftIndex(),nodes,leaves,nodeSAH,leafSAH,maxDepth,numPrimitives,bvh2_max_allocations,depth+1);
|
||||
|
||||
if (!bvh2[index].bounds.encloses( bvh2[ bvh2[index].rightIndex() ].bounds )) PRINT2("ENCLOSING ERROR RIGHT",index);
|
||||
checkBVH2PlocHW(bvh2,bvh2[index].rightIndex(),nodes,leaves,nodeSAH,leafSAH,maxDepth,numPrimitives,bvh2_max_allocations,depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
struct BuildTimer {
|
||||
enum Type {
|
||||
PRE_PROCESS = 0,
|
||||
BUILD = 1,
|
||||
POST_PROCESS = 2,
|
||||
ALLOCATION = 3,
|
||||
TOTAL = 4
|
||||
};
|
||||
|
||||
double host_timers[TOTAL];
|
||||
double device_timers[TOTAL];
|
||||
|
||||
double t0,t1;
|
||||
|
||||
inline void reset()
|
||||
{
|
||||
for (uint i=0;i<TOTAL;i++)
|
||||
{
|
||||
host_timers[i] = 0.0;
|
||||
device_timers[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void start(const Type type)
|
||||
{
|
||||
t0 = getSeconds();
|
||||
}
|
||||
|
||||
inline void stop(const Type type)
|
||||
{
|
||||
t1 = getSeconds();
|
||||
host_timers[(int)type] += 1000.0*(t1-t0);
|
||||
}
|
||||
|
||||
inline void add_to_device_timer(const Type type, double t)
|
||||
{
|
||||
device_timers[(int)type] += t;
|
||||
}
|
||||
|
||||
inline float get_accum_device_timer(const Type type) { return device_timers[(int)type]; }
|
||||
inline float get_accum_host_timer (const Type type) { return host_timers[(int)type]; }
|
||||
inline float get_host_timer() { return 1000.0*(t1-t0); }
|
||||
|
||||
inline float get_total_device_time()
|
||||
{
|
||||
double sum = 0.0;
|
||||
for (uint i=0;i<ALLOCATION;i++) sum += device_timers[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
inline float get_total_host_time()
|
||||
{
|
||||
double sum = 0.0;
|
||||
for (uint i=0;i<ALLOCATION;i++) sum += host_timers[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
__forceinline uint32_t getNumPrimitives(const RTHWIF_GEOMETRY_DESC* geom)
|
||||
{
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return ((RTHWIF_GEOMETRY_TRIANGLES_DESC*) geom)->triangleCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR : return ((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*) geom)->primCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return ((RTHWIF_GEOMETRY_QUADS_DESC*) geom)->quadCount;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : return 1;
|
||||
default : return 0;
|
||||
};
|
||||
}
|
||||
|
||||
/* fill all arg members that app did not know of yet */
|
||||
__forceinline RTHWIF_BUILD_ACCEL_ARGS rthwifPrepareBuildAccelArgs(const RTHWIF_BUILD_ACCEL_ARGS& args_i)
|
||||
{
|
||||
RTHWIF_BUILD_ACCEL_ARGS args;
|
||||
memset(&args,0,sizeof(RTHWIF_BUILD_ACCEL_ARGS));
|
||||
memcpy(&args,&args_i,std::min(sizeof(RTHWIF_BUILD_ACCEL_ARGS),args_i.structBytes));
|
||||
args.structBytes = sizeof(RTHWIF_BUILD_ACCEL_ARGS);
|
||||
return args;
|
||||
}
|
||||
|
||||
__forceinline PrimitiveCounts countPrimitives(const RTHWIF_GEOMETRY_DESC** geometries, const uint numGeometries)
|
||||
{
|
||||
auto reduce = [&](const range<size_t>& r) -> PrimitiveCounts
|
||||
{
|
||||
PrimitiveCounts counts;
|
||||
for (size_t geomID = r.begin(); geomID < r.end(); geomID++)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
if (geom == nullptr) continue;
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES :
|
||||
{
|
||||
counts.numTriangles += ((RTHWIF_GEOMETRY_TRIANGLES_DESC*) geom)->triangleCount;
|
||||
counts.numQuadBlocks += (((RTHWIF_GEOMETRY_TRIANGLES_DESC *)geom)->triangleCount+TRIANGLE_QUAD_BLOCK_SIZE-1)/TRIANGLE_QUAD_BLOCK_SIZE;
|
||||
break;
|
||||
}
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS :
|
||||
{
|
||||
counts.numQuads += ((RTHWIF_GEOMETRY_QUADS_DESC*) geom)->quadCount;
|
||||
counts.numQuadBlocks += (((RTHWIF_GEOMETRY_QUADS_DESC *)geom)->quadCount+TRIANGLE_QUAD_BLOCK_SIZE-1)/TRIANGLE_QUAD_BLOCK_SIZE;
|
||||
break;
|
||||
}
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR : counts.numProcedurals += ((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*) geom)->primCount; break;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : counts.numInstances += 1; break;
|
||||
default: assert(false); break;
|
||||
};
|
||||
};
|
||||
return counts;
|
||||
};
|
||||
|
||||
const uint COUNT_BLOCK_SIZE = 256;
|
||||
const uint COUNT_PARALLEL_THRESHOLD = 256;
|
||||
|
||||
const PrimitiveCounts primCounts = parallel_reduce((uint)0, numGeometries, COUNT_BLOCK_SIZE, COUNT_PARALLEL_THRESHOLD, PrimitiveCounts(), reduce,
|
||||
[&](const PrimitiveCounts& b0, const PrimitiveCounts& b1) -> PrimitiveCounts { return b0 + b1; });
|
||||
return primCounts;
|
||||
}
|
||||
|
||||
RTHWIF_ERROR createEmptyBVH(const RTHWIF_BUILD_ACCEL_ARGS& args, sycl::queue &gpu_queue)
|
||||
{
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
QBVH6* qbvh = (QBVH6*)args.accelBuffer;
|
||||
qbvh->bounds = BBox3f(empty);
|
||||
qbvh->numPrims = 0;
|
||||
qbvh->nodeDataStart = 2;
|
||||
qbvh->nodeDataCur = 3;
|
||||
qbvh->leafDataStart = 3;
|
||||
qbvh->leafDataCur = 3;
|
||||
new (qbvh->nodePtr(2)) QBVH6::InternalNode6(NODE_TYPE_INTERNAL);
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
if (args.accelBufferBytesOut) *args.accelBufferBytesOut = 128+64;
|
||||
if (args.boundsOut) { BBox3f geometryBounds (empty); *args.boundsOut = *(RTHWIF_AABB*)&geometryBounds; };
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
// =================================================================================================================================================================================
|
||||
// =================================================================================================================================================================================
|
||||
// =================================================================================================================================================================================
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifGetAccelSizeGPU(const RTHWIF_BUILD_ACCEL_ARGS& args_i, RTHWIF_ACCEL_SIZE& size_o, void *sycl_queue, uint verbose_level=0)
|
||||
{
|
||||
double time0 = getSeconds();
|
||||
|
||||
RTHWIF_BUILD_ACCEL_ARGS args = rthwifPrepareBuildAccelArgs(args_i);
|
||||
const RTHWIF_GEOMETRY_DESC** geometries = args.geometries;
|
||||
const uint numGeometries = args.numGeometries;
|
||||
sycl::queue &gpu_queue = *(sycl::queue*)sycl_queue;
|
||||
|
||||
// =============================================================================
|
||||
// === GPU-based primitive count estimation including triangle quadification ===
|
||||
// =============================================================================
|
||||
|
||||
const PrimitiveCounts primCounts = getEstimatedPrimitiveCounts(gpu_queue,geometries,numGeometries,verbose_level >= 2);
|
||||
|
||||
const uint numTriangles = primCounts.numTriangles; // === original number of triangles ===
|
||||
const uint numMergedTrisQuads = primCounts.numMergedTrisQuads;
|
||||
const uint numQuads = primCounts.numQuads;
|
||||
const uint numProcedurals = primCounts.numProcedurals;
|
||||
const uint numInstances = primCounts.numInstances;
|
||||
|
||||
const uint numPrimitives = numMergedTrisQuads + numProcedurals + numInstances;
|
||||
|
||||
// =============================================
|
||||
// === allocation for empty scene is default ===
|
||||
// =============================================
|
||||
|
||||
size_t expectedBytes = 3*64;
|
||||
size_t worstCaseBytes = 4*64;
|
||||
|
||||
if (numPrimitives)
|
||||
{
|
||||
expectedBytes = estimateAccelBufferSize( numMergedTrisQuads, numInstances, numProcedurals, false);
|
||||
worstCaseBytes = estimateAccelBufferSize(numQuads + numTriangles, numInstances, numProcedurals, true);
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// === estimate accel and scratch buffer sizes ===
|
||||
// ===============================================
|
||||
|
||||
const size_t scratchBytes = estimateScratchBufferSize(std::max(numPrimitives,numGeometries));
|
||||
|
||||
if (verbose_level >= 2)
|
||||
{
|
||||
PRINT5(numMergedTrisQuads,numTriangles,numQuads,numProcedurals,numInstances);
|
||||
PRINT3(expectedBytes,worstCaseBytes,scratchBytes);
|
||||
}
|
||||
|
||||
/* return size to user */
|
||||
RTHWIF_ACCEL_SIZE size;
|
||||
memset(&size,0,sizeof(RTHWIF_ACCEL_SIZE));
|
||||
size.accelBufferExpectedBytes = expectedBytes;
|
||||
size.accelBufferWorstCaseBytes = worstCaseBytes;
|
||||
size.scratchBufferBytes = scratchBytes;
|
||||
size_t bytes_o = size_o.structBytes;
|
||||
memset(&size_o,0,bytes_o);
|
||||
memcpy(&size_o,&size,bytes_o);
|
||||
size_o.structBytes = bytes_o;
|
||||
|
||||
double time1 = getSeconds();
|
||||
if (verbose_level >= 1)
|
||||
std::cout << "rthwifGetAccelSizeGPU time = " << (float)(time1-time0)*1000.0f << " ms" << std::endl;
|
||||
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifPrefetchAccelGPU(const RTHWIF_BUILD_ACCEL_ARGS& args, void *sycl_queue, uint verbose_level=0)
|
||||
{
|
||||
double time0 = getSeconds();
|
||||
|
||||
sycl::queue &gpu_queue = *(sycl::queue*)sycl_queue;
|
||||
|
||||
#if 0
|
||||
const RTHWIF_GEOMETRY_DESC** geometries = args.geometries;
|
||||
const uint numGeometries = args.numGeometries;
|
||||
|
||||
// ===================================
|
||||
// === prefetch builder scene data ===
|
||||
// ===================================
|
||||
|
||||
for (size_t geomID = 0; geomID < numGeometries; geomID++)
|
||||
{
|
||||
const RTHWIF_GEOMETRY_DESC* geom = geometries[geomID];
|
||||
if (geom == nullptr) continue;
|
||||
switch (geom->geometryType) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES :
|
||||
{
|
||||
RTHWIF_GEOMETRY_TRIANGLES_DESC *t = (RTHWIF_GEOMETRY_TRIANGLES_DESC*)geom;
|
||||
if (t->vertexBuffer) gpu_queue.prefetch(t->vertexBuffer,t->vertexCount*t->vertexStride);
|
||||
if (t->triangleBuffer) gpu_queue.prefetch(t->triangleBuffer,t->triangleCount*t->triangleStride);
|
||||
gpu_queue.prefetch(t,sizeof(RTHWIF_GEOMETRY_TRIANGLES_DESC));
|
||||
break;
|
||||
}
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS :
|
||||
{
|
||||
RTHWIF_GEOMETRY_QUADS_DESC *q = (RTHWIF_GEOMETRY_QUADS_DESC*)geom;
|
||||
if (q->vertexBuffer) gpu_queue.prefetch(q->vertexBuffer,q->vertexCount*q->vertexStride);
|
||||
if (q->quadBuffer) gpu_queue.prefetch(q->quadBuffer,q->quadCount*q->quadStride);
|
||||
gpu_queue.prefetch(q,sizeof(RTHWIF_GEOMETRY_QUADS_DESC));
|
||||
break;
|
||||
}
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR :
|
||||
{
|
||||
RTHWIF_GEOMETRY_AABBS_FPTR_DESC *a = (RTHWIF_GEOMETRY_AABBS_FPTR_DESC*)geom;
|
||||
gpu_queue.prefetch(a,sizeof(RTHWIF_GEOMETRY_AABBS_FPTR_DESC));
|
||||
break;
|
||||
}
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE :
|
||||
{
|
||||
RTHWIF_GEOMETRY_INSTANCE_DESC *i = (RTHWIF_GEOMETRY_INSTANCE_DESC*)geom;
|
||||
gpu_queue.prefetch(i->bounds,sizeof(RTHWIF_AABB));
|
||||
gpu_queue.prefetch(i,sizeof(RTHWIF_GEOMETRY_INSTANCE_DESC));
|
||||
break;
|
||||
}
|
||||
default: assert(false); break;
|
||||
};
|
||||
};
|
||||
|
||||
if (geometries) gpu_queue.prefetch(geometries,sizeof(RTHWIF_GEOMETRY_DESC*)*numGeometries);
|
||||
if (args.accelBuffer) gpu_queue.prefetch(args.accelBuffer ,args.accelBufferBytes);
|
||||
if (args.scratchBuffer) gpu_queue.prefetch(args.scratchBuffer,args.scratchBufferBytes);
|
||||
#endif
|
||||
// ======================================================
|
||||
// === DUMMY KERNEL TO TRIGGER REMAINING USM TRANSFER ===
|
||||
// ======================================================
|
||||
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) { cgh.single_task([=]() {}); });
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
|
||||
double time1 = getSeconds();
|
||||
if (verbose_level >= 1)
|
||||
std::cout << "rthwifPrefetchAccelGPU time = " << (float)(time1-time0)*1000.0f << " ms" << std::endl;
|
||||
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
|
||||
RTHWIF_API RTHWIF_ERROR rthwifBuildAccelGPU(const RTHWIF_BUILD_ACCEL_ARGS& args, void *sycl_queue, uint verbose_level=0)
|
||||
{
|
||||
BuildTimer timer;
|
||||
timer.reset();
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
|
||||
// ================================
|
||||
// === GPU device/queue/context ===
|
||||
// ================================
|
||||
|
||||
sycl::queue &gpu_queue = *(sycl::queue*)sycl_queue;
|
||||
const bool verbose1 = verbose_level >= 1;
|
||||
const bool verbose2 = verbose_level >= 2;
|
||||
const uint gpu_maxComputeUnits = gpu_queue.get_device().get_info<sycl::info::device::max_compute_units>();
|
||||
const uint MAX_WGS = gpu_maxComputeUnits / 8;
|
||||
|
||||
uint *host_device_tasks = (uint*)sycl::aligned_alloc(64,HOST_DEVICE_COMM_BUFFER_SIZE,gpu_queue.get_device(),gpu_queue.get_context(),sycl::usm::alloc::host);
|
||||
|
||||
|
||||
if (unlikely(verbose2))
|
||||
{
|
||||
const uint gpu_maxWorkGroupSize = gpu_queue.get_device().get_info<sycl::info::device::max_work_group_size>();
|
||||
const uint gpu_maxLocalMemory = gpu_queue.get_device().get_info<sycl::info::device::local_mem_size>();
|
||||
PRINT("PLOC++ GPU BVH BUILDER");
|
||||
PRINT( gpu_queue.get_device().get_info<sycl::info::device::global_mem_size>() );
|
||||
PRINT(gpu_maxWorkGroupSize);
|
||||
PRINT(gpu_maxComputeUnits);
|
||||
PRINT(gpu_maxLocalMemory);
|
||||
}
|
||||
|
||||
// =============================
|
||||
// === setup scratch pointer ===
|
||||
// =============================
|
||||
|
||||
PLOCGlobals *globals = (PLOCGlobals *)args.scratchBuffer;
|
||||
uint *const sync_mem = (uint*)((char*)args.scratchBuffer + sizeof(PLOCGlobals));
|
||||
uint *const scratch = (uint*)((char*)args.scratchBuffer + sizeof(PLOCGlobals) + sizeof(uint)*MAX_LARGE_WGS);
|
||||
|
||||
// ======================
|
||||
// ==== init globals ====
|
||||
// ======================
|
||||
{
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
globals->reset();
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
if (unlikely(verbose1))
|
||||
{
|
||||
double dt = gpu::getDeviceExecutionTiming(queue_event);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,dt);
|
||||
if (unlikely(verbose2)) std::cout << "=> Init Globals I: " << dt << " ms" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================================================
|
||||
// === get primitive type count from geometries, compute quad blocks per geom ===
|
||||
// ==============================================================================
|
||||
|
||||
const RTHWIF_GEOMETRY_DESC** geometries = args.geometries;
|
||||
uint numGeometries = args.numGeometries;
|
||||
|
||||
double device_prim_counts_time = 0.0f;
|
||||
|
||||
const PrimitiveCounts primCounts = countPrimitives(gpu_queue,geometries,numGeometries,globals,scratch,host_device_tasks,device_prim_counts_time,verbose1);
|
||||
|
||||
// ================================================
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,device_prim_counts_time);
|
||||
if (unlikely(verbose2)) std::cout << "=> Count Primitives from Geometries: " << timer.get_host_timer() << " ms (host) " << device_prim_counts_time << " ms (device) " << std::endl;
|
||||
|
||||
uint numQuads = primCounts.numQuads + primCounts.numTriangles; // no quadification taken into account at this point
|
||||
uint numProcedurals = primCounts.numProcedurals;
|
||||
uint numInstances = primCounts.numInstances;
|
||||
const uint numQuadBlocks = primCounts.numQuadBlocks;
|
||||
|
||||
const uint expected_numPrimitives = numQuads + numProcedurals + numInstances;
|
||||
|
||||
// =================================================
|
||||
// === empty scene before removing invalid prims ===
|
||||
// =================================================
|
||||
|
||||
if (unlikely(expected_numPrimitives == 0)) createEmptyBVH(args,gpu_queue);
|
||||
|
||||
if (numQuads)
|
||||
{
|
||||
// ==================================================
|
||||
// === compute correct quadification using blocks ===
|
||||
// ==================================================
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
double device_quadification_time = 0.0;
|
||||
numQuads = countQuadsPerGeometryUsingBlocks(gpu_queue,globals,args.geometries,numGeometries,numQuadBlocks,scratch,scratch+numGeometries,host_device_tasks,device_quadification_time,verbose1);
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,device_quadification_time);
|
||||
if (unlikely(verbose2)) std::cout << "=> Count " << numQuads << " Quads " << timer.get_host_timer() << " ms (host) " << (float)device_quadification_time << " ms (device) " << std::endl;
|
||||
}
|
||||
|
||||
// ================================
|
||||
// === estimate size of the BVH ===
|
||||
// ================================
|
||||
|
||||
size_t numPrimitives = numQuads + numInstances + numProcedurals; // actual #prims can be lower due to invalid instances or procedurals but quads count is accurate at this point
|
||||
const size_t allocated_size = args.accelBufferBytes;
|
||||
const size_t header = 128;
|
||||
const size_t leaf_size = estimateSizeLeafNodes(numQuads,numInstances,numProcedurals);
|
||||
const size_t node_size = (header + leaf_size) <= allocated_size ? allocated_size - leaf_size - header : 0;
|
||||
const size_t node_data_start = header;
|
||||
const size_t leaf_data_start = header + node_size;
|
||||
|
||||
// =================================================================
|
||||
// === if allocated accel buffer is too small, return with error ===
|
||||
// =================================================================
|
||||
|
||||
const uint required_size = header + estimateSizeInternalNodes(numQuads,numInstances,numProcedurals,false) + leaf_size;
|
||||
if (unlikely(allocated_size < required_size))
|
||||
{
|
||||
if (unlikely(verbose2))
|
||||
{
|
||||
PRINT2(required_size,allocated_size);
|
||||
PRINT2(node_size,estimateSizeInternalNodes(numQuads,numInstances,numProcedurals,false));
|
||||
PRINT3("RETRY BVH BUILD DUE BECAUSE OF SMALL ACCEL BUFFER ALLOCATION!!!", args.accelBufferBytes,required_size );
|
||||
}
|
||||
if (args.accelBufferBytesOut) *args.accelBufferBytesOut = required_size;
|
||||
if (host_device_tasks) sycl::free(host_device_tasks,gpu_queue.get_context());
|
||||
return RTHWIF_ERROR_RETRY;
|
||||
}
|
||||
|
||||
const size_t conv_mem_size = sizeof(numPrimitives)*numPrimitives;
|
||||
const size_t NUM_ACTIVE_LARGE_WGS = min((numPrimitives+LARGE_WG_SIZE-1)/LARGE_WG_SIZE,(size_t)MAX_WGS);
|
||||
|
||||
// ===========================
|
||||
// === set up all pointers ===
|
||||
// ===========================
|
||||
QBVH6* qbvh = (QBVH6*)args.accelBuffer;
|
||||
char *bvh_mem = (char*)qbvh + header;
|
||||
char *const leaf_mem = (char*)qbvh + leaf_data_start;
|
||||
BVH2Ploc *const bvh2 = (BVH2Ploc*)(leaf_mem);
|
||||
typedef gpu::MortonCodePrimitive64Bit_2x MCPrim;
|
||||
MCPrim *const mc0 = (MCPrim*)(bvh2 + numPrimitives);
|
||||
MCPrim *const mc1 = mc0 + numPrimitives;
|
||||
MCPrim *const morton_codes[2] = { mc0, mc1 };
|
||||
uint *const cluster_index = (uint*) (bvh_mem + 0 * numPrimitives * sizeof(uint)); // * 2
|
||||
BVH2SubTreeState *const bvh2_subtree_size = (BVH2SubTreeState*) (bvh_mem + 2 * numPrimitives * sizeof(uint)); // * 2
|
||||
uint *cluster_i[2] = { cluster_index + 0, cluster_index + numPrimitives };
|
||||
uint *const cluster_index_source = cluster_i[0];
|
||||
uint *const cluster_index_dest = cluster_i[1];
|
||||
LeafGenerationData *leafGenData = (LeafGenerationData*)scratch;
|
||||
|
||||
// ==============================
|
||||
// ==== init globals phase 2 ====
|
||||
// ==============================
|
||||
{
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
globals->numPrimitives = numPrimitives;
|
||||
globals->node_mem_allocator_cur = node_data_start/64;
|
||||
globals->node_mem_allocator_start = node_data_start/64;
|
||||
globals->leaf_mem_allocator_cur = leaf_data_start/64;
|
||||
globals->leaf_mem_allocator_start = leaf_data_start/64;
|
||||
globals->bvh2_index_allocator = numPrimitives;
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
if (unlikely(verbose1))
|
||||
{
|
||||
double dt = gpu::getDeviceExecutionTiming(queue_event);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,dt);
|
||||
if (unlikely(verbose2)) std::cout << "=> Init Globals II: " << dt << " ms" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
|
||||
double create_primref_time = 0.0f;
|
||||
// ===================================================
|
||||
// ==== merge triangles to quads, create primrefs ====
|
||||
// ===================================================
|
||||
|
||||
if (numQuads)
|
||||
createQuads_initPLOCPrimRefs(gpu_queue,globals,args.geometries,numGeometries,numQuadBlocks,scratch,bvh2,0,create_primref_time,verbose1);
|
||||
|
||||
// ====================================
|
||||
// ==== create procedural primrefs ====
|
||||
// ====================================
|
||||
|
||||
if (numProcedurals)
|
||||
numProcedurals = createProcedurals_initPLOCPrimRefs(gpu_queue,args.geometries,numGeometries,sync_mem,NUM_ACTIVE_LARGE_WGS,bvh2,numQuads,host_device_tasks,create_primref_time,verbose1);
|
||||
|
||||
// ==================================
|
||||
// ==== create instance primrefs ====
|
||||
// ==================================
|
||||
|
||||
if (numInstances)
|
||||
numInstances = createInstances_initPLOCPrimRefs(gpu_queue,args.geometries,numGeometries,sync_mem,NUM_ACTIVE_LARGE_WGS,bvh2,numQuads + numProcedurals,host_device_tasks,create_primref_time,verbose1);
|
||||
|
||||
// =================================================================================================
|
||||
// === recompute actual number of primitives after quadification and removing of invalid entries ===
|
||||
// =================================================================================================
|
||||
|
||||
numPrimitives = numQuads + numInstances + numProcedurals;
|
||||
|
||||
const GeometryTypeRanges geometryTypeRanges(numQuads,numProcedurals,numInstances);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
{
|
||||
PRINT4(numPrimitives,numQuads,numInstances,numProcedurals);
|
||||
PRINT3(node_size,leaf_size,args.accelBufferBytes);
|
||||
PRINT2(node_size/64,leaf_size/64);
|
||||
}
|
||||
|
||||
// =================================================================================
|
||||
// === test for empty scene again after all final primitive counts are available ===
|
||||
// =================================================================================
|
||||
|
||||
if (unlikely(numPrimitives == 0))
|
||||
{
|
||||
if (host_device_tasks) sycl::free(host_device_tasks,gpu_queue.get_context());
|
||||
return createEmptyBVH(args,gpu_queue);
|
||||
}
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,create_primref_time);
|
||||
if (unlikely(verbose2)) std::cout << "=> Create Quads/Procedurals/Instances etc, Init PrimRefs: " << timer.get_host_timer() << " ms (host) " << create_primref_time << " ms (device) " << std::endl;
|
||||
|
||||
// ==========================================
|
||||
// ==== get centroid and geometry bounds ====
|
||||
// ==========================================
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
double device_compute_centroid_bounds_time = 0.0f;
|
||||
|
||||
computeCentroidGeometryBounds(gpu_queue, &globals->geometryBounds, &globals->centroidBounds, bvh2, numPrimitives, device_compute_centroid_bounds_time, verbose1);
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,device_compute_centroid_bounds_time);
|
||||
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> Get Geometry and Centroid Bounds Phase: " << timer.get_host_timer() << " ms (host) " << device_compute_centroid_bounds_time << " ms (device) " << std::endl;
|
||||
|
||||
// ==============================
|
||||
// ==== compute morton codes ====
|
||||
// ==============================
|
||||
|
||||
const bool fastMCMode = numPrimitives < FAST_MC_NUM_PRIMS_THRESHOLD || (args.quality == RTHWIF_BUILD_QUALITY_LOW && numPrimitives < FAST_MC_MAX_NUM_PRIMS);
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
double device_compute_mc_time = 0.0f;
|
||||
|
||||
if (!fastMCMode)
|
||||
computeMortonCodes64Bit_SaveMSBBits(gpu_queue,&globals->centroidBounds,mc0,bvh2,(uint*)bvh2_subtree_size,numPrimitives,device_compute_mc_time,verbose1);
|
||||
else
|
||||
computeMortonCodes64Bit(gpu_queue,&globals->centroidBounds,(gpu::MortonCodePrimitive40x24Bits3D*)mc1,bvh2,numPrimitives,0,(uint64_t)-1,device_compute_mc_time,verbose1);
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> Compute Morton Codes: " << timer.get_host_timer() << " ms (host) " << device_compute_mc_time << " ms (device) " << std::endl;
|
||||
|
||||
// ===========================
|
||||
// ==== sort morton codes ====
|
||||
// ===========================
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
|
||||
if (!fastMCMode) // fastMCMode == 32bit key + 32bit value pairs, !fastMode == 64bit key + 32bit value pairs
|
||||
{
|
||||
const uint scratchMemWGs = gpu::getNumWGsScratchSize(conv_mem_size);
|
||||
const uint nextPowerOf2 = 1 << (32 - sycl::clz(numPrimitives) - 1);
|
||||
const uint sortWGs = min(max(min((int)nextPowerOf2/8192,(int)gpu_maxComputeUnits/4),1),(int)scratchMemWGs);
|
||||
|
||||
sycl::event initial = sycl::event();
|
||||
sycl::event block0 = gpu::radix_sort_Nx8Bit(gpu_queue, morton_codes[0], morton_codes[1], numPrimitives, (uint*)scratch, 4, 8, initial, sortWGs);
|
||||
sycl::event restore = restoreMSBBits(gpu_queue,mc0,(uint*)bvh2_subtree_size,numPrimitives,block0,verbose1);
|
||||
sycl::event block1 = gpu::radix_sort_Nx8Bit(gpu_queue, morton_codes[0], morton_codes[1], numPrimitives, (uint*)scratch, 4, 8, restore, sortWGs);
|
||||
gpu::waitOnEventAndCatchException(block1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numPrimitives < SMALL_SORT_THRESHOLD)
|
||||
gpu::radix_sort_single_workgroup(gpu_queue, (uint64_t *)mc0, (uint64_t *)mc1, numPrimitives, 3,8);
|
||||
else
|
||||
{
|
||||
const uint scratchMemWGs = gpu::getNumWGsScratchSize(conv_mem_size);
|
||||
const uint nextPowerOf2 = 1 << (32 - sycl::clz(numPrimitives) - 1);
|
||||
const uint sortWGs = min(max(min((int)nextPowerOf2/LARGE_WG_SIZE,(int)gpu_maxComputeUnits/4),1),(int)scratchMemWGs);
|
||||
sycl::event initial = sycl::event();
|
||||
sycl::event block0 = gpu::radix_sort_Nx8Bit(gpu_queue, (gpu::MortonCodePrimitive40x24Bits3D*)morton_codes[1], (gpu::MortonCodePrimitive40x24Bits3D*)morton_codes[0], numPrimitives, (uint*)scratch, 3, 8, initial, sortWGs);
|
||||
gpu::waitOnEventAndCatchException(block0);
|
||||
}
|
||||
}
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,timer.get_host_timer());
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> Sort Morton Codes: " << timer.get_host_timer() << " ms (host and device)" << std::endl;
|
||||
|
||||
// ===========================
|
||||
// ====== init clusters ======
|
||||
// ===========================
|
||||
|
||||
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
double device_init_clusters_time = 0.0f;
|
||||
|
||||
if (!fastMCMode)
|
||||
initClusters(gpu_queue,mc0,bvh2,cluster_index,bvh2_subtree_size,numPrimitives,device_init_clusters_time,verbose1);
|
||||
else
|
||||
initClusters(gpu_queue,(gpu::MortonCodePrimitive40x24Bits3D*)mc0,bvh2,cluster_index,bvh2_subtree_size,numPrimitives,device_init_clusters_time,verbose1);
|
||||
|
||||
timer.stop(BuildTimer::PRE_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::PRE_PROCESS,device_init_clusters_time);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> Init Clusters: " << timer.get_host_timer() << " ms (host) " << device_init_clusters_time << " ms (device) " << std::endl;
|
||||
|
||||
uint numPrims = numPrimitives;
|
||||
// ===================================================================================================================================================
|
||||
// ===================================================================================================================================================
|
||||
// ===================================================================================================================================================
|
||||
|
||||
// === 8 or 16-wide search radius dependening on compiler flags ===
|
||||
const uint SEARCH_RADIUS_SHIFT = args.quality == RTHWIF_BUILD_QUALITY_LOW ? 3 : 4;
|
||||
|
||||
double device_ploc_iteration_time = 0.0f;
|
||||
|
||||
uint iteration = 0;
|
||||
|
||||
timer.start(BuildTimer::BUILD);
|
||||
|
||||
// ========================
|
||||
// ==== clear sync mem ====
|
||||
// ========================
|
||||
|
||||
clearScratchMem(gpu_queue,sync_mem,0,NUM_ACTIVE_LARGE_WGS,device_ploc_iteration_time,verbose1);
|
||||
|
||||
float ratio = 100.0f;
|
||||
for (;numPrims>1;iteration++)
|
||||
{
|
||||
// ==================================================
|
||||
// ==== single kernel path if #prims < threshold ====
|
||||
// ==================================================
|
||||
|
||||
if (numPrims < SINGLE_WG_SWITCH_THRESHOLD)
|
||||
{
|
||||
double singleWG_time = 0.0f;
|
||||
singleWGBuild(gpu_queue, globals, bvh2, cluster_index_source, cluster_index_dest, bvh2_subtree_size, numPrims, SEARCH_RADIUS_SHIFT, singleWG_time, verbose1);
|
||||
timer.add_to_device_timer(BuildTimer::BUILD,singleWG_time);
|
||||
numPrims = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ===================================================================================
|
||||
// ==== nearest neighbor search, merge clusters and create bvh2 nodes (fast path) ====
|
||||
// ===================================================================================
|
||||
device_ploc_iteration_time = 0.0f;
|
||||
iteratePLOC(gpu_queue,globals,bvh2,cluster_index_source,cluster_index_dest,bvh2_subtree_size,sync_mem,numPrims,NUM_ACTIVE_LARGE_WGS,host_device_tasks,SEARCH_RADIUS_SHIFT,device_ploc_iteration_time,ratio < BOTTOM_LEVEL_RATIO,verbose1);
|
||||
timer.add_to_device_timer(BuildTimer::BUILD,device_ploc_iteration_time);
|
||||
|
||||
const uint new_numPrims = *host_device_tasks;
|
||||
assert(new_numPrims < numPrims);
|
||||
ratio = (float)(numPrims-new_numPrims) / numPrims * 100.0f;
|
||||
numPrims = new_numPrims;
|
||||
// ==========================
|
||||
}
|
||||
if (unlikely(verbose2))
|
||||
PRINT5(iteration,numPrims,ratio,(float)device_ploc_iteration_time,(float)timer.get_accum_device_timer(BuildTimer::BUILD));
|
||||
}
|
||||
|
||||
timer.stop(BuildTimer::BUILD);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> PLOC phase: " << timer.get_host_timer() << " ms (host) " << (float)timer.get_accum_device_timer(BuildTimer::BUILD) << " ms (device) " << std::endl;
|
||||
|
||||
|
||||
|
||||
#if BVH2_REBALANCE == 1
|
||||
// ===============================================================================================================
|
||||
// ========================================== rebalance BVH2 if degenerated ======================================
|
||||
// ===============================================================================================================
|
||||
#if 0
|
||||
uint maxDepth = 0;
|
||||
for (uint i=0;i<numPrims;i++)
|
||||
{
|
||||
const uint depth = getBVH2Depth(bvh2,cluster_index_source[i],numPrimitives);
|
||||
maxDepth = max(maxDepth,depth);
|
||||
}
|
||||
PRINT(maxDepth);
|
||||
#endif
|
||||
|
||||
double rebalanceBVH2_time = 0.0f;
|
||||
rebalanceBVH2(gpu_queue,bvh2,bvh2_subtree_size,numPrimitives,rebalanceBVH2_time,verbose1);
|
||||
if (unlikely(verbose2))
|
||||
PRINT(rebalanceBVH2_time);
|
||||
timer.add_to_device_timer(BuildTimer::BUILD,rebalanceBVH2_time);
|
||||
|
||||
#if 0
|
||||
maxDepth = 0;
|
||||
for (uint i=0;i<numPrims;i++)
|
||||
{
|
||||
const uint depth = getBVH2Depth(bvh2,cluster_index_source[i],numPrimitives);
|
||||
maxDepth = max(maxDepth,depth);
|
||||
}
|
||||
PRINT(maxDepth);
|
||||
#endif
|
||||
// ===============================================================================================================
|
||||
// ===============================================================================================================
|
||||
// ===============================================================================================================
|
||||
#endif
|
||||
|
||||
// =====================================
|
||||
// === check and convert BVH2 (host) ===
|
||||
// =====================================
|
||||
|
||||
if (unlikely(verbose2))
|
||||
PRINT2(globals->bvh2_index_allocator,2*numPrimitives);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
{
|
||||
PRINT2(globals->bvh2_index_allocator,2*numPrimitives);
|
||||
if (globals->bvh2_index_allocator >= 2*numPrimitives)
|
||||
FATAL("BVH2 construction, allocator");
|
||||
PRINT(globals->rootIndex);
|
||||
uint nodes = 0;
|
||||
uint leaves = 0;
|
||||
float nodeSAH = 0;
|
||||
float leafSAH = 0;
|
||||
uint maxDepth = 0;
|
||||
checkBVH2PlocHW(bvh2,globals->rootIndex,nodes,leaves,nodeSAH,leafSAH,maxDepth,numPrimitives,globals->bvh2_index_allocator,0);
|
||||
nodeSAH /= globals->geometryBounds.area();
|
||||
leafSAH /= globals->geometryBounds.area();
|
||||
PRINT5(nodes,leaves,nodeSAH,leafSAH,maxDepth);
|
||||
|
||||
/* --- dummy kernel to trigger USM transfer again to not screw up device timings --- */
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
}
|
||||
|
||||
// =============================
|
||||
// === convert BVH2 to QBVH6 ===
|
||||
// =============================
|
||||
timer.start(BuildTimer::PRE_PROCESS);
|
||||
float conversion_device_time = 0.0f;
|
||||
const bool convert_success = convertBVH2toQBVH6(gpu_queue,globals,host_device_tasks,args.geometries,qbvh,bvh2,leafGenData,numPrimitives,numInstances != 0,geometryTypeRanges,conversion_device_time,verbose1);
|
||||
|
||||
/* --- init final QBVH6 header --- */
|
||||
{
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
/* init qbvh */
|
||||
qbvh->bounds.lower.x = globals->geometryBounds.lower_x;
|
||||
qbvh->bounds.lower.y = globals->geometryBounds.lower_y;
|
||||
qbvh->bounds.lower.z = globals->geometryBounds.lower_z;
|
||||
qbvh->bounds.upper.x = globals->geometryBounds.upper_x;
|
||||
qbvh->bounds.upper.y = globals->geometryBounds.upper_y;
|
||||
qbvh->bounds.upper.z = globals->geometryBounds.upper_z;
|
||||
qbvh->numPrims = numPrimitives;
|
||||
qbvh->nodeDataStart = globals->node_mem_allocator_start;
|
||||
qbvh->nodeDataCur = globals->node_mem_allocator_cur;
|
||||
qbvh->leafDataStart = globals->leaf_mem_allocator_start;
|
||||
qbvh->leafDataCur = globals->leaf_mem_allocator_cur;
|
||||
*(gpu::AABB3f*)host_device_tasks = globals->geometryBounds;
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
}
|
||||
|
||||
if (args.boundsOut) *args.boundsOut = *(RTHWIF_AABB*)host_device_tasks;
|
||||
|
||||
timer.stop(BuildTimer::POST_PROCESS);
|
||||
timer.add_to_device_timer(BuildTimer::POST_PROCESS,conversion_device_time);
|
||||
|
||||
if (unlikely(verbose2))
|
||||
std::cout << "=> BVH2 -> QBVH6 Flattening: " << timer.get_host_timer() << " ms (host) " << conversion_device_time << " ms (device) " << std::endl;
|
||||
|
||||
// ==========================================================
|
||||
// ==========================================================
|
||||
// ==========================================================
|
||||
|
||||
if (unlikely(verbose2))
|
||||
{
|
||||
// === memory allocation and usage stats ===
|
||||
const uint nodes_used = globals->node_mem_allocator_cur-globals->node_mem_allocator_start;
|
||||
const uint leaves_used = globals->leaf_mem_allocator_cur-globals->leaf_mem_allocator_start;
|
||||
const float nodes_util = 100.0f * (float)(globals->node_mem_allocator_cur-globals->node_mem_allocator_start) / (node_size/64);
|
||||
const float leaves_util = 100.0f * (float)(globals->leaf_mem_allocator_cur-globals->leaf_mem_allocator_start) / (leaf_size/64);
|
||||
PRINT4(globals->node_mem_allocator_start,globals->node_mem_allocator_cur,nodes_used,nodes_util);
|
||||
PRINT4(globals->leaf_mem_allocator_start,globals->leaf_mem_allocator_cur,leaves_used,leaves_util);
|
||||
PRINT(globals->numLeaves);
|
||||
}
|
||||
|
||||
if (unlikely(convert_success == false))
|
||||
{
|
||||
if (args.accelBufferBytesOut) *args.accelBufferBytesOut = estimateAccelBufferSize(numQuads, numInstances, numProcedurals, true);
|
||||
if (host_device_tasks) sycl::free(host_device_tasks,gpu_queue.get_context());
|
||||
return RTHWIF_ERROR_RETRY;
|
||||
}
|
||||
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
{
|
||||
sycl::event queue_event = gpu_queue.submit([&](sycl::handler &cgh) {
|
||||
cgh.single_task([=]() {
|
||||
HWAccel* hwaccel = (HWAccel*)args.accelBuffer;
|
||||
hwaccel->dispatchGlobalsPtr = (uint64_t)args.dispatchGlobalsPtr;
|
||||
});
|
||||
});
|
||||
gpu::waitOnEventAndCatchException(queue_event);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (args.accelBufferBytesOut)
|
||||
*args.accelBufferBytesOut = args.accelBufferBytes;
|
||||
|
||||
#if 1
|
||||
if (verbose2)
|
||||
{
|
||||
gpu::waitOnQueueAndCatchException(gpu_queue);
|
||||
|
||||
qbvh->print(std::cout,qbvh->root(),0,6);
|
||||
BVHStatistics stats = qbvh->computeStatistics();
|
||||
stats.print(std::cout);
|
||||
stats.print_raw(std::cout);
|
||||
PRINT("VERBOSE STATS DONE");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (host_device_tasks) sycl::free(host_device_tasks,gpu_queue.get_context());
|
||||
|
||||
if (unlikely(verbose1))
|
||||
std::cout << "=> BVH build time: host = " << timer.get_total_host_time() << " ms , device = " << timer.get_total_device_time() << " ms , numPrimitives (original) = " << expected_numPrimitives << " , numPrimitives (build) = " << numPrimitives << std::endl;
|
||||
|
||||
return RTHWIF_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,8 +74,7 @@ namespace embree
|
||||
cout << " numBuildPrimitivesPostSplit = " << numBuildPrimitivesPostSplit << std::endl;
|
||||
cout << " primRefSplits = " << std::setprecision(2) << percent(numBuildPrimitivesPostSplit,numBuildPrimitives) << "%" << std::endl;
|
||||
cout << " numBVHPrimitives = " << totalPrimitives << std::endl;
|
||||
cout << " spatialSplits = " << std::setprecision(2) << percent(totalPrimitives,numScenePrimitives) << "%" << std::endl;
|
||||
cout << " maxDepth = " << depth << std::endl;
|
||||
cout << " spatialSplits = " << std::setprecision(2) << percent(totalPrimitives,numScenePrimitives) << "%" << std::endl;
|
||||
cout << std::endl;
|
||||
|
||||
cout << " #nodes SAH total bytes used total b/node b/child b/prim #child fill" << std::endl;
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ZE_RAYTRACING)
|
||||
#include "sys/platform.h"
|
||||
#else
|
||||
#include "../../../common/sys/platform.h"
|
||||
#endif
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -98,7 +102,7 @@ namespace embree
|
||||
};
|
||||
|
||||
BVHStatistics ()
|
||||
: numScenePrimitives(0), numBuildPrimitives(0), numBuildPrimitivesPostSplit(0), depth(1) {}
|
||||
: numScenePrimitives(0), numBuildPrimitives(0), numBuildPrimitivesPostSplit(0) {}
|
||||
|
||||
void print (std::ostream& cout) const;
|
||||
void print_raw(std::ostream& cout) const;
|
||||
@@ -106,7 +110,6 @@ namespace embree
|
||||
size_t numScenePrimitives;
|
||||
size_t numBuildPrimitives;
|
||||
size_t numBuildPrimitivesPostSplit;
|
||||
size_t depth;
|
||||
NodeStat internalNode;
|
||||
LeafStat quadLeaf;
|
||||
LeafStat proceduralLeaf;
|
||||
|
||||
@@ -0,0 +1,980 @@
|
||||
// Copyright 2009-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE ((ze_result_t)0x7ff00004) ///< [Core, Experimental] operands of comparison are not compatible
|
||||
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC ((ze_structure_type_t)0x0002000E) ///< ::ze_rtas_builder_exp_desc_t
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC ((ze_structure_type_t)0x0002000F) ///< ::ze_rtas_builder_build_op_exp_desc_t
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES ((ze_structure_type_t)0x00020010) ///< ::ze_rtas_builder_exp_properties_t
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES ((ze_structure_type_t)0x00020011) ///< ::ze_rtas_parallel_operation_exp_properties_t
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES ((ze_structure_type_t)0x00020012) ///< ::ze_rtas_device_exp_properties_t
|
||||
#define ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS ((ze_structure_type_t)0x00020013) ///< ::ze_rtas_geometry_aabbs_exp_cb_params_t
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_exp_desc_t
|
||||
typedef struct _ze_rtas_builder_exp_desc_t ze_rtas_builder_exp_desc_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_exp_properties_t
|
||||
typedef struct _ze_rtas_builder_exp_properties_t ze_rtas_builder_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_parallel_operation_exp_properties_t
|
||||
typedef struct _ze_rtas_parallel_operation_exp_properties_t ze_rtas_parallel_operation_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_device_exp_properties_t
|
||||
typedef struct _ze_rtas_device_exp_properties_t ze_rtas_device_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_float3_exp_t
|
||||
typedef struct _ze_rtas_float3_exp_t ze_rtas_float3_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_transform_float3x4_column_major_exp_t
|
||||
typedef struct _ze_rtas_transform_float3x4_column_major_exp_t ze_rtas_transform_float3x4_column_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_transform_float3x4_aligned_column_major_exp_t
|
||||
typedef struct _ze_rtas_transform_float3x4_aligned_column_major_exp_t ze_rtas_transform_float3x4_aligned_column_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_transform_float3x4_row_major_exp_t
|
||||
typedef struct _ze_rtas_transform_float3x4_row_major_exp_t ze_rtas_transform_float3x4_row_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_aabb_exp_t
|
||||
typedef struct _ze_rtas_aabb_exp_t ze_rtas_aabb_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_triangle_indices_uint32_exp_t
|
||||
typedef struct _ze_rtas_triangle_indices_uint32_exp_t ze_rtas_triangle_indices_uint32_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_quad_indices_uint32_exp_t
|
||||
typedef struct _ze_rtas_quad_indices_uint32_exp_t ze_rtas_quad_indices_uint32_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_geometry_info_exp_t
|
||||
typedef struct _ze_rtas_builder_geometry_info_exp_t ze_rtas_builder_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_triangles_geometry_info_exp_t
|
||||
typedef struct _ze_rtas_builder_triangles_geometry_info_exp_t ze_rtas_builder_triangles_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_quads_geometry_info_exp_t
|
||||
typedef struct _ze_rtas_builder_quads_geometry_info_exp_t ze_rtas_builder_quads_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_geometry_aabbs_exp_cb_params_t
|
||||
typedef struct _ze_rtas_geometry_aabbs_exp_cb_params_t ze_rtas_geometry_aabbs_exp_cb_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_procedural_geometry_info_exp_t
|
||||
typedef struct _ze_rtas_builder_procedural_geometry_info_exp_t ze_rtas_builder_procedural_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_instance_geometry_info_exp_t
|
||||
typedef struct _ze_rtas_builder_instance_geometry_info_exp_t ze_rtas_builder_instance_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Forward-declare ze_rtas_builder_build_op_exp_desc_t
|
||||
typedef struct _ze_rtas_builder_build_op_exp_desc_t ze_rtas_builder_build_op_exp_desc_t;
|
||||
|
||||
|
||||
// Intel 'oneAPI' Level-Zero Extension for supporting ray tracing acceleration structure builder.
|
||||
#if !defined(__GNUC__)
|
||||
#pragma region RTASBuilder
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ZE_RTAS_BUILDER_EXP_NAME
|
||||
/// @brief Ray Tracing Acceleration Structure Builder Extension Name
|
||||
#define ZE_RTAS_BUILDER_EXP_NAME "ZE_experimental_rtas_builder"
|
||||
#endif // ZE_RTAS_BUILDER_EXP_NAME
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray Tracing Acceleration Structure Builder Extension Version(s)
|
||||
typedef enum _ze_rtas_builder_exp_version_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0
|
||||
ZE_RTAS_BUILDER_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version
|
||||
ZE_RTAS_BUILDER_EXP_VERSION_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_exp_version_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure device flags
|
||||
typedef uint32_t ze_rtas_device_exp_flags_t;
|
||||
typedef enum _ze_rtas_device_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_DEVICE_EXP_FLAG_RESERVED = ZE_BIT(0), ///< reserved for future use
|
||||
ZE_RTAS_DEVICE_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_device_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure format
|
||||
///
|
||||
/// @details
|
||||
/// - This is an opaque ray tracing acceleration structure format
|
||||
/// identifier.
|
||||
typedef enum _ze_rtas_format_exp_t
|
||||
{
|
||||
ZE_RTAS_FORMAT_EXP_INVALID = 0, ///< Invalid acceleration structure format
|
||||
ZE_RTAS_FORMAT_EXP_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_format_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder flags
|
||||
typedef uint32_t ze_rtas_builder_exp_flags_t;
|
||||
typedef enum _ze_rtas_builder_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_EXP_FLAG_RESERVED = ZE_BIT(0), ///< Reserved for future use
|
||||
ZE_RTAS_BUILDER_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder parallel operation flags
|
||||
typedef uint32_t ze_rtas_parallel_operation_exp_flags_t;
|
||||
typedef enum _ze_rtas_parallel_operation_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_PARALLEL_OPERATION_EXP_FLAG_RESERVED = ZE_BIT(0), ///< Reserved for future use
|
||||
ZE_RTAS_PARALLEL_OPERATION_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_parallel_operation_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder geometry flags
|
||||
typedef uint32_t ze_rtas_builder_geometry_exp_flags_t;
|
||||
typedef enum _ze_rtas_builder_geometry_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE = ZE_BIT(0), ///< non-opaque geometries invoke an any-hit shader
|
||||
ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_geometry_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Packed ray tracing acceleration structure builder geometry flags (see
|
||||
/// ::ze_rtas_builder_geometry_exp_flags_t)
|
||||
typedef uint8_t ze_rtas_builder_packed_geometry_exp_flags_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder instance flags
|
||||
typedef uint32_t ze_rtas_builder_instance_exp_flags_t;
|
||||
typedef enum _ze_rtas_builder_instance_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_CULL_DISABLE = ZE_BIT(0),///< disables culling of front-facing and back-facing triangles
|
||||
ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = ZE_BIT(1), ///< reverses front and back face of triangles
|
||||
ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FORCE_OPAQUE = ZE_BIT(2),///< forces instanced geometry to be opaque, unless ray flag forces it to
|
||||
///< be non-opaque
|
||||
ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FORCE_NON_OPAQUE = ZE_BIT(3),///< forces instanced geometry to be non-opaque, unless ray flag forces it
|
||||
///< to be opaque
|
||||
ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_instance_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Packed ray tracing acceleration structure builder instance flags (see
|
||||
/// ::ze_rtas_builder_instance_exp_flags_t)
|
||||
typedef uint8_t ze_rtas_builder_packed_instance_exp_flags_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder build operation flags
|
||||
///
|
||||
/// @details
|
||||
/// - These flags allow the application to tune the acceleration structure
|
||||
/// build operation.
|
||||
/// - The acceleration structure builder implementation might choose to use
|
||||
/// spatial splitting to split large or long primitives into smaller
|
||||
/// pieces. This may result in any-hit shaders being invoked multiple
|
||||
/// times for non-opaque primitives, unless
|
||||
/// ::ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION is specified.
|
||||
/// - Usage of any of these flags may reduce ray tracing performance.
|
||||
typedef uint32_t ze_rtas_builder_build_op_exp_flags_t;
|
||||
typedef enum _ze_rtas_builder_build_op_exp_flag_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_COMPACT = ZE_BIT(0), ///< build more compact acceleration structure
|
||||
ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = ZE_BIT(1), ///< guarantees single any-hit shader invocation per primitive
|
||||
ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_build_op_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder build quality hint
|
||||
///
|
||||
/// @details
|
||||
/// - Depending on use case different quality modes for acceleration
|
||||
/// structure build are supported.
|
||||
/// - A low-quality build builds an acceleration structure fast, but at the
|
||||
/// cost of some reduction in ray tracing performance. This mode is
|
||||
/// recommended for dynamic content, such as animated characters.
|
||||
/// - A medium-quality build uses a compromise between build quality and ray
|
||||
/// tracing performance. This mode should be used by default.
|
||||
/// - Higher ray tracing performance can be achieved by using a high-quality
|
||||
/// build, but acceleration structure build performance might be
|
||||
/// significantly reduced.
|
||||
typedef enum _ze_rtas_builder_build_quality_hint_exp_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_LOW = 0, ///< build low-quality acceleration structure (fast)
|
||||
ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM = 1, ///< build medium-quality acceleration structure (slower)
|
||||
ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH = 2,///< build high-quality acceleration structure (slow)
|
||||
ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_build_quality_hint_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder geometry type
|
||||
typedef enum _ze_rtas_builder_geometry_type_exp_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES = 0,///< triangle mesh geometry type
|
||||
ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS = 1, ///< quad mesh geometry type
|
||||
ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL = 2, ///< procedural geometry type
|
||||
ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE = 3, ///< instance geometry type
|
||||
ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_geometry_type_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Packed ray tracing acceleration structure builder geometry type (see
|
||||
/// ::ze_rtas_builder_geometry_type_exp_t)
|
||||
typedef uint8_t ze_rtas_builder_packed_geometry_type_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure data buffer element format
|
||||
///
|
||||
/// @details
|
||||
/// - Specifies the format of data buffer elements.
|
||||
/// - Data buffers may contain instancing transform matrices, triangle/quad
|
||||
/// vertex indices, etc...
|
||||
typedef enum _ze_rtas_builder_input_data_format_exp_t
|
||||
{
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3 = 0, ///< 3-component float vector (see ::ze_rtas_float3_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_COLUMN_MAJOR = 1,///< 3x4 affine transformation in column-major format (see
|
||||
///< ::ze_rtas_transform_float3x4_column_major_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR = 2,///< 3x4 affine transformation in column-major format (see
|
||||
///< ::ze_rtas_transform_float3x4_aligned_column_major_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ROW_MAJOR = 3, ///< 3x4 affine transformation in row-major format (see
|
||||
///< ::ze_rtas_transform_float3x4_row_major_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_AABB = 4, ///< 3-dimensional axis-aligned bounding-box (see ::ze_rtas_aabb_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32 = 5, ///< Unsigned 32-bit triangle indices (see
|
||||
///< ::ze_rtas_triangle_indices_uint32_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32 = 6, ///< Unsigned 32-bit quad indices (see ::ze_rtas_quad_indices_uint32_exp_t)
|
||||
ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_rtas_builder_input_data_format_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Packed ray tracing acceleration structure data buffer element format
|
||||
/// (see ::ze_rtas_builder_input_data_format_exp_t)
|
||||
typedef uint8_t ze_rtas_builder_packed_input_data_format_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Handle of ray tracing acceleration structure builder object
|
||||
typedef struct _ze_rtas_builder_exp_handle_t *ze_rtas_builder_exp_handle_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Handle of ray tracing acceleration structure builder parallel
|
||||
/// operation object
|
||||
typedef struct _ze_rtas_parallel_operation_exp_handle_t *ze_rtas_parallel_operation_exp_handle_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder descriptor
|
||||
typedef struct _ze_rtas_builder_exp_desc_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_rtas_builder_exp_version_t builderVersion; ///< [in] ray tracing acceleration structure builder version
|
||||
|
||||
} ze_rtas_builder_exp_desc_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder properties
|
||||
typedef struct _ze_rtas_builder_exp_properties_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_rtas_builder_exp_flags_t flags; ///< [out] ray tracing acceleration structure builder flags
|
||||
size_t rtasBufferSizeBytesExpected; ///< [out] expected size (in bytes) required for acceleration structure buffer
|
||||
///< - When using an acceleration structure buffer of this size, the
|
||||
///< build is expected to succeed; however, it is possible that the build
|
||||
///< may fail with ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
size_t rtasBufferSizeBytesMaxRequired; ///< [out] worst-case size (in bytes) required for acceleration structure buffer
|
||||
///< - When using an acceleration structure buffer of this size, the
|
||||
///< build is guaranteed to not run out of memory.
|
||||
size_t scratchBufferSizeBytes; ///< [out] scratch buffer size (in bytes) required for acceleration
|
||||
///< structure build.
|
||||
|
||||
} ze_rtas_builder_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder parallel operation
|
||||
/// properties
|
||||
typedef struct _ze_rtas_parallel_operation_exp_properties_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_rtas_parallel_operation_exp_flags_t flags; ///< [out] ray tracing acceleration structure builder parallel operation
|
||||
///< flags
|
||||
uint32_t maxConcurrency; ///< [out] maximum number of threads that may join the parallel operation
|
||||
|
||||
} ze_rtas_parallel_operation_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure device properties
|
||||
///
|
||||
/// @details
|
||||
/// - This structure may be passed to ::zeDeviceGetProperties, via `pNext`
|
||||
/// member of ::ze_device_properties_t.
|
||||
/// - The implementation shall populate `format` with a value other than
|
||||
/// ::ZE_RTAS_FORMAT_EXP_INVALID when the device supports ray tracing.
|
||||
typedef struct _ze_rtas_device_exp_properties_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_rtas_device_exp_flags_t flags; ///< [out] ray tracing acceleration structure device flags
|
||||
ze_rtas_format_exp_t rtasFormat; ///< [out] ray tracing acceleration structure format
|
||||
uint32_t rtasBufferAlignment; ///< [out] required alignment of acceleration structure buffer
|
||||
|
||||
} ze_rtas_device_exp_properties_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A 3-component vector type
|
||||
typedef struct _ze_rtas_float3_exp_t
|
||||
{
|
||||
float x; ///< [in] x-coordinate of float3 vector
|
||||
float y; ///< [in] y-coordinate of float3 vector
|
||||
float z; ///< [in] z-coordinate of float3 vector
|
||||
|
||||
} ze_rtas_float3_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3x4 affine transformation in column-major layout
|
||||
///
|
||||
/// @details
|
||||
/// - A 3x4 affine transformation in column major layout, consisting of vectors
|
||||
/// - vx=(vx_x, vx_y, vx_z),
|
||||
/// - vy=(vy_x, vy_y, vy_z),
|
||||
/// - vz=(vz_x, vz_y, vz_z), and
|
||||
/// - p=(p_x, p_y, p_z)
|
||||
/// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy +
|
||||
/// z*vz + p`.
|
||||
typedef struct _ze_rtas_transform_float3x4_column_major_exp_t
|
||||
{
|
||||
float vx_x; ///< [in] element 0 of column 0 of 3x4 matrix
|
||||
float vx_y; ///< [in] element 1 of column 0 of 3x4 matrix
|
||||
float vx_z; ///< [in] element 2 of column 0 of 3x4 matrix
|
||||
float vy_x; ///< [in] element 0 of column 1 of 3x4 matrix
|
||||
float vy_y; ///< [in] element 1 of column 1 of 3x4 matrix
|
||||
float vy_z; ///< [in] element 2 of column 1 of 3x4 matrix
|
||||
float vz_x; ///< [in] element 0 of column 2 of 3x4 matrix
|
||||
float vz_y; ///< [in] element 1 of column 2 of 3x4 matrix
|
||||
float vz_z; ///< [in] element 2 of column 2 of 3x4 matrix
|
||||
float p_x; ///< [in] element 0 of column 3 of 3x4 matrix
|
||||
float p_y; ///< [in] element 1 of column 3 of 3x4 matrix
|
||||
float p_z; ///< [in] element 2 of column 3 of 3x4 matrix
|
||||
|
||||
} ze_rtas_transform_float3x4_column_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3x4 affine transformation in column-major layout with aligned column
|
||||
/// vectors
|
||||
///
|
||||
/// @details
|
||||
/// - A 3x4 affine transformation in column major layout, consisting of vectors
|
||||
/// - vx=(vx_x, vx_y, vx_z),
|
||||
/// - vy=(vy_x, vy_y, vy_z),
|
||||
/// - vz=(vz_x, vz_y, vz_z), and
|
||||
/// - p=(p_x, p_y, p_z)
|
||||
/// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy +
|
||||
/// z*vz + p`.
|
||||
/// - The column vectors are aligned to 16-bytes and pad members are
|
||||
/// ignored.
|
||||
typedef struct _ze_rtas_transform_float3x4_aligned_column_major_exp_t
|
||||
{
|
||||
float vx_x; ///< [in] element 0 of column 0 of 3x4 matrix
|
||||
float vx_y; ///< [in] element 1 of column 0 of 3x4 matrix
|
||||
float vx_z; ///< [in] element 2 of column 0 of 3x4 matrix
|
||||
float pad0; ///< [in] ignored padding
|
||||
float vy_x; ///< [in] element 0 of column 1 of 3x4 matrix
|
||||
float vy_y; ///< [in] element 1 of column 1 of 3x4 matrix
|
||||
float vy_z; ///< [in] element 2 of column 1 of 3x4 matrix
|
||||
float pad1; ///< [in] ignored padding
|
||||
float vz_x; ///< [in] element 0 of column 2 of 3x4 matrix
|
||||
float vz_y; ///< [in] element 1 of column 2 of 3x4 matrix
|
||||
float vz_z; ///< [in] element 2 of column 2 of 3x4 matrix
|
||||
float pad2; ///< [in] ignored padding
|
||||
float p_x; ///< [in] element 0 of column 3 of 3x4 matrix
|
||||
float p_y; ///< [in] element 1 of column 3 of 3x4 matrix
|
||||
float p_z; ///< [in] element 2 of column 3 of 3x4 matrix
|
||||
float pad3; ///< [in] ignored padding
|
||||
|
||||
} ze_rtas_transform_float3x4_aligned_column_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3x4 affine transformation in row-major layout
|
||||
///
|
||||
/// @details
|
||||
/// - A 3x4 affine transformation in row-major layout, consisting of vectors
|
||||
/// - vx=(vx_x, vx_y, vx_z),
|
||||
/// - vy=(vy_x, vy_y, vy_z),
|
||||
/// - vz=(vz_x, vz_y, vz_z), and
|
||||
/// - p=(p_x, p_y, p_z)
|
||||
/// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy +
|
||||
/// z*vz + p`.
|
||||
typedef struct _ze_rtas_transform_float3x4_row_major_exp_t
|
||||
{
|
||||
float vx_x; ///< [in] element 0 of row 0 of 3x4 matrix
|
||||
float vy_x; ///< [in] element 1 of row 0 of 3x4 matrix
|
||||
float vz_x; ///< [in] element 2 of row 0 of 3x4 matrix
|
||||
float p_x; ///< [in] element 3 of row 0 of 3x4 matrix
|
||||
float vx_y; ///< [in] element 0 of row 1 of 3x4 matrix
|
||||
float vy_y; ///< [in] element 1 of row 1 of 3x4 matrix
|
||||
float vz_y; ///< [in] element 2 of row 1 of 3x4 matrix
|
||||
float p_y; ///< [in] element 3 of row 1 of 3x4 matrix
|
||||
float vx_z; ///< [in] element 0 of row 2 of 3x4 matrix
|
||||
float vy_z; ///< [in] element 1 of row 2 of 3x4 matrix
|
||||
float vz_z; ///< [in] element 2 of row 2 of 3x4 matrix
|
||||
float p_z; ///< [in] element 3 of row 2 of 3x4 matrix
|
||||
|
||||
} ze_rtas_transform_float3x4_row_major_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A 3-dimensional axis-aligned bounding-box with lower and upper bounds
|
||||
/// in each dimension
|
||||
typedef struct _ze_rtas_aabb_exp_t
|
||||
{
|
||||
ze_rtas_float3_exp_t lower; ///< [in] lower bounds of AABB
|
||||
ze_rtas_float3_exp_t upper; ///< [in] upper bounds of AABB
|
||||
|
||||
} ze_rtas_aabb_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Triangle represented using 3 vertex indices
|
||||
///
|
||||
/// @details
|
||||
/// - Represents a triangle using 3 vertex indices that index into a vertex
|
||||
/// array that needs to be provided together with the index array.
|
||||
/// - The linear barycentric u/v parametrization of the triangle is defined as:
|
||||
/// - (u=0, v=0) at v0,
|
||||
/// - (u=1, v=0) at v1, and
|
||||
/// - (u=0, v=1) at v2
|
||||
typedef struct _ze_rtas_triangle_indices_uint32_exp_t
|
||||
{
|
||||
uint32_t v0; ///< [in] first index pointing to the first triangle vertex in vertex array
|
||||
uint32_t v1; ///< [in] second index pointing to the second triangle vertex in vertex
|
||||
///< array
|
||||
uint32_t v2; ///< [in] third index pointing to the third triangle vertex in vertex array
|
||||
|
||||
} ze_rtas_triangle_indices_uint32_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Quad represented using 4 vertex indices
|
||||
///
|
||||
/// @details
|
||||
/// - Represents a quad composed of 4 indices that index into a vertex array
|
||||
/// that needs to be provided together with the index array.
|
||||
/// - A quad is a triangle pair represented using 4 vertex indices v0, v1,
|
||||
/// v2, v3.
|
||||
/// The first triangle is made out of indices v0, v1, v3 and the second triangle
|
||||
/// from indices v2, v3, v1. The piecewise linear barycentric u/v parametrization
|
||||
/// of the quad is defined as:
|
||||
/// - (u=0, v=0) at v0,
|
||||
/// - (u=1, v=0) at v1,
|
||||
/// - (u=0, v=1) at v3, and
|
||||
/// - (u=1, v=1) at v2
|
||||
/// This is achieved by correcting the u'/v' coordinates of the second
|
||||
/// triangle by
|
||||
/// *u = 1-u'* and *v = 1-v'*, yielding a piecewise linear parametrization.
|
||||
typedef struct _ze_rtas_quad_indices_uint32_exp_t
|
||||
{
|
||||
uint32_t v0; ///< [in] first index pointing to the first quad vertex in vertex array
|
||||
uint32_t v1; ///< [in] second index pointing to the second quad vertex in vertex array
|
||||
uint32_t v2; ///< [in] third index pointing to the third quad vertex in vertex array
|
||||
uint32_t v3; ///< [in] fourth index pointing to the fourth quad vertex in vertex array
|
||||
|
||||
} ze_rtas_quad_indices_uint32_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder geometry info
|
||||
typedef struct _ze_rtas_builder_geometry_info_exp_t
|
||||
{
|
||||
ze_rtas_builder_packed_geometry_type_exp_t geometryType;///< [in] geometry type
|
||||
|
||||
} ze_rtas_builder_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder triangle mesh geometry info
|
||||
///
|
||||
/// @details
|
||||
/// - The linear barycentric u/v parametrization of the triangle is defined as:
|
||||
/// - (u=0, v=0) at v0,
|
||||
/// - (u=1, v=0) at v1, and
|
||||
/// - (u=0, v=1) at v2
|
||||
typedef struct _ze_rtas_builder_triangles_geometry_info_exp_t
|
||||
{
|
||||
ze_rtas_builder_packed_geometry_type_exp_t geometryType;///< [in] geometry type, must be
|
||||
///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES
|
||||
ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t
|
||||
///< bits representing the geometry flags for all primitives of this
|
||||
///< geometry
|
||||
uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; ///< [in] reserved for future use
|
||||
uint8_t reserved1; ///< [in] reserved for future use
|
||||
uint8_t reserved2; ///< [in] reserved for future use
|
||||
ze_rtas_builder_packed_input_data_format_exp_t triangleFormat; ///< [in] format of triangle buffer data, must be
|
||||
///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32
|
||||
ze_rtas_builder_packed_input_data_format_exp_t vertexFormat;///< [in] format of vertex buffer data, must be
|
||||
///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3
|
||||
uint32_t triangleCount; ///< [in] number of triangles in triangle buffer
|
||||
uint32_t vertexCount; ///< [in] number of vertices in vertex buffer
|
||||
uint32_t triangleStride; ///< [in] stride (in bytes) of triangles in triangle buffer
|
||||
uint32_t vertexStride; ///< [in] stride (in bytes) of vertices in vertex buffer
|
||||
void* pTriangleBuffer; ///< [in] pointer to array of triangle indices in specified format
|
||||
void* pVertexBuffer; ///< [in] pointer to array of triangle vertices in specified format
|
||||
|
||||
} ze_rtas_builder_triangles_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder quad mesh geometry info
|
||||
///
|
||||
/// @details
|
||||
/// - A quad is a triangle pair represented using 4 vertex indices v0, v1,
|
||||
/// v2, v3.
|
||||
/// The first triangle is made out of indices v0, v1, v3 and the second triangle
|
||||
/// from indices v2, v3, v1. The piecewise linear barycentric u/v parametrization
|
||||
/// of the quad is defined as:
|
||||
/// - (u=0, v=0) at v0,
|
||||
/// - (u=1, v=0) at v1,
|
||||
/// - (u=0, v=1) at v3, and
|
||||
/// - (u=1, v=1) at v2
|
||||
/// This is achieved by correcting the u'/v' coordinates of the second
|
||||
/// triangle by
|
||||
/// *u = 1-u'* and *v = 1-v'*, yielding a piecewise linear parametrization.
|
||||
typedef struct _ze_rtas_builder_quads_geometry_info_exp_t
|
||||
{
|
||||
ze_rtas_builder_packed_geometry_type_exp_t geometryType;///< [in] geometry type, must be ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS
|
||||
ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t
|
||||
///< bits representing the geometry flags for all primitives of this
|
||||
///< geometry
|
||||
uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking
|
||||
uint8_t reserved0; ///< [in] reserved for future use
|
||||
uint8_t reserved1; ///< [in] reserved for future use
|
||||
uint8_t reserved2; ///< [in] reserved for future use
|
||||
ze_rtas_builder_packed_input_data_format_exp_t quadFormat; ///< [in] format of quad buffer data, must be
|
||||
///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32
|
||||
ze_rtas_builder_packed_input_data_format_exp_t vertexFormat;///< [in] format of vertex buffer data, must be
|
||||
///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3
|
||||
uint32_t quadCount; ///< [in] number of quads in quad buffer
|
||||
uint32_t vertexCount; ///< [in] number of vertices in vertex buffer
|
||||
uint32_t quadStride; ///< [in] stride (in bytes) of quads in quad buffer
|
||||
uint32_t vertexStride; ///< [in] stride (in bytes) of vertices in vertex buffer
|
||||
void* pQuadBuffer; ///< [in] pointer to array of quad indices in specified format
|
||||
void* pVertexBuffer; ///< [in] pointer to array of quad vertices in specified format
|
||||
|
||||
} ze_rtas_builder_quads_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief AABB callback function parameters
|
||||
typedef struct _ze_rtas_geometry_aabbs_exp_cb_params_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
uint32_t primID; ///< [in] first primitive to return bounds for
|
||||
uint32_t primIDCount; ///< [in] number of primitives to return bounds for
|
||||
void* pGeomUserPtr; ///< [in] pointer provided through geometry descriptor
|
||||
void* pBuildUserPtr; ///< [in] pointer provided through ::zeRTASBuilderBuildExp function
|
||||
ze_rtas_aabb_exp_t* pBoundsOut; ///< [out] destination buffer to write AABB bounds to
|
||||
|
||||
} ze_rtas_geometry_aabbs_exp_cb_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Callback function pointer type to return AABBs for a range of
|
||||
/// procedural primitives
|
||||
typedef void (*ze_rtas_geometry_aabbs_cb_exp_t)(
|
||||
ze_rtas_geometry_aabbs_exp_cb_params_t* params ///< [in] callback function parameters structure
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder procedural primitives
|
||||
/// geometry info
|
||||
///
|
||||
/// @details
|
||||
/// - A host-side bounds callback function is invoked by the acceleration
|
||||
/// structure builder to query the bounds of procedural primitives on
|
||||
/// demand. The callback is passed some `pGeomUserPtr` that can point to
|
||||
/// an application-side representation of the procedural primitives.
|
||||
/// Further, a second `pBuildUserPtr`, which is set by a parameter to
|
||||
/// ::zeRTASBuilderBuildExp, is passed to the callback. This allows the
|
||||
/// build to change the bounds of the procedural geometry, for example, to
|
||||
/// build a BVH only over a short time range to implement multi-segment
|
||||
/// motion blur.
|
||||
typedef struct _ze_rtas_builder_procedural_geometry_info_exp_t
|
||||
{
|
||||
ze_rtas_builder_packed_geometry_type_exp_t geometryType;///< [in] geometry type, must be
|
||||
///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL
|
||||
ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t
|
||||
///< bits representing the geometry flags for all primitives of this
|
||||
///< geometry
|
||||
uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking
|
||||
uint8_t reserved; ///< [in] reserved for future use
|
||||
uint32_t primCount; ///< [in] number of primitives in geometry
|
||||
ze_rtas_geometry_aabbs_cb_exp_t pfnGetBoundsCb; ///< [in] pointer to callback function to get the axis-aligned bounding-box
|
||||
///< for a range of primitives
|
||||
void* pGeomUserPtr; ///< [in] user data pointer passed to callback
|
||||
|
||||
} ze_rtas_builder_procedural_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ray tracing acceleration structure builder instance geometry info
|
||||
typedef struct _ze_rtas_builder_instance_geometry_info_exp_t
|
||||
{
|
||||
ze_rtas_builder_packed_geometry_type_exp_t geometryType;///< [in] geometry type, must be
|
||||
///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE
|
||||
ze_rtas_builder_packed_instance_exp_flags_t instanceFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t
|
||||
///< bits representing the geometry flags for all primitives of this
|
||||
///< geometry
|
||||
uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking
|
||||
ze_rtas_builder_packed_input_data_format_exp_t transformFormat; ///< [in] format of the specified transformation
|
||||
uint32_t instanceUserID; ///< [in] user-specified identifier for the instance
|
||||
void* pTransform; ///< [in] object-to-world instance transformation in specified format
|
||||
ze_rtas_aabb_exp_t* pBounds; ///< [in] object-space axis-aligned bounding-box of the instanced
|
||||
///< acceleration structure
|
||||
void* pAccelerationStructure; ///< [in] pointer to acceleration structure to instantiate
|
||||
|
||||
} ze_rtas_builder_instance_geometry_info_exp_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief
|
||||
typedef struct _ze_rtas_builder_build_op_exp_desc_t
|
||||
{
|
||||
ze_structure_type_t stype; ///< [in] type of this structure
|
||||
const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_rtas_format_exp_t rtasFormat; ///< [in] ray tracing acceleration structure format
|
||||
ze_rtas_builder_build_quality_hint_exp_t buildQuality; ///< [in] acceleration structure build quality hint
|
||||
ze_rtas_builder_build_op_exp_flags_t buildFlags;///< [in] 0 or some combination of ::ze_rtas_builder_build_op_exp_flag_t
|
||||
///< flags
|
||||
const ze_rtas_builder_geometry_info_exp_t** ppGeometries; ///< [in][optional][range(0, `numGeometries`)] NULL or a valid array of
|
||||
///< pointers to geometry infos
|
||||
uint32_t numGeometries; ///< [in] number of geometries in geometry infos array, can be zero when
|
||||
///< `ppGeometries` is NULL
|
||||
|
||||
/* for debugging purposes use only */
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
void* dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
} ze_rtas_builder_build_op_exp_desc_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Creates a ray tracing acceleration structure builder object
|
||||
///
|
||||
/// @details
|
||||
/// - The application may call this function from simultaneous threads.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
/// - The implementation must support ::ZE_experimental_rtas_builder
|
||||
/// extension.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hDriver`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER
|
||||
/// + `nullptr == pDescriptor`
|
||||
/// + `nullptr == phBuilder`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION
|
||||
/// + `::ZE_RTAS_BUILDER_EXP_VERSION_CURRENT < pDescriptor->builderVersion`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASBuilderCreateExp(
|
||||
ze_driver_handle_t hDriver, ///< [in] handle of driver object
|
||||
const ze_rtas_builder_exp_desc_t* pDescriptor, ///< [in] pointer to builder descriptor
|
||||
ze_rtas_builder_exp_handle_t* phBuilder ///< [out] handle of builder object
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves ray tracing acceleration structure builder properties
|
||||
///
|
||||
/// @details
|
||||
/// - The application may call this function from simultaneous threads.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hBuilder`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER
|
||||
/// + `nullptr == pBuildOpDescriptor`
|
||||
/// + `nullptr == pProperties`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION
|
||||
/// + `::ZE_RTAS_FORMAT_EXP_INVALID < pBuildOpDescriptor->rtasFormat`
|
||||
/// + `::ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < pBuildOpDescriptor->buildQuality`
|
||||
/// + `0x3 < pBuildOpDescriptor->buildFlags`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASBuilderGetBuildPropertiesExp(
|
||||
ze_rtas_builder_exp_handle_t hBuilder, ///< [in] handle of builder object
|
||||
const ze_rtas_builder_build_op_exp_desc_t* pBuildOpDescriptor, ///< [in] pointer to build operation descriptor
|
||||
ze_rtas_builder_exp_properties_t* pProperties ///< [in,out] query result for builder properties
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks ray tracing acceleration structure format compatibility
|
||||
///
|
||||
/// @details
|
||||
/// - The application may call this function from simultaneous threads.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hBuilder`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION
|
||||
/// + `::ZE_RTAS_FORMAT_EXP_INVALID < rtasFormatA`
|
||||
/// + `::ZE_RTAS_FORMAT_EXP_INVALID < rtasFormatB`
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// + An acceleration structure built with `rtasFormatA` is compatible with devices that report `rtasFormatB`.
|
||||
/// - ::ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE
|
||||
/// + An acceleration structure built with `rtasFormatA` is **not** compatible with devices that report `rtasFormatB`.
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASBuilderFormatCompatibilityCheckExp(
|
||||
ze_rtas_builder_exp_handle_t hBuilder, ///< [in] handle of builder object
|
||||
ze_rtas_format_exp_t rtasFormatA, ///< [in] operand A
|
||||
ze_rtas_format_exp_t rtasFormatB ///< [in] operand B
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Build ray tracing acceleration structure
|
||||
///
|
||||
/// @details
|
||||
/// - This function builds an acceleration structure of the scene consisting
|
||||
/// of the specified geometry information and writes the acceleration
|
||||
/// structure to the provided destination buffer. All types of geometries
|
||||
/// can get freely mixed inside a scene.
|
||||
/// - It is the user's responsibility to manage the acceleration structure
|
||||
/// buffer allocation, de-allocation, and potential prefetching to the
|
||||
/// device memory. The required size of the acceleration structure buffer
|
||||
/// can be queried with the ::zeRTASBuilderGetPropertiesExp function. The
|
||||
/// acceleration structure buffer must be a shared USM allocation and
|
||||
/// should be present on the host at build time. The referenced scene data
|
||||
/// (index- and vertex- buffers) can be standard host allocations, and
|
||||
/// will not be referenced into by the build acceleration structure.
|
||||
/// - Before an acceleration structure can be built, the user must allocate
|
||||
/// the memory for the acceleration structure buffer and scratch buffer
|
||||
/// using sizes based on a query for the estimated size properties.
|
||||
/// - When using the "worst-case" size for the acceleration structure
|
||||
/// buffer, the acceleration structure construction will never fail with
|
||||
/// an out-of-memory error.
|
||||
/// - When using the "expected" size for the acceleration structure buffer,
|
||||
/// the acceleration structure construction may fail with
|
||||
/// ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY. If this happens, the user may
|
||||
/// resize their acceleration structure buffer using the
|
||||
/// `*pRtasBufferSizeBytes` value, which will be updated with an improved
|
||||
/// size estimate that will likely result in a successful build.
|
||||
/// - The acceleration structure construction is run on the host and is
|
||||
/// synchronous, thus after the function returns with a successful result,
|
||||
/// the acceleration structure may be used.
|
||||
/// - All provided data buffers must be host-accessible.
|
||||
/// - The acceleration structure buffer must be a USM allocation.
|
||||
/// - A successfully constructed acceleration structure is entirely
|
||||
/// self-contained. There is no requirement for input data to persist
|
||||
/// beyond build completion.
|
||||
/// - A successfully constructed acceleration structure is non-copyable.
|
||||
/// - Acceleration structure construction may be parallelized by passing a
|
||||
/// valid handle to a parallel operation object and joining that parallel
|
||||
/// operation using ::zeRTASParallelOperationJoinExp with user-provided
|
||||
/// worker threads.
|
||||
/// - **Additional Notes**
|
||||
/// - "The geometry infos array, geometry infos, and scratch buffer must
|
||||
/// all be standard host memory allocations."
|
||||
/// - "A pointer to a geometry info can be a null pointer, in which case
|
||||
/// the geometry is treated as empty."
|
||||
/// - "If no parallel operation handle is provided, the build is run
|
||||
/// sequentially on the current thread."
|
||||
/// - "A parallel operation object may only be associated with a single
|
||||
/// acceleration structure build at a time."
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hBuilder`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER
|
||||
/// + `nullptr == pBuildOpDescriptor`
|
||||
/// + `nullptr == pScratchBuffer`
|
||||
/// + `nullptr == pRtasBuffer`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION
|
||||
/// + `::ZE_RTAS_FORMAT_EXP_INVALID < pBuildOpDescriptor->rtasFormat`
|
||||
/// + `::ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < pBuildOpDescriptor->buildQuality`
|
||||
/// + `0x3 < pBuildOpDescriptor->buildFlags`
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// + Acceleration structure build failed due to insufficient resources
|
||||
/// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE
|
||||
/// + Acceleration structure build failed due to parallel operation object participation in another build operation.
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASBuilderBuildExp(
|
||||
ze_rtas_builder_exp_handle_t hBuilder, ///< [in] handle of builder object
|
||||
const ze_rtas_builder_build_op_exp_desc_t* pBuildOpDescriptor, ///< [in] pointer to build operation descriptor
|
||||
void* pScratchBuffer, ///< [in][range(0, `scratchBufferSizeBytes`)] scratch buffer to be used
|
||||
///< during acceleration structure construction
|
||||
size_t scratchBufferSizeBytes, ///< [in] size of scratch buffer, in bytes
|
||||
void* pRtasBuffer, ///< [in] pointer to destination buffer
|
||||
size_t rtasBufferSizeBytes, ///< [in] destination buffer size, in bytes
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ///< [in][optional] handle to parallel operation object
|
||||
void* pBuildUserPtr, ///< [in][optional] pointer passed to callbacks
|
||||
ze_rtas_aabb_exp_t* pBounds, ///< [in,out][optional] pointer to destination address for acceleration
|
||||
///< structure bounds
|
||||
size_t* pRtasBufferSizeBytes ///< [out][optional] updated acceleration structure size requirement, in
|
||||
///< bytes
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Destroys a ray tracing acceleration structure builder object
|
||||
///
|
||||
/// @details
|
||||
/// - The application must destroy all the parallel operation handles
|
||||
/// created from the builder before destroying the builder itself.
|
||||
/// - The implementation of this function may immediately release any
|
||||
/// internal Host and Device resources associated with this builder.
|
||||
/// - The application must **not** call this function from simultaneous
|
||||
/// threads with the same builder handle.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hBuilder`
|
||||
/// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASBuilderDestroyExp(
|
||||
ze_rtas_builder_exp_handle_t hBuilder ///< [in][release] handle of builder object to destroy
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Creates a ray tracing acceleration structure builder parallel
|
||||
/// operation object
|
||||
///
|
||||
/// @details
|
||||
/// - The application may call this function from simultaneous threads.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
/// - The implementation must support ::ZE_experimental_rtas_builder
|
||||
/// extension.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hDriver`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER
|
||||
/// + `nullptr == phParallelOperation`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASParallelOperationCreateExp(
|
||||
ze_driver_handle_t hDriver, ///< [in] handle of driver object
|
||||
ze_rtas_parallel_operation_exp_handle_t* phParallelOperation///< [out] handle of parallel operation object
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves ray tracing acceleration structure builder parallel
|
||||
/// operation properties
|
||||
///
|
||||
/// @details
|
||||
/// - The application may call this function from simultaneous threads.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hParallelOperation`
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER
|
||||
/// + `nullptr == pProperties`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASParallelOperationGetPropertiesExp(
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ///< [in] handle of parallel operation object
|
||||
ze_rtas_parallel_operation_exp_properties_t* pProperties///< [in,out] query result for parallel operation properties
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Joins a parallel build operation
|
||||
///
|
||||
/// @details
|
||||
/// - All worker threads return the same error code for the parallel build
|
||||
/// operation upon build completion
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hParallelOperation`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASParallelOperationJoinExp(
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation ///< [in] handle of parallel operation object
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Destroys a ray tracing acceleration structure builder parallel
|
||||
/// operation object
|
||||
///
|
||||
/// @details
|
||||
/// - The implementation of this function may immediately release any
|
||||
/// internal Host and Device resources associated with this parallel
|
||||
/// operation.
|
||||
/// - The application must **not** call this function from simultaneous
|
||||
/// threads with the same parallel operation handle.
|
||||
/// - The implementation of this function must be thread-safe.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::ZE_RESULT_SUCCESS
|
||||
/// - ::ZE_RESULT_ERROR_UNINITIALIZED
|
||||
/// - ::ZE_RESULT_ERROR_DEVICE_LOST
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY
|
||||
/// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE
|
||||
/// + `nullptr == hParallelOperation`
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeRTASParallelOperationDestroyExp(
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation ///< [in][release] handle of parallel operation object to destroy
|
||||
);
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
#pragma endregion
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(EMBREE_SYCL_RT_VALIDATION_API)
|
||||
# include "rttrace_validation.h"
|
||||
#else
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
@@ -255,3 +259,4 @@ inline bool intel_has_committed_hit( intel_ray_query_t query ) { return false; }
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#endif
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "rthwif_production.h"
|
||||
#include "rthwif_internal.h"
|
||||
#include "rttrace_validation.h"
|
||||
|
||||
#define sizeof_QBVH6_InternalNode6 64
|
||||
#define QBVH6_rootNodeOffset 128
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rthwif_internal.h"
|
||||
#include "rttrace_internal.h"
|
||||
|
||||
enum intel_ray_flags_t
|
||||
{
|
||||
@@ -14,18 +14,6 @@ IF (NOT DEFINED EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
OPTION(EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS "Using L0 allocated Dispatch Globals" ON)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS")
|
||||
ENDIF()
|
||||
|
||||
#ADD_EXECUTABLE(rthwif_cornell_box rthwif_cornell_box.cpp ../rthwif_production.cpp)
|
||||
#SET_PROPERTY(TARGET rthwif_cornell_box APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64 -DEMBREE_SYCL_SUPPORT")
|
||||
#SET_PROPERTY(TARGET rthwif_cornell_box APPEND PROPERTY LINK_FLAGS "-fsycl -lze_loader")
|
||||
|
||||
#ADD_EXECUTABLE(rthwif_test rthwif_test.cpp ../rthwif_production.cpp)
|
||||
#TARGET_LINK_LIBRARIES(rthwif_test embree_rthwif sys tbb)
|
||||
#TARGET_LINK_LIBRARIES(rthwif_test embree_rthwif_gpu sys tbb)
|
||||
|
||||
IF (NOT DEFINED EMBREE_SYCL_RT_VALIDATION_API)
|
||||
OPTION(EMBREE_SYCL_RT_VALIDATION_API "Use rt_validation API instead of IGC provided rt_production API" OFF)
|
||||
ENDIF()
|
||||
@@ -34,6 +22,10 @@ IF (EMBREE_SYCL_RT_VALIDATION_API)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_RT_VALIDATION_API")
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_SYCL_RT_VALIDATION_API AND NOT EMBREE_SYCL_IMPLICIT_DISPATCH_GLOBALS)
|
||||
ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS")
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_SYCL_RT_SIMULATION)
|
||||
SET(RT_SIM_LIBRARY rtcore)
|
||||
ENDIF()
|
||||
@@ -43,21 +35,8 @@ TARGET_LINK_LIBRARIES(embree_rthwif_cornell_box embree_rthwif sys simd ${TBB_TAR
|
||||
SET_PROPERTY(TARGET embree_rthwif_cornell_box APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64 -DEMBREE_SYCL_SUPPORT")
|
||||
SET_PROPERTY(TARGET embree_rthwif_cornell_box APPEND PROPERTY LINK_FLAGS "-fsycl -lze_loader -fsycl-targets=spir64 -Xsycl-target-backend=spir64 \" -cl-intel-greater-than-4GB-buffer-required \"")
|
||||
|
||||
#ADD_EXECUTABLE(rthwif_test rthwif_test.cpp)
|
||||
#TARGET_LINK_LIBRARIES(rthwif_test embree_rthwif sys simd tbb)
|
||||
#IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
#TARGET_LINK_LIBRARIES(rthwif_test embree_rthwif_gpu sys tbb)
|
||||
#ENDIF()
|
||||
|
||||
#SET_PROPERTY(TARGET rthwif_test APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64 -DEMBREE_SYCL_SUPPORT")
|
||||
#SET_PROPERTY(TARGET rthwif_test APPEND PROPERTY LINK_FLAGS "-fsycl -lze_loader -fsycl-targets=spir64 -Xsycl-target-backend=spir64 \" -cl-intel-greater-than-4GB-buffer-required \"")
|
||||
|
||||
ADD_EXECUTABLE(embree_rthwif_test rthwif_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif_test embree_rthwif sys simd ${TBB_TARGET} ${RT_SIM_LIBRARY})
|
||||
IF (EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
TARGET_LINK_LIBRARIES(embree_rthwif_test embree_rthwif_gpu sys tbb)
|
||||
ENDIF()
|
||||
|
||||
SET_PROPERTY(TARGET embree_rthwif_test APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64 -DEMBREE_SYCL_SUPPORT")
|
||||
SET_PROPERTY(TARGET embree_rthwif_test APPEND PROPERTY LINK_FLAGS "-fsycl -lze_loader -fsycl-targets=spir64 -Xsycl-target-backend=spir64 \" -cl-intel-greater-than-4GB-buffer-required \"")
|
||||
|
||||
@@ -72,7 +51,6 @@ IF (NOT DEFINED EMBREE_SYCL_RT_VALIDATION_API OR EMBREE_SYCL_IMPLICIT_DISPATCH_G
|
||||
ADD_TEST(NAME rthwif_cornell_box
|
||||
COMMAND embree_rthwif_cornell_box --compare "${CORNELL_BOX_REFERENCE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
ENDIF()
|
||||
|
||||
ADD_TEST(NAME rthwif_test_builder_triangles_expected COMMAND embree_rthwif_test --build_test_triangles --build_mode_expected)
|
||||
@@ -105,4 +83,3 @@ ADD_TEST(NAME rthwif_test_swinstancing_triangles_potential_hit COMMAND em
|
||||
ADD_TEST(NAME rthwif_test_swinstancing_triangles_anyhit_shader_commit COMMAND embree_rthwif_test --sw-instancing --triangles-anyhit-shader-commit)
|
||||
ADD_TEST(NAME rthwif_test_swinstancing_triangles_anyhit_shader_reject COMMAND embree_rthwif_test --sw-instancing --triangles-anyhit-shader-reject)
|
||||
ADD_TEST(NAME rthwif_test_swinstancing_procedurals_committed_hit COMMAND embree_rthwif_test --sw-instancing --procedurals-committed-hit)
|
||||
|
||||
|
||||
@@ -2,23 +2,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include <CL/sycl.hpp>
|
||||
#include "tbb/tbb.h"
|
||||
|
||||
#if defined(EMBREE_SYCL_RT_VALIDATION_API)
|
||||
# include "../rttrace/rthwif_production.h"
|
||||
#else
|
||||
# include "../rttrace/rthwif_production_igc.h"
|
||||
#endif
|
||||
#include "../rtbuild/rthwif_builder.h"
|
||||
|
||||
#include <level_zero/ze_api.h>
|
||||
#include "../rttrace/rttrace.h"
|
||||
#include "../rtbuild/rtbuild.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#if !defined(_unused)
|
||||
#define _unused(x) ((void)(x))
|
||||
#endif
|
||||
|
||||
void exception_handler(sycl::exception_list exceptions)
|
||||
{
|
||||
for (std::exception_ptr const& e : exceptions) {
|
||||
@@ -93,13 +84,19 @@ bool compareTga(const std::string& fileNameA, const std::string& fileNameB)
|
||||
return dataA == dataB;
|
||||
}
|
||||
|
||||
/* Properly allocates an acceleration structure buffer using ze_raytracing_mem_alloc_ext_desc_t property. */
|
||||
void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context context)
|
||||
{
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
ze_result_t err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
ze_raytracing_mem_alloc_ext_desc_t rt_desc;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_RAYTRACING_EXT_PROPERTIES;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC;
|
||||
rt_desc.pNext = nullptr;
|
||||
rt_desc.flags = 0;
|
||||
|
||||
@@ -115,9 +112,10 @@ void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context contex
|
||||
host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED;
|
||||
|
||||
void* ptr = nullptr;
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT,hDevice,&ptr);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
_unused(result);
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,rtasProp.rtasBufferAlignment,hDevice,&ptr);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("acceleration buffer allocation failed");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -125,173 +123,237 @@ void free_accel_buffer(void* ptr, sycl::context context)
|
||||
{
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_result_t result = zeMemFree(hContext,ptr);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
_unused(result);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("acceleration buffer free failed");
|
||||
}
|
||||
|
||||
#define bvh_bytes 4992
|
||||
|
||||
const unsigned char bvh_data[bvh_bytes] = {
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x02,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,
|
||||
0x06,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0xce,0x74,0x2f,0x7f,0x00,0x00,
|
||||
0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x0a,0x0a,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x89,0x42,0x00,
|
||||
0x42,0x14,0x8c,0x8c,0x6a,0x8c,0x77,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x8a,0x8a,0x53,0x8a,0x53,0x2a,0x8b,0x00,0x3d,0x00,0x3d,0x10,0x8c,0x8c,0x4b,0x8c,0x73,0x45,
|
||||
0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0xcc,0xcc,0x0b,0x44,0x1a,0x00,0x00,0x00,0x04,0x00,0x0a,0x0a,0xf4,0xff,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,
|
||||
0x80,0x80,0x8c,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x8a,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
|
||||
0x65,0x66,0x09,0x44,0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0x1b,0x00,0x00,0x00,0x04,0x00,0x03,0x0a,0x0a,0xff,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x66,0x80,0x80,
|
||||
0x80,0x80,0xcd,0xcd,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x8a,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x8c,0x8c,0x00,0x00,0x00,0x00,
|
||||
0xfe,0x7f,0x84,0x43,0x00,0x80,0x53,0xb8,0xfd,0xff,0x76,0x43,0x1c,0x00,0x00,0x00,0x04,0x00,0x08,0x09,0x06,0xff,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,
|
||||
0x80,0x80,0x9f,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xa6,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xc5,0xc5,0x00,0x00,0x00,0x00,
|
||||
0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0xcd,0xcc,0x8b,0xb8,0x1d,0x00,0x00,0x00,0x04,0x00,0x0a,0x0a,0x0a,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x8c,0x8c,0x8b,0x8b,0x01,0x01,0x89,0x89,0x00,0x00,0x00,0x00,0x8a,0x8a,0x01,0x01,0x8a,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
|
||||
0xfe,0x7f,0x84,0x43,0x00,0x00,0x6c,0xb8,0xfc,0xff,0x76,0x43,0x02,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x08,0xff,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x31,0x80,0x80,
|
||||
0x80,0x80,0xd0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xa6,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xd2,0xd2,0x00,0x00,0x00,0x00,
|
||||
0xfb,0xff,0xa3,0x42,0x00,0x00,0x11,0xb8,0xfb,0xff,0x81,0x42,0x03,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0xff,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x30,0x80,
|
||||
0x80,0x80,0x9f,0xd1,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0xa6,0xa6,0xa6,0x00,0x00,0x00,0xa0,0x00,0x00,0x80,0x80,0x80,0xd0,0xd0,0xd0,0x00,0x00,0x00,
|
||||
0xfe,0x7f,0x84,0x43,0x00,0x00,0x6c,0xb8,0xfc,0xff,0x76,0x43,0x20,0x00,0x00,0x00,0x04,0x00,0x08,0x09,0x08,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x80,0x32,0x32,0xd0,0x9f,0xd0,0x00,0x00,0x00,0x00,0xa5,0x00,0x80,0xa6,0xa6,0x01,0xa6,0x01,0x00,0x31,0x31,0x31,0x00,0x00,0x80,0xd2,0xd2,0xd2,0xd2,0xa0,0x00,
|
||||
0xfe,0xff,0x9c,0x43,0x00,0x00,0x6c,0xb8,0xfc,0xff,0x76,0x43,0x24,0x00,0x00,0x00,0x04,0x00,0x08,0x09,0x08,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x6d,0x6d,
|
||||
0x00,0x80,0x9f,0x9f,0x9f,0x9f,0x9f,0x00,0x00,0x00,0x00,0x00,0xa5,0x80,0xa6,0xa6,0xa6,0xa6,0xa6,0x00,0x9f,0x9f,0x00,0x00,0x00,0x80,0xd2,0xd2,0xa0,0xa0,0xd2,0x00,
|
||||
0xfc,0xff,0xa3,0x42,0x00,0x00,0x08,0xb8,0xfe,0xff,0x60,0x43,0x28,0x00,0x00,0x00,0x04,0x00,0x08,0x08,0x06,0xff,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,
|
||||
0x80,0x80,0x9f,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xa6,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xbd,0xbd,0x00,0x00,0x00,0x00,
|
||||
0xfb,0xff,0xa3,0x42,0x00,0x00,0x11,0xb8,0xfb,0xff,0x81,0x42,0x29,0x00,0x00,0x00,0x04,0x00,0x08,0x08,0x08,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x80,0x31,0x31,0xd1,0xd1,0x9f,0x00,0x00,0x00,0x00,0x00,0xa5,0x80,0xa6,0xa6,0x01,0x01,0xa6,0x00,0x00,0x00,0x00,0x31,0x00,0x80,0xa1,0xa1,0xa1,0xd0,0xd0,0x00,
|
||||
0xfe,0xff,0x01,0x43,0x00,0x00,0x11,0xb8,0xfb,0xff,0x81,0x42,0x2d,0x00,0x00,0x00,0x04,0x00,0x08,0x08,0x08,0xff,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x6e,0x6e,
|
||||
0x00,0x80,0xa1,0xa1,0xa1,0xa1,0xa1,0x00,0x00,0x00,0x00,0x00,0xa5,0x80,0xa6,0xa6,0xa6,0xa6,0xa6,0x00,0x00,0x00,0x31,0x31,0x00,0x80,0x32,0x32,0xd0,0xd0,0xd0,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x02,0x00,0x00,0xff,0x02,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x66,0x66,0x09,0x44,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,
|
||||
0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x02,0x00,0x00,0xff,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x66,0x66,0x09,0x44,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x04,0x00,0x00,0xff,0x04,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x33,0x33,0x0a,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x09,0x44,
|
||||
0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x04,0x00,0x00,0xff,0x04,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x33,0x33,0x0a,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x44,
|
||||
0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x07,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,0x00,0x80,0xd3,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x06,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,0x00,0x80,0x84,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0x94,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,
|
||||
0x01,0x00,0x00,0xff,0x01,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0xff,0x01,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x0b,0x44,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x44,
|
||||
0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x33,0x33,0x0a,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x33,0x33,0x0a,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x66,0x66,0x09,0x44,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x66,0x66,0x09,0x44,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,
|
||||
0x03,0x00,0x00,0xff,0x03,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,
|
||||
0x03,0x00,0x00,0xff,0x03,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,
|
||||
0x33,0x33,0x09,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,0x00,0x00,0x00,0x00,0x33,0x33,0x09,0x44,0xcd,0xcc,0x0b,0x44,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x9d,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,0x00,0x80,0x84,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0x94,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x9d,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,0x00,0x00,0x9d,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x94,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x94,0x43,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,0x00,0x00,0x9d,0x43,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,0x00,0x80,0x84,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,
|
||||
0x06,0x00,0x00,0xff,0x06,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0xd3,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,0x00,0x80,0x84,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0x94,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,0x00,0x80,0x84,0x43,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,0x00,0x00,0xec,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,0x00,0x00,0x9d,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,0x00,0x00,0x9d,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,0x00,0x80,0xd3,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,
|
||||
0x07,0x00,0x00,0xff,0x07,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0xd3,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x43,0x00,0x00,0xec,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x43,
|
||||
0x06,0x00,0x00,0xff,0x06,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x80,0xd3,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0x77,0x43,0x00,0x00,0x9d,0x43,
|
||||
0x00,0x00,0xa5,0x43,0x00,0x00,0xe4,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,0x00,0x00,0xec,0x43,0x00,0x00,0xa5,0x43,0x00,0x00,0xcb,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x70,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x43,0x00,0x00,0x70,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x25,0x43,0x00,0x00,0x61,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x25,0x43,0x00,0x00,0x61,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x09,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x70,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x43,0x00,0x00,0xa4,0x42,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x61,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x06,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,0x00,0x00,0xa4,0x42,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x61,0x43,0x00,0x00,0x02,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,0x00,0x00,0x02,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x07,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,0x00,0x00,0x02,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,0x00,0x00,0xa4,0x42,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,
|
||||
0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,0x00,0x00,0x70,0x43,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,0x00,0x00,0xa4,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,0x00,0x00,0xa4,0x42,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x61,0x43,0x00,0x00,0x70,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,0x00,0x00,0x70,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x00,0x91,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x00,0x02,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,0x00,0x00,0x91,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,0x00,0x00,0x91,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,0x00,0x00,0x91,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,0x00,0x00,0x70,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,0x00,0x00,0x70,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x91,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x42,0x00,0x00,0x70,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,0x00,0x00,0x70,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x43,0x00,0x00,0x70,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x43,
|
||||
0x05,0x00,0x00,0xff,0x05,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0x82,0x42,0x00,0x00,0x70,0x43,
|
||||
0x00,0x00,0x25,0x43,0x00,0x00,0x88,0x43,0x00,0x00,0x91,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,0x00,0x00,0x91,0x43,0x00,0x00,0x25,0x43,0x00,0x00,0xe4,0x42,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
/* vertex indices for cornell_box model */
|
||||
ze_rtas_triangle_indices_uint32_exp_t indices[] = {
|
||||
{ 0, 1, 2 },
|
||||
{ 0, 2, 3 },
|
||||
{ 4, 5, 6 },
|
||||
{ 4, 6, 7 },
|
||||
{ 8, 9, 10 },
|
||||
{ 8, 10, 11 },
|
||||
{ 12, 13, 14 },
|
||||
{ 12, 14, 15 },
|
||||
{ 16, 17, 18 },
|
||||
{ 16, 18, 19 },
|
||||
{ 20, 21, 22 },
|
||||
{ 20, 22, 23 },
|
||||
{ 24, 25, 26 },
|
||||
{ 24, 26, 27 },
|
||||
{ 28, 29, 30 },
|
||||
{ 28, 30, 31 },
|
||||
{ 32, 33, 34 },
|
||||
{ 32, 34, 35 },
|
||||
{ 36, 37, 38 },
|
||||
{ 36, 38, 39 },
|
||||
{ 40, 41, 42 },
|
||||
{ 40, 42, 43 },
|
||||
{ 44, 45, 46 },
|
||||
{ 44, 46, 47 },
|
||||
{ 48, 49, 50 },
|
||||
{ 48, 50, 51 },
|
||||
{ 52, 53, 54 },
|
||||
{ 52, 54, 55 },
|
||||
{ 56, 57, 58 },
|
||||
{ 56, 58, 59 },
|
||||
{ 60, 61, 62 },
|
||||
{ 60, 62, 63 },
|
||||
{ 64, 65, 66 },
|
||||
{ 64, 66, 67 }
|
||||
};
|
||||
|
||||
/* vertex positions for cornell_box model */
|
||||
ze_rtas_float3_exp_t vertices[] = {
|
||||
{ 552.8, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 559.2 },
|
||||
{ 549.6, 0, 559.2 },
|
||||
{ 290, 0, 114 },
|
||||
{ 240, 0, 272 },
|
||||
{ 82, 0, 225 },
|
||||
{ 130, 0, 65 },
|
||||
{ 472, 0, 406 },
|
||||
{ 314, 0, 456 },
|
||||
{ 265, 0, 296 },
|
||||
{ 423, 0, 247 },
|
||||
{ 556, 548.8, 0 },
|
||||
{ 556, 548.8, 559.2 },
|
||||
{ 0, 548.8, 559.2 },
|
||||
{ 0, 548.8, 0 },
|
||||
{ 549.6, 0, 559.2 },
|
||||
{ 0, 0, 559.2 },
|
||||
{ 0, 548.8, 559.2 },
|
||||
{ 556, 548.8, 559.2 },
|
||||
{ 0, 0, 559.2 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 548.8, 0 },
|
||||
{ 0, 548.8, 559.2 },
|
||||
{ 552.8, 0, 0 },
|
||||
{ 549.6, 0, 559.2 },
|
||||
{ 556, 548.8, 559.2 },
|
||||
{ 556, 548.8, 0 },
|
||||
{ 130, 165, 65 },
|
||||
{ 82, 165, 225 },
|
||||
{ 240, 165, 272 },
|
||||
{ 290, 165, 114 },
|
||||
{ 290, 0, 114 },
|
||||
{ 290, 165, 114 },
|
||||
{ 240, 165, 272 },
|
||||
{ 240, 0, 272 },
|
||||
{ 130, 0, 65 },
|
||||
{ 130, 165, 65 },
|
||||
{ 290, 165, 114 },
|
||||
{ 290, 0, 114 },
|
||||
{ 82, 0, 225 },
|
||||
{ 82, 165, 225 },
|
||||
{ 130, 165, 65 },
|
||||
{ 130, 0, 65 },
|
||||
{ 240, 0, 272 },
|
||||
{ 240, 165, 272 },
|
||||
{ 82, 165, 225 },
|
||||
{ 82, 0, 225 },
|
||||
{ 423, 330, 247 },
|
||||
{ 265, 330, 296 },
|
||||
{ 314, 330, 456 },
|
||||
{ 472, 330, 406 },
|
||||
{ 423, 0, 247 },
|
||||
{ 423, 330, 247 },
|
||||
{ 472, 330, 406 },
|
||||
{ 472, 0, 406 },
|
||||
{ 472, 0, 406 },
|
||||
{ 472, 330, 406 },
|
||||
{ 314, 330, 456 },
|
||||
{ 314, 0, 456 },
|
||||
{ 314, 0, 456 },
|
||||
{ 314, 330, 456 },
|
||||
{ 265, 330, 296 },
|
||||
{ 265, 0, 296 },
|
||||
{ 265, 0, 296 },
|
||||
{ 265, 330, 296 },
|
||||
{ 423, 330, 247 },
|
||||
{ 423, 0, 247 },
|
||||
};
|
||||
|
||||
/* builds acceleration structure */
|
||||
void* build_rtas(sycl::device device, sycl::context context)
|
||||
{
|
||||
/* get L0 handles */
|
||||
ze_driver_handle_t hDriver = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device.get_platform());
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
|
||||
/* create rtas builder object */
|
||||
ze_rtas_builder_exp_desc_t builderDesc = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC };
|
||||
ze_rtas_builder_exp_handle_t hBuilder = nullptr;
|
||||
ze_result_t err = zeRTASBuilderCreateExp(hDriver, &builderDesc, &hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("ze_rtas_builder creation failed");
|
||||
|
||||
/* create geometry descriptor for single triangle mesh */
|
||||
ze_rtas_builder_triangles_geometry_info_exp_t mesh = {};
|
||||
mesh.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES;
|
||||
mesh.geometryFlags = 0;
|
||||
mesh.geometryMask = 0xFF;
|
||||
|
||||
mesh.triangleFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32;
|
||||
mesh.triangleCount = sizeof(indices)/sizeof(ze_rtas_triangle_indices_uint32_exp_t);
|
||||
mesh.triangleStride = sizeof(ze_rtas_triangle_indices_uint32_exp_t);
|
||||
mesh.pTriangleBuffer = indices;
|
||||
|
||||
mesh.vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3;
|
||||
mesh.vertexCount = sizeof(vertices)/sizeof(ze_rtas_float3_exp_t);
|
||||
mesh.vertexStride = sizeof(ze_rtas_float3_exp_t);
|
||||
mesh.pVertexBuffer = vertices;
|
||||
|
||||
/* fill geometry descriptor array with pointer to single geometry descriptor */
|
||||
std::vector<ze_rtas_builder_geometry_info_exp_t*> descs;
|
||||
descs.push_back((ze_rtas_builder_geometry_info_exp_t*)&mesh);
|
||||
|
||||
/* get acceleration structure format for this device */
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
/* create parallel operation for parallel build */
|
||||
ze_rtas_parallel_operation_exp_handle_t hParallelOperation = nullptr;
|
||||
err = zeRTASParallelOperationCreateExp(hDriver, &hParallelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASParallelOperationCreateExp failed");
|
||||
|
||||
/* create descriptor of build operation */
|
||||
size_t accelBufferBytesOut = 0;
|
||||
ze_rtas_aabb_exp_t bounds;
|
||||
ze_rtas_builder_build_op_exp_desc_t buildOp = {};
|
||||
buildOp.stype = ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC;
|
||||
buildOp.pNext = nullptr;
|
||||
buildOp.rtasFormat = rtasProp.rtasFormat;
|
||||
buildOp.buildQuality = ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM;
|
||||
buildOp.buildFlags = 0;
|
||||
buildOp.ppGeometries = (const ze_rtas_builder_geometry_info_exp_t **) descs.data();
|
||||
buildOp.numGeometries = descs.size();
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
buildOp.dispatchGlobalsPtr = dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
/* query required buffer sizes */
|
||||
ze_rtas_builder_exp_properties_t buildProps = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES };
|
||||
err = zeRTASBuilderGetBuildPropertiesExp(hBuilder,&buildOp,&buildProps);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASBuilderGetBuildPropertiesExp failed");
|
||||
|
||||
/* allocate scratch buffer */
|
||||
std::vector<char> scratchBuffer(buildProps.scratchBufferSizeBytes);
|
||||
memset(scratchBuffer.data(),0,scratchBuffer.size());
|
||||
|
||||
/* allocate acceleration structure buffer */
|
||||
size_t accelBytes = buildProps.rtasBufferSizeBytesMaxRequired;
|
||||
void* accel = alloc_accel_buffer(accelBytes,device,context);
|
||||
memset(accel,0,accelBytes); // optional
|
||||
|
||||
/* build acceleration strucuture multi threaded */
|
||||
err = zeRTASBuilderBuildExp(hBuilder,&buildOp,
|
||||
scratchBuffer.data(),scratchBuffer.size(),
|
||||
accel, accelBytes,
|
||||
hParallelOperation,
|
||||
nullptr, &bounds, &accelBufferBytesOut);
|
||||
|
||||
if (err != ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE)
|
||||
throw std::runtime_error("zeRTASBuilderBuildExp failed");
|
||||
|
||||
/* after the build is started one can query number of threads to use for the build */
|
||||
ze_rtas_parallel_operation_exp_properties_t prop = { ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES };
|
||||
err = zeRTASParallelOperationGetPropertiesExp(hParallelOperation,&prop);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASParallelOperationGetPropertiesExp failed");
|
||||
|
||||
/* build in parallel using maximal number of build threads */
|
||||
tbb::parallel_for(0u, prop.maxConcurrency, 1u, [&](uint32_t) {
|
||||
err = zeRTASParallelOperationJoinExp(hParallelOperation);
|
||||
});
|
||||
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASParallelOperationJoinExp failed");
|
||||
|
||||
/* destroy parallel operation again */
|
||||
err = zeRTASParallelOperationDestroyExp(hParallelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASParallelOperationDestroyExp failed");
|
||||
|
||||
/* destroy rtas builder again */
|
||||
err = zeRTASBuilderDestroyExp(hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("zeRTASBuilderDestroyExp failed");
|
||||
|
||||
return accel;
|
||||
}
|
||||
|
||||
/* render using simple UV shading */
|
||||
void render(unsigned int x, unsigned int y, void* bvh, unsigned int* pixels, unsigned int width, unsigned int height)
|
||||
{
|
||||
/* write zero image if ray tracing extension is not supported */
|
||||
intel_raytracing_ext_flag_t flags = intel_get_raytracing_ext_flag();
|
||||
if (!(flags & intel_raytracing_ext_flag_ray_query)) {
|
||||
pixels[y*width+x] = 0;
|
||||
@@ -337,29 +399,29 @@ void render(unsigned int x, unsigned int y, void* bvh, unsigned int* pixels, uns
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
/* use can specify reference image to compare against */
|
||||
char* reference_img = NULL;
|
||||
if (argc > 2 && std::string(argv[1]) == std::string("--compare"))
|
||||
{
|
||||
reference_img = argv[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
reference_img = (char*)"cornell_box_reference.tga";
|
||||
}
|
||||
|
||||
/* create SYCL objects */
|
||||
sycl::device device = sycl::device(sycl::gpu_selector_v);
|
||||
sycl::queue queue = sycl::queue(device,exception_handler);
|
||||
sycl::context context = queue.get_context();
|
||||
|
||||
void* bvh = alloc_accel_buffer(bvh_bytes,device,context);
|
||||
memcpy(bvh, bvh_data, bvh_bytes);
|
||||
/* initialize L0 ray tracing extension */
|
||||
zeRTASInitExp();
|
||||
|
||||
/* build acceleration structure */
|
||||
void* bvh = build_rtas(device,context);
|
||||
|
||||
/* creates framebuffer */
|
||||
static const int width = 512;
|
||||
static const int height = 512;
|
||||
unsigned int* pixels = (unsigned int*) sycl::aligned_alloc(64,width*height*sizeof(unsigned int),device,context,sycl::usm::alloc::shared);
|
||||
memset(pixels, 0, width*height*sizeof(uint32_t));
|
||||
|
||||
for (int i=0; i<10; i++) {
|
||||
/* renders image on device */
|
||||
queue.submit([&](sycl::handler& cgh) {
|
||||
const sycl::range<2> range(width,height);
|
||||
cgh.parallel_for(range, [=](sycl::item<2> item) {
|
||||
@@ -369,13 +431,19 @@ int main(int argc, char* argv[])
|
||||
});
|
||||
});
|
||||
queue.wait_and_throw();
|
||||
}
|
||||
|
||||
/* free acceleration structure again */
|
||||
free_accel_buffer(bvh,context);
|
||||
|
||||
storeTga(pixels,width,height,"cornell_box.tga");
|
||||
const bool ok = compareTga("cornell_box.tga", reference_img);
|
||||
/* cleanup L0 ray tracing extension */
|
||||
zeRTASExitExp();
|
||||
|
||||
/* store image to disk */
|
||||
storeTga(pixels,width,height,"cornell_box.tga");
|
||||
if (!reference_img) return 0;
|
||||
|
||||
/* compare to reference image */
|
||||
const bool ok = compareTga("cornell_box.tga", reference_img);
|
||||
std::cout << "cornell_box ";
|
||||
if (ok) std::cout << "[PASSED]" << std::endl;
|
||||
else std::cout << "[FAILED]" << std::endl;
|
||||
|
||||
@@ -13,22 +13,13 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#if defined(EMBREE_SYCL_RT_VALIDATION_API)
|
||||
# include "../rttrace/rthwif_production.h"
|
||||
#else
|
||||
# include "../rttrace/rthwif_production_igc.h"
|
||||
#endif
|
||||
|
||||
#include "../rtbuild/rthwif_builder.h"
|
||||
|
||||
#include <level_zero/ze_api.h>
|
||||
#include "../rttrace/rttrace.h"
|
||||
#include "../rtbuild/rtbuild.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
namespace embree {
|
||||
double getSeconds();
|
||||
}
|
||||
@@ -150,7 +141,8 @@ sycl::float3 RandomSampler_getFloat3(RandomSampler& self)
|
||||
|
||||
RandomSampler rng;
|
||||
|
||||
volatile RTHWIF_PARALLEL_OPERATION parallelOperation = nullptr;
|
||||
ze_rtas_builder_exp_handle_t hBuilder = nullptr;
|
||||
ze_rtas_parallel_operation_exp_handle_t parallelOperation = nullptr;
|
||||
|
||||
enum class InstancingType
|
||||
{
|
||||
@@ -418,7 +410,7 @@ struct Bounds3f
|
||||
return { sycl::float3(INFINITY), sycl::float3(-INFINITY) };
|
||||
}
|
||||
|
||||
operator RTHWIF_AABB () const {
|
||||
operator ze_rtas_aabb_exp_t () const {
|
||||
return { { lower.x(), lower.y(), lower.z() }, { upper.x(), upper.y(), upper.z() } };
|
||||
}
|
||||
|
||||
@@ -503,17 +495,17 @@ struct Hit
|
||||
};
|
||||
|
||||
|
||||
struct GEOMETRY_INSTANCE_DESC : RTHWIF_GEOMETRY_INSTANCE_DESC
|
||||
struct GEOMETRY_INSTANCE_DESC : ze_rtas_builder_instance_geometry_info_exp_t
|
||||
{
|
||||
RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR xfmdata;
|
||||
ze_rtas_transform_float3x4_aligned_column_major_exp_t xfmdata;
|
||||
};
|
||||
|
||||
typedef union GEOMETRY_DESC
|
||||
{
|
||||
RTHWIF_GEOMETRY_TYPE geometryType;
|
||||
RTHWIF_GEOMETRY_TRIANGLES_DESC Triangles;
|
||||
RTHWIF_GEOMETRY_QUADS_DESC Quads;
|
||||
RTHWIF_GEOMETRY_AABBS_FPTR_DESC AABBs;
|
||||
ze_rtas_builder_geometry_type_exp_t geometryType;
|
||||
ze_rtas_builder_triangles_geometry_info_exp_t Triangles;
|
||||
ze_rtas_builder_quads_geometry_info_exp_t Quads;
|
||||
ze_rtas_builder_procedural_geometry_info_exp_t AABBs;
|
||||
GEOMETRY_INSTANCE_DESC Instance;
|
||||
|
||||
} GEOMETRY_DESC;
|
||||
@@ -534,7 +526,7 @@ struct Geometry
|
||||
throw std::runtime_error("Geometry::transform not implemented");
|
||||
}
|
||||
|
||||
virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, RTHWIF_BUILD_QUALITY quality) {
|
||||
virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, ze_rtas_builder_build_quality_hint_exp_t quality) {
|
||||
};
|
||||
|
||||
virtual void buildTriMap(Transform local_to_world, std::vector<uint32_t> id_stack, uint32_t instUserID, bool procedural_instance, std::vector<Hit>& tri_map) = 0;
|
||||
@@ -548,7 +540,7 @@ struct TriangleMesh : public Geometry
|
||||
{
|
||||
public:
|
||||
|
||||
TriangleMesh (RTHWIF_GEOMETRY_FLAGS gflags = RTHWIF_GEOMETRY_FLAG_OPAQUE, bool procedural = false)
|
||||
TriangleMesh (ze_rtas_builder_geometry_exp_flags_t gflags = 0, bool procedural = false)
|
||||
: Geometry(Type::TRIANGLE_MESH),
|
||||
gflags(gflags), procedural(procedural),
|
||||
triangles_alloc(context,device,sycl::ext::oneapi::property::usm::device_read_only()), triangles(0,triangles_alloc),
|
||||
@@ -573,14 +565,16 @@ public:
|
||||
vertices[i] = xfmPoint(xfm,vertices[i]);
|
||||
}
|
||||
|
||||
static void getBoundsCallback (const uint32_t primIDStart, const uint32_t primIDCount, void* geomUserPtr, void* buildUserPtr, RTHWIF_AABB* boundsOut)
|
||||
static void getBoundsCallback (ze_rtas_geometry_aabbs_exp_cb_params_t* params)
|
||||
{
|
||||
const TriangleMesh* mesh = (TriangleMesh*) geomUserPtr;
|
||||
assert(params->stype == ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS);
|
||||
const TriangleMesh* mesh = (TriangleMesh*) params->pGeomUserPtr;
|
||||
|
||||
for (uint32_t i=0; i<primIDCount; i++)
|
||||
for (uint32_t i=0; i<params->primIDCount; i++)
|
||||
{
|
||||
const uint32_t primID = primIDStart+i;
|
||||
const uint32_t primID = params->primID+i;
|
||||
const Bounds3f bounds = mesh->getBounds(primID);
|
||||
ze_rtas_aabb_exp_t* boundsOut = params->pBoundsOut;
|
||||
boundsOut[i].lower.x = bounds.lower.x();
|
||||
boundsOut[i].lower.y = bounds.lower.y();
|
||||
boundsOut[i].lower.z = bounds.lower.z();
|
||||
@@ -594,26 +588,28 @@ public:
|
||||
{
|
||||
if (procedural)
|
||||
{
|
||||
RTHWIF_GEOMETRY_AABBS_FPTR_DESC& out = desc->AABBs;
|
||||
ze_rtas_builder_procedural_geometry_info_exp_t& out = desc->AABBs;
|
||||
memset(&out,0,sizeof(out));
|
||||
out.geometryType = RTHWIF_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL;
|
||||
out.geometryFlags = gflags;
|
||||
out.geometryMask = 0xFF;
|
||||
out.primCount = triangles.size();
|
||||
out.getBounds = TriangleMesh::getBoundsCallback;
|
||||
out.geomUserPtr = this;
|
||||
out.pfnGetBoundsCb = TriangleMesh::getBoundsCallback;
|
||||
out.pGeomUserPtr = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
RTHWIF_GEOMETRY_TRIANGLES_DESC& out = desc->Triangles;
|
||||
ze_rtas_builder_triangles_geometry_info_exp_t& out = desc->Triangles;
|
||||
memset(&out,0,sizeof(out));
|
||||
out.geometryType = RTHWIF_GEOMETRY_TYPE_TRIANGLES;
|
||||
out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES;
|
||||
out.geometryFlags = gflags;
|
||||
out.geometryMask = 0xFF;
|
||||
out.triangleBuffer = (RTHWIF_TRIANGLE_INDICES*) triangles.data();
|
||||
out.triangleFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32;
|
||||
out.vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3;
|
||||
out.pTriangleBuffer = (ze_rtas_triangle_indices_uint32_exp_t*) triangles.data();
|
||||
out.triangleCount = triangles.size();
|
||||
out.triangleStride = sizeof(sycl::int4);
|
||||
out.vertexBuffer = (RTHWIF_FLOAT3*) vertices.data();
|
||||
out.pVertexBuffer = (ze_rtas_float3_exp_t*) vertices.data();
|
||||
out.vertexCount = vertices.size();
|
||||
out.vertexStride = sizeof(sycl::float3);
|
||||
}
|
||||
@@ -765,7 +761,7 @@ public:
|
||||
|
||||
|
||||
public:
|
||||
RTHWIF_GEOMETRY_FLAGS gflags = RTHWIF_GEOMETRY_FLAG_OPAQUE;
|
||||
ze_rtas_builder_geometry_exp_flags_t gflags = 0;
|
||||
bool procedural = false;
|
||||
|
||||
typedef sycl::usm_allocator<sycl::int4, sycl::usm::alloc::shared> triangles_alloc_ty;
|
||||
@@ -794,14 +790,15 @@ struct InstanceGeometryT : public Geometry
|
||||
sycl::free(ptr,context);
|
||||
}
|
||||
|
||||
static void getBoundsCallback (const uint32_t primIDStart, const uint32_t primIDCount, void* geomUserPtr, void* buildUserPtr, RTHWIF_AABB* boundsOut)
|
||||
static void getBoundsCallback (ze_rtas_geometry_aabbs_exp_cb_params_t* params)
|
||||
{
|
||||
assert(primIDStart == 0);
|
||||
assert(primIDCount == 1);
|
||||
const InstanceGeometryT* inst = (InstanceGeometryT*) geomUserPtr;
|
||||
assert(params->stype == ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS);
|
||||
assert(params->primID == 0);
|
||||
assert(params->primIDCount == 1);
|
||||
const InstanceGeometryT* inst = (InstanceGeometryT*) params->pGeomUserPtr;
|
||||
const Bounds3f scene_bounds = inst->scene->getBounds();
|
||||
const Bounds3f bounds = xfmBounds(inst->local2world, scene_bounds);
|
||||
|
||||
ze_rtas_aabb_exp_t* boundsOut = params->pBoundsOut;
|
||||
boundsOut->lower.x = bounds.lower.x();
|
||||
boundsOut->lower.y = bounds.lower.y();
|
||||
boundsOut->lower.z = bounds.lower.z();
|
||||
@@ -814,25 +811,25 @@ struct InstanceGeometryT : public Geometry
|
||||
{
|
||||
if (procedural)
|
||||
{
|
||||
RTHWIF_GEOMETRY_AABBS_FPTR_DESC& out = desc->AABBs;
|
||||
ze_rtas_builder_procedural_geometry_info_exp_t& out = desc->AABBs;
|
||||
memset(&out,0,sizeof(out));
|
||||
out.geometryType = RTHWIF_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
out.geometryFlags = RTHWIF_GEOMETRY_FLAG_NONE;
|
||||
out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL;
|
||||
out.geometryFlags = 0;
|
||||
out.geometryMask = 0xFF;
|
||||
out.primCount = 1;
|
||||
out.getBounds = InstanceGeometryT::getBoundsCallback;
|
||||
out.geomUserPtr = this;
|
||||
out.pfnGetBoundsCb = InstanceGeometryT::getBoundsCallback;
|
||||
out.pGeomUserPtr = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
GEOMETRY_INSTANCE_DESC& out = desc->Instance;
|
||||
memset(&out,0,sizeof(GEOMETRY_INSTANCE_DESC));
|
||||
out.geometryType = RTHWIF_GEOMETRY_TYPE_INSTANCE;
|
||||
out.instanceFlags = RTHWIF_INSTANCE_FLAG_NONE;
|
||||
out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE;
|
||||
out.instanceFlags = 0;
|
||||
out.geometryMask = 0xFF;
|
||||
out.instanceUserID = instUserID;
|
||||
out.transformFormat = RTHWIF_TRANSFORM_FORMAT_FLOAT4X4_COLUMN_MAJOR;
|
||||
out.transform = (float*)&out.xfmdata;
|
||||
out.transformFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR;
|
||||
out.pTransform = (float*)&out.xfmdata;
|
||||
out.xfmdata.vx_x = local2world.vx.x();
|
||||
out.xfmdata.vx_y = local2world.vx.y();
|
||||
out.xfmdata.vx_z = local2world.vx.z();
|
||||
@@ -849,12 +846,12 @@ struct InstanceGeometryT : public Geometry
|
||||
out.xfmdata.p_y = local2world.p.y();
|
||||
out.xfmdata.p_z = local2world.p.z();
|
||||
out.xfmdata.pad3 = 0.0f;
|
||||
out.bounds = &scene->bounds;
|
||||
out.accel = scene->getAccel();
|
||||
out.pBounds = &scene->bounds;
|
||||
out.pAccelerationStructure = scene->getAccel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, RTHWIF_BUILD_QUALITY quality) override {
|
||||
virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, ze_rtas_builder_build_quality_hint_exp_t quality) override {
|
||||
scene->buildAccel(device,context,buildMode);
|
||||
}
|
||||
|
||||
@@ -900,18 +897,18 @@ std::shared_ptr<TriangleMesh> createTrianglePlane (const sycl::float3& p0, const
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context context)
|
||||
void* alloc_accel_buffer_internal(size_t bytes, sycl::device device, sycl::context context)
|
||||
{
|
||||
#if 1
|
||||
return sycl::aligned_alloc_shared(RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT,bytes,device,context,sycl::ext::oneapi::property::usm::device_read_only());
|
||||
|
||||
#else // FIXME: enable this
|
||||
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
ze_result_t err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
ze_raytracing_mem_alloc_ext_desc_t rt_desc;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_RAYTRACING_EXT_PROPERTIES;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC;
|
||||
rt_desc.pNext = nullptr;
|
||||
rt_desc.flags = 0;
|
||||
|
||||
@@ -927,38 +924,73 @@ void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context contex
|
||||
host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED;
|
||||
|
||||
void* ptr = nullptr;
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT,hDevice,&ptr);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,rtasProp.rtasBufferAlignment,hDevice,&ptr);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("accel allocation failed");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void free_accel_buffer_internal(void* ptr, sycl::context context)
|
||||
{
|
||||
if (ptr == nullptr) return;
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_result_t result = zeMemFree(hContext,ptr);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("accel free failed");
|
||||
}
|
||||
|
||||
struct Block {
|
||||
Block (size_t bytes, sycl::device device, sycl::context context)
|
||||
: base((char*)alloc_accel_buffer_internal(bytes,device,context)), total(bytes), cur(0) {}
|
||||
~Block() {
|
||||
free_accel_buffer_internal((void*)base,context);
|
||||
}
|
||||
void* alloc(size_t bytes) {
|
||||
bytes &= -128;
|
||||
if (cur+bytes > total) return nullptr;
|
||||
void* ptr = &base[cur];
|
||||
cur += bytes;
|
||||
return ptr;
|
||||
}
|
||||
char* base = nullptr;
|
||||
size_t total = 0;
|
||||
size_t cur = 0;
|
||||
|
||||
};
|
||||
|
||||
bool g_use_accel_blocks = true;
|
||||
std::vector<std::shared_ptr<Block>> g_blocks;
|
||||
|
||||
void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context context)
|
||||
{
|
||||
if (!g_use_accel_blocks)
|
||||
return alloc_accel_buffer_internal(bytes,device,context);
|
||||
|
||||
if (g_blocks.size() == 0)
|
||||
g_blocks.push_back(std::shared_ptr<Block>(new Block(1024*1024,device,context)));
|
||||
|
||||
if (bytes > 1024*1024) {
|
||||
g_blocks.push_back(std::shared_ptr<Block>(new Block(bytes,device,context)));
|
||||
void* ptr = g_blocks.back()->alloc(bytes);
|
||||
assert(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* ptr = g_blocks.back()->alloc(bytes);
|
||||
if (ptr) return ptr;
|
||||
|
||||
g_blocks.push_back(std::shared_ptr<Block>(new Block(1024*1024,device,context)));
|
||||
ptr = g_blocks.back()->alloc(bytes);
|
||||
assert(ptr);
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void free_accel_buffer(void* ptr, sycl::context context)
|
||||
{
|
||||
#if 1
|
||||
sycl::free(ptr,context);
|
||||
|
||||
#else // FIXME: enable this
|
||||
if (ptr == nullptr) return;
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_result_t result = zeMemFree(hContext,ptr);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
#endif
|
||||
if (!g_use_accel_blocks)
|
||||
return free_accel_buffer_internal(ptr,context);
|
||||
}
|
||||
|
||||
|
||||
void exception_handler(sycl::exception_list exceptions)
|
||||
{
|
||||
for (std::exception_ptr const& e : exceptions) {
|
||||
try {
|
||||
std::rethrow_exception(e);
|
||||
} catch(sycl::exception const& e) {
|
||||
std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Scene
|
||||
{
|
||||
typedef InstanceGeometryT<Scene> InstanceGeometry;
|
||||
@@ -970,7 +1002,7 @@ struct Scene
|
||||
: geometries_alloc(context,device,sycl::ext::oneapi::property::usm::device_read_only()), geometries(0,geometries_alloc), bounds(Bounds3f::empty()), accel(nullptr)
|
||||
{
|
||||
std::shared_ptr<TriangleMesh> plane = createTrianglePlane(sycl::float3(0,0,0), sycl::float3(width,0,0), sycl::float3(0,height,0), width, height);
|
||||
plane->gflags = opaque ? RTHWIF_GEOMETRY_FLAG_OPAQUE : RTHWIF_GEOMETRY_FLAG_NONE;
|
||||
plane->gflags = opaque ? (ze_rtas_builder_geometry_exp_flag_t) 0 : ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE;
|
||||
plane->procedural = procedural;
|
||||
geometries.push_back(plane);
|
||||
}
|
||||
@@ -1088,7 +1120,7 @@ struct Scene
|
||||
geometries[j]->transform(world2local);
|
||||
scene->geometries.push_back(geometries[j]);
|
||||
}
|
||||
|
||||
|
||||
//std::shared_ptr<InstanceGeometry> instance = std::make_shared<InstanceGeometry>(local2world,scene,procedural);
|
||||
uint32_t instUserID = RandomSampler_getUInt(rng);
|
||||
std::shared_ptr<InstanceGeometry> instance(new InstanceGeometry(local2world,scene,procedural,instUserID));
|
||||
@@ -1116,22 +1148,14 @@ struct Scene
|
||||
std::swap(geometries[g],geometries[k]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, bool benchmark = false)
|
||||
{
|
||||
RTHWIF_BUILD_QUALITY quality = (RTHWIF_BUILD_QUALITY) (RandomSampler_getUInt(rng) % 3);
|
||||
ze_rtas_builder_build_quality_hint_exp_t quality = (ze_rtas_builder_build_quality_hint_exp_t) (RandomSampler_getUInt(rng) % 3);
|
||||
|
||||
/* fill geometry descriptor buffer */
|
||||
const size_t numGeometries = size();
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
sycl::queue queue(device, exception_handler);
|
||||
|
||||
GEOMETRY_DESC *desc = (GEOMETRY_DESC*)sycl::aligned_alloc(64,sizeof(GEOMETRY_DESC)*numGeometries,device,context,sycl::usm::alloc::shared);
|
||||
RTHWIF_GEOMETRY_DESC **geom = (RTHWIF_GEOMETRY_DESC**)sycl::aligned_alloc(64,numGeometries*sizeof(RTHWIF_GEOMETRY_DESC*),device,context,sycl::usm::alloc::shared);
|
||||
#else
|
||||
std::vector<GEOMETRY_DESC> desc(size());
|
||||
std::vector<const RTHWIF_GEOMETRY_DESC*> geom(size());
|
||||
#endif
|
||||
std::vector<const ze_rtas_builder_geometry_info_exp_t*> geom(size());
|
||||
size_t numPrimitives = 0;
|
||||
for (size_t geomID=0; geomID<size(); geomID++)
|
||||
{
|
||||
@@ -1146,69 +1170,45 @@ struct Scene
|
||||
numPrimitives += g->getNumPrimitives();
|
||||
g->buildAccel(device,context,buildMode,quality);
|
||||
g->getDesc(&desc[geomID]);
|
||||
geom[geomID] = (RTHWIF_GEOMETRY_DESC*) &desc[geomID];
|
||||
geom[geomID] = (const ze_rtas_builder_geometry_info_exp_t*) &desc[geomID];
|
||||
}
|
||||
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
ze_result_t err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
/* estimate accel size */
|
||||
size_t accelBufferBytesOut = 0;
|
||||
RTHWIF_AABB bounds;
|
||||
RTHWIF_BUILD_ACCEL_ARGS args;
|
||||
ze_rtas_aabb_exp_t bounds;
|
||||
ze_rtas_builder_build_op_exp_desc_t args;
|
||||
memset(&args,0,sizeof(args));
|
||||
args.structBytes = sizeof(args);
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geom;
|
||||
#else
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geom.data();
|
||||
#endif
|
||||
args.numGeometries = numGeometries; //geom.size();
|
||||
args.accelBuffer = nullptr;
|
||||
args.accelBufferBytes = 0;
|
||||
args.scratchBuffer = nullptr;
|
||||
args.scratchBufferBytes = 0;
|
||||
args.quality = quality;
|
||||
args.flags = RTHWIF_BUILD_FLAG_NONE;
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
args.parallelOperation = nullptr;
|
||||
#else
|
||||
args.parallelOperation = parallelOperation;
|
||||
#endif
|
||||
args.boundsOut = &bounds;
|
||||
args.accelBufferBytesOut = &accelBufferBytesOut;
|
||||
args.buildUserPtr = nullptr;
|
||||
args.stype = ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC;
|
||||
args.pNext = nullptr;
|
||||
args.rtasFormat = rtasProp.rtasFormat;
|
||||
args.buildQuality = quality;
|
||||
args.buildFlags = 0;
|
||||
args.ppGeometries = (const ze_rtas_builder_geometry_info_exp_t**) geom.data();
|
||||
args.numGeometries = geom.size();
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
args.dispatchGlobalsPtr = dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
RTHWIF_ACCEL_SIZE size;
|
||||
memset(&size,0,sizeof(RTHWIF_ACCEL_SIZE));
|
||||
size.structBytes = sizeof(RTHWIF_ACCEL_SIZE);
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
RTHWIF_ERROR err = rthwifGetAccelSizeGPU(args,size,&queue,VERBOSE);
|
||||
#else
|
||||
RTHWIF_ERROR err = rthwifGetAccelSize(args,size);
|
||||
#endif
|
||||
if (err != RTHWIF_ERROR_NONE)
|
||||
ze_rtas_builder_exp_properties_t size = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES };
|
||||
err = zeRTASBuilderGetBuildPropertiesExp(hBuilder,&args,&size);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("BVH size estimate failed");
|
||||
|
||||
if (size.accelBufferExpectedBytes > size.accelBufferWorstCaseBytes)
|
||||
if (size.rtasBufferSizeBytesExpected > size.rtasBufferSizeBytesMaxRequired)
|
||||
throw std::runtime_error("expected larger than worst case");
|
||||
|
||||
/* allocate scratch buffer */
|
||||
size_t sentinelBytes = 1024; // add that many zero bytes to catch buffer overruns
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
// === scratch buffer ===
|
||||
char *scratchBuffer = (char*)sycl::aligned_alloc(64,size.scratchBufferBytes+sentinelBytes,device,context,sycl::usm::alloc::shared);
|
||||
assert(scratchBuffer);
|
||||
memset(scratchBuffer,0,size.scratchBufferBytes+sentinelBytes);
|
||||
args.scratchBuffer = scratchBuffer;
|
||||
args.scratchBufferBytes = size.scratchBufferBytes;
|
||||
#else
|
||||
std::vector<char> scratchBuffer(size.scratchBufferBytes+sentinelBytes);
|
||||
std::vector<char> scratchBuffer(size.scratchBufferSizeBytes+sentinelBytes);
|
||||
memset(scratchBuffer.data(),0,scratchBuffer.size());
|
||||
args.scratchBuffer = scratchBuffer.data();
|
||||
args.scratchBufferBytes = size.scratchBufferBytes;
|
||||
#endif
|
||||
|
||||
|
||||
accel = nullptr;
|
||||
size_t accelBytes = 0;
|
||||
|
||||
@@ -1217,42 +1217,37 @@ struct Scene
|
||||
{
|
||||
case BuildMode::BUILD_WORST_CASE_SIZE: {
|
||||
|
||||
accelBytes = size.accelBufferWorstCaseBytes;
|
||||
accelBytes = size.rtasBufferSizeBytesMaxRequired;
|
||||
accel = alloc_accel_buffer(accelBytes+sentinelBytes,device,context);
|
||||
memset(accel,0,accelBytes+sentinelBytes);
|
||||
|
||||
|
||||
size_t numIterations = benchmark ? 16 : 1;
|
||||
|
||||
args.numGeometries = numGeometries; //geom.size();
|
||||
args.accelBuffer = accel;
|
||||
args.accelBufferBytes = size.accelBufferWorstCaseBytes;
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
rthwifPrefetchAccelGPU(args,&queue,VERBOSE);
|
||||
#endif
|
||||
|
||||
/* build accel */
|
||||
double t0 = embree::getSeconds();
|
||||
size_t numIterations = benchmark ? 16 : 1;
|
||||
|
||||
for (size_t i=0; i<numIterations; i++)
|
||||
{
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
err = rthwifBuildAccelGPU(args,&queue,VERBOSE);
|
||||
#else
|
||||
err = rthwifBuildAccel(args);
|
||||
#endif
|
||||
err = zeRTASBuilderBuildExp(hBuilder,&args,
|
||||
scratchBuffer.data(),scratchBuffer.size(),
|
||||
accel, accelBytes,
|
||||
parallelOperation,
|
||||
nullptr, &bounds, &accelBufferBytesOut);
|
||||
|
||||
if (args.parallelOperation) {
|
||||
assert(err == RTHWIF_ERROR_PARALLEL_OPERATION);
|
||||
uint32_t maxThreads = rthwifGetParallelOperationMaxConcurrency(parallelOperation);
|
||||
tbb::parallel_for(0u, maxThreads, 1u, [&](uint32_t) {
|
||||
err = rthwifJoinParallelOperation(parallelOperation);
|
||||
});
|
||||
if (parallelOperation)
|
||||
{
|
||||
assert(err == ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE);
|
||||
|
||||
ze_rtas_parallel_operation_exp_properties_t prop = { ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES };
|
||||
err = zeRTASParallelOperationGetPropertiesExp(parallelOperation,&prop);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get max concurrency failed");
|
||||
|
||||
tbb::parallel_for(0u, prop.maxConcurrency, 1u, [&](uint32_t) {
|
||||
err = zeRTASParallelOperationJoinExp(parallelOperation);
|
||||
});
|
||||
}
|
||||
|
||||
if (err != RTHWIF_ERROR_NONE)
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("build error");
|
||||
}
|
||||
double t1 = embree::getSeconds();
|
||||
@@ -1265,7 +1260,7 @@ struct Scene
|
||||
}
|
||||
case BuildMode::BUILD_EXPECTED_SIZE: {
|
||||
|
||||
size_t bytes = size.accelBufferExpectedBytes;
|
||||
size_t bytes = size.rtasBufferSizeBytesExpected;
|
||||
for (size_t i=0; i<=16; i++) // FIXME: reduce worst cast iteration number
|
||||
{
|
||||
if (i == 16)
|
||||
@@ -1278,40 +1273,36 @@ struct Scene
|
||||
memset(accel,0,accelBytes+sentinelBytes);
|
||||
|
||||
/* build accel */
|
||||
args.numGeometries = numGeometries; //geom.size();
|
||||
args.accelBuffer = accel;
|
||||
args.accelBufferBytes = accelBytes;
|
||||
err = zeRTASBuilderBuildExp(hBuilder,&args,
|
||||
scratchBuffer.data(),scratchBuffer.size(),
|
||||
accel, accelBytes,
|
||||
parallelOperation,
|
||||
nullptr, &bounds, &accelBufferBytesOut);
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
err = rthwifBuildAccelGPU(args,&queue,VERBOSE);
|
||||
#else
|
||||
err = rthwifBuildAccel(args);
|
||||
#endif
|
||||
|
||||
if (args.parallelOperation) {
|
||||
assert(err == RTHWIF_ERROR_PARALLEL_OPERATION);
|
||||
uint32_t maxThreads = rthwifGetParallelOperationMaxConcurrency(parallelOperation);
|
||||
tbb::parallel_for(0u, maxThreads, 1u, [&](uint32_t) {
|
||||
err = rthwifJoinParallelOperation(parallelOperation);
|
||||
});
|
||||
if (parallelOperation)
|
||||
{
|
||||
assert(err == ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE);
|
||||
|
||||
ze_rtas_parallel_operation_exp_properties_t prop = { ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES };
|
||||
err = zeRTASParallelOperationGetPropertiesExp(parallelOperation,&prop);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get max concurrency failed");
|
||||
|
||||
tbb::parallel_for(0u, prop.maxConcurrency, 1u, [&](uint32_t) {
|
||||
err = zeRTASParallelOperationJoinExp(parallelOperation);
|
||||
});
|
||||
}
|
||||
|
||||
if (err != RTHWIF_ERROR_RETRY)
|
||||
if (err != ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY)
|
||||
break;
|
||||
|
||||
// PRINT(accelBufferBytesOut);
|
||||
// PRINT(bytes);
|
||||
// PRINT(size.accelBufferExpectedBytes);
|
||||
// PRINT(size.accelBufferWorstCaseBytes);
|
||||
// PRINT(accelBufferBytesOut);
|
||||
|
||||
if (accelBufferBytesOut < bytes || size.accelBufferWorstCaseBytes < accelBufferBytesOut )
|
||||
if (accelBufferBytesOut < bytes || size.rtasBufferSizeBytesMaxRequired < accelBufferBytesOut )
|
||||
throw std::runtime_error("failed build returned wrong new estimate");
|
||||
|
||||
bytes = accelBufferBytesOut;
|
||||
}
|
||||
|
||||
if (err != RTHWIF_ERROR_NONE)
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("build error");
|
||||
|
||||
break;
|
||||
@@ -1323,27 +1314,21 @@ struct Scene
|
||||
if (!benchmark)
|
||||
{
|
||||
/* scratch buffer bounds check */
|
||||
for (size_t i=size.scratchBufferBytes; i<size.scratchBufferBytes+sentinelBytes; i++) {
|
||||
if (((char*)args.scratchBuffer)[i] == 0x00) continue;
|
||||
for (size_t i=size.scratchBufferSizeBytes; i<size.scratchBufferSizeBytes+sentinelBytes; i++) {
|
||||
if (scratchBuffer[i] == 0x00) continue;
|
||||
throw std::runtime_error("scratch buffer bounds check failed");
|
||||
}
|
||||
/* acceleration structure bounds check */
|
||||
for (size_t i=accelBytes; i<accelBytes+sentinelBytes; i++) {
|
||||
if (((char*)args.accelBuffer)[i] == 0x00) continue;
|
||||
if (((char*)accel)[i] == 0x00) continue;
|
||||
throw std::runtime_error("acceleration buffer bounds check failed");
|
||||
}
|
||||
/* check if returned size of acceleration structure is correct */
|
||||
for (size_t i=accelBufferBytesOut; i<accelBytes; i++) {
|
||||
if (((char*)args.accelBuffer)[i] == 0x00) continue;
|
||||
if (((char*)accel)[i] == 0x00) continue;
|
||||
throw std::runtime_error("wrong acceleration structure size returned");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
sycl::free(scratchBuffer,context);
|
||||
sycl::free(geom ,context);
|
||||
sycl::free(desc ,context);
|
||||
#endif
|
||||
}
|
||||
|
||||
void buildTriMap(Transform local_to_world, std::vector<uint32_t> id_stack, uint32_t instUserID, bool procedural_instance, std::vector<Hit>& tri_map)
|
||||
@@ -1380,10 +1365,21 @@ struct Scene
|
||||
geometries_alloc_ty geometries_alloc;
|
||||
std::vector<std::shared_ptr<Geometry>, geometries_alloc_ty> geometries;
|
||||
|
||||
RTHWIF_AABB bounds;
|
||||
ze_rtas_aabb_exp_t bounds;
|
||||
void* accel;
|
||||
};
|
||||
|
||||
void exception_handler(sycl::exception_list exceptions)
|
||||
{
|
||||
for (std::exception_ptr const& e : exceptions) {
|
||||
try {
|
||||
std::rethrow_exception(e);
|
||||
} catch(sycl::exception const& e) {
|
||||
std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void render(uint32_t i, const TestInput& in, TestOutput& out, intel_raytracing_acceleration_structure_t accel)
|
||||
{
|
||||
intel_raytracing_ext_flag_t flags = intel_get_raytracing_ext_flag();
|
||||
@@ -1614,7 +1610,7 @@ void render_loop(uint32_t i, const TestInput& in, TestOutput& out, size_t scene_
|
||||
const float V = sycl::dot(cross(e1,v0+v1),D);
|
||||
const float W = sycl::dot(cross(e2,v1+v2),D);
|
||||
const float UVW = U+V+W;
|
||||
bool valid = (std::min(U,std::min(V,W)) >= -0.0f) | (std::max(U,std::max(V,W)) <= 0.0f);
|
||||
bool valid = (std::min(U,std::min(V,W)) >= -0.0f) || (std::max(U,std::max(V,W)) <= 0.0f);
|
||||
|
||||
/* calculate geometry normal and denominator */
|
||||
const sycl::float3 Ng = sycl::cross(e2,e1);
|
||||
@@ -1848,6 +1844,7 @@ uint32_t executeTest(sycl::device& device, sycl::queue& queue, sycl::context& co
|
||||
scene->createInstances(scene->size(),3, inst == InstancingType::SW_INSTANCING);
|
||||
|
||||
scene->addNullGeometries(16);
|
||||
|
||||
scene->buildAccel(device,context,BuildMode::BUILD_EXPECTED_SIZE,false);
|
||||
|
||||
/* calculate test input and expected output */
|
||||
@@ -1973,9 +1970,6 @@ uint32_t executeBuildTest(sycl::device& device, sycl::queue& queue, sycl::contex
|
||||
const uint32_t numPrimitives = i>10 ? i*i : i;
|
||||
std::cout << "testing " << numPrimitives << " primitives" << std::endl;
|
||||
numErrors += executeBuildTest(device,queue,context,test,buildMode,numPrimitives,i);
|
||||
if (VERBOSE)
|
||||
if (numErrors)
|
||||
exit(1);
|
||||
}
|
||||
return numErrors;
|
||||
}
|
||||
@@ -2030,13 +2024,9 @@ void* allocDispatchGlobals(sycl::device device, sycl::context context)
|
||||
size_t num_rtstacks = 1<<17; // this is sufficiently large also for PVC
|
||||
size_t dispatchGlobalSize = 128+num_rtstacks*rtstack_bytes;
|
||||
|
||||
//dispatchGlobalsPtr = this->malloc(dispatchGlobalSize, 64);
|
||||
void* dispatchGlobalsPtr = sycl::aligned_alloc(64,dispatchGlobalSize,device,context,sycl::usm::alloc::shared);
|
||||
void* dispatchGlobalsPtr = alloc_accel_buffer(dispatchGlobalSize,device,context);
|
||||
memset(dispatchGlobalsPtr, 0, dispatchGlobalSize);
|
||||
|
||||
if (((size_t)dispatchGlobalsPtr & 0xFFFF000000000000ull) != 0)
|
||||
throw std::runtime_error("internal error in RTStack allocation");
|
||||
|
||||
|
||||
DispatchGlobals* dg = (DispatchGlobals*) dispatchGlobalsPtr;
|
||||
dg->rtMemBasePtr = (uint64_t) dispatchGlobalsPtr + dispatchGlobalSize;
|
||||
dg->callStackHandlerKSP = 0;
|
||||
@@ -2052,7 +2042,7 @@ void* allocDispatchGlobals(sycl::device device, sycl::context context)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
rthwifInit();
|
||||
zeRTASInitExp();
|
||||
|
||||
TestType test = TestType::TRIANGLES_COMMITTED_HIT;
|
||||
InstancingType inst = InstancingType::NONE;
|
||||
@@ -2139,33 +2129,52 @@ int main(int argc, char* argv[])
|
||||
|
||||
/* initialize SYCL device */
|
||||
device = sycl::device(sycl::gpu_selector_v);
|
||||
sycl::queue queue = sycl::queue(device, exception_handler);
|
||||
sycl::queue queue = sycl::queue(device,exception_handler);
|
||||
context = queue.get_context();
|
||||
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
dispatchGlobalsPtr = allocDispatchGlobals(device,context);
|
||||
#endif
|
||||
|
||||
/* execute test */
|
||||
RandomSampler_init(rng,0x56FE238A);
|
||||
|
||||
parallelOperation = rthwifNewParallelOperation();
|
||||
sycl::platform platform = device.get_platform();
|
||||
ze_driver_handle_t hDriver = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(platform);
|
||||
|
||||
/* create L0 builder object */
|
||||
ze_rtas_builder_exp_desc_t builderDesc = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC };
|
||||
ze_result_t err = zeRTASBuilderCreateExp(hDriver, &builderDesc, &hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("ze_rtas_builder creation failed");
|
||||
|
||||
err = zeRTASParallelOperationCreateExp(hDriver,¶llelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("parallel operation creation failed");
|
||||
|
||||
uint32_t numErrors = 0;
|
||||
if (test >= TestType::BENCHMARK_TRIANGLES)
|
||||
{
|
||||
numErrors = executeBenchmark(device,queue,context,test);
|
||||
}
|
||||
else if (test >= TestType::BUILD_TEST_TRIANGLES)
|
||||
{
|
||||
numErrors = executeBuildTest(device,queue,context,test,buildMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
numErrors = executeTest(device,queue,context,inst,test);
|
||||
}
|
||||
|
||||
sycl::free(dispatchGlobalsPtr, context);
|
||||
err = zeRTASParallelOperationDestroyExp(parallelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("parallel operation destruction failed");
|
||||
|
||||
rthwifExit();
|
||||
/* destroy rtas builder again */
|
||||
err = zeRTASBuilderDestroyExp(hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("ze_rtas_builder destruction failed");
|
||||
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
free_accel_buffer(dispatchGlobalsPtr, context);
|
||||
#endif
|
||||
|
||||
zeRTASExitExp();
|
||||
|
||||
return numErrors ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ RTC_API_EXTERN_C RTCDevice rtcNewSYCLDevice(sycl::context context, const char* c
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT) && (defined(__SYCL_DEVICE_ONLY__) || defined(EMBREE_SYCL_RT_SIMULATION))
|
||||
|
||||
SYCL_EXTERNAL void rtcIntersect1(RTCScene hscene, struct RTCRayHit* rayhit, struct RTCIntersectArguments* args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcIntersect1(RTCScene hscene, struct RTCRayHit* rayhit, struct RTCIntersectArguments* args)
|
||||
{
|
||||
RTCIntersectArguments default_args;
|
||||
if (args == nullptr) {
|
||||
@@ -50,7 +50,7 @@ SYCL_EXTERNAL void rtcIntersect1(RTCScene hscene, struct RTCRayHit* rayhit, stru
|
||||
rtcIntersectRTHW(hscene, context, rayhit, args);
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcForwardIntersect1(const RTCIntersectFunctionNArguments* args_, RTCScene scene, struct RTCRay* iray, unsigned int instID)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcForwardIntersect1(const RTCIntersectFunctionNArguments* args_, RTCScene scene, struct RTCRay* iray, unsigned int instID)
|
||||
{
|
||||
IntersectFunctionNArguments* args = (IntersectFunctionNArguments*) args_;
|
||||
assert(args->N == 1);
|
||||
@@ -67,7 +67,7 @@ SYCL_EXTERNAL void rtcForwardIntersect1(const RTCIntersectFunctionNArguments* ar
|
||||
instance_id_stack::push(args->context, instID);
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcOccluded1(RTCScene hscene, struct RTCRay* ray, struct RTCOccludedArguments* args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcOccluded1(RTCScene hscene, struct RTCRay* ray, struct RTCOccludedArguments* args)
|
||||
{
|
||||
RTCOccludedArguments default_args;
|
||||
if (args == nullptr) {
|
||||
@@ -85,7 +85,7 @@ SYCL_EXTERNAL void rtcOccluded1(RTCScene hscene, struct RTCRay* ray, struct RTCO
|
||||
rtcOccludedRTHW(hscene, context, ray, args);
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcForwardOccluded1(const RTCOccludedFunctionNArguments* args_, RTCScene scene, struct RTCRay* iray, unsigned int instID)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcForwardOccluded1(const RTCOccludedFunctionNArguments* args_, RTCScene scene, struct RTCRay* iray, unsigned int instID)
|
||||
{
|
||||
OccludedFunctionNArguments* args = (OccludedFunctionNArguments*) args_;
|
||||
assert(args->N == 1);
|
||||
@@ -102,7 +102,7 @@ SYCL_EXTERNAL void rtcForwardOccluded1(const RTCOccludedFunctionNArguments* args
|
||||
instance_id_stack::push(args->context, instID);
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void* rtcGetGeometryUserDataFromScene (RTCScene hscene, unsigned int geomID)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void* rtcGetGeometryUserDataFromScene (RTCScene hscene, unsigned int geomID)
|
||||
{
|
||||
Scene* scene = (Scene*) hscene;
|
||||
//RTC_CATCH_BEGIN;
|
||||
@@ -117,7 +117,7 @@ SYCL_EXTERNAL void* rtcGetGeometryUserDataFromScene (RTCScene hscene, unsigned i
|
||||
//return nullptr;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcInvokeIntersectFilterFromGeometry(const RTCIntersectFunctionNArguments* args_i, const RTCFilterFunctionNArguments* filter_args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcInvokeIntersectFilterFromGeometry(const RTCIntersectFunctionNArguments* args_i, const RTCFilterFunctionNArguments* filter_args)
|
||||
{
|
||||
#if EMBREE_SYCL_GEOMETRY_CALLBACK
|
||||
IntersectFunctionNArguments* args = (IntersectFunctionNArguments*) args_i;
|
||||
@@ -126,7 +126,7 @@ SYCL_EXTERNAL void rtcInvokeIntersectFilterFromGeometry(const RTCIntersectFuncti
|
||||
#endif
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcInvokeOccludedFilterFromGeometry(const RTCOccludedFunctionNArguments* args_i, const RTCFilterFunctionNArguments* filter_args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcInvokeOccludedFilterFromGeometry(const RTCOccludedFunctionNArguments* args_i, const RTCFilterFunctionNArguments* filter_args)
|
||||
{
|
||||
#if EMBREE_SYCL_GEOMETRY_CALLBACK
|
||||
OccludedFunctionNArguments* args = (OccludedFunctionNArguments*) args_i;
|
||||
|
||||
@@ -22,12 +22,7 @@
|
||||
#include "../geometry/triangle_intersector_pluecker.h"
|
||||
|
||||
#include "rthwif_embree.h"
|
||||
|
||||
#if defined(EMBREE_SYCL_RT_VALIDATION_API)
|
||||
# include "../rthwif/rttrace/rthwif_production.h"
|
||||
#else
|
||||
# include "../rthwif/rttrace/rthwif_production_igc.h"
|
||||
#endif
|
||||
#include "../rthwif/rttrace/rttrace.h"
|
||||
|
||||
using namespace embree;
|
||||
|
||||
@@ -68,7 +63,7 @@ const constexpr uint32_t TRAV_LOOP_FEATURES =
|
||||
void use_rthwif_embree() {
|
||||
}
|
||||
|
||||
Vec3f intel_get_hit_triangle_normal(intel_ray_query_t& query, intel_hit_type_t hit_type)
|
||||
__forceinline Vec3f intel_get_hit_triangle_normal(intel_ray_query_t& query, intel_hit_type_t hit_type)
|
||||
{
|
||||
intel_float3 v[3]; intel_get_hit_triangle_vertices(query, v, hit_type);
|
||||
const Vec3f v0(v[0].x, v[0].y, v[0].z);
|
||||
@@ -77,7 +72,7 @@ Vec3f intel_get_hit_triangle_normal(intel_ray_query_t& query, intel_hit_type_t h
|
||||
return cross(v1-v0, v2-v0);
|
||||
}
|
||||
|
||||
bool intersect_user_geometry(intel_ray_query_t& query, RayHit& ray, UserGeometry* geom, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
__forceinline bool intersect_user_geometry(intel_ray_query_t& query, RayHit& ray, UserGeometry* geom, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
{
|
||||
/* perform ray mask test */
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -118,7 +113,7 @@ bool intersect_user_geometry(intel_ray_query_t& query, RayHit& ray, UserGeometry
|
||||
return false;
|
||||
}
|
||||
|
||||
bool intersect_user_geometry(intel_ray_query_t& query, Ray& ray, UserGeometry* geom, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
__forceinline bool intersect_user_geometry(intel_ray_query_t& query, Ray& ray, UserGeometry* geom, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
{
|
||||
/* perform ray mask test */
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -160,10 +155,10 @@ bool intersect_user_geometry(intel_ray_query_t& query, Ray& ray, UserGeometry* g
|
||||
}
|
||||
|
||||
template<typename Ray>
|
||||
bool intersect_instance(intel_ray_query_t& query, Ray& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID);
|
||||
__forceinline bool intersect_instance(intel_ray_query_t& query, Ray& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID);
|
||||
|
||||
template<>
|
||||
bool intersect_instance(intel_ray_query_t& query, RayHit& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
__forceinline bool intersect_instance(intel_ray_query_t& query, RayHit& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
{
|
||||
/* perform ray mask test */
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -214,7 +209,7 @@ bool intersect_instance(intel_ray_query_t& query, RayHit& ray, Instance* instanc
|
||||
}
|
||||
|
||||
template<>
|
||||
bool intersect_instance(intel_ray_query_t& query, Ray& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
__forceinline bool intersect_instance(intel_ray_query_t& query, Ray& ray, Instance* instance, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID)
|
||||
{
|
||||
/* perform ray mask test */
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -265,7 +260,7 @@ bool intersect_instance(intel_ray_query_t& query, Ray& ray, Instance* instance,
|
||||
}
|
||||
|
||||
template<typename Ray>
|
||||
bool intersect_primitive(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], Geometry* geom, sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID, const RTCFeatureFlags feature_mask)
|
||||
__forceinline bool intersect_primitive(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], Geometry* geom, sycl::private_ptr<RayQueryContext> context, uint32_t geomID, uint32_t primID, const RTCFeatureFlags feature_mask)
|
||||
{
|
||||
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
|
||||
bool filter = feature_mask & (RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS | RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_GEOMETRY);
|
||||
@@ -465,7 +460,7 @@ bool intersect_primitive(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_M
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom, uint32_t bvh_level, RayHit& ray, Hit& hit, sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
__forceinline bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom, uint32_t bvh_level, RayHit& ray, Hit& hit, sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
{
|
||||
#if defined(EMBREE_FILTER_FUNCTION)
|
||||
if (!(feature_mask & RTC_FEATURE_FLAG_FILTER_FUNCTION) || runIntersectionFilter1SYCL(geom, ray, context, hit))
|
||||
@@ -479,7 +474,7 @@ bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom, uint32_t bvh_level, Ray& ray, Hit& hit, sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
__forceinline bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom, uint32_t bvh_level, Ray& ray, Hit& hit, sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
{
|
||||
bool ishit = true;
|
||||
#if defined(EMBREE_FILTER_FUNCTION)
|
||||
@@ -492,18 +487,18 @@ bool invokeTriangleIntersectionFilter(intel_ray_query_t& query, Geometry* geom,
|
||||
return ishit;
|
||||
}
|
||||
|
||||
bool commit_potential_hit(intel_ray_query_t& query, RayHit& ray) {
|
||||
__forceinline bool commit_potential_hit(intel_ray_query_t& query, RayHit& ray) {
|
||||
intel_ray_query_commit_potential_hit_override (query, ray.tfar, float2(ray.u, ray.v));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool commit_potential_hit(intel_ray_query_t& query, Ray& ray) {
|
||||
__forceinline bool commit_potential_hit(intel_ray_query_t& query, Ray& ray) {
|
||||
intel_ray_query_commit_potential_hit_override (query, ray.tfar, float2(0.0f, 0.0f));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Ray>
|
||||
void trav_loop(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
__forceinline void trav_loop(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_MAX_INSTANCE_LEVEL_COUNT+1], sycl::private_ptr<RayQueryContext> context, const RTCFeatureFlags feature_mask)
|
||||
{
|
||||
while (!intel_is_traversal_done(query))
|
||||
{
|
||||
@@ -570,7 +565,7 @@ void trav_loop(intel_ray_query_t& query, Ray& ray, Scene* scenes[RTC_MAX_INSTANC
|
||||
}
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcIntersectRTHW(sycl::global_ptr<RTCSceneTy> hscene, sycl::private_ptr<RTCRayQueryContext> ucontext, sycl::private_ptr<RTCRayHit> rayhit_i, sycl::private_ptr<RTCIntersectArguments> args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcIntersectRTHW(sycl::global_ptr<RTCSceneTy> hscene, sycl::private_ptr<RTCRayQueryContext> ucontext, sycl::private_ptr<RTCRayHit> rayhit_i, sycl::private_ptr<RTCIntersectArguments> args)
|
||||
{
|
||||
Scene* scene = (Scene*) hscene.get();
|
||||
intel_raytracing_acceleration_structure_t hwaccel_ptr = (intel_raytracing_acceleration_structure_t) scene->hwaccel.data();
|
||||
@@ -683,7 +678,7 @@ SYCL_EXTERNAL void rtcIntersectRTHW(sycl::global_ptr<RTCSceneTy> hscene, sycl::p
|
||||
intel_ray_query_abandon(query);
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL void rtcOccludedRTHW(sycl::global_ptr<RTCSceneTy> hscene, sycl::private_ptr<RTCRayQueryContext> ucontext, sycl::private_ptr<RTCRay> ray_i, sycl::private_ptr<RTCOccludedArguments> args)
|
||||
SYCL_EXTERNAL __attribute__((always_inline)) void rtcOccludedRTHW(sycl::global_ptr<RTCSceneTy> hscene, sycl::private_ptr<RTCRayQueryContext> ucontext, sycl::private_ptr<RTCRay> ray_i, sycl::private_ptr<RTCOccludedArguments> args)
|
||||
{
|
||||
Scene* scene = (Scene*) hscene.get();
|
||||
intel_raytracing_acceleration_structure_t hwaccel_ptr = (intel_raytracing_acceleration_structure_t) scene->hwaccel.data();
|
||||
|
||||
@@ -9,17 +9,10 @@
|
||||
#include "rthwif_embree_builder.h"
|
||||
#include "../common/scene.h"
|
||||
#include "../builders/primrefgen.h"
|
||||
#include "../rthwif/rtbuild/rthwif_builder.h"
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
#include <level_zero/ze_api.h>
|
||||
#endif
|
||||
#include "../rthwif/rtbuild/rtbuild.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
|
||||
BBox3fa rthwifBuildPloc(Scene* scene, RTCBuildQuality quality_flags, Device::avector<char,64>& buffer_o, const bool two_level=false);
|
||||
|
||||
using namespace embree::isa;
|
||||
|
||||
enum Flags : uint32_t {
|
||||
@@ -34,7 +27,7 @@ namespace embree
|
||||
struct DispatchGlobals
|
||||
{
|
||||
uint64_t rtMemBasePtr; // base address of the allocated stack memory
|
||||
uint64_t callStackHandlerKSP; // this is the KSP of the continuation handler that is invoked by BTD when the read KSP is 0
|
||||
uint64_t callStackHandlerKSP; // this is the KSP of the continuation handler that is invoked by BTD when the read KSP is 0
|
||||
uint32_t asyncStackSize; // async-RT stack size in 64 byte blocks
|
||||
uint32_t numDSSRTStacks : 16; // number of stacks per DSS
|
||||
uint32_t syncRayQueryCount : 4; // number of ray queries in the sync-RT stack: 0-15 mapped to: 1-16
|
||||
@@ -43,11 +36,15 @@ namespace embree
|
||||
Flags flags; // per context control flags
|
||||
};
|
||||
|
||||
void* rthwifInit(sycl::device device, sycl::context context)
|
||||
void* zeRTASInitExp(sycl::device device, sycl::context context)
|
||||
{
|
||||
::rthwifInit();
|
||||
::zeRTASInitExp();
|
||||
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
|
||||
#if !defined(EMBREE_LEVEL_ZERO)
|
||||
# error "Level Zero required to properly allocate RTDispatchGlobals"
|
||||
#endif
|
||||
|
||||
size_t maxBVHLevels = RTC_MAX_INSTANCE_LEVEL_COUNT+1;
|
||||
|
||||
@@ -55,13 +52,9 @@ namespace embree
|
||||
size_t num_rtstacks = 1<<17; // this is sufficiently large also for PVC
|
||||
size_t dispatchGlobalSize = 128+num_rtstacks*rtstack_bytes;
|
||||
|
||||
//dispatchGlobalsPtr = this->malloc(dispatchGlobalSize, 64);
|
||||
void* dispatchGlobalsPtr = sycl::aligned_alloc(64,dispatchGlobalSize,device,context,sycl::usm::alloc::shared);
|
||||
void* dispatchGlobalsPtr = rthwifAllocAccelBuffer(dispatchGlobalSize,device,context);
|
||||
memset(dispatchGlobalsPtr, 0, dispatchGlobalSize);
|
||||
|
||||
if (((size_t)dispatchGlobalsPtr & 0xFFFF000000000000ull) != 0)
|
||||
throw_RTCError(RTC_ERROR_UNKNOWN,"internal error in RTStack allocation");
|
||||
|
||||
DispatchGlobals* dg = (DispatchGlobals*) dispatchGlobalsPtr;
|
||||
dg->rtMemBasePtr = (uint64_t) dispatchGlobalsPtr + dispatchGlobalSize;
|
||||
dg->callStackHandlerKSP = 0;
|
||||
@@ -83,9 +76,11 @@ namespace embree
|
||||
|
||||
void rthwifCleanup(void* dispatchGlobalsPtr, sycl::context context)
|
||||
{
|
||||
sycl::free(dispatchGlobalsPtr, context);
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
rthwifFreeAccelBuffer(dispatchGlobalsPtr, context);
|
||||
#endif
|
||||
|
||||
rthwifExit();
|
||||
zeRTASExitExp();
|
||||
}
|
||||
|
||||
#if defined(EMBREE_LEVEL_ZERO)
|
||||
@@ -123,15 +118,7 @@ namespace embree
|
||||
if (!ze_extension_ray_tracing)
|
||||
return -1;
|
||||
|
||||
#if 1
|
||||
|
||||
/* check if GPU device is supported */
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(sycl_device);
|
||||
const RTHWIF_FEATURES features = rthwifGetSupportedFeatures(hDevice);
|
||||
if (features == RTHWIF_FEATURES_NONE)
|
||||
return -1;
|
||||
|
||||
#else
|
||||
#if 0
|
||||
|
||||
/* check if GPU device is supported */
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(sycl_device);
|
||||
@@ -186,8 +173,13 @@ namespace embree
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
ze_result_t err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
ze_raytracing_mem_alloc_ext_desc_t rt_desc;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_RAYTRACING_EXT_PROPERTIES;
|
||||
rt_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC;
|
||||
rt_desc.pNext = nullptr;
|
||||
rt_desc.flags = 0;
|
||||
|
||||
@@ -208,10 +200,10 @@ namespace embree
|
||||
host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED;
|
||||
|
||||
void* ptr = nullptr;
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT,hDevice,&ptr);
|
||||
ze_result_t result = zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,rtasProp.rtasBufferAlignment,hDevice,&ptr);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"BVH memory allocation failed");
|
||||
_unused(result);
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"rtas memory allocation failed");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -220,17 +212,25 @@ namespace embree
|
||||
if (ptr == nullptr) return;
|
||||
ze_context_handle_t hContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(context);
|
||||
ze_result_t result = zeMemFree(hContext,ptr);
|
||||
assert(result == ZE_RESULT_SUCCESS);
|
||||
_unused(result);
|
||||
if (result != ZE_RESULT_SUCCESS)
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"rtas memory free failed");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void* rthwifAllocAccelBuffer(size_t bytes, sycl::device device, sycl::context context)
|
||||
{
|
||||
void* ptr = sycl::aligned_alloc_shared(RTHWIF_ACCELERATION_STRUCTURE_ALIGNMENT, bytes, device, context);
|
||||
void* ptr = sycl::aligned_alloc_shared(128, bytes, device, context);
|
||||
|
||||
if (ptr == nullptr)
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"BVH memory allocation failed");
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"rtas memory allocation failed");
|
||||
|
||||
auto isAddrCanonical = [](uint64_t addr) {
|
||||
return ((addr & 0xFFFF000000000000LL) == 0x0) || ((addr & 0xFFFF800000000000LL) == 0xFFFF800000000000LL);
|
||||
};
|
||||
if (!isAddrCanonical((uint64_t)ptr))
|
||||
throw_RTCError(RTC_ERROR_OUT_OF_MEMORY,"rtas memory allocation out of 48 bit address range");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -242,27 +242,27 @@ namespace embree
|
||||
|
||||
#endif
|
||||
|
||||
struct GEOMETRY_INSTANCE_DESC : RTHWIF_GEOMETRY_INSTANCE_DESC
|
||||
struct GEOMETRY_INSTANCE_DESC : ze_rtas_builder_instance_geometry_info_exp_t
|
||||
{
|
||||
RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR xfmdata;
|
||||
ze_rtas_transform_float3x4_aligned_column_major_exp_t xfmdata;
|
||||
};
|
||||
|
||||
struct GEOMETRY_TYPE
|
||||
{
|
||||
GEOMETRY_TYPE(RTHWIF_GEOMETRY_TYPE type, size_t extraBytes = 0)
|
||||
GEOMETRY_TYPE(ze_rtas_builder_geometry_type_exp_t type, size_t extraBytes = 0)
|
||||
: type(type), extraBytes(extraBytes) {}
|
||||
|
||||
RTHWIF_GEOMETRY_TYPE type;
|
||||
ze_rtas_builder_geometry_type_exp_t type;
|
||||
size_t extraBytes;
|
||||
};
|
||||
|
||||
size_t sizeof_RTHWIF_GEOMETRY(GEOMETRY_TYPE type)
|
||||
{
|
||||
switch (type.type) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return sizeof(RTHWIF_GEOMETRY_TRIANGLES_DESC)+type.extraBytes;
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return sizeof(RTHWIF_GEOMETRY_QUADS_DESC)+type.extraBytes;
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return sizeof(RTHWIF_GEOMETRY_AABBS_FPTR_DESC)+type.extraBytes;
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : return sizeof(RTHWIF_GEOMETRY_INSTANCE_DESC)+type.extraBytes;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return sizeof(ze_rtas_builder_triangles_geometry_info_exp_t)+type.extraBytes;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return sizeof(ze_rtas_builder_quads_geometry_info_exp_t)+type.extraBytes;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return sizeof(ze_rtas_builder_procedural_geometry_info_exp_t)+type.extraBytes;
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : return sizeof(ze_rtas_builder_instance_geometry_info_exp_t)+type.extraBytes;
|
||||
default: assert(false); return 0;
|
||||
}
|
||||
}
|
||||
@@ -270,66 +270,73 @@ namespace embree
|
||||
size_t alignof_RTHWIF_GEOMETRY(GEOMETRY_TYPE type)
|
||||
{
|
||||
switch (type.type) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return alignof(RTHWIF_GEOMETRY_TRIANGLES_DESC);
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return alignof(RTHWIF_GEOMETRY_QUADS_DESC);
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return alignof(RTHWIF_GEOMETRY_AABBS_FPTR_DESC);
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE : return alignof(RTHWIF_GEOMETRY_INSTANCE_DESC);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return alignof(ze_rtas_builder_triangles_geometry_info_exp_t);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return alignof(ze_rtas_builder_quads_geometry_info_exp_t);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return alignof(ze_rtas_builder_procedural_geometry_info_exp_t);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : return alignof(ze_rtas_builder_instance_geometry_info_exp_t);
|
||||
default: assert(false); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
RTHWIF_GEOMETRY_FLAGS getGeometryFlags(Scene* scene, Geometry* geom)
|
||||
ze_rtas_builder_geometry_exp_flags_t getGeometryFlags(Scene* scene, Geometry* geom)
|
||||
{
|
||||
/* invoke any hit callback when Embree filter functions are present */
|
||||
RTHWIF_GEOMETRY_FLAGS gflags = RTHWIF_GEOMETRY_FLAG_OPAQUE;
|
||||
ze_rtas_builder_geometry_exp_flags_t gflags = 0;
|
||||
if (geom->hasArgumentFilterFunctions() || geom->hasGeometryFilterFunctions())
|
||||
gflags = RTHWIF_GEOMETRY_FLAG_NONE;
|
||||
gflags = ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE;
|
||||
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
/* invoke any hit callback when high mask bits are enabled */
|
||||
if (geom->mask & 0xFFFFFF80)
|
||||
gflags = RTHWIF_GEOMETRY_FLAG_NONE;
|
||||
gflags = ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE;
|
||||
#endif
|
||||
|
||||
return gflags;
|
||||
}
|
||||
|
||||
void createGeometryDesc(RTHWIF_GEOMETRY_TRIANGLES_DESC* out, Scene* scene, TriangleMesh* geom)
|
||||
void createGeometryDesc(ze_rtas_builder_triangles_geometry_info_exp_t* out, Scene* scene, TriangleMesh* geom)
|
||||
{
|
||||
memset(out,0,sizeof(RTHWIF_GEOMETRY_TRIANGLES_DESC));
|
||||
out->geometryType = RTHWIF_GEOMETRY_TYPE_TRIANGLES;
|
||||
memset(out,0,sizeof(ze_rtas_builder_triangles_geometry_info_exp_t));
|
||||
out->geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES;
|
||||
out->geometryFlags = getGeometryFlags(scene,geom);
|
||||
out->geometryMask = mask32_to_mask8(geom->mask);
|
||||
out->triangleBuffer = (RTHWIF_TRIANGLE_INDICES*) geom->triangles.getPtr();
|
||||
out->triangleFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32;
|
||||
out->vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3;
|
||||
out->pTriangleBuffer = (ze_rtas_triangle_indices_uint32_exp_t*) geom->triangles.getPtr();
|
||||
out->triangleCount = geom->triangles.size();
|
||||
out->triangleStride = geom->triangles.getStride();
|
||||
out->vertexBuffer = (RTHWIF_FLOAT3*) geom->vertices0.getPtr();
|
||||
out->pVertexBuffer = (ze_rtas_float3_exp_t*) geom->vertices0.getPtr();
|
||||
out->vertexCount = geom->vertices0.size();
|
||||
out->vertexStride = geom->vertices0.getStride();
|
||||
}
|
||||
|
||||
void createGeometryDesc(RTHWIF_GEOMETRY_QUADS_DESC* out, Scene* scene, QuadMesh* geom)
|
||||
void createGeometryDesc(ze_rtas_builder_quads_geometry_info_exp_t* out, Scene* scene, QuadMesh* geom)
|
||||
{
|
||||
memset(out,0,sizeof(RTHWIF_GEOMETRY_QUADS_DESC));
|
||||
out->geometryType = RTHWIF_GEOMETRY_TYPE_QUADS;
|
||||
memset(out,0,sizeof(ze_rtas_builder_quads_geometry_info_exp_t));
|
||||
out->geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS;
|
||||
out->geometryFlags = getGeometryFlags(scene,geom);
|
||||
out->geometryMask = mask32_to_mask8(geom->mask);
|
||||
out->quadBuffer = (RTHWIF_QUAD_INDICES*) geom->quads.getPtr();
|
||||
out->quadFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32;
|
||||
out->vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3;
|
||||
out->pQuadBuffer = (ze_rtas_quad_indices_uint32_exp_t*) geom->quads.getPtr();
|
||||
out->quadCount = geom->quads.size();
|
||||
out->quadStride = geom->quads.getStride();
|
||||
out->vertexBuffer = (RTHWIF_FLOAT3*) geom->vertices0.getPtr();
|
||||
out->pVertexBuffer = (ze_rtas_float3_exp_t*) geom->vertices0.getPtr();
|
||||
out->vertexCount = geom->vertices0.size();
|
||||
out->vertexStride = geom->vertices0.getStride();
|
||||
}
|
||||
|
||||
void getProceduralAABB(const uint32_t primIDStart, const uint32_t primIDCount, void* geomUserPtr, void* buildUserPtr, RTHWIF_AABB* boundsOut)
|
||||
void getProceduralAABB(ze_rtas_geometry_aabbs_exp_cb_params_t* params)
|
||||
{
|
||||
BBox1f time_range = * (BBox1f*) buildUserPtr;
|
||||
Geometry* geom = (Geometry*) geomUserPtr;
|
||||
assert(params->stype == ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS);
|
||||
|
||||
BBox1f time_range = * (BBox1f*) params->pBuildUserPtr;
|
||||
Geometry* geom = (Geometry*) params->pGeomUserPtr;
|
||||
ze_rtas_aabb_exp_t* boundsOut = params->pBoundsOut;
|
||||
|
||||
for (uint32_t i=0; i<primIDCount; i++)
|
||||
for (uint32_t i=0; i<params->primIDCount; i++)
|
||||
{
|
||||
const uint32_t primID = primIDStart+i;
|
||||
const uint32_t primID = params->primID+i;
|
||||
PrimRef prim;
|
||||
range<size_t> r(primID);
|
||||
size_t k = 0;
|
||||
@@ -363,169 +370,162 @@ namespace embree
|
||||
}
|
||||
};
|
||||
|
||||
void createGeometryDescProcedural(RTHWIF_GEOMETRY_AABBS_FPTR_DESC* out, Scene* scene, Geometry* geom)
|
||||
void createGeometryDescProcedural(ze_rtas_builder_procedural_geometry_info_exp_t* out, Scene* scene, Geometry* geom)
|
||||
{
|
||||
uint32_t numPrimitives = geom->size();
|
||||
if (GridMesh* mesh = dynamic_cast<GridMesh*>(geom))
|
||||
numPrimitives = mesh->getNumTotalQuads(); // FIXME: slow
|
||||
|
||||
memset(out,0,sizeof(RTHWIF_GEOMETRY_AABBS_FPTR_DESC));
|
||||
out->geometryType = RTHWIF_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
out->geometryFlags = RTHWIF_GEOMETRY_FLAG_NONE;
|
||||
memset(out,0,sizeof(ze_rtas_builder_procedural_geometry_info_exp_t));
|
||||
out->geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL;
|
||||
out->geometryFlags = 0;
|
||||
out->geometryMask = mask32_to_mask8(geom->mask);
|
||||
out->primCount = numPrimitives;
|
||||
out->getBounds = getProceduralAABB;
|
||||
out->geomUserPtr = geom;
|
||||
out->pfnGetBoundsCb = getProceduralAABB;
|
||||
out->pGeomUserPtr = geom;
|
||||
}
|
||||
|
||||
void createGeometryDesc(GEOMETRY_INSTANCE_DESC* out, Scene* scene, Instance* geom)
|
||||
{
|
||||
assert(geom->gsubtype == AccelSet::GTY_SUBTYPE_INSTANCE_QUATERNION);
|
||||
memset(out,0,sizeof(GEOMETRY_INSTANCE_DESC));
|
||||
out->geometryType = RTHWIF_GEOMETRY_TYPE_INSTANCE;
|
||||
out->instanceFlags = RTHWIF_INSTANCE_FLAG_NONE;
|
||||
out->geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE;
|
||||
out->instanceFlags = 0;
|
||||
out->geometryMask = mask32_to_mask8(geom->mask);
|
||||
out->instanceUserID = 0;
|
||||
const AffineSpace3fa local2world = geom->getLocal2World();
|
||||
out->transformFormat = RTHWIF_TRANSFORM_FORMAT_FLOAT4X4_COLUMN_MAJOR;
|
||||
out->transform = (float*) &out->xfmdata;
|
||||
out->bounds = (RTHWIF_AABB*) &dynamic_cast<Scene*>(geom->object)->hwaccel_bounds;
|
||||
out->xfmdata = *(RTHWIF_TRANSFORM_FLOAT4X4_COLUMN_MAJOR*) &local2world;
|
||||
|
||||
out->transformFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR;
|
||||
out->pTransform = (float*) &out->xfmdata;
|
||||
out->pBounds = (ze_rtas_aabb_exp_t*) &dynamic_cast<Scene*>(geom->object)->hwaccel_bounds;
|
||||
out->xfmdata = *(ze_rtas_transform_float3x4_aligned_column_major_exp_t*) &local2world;
|
||||
EmbreeHWAccel* hwaccel = (EmbreeHWAccel*) dynamic_cast<Scene*>(geom->object)->hwaccel.data();
|
||||
out->accel = hwaccel->AccelTable[0];
|
||||
out->pAccelerationStructure = hwaccel->AccelTable[0];
|
||||
}
|
||||
|
||||
void createGeometryDesc(RTHWIF_GEOMETRY_INSTANCE_DESC* out, Scene* scene, Instance* geom)
|
||||
void createGeometryDesc(ze_rtas_builder_instance_geometry_info_exp_t* out, Scene* scene, Instance* geom)
|
||||
{
|
||||
assert(geom->gsubtype == AccelSet::GTY_SUBTYPE_DEFAULT);
|
||||
memset(out,0,sizeof(RTHWIF_GEOMETRY_INSTANCE_DESC));
|
||||
out->geometryType = RTHWIF_GEOMETRY_TYPE_INSTANCE;
|
||||
out->instanceFlags = RTHWIF_INSTANCE_FLAG_NONE;
|
||||
memset(out,0,sizeof(ze_rtas_builder_instance_geometry_info_exp_t));
|
||||
out->geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE;
|
||||
out->instanceFlags = 0;
|
||||
out->geometryMask = mask32_to_mask8(geom->mask);
|
||||
out->instanceUserID = 0;
|
||||
out->transformFormat = RTHWIF_TRANSFORM_FORMAT_FLOAT4X4_COLUMN_MAJOR;
|
||||
out->transform = (float*) &geom->local2world[0];
|
||||
out->bounds = (RTHWIF_AABB*) &dynamic_cast<Scene*>(geom->object)->hwaccel_bounds;
|
||||
out->transformFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR;
|
||||
out->pTransform = (float*) &geom->local2world[0];
|
||||
out->pBounds = (ze_rtas_aabb_exp_t*) &dynamic_cast<Scene*>(geom->object)->hwaccel_bounds;
|
||||
EmbreeHWAccel* hwaccel = (EmbreeHWAccel*) dynamic_cast<Scene*>(geom->object)->hwaccel.data();
|
||||
out->accel = hwaccel->AccelTable[0];
|
||||
out->pAccelerationStructure = hwaccel->AccelTable[0];
|
||||
}
|
||||
|
||||
void createGeometryDesc(char* out, Scene* scene, Geometry* geom, GEOMETRY_TYPE type)
|
||||
{
|
||||
switch (type.type) {
|
||||
case RTHWIF_GEOMETRY_TYPE_TRIANGLES : return createGeometryDesc((RTHWIF_GEOMETRY_TRIANGLES_DESC*)out,scene,dynamic_cast<TriangleMesh*>(geom));
|
||||
case RTHWIF_GEOMETRY_TYPE_QUADS : return createGeometryDesc((RTHWIF_GEOMETRY_QUADS_DESC*)out,scene,dynamic_cast<QuadMesh*>(geom));
|
||||
case RTHWIF_GEOMETRY_TYPE_AABBS_FPTR: return createGeometryDescProcedural((RTHWIF_GEOMETRY_AABBS_FPTR_DESC*)out,scene,geom);
|
||||
case RTHWIF_GEOMETRY_TYPE_INSTANCE:
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return createGeometryDesc((ze_rtas_builder_triangles_geometry_info_exp_t*)out,scene,dynamic_cast<TriangleMesh*>(geom));
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return createGeometryDesc((ze_rtas_builder_quads_geometry_info_exp_t*)out,scene,dynamic_cast<QuadMesh*>(geom));
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return createGeometryDescProcedural((ze_rtas_builder_procedural_geometry_info_exp_t*)out,scene,geom);
|
||||
case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE:
|
||||
if (type.extraBytes) return createGeometryDesc((GEOMETRY_INSTANCE_DESC*)out,scene,dynamic_cast<Instance*>(geom));
|
||||
else return createGeometryDesc((RTHWIF_GEOMETRY_INSTANCE_DESC*)out,scene,dynamic_cast<Instance*>(geom));
|
||||
else return createGeometryDesc((ze_rtas_builder_instance_geometry_info_exp_t*)out,scene,dynamic_cast<Instance*>(geom));
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
RTHWIF_BUILD_QUALITY convertBuildQuality(RTCBuildQuality quality_flags)
|
||||
ze_rtas_builder_build_quality_hint_exp_t convertBuildQuality(RTCBuildQuality quality_flags)
|
||||
{
|
||||
switch (quality_flags) {
|
||||
case RTC_BUILD_QUALITY_LOW : return RTHWIF_BUILD_QUALITY_LOW;
|
||||
case RTC_BUILD_QUALITY_MEDIUM : return RTHWIF_BUILD_QUALITY_MEDIUM;
|
||||
case RTC_BUILD_QUALITY_HIGH : return RTHWIF_BUILD_QUALITY_HIGH;
|
||||
case RTC_BUILD_QUALITY_REFIT : return RTHWIF_BUILD_QUALITY_LOW;
|
||||
default : return RTHWIF_BUILD_QUALITY_MEDIUM;
|
||||
case RTC_BUILD_QUALITY_LOW : return ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_LOW;
|
||||
case RTC_BUILD_QUALITY_MEDIUM : return ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM;
|
||||
case RTC_BUILD_QUALITY_HIGH : return ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH;
|
||||
case RTC_BUILD_QUALITY_REFIT : return ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_LOW;
|
||||
default : return ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
RTHWIF_BUILD_FLAGS convertBuildFlags(RTCSceneFlags scene_flags)
|
||||
ze_rtas_builder_build_op_exp_flags_t convertBuildFlags(RTCSceneFlags scene_flags, RTCBuildQuality quality_flags)
|
||||
{
|
||||
uint32_t result = RTHWIF_BUILD_FLAG_NONE;
|
||||
if (scene_flags & RTC_SCENE_FLAG_DYNAMIC) result |= RTHWIF_BUILD_FLAG_DYNAMIC;
|
||||
if (scene_flags & RTC_SCENE_FLAG_COMPACT) result |= RTHWIF_BUILD_FLAG_COMPACT;
|
||||
return (RTHWIF_BUILD_FLAGS) result;
|
||||
ze_rtas_builder_build_op_exp_flags_t result = 0;
|
||||
if (scene_flags & RTC_SCENE_FLAG_COMPACT) result |= ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_COMPACT;
|
||||
|
||||
/* only in high quality build mode spatial splits are allowed in Embree */
|
||||
if (quality_flags != RTC_BUILD_QUALITY_HIGH)
|
||||
result |= ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
|
||||
void exception_handler(sycl::exception_list exceptions)
|
||||
{
|
||||
for (std::exception_ptr const& e : exceptions) {
|
||||
try {
|
||||
std::rethrow_exception(e);
|
||||
} catch(sycl::exception const& e) {
|
||||
std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BBox3f rthwifBuild(Scene* scene, AccelBuffer& accel)
|
||||
{
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
DeviceGPU *gpu_device = dynamic_cast<DeviceGPU*>(scene->device);
|
||||
sycl::device &sycl_device = gpu_device->getGPUDevice();
|
||||
sycl::property_list PropList;
|
||||
if (gpu_device->verbose) PropList = { sycl::property::queue::enable_profiling() };
|
||||
sycl::queue sycl_queue(sycl_device, exception_handler, PropList );
|
||||
#endif
|
||||
{
|
||||
DeviceGPU* gpuDevice = dynamic_cast<DeviceGPU*>(scene->device);
|
||||
if (gpuDevice == nullptr) throw std::runtime_error("internal error");
|
||||
|
||||
sycl::device device = gpuDevice->getGPUDevice();
|
||||
ze_device_handle_t hDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device);
|
||||
sycl::platform platform = device.get_platform();
|
||||
ze_driver_handle_t hDriver = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(platform);
|
||||
|
||||
/* create L0 builder object */
|
||||
ze_rtas_builder_exp_desc_t builderDesc = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC };
|
||||
ze_rtas_builder_exp_handle_t hBuilder = nullptr;
|
||||
ze_result_t err = zeRTASBuilderCreateExp(hDriver, &builderDesc, &hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("ze_rtas_builder creation failed");
|
||||
|
||||
auto getType = [&](unsigned int geomID) -> GEOMETRY_TYPE
|
||||
{
|
||||
/* no HW support for MB yet */
|
||||
if (scene->get(geomID)->numTimeSegments() > 0)
|
||||
return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL;
|
||||
|
||||
switch (scene->get(geomID)->getType()) {
|
||||
case Geometry::GTY_FLAT_LINEAR_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ROUND_LINEAR_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_LINEAR_CURVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_CONE_LINEAR_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_FLAT_LINEAR_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ROUND_LINEAR_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_LINEAR_CURVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_CONE_LINEAR_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_FLAT_BEZIER_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ROUND_BEZIER_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_BEZIER_CURVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_FLAT_BEZIER_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ROUND_BEZIER_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_BEZIER_CURVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_FLAT_BSPLINE_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ROUND_BSPLINE_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_BSPLINE_CURVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_FLAT_BSPLINE_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ROUND_BSPLINE_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_BSPLINE_CURVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_FLAT_HERMITE_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ROUND_HERMITE_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_HERMITE_CURVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_FLAT_HERMITE_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ROUND_HERMITE_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_HERMITE_CURVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_FLAT_CATMULL_ROM_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ROUND_CATMULL_ROM_CURVE : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_FLAT_CATMULL_ROM_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ROUND_CATMULL_ROM_CURVE : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_TRIANGLE_MESH: return RTHWIF_GEOMETRY_TYPE_TRIANGLES; break;
|
||||
case Geometry::GTY_QUAD_MESH : return RTHWIF_GEOMETRY_TYPE_QUADS; break;
|
||||
case Geometry::GTY_GRID_MESH : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_SUBDIV_MESH : assert(false); return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_TRIANGLE_MESH: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES; break;
|
||||
case Geometry::GTY_QUAD_MESH : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS; break;
|
||||
case Geometry::GTY_GRID_MESH : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_SUBDIV_MESH : assert(false); return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_SPHERE_POINT : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_DISC_POINT : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_ORIENTED_DISC_POINT: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_SPHERE_POINT : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_DISC_POINT : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_ORIENTED_DISC_POINT: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
case Geometry::GTY_USER_GEOMETRY : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_USER_GEOMETRY : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
|
||||
#if RTC_MAX_INSTANCE_LEVEL_COUNT < 2
|
||||
case Geometry::GTY_INSTANCE_CHEAP :
|
||||
case Geometry::GTY_INSTANCE_EXPENSIVE: {
|
||||
Instance* instance = scene->get<Instance>(geomID);
|
||||
EmbreeHWAccel* object = (EmbreeHWAccel*)((Scene*)instance->object)->hwaccel.data();
|
||||
if (object->numTimeSegments > 1) return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; // we need to handle instances in procedural mode if instanced scene has motion blur
|
||||
if (instance->mask & 0xFFFFFF80) return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; // we need to handle instances in procedural mode if high mask bits are set
|
||||
if (object->numTimeSegments > 1) return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; // we need to handle instances in procedural mode if instanced scene has motion blur
|
||||
if (instance->mask & 0xFFFFFF80) return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; // we need to handle instances in procedural mode if high mask bits are set
|
||||
else if (instance->gsubtype == AccelSet::GTY_SUBTYPE_INSTANCE_QUATERNION)
|
||||
return GEOMETRY_TYPE(RTHWIF_GEOMETRY_TYPE_INSTANCE,sizeof(GEOMETRY_INSTANCE_DESC)-sizeof(RTHWIF_GEOMETRY_INSTANCE_DESC));
|
||||
else return RTHWIF_GEOMETRY_TYPE_INSTANCE;
|
||||
return GEOMETRY_TYPE(ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE,sizeof(GEOMETRY_INSTANCE_DESC)-sizeof(ze_rtas_builder_instance_geometry_info_exp_t));
|
||||
else return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE;
|
||||
}
|
||||
#else
|
||||
case Geometry::GTY_INSTANCE_CHEAP : return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_INSTANCE_EXPENSIVE: return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR; break;
|
||||
case Geometry::GTY_INSTANCE_CHEAP : return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
case Geometry::GTY_INSTANCE_EXPENSIVE: return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; break;
|
||||
#endif
|
||||
|
||||
default: assert(false); return RTHWIF_GEOMETRY_TYPE_AABBS_FPTR;
|
||||
default: assert(false); return ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -550,22 +550,12 @@ namespace embree
|
||||
totalBytes += sizeof_RTHWIF_GEOMETRY(type);
|
||||
}
|
||||
|
||||
const size_t numGeometries = scene->size();
|
||||
|
||||
/* fill geomdesc buffers */
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
const size_t geomDescrBytes = sizeof(RTHWIF_GEOMETRY_DESC*)*numGeometries;
|
||||
RTHWIF_GEOMETRY_DESC** geomDescr = (RTHWIF_GEOMETRY_DESC**)sycl::aligned_alloc_shared(64,geomDescrBytes,gpu_device->getGPUDevice(),gpu_device->getGPUContext(),sycl::ext::oneapi::property::usm::device_read_only());
|
||||
assert(geomDescr);
|
||||
char *geomDescrData = (char*)sycl::aligned_alloc_shared(64,totalBytes,gpu_device->getGPUDevice(),gpu_device->getGPUContext(),sycl::ext::oneapi::property::usm::device_read_only());
|
||||
assert(geomDescrData);
|
||||
#else
|
||||
std::vector<RTHWIF_GEOMETRY_DESC*> geomDescr(numGeometries);
|
||||
/* fill geomdesc buffers */
|
||||
std::vector<ze_rtas_builder_geometry_info_exp_t*> geomDescr(scene->size());
|
||||
std::vector<char> geomDescrData(totalBytes);
|
||||
#endif
|
||||
|
||||
|
||||
size_t offset = 0;
|
||||
for (size_t geomID=0; geomID<numGeometries; geomID++) // FIXME: slow if numGeometries is large
|
||||
for (size_t geomID=0; geomID<scene->size(); geomID++)
|
||||
{
|
||||
geomDescr[geomID] = nullptr;
|
||||
Geometry* geom = scene->get(geomID);
|
||||
@@ -574,72 +564,45 @@ namespace embree
|
||||
const GEOMETRY_TYPE type = getType(geomID);
|
||||
align(offset,alignof_RTHWIF_GEOMETRY(type));
|
||||
createGeometryDesc(&geomDescrData[offset],scene,scene->get(geomID),type);
|
||||
geomDescr[geomID] = (RTHWIF_GEOMETRY_DESC*) &geomDescrData[offset];
|
||||
geomDescr[geomID] = (ze_rtas_builder_geometry_info_exp_t*) &geomDescrData[offset];
|
||||
offset += sizeof_RTHWIF_GEOMETRY(type);
|
||||
#if !defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
assert(offset <= geomDescrData.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
RTHWIF_PARALLEL_OPERATION parallelOperation = nullptr;
|
||||
#else
|
||||
RTHWIF_PARALLEL_OPERATION parallelOperation = rthwifNewParallelOperation();
|
||||
#endif
|
||||
ze_rtas_parallel_operation_exp_handle_t parallelOperation = nullptr;
|
||||
err = zeRTASParallelOperationCreateExp(hDriver, ¶llelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("parallel operation creation failed");
|
||||
|
||||
ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES };
|
||||
err = zeDeviceGetRTASPropertiesExp(hDevice, &rtasProp );
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get rtas device properties failed");
|
||||
|
||||
/* estimate static accel size */
|
||||
BBox1f time_range(0,1);
|
||||
RTHWIF_AABB bounds;
|
||||
RTHWIF_BUILD_ACCEL_ARGS args;
|
||||
ze_rtas_aabb_exp_t bounds;
|
||||
ze_rtas_builder_build_op_exp_desc_t args;
|
||||
memset(&args,0,sizeof(args));
|
||||
args.structBytes = sizeof(args);
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geomDescr;
|
||||
#else
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geomDescr.data();
|
||||
#endif
|
||||
args.numGeometries = numGeometries;
|
||||
args.accelBuffer = nullptr;
|
||||
args.accelBufferBytes = 0;
|
||||
args.scratchBuffer = nullptr;
|
||||
args.scratchBufferBytes = 0;
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
args.quality = gpu_device->quality_flags == RTC_BUILD_QUALITY_LOW ? RTHWIF_BUILD_QUALITY_LOW : RTHWIF_BUILD_QUALITY_MEDIUM;
|
||||
#else
|
||||
args.quality = convertBuildQuality(scene->quality_flags);
|
||||
#endif
|
||||
args.flags = convertBuildFlags(scene->scene_flags);
|
||||
args.parallelOperation = parallelOperation;
|
||||
args.boundsOut = &bounds;
|
||||
args.buildUserPtr = &time_range;
|
||||
args.stype = ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC;
|
||||
args.pNext = nullptr;
|
||||
args.rtasFormat = rtasProp.rtasFormat;
|
||||
args.buildQuality = convertBuildQuality(scene->quality_flags);
|
||||
args.buildFlags = convertBuildFlags(scene->scene_flags,scene->quality_flags);
|
||||
args.ppGeometries = (const ze_rtas_builder_geometry_info_exp_t**) geomDescr.data();
|
||||
args.numGeometries = geomDescr.size();
|
||||
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
||||
args.dispatchGlobalsPtr = dynamic_cast<DeviceGPU*>(scene->device)->dispatchGlobalsPtr;
|
||||
#endif
|
||||
|
||||
RTHWIF_ACCEL_SIZE sizeTotal;
|
||||
memset(&sizeTotal,0,sizeof(RTHWIF_ACCEL_SIZE));
|
||||
sizeTotal.structBytes = sizeof(RTHWIF_ACCEL_SIZE);
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
RTHWIF_ERROR err = rthwifGetAccelSizeGPU(args,sizeTotal,&sycl_queue,gpu_device->verbose);
|
||||
#else
|
||||
RTHWIF_ERROR err = rthwifGetAccelSize(args,sizeTotal);
|
||||
#endif
|
||||
if (err != RTHWIF_ERROR_NONE)
|
||||
ze_rtas_builder_exp_properties_t sizeTotal = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES };
|
||||
err = zeRTASBuilderGetBuildPropertiesExp(hBuilder,&args,&sizeTotal);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw_RTCError(RTC_ERROR_UNKNOWN,"BVH size estimate failed");
|
||||
|
||||
/* allocate scratch buffer */
|
||||
std::vector<char> scratchBuffer(sizeTotal.scratchBufferSizeBytes);
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
// === scratch buffer ===
|
||||
char *scratchBuffer = (char*)sycl::aligned_alloc(64,sizeTotal.scratchBufferBytes,gpu_device->getGPUDevice(),gpu_device->getGPUContext(),gpu_device->verbose > 1 ? sycl::usm::alloc::shared : sycl::usm::alloc::device);
|
||||
assert(scratchBuffer);
|
||||
args.scratchBuffer = scratchBuffer;
|
||||
args.scratchBufferBytes = sizeTotal.scratchBufferBytes;
|
||||
#else
|
||||
std::vector<char> scratchBuffer(sizeTotal.scratchBufferBytes);
|
||||
args.scratchBuffer = scratchBuffer.data();
|
||||
args.scratchBufferBytes = scratchBuffer.size();
|
||||
#endif
|
||||
|
||||
size_t headerBytes = sizeof(EmbreeHWAccel) + std::max(1u,maxTimeSegments)*8;
|
||||
align(headerBytes,128);
|
||||
|
||||
@@ -648,99 +611,78 @@ namespace embree
|
||||
while (true)
|
||||
{
|
||||
/* estimate size of all mblur BVHs */
|
||||
RTHWIF_ACCEL_SIZE size;
|
||||
size.accelBufferExpectedBytes = maxTimeSegments*sizeTotal.accelBufferExpectedBytes;
|
||||
size.accelBufferWorstCaseBytes = maxTimeSegments*sizeTotal.accelBufferWorstCaseBytes;
|
||||
size_t bytes = headerBytes+size.accelBufferExpectedBytes;
|
||||
|
||||
ze_rtas_builder_exp_properties_t size = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES };
|
||||
size.rtasBufferSizeBytesExpected = maxTimeSegments*sizeTotal.rtasBufferSizeBytesExpected;
|
||||
size.rtasBufferSizeBytesMaxRequired = maxTimeSegments*sizeTotal.rtasBufferSizeBytesMaxRequired;
|
||||
size_t bytes = headerBytes+size.rtasBufferSizeBytesExpected;
|
||||
|
||||
/* allocate BVH data */
|
||||
if (accel.size() < bytes) accel.resize(bytes);
|
||||
|
||||
#if !defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
memset(accel.data(),0,accel.size()); // FIXME: not required
|
||||
#endif
|
||||
|
||||
|
||||
/* build BVH for each time segment */
|
||||
for (uint32_t i=0; i<maxTimeSegments; i++)
|
||||
{
|
||||
const float t0 = float(i+0)/float(maxTimeSegments);
|
||||
const float t1 = float(i+1)/float(maxTimeSegments);
|
||||
time_range = BBox1f(t0,t1);
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geomDescr;
|
||||
#else
|
||||
args.geometries = (const RTHWIF_GEOMETRY_DESC**) geomDescr.data();
|
||||
#endif
|
||||
args.numGeometries = numGeometries;
|
||||
args.accelBuffer = accel.data() + headerBytes + i*sizeTotal.accelBufferExpectedBytes; // why + headerBytes?
|
||||
|
||||
args.accelBufferBytes = sizeTotal.accelBufferExpectedBytes;
|
||||
bounds = { { INFINITY, INFINITY, INFINITY }, { -INFINITY, -INFINITY, -INFINITY } }; // why does the host initializes the bounds
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
err = rthwifPrefetchAccelGPU(args,&sycl_queue,gpu_device->verbose); //triggers additional USM transfers
|
||||
#endif
|
||||
void* accelBuffer = accel.data() + headerBytes + i*sizeTotal.rtasBufferSizeBytesExpected;
|
||||
size_t accelBufferBytes = sizeTotal.rtasBufferSizeBytesExpected;
|
||||
bounds = { { INFINITY, INFINITY, INFINITY }, { -INFINITY, -INFINITY, -INFINITY } };
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
err = rthwifBuildAccelGPU(args,&sycl_queue,gpu_device->verbose);
|
||||
#else
|
||||
err = rthwifBuildAccel(args);
|
||||
|
||||
#endif
|
||||
|
||||
if (args.parallelOperation) {
|
||||
assert(err == RTHWIF_ERROR_PARALLEL_OPERATION);
|
||||
uint32_t maxThreads = rthwifGetParallelOperationMaxConcurrency(parallelOperation);
|
||||
parallel_for(maxThreads, [&](uint32_t) { err = rthwifJoinParallelOperation(parallelOperation); });
|
||||
}
|
||||
|
||||
if (err == RTHWIF_ERROR_NONE) // added if
|
||||
fullBounds.extend(*(BBox3f*) args.boundsOut);
|
||||
|
||||
if (err == RTHWIF_ERROR_RETRY)
|
||||
err = zeRTASBuilderBuildExp(hBuilder,&args,
|
||||
scratchBuffer.data(),scratchBuffer.size(),
|
||||
accelBuffer, accelBufferBytes,
|
||||
parallelOperation,
|
||||
&time_range, &bounds, nullptr);
|
||||
if (parallelOperation)
|
||||
{
|
||||
if (sizeTotal.accelBufferExpectedBytes == sizeTotal.accelBufferWorstCaseBytes)
|
||||
assert(err == ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE);
|
||||
|
||||
ze_rtas_parallel_operation_exp_properties_t prop = { ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES };
|
||||
err = zeRTASParallelOperationGetPropertiesExp(parallelOperation,&prop);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("get max concurrency failed");
|
||||
|
||||
parallel_for(prop.maxConcurrency, [&](uint32_t) { err = zeRTASParallelOperationJoinExp(parallelOperation); });
|
||||
}
|
||||
|
||||
fullBounds.extend(*(BBox3f*) &bounds);
|
||||
|
||||
if (err == ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY)
|
||||
{
|
||||
if (sizeTotal.rtasBufferSizeBytesExpected == sizeTotal.rtasBufferSizeBytesMaxRequired)
|
||||
throw_RTCError(RTC_ERROR_UNKNOWN,"build error");
|
||||
|
||||
sizeTotal.accelBufferExpectedBytes = std::min(sizeTotal.accelBufferWorstCaseBytes,(size_t(1.2*sizeTotal.accelBufferExpectedBytes)+127)&-128);
|
||||
sizeTotal.rtasBufferSizeBytesExpected = std::min(sizeTotal.rtasBufferSizeBytesMaxRequired,(size_t(1.2*sizeTotal.rtasBufferSizeBytesExpected)+127)&-128);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err != RTHWIF_ERROR_NONE) break;
|
||||
if (err != ZE_RESULT_SUCCESS) break;
|
||||
}
|
||||
if (err != RTHWIF_ERROR_RETRY) break;
|
||||
if (err != ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY) break;
|
||||
}
|
||||
|
||||
if (err != RTHWIF_ERROR_NONE)
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw_RTCError(RTC_ERROR_UNKNOWN,"build error");
|
||||
|
||||
// === moving this to device code prevents USM down and up transfer of accel ===
|
||||
/* destroy parallel operation */
|
||||
err = zeRTASParallelOperationDestroyExp(parallelOperation);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("parallel operation destruction failed");
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
EmbreeHWAccel hwaccel;
|
||||
hwaccel.numTimeSegments = maxTimeSegments;
|
||||
for (size_t i=0; i<maxTimeSegments; i++)
|
||||
hwaccel.AccelTable[i] = (char*)accel.data() + headerBytes + i*sizeTotal.accelBufferExpectedBytes;
|
||||
sycl::event queue_event = sycl_queue.memcpy(accel.data(),&hwaccel,sizeof(EmbreeHWAccel));
|
||||
queue_event.wait();
|
||||
#else
|
||||
/* destroy rtas builder again */
|
||||
err = zeRTASBuilderDestroyExp(hBuilder);
|
||||
if (err != ZE_RESULT_SUCCESS)
|
||||
throw std::runtime_error("ze_rtas_builder destruction failed");
|
||||
|
||||
EmbreeHWAccel* hwaccel = (EmbreeHWAccel*) accel.data();
|
||||
hwaccel->numTimeSegments = maxTimeSegments;
|
||||
|
||||
for (size_t i=0; i<maxTimeSegments; i++)
|
||||
hwaccel->AccelTable[i] = (char*)hwaccel + headerBytes + i*sizeTotal.accelBufferExpectedBytes;
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#if defined(EMBREE_SYCL_GPU_BVH_BUILDER)
|
||||
sycl::free(geomDescr ,gpu_device->getGPUContext());
|
||||
sycl::free(geomDescrData ,gpu_device->getGPUContext());
|
||||
sycl::free(scratchBuffer ,gpu_device->getGPUContext());
|
||||
#endif
|
||||
hwaccel->AccelTable[i] = (char*)hwaccel + headerBytes + i*sizeTotal.rtasBufferSizeBytesExpected;
|
||||
|
||||
return fullBounds;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace embree
|
||||
|
||||
typedef vector_t<char,AccelAllocator<char>> AccelBuffer;
|
||||
|
||||
void* rthwifInit(sycl::device device, sycl::context context);
|
||||
void* zeRTASInitExp(sycl::device device, sycl::context context);
|
||||
|
||||
void rthwifCleanup(void* dispatchGlobalsPtr, sycl::context context);
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCBufferType" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCBufferType" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCFormat \- specifies format of data in buffers
|
||||
RTCFormat - specifies format of data in buffers
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCCurveFlags" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCCurveFlags" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCCurveFlags \- per segment flags for curve geometry
|
||||
RTCCurveFlags - per segment flags for curve geometry
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -14,11 +14,14 @@ RTCCurveFlags \- per segment flags for curve geometry
|
||||
.nf
|
||||
\f[C]
|
||||
#include <embree4/rtcore.h>
|
||||
|
||||
enum RTCCurveFlags
|
||||
{
|
||||
RTC_CURVE_FLAG_NEIGHBOR_LEFT = (1 << 0),
|
||||
RTC_CURVE_FLAG_NEIGHBOR_RIGHT = (1 << 1)
|
||||
};
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
enum RTCCurveFlags { RTC_CURVE_FLAG_NEIGHBOR_LEFT = (1 << 0),
|
||||
RTC_CURVE_FLAG_NEIGHBOR_RIGHT = (1 << 1) };
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The RTCCurveFlags type is used for linear curves to determine if the
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCFeatureFlags" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCFeatureFlags - specifies features to enable
|
||||
for ray queries
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
#include <embree4/rtcore_ray.h>
|
||||
|
||||
enum RTCFeatureFlags
|
||||
{
|
||||
RTC_FEATURE_FLAG_NONE = 0,
|
||||
|
||||
RTC_FEATURE_FLAG_MOTION_BLUR = 1 << 0,
|
||||
|
||||
RTC_FEATURE_FLAG_TRIANGLE = 1 << 1,
|
||||
RTC_FEATURE_FLAG_QUAD = 1 << 2,
|
||||
RTC_FEATURE_FLAG_GRID = 1 << 3,
|
||||
RTC_FEATURE_FLAG_SUBDIVISION = 1 << 4,
|
||||
RTC_FEATURE_FLAG_POINT = ... ,
|
||||
RTC_FEATURE_FLAG_CURVES = ... ,
|
||||
|
||||
RTC_FEATURE_FLAG_CONE_LINEAR_CURVE = 1 << 5,
|
||||
RTC_FEATURE_FLAG_ROUND_LINEAR_CURVE = 1 << 6,
|
||||
RTC_FEATURE_FLAG_FLAT_LINEAR_CURVE = 1 << 7,
|
||||
|
||||
RTC_FEATURE_FLAG_ROUND_BEZIER_CURVE = 1 << 8,
|
||||
RTC_FEATURE_FLAG_FLAT_BEZIER_CURVE = 1 << 9,
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_BEZIER_CURVE = 1 << 10,
|
||||
|
||||
RTC_FEATURE_FLAG_ROUND_BSPLINE_CURVE = 1 << 11,
|
||||
RTC_FEATURE_FLAG_FLAT_BSPLINE_CURVE = 1 << 12,
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_BSPLINE_CURVE = 1 << 13,
|
||||
|
||||
RTC_FEATURE_FLAG_ROUND_HERMITE_CURVE = 1 << 14,
|
||||
RTC_FEATURE_FLAG_FLAT_HERMITE_CURVE = 1 << 15,
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_HERMITE_CURVE = 1 << 16,
|
||||
|
||||
RTC_FEATURE_FLAG_ROUND_CATMULL_ROM_CURVE = 1 << 17,
|
||||
RTC_FEATURE_FLAG_FLAT_CATMULL_ROM_CURVE = 1 << 18,
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_CATMULL_ROM_CURVE = 1 << 19,
|
||||
|
||||
RTC_FEATURE_FLAG_SPHERE_POINT = 1 << 20,
|
||||
RTC_FEATURE_FLAG_DISC_POINT = 1 << 21,
|
||||
RTC_FEATURE_FLAG_ORIENTED_DISC_POINT = 1 << 22,
|
||||
|
||||
RTC_FEATURE_FLAG_ROUND_CURVES = ... ,
|
||||
RTC_FEATURE_FLAG_FLAT_CURVES = ... ,
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_CURVES = ... ,
|
||||
|
||||
RTC_FEATURE_FLAG_LINEAR_CURVES = ... ,
|
||||
RTC_FEATURE_FLAG_BEZIER_CURVES = ... ,
|
||||
RTC_FEATURE_FLAG_BSPLINE_CURVES = ... ,
|
||||
RTC_FEATURE_FLAG_HERMITE_CURVES = ... ,
|
||||
|
||||
RTC_FEATURE_FLAG_INSTANCE = 1 << 23,
|
||||
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS = 1 << 24,
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_GEOMETRY = 1 << 25,
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION = ... ,
|
||||
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS = 1 << 26,
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY = 1 << 27,
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY = ... ,
|
||||
|
||||
RTC_FEATURE_FLAG_32_BIT_RAY_MASK = 1 << 28,
|
||||
|
||||
RTC_FEATURE_FLAG_ALL = 0xffffffff
|
||||
};
|
||||
\f[R]
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]RTCFeatureFlags\f[R] enum specify a bit mask to enable specific
|
||||
ray tracing features for ray query operations.
|
||||
The feature flags are passed to the \f[C]rtcIntersect1/4/8/16\f[R] and
|
||||
\f[C]rtcOccluded1/4/8/16\f[R] functions through the
|
||||
\f[C]RTCIntersectArguments\f[R] and \f[C]RTCOccludedArguments\f[R]
|
||||
structures.
|
||||
Only a ray tracing feature whose bit is enabled in the feature mask can
|
||||
get used.
|
||||
If a feature bit is not set, the behaviour is undefined, thus the
|
||||
feature may work or not.
|
||||
To enable multiple features the respective features have to get combined
|
||||
using a bitwise \f[C]OR\f[R] operation.
|
||||
.PP
|
||||
The purpose of feature flags is to reduce code size on the GPU by
|
||||
enabling just the features required to render the scene.
|
||||
On the CPU there is no need to use feature flags, and the default of all
|
||||
features enabled (\f[C]RTC_FEATURE_FLAG_ALL\f[R]) can just be kept.
|
||||
.PP
|
||||
The following features can get enabled using feature flags:
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_MOTION_BLUR: Enables motion blur for all geometry
|
||||
types.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_TRIANGLE: Enables triangle geometries
|
||||
(RTC_GEOMETRY_TYPE_TRIANGLE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_QUAD: Enables quad geometries (RTC_GEOMETRY_TYPE_QUAD).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_GRID: Enables grid geometries (RTC_GEOMETRY_TYPE_GRID).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_SUBDIVISION: Enables subdivision geometries
|
||||
(RTC_GEOMETRY_TYPE_SUBDIVISION).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_POINT: Enables all point geometry types
|
||||
(RTC_GEOMETRY_TYPE_XXX_POINT)
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_CURVES: Enables all curve geometry types
|
||||
(RTC_GEOMETRY_TYPE_XXX_YYY_CURVE)
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_CURVES: Enables all round curves
|
||||
(RTC_GEOMETRY_TYPE_ROUND_XXX_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_CURVES: Enables all flat curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_XXX_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_CURVES: Enables all normal oriented
|
||||
curves (RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_XXX_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_LINEAR_CURVES: Enables all linear curves
|
||||
(RTC_GEOMETRY_TYPE_XXX_LINEAR_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_BEZIER_CURVES: Enables all B\['e]zier curves
|
||||
(RTC_GEOMETRY_TYPE_XXX_BEZIER_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_BSPLINE_CURVES: Enables all B-spline curves
|
||||
(RTC_GEOMETRY_TYPE_XXX_BSPLINE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_HERMITE_CURVES: Enables all Hermite curves
|
||||
(RTC_GEOMETRY_TYPE_XXX_HERMITE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_CONE_LINEAR_CURVE: Enables cone geometry type
|
||||
(RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_LINEAR_CURVE: Enables round linear curves
|
||||
(RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_LINEAR_CURVE: Enables flat linear curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_BEZIER_CURVE: Enables round B\['e]zier curves
|
||||
(RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_BEZIER_CURVE: Enables flat B\['e]zier curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_BEZIER_CURVE: Enables normal oriented
|
||||
B\['e]zier curves (RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_BSPLINE_CURVE: Enables round B-spline curves
|
||||
(RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_BSPLINE_CURVE: Enables flat B-spline curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_BSPLINE_CURVE: Enables normal oriented
|
||||
B-spline curves (RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_HERMITE_CURVE: Enables round Hermite curves
|
||||
(RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_HERMITE_CURVE: Enables flat Hermite curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_HERMITE_CURVE: Enables normal oriented
|
||||
Hermite curves (RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ROUND_CATMULL_ROM_CURVE: Enables round Catmull Rom
|
||||
curves (RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FLAT_CATMULL_ROM_CURVE: Enables flat Catmull Rom curves
|
||||
(RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_NORMAL_ORIENTED_CATMULL_ROM_CURVE: Enables normal
|
||||
oriented Catmull Rom curves
|
||||
(RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_SPHERE_POINT: Enables sphere geometry type
|
||||
(RTC_GEOMETRY_TYPE_SPHERE_POINT).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_DISC_POINT: Enables disc geometry type
|
||||
(RTC_GEOMETRY_TYPE_DISC_POINT).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ORIENTED_DISC_POINT: Enables oriented disc geometry
|
||||
types (RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_INSTANCE: Enables instance geometries
|
||||
(RTC_GEOMETRY_TYPE_INSTANCE).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS: Enables filter functions
|
||||
passed through intersect arguments.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION_IN_GEOMETRY: Enable filter functions
|
||||
passed through geometry.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_FILTER_FUNCTION: Enables filter functions (argument and
|
||||
geometry version).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS: Enables
|
||||
RTC_GEOMETRY_TYPE_USER with function pointer passed through intersect
|
||||
arguments.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY: Enables
|
||||
RTC_GEOMETRY_TYPE_USER with function pointer passed through geometry
|
||||
object.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_USER_GEOMETRY: Enables RTC_GEOMETRY_TYPE_USER
|
||||
geometries (both argument and geometry callback versions).
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_32_BIT_RAY_MASK: Enables full 32 bit ray masks.
|
||||
If not used, only the lower 7 bits in the ray mask are handled
|
||||
correctly.
|
||||
.IP \[bu] 2
|
||||
RTC_FEATURE_FLAG_ALL: Enables all features (default).
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
[rtcIntersect1], [rtcIntersect4/8/16], [rtcOccluded1],
|
||||
[rtcOccluded4/8/16],
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCFormat" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCFormat" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCFormat \- specifies format of data in buffers
|
||||
RTCFormat - specifies format of data in buffers
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -46,10 +46,9 @@ enum RTCFormat
|
||||
RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR,
|
||||
|
||||
RTC_FORMAT_GRID,
|
||||
};
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
};
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]RTFormat\f[R] structure defines the data format stored in data
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCHit" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCHit" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCHit \- single hit structure
|
||||
RTCHit - single hit structure
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -48,8 +48,8 @@ hit structure in structure of array (SOA) layout for hit packets of size
|
||||
4 (\f[C]RTCHit4\f[R] type), size 8 (\f[C]RTCHit8\f[R] type), and size 16
|
||||
(\f[C]RTCHit16\f[R] type).
|
||||
The header additionally defines an \f[C]RTCHitNt\f[R] template for hit
|
||||
packets of an arbitrary compile\-time size.
|
||||
packets of an arbitrary compile-time size.
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
[RTCRay], [Multi\-Level Instancing]
|
||||
[RTCRay], [Multi-Level Instancing]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCHitN" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCHitN" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCHitN \- hit packet of runtime size
|
||||
RTCHitN - hit packet of runtime size
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -45,7 +45,7 @@ type, or implement one general code path that uses the
|
||||
These helper functions get a pointer to the hit packet (\f[C]hit\f[R]
|
||||
argument), the packet size (\f[C]N\f[R] argument), and returns a
|
||||
reference to a component (e.g.\ x component of \f[C]Ng\f[R]) of the the
|
||||
i\-th hit of the packet (\f[C]i\f[R] argument).
|
||||
i-th hit of the packet (\f[C]i\f[R] argument).
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCQuaternionDecomposition" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCQuaternionDecomposition" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCQuaternionDecomposition \- structure that represents a quaternion
|
||||
RTCQuaternionDecomposition - structure that represents a quaternion
|
||||
decomposition of an affine transformation
|
||||
\f[R]
|
||||
.fi
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCRay" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCRay" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCRay \- single ray structure
|
||||
RTCRay - single ray structure
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -48,8 +48,6 @@ considered valid.
|
||||
The ray segment must be in the range [0,\[u2006]\[if]], thus ranges that
|
||||
start behind the ray origin are not allowed, but ranges can reach to
|
||||
infinity.
|
||||
For rays inside a ray stream, \f[C]tfar\f[R] < \f[C]tnear\f[R]
|
||||
identifies an inactive ray.
|
||||
.PP
|
||||
The ray further contains a motion blur time in the range [0,\[u2006]1]
|
||||
(\f[C]time\f[R] member), a ray mask (\f[C]mask\f[R] member), a ray ID
|
||||
@@ -57,15 +55,14 @@ The ray further contains a motion blur time in the range [0,\[u2006]1]
|
||||
The ray mask can be used to mask out some geometries for some rays (see
|
||||
\f[C]rtcSetGeometryMask\f[R] for more details).
|
||||
The ray ID can be used to identify a ray inside a callback function,
|
||||
even if the order of rays inside a ray packet or stream has changed.
|
||||
The ray flags are reserved.
|
||||
even if the order of rays inside a ray packet has changed.
|
||||
.PP
|
||||
The \f[C]embree4/rtcore_ray.h\f[R] header additionally defines the same
|
||||
ray structure in structure of array (SOA) layout for API functions
|
||||
accepting ray packets of size 4 (\f[C]RTCRay4\f[R] type), size 8
|
||||
(\f[C]RTCRay8\f[R] type), and size 16 (\f[C]RTCRay16\f[R] type).
|
||||
The header additionally defines an \f[C]RTCRayNt\f[R] template for ray
|
||||
packets of an arbitrary compile\-time size.
|
||||
packets of an arbitrary compile-time size.
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCRay" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCRay" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCRayHit \- combined single ray/hit structure
|
||||
RTCRayHit - combined single ray/hit structure
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -25,7 +25,7 @@ struct RTCORE_ALIGN(16) RTCRayHit
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]RTCRayHit\f[R] structure is used as input for the
|
||||
\f[C]rtcIntersect\f[R]\-type functions and stores the ray to intersect
|
||||
\f[C]rtcIntersect\f[R]-type functions and stores the ray to intersect
|
||||
and some hit fields that hold the intersection result afterwards.
|
||||
.PP
|
||||
The \f[C]embree4/rtcore_ray.h\f[R] header additionally defines the same
|
||||
@@ -33,7 +33,7 @@ ray/hit structure in structure of array (SOA) layout for API functions
|
||||
accepting ray packets of size 4 (\f[C]RTCRayHit4\f[R] type), size 8
|
||||
(\f[C]RTCRayHit8\f[R] type), and size 16 (\f[C]RTCRayHit16\f[R] type).
|
||||
The header additionally defines an \f[C]RTCRayHitNt\f[R] template to
|
||||
generate ray/hit packets of an arbitrary compile\-time size.
|
||||
generate ray/hit packets of an arbitrary compile-time size.
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCRayHitN" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCRayHitN" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCRayHitN \- combined ray/hit packet of runtime size
|
||||
RTCRayHitN - combined ray/hit packet of runtime size
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTCRayN" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTCRayN" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTCRayN \- ray packet of runtime size
|
||||
RTCRayN - ray packet of runtime size
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -49,7 +49,7 @@ components.
|
||||
.PP
|
||||
These helper functions get a pointer to the ray packet (\f[C]ray\f[R]
|
||||
argument), the packet size (\f[C]N\f[R] argument), and returns a
|
||||
reference to a component (e.g.\ x\-component of origin) of the the i\-th
|
||||
reference to a component (e.g.\ x-component of origin) of the the i-th
|
||||
ray of the packet (\f[C]i\f[R] argument).
|
||||
.SS EXIT STATUS
|
||||
.SS SEE ALSO
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_*_CURVE" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_*_CURVE" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE -
|
||||
flat curve geometry with linear basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE -
|
||||
flat curve geometry with cubic B\['e]zier basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE \-
|
||||
flat curve geometry with cubic B\-spline basis
|
||||
RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE -
|
||||
flat curve geometry with cubic B-spline basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE -
|
||||
flat curve geometry with cubic Hermite basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE \-
|
||||
flat curve geometry with Catmull\-Rom basis
|
||||
RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE -
|
||||
flat curve geometry with Catmull-Rom basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE -
|
||||
flat normal oriented curve geometry with cubic B\['e]zier basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE \-
|
||||
flat normal oriented curve geometry with cubic B\-spline basis
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE -
|
||||
flat normal oriented curve geometry with cubic B-spline basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE -
|
||||
flat normal oriented curve geometry with cubic Hermite basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE \-
|
||||
flat normal oriented curve geometry with Catmull\-Rom basis
|
||||
RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE -
|
||||
flat normal oriented curve geometry with Catmull-Rom basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE \-
|
||||
capped cone curve geometry with linear basis \- discontinuous at edge boundaries
|
||||
RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE -
|
||||
capped cone curve geometry with linear basis - discontinuous at edge boundaries
|
||||
|
||||
RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE -
|
||||
capped cone curve geometry with linear basis and spherical ending
|
||||
|
||||
RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE -
|
||||
swept surface curve geometry with cubic B\['e]zier basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE \-
|
||||
swept surface curve geometry with cubic B\-spline basis
|
||||
RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE -
|
||||
swept surface curve geometry with cubic B-spline basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE \-
|
||||
RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE -
|
||||
swept surface curve geometry with cubic Hermite basis
|
||||
|
||||
RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE \-
|
||||
swept surface curve geometry with Catmull\-Rom basis
|
||||
RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE -
|
||||
swept surface curve geometry with Catmull-Rom basis
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -78,7 +78,7 @@ rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE);
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
Curves with per vertex radii are supported with linear, cubic
|
||||
B\['e]zier, cubic B\-spline, and cubic Hermite bases.
|
||||
B\['e]zier, cubic B-spline, and cubic Hermite bases.
|
||||
Such curve geometries are created by passing
|
||||
\f[C]RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE\f[R],
|
||||
\f[C]RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE\f[R],
|
||||
@@ -109,7 +109,7 @@ See \f[C]rtcSetGeometryBuffer\f[R] and
|
||||
\f[C]rtcSetSharedGeometryBuffer\f[R] for more details on how to set
|
||||
buffers.
|
||||
.PP
|
||||
The index buffer contains an array of 32\-bit indices
|
||||
The index buffer contains an array of 32-bit indices
|
||||
(\f[C]RTC_FORMAT_UINT\f[R] format), each pointing to the first control
|
||||
vertex in the vertex buffer, but also to the first tangent in the
|
||||
tangent buffer, and first normal in the normal buffer if these buffers
|
||||
@@ -133,7 +133,7 @@ For the linear basis the indices point to the first of 2 consecutive
|
||||
control points in the vertex buffer.
|
||||
The first control point is the start and the second control point the
|
||||
end of the line segment.
|
||||
When constructing hair strands in this basis, the end\-point can be
|
||||
When constructing hair strands in this basis, the end-point can be
|
||||
shared with the start of the next line segment.
|
||||
.PP
|
||||
For the linear basis the user optionally can provide a flags buffer of
|
||||
@@ -143,8 +143,8 @@ and/or right neighbor segment (\f[C]RTC_CURVE_FLAG_NEIGHBOR_RIGHT\f[R]
|
||||
flags) exist (see [RTCCurveFlags]).
|
||||
If this buffer is not set, than the left/right neighbor bits are
|
||||
automatically calculated base on the index buffer (left segment exists
|
||||
if segment(id\-1)+1 == segment(id) and right segment exists if
|
||||
segment(id+1)\-1 == segment(id)).
|
||||
if segment(id-1)+1 == segment(id) and right segment exists if
|
||||
segment(id+1)-1 == segment(id)).
|
||||
.PP
|
||||
A left neighbor segment is assumed to end at the start vertex of the
|
||||
current segment, and to start at the previous vertex in the vertex
|
||||
@@ -165,11 +165,11 @@ control point represents the start point of the curve, and the 4th
|
||||
control point the end point of the curve.
|
||||
The B\['e]zier basis is interpolating, thus the curve does go exactly
|
||||
through the first and fourth control vertex.
|
||||
.SS B\-spline Basis
|
||||
.SS B-spline Basis
|
||||
.PP
|
||||
For the cubic B\-spline basis the indices point to the first of 4
|
||||
For the cubic B-spline basis the indices point to the first of 4
|
||||
consecutive control points in the vertex buffer.
|
||||
These control points make up a cardinal cubic B\-spline (implicit
|
||||
These control points make up a cardinal cubic B-spline (implicit
|
||||
equidistant knot vector).
|
||||
This basis is not interpolating, thus the curve does in general not go
|
||||
through any of the control points directly.
|
||||
@@ -177,7 +177,7 @@ A big advantage of this basis is that 3 control points can be shared for
|
||||
two continuous neighboring curve segments, e.g.\ the curves
|
||||
(p0,p1,p2,p3) and (p1,p2,p3,p4) are C1 continuous.
|
||||
This feature makes this basis a good choice to construct continuous
|
||||
multi\-segment curves, as memory consumption can be kept minimal.
|
||||
multi-segment curves, as memory consumption can be kept minimal.
|
||||
.SS Hermite Basis
|
||||
.PP
|
||||
For the cubic Hermite basis the indices point to the first of 2
|
||||
@@ -189,15 +189,15 @@ second control point, and the first order derivative at the begin and
|
||||
end matches exactly the value specified in the tangent buffer.
|
||||
When connecting two segments continuously, the end point and tangent of
|
||||
the previous segment can be shared.
|
||||
Different versions of Catmull\-Rom splines can be easily constructed
|
||||
Different versions of Catmull-Rom splines can be easily constructed
|
||||
using the Hermite basis, by calculating a proper tangent buffer from the
|
||||
control points.
|
||||
.SS Catmull\-Rom Basis
|
||||
.SS Catmull-Rom Basis
|
||||
.PP
|
||||
For the Catmull\-Rom basis the indices point to the first of 4
|
||||
For the Catmull-Rom basis the indices point to the first of 4
|
||||
consecutive control points in the vertex buffer.
|
||||
This basis goes through p1 and p2, with tangents (p2\-p0)/2 and
|
||||
(p3\-p1)/2.
|
||||
This basis goes through p1 and p2, with tangents (p2-p0)/2 and
|
||||
(p3-p1)/2.
|
||||
.SS Flat Curves
|
||||
.PP
|
||||
The \f[C]RTC_GEOMETRY_TYPE_FLAT_*\f[R] flat mode is a fast mode designed
|
||||
@@ -223,7 +223,7 @@ the provided vertex spline, whose half width approximately follows the
|
||||
provided radius spline, and whose normal orientation approximately
|
||||
follows the provided normal spline.
|
||||
.PP
|
||||
To intersect the normal oriented curve, we perform a newton\-raphson
|
||||
To intersect the normal oriented curve, we perform a newton-raphson
|
||||
style intersection of a ray with a tensor product surface of a linear
|
||||
basis (perpendicular to the curve) and cubic B\['e]zier basis (along the
|
||||
curve).
|
||||
@@ -248,7 +248,7 @@ surface is rendered for the curve, which is more expensive but allows
|
||||
closeup views.
|
||||
.PP
|
||||
For the linear basis the round mode renders a cone that tangentially
|
||||
touches a start\-sphere and end\-sphere.
|
||||
touches a start-sphere and end-sphere.
|
||||
The start sphere is rendered when no previous segments is indicated by
|
||||
the neighbor bits.
|
||||
The end sphere is always rendered but parts that lie inside the next
|
||||
@@ -264,20 +264,20 @@ As a limitation, the radius of the curve has to be smaller than the
|
||||
curvature radius of the curve at each location on the curve.
|
||||
.PP
|
||||
The intersection with the curve segment stores the parametric hit
|
||||
location along the curve segment as u\-coordinate (range 0 to +1).
|
||||
location along the curve segment as u-coordinate (range 0 to +1).
|
||||
.PP
|
||||
For flat curves, the v\-coordinate is set to the normalized distance in
|
||||
the range \-1 to +1.
|
||||
For normal oriented curves the v\-coordinate is in the range 0 to 1.
|
||||
For the linear basis and in round mode the v\-coordinate is set to zero.
|
||||
For flat curves, the v-coordinate is set to the normalized distance in
|
||||
the range -1 to +1.
|
||||
For normal oriented curves the v-coordinate is in the range 0 to 1.
|
||||
For the linear basis and in round mode the v-coordinate is set to zero.
|
||||
.PP
|
||||
In flat mode, the geometry normal \f[C]Ng\f[R] is set to the tangent of
|
||||
the curve at the hit location.
|
||||
In round mode and for normal oriented curves, the geometry normal
|
||||
\f[C]Ng\f[R] is set to the non\-normalized geometric normal of the
|
||||
\f[C]Ng\f[R] is set to the non-normalized geometric normal of the
|
||||
surface.
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers must have the same stride and size.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_GRID" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_GRID" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_GRID \- grid geometry type
|
||||
RTC_GEOMETRY_TYPE_GRID - grid geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -58,20 +58,20 @@ The \f[C]width\f[R] and \f[C]height\f[R] members specify the number of
|
||||
vertices in u and v direction, e.g.\ setting both \f[C]width\f[R] and
|
||||
\f[C]height\f[R] to 3 sets up a 3\[tmu]3 vertex grid.
|
||||
The maximum allowed \f[C]width\f[R] and \f[C]height\f[R] is 32767.
|
||||
The \f[C]startVertexID\f[R] specifies the ID of the top\-left vertex in
|
||||
The \f[C]startVertexID\f[R] specifies the ID of the top-left vertex in
|
||||
the vertex grid, while the \f[C]stride\f[R] parameter specifies a stride
|
||||
(in number of vertices) used to step to the next row.
|
||||
.PP
|
||||
A vertex grid of dimensions \f[C]width\f[R] and \f[C]height\f[R] is
|
||||
treated as a \f[C](width\-1)\f[R] x \f[C](height\-1)\f[R] grid of
|
||||
\f[C]quads\f[R] (triangle\-pairs), with the same shared edge handling as
|
||||
treated as a \f[C](width-1)\f[R] x \f[C](height-1)\f[R] grid of
|
||||
\f[C]quads\f[R] (triangle-pairs), with the same shared edge handling as
|
||||
for regular quad meshes.
|
||||
However, the \f[C]u\f[R]/\f[C]v\f[R] coordinates have the uniform range
|
||||
\f[C][0..1]\f[R] for an entire vertex grid.
|
||||
The \f[C]u\f[R] direction follows the \f[C]width\f[R] of the grid while
|
||||
the \f[C]v\f[R] direction the \f[C]height\f[R].
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers must have the same stride and size.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_INSTANCE" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_INSTANCE" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_INSTANCE \- instance geometry type
|
||||
RTC_GEOMETRY_TYPE_INSTANCE - instance geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -27,11 +27,10 @@ As the instanced scene is stored only a single time, even if instanced
|
||||
to multiple locations, this feature can be used to create very complex
|
||||
scenes with small memory footprint.
|
||||
.PP
|
||||
Embree supports both single\-level instancing and multi\-level
|
||||
instancing.
|
||||
Embree supports both single-level instancing and multi-level instancing.
|
||||
The maximum instance nesting depth is
|
||||
\f[C]RTC_MAX_INSTANCE_LEVEL_COUNT\f[R]; it can be configured at
|
||||
compile\-time using the constant
|
||||
compile-time using the constant
|
||||
\f[C]EMBREE_MAX_INSTANCE_LEVEL_COUNT\f[R].
|
||||
Users should adapt this constant to their needs: instances nested any
|
||||
deeper are silently ignored in release mode, and cause assertions in
|
||||
@@ -46,26 +45,26 @@ function.
|
||||
.PP
|
||||
Please note that \f[C]rtcCommitScene\f[R] on the instanced scene should
|
||||
be called first, followed by \f[C]rtcCommitGeometry\f[R] on the
|
||||
instance, followed by \f[C]rtcCommitScene\f[R] for the top\-level scene
|
||||
instance, followed by \f[C]rtcCommitScene\f[R] for the top-level scene
|
||||
containing the instance.
|
||||
.PP
|
||||
If a ray hits the instance, the \f[C]geomID\f[R] and \f[C]primID\f[R]
|
||||
members of the hit are set to the geometry ID and primitive ID of the
|
||||
hit primitive in the instanced scene, and the \f[C]instID\f[R] member of
|
||||
the hit is set to the geometry ID of the instance in the top\-level
|
||||
the hit is set to the geometry ID of the instance in the top-level
|
||||
scene.
|
||||
.PP
|
||||
The instancing scheme can also be implemented using user geometries.
|
||||
To achieve this, the user geometry code should set the \f[C]instID\f[R]
|
||||
member of the ray query context to the geometry ID of the instance,
|
||||
then trace the transformed ray, and finally set the \f[C]instID\f[R]
|
||||
field of the ray query context again to \-1.
|
||||
member of the ray query context to the geometry ID of the instance, then
|
||||
trace the transformed ray, and finally set the \f[C]instID\f[R] field of
|
||||
the ray query context again to -1.
|
||||
The \f[C]instID\f[R] field is copied automatically by each primitive
|
||||
intersector into the \f[C]instID\f[R] field of the hit structure when
|
||||
the primitive is hit.
|
||||
See the [User Geometry] tutorial for an example.
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] function.
|
||||
Then a transformation for each time step can be specified using the
|
||||
\f[C]rtcSetGeometryTransform\f[R] function.
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_*_POINT" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_*_POINT" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_SPHERE_POINT \-
|
||||
RTC_GEOMETRY_TYPE_SPHERE_POINT -
|
||||
point geometry spheres
|
||||
|
||||
RTC_GEOMETRY_TYPE_DISC_POINT \-
|
||||
point geometry with ray\-oriented discs
|
||||
RTC_GEOMETRY_TYPE_DISC_POINT -
|
||||
point geometry with ray-oriented discs
|
||||
|
||||
RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT \-
|
||||
point geometry with normal\-oriented discs
|
||||
RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT -
|
||||
point geometry with normal-oriented discs
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -29,8 +29,8 @@ rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT);
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
Points with per vertex radii are supported with sphere, ray\-oriented
|
||||
discs, and normal\-oriented discs geometric representations.
|
||||
Points with per vertex radii are supported with sphere, ray-oriented
|
||||
discs, and normal-oriented discs geometric representations.
|
||||
Such point geometries are created by passing
|
||||
\f[C]RTC_GEOMETRY_TYPE_SPHERE_POINT\f[R],
|
||||
\f[C]RTC_GEOMETRY_TYPE_DISC_POINT\f[R], or
|
||||
@@ -69,7 +69,7 @@ In this mode the point is rendered as a normal oriented disc.
|
||||
For all point types, only the hit distance and geometry normal is
|
||||
returned as hit information, u and v are set to zero.
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers must have the same stride and size.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_QUAD" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_QUAD" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_QUAD \- quad geometry type
|
||||
RTC_GEOMETRY_TYPE_QUAD - quad geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -29,7 +29,7 @@ a vertex buffer (\f[C]RTC_BUFFER_TYPE_VERTEX\f[R] type).
|
||||
See \f[C]rtcSetGeometryBuffer\f[R] and
|
||||
\f[C]rtcSetSharedGeometryBuffer\f[R] for more details on how to set
|
||||
buffers.
|
||||
The index buffer contains an array of four 32\-bit indices per quad
|
||||
The index buffer contains an array of four 32-bit indices per quad
|
||||
(\f[C]RTC_FORMAT_UINT4\f[R] format), and the number of primitives is
|
||||
inferred from the size of that buffer.
|
||||
The vertex buffer contains an array of single precision \f[C]x\f[R],
|
||||
@@ -41,29 +41,29 @@ The vertex buffer can be at most 16 GB large.
|
||||
A quad is internally handled as a pair of two triangles
|
||||
\f[C]v0,v1,v3\f[R] and \f[C]v2,v3,v1\f[R], with the
|
||||
\f[C]u\[aq]\f[R]/\f[C]v\[aq]\f[R] coordinates of the second triangle
|
||||
corrected by \f[C]u = 1\-u\[aq]\f[R] and \f[C]v = 1\-v\[aq]\f[R] to
|
||||
corrected by \f[C]u = 1-u\[aq]\f[R] and \f[C]v = 1-v\[aq]\f[R] to
|
||||
produce a quad parametrization where \f[C]u\f[R] and \f[C]v\f[R] are in
|
||||
the range 0 to 1.
|
||||
Thus the parametrization of a quad uses the first vertex \f[C]p0\f[R] as
|
||||
base point, and the vector \f[C]p1 \- p0\f[R] as \f[C]u\f[R]\-direction,
|
||||
and \f[C]p3 \- p0\f[R] as v\-direction.
|
||||
base point, and the vector \f[C]p1 - p0\f[R] as \f[C]u\f[R]-direction,
|
||||
and \f[C]p3 - p0\f[R] as v-direction.
|
||||
Thus vertex attributes \f[C]t0,t1,t2,t3\f[R] can be bilinearly
|
||||
interpolated over the quadrilateral the following way:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
t_uv = (1\-v)((1\-u)*t0 + u*t1) + v*((1\-u)*t3 + u*t2)
|
||||
t_uv = (1-v)((1-u)*t0 + u*t1) + v*((1-u)*t3 + u*t2)
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
Mixed triangle/quad meshes are supported by encoding a triangle as a
|
||||
quad, which can be achieved by replicating the last triangle vertex
|
||||
(\f[C]v0,v1,v2\f[R] \-> \f[C]v0,v1,v2,v2\f[R]).
|
||||
(\f[C]v0,v1,v2\f[R] -> \f[C]v0,v1,v2,v2\f[R]).
|
||||
This way the second triangle is a line (which can never get hit), and
|
||||
the parametrization of the first triangle is compatible with the
|
||||
standard triangle parametrization.
|
||||
.PP
|
||||
A quad whose vertices are laid out counter\-clockwise has its geometry
|
||||
A quad whose vertices are laid out counter-clockwise has its geometry
|
||||
normal pointing upwards outside the front face, like illustrated in the
|
||||
following picture.
|
||||
.IP
|
||||
@@ -72,7 +72,7 @@ following picture.
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers must have the same stride and size.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_SUBDIVISION" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_SUBDIVISION" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_SUBDIVISION \- subdivision geometry type
|
||||
RTC_GEOMETRY_TYPE_SUBDIVISION - subdivision geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -21,9 +21,9 @@ RTCGeometry geometry =
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
Catmull\-Clark subdivision meshes are supported, including support for
|
||||
edge creases, vertex creases, holes, non\-manifold geometry, and
|
||||
face\-varying interpolation.
|
||||
Catmull-Clark subdivision meshes are supported, including support for
|
||||
edge creases, vertex creases, holes, non-manifold geometry, and
|
||||
face-varying interpolation.
|
||||
The number of vertices per face can be in the range of 3 to 15 vertices
|
||||
(triangles, quadrilateral, pentagons, etc).
|
||||
.PP
|
||||
@@ -40,7 +40,7 @@ The face buffer (\f[C]RTC_BUFFER_TYPE_FACE\f[R] type and
|
||||
of each face (3 to 15), and the number of faces is inferred from the
|
||||
size of this buffer.
|
||||
The index buffer (\f[C]RTC_BUFFER_TYPE_INDEX\f[R] type) contains
|
||||
multiple (3 to 15) 32\-bit vertex indices (\f[C]RTC_FORMAT_UINT\f[R]
|
||||
multiple (3 to 15) 32-bit vertex indices (\f[C]RTC_FORMAT_UINT\f[R]
|
||||
format) for each face, and the number of edges is inferred from the size
|
||||
of this buffer.
|
||||
The vertex buffer (\f[C]RTC_BUFFER_TYPE_VERTEX\f[R] type) stores an
|
||||
@@ -50,7 +50,7 @@ of vertices is inferred from the size of this buffer.
|
||||
.PP
|
||||
Optionally, the application may set additional index buffers using
|
||||
different buffer slots if multiple topologies are required for
|
||||
face\-varying interpolation.
|
||||
face-varying interpolation.
|
||||
The standard vertex buffers (\f[C]RTC_BUFFER_TYPE_VERTEX\f[R]) are
|
||||
always bound to the geometry topology (topology 0) thus use
|
||||
\f[C]RTC_BUFFER_TYPE_INDEX\f[R] with buffer slot 0.
|
||||
@@ -58,9 +58,9 @@ User vertex data interpolation may use different topologies as described
|
||||
later.
|
||||
.PP
|
||||
Optionally, the application can set up the hole buffer
|
||||
(\f[C]RTC_BUFFER_TYPE_HOLE\f[R]) which contains an array of 32\-bit
|
||||
(\f[C]RTC_BUFFER_TYPE_HOLE\f[R]) which contains an array of 32-bit
|
||||
indices (\f[C]RTC_FORMAT_UINT\f[R] format) of faces that should be
|
||||
considered non\-existing in all topologies.
|
||||
considered non-existing in all topologies.
|
||||
The number of holes is inferred from the size of this buffer.
|
||||
.PP
|
||||
Optionally, the application can fill the level buffer
|
||||
@@ -85,7 +85,7 @@ Optionally, the application can fill the sparse edge crease buffers to
|
||||
make edges appear sharper.
|
||||
The edge crease index buffer
|
||||
(\f[C]RTC_BUFFER_TYPE_EDGE_CREASE_INDEX\f[R]) contains an array of pairs
|
||||
of 32\-bit vertex indices (\f[C]RTC_FORMAT_UINT2\f[R] format) that
|
||||
of 32-bit vertex indices (\f[C]RTC_FORMAT_UINT2\f[R] format) that
|
||||
specify unoriented edges in the geometry topology.
|
||||
The edge crease weight buffer
|
||||
(\f[C]RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT\f[R]) stores for each of these
|
||||
@@ -108,7 +108,7 @@ Optionally, the application can fill the sparse vertex crease buffers to
|
||||
make vertices appear sharper.
|
||||
The vertex crease index buffer
|
||||
(\f[C]RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX\f[R]), contains an array of
|
||||
32\-bit vertex indices (\f[C]RTC_FORMAT_UINT\f[R] format) to specify a
|
||||
32-bit vertex indices (\f[C]RTC_FORMAT_UINT\f[R] format) to specify a
|
||||
set of vertices from the geometry topology.
|
||||
The vertex crease weight buffer
|
||||
(\f[C]RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT\f[R]) specifies for each of
|
||||
@@ -129,7 +129,7 @@ Subdivision modes can be used to force linear interpolation for parts of
|
||||
the subdivision mesh; see \f[C]rtcSetGeometrySubdivisionMode\f[R] for
|
||||
more details.
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers have to have the same stride and
|
||||
@@ -140,18 +140,18 @@ subdivision surfaces.
|
||||
.SS Parametrization
|
||||
.PP
|
||||
The parametrization for subdivision faces is different for
|
||||
quadrilaterals and non\-quadrilateral faces.
|
||||
quadrilaterals and non-quadrilateral faces.
|
||||
.PP
|
||||
The parametrization of a quadrilateral face uses the first vertex
|
||||
\f[C]p0\f[R] as base point, and the vector \f[C]p1 \- p0\f[R] as
|
||||
u\-direction and \f[C]p3 \- p0\f[R] as v\-direction.
|
||||
\f[C]p0\f[R] as base point, and the vector \f[C]p1 - p0\f[R] as
|
||||
u-direction and \f[C]p3 - p0\f[R] as v-direction.
|
||||
.PP
|
||||
The parametrization for all other face types (with number of vertices
|
||||
not equal 4), have a special parametrization where the subpatch ID
|
||||
\f[C]n\f[R] (of the \f[C]n\f[R]\-th quadrilateral that would be obtained
|
||||
\f[C]n\f[R] (of the \f[C]n\f[R]-th quadrilateral that would be obtained
|
||||
by a single subdivision step) and the local hit location inside this
|
||||
quadrilateral are encoded in the UV coordinates.
|
||||
The following code extracts the sub\-patch ID \f[C]i\f[R] and local UVs
|
||||
The following code extracts the sub-patch ID \f[C]i\f[R] and local UVs
|
||||
of this subpatch:
|
||||
.IP
|
||||
.nf
|
||||
@@ -159,28 +159,28 @@ of this subpatch:
|
||||
unsigned int l = floorf(0.5f*U);
|
||||
unsigned int h = floorf(0.5f*V);
|
||||
unsigned int i = 4*h+l;
|
||||
float u = 2.0f*fracf(0.5f*U)\-0.5f;
|
||||
float v = 2.0f*fracf(0.5f*V)\-0.5f;
|
||||
float u = 2.0f*fracf(0.5f*U)-0.5f;
|
||||
float v = 2.0f*fracf(0.5f*V)-0.5f;
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
This encoding allows local subpatch UVs to be in the range
|
||||
\f[C][\-0.5,1.5[\f[R] thus negative subpatch UVs can be passed to
|
||||
\f[C][-0.5,1.5[\f[R] thus negative subpatch UVs can be passed to
|
||||
\f[C]rtcInterpolate\f[R] to sample subpatches slightly out of bounds.
|
||||
This can be useful to calculate derivatives using finite differences if
|
||||
required.
|
||||
The encoding further has the property that one can just move the value
|
||||
\f[C]u\f[R] (or \f[C]v\f[R]) on a subpatch by adding \f[C]du\f[R] (or
|
||||
\f[C]dv\f[R]) to the special UV encoding as long as it does not fall out
|
||||
of the \f[C][\-0.5,1.5[\f[R] range.
|
||||
of the \f[C][-0.5,1.5[\f[R] range.
|
||||
.PP
|
||||
To smoothly interpolate vertex attributes over the subdivision surface
|
||||
we recommend using the \f[C]rtcInterpolate\f[R] function, which will
|
||||
apply the standard subdivision rules for interpolation and automatically
|
||||
takes care of the special UV encoding for non\-quadrilaterals.
|
||||
.SS Face\-Varying Data
|
||||
takes care of the special UV encoding for non-quadrilaterals.
|
||||
.SS Face-Varying Data
|
||||
.PP
|
||||
Face\-varying interpolation is supported through multiple topologies per
|
||||
Face-varying interpolation is supported through multiple topologies per
|
||||
subdivision mesh and binding such topologies to vertex attribute buffers
|
||||
to interpolate.
|
||||
This way, texture coordinates may use a different topology with
|
||||
@@ -197,9 +197,9 @@ interpolation using the \f[C]rtcSetGeometryVertexAttributeTopology\f[R]
|
||||
call.
|
||||
.PP
|
||||
The face buffer (\f[C]RTC_BUFFER_TYPE_FACE\f[R] type) is shared between
|
||||
all topologies, which means that the \f[C]n\f[R]\-th primitive always
|
||||
has the same number of vertices (e.g.\ being a triangle or a quad) for
|
||||
each topology.
|
||||
all topologies, which means that the \f[C]n\f[R]-th primitive always has
|
||||
the same number of vertices (e.g.\ being a triangle or a quad) for each
|
||||
topology.
|
||||
However, the indices of the topologies themselves may be different.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_TRIANGLE" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_TRIANGLE" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_TRIANGLE \- triangle geometry type
|
||||
RTC_GEOMETRY_TYPE_TRIANGLE - triangle geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -30,7 +30,7 @@ setting a vertex buffer (\f[C]RTC_BUFFER_TYPE_VERTEX\f[R] type).
|
||||
See \f[C]rtcSetGeometryBuffer\f[R] and
|
||||
\f[C]rtcSetSharedGeometryBuffer\f[R] for more details on how to set
|
||||
buffers.
|
||||
The index buffer must contain an array of three 32\-bit indices per
|
||||
The index buffer must contain an array of three 32-bit indices per
|
||||
triangle (\f[C]RTC_FORMAT_UINT3\f[R] format) and the number of
|
||||
primitives is inferred from the size of that buffer.
|
||||
The vertex buffer must contain an array of single precision \f[C]x\f[R],
|
||||
@@ -40,19 +40,19 @@ inferred from the size of that buffer.
|
||||
The vertex buffer can be at most 16 GB large.
|
||||
.PP
|
||||
The parametrization of a triangle uses the first vertex \f[C]p0\f[R] as
|
||||
base point, the vector \f[C]p1 \- p0\f[R] as u\-direction and the vector
|
||||
\f[C]p2 \- p0\f[R] as v\-direction.
|
||||
base point, the vector \f[C]p1 - p0\f[R] as u-direction and the vector
|
||||
\f[C]p2 - p0\f[R] as v-direction.
|
||||
Thus vertex attributes \f[C]t0,t1,t2\f[R] can be linearly interpolated
|
||||
over the triangle the following way:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
t_uv = (1\-u\-v)*t0 + u*t1 + v*t2
|
||||
= t0 + u*(t1\-t0) + v*(t2\-t0)
|
||||
t_uv = (1-u-v)*t0 + u*t1 + v*t2
|
||||
= t0 + u*(t1-t0) + v*(t2-t0)
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
A triangle whose vertices are laid out counter\-clockwise has its
|
||||
A triangle whose vertices are laid out counter-clockwise has its
|
||||
geometry normal pointing upwards outside the front face, like
|
||||
illustrated in the following picture:
|
||||
.IP
|
||||
@@ -61,7 +61,7 @@ illustrated in the following picture:
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
For multi\-segment motion blur, the number of time steps must be first
|
||||
For multi-segment motion blur, the number of time steps must be first
|
||||
specified using the \f[C]rtcSetGeometryTimeStepCount\f[R] call.
|
||||
Then a vertex buffer for each time step can be set using different
|
||||
buffer slots, and all these buffers have to have the same stride and
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "RTC_GEOMETRY_TYPE_USER" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "RTC_GEOMETRY_TYPE_USER" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
RTC_GEOMETRY_TYPE_USER \- user geometry type
|
||||
RTC_GEOMETRY_TYPE_USER - user geometry type
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -21,19 +21,19 @@ RTCGeometry geometry =
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
User\-defined geometries contain a number of user\-defined primitives,
|
||||
User-defined geometries contain a number of user-defined primitives,
|
||||
just like triangle meshes contain multiple triangles.
|
||||
The shape of the user\-defined primitives is specified through
|
||||
registered callback functions, which enable extending Embree with
|
||||
arbitrary types of primitives.
|
||||
The shape of the user-defined primitives is specified through registered
|
||||
callback functions, which enable extending Embree with arbitrary types
|
||||
of primitives.
|
||||
.PP
|
||||
User\-defined geometries are created by passing
|
||||
User-defined geometries are created by passing
|
||||
\f[C]RTC_GEOMETRY_TYPE_USER\f[R] to the \f[C]rtcNewGeometry\f[R]
|
||||
function call.
|
||||
One has to set the number of primitives (see
|
||||
\f[C]rtcSetGeometryUserPrimitiveCount\f[R]), a user data pointer (see
|
||||
\f[C]rtcSetGeometryUserData\f[R]), a bounding function closure (see
|
||||
\f[C]rtcSetGeometryBoundsFunction\f[R]), as well as user\-defined
|
||||
\f[C]rtcSetGeometryBoundsFunction\f[R]), as well as user-defined
|
||||
intersect (see \f[C]rtcSetGeometryIntersectFunction\f[R]) and occluded
|
||||
(see \f[C]rtcSetGeometryOccludedFunction\f[R]) callback functions.
|
||||
The bounding function is used to query the bounds of all time steps of a
|
||||
@@ -66,7 +66,7 @@ bounds are empty, thus bounds have lower>upper in at least one
|
||||
dimension.
|
||||
.PP
|
||||
See tutorial [User Geometry] for an example of how to use the
|
||||
user\-defined geometries.
|
||||
user-defined geometries.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
On failure \f[C]NULL\f[R] is returned and an error code is set that can
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcAttachGeometry" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcAttachGeometry" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcAttachGeometry \- attaches a geometry to the scene
|
||||
rtcAttachGeometry - attaches a geometry to the scene
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -32,7 +32,7 @@ A geometry can get attached to multiple scenes.
|
||||
The geometry ID is unique for the scene, and is used to identify the
|
||||
geometry when hit by a ray during ray queries.
|
||||
.PP
|
||||
This function is thread\-safe, thus multiple threads can attach
|
||||
This function is thread-safe, thus multiple threads can attach
|
||||
geometries to a scene in parallel.
|
||||
.PP
|
||||
The geometry IDs are assigned sequentially, starting from 0, as long as
|
||||
@@ -44,7 +44,7 @@ compact range of IDs.
|
||||
.PP
|
||||
These rules allow the application to manage a dynamic array to
|
||||
efficiently map from geometry IDs to its own geometry representation.
|
||||
Alternatively, the application can also use per\-geometry user data to
|
||||
Alternatively, the application can also use per-geometry user data to
|
||||
map to its geometry representation.
|
||||
See \f[C]rtcSetGeometryUserData\f[R] and
|
||||
\f[C]rtcGetGeometryUserData\f[R] for more information.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcAttachGeometryByID" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcAttachGeometryByID" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcAttachGeometryByID \- attaches a geometry to the scene
|
||||
rtcAttachGeometryByID - attaches a geometry to the scene
|
||||
using a specified geometry ID
|
||||
\f[R]
|
||||
.fi
|
||||
@@ -32,17 +32,17 @@ geometry.
|
||||
All geometries attached to a scene are defined to be included inside the
|
||||
scene.
|
||||
A geometry can get attached to multiple scenes.
|
||||
The passed user\-defined geometry ID is used to identify the geometry
|
||||
The passed user-defined geometry ID is used to identify the geometry
|
||||
when hit by a ray during ray queries.
|
||||
Using this function, it is possible to share the same IDs to refer to
|
||||
geometries inside the application and Embree.
|
||||
.PP
|
||||
This function is thread\-safe, thus multiple threads can attach
|
||||
This function is thread-safe, thus multiple threads can attach
|
||||
geometries to a scene in parallel.
|
||||
.PP
|
||||
The user\-provided geometry ID must be unused in the scene, otherwise
|
||||
the creation of the geometry will fail.
|
||||
Further, the user\-provided geometry IDs should be compact, as Embree
|
||||
The user-provided geometry ID must be unused in the scene, otherwise the
|
||||
creation of the geometry will fail.
|
||||
Further, the user-provided geometry IDs should be compact, as Embree
|
||||
internally creates a vector which size is equal to the largest geometry
|
||||
ID used.
|
||||
Creating very large geometry IDs for small scenes would thus cause a
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcBuildBVH" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcBuildBVH" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcBuildBVH \- builds a BVH
|
||||
rtcBuildBVH - builds a BVH
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -107,7 +107,7 @@ void* rtcBuildBVH(
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]rtcBuildBVH\f[R] function can be used to build a BVH in a
|
||||
user\-defined format over arbitrary primitives.
|
||||
user-defined format over arbitrary primitives.
|
||||
All arguments to the function are provided through the
|
||||
\f[C]RTCBuildArguments\f[R] structure.
|
||||
The first member of that structure must be set to the size of the
|
||||
@@ -121,12 +121,12 @@ The \f[C]rtcBuildBVH\f[R] function gets passed the BVH to build
|
||||
member), the capacity of that array (\f[C]primitiveArrayCapacity\f[R]
|
||||
member), the number of primitives stored inside the array
|
||||
(\f[C]primitiveCount\f[R] member), callback function pointers, and a
|
||||
user\-defined pointer (\f[C]userPtr\f[R] member) that is passed to all
|
||||
user-defined pointer (\f[C]userPtr\f[R] member) that is passed to all
|
||||
callback functions when invoked.
|
||||
The \f[C]primitives\f[R] array can be freed by the application after the
|
||||
BVH is built.
|
||||
All callback functions are typically called from multiple threads, thus
|
||||
their implementation must be thread\-safe.
|
||||
their implementation must be thread-safe.
|
||||
.PP
|
||||
Four callback functions must be registered, which are invoked during
|
||||
build to create BVH nodes (\f[C]createNode\f[R] member), to set the
|
||||
@@ -153,7 +153,7 @@ have (\f[C]maxDepth\f[R] member), the block size for the SAH heuristic
|
||||
estimated costs of one traversal step and one primitive intersection
|
||||
(\f[C]traversalCost\f[R] and \f[C]intersectionCost\f[R] members).
|
||||
When enabling the \f[C]RTC_BUILD_FLAG_DYNAMIC\f[R] build flags
|
||||
(\f[C]buildFlags\f[R] member), re\-build performance for dynamic scenes
|
||||
(\f[C]buildFlags\f[R] member), re-build performance for dynamic scenes
|
||||
is improved at the cost of higher memory requirements.
|
||||
.PP
|
||||
To spatially split primitives in high quality mode, the builder needs
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcCollide" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcCollide" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcCollide \- intersects one BVH with another
|
||||
rtcCollide - intersects one BVH with another
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcCommitGeometry" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcCommitGeometry" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcCommitGeometry \- commits geometry changes
|
||||
rtcCommitGeometry - commits geometry changes
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcCommitScene" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcCommitScene" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcCommitScene \- commits scene changes
|
||||
rtcCommitScene - commits scene changes
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcDetachGeometry" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcDetachGeometry" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcDetachGeometry \- detaches a geometry from the scene
|
||||
rtcDetachGeometry - detaches a geometry from the scene
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
@@ -24,7 +24,7 @@ This function detaches a geometry identified by its geometry ID
|
||||
(\f[C]geomID\f[R] argument) from a scene (\f[C]scene\f[R] argument).
|
||||
When detached, the geometry is no longer contained in the scene.
|
||||
.PP
|
||||
This function is thread\-safe, thus multiple threads can detach
|
||||
This function is thread-safe, thus multiple threads can detach
|
||||
geometries from a scene at the same time.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcDisableGeometry" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcDisableGeometry" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcDisableGeometry \- disables the geometry
|
||||
rtcDisableGeometry - disables the geometry
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcEnableGeometry" "3" "" "" "Embree Ray Tracing Kernels 3"
|
||||
.TH "rtcEnableGeometry" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcEnableGeometry \- enables the geometry
|
||||
rtcEnableGeometry - enables the geometry
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcForwardIntersect1" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcForwardIntersect1 - forwards a single ray to new scene
|
||||
from user geometry callback
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
#include <embree4/rtcore.h>
|
||||
|
||||
void rtcForwardIntersect1(
|
||||
const struct RTCIntersectFunctionNArguments* args,
|
||||
RTCScene scene,
|
||||
struct RTCRay* ray,
|
||||
unsigned int instID
|
||||
);
|
||||
\f[R]
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]rtcForwardIntersect1\f[R] function forwards the traversal of a
|
||||
transformed ray (\f[C]ray\f[R] argument) into a scene (\f[C]scene\f[R]
|
||||
argument) from a user geometry callback.
|
||||
The function can only get invoked from a user geometry callback for a
|
||||
ray traversal initiated with the \f[C]rtcIntersect1\f[R] function.
|
||||
The callback arguments structure of the callback invokation has to get
|
||||
passed to the ray forwarding (\f[C]args\f[R] argument).
|
||||
The user geometry callback should instantly terminate after invoking the
|
||||
\f[C]rtcForwardIntersect1\f[R] function.
|
||||
.PP
|
||||
Only the ray origin and ray direction members of the ray argument are
|
||||
used for forwarding, all additional ray properties are inherited from
|
||||
the initial ray traversal invokation of \f[C]rtcIntersect1\f[R].
|
||||
.PP
|
||||
The implementation of the \f[C]rtcForwardIntersect1\f[R] function
|
||||
recursively continues the ray traversal into the specified scene and
|
||||
pushes the provided instance ID (\f[C]instID\f[R] argument) to the
|
||||
instance ID stack.
|
||||
Hit information is updated into the ray hit structure passed to the
|
||||
original \f[C]rtcIntersect1\f[R] invokation.
|
||||
.PP
|
||||
This function can get used to implement user defined instancing using
|
||||
user geometries, e.g.\ by transforming the ray in a special way, and/or
|
||||
selecting between different scenes to instantiate.
|
||||
.PP
|
||||
When using Embree on the CPU it is possible to recursively invoke
|
||||
\f[C]rtcIntersect1\f[R] directly from a user geometry callback.
|
||||
However, when SYCL is used, recursively tracing rays is not directly
|
||||
supported, and the \f[C]rtcForwardIntersect1\f[R] function must be used.
|
||||
.PP
|
||||
The ray structure must be aligned to 16 bytes.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
For performance reasons this function does not do any error checks, thus
|
||||
will not set any error flags on failure.
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
[rtcIntersect1], [RTCRay]
|
||||
@@ -0,0 +1,87 @@
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcForwardIntersect4/8/16" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcForwardIntersect4/8/16 - forwards a ray packet to new scene
|
||||
from user geometry callback
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
#include <embree4/rtcore.h>
|
||||
|
||||
void rtcForwardIntersect4(
|
||||
void int* valid,
|
||||
const struct RTCIntersectFunctionNArguments* args,
|
||||
RTCScene scene,
|
||||
struct RTCRay4* ray,
|
||||
unsigned int instID
|
||||
);
|
||||
|
||||
void rtcForwardIntersect4(
|
||||
void int* valid,
|
||||
const struct RTCIntersectFunctionNArguments* args,
|
||||
RTCScene scene,
|
||||
struct RTCRay4* ray,
|
||||
unsigned int instID
|
||||
);
|
||||
|
||||
void rtcForwardIntersect16(
|
||||
void int* valid,
|
||||
const struct RTCIntersectFunctionNArguments* args,
|
||||
RTCScene scene,
|
||||
struct RTCRay16* ray,
|
||||
unsigned int instID
|
||||
);
|
||||
\f[R]
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]rtcForwardIntersect4/8/16\f[R] functions forward the traversal
|
||||
of a transformed ray packet (\f[C]ray\f[R] argument) into a scene
|
||||
(\f[C]scene\f[R] argument) from a user geometry callback.
|
||||
The function can only get invoked from a user geometry callback for a
|
||||
ray traversal initiated with the \f[C]rtcIntersect4/8/16\f[R] function.
|
||||
The callback arguments structure of the callback invokation has to get
|
||||
passed to the ray forwarding (\f[C]args\f[R] argument).
|
||||
The user geometry callback should instantly terminate after invoking the
|
||||
\f[C]rtcForwardIntersect4/8/16\f[R] function.
|
||||
.PP
|
||||
Only the ray origin and ray direction members of the ray argument are
|
||||
used for forwarding, all additional ray properties are inherited from
|
||||
the initial ray traversal invokation of \f[C]rtcIntersect4/8/16\f[R].
|
||||
.PP
|
||||
The implementation of the \f[C]rtcForwardIntersect4/8/16\f[R] function
|
||||
recursively continues the ray traversal into the specified scene and
|
||||
pushes the provided instance ID (\f[C]instID\f[R] argument) to the
|
||||
instance ID stack.
|
||||
Hit information is updated into the ray hit structure passed to the
|
||||
original \f[C]rtcIntersect4/8/16\f[R] invokation.
|
||||
.PP
|
||||
This function can get used to implement user defined instancing using
|
||||
user geometries, e.g.\ by transforming the ray in a special way, and/or
|
||||
selecting between different scenes to instantiate.
|
||||
.PP
|
||||
When using Embree on the CPU it is possible to recursively invoke
|
||||
\f[C]rtcIntersect4/8/16\f[R] directly from a user geometry callback.
|
||||
However, when SYCL is used, recursively tracing rays is not directly
|
||||
supported, and the \f[C]rtcForwardIntersect4/8/16\f[R] function must be
|
||||
used.
|
||||
.PP
|
||||
For \f[C]rtcForwardIntersect4\f[R] the ray packet must be aligned to 16
|
||||
bytes, for \f[C]rtcForwardIntersect8\f[R] the alignment must be 32
|
||||
bytes, and for \f[C]rtcForwardIntersect16\f[R] the alignment must be 64
|
||||
bytes.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
For performance reasons this function does not do any error checks, thus
|
||||
will not set any error flags on failure.
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
[rtcIntersect4/8/16]
|
||||
@@ -0,0 +1,66 @@
|
||||
.\" Automatically generated by Pandoc 2.9.2.1
|
||||
.\"
|
||||
.TH "rtcForwardOccluded1" "3" "" "" "Embree Ray Tracing Kernels 4"
|
||||
.hy
|
||||
.SS NAME
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rtcForwardOccluded1 - forwards a single ray to new scene
|
||||
from user geometry callback
|
||||
\f[R]
|
||||
.fi
|
||||
.SS SYNOPSIS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
#include <embree4/rtcore.h>
|
||||
|
||||
void rtcForwardOccluded1(
|
||||
const struct RTCOccludedFunctionNArguments* args,
|
||||
RTCScene scene,
|
||||
struct RTCRay* ray,
|
||||
unsigned int instID
|
||||
);
|
||||
\f[R]
|
||||
.fi
|
||||
.SS DESCRIPTION
|
||||
.PP
|
||||
The \f[C]rtcForwardOccluded1\f[R] function forwards the traversal of a
|
||||
transformed ray (\f[C]ray\f[R] argument) into a scene (\f[C]scene\f[R]
|
||||
argument) from a user geometry callback.
|
||||
The function can only get invoked from a user geometry callback for a
|
||||
ray traversal initiated with the \f[C]rtcOccluded1\f[R] function.
|
||||
The callback arguments structure of the callback invokation has to get
|
||||
passed to the ray forwarding (\f[C]args\f[R] argument).
|
||||
The user geometry callback should instantly terminate after invoking the
|
||||
\f[C]rtcForwardOccluded1\f[R] function.
|
||||
.PP
|
||||
Only the ray origin and ray direction members of the ray argument are
|
||||
used for forwarding, all additional ray properties are inherited from
|
||||
the initial ray traversal invokation of \f[C]rtcOccluded1\f[R].
|
||||
.PP
|
||||
The implementation of the \f[C]rtcForwardOccluded1\f[R] function
|
||||
recursively continues the ray traversal into the specified scene and
|
||||
pushes the provided instance ID (\f[C]instID\f[R] argument) to the
|
||||
instance ID stack.
|
||||
Hit information is updated into the ray structure passed to the original
|
||||
\f[C]rtcOccluded1\f[R] invokation.
|
||||
.PP
|
||||
This function can get used to implement user defined instancing using
|
||||
user geometries, e.g.\ by transforming the ray in a special way, and/or
|
||||
selecting between different scenes to instantiate.
|
||||
.PP
|
||||
When using Embree on the CPU it is possible to recursively invoke
|
||||
\f[C]rtcOccluded1\f[R] directly from a user geometry callback.
|
||||
However, when SYCL is used, recursively tracing rays is not directly
|
||||
supported, and the \f[C]rtcForwardOccluded1\f[R] function must be used.
|
||||
.PP
|
||||
The ray structure must be aligned to 16 bytes.
|
||||
.SS EXIT STATUS
|
||||
.PP
|
||||
For performance reasons this function does not do any error checks, thus
|
||||
will not set any error flags on failure.
|
||||
.SS SEE ALSO
|
||||
.PP
|
||||
[rtcOccluded1], [RTCRay]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user