Merge remote-tracking branch 'origin' into sculpt-dev
This commit is contained in:
commit
92bc610c36
|
@ -242,17 +242,17 @@ if(UNIX AND NOT (APPLE OR HAIKU))
|
|||
option(WITH_GHOST_X11 "Enable building Blender against X11 for windowing" ON)
|
||||
mark_as_advanced(WITH_GHOST_X11)
|
||||
|
||||
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing (under development)" OFF)
|
||||
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing" ON)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND)
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" OFF)
|
||||
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" ON)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
|
||||
option(WITH_GHOST_WAYLAND_DBUS "Optionally build with DBUS support (used for Cursor themes). May hang on startup systems where DBUS is not used." OFF)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
|
||||
|
||||
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" OFF)
|
||||
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1922,9 +1922,25 @@ if(FIRST_RUN)
|
|||
info_cfg_option(WITH_INSTALL_PORTABLE)
|
||||
info_cfg_option(WITH_MEM_JEMALLOC)
|
||||
info_cfg_option(WITH_MEM_VALGRIND)
|
||||
info_cfg_option(WITH_X11_XF86VMODE)
|
||||
info_cfg_option(WITH_X11_XFIXES)
|
||||
info_cfg_option(WITH_X11_XINPUT)
|
||||
|
||||
info_cfg_text("GHOST Options:")
|
||||
info_cfg_option(WITH_GHOST_DEBUG)
|
||||
info_cfg_option(WITH_GHOST_SDL)
|
||||
if(UNIX AND NOT APPLE)
|
||||
info_cfg_option(WITH_GHOST_X11)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND)
|
||||
if(WITH_GHOST_X11)
|
||||
info_cfg_option(WITH_GHOST_XDND)
|
||||
info_cfg_option(WITH_X11_XF86VMODE)
|
||||
info_cfg_option(WITH_X11_XFIXES)
|
||||
info_cfg_option(WITH_X11_XINPUT)
|
||||
endif()
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_DBUS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
info_cfg_text("Image Formats:")
|
||||
info_cfg_option(WITH_IMAGE_CINEON)
|
||||
|
|
|
@ -172,6 +172,8 @@ if(UNIX AND NOT APPLE)
|
|||
include(cmake/wayland_protocols.cmake)
|
||||
# Can be removed when the build-bot upgrades to v1.20.x or newer.
|
||||
include(cmake/wayland.cmake)
|
||||
include(cmake/wayland_libdecor.cmake)
|
||||
endif()
|
||||
|
||||
include(cmake/harvest.cmake)
|
||||
include(cmake/cve_check.cmake)
|
||||
|
|
|
@ -46,7 +46,7 @@ if(UNIX)
|
|||
" ${_software_missing}\n"
|
||||
"\n"
|
||||
"On Debian and Ubuntu:\n"
|
||||
" apt install autoconf automake libtool yasm tcl ninja-build meson python3-mako\n"
|
||||
" apt install autoconf automake bison libtool yasm tcl ninja-build meson python3-mako\n"
|
||||
"\n"
|
||||
"On macOS (with homebrew):\n"
|
||||
" brew install autoconf automake bison flex libtool meson ninja pkg-config yasm\n"
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# CVE Check requirements
|
||||
#
|
||||
# - A working installation of intels cve-bin-tool [1] has to be available in
|
||||
# your path
|
||||
#
|
||||
# - Not strictly required, but highly recommended is obtaining a NVD key from
|
||||
# nist since it significantly speeds up downloading/updating the required
|
||||
# databases one can request a key on the following website:
|
||||
# https://nvd.nist.gov/developers/request-an-api-key
|
||||
|
||||
# Bill of Materials construction
|
||||
#
|
||||
# This constructs a CSV cve-bin-tool [1] can read and process. Sadly
|
||||
# cve-bin-tool at this point does not take a list of CPE's and output a check
|
||||
# based on that list. so we need to pick apart the CPE retrieve the vendor,
|
||||
# product and version tokens and generate a CSV.
|
||||
#
|
||||
# [1] https://github.com/intel/cve-bin-tool
|
||||
|
||||
# Because not all deps are downloaded (ie python packages) but can still have a
|
||||
# xxx_CPE declared loop over all variables and look for variables ending in CPE.
|
||||
|
||||
set(SBOMCONTENTS)
|
||||
get_cmake_property(_variableNames VARIABLES)
|
||||
foreach (_variableName ${_variableNames})
|
||||
if(_variableName MATCHES "CPE$")
|
||||
string(REPLACE ":" ";" CPE_LIST ${${_variableName}})
|
||||
list(GET CPE_LIST 3 CPE_VENDOR)
|
||||
list(GET CPE_LIST 4 CPE_NAME)
|
||||
list(GET CPE_LIST 5 CPE_VERSION)
|
||||
set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}\n")
|
||||
endif()
|
||||
endforeach()
|
||||
configure_file(${CMAKE_SOURCE_DIR}/cmake/cve_check.csv.in ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv @ONLY)
|
||||
|
||||
# Custom Targets
|
||||
#
|
||||
# This defines two new custom targets one could run in the build folder
|
||||
# `cve_check` which will output the report to the console, and `cve_check_html`
|
||||
# which will write out blender_dependencies.html in the build folder that one
|
||||
# could share with other people or be used to get more information on the
|
||||
# reported CVE's.
|
||||
#
|
||||
# cve-bin-tool takes data from the nist nvd database which rate limits
|
||||
# unauthenticated requests to 1 requests per 6 seconds making the database
|
||||
# download take "quite a bit" of time.
|
||||
#
|
||||
# When adding -DCVE_CHECK_NVD_KEY=your_api_key_here to your cmake invocation
|
||||
# this key will be passed on to cve-bin-tool speeding up the process.
|
||||
#
|
||||
if(DEFINED CVE_CHECK_NVD_KEY)
|
||||
set(NVD_ARGS --nvd-api-key ${CVE_CHECK_NVD_KEY})
|
||||
endif()
|
||||
|
||||
# This will just report to the console
|
||||
add_custom_target(cve_check
|
||||
COMMAND cve-bin-tool
|
||||
${NVD_ARGS}
|
||||
-i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
|
||||
--affected-versions
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
|
||||
)
|
||||
|
||||
# This will write out blender_dependencies.html
|
||||
add_custom_target(cve_check_html
|
||||
COMMAND cve-bin-tool
|
||||
${NVD_ARGS}
|
||||
-i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
|
||||
-f html
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
|
||||
)
|
|
@ -0,0 +1,2 @@
|
|||
vendor,product,version
|
||||
@SBOMCONTENTS@
|
|
@ -133,6 +133,7 @@ download_source(NASM)
|
|||
download_source(XR_OPENXR_SDK)
|
||||
download_source(WL_PROTOCOLS)
|
||||
download_source(WAYLAND)
|
||||
download_source(WAYLAND_LIBDECOR)
|
||||
download_source(ISPC)
|
||||
download_source(GMP)
|
||||
download_source(POTRACE)
|
||||
|
|
|
@ -118,6 +118,8 @@ else()
|
|||
|
||||
harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml")
|
||||
harvest(wayland/bin wayland/bin "wayland-scanner")
|
||||
harvest(wayland/include wayland/include "*.h")
|
||||
harvest(wayland_libdecor/include wayland_libdecor/include "*.h")
|
||||
else()
|
||||
harvest(blosc/lib openvdb/lib "*.a")
|
||||
harvest(xml2/lib opencollada/lib "*.a")
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# CPE's are used to identify dependencies, for more information on what they
|
||||
# are please see https://nvd.nist.gov/products/cpe
|
||||
#
|
||||
# We use them in combination with cve-bin-tool to scan for known security issues.
|
||||
#
|
||||
# Not all of our dependencies are currently in the nvd database so not all
|
||||
# dependencies have one assigned.
|
||||
|
||||
set(ZLIB_VERSION 1.2.12)
|
||||
set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz)
|
||||
set(ZLIB_HASH 5fc414a9726be31427b440b434d05f78)
|
||||
set(ZLIB_HASH_TYPE MD5)
|
||||
set(ZLIB_FILE zlib-${ZLIB_VERSION}.tar.gz)
|
||||
set(ZLIB_CPE "cpe:2.3:a:zlib:zlib:${ZLIB_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPENAL_VERSION 1.21.1)
|
||||
set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
|
||||
|
@ -17,12 +26,14 @@ set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.
|
|||
set(PNG_HASH 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca)
|
||||
set(PNG_HASH_TYPE SHA256)
|
||||
set(PNG_FILE libpng-${PNG_VERSION}.tar.xz)
|
||||
set(PNG_CPE "cpe:2.3:a:libpng:libpng:${PNG_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(JPEG_VERSION 2.1.3)
|
||||
set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz)
|
||||
set(JPEG_HASH 627b980fad0573e08e4c3b80b290fc91)
|
||||
set(JPEG_HASH_TYPE MD5)
|
||||
set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz)
|
||||
set(JPEG_CPE "cpe:2.3:a:d.r.commander:libjpeg-turbo:${JPEG_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(BOOST_VERSION 1.78.0)
|
||||
set(BOOST_VERSION_SHORT 1.78)
|
||||
|
@ -32,12 +43,14 @@ set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION
|
|||
set(BOOST_HASH c2f6428ac52b0e5a3c9b2e1d8cc832b5)
|
||||
set(BOOST_HASH_TYPE MD5)
|
||||
set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz)
|
||||
set(BOOST_CPE "cpe:2.3:a:boost:boost:${BOOST_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(BLOSC_VERSION 1.21.1)
|
||||
set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.tar.gz)
|
||||
set(BLOSC_HASH 134b55813b1dca57019d2a2dc1f7a923)
|
||||
set(BLOSC_HASH_TYPE MD5)
|
||||
set(BLOSC_FILE blosc-${BLOSC_VERSION}.tar.gz)
|
||||
set(BLOSC_CPE "cpe:2.3:a:c-blosc2_project:c-blosc2:${BLOSC_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(PTHREADS_VERSION 3.0.0)
|
||||
set(PTHREADS_URI http://prdownloads.sourceforge.net/pthreads4w/pthreads4w-code-v${PTHREADS_VERSION}.zip)
|
||||
|
@ -50,6 +63,7 @@ set(OPENEXR_URI https://github.com/AcademySoftwareFoundation/openexr/archive/v${
|
|||
set(OPENEXR_HASH a92f38eedd43e56c0af56d4852506886)
|
||||
set(OPENEXR_HASH_TYPE MD5)
|
||||
set(OPENEXR_FILE openexr-${OPENEXR_VERSION}.tar.gz)
|
||||
set(OPENEXR_CPE "cpe:2.3:a:openexr:openexr:${OPENEXR_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(IMATH_VERSION 3.1.5)
|
||||
set(IMATH_URI https://github.com/AcademySoftwareFoundation/Imath/archive/v${OPENEXR_VERSION}.tar.gz)
|
||||
|
@ -79,6 +93,7 @@ set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE
|
|||
set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
|
||||
set(FREETYPE_HASH_TYPE MD5)
|
||||
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
|
||||
SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(EPOXY_VERSION 1.5.10)
|
||||
set(EPOXY_URI https://github.com/anholt/libepoxy/archive/refs/tags/${EPOXY_VERSION}.tar.gz)
|
||||
|
@ -97,6 +112,7 @@ set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.ta
|
|||
set(ALEMBIC_HASH 2cd8d6e5a3ac4a014e24a4b04f4fadf9)
|
||||
set(ALEMBIC_HASH_TYPE MD5)
|
||||
set(ALEMBIC_FILE alembic-${ALEMBIC_VERSION}.tar.gz)
|
||||
SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPENSUBDIV_VERSION v3_4_4)
|
||||
set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz)
|
||||
|
@ -109,6 +125,7 @@ set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
|
|||
set(SDL_HASH a53acc02e1cca98c4123229069b67c9e)
|
||||
set(SDL_HASH_TYPE MD5)
|
||||
set(SDL_FILE SDL2-${SDL_VERSION}.tar.gz)
|
||||
set(SDL_CPE "cpe:2.3:a:libsdl:sdl:${SDL_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPENCOLLADA_VERSION v1.6.68)
|
||||
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
|
||||
|
@ -127,6 +144,7 @@ set(LLVM_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LL
|
|||
set(LLVM_HASH 5a4fab4d7fc84aefffb118ac2c8a4fc0)
|
||||
set(LLVM_HASH_TYPE MD5)
|
||||
set(LLVM_FILE llvm-project-${LLVM_VERSION}.src.tar.xz)
|
||||
set(LLVM_CPE "cpe:2.3:a:llvm:compiler:${LLVM_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
if(APPLE)
|
||||
# Cloth physics test is crashing due to this bug:
|
||||
|
@ -154,6 +172,7 @@ set(FMT_URI https://github.com/fmtlib/fmt/archive/refs/tags/${FMT_VERSION}.tar.g
|
|||
set(FMT_HASH 7bce0e9e022e586b178b150002e7c2339994e3c2bbe44027e9abb0d60f9cce83)
|
||||
set(FMT_HASH_TYPE SHA256)
|
||||
set(FMT_FILE fmt-${FMT_VERSION}.tar.gz)
|
||||
set(FMT_CPE "cpe:2.3:a:fmt:fmt:${FMT_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
# 0.6.2 is currently oiio's preferred version although never versions may be available.
|
||||
# the preferred version can be found in oiio's externalpackages.cmake
|
||||
|
@ -168,6 +187,7 @@ set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz)
|
|||
set(TIFF_HASH 376f17f189e9d02280dfe709b2b2bbea)
|
||||
set(TIFF_HASH_TYPE MD5)
|
||||
set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz)
|
||||
set(TIFF_CPE "cpe:2.3:a:libtiff:libtiff:${TIFF_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OSL_VERSION 1.11.17.0)
|
||||
set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
|
||||
|
@ -182,12 +202,15 @@ set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTH
|
|||
set(PYTHON_HASH 14e8c22458ed7779a1957b26cde01db9)
|
||||
set(PYTHON_HASH_TYPE MD5)
|
||||
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
|
||||
set(PYTHON_CPE "cpe:2.3:a:python:python:${PYTHON_VERSION}:-:*:*:*:*:*:*")
|
||||
|
||||
set(TBB_VERSION 2020_U3)
|
||||
set(TBB_YEAR 2020)
|
||||
set(TBB_VERSION ${TBB_YEAR}_U3)
|
||||
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
|
||||
set(TBB_HASH 55ec8df6eae5ed6364a47f0e671e460c)
|
||||
set(TBB_HASH_TYPE MD5)
|
||||
set(TBB_FILE oneTBB-${TBB_VERSION}.tar.gz)
|
||||
set(TBB_CPE "cpe:2.3:a:intel:threading_building_blocks:${TBB_YEAR}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPENVDB_VERSION 9.0.0)
|
||||
set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
|
||||
|
@ -198,6 +221,7 @@ set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz)
|
|||
set(IDNA_VERSION 3.3)
|
||||
set(CHARSET_NORMALIZER_VERSION 2.0.10)
|
||||
set(URLLIB3_VERSION 1.26.8)
|
||||
set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*")
|
||||
set(CERTIFI_VERSION 2021.10.8)
|
||||
set(REQUESTS_VERSION 2.27.1)
|
||||
set(CYTHON_VERSION 0.29.26)
|
||||
|
@ -214,12 +238,14 @@ set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}
|
|||
set(NUMPY_HASH 252de134862a27bd66705d29622edbfe)
|
||||
set(NUMPY_HASH_TYPE MD5)
|
||||
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)
|
||||
set(NUMPY_CPE "cpe:2.3:a:numpy:numpy:${NUMPY_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(LAME_VERSION 3.100)
|
||||
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
|
||||
set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb)
|
||||
set(LAME_HASH_TYPE MD5)
|
||||
set(LAME_FILE lame-${LAME_VERSION}.tar.gz)
|
||||
set(LAME_CPE "cpe:2.3:a:lame_project:lame:${LAME_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OGG_VERSION 1.3.5)
|
||||
set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
|
||||
|
@ -232,6 +258,7 @@ set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERS
|
|||
set(VORBIS_HASH 0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab)
|
||||
set(VORBIS_HASH_TYPE SHA256)
|
||||
set(VORBIS_FILE libvorbis-${VORBIS_VERSION}.tar.gz)
|
||||
set(VORBIS_CPE "cpe:2.3:a:xiph.org:libvorbis:${VORBIS_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(THEORA_VERSION 1.1.1)
|
||||
set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
|
||||
|
@ -244,12 +271,14 @@ set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz
|
|||
set(FLAC_HASH 8ff0607e75a322dd7cd6ec48f4f225471404ae2730d0ea945127b1355155e737 )
|
||||
set(FLAC_HASH_TYPE SHA256)
|
||||
set(FLAC_FILE flac-${FLAC_VERSION}.tar.xz)
|
||||
set(FLAC_CPE "cpe:2.3:a:flac_project:flac:${FLAC_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(VPX_VERSION 1.11.0)
|
||||
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
|
||||
set(VPX_HASH 965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83)
|
||||
set(VPX_HASH_TYPE SHA256)
|
||||
set(VPX_FILE libvpx-v${VPX_VERSION}.tar.gz)
|
||||
set(VPX_CPE "cpe:2.3:a:webmproject:libvpx:${VPX_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPUS_VERSION 1.3.1)
|
||||
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
|
||||
|
@ -275,12 +304,14 @@ set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSI
|
|||
set(OPENJPEG_HASH 8702ba68b442657f11aaeb2b338443ca8d5fb95b0d845757968a7be31ef7f16d)
|
||||
set(OPENJPEG_HASH_TYPE SHA256)
|
||||
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
|
||||
set(OPENJPEG_CPE "cpe:2.3:a:uclouvain:openjpeg:${OPENJPEG_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(FFMPEG_VERSION 5.0)
|
||||
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
|
||||
set(FFMPEG_HASH c0130b8db2c763430fd1c6905288d61bc44ee0548ad5fcd2dfd650b88432bed9)
|
||||
set(FFMPEG_HASH_TYPE SHA256)
|
||||
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
|
||||
set(FFMPEG_CPE "cpe:2.3:a:ffmpeg:ffmpeg:${FFMPEG_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(FFTW_VERSION 3.3.10)
|
||||
set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
|
||||
|
@ -299,12 +330,14 @@ set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_V
|
|||
set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c)
|
||||
set(SNDFILE_HASH_TYPE MD5)
|
||||
set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.gz)
|
||||
set(SNDFILE_CPE "cpe:2.3:a:libsndfile_project:libsndfile:${SNDFILE_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(WEBP_VERSION 1.2.2)
|
||||
set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz)
|
||||
set(WEBP_HASH b5e2e414a8adee4c25fe56b18dd9c549)
|
||||
set(WEBP_HASH_TYPE MD5)
|
||||
set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz)
|
||||
set(WEBP_CPE "cpe:2.3:a:webmproject:libwebp:${WEBP_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(SPNAV_VERSION 0.2.3)
|
||||
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
|
||||
|
@ -323,6 +356,7 @@ set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
|
|||
set(XML2_HASH 10942a1dc23137a8aa07f0639cbfece5)
|
||||
set(XML2_HASH_TYPE MD5)
|
||||
set(XML2_FILE libxml2-${XML2_VERSION}.tar.gz)
|
||||
set(XML2_CPE "cpe:2.3:a:xmlsoft:libxml2:${XML2_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(TINYXML_VERSION 2_6_2)
|
||||
set(TINYXML_VERSION_DOTS 2.6.2)
|
||||
|
@ -330,12 +364,14 @@ set(TINYXML_URI https://nchc.dl.sourceforge.net/project/tinyxml/tinyxml/${TINYXM
|
|||
set(TINYXML_HASH c1b864c96804a10526540c664ade67f0)
|
||||
set(TINYXML_HASH_TYPE MD5)
|
||||
set(TINYXML_FILE tinyxml_${TINYXML_VERSION}.tar.gz)
|
||||
set(TINYXML_CPE "cpe:2.3:a:tinyxml_project:tinyxml:${TINYXML_VERSION_DOTS}:*:*:*:*:*:*:*")
|
||||
|
||||
set(YAMLCPP_VERSION 0.6.3)
|
||||
set(YAMLCPP_URI https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-${YAMLCPP_VERSION})
|
||||
set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2)
|
||||
set(YAMLCPP_HASH_TYPE MD5)
|
||||
set(YAMLCPP_FILE yaml-cpp-${YAMLCPP_VERSION}.tar.gz)
|
||||
set(YAMLCPP "cpe:2.3:a:yaml-cpp_project:yaml-cpp:${YAMLCPP_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(PYSTRING_VERSION v1.1.3)
|
||||
set(PYSTRING_URI https://codeload.github.com/imageworks/pystring/tar.gz/refs/tags/${PYSTRING_VERSION})
|
||||
|
@ -344,16 +380,19 @@ set(PYSTRING_HASH_TYPE MD5)
|
|||
set(PYSTRING_FILE pystring-${PYSTRING_VERSION}.tar.gz)
|
||||
|
||||
set(EXPAT_VERSION 2_4_4)
|
||||
set(EXPAT_VERSION_DOTS 2.4.4)
|
||||
set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz)
|
||||
set(EXPAT_HASH 2d3e81dee94b452369dc6394ff0f8f98)
|
||||
set(EXPAT_HASH_TYPE MD5)
|
||||
set(EXPAT_FILE libexpat-${EXPAT_VERSION}.tar.gz)
|
||||
set(EXPAT_CPE "cpe:2.3:a:libexpat_project:libexpat:${EXPAT_VERSION_DOTS}:*:*:*:*:*:*:*")
|
||||
|
||||
set(PUGIXML_VERSION 1.10)
|
||||
set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.gz)
|
||||
set(PUGIXML_HASH 0c208b0664c7fb822bf1b49ad035e8fd)
|
||||
set(PUGIXML_HASH_TYPE MD5)
|
||||
set(PUGIXML_FILE pugixml-${PUGIXML_VERSION}.tar.gz)
|
||||
set(PUGIXML_CPE "cpe:2.3:a:pugixml_project:pugixml:${PUGIXML_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(FLEXBISON_VERSION 2.5.24)
|
||||
set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison/win_flex_bison-${FLEXBISON_VERSION}.zip)
|
||||
|
@ -376,12 +415,14 @@ set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERS
|
|||
set(BZIP2_HASH ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269)
|
||||
set(BZIP2_HASH_TYPE SHA256)
|
||||
set(BZIP2_FILE bzip2_${BZIP2_VERSION}.orig.tar.gz)
|
||||
set(BZIP2_CPE "cpe:2.3:a:bzip:bzip2:${BZIP2_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(FFI_VERSION 3.3)
|
||||
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
|
||||
set(FFI_HASH 72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056)
|
||||
set(FFI_HASH_TYPE SHA256)
|
||||
set(FFI_FILE libffi-${FFI_VERSION}.tar.gz)
|
||||
set(FFI_CPE "cpe:2.3:a:libffi_project:libffi:${FFI_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(LZMA_VERSION 5.2.5)
|
||||
set(LZMA_URI https://tukaani.org/xz/xz-${LZMA_VERSION}.tar.bz2)
|
||||
|
@ -403,12 +444,14 @@ else()
|
|||
set(SSL_HASH_TYPE SHA256)
|
||||
set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
|
||||
endif()
|
||||
set(SSL_CPE "cpe:2.3:a:openssl:openssl:${SSL_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(SQLITE_VERSION 3.31.1)
|
||||
set(SQLITE_URI https://www.sqlite.org/2018/sqlite-src-3240000.zip)
|
||||
set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
|
||||
set(SQLITE_HASH_TYPE SHA1)
|
||||
set(SQLITE_FILE sqlite-src-3240000.zip)
|
||||
set(SQLITE_CPE "cpe:2.3:a:sqlite:sqlite:${SQLITE_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(EMBREE_VERSION 3.13.4)
|
||||
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
|
||||
|
@ -439,12 +482,14 @@ set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa/mesa-${MESA_VERSION}.tar.xz)
|
|||
set(MESA_HASH 022c7293074aeeced2278c872db4fa693147c70f8595b076cf3f1ef81520766d)
|
||||
set(MESA_HASH_TYPE SHA256)
|
||||
set(MESA_FILE mesa-${MESA_VERSION}.tar.xz)
|
||||
set(MESA_CPE "cpe:2.3:a:mesa3d:mesa:${MESA_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(NASM_VERSION 2.15.02)
|
||||
set(NASM_URI https://github.com/netwide-assembler/nasm/archive/nasm-${NASM_VERSION}.tar.gz)
|
||||
set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589)
|
||||
set(NASM_HASH_TYPE SHA256)
|
||||
set(NASM_FILE nasm-${NASM_VERSION}.tar.gz)
|
||||
set(NASM_PCE "cpe:2.3:a:nasm:nasm:${NASM_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(XR_OPENXR_SDK_VERSION 1.0.22)
|
||||
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
|
||||
|
@ -464,6 +509,12 @@ set(WAYLAND_URI https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.21.0
|
|||
set(WAYLAND_HASH f2653a2293bcd882d756c6a83d278903)
|
||||
set(WAYLAND_HASH_TYPE MD5)
|
||||
|
||||
set(WAYLAND_LIBDECOR_VERSION 0.1.0)
|
||||
set(WAYLAND_LIBDECOR_FILE libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz)
|
||||
set(WAYLAND_LIBDECOR_URI https://gitlab.gnome.org/jadahl/libdecor/uploads/81adf91d27620e20bcc5f6b9b312d768/libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz )
|
||||
set(WAYLAND_LIBDECOR_HASH 47b59eba76faa3787f0878bf8700e912)
|
||||
set(WAYLAND_LIBDECOR_HASH_TYPE MD5)
|
||||
|
||||
set(ISPC_VERSION v1.17.0)
|
||||
set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz)
|
||||
set(ISPC_HASH 4f476a3109332a77fe839a9014c60ca9)
|
||||
|
@ -475,12 +526,14 @@ set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
|
|||
set(GMP_HASH 0b82665c4a92fd2ade7440c13fcaa42b)
|
||||
set(GMP_HASH_TYPE MD5)
|
||||
set(GMP_FILE gmp-${GMP_VERSION}.tar.xz)
|
||||
set(GMP_CPE "cpe:2.3:a:gmplib:gmp:${GMP_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(POTRACE_VERSION 1.16)
|
||||
set(POTRACE_URI http://potrace.sourceforge.net/download/${POTRACE_VERSION}/potrace-${POTRACE_VERSION}.tar.gz)
|
||||
set(POTRACE_HASH 5f0bd87ddd9a620b0c4e65652ef93d69)
|
||||
set(POTRACE_HASH_TYPE MD5)
|
||||
set(POTRACE_FILE potrace-${POTRACE_VERSION}.tar.gz)
|
||||
set(POTRACE_CPE "cpe:2.3:a:icoasoft:potrace:${POTRACE_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(HARU_VERSION 2_3_0)
|
||||
set(HARU_URI https://github.com/libharu/libharu/archive/RELEASE_${HARU_VERSION}.tar.gz)
|
||||
|
@ -493,6 +546,7 @@ set(ZSTD_URI https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}
|
|||
set(ZSTD_HASH 5194fbfa781fcf45b98c5e849651aa7b3b0a008c6b72d4a0db760f3002291e94)
|
||||
set(ZSTD_HASH_TYPE SHA256)
|
||||
set(ZSTD_FILE zstd-${ZSTD_VERSION}.tar.gz)
|
||||
set(ZSTD_CPE "cpe:2.3:a:facebook:zstandard:${ZSTD_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(SSE2NEON_VERSION fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
|
||||
set(SSE2NEON_URI https://github.com/DLTcollab/sse2neon/archive/${SSE2NEON_VERSION}.tar.gz)
|
||||
|
@ -500,11 +554,12 @@ set(SSE2NEON_HASH 0780253525d299c31775ef95853698d03db9c7739942af8570000f4a25a5d6
|
|||
set(SSE2NEON_HASH_TYPE SHA256)
|
||||
set(SSE2NEON_FILE sse2neon-${SSE2NEON_VERSION}.tar.gz)
|
||||
|
||||
set(BROTLI_VERSION v1.0.9)
|
||||
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSION}.tar.gz)
|
||||
set(BROTLI_VERSION 1.0.9)
|
||||
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz)
|
||||
set(BROTLI_HASH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46)
|
||||
set(BROTLI_HASH_TYPE SHA256)
|
||||
set(BROTLI_FILE brotli-${BROTLI_VERSION}.tar.gz)
|
||||
set(BROTLI_FILE brotli-v${BROTLI_VERSION}.tar.gz)
|
||||
set(BROTLI_CPE "cpe:2.3:a:google:brotli:${BROTLI_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(OPENPGL_VERSION v0.3.1-beta)
|
||||
set(OPENPGL_SHORT_VERSION 0.3.1)
|
||||
|
|
|
@ -6,9 +6,11 @@ ExternalProject_Add(external_wayland
|
|||
URL_HASH ${WAYLAND_HASH_TYPE}=${WAYLAND_HASH}
|
||||
PREFIX ${BUILD_DIR}/wayland
|
||||
PATCH_COMMAND ${PATCH_CMD} -d ${BUILD_DIR}/wayland/src/external_wayland < ${PATCH_DIR}/wayland.diff
|
||||
# Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT.
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||
meson --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -Dlibraries=false . ../external_wayland
|
||||
# Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT & LIBXML2.
|
||||
# Note that passing link args "ffi/lib" should not be needed, but
|
||||
# `pkgconfig` would incorrectly look in "ffi/lib/../lib64" otherwise.
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:${LIBDIR}/ffi/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||
meson --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -Dc_link_args=-L${LIBDIR}/ffi/lib . ../external_wayland
|
||||
BUILD_COMMAND ninja
|
||||
INSTALL_COMMAND ninja install
|
||||
)
|
||||
|
@ -17,4 +19,5 @@ add_dependencies(
|
|||
external_wayland
|
||||
external_expat
|
||||
external_xml2
|
||||
external_ffi
|
||||
)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# NOTE: currently only the header file is extracted, no compilation is needed
|
||||
# as the library is dynamically loaded when found on the system.
|
||||
|
||||
ExternalProject_Add(external_wayland_libdecor
|
||||
URL file://${PACKAGE_DIR}/${WAYLAND_LIBDECOR_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${WAYLAND_LIBDECOR_HASH_TYPE}=${WAYLAND_LIBDECOR_HASH}
|
||||
PREFIX ${BUILD_DIR}/wayland_libdecor
|
||||
BUILD_COMMAND echo .
|
||||
CONFIGURE_COMMAND echo .
|
||||
INSTALL_COMMAND cp ../external_wayland_libdecor/src/libdecor.h ${LIBDIR}/wayland_libdecor/include/libdecor-0/libdecor.h
|
||||
INSTALL_DIR ${LIBDIR}/wayland_libdecor/include/libdecor-0
|
||||
)
|
|
@ -0,0 +1,65 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ `id -u` -ne 0 ]; then
|
||||
echo "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# yum-config-manager does not come in the default minimal install,
|
||||
# so make sure it is installed and available.
|
||||
yum -y update
|
||||
yum -y install yum-utils
|
||||
|
||||
# Install all the packages needed for a new toolchain.
|
||||
#
|
||||
# NOTE: Keep this separate from the packages install, since otherwise
|
||||
# older toolchain will be installed.
|
||||
yum -y update
|
||||
yum -y install epel-release
|
||||
yum -y install centos-release-scl
|
||||
yum -y install devtoolset-9
|
||||
|
||||
# Install packages needed for Blender's dependencies.
|
||||
yum -y install -y \
|
||||
git subversion bzip2 tar cmake3 patch make autoconf automake libtool \
|
||||
meson ninja-build \
|
||||
libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel \
|
||||
libX11-devel libXt-devel \
|
||||
mesa-libEGL-devel mesa-libGL-devel mesa-libGLU-devel \
|
||||
zlib-devel \
|
||||
rubygem-asciidoctor \
|
||||
wget tcl yasm python36 python-setuptools bison flex \
|
||||
ncurses-devel \
|
||||
wayland-devel libwayland-client libwayland-server \
|
||||
|
||||
|
||||
# Dependencies for Mesa
|
||||
yum -y install expat-devel
|
||||
python3 -m pip install mako
|
||||
|
||||
# Dependencies for pip (needed for buildbot-worker).
|
||||
yum -y install python36-pip python36-devel
|
||||
|
||||
# Dependencies for asound.
|
||||
yum -y install -y \
|
||||
alsa-lib-devel pulseaudio-libs-devel
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \
|
||||
--family cmake
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
|
||||
--family cmake
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
|
||||
--family cmake
|
|
@ -62,6 +62,13 @@ FIND_LIBRARY(SYCL_LIBRARY
|
|||
lib64 lib
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
string(REPLACE ".lib" "d.lib" SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY})
|
||||
set(SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY_DEBUG} CACHE FILEPATH "Path to SYCL debug library")
|
||||
else()
|
||||
set(SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY} CACHE FILEPATH "Path to SYCL debug library")
|
||||
endif()
|
||||
|
||||
FIND_PATH(SYCL_INCLUDE_DIR
|
||||
NAMES
|
||||
CL/sycl.hpp
|
||||
|
@ -85,4 +92,5 @@ ENDIF()
|
|||
|
||||
MARK_AS_ADVANCED(
|
||||
_SYCL_INCLUDE_PARENT_DIR
|
||||
SYCL_LIBRARY_DEBUG
|
||||
)
|
||||
|
|
|
@ -335,10 +335,18 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
set(LEVEL_ZERO_ROOT_DIR ${CYCLES_LEVEL_ZERO})
|
||||
endif()
|
||||
|
||||
set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to DPC++ and SYCL installation")
|
||||
set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to oneAPI DPC++ compiler")
|
||||
if(EXISTS ${CYCLES_SYCL} AND NOT SYCL_ROOT_DIR)
|
||||
set(SYCL_ROOT_DIR ${CYCLES_SYCL})
|
||||
endif()
|
||||
file(GLOB _sycl_runtime_libraries
|
||||
${SYCL_ROOT_DIR}/lib/libsycl.so
|
||||
${SYCL_ROOT_DIR}/lib/libsycl.so.[0-9]
|
||||
${SYCL_ROOT_DIR}/lib/libsycl.so.[0-9].[0-9].[0-9]-[0-9]
|
||||
${SYCL_ROOT_DIR}/lib/libpi_level_zero.so
|
||||
)
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries})
|
||||
unset(_sycl_runtime_libraries)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
|
@ -691,14 +699,23 @@ endif()
|
|||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(wayland-client wayland-client>=1.12)
|
||||
pkg_check_modules(wayland-egl wayland-egl)
|
||||
pkg_check_modules(wayland-scanner wayland-scanner)
|
||||
pkg_check_modules(xkbcommon xkbcommon)
|
||||
pkg_check_modules(wayland-cursor wayland-cursor)
|
||||
pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
|
||||
|
||||
if(${wayland-protocols_FOUND})
|
||||
# When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present,
|
||||
# there is no need to search for the libraries as they are not needed for building.
|
||||
# Only the headers are needed which can reference the known paths.
|
||||
if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
set(_use_system_wayland OFF)
|
||||
else()
|
||||
set(_use_system_wayland ON)
|
||||
endif()
|
||||
|
||||
if(_use_system_wayland)
|
||||
pkg_check_modules(wayland-client wayland-client>=1.12)
|
||||
pkg_check_modules(wayland-egl wayland-egl)
|
||||
pkg_check_modules(wayland-scanner wayland-scanner)
|
||||
pkg_check_modules(wayland-cursor wayland-cursor)
|
||||
pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||
else()
|
||||
# CentOS 7 packages have too old a version, a newer version exist in the
|
||||
|
@ -712,6 +729,15 @@ if(WITH_GHOST_WAYLAND)
|
|||
if(EXISTS ${WAYLAND_PROTOCOLS_DIR})
|
||||
set(wayland-protocols_FOUND ON)
|
||||
endif()
|
||||
|
||||
set(wayland-client_INCLUDE_DIRS "${LIBDIR}/wayland/include")
|
||||
set(wayland-egl_INCLUDE_DIRS "${LIBDIR}/wayland/include")
|
||||
set(wayland-cursor_INCLUDE_DIRS "${LIBDIR}/wayland/include")
|
||||
|
||||
set(wayland-client_FOUND ON)
|
||||
set(wayland-egl_FOUND ON)
|
||||
set(wayland-scanner_FOUND ON)
|
||||
set(wayland-cursor_FOUND ON)
|
||||
endif()
|
||||
|
||||
if (NOT ${wayland-client_FOUND})
|
||||
|
@ -745,7 +771,11 @@ if(WITH_GHOST_WAYLAND)
|
|||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
|
||||
if(_use_system_wayland)
|
||||
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
|
||||
else()
|
||||
set(libdecor_INCLUDE_DIRS "${LIBDIR}/wayland_libdecor/include/libdecor-0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
|
@ -815,6 +845,8 @@ if(WITH_GHOST_WAYLAND)
|
|||
# End wayland-scanner version check.
|
||||
|
||||
endif()
|
||||
|
||||
unset(_use_system_wayland)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_X11)
|
||||
|
|
|
@ -952,5 +952,23 @@ endif()
|
|||
set(ZSTD_INCLUDE_DIRS ${LIBDIR}/zstd/include)
|
||||
set(ZSTD_LIBRARIES ${LIBDIR}/zstd/lib/zstd_static.lib)
|
||||
|
||||
set(LEVEL_ZERO_ROOT_DIR ${LIBDIR}/level_zero)
|
||||
set(SYCL_ROOT_DIR ${LIBDIR}/dpcpp)
|
||||
if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
set(LEVEL_ZERO_ROOT_DIR ${LIBDIR}/level_zero)
|
||||
set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to oneAPI DPC++ compiler")
|
||||
if(EXISTS ${CYCLES_SYCL} AND NOT SYCL_ROOT_DIR)
|
||||
set(SYCL_ROOT_DIR ${CYCLES_SYCL})
|
||||
endif()
|
||||
file(GLOB _sycl_runtime_libraries_glob
|
||||
${SYCL_ROOT_DIR}/bin/sycl.dll
|
||||
${SYCL_ROOT_DIR}/bin/sycl[0-9].dll
|
||||
)
|
||||
foreach(sycl_runtime_library IN LISTS _sycl_runtime_libraries_glob)
|
||||
string(REPLACE ".dll" "$<$<CONFIG:Debug>:d>.dll" sycl_runtime_library ${sycl_runtime_library})
|
||||
list(APPEND _sycl_runtime_libraries ${sycl_runtime_library})
|
||||
endforeach()
|
||||
unset(_sycl_runtime_libraries_glob)
|
||||
|
||||
list(APPEND _sycl_runtime_libraries ${SYCL_ROOT_DIR}/bin/pi_level_zero.dll)
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries})
|
||||
unset(_sycl_runtime_libraries)
|
||||
endif()
|
||||
|
|
|
@ -525,8 +525,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||
|
||||
use_deterministic_guiding: BoolProperty(
|
||||
name="Deterministic",
|
||||
description="Makes path guiding deterministic which means renderings will be"
|
||||
"reproducible with the same pixel values every time. This feature slows down"
|
||||
description="Makes path guiding deterministic which means renderings will be "
|
||||
"reproducible with the same pixel values every time. This feature slows down "
|
||||
"training",
|
||||
default=True,
|
||||
)
|
||||
|
@ -562,7 +562,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||
description="The maximum number of samples used for training path guiding. "
|
||||
"Higher samples lead to more accurate guiding, however may also unnecessarily slow "
|
||||
"down rendering once guiding is accurate enough. "
|
||||
"A value 0 will continue training until the last sample",
|
||||
"A value of 0 will continue training until the last sample",
|
||||
min=0,
|
||||
soft_min=1,
|
||||
default=128,
|
||||
|
|
|
@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
|
|||
* Utility class to map between Blender datablocks and Cycles data structures,
|
||||
* and keep track of recalc tags from the dependency graph. */
|
||||
|
||||
template<typename K, typename T> class id_map {
|
||||
template<typename K, typename T, typename Flags = uint> class id_map {
|
||||
public:
|
||||
id_map(Scene *scene_) : scene(scene_)
|
||||
{
|
||||
|
@ -63,6 +63,11 @@ template<typename K, typename T> class id_map {
|
|||
b_recalc.insert(id_ptr);
|
||||
}
|
||||
|
||||
bool check_recalc(const BL::ID &id)
|
||||
{
|
||||
return id.ptr.data && b_recalc.find(id.ptr.data) != b_recalc.end();
|
||||
}
|
||||
|
||||
bool has_recalc()
|
||||
{
|
||||
return !(b_recalc.empty());
|
||||
|
@ -154,6 +159,7 @@ template<typename K, typename T> class id_map {
|
|||
TMapPair &pair = *jt;
|
||||
|
||||
if (do_delete && used_set.find(pair.second) == used_set.end()) {
|
||||
flags.erase(pair.second);
|
||||
scene->delete_node(pair.second);
|
||||
}
|
||||
else {
|
||||
|
@ -171,9 +177,33 @@ template<typename K, typename T> class id_map {
|
|||
return b_map;
|
||||
}
|
||||
|
||||
bool test_flag(T *data, Flags val)
|
||||
{
|
||||
typename map<T *, uint>::iterator it = flags.find(data);
|
||||
return it != flags.end() && (it->second & (1 << val)) != 0;
|
||||
}
|
||||
|
||||
void set_flag(T *data, Flags val)
|
||||
{
|
||||
flags[data] |= (1 << val);
|
||||
}
|
||||
|
||||
void clear_flag(T *data, Flags val)
|
||||
{
|
||||
typename map<T *, uint>::iterator it = flags.find(data);
|
||||
if (it != flags.end()) {
|
||||
it->second &= ~(1 << val);
|
||||
|
||||
if (it->second == 0) {
|
||||
flags.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
map<K, T *> b_map;
|
||||
set<T *> used_set;
|
||||
map<T *, uint> flags;
|
||||
set<void *> b_recalc;
|
||||
Scene *scene;
|
||||
};
|
||||
|
|
|
@ -96,6 +96,13 @@ bool BlenderSync::object_is_light(BL::Object &b_ob)
|
|||
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
|
||||
}
|
||||
|
||||
bool BlenderSync::object_is_camera(BL::Object &b_ob)
|
||||
{
|
||||
BL::ID b_ob_data = b_ob.data();
|
||||
|
||||
return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
|
||||
}
|
||||
|
||||
void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object)
|
||||
{
|
||||
/* Initialize motion blur for object, detecting if it's enabled and creating motion
|
||||
|
@ -400,7 +407,8 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
|
|||
std::string real_name;
|
||||
BlenderAttributeType type = blender_attribute_name_split_type(name, &real_name);
|
||||
|
||||
if (type != BL::ShaderNodeAttribute::attribute_type_GEOMETRY) {
|
||||
if (type == BL::ShaderNodeAttribute::attribute_type_OBJECT ||
|
||||
type == BL::ShaderNodeAttribute::attribute_type_INSTANCER) {
|
||||
bool use_instancer = (type == BL::ShaderNodeAttribute::attribute_type_INSTANCER);
|
||||
float4 value = lookup_instance_property(b_instance, real_name, use_instancer);
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "util/string.h"
|
||||
#include "util/task.h"
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
typedef map<void *, ShaderInput *> PtrInputMap;
|
||||
|
@ -103,6 +105,7 @@ static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
|
|||
|
||||
static const string_view object_attr_prefix("\x01object:");
|
||||
static const string_view instancer_attr_prefix("\x01instancer:");
|
||||
static const string_view view_layer_attr_prefix("\x01layer:");
|
||||
|
||||
static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type)
|
||||
{
|
||||
|
@ -111,6 +114,8 @@ static ustring blender_attribute_name_add_type(const string &name, BlenderAttrib
|
|||
return ustring::concat(object_attr_prefix, name);
|
||||
case BL::ShaderNodeAttribute::attribute_type_INSTANCER:
|
||||
return ustring::concat(instancer_attr_prefix, name);
|
||||
case BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER:
|
||||
return ustring::concat(view_layer_attr_prefix, name);
|
||||
default:
|
||||
return ustring(name);
|
||||
}
|
||||
|
@ -130,6 +135,11 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
|
|||
return BL::ShaderNodeAttribute::attribute_type_INSTANCER;
|
||||
}
|
||||
|
||||
if (sname.substr(0, view_layer_attr_prefix.size()) == view_layer_attr_prefix) {
|
||||
*r_real_name = sname.substr(view_layer_attr_prefix.size());
|
||||
return BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER;
|
||||
}
|
||||
|
||||
return BL::ShaderNodeAttribute::attribute_type_GEOMETRY;
|
||||
}
|
||||
|
||||
|
@ -205,7 +215,9 @@ static void set_default_value(ShaderInput *input,
|
|||
}
|
||||
case SocketType::INT: {
|
||||
if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
|
||||
node->set(socket, get_boolean(b_sock.ptr, "default_value"));
|
||||
/* Make sure to call the int overload of set() since this is an integer socket as far as
|
||||
* Cycles is concerned. */
|
||||
node->set(socket, get_boolean(b_sock.ptr, "default_value") ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
node->set(socket, get_int(b_sock.ptr, "default_value"));
|
||||
|
@ -1420,6 +1432,89 @@ static void add_nodes(Scene *scene,
|
|||
empty_proxy_map);
|
||||
}
|
||||
|
||||
/* Look up and constant fold all references to View Layer attributes. */
|
||||
void BlenderSync::resolve_view_layer_attributes(Shader *shader,
|
||||
ShaderGraph *graph,
|
||||
BL::Depsgraph &b_depsgraph)
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
foreach (ShaderNode *node, graph->nodes) {
|
||||
if (node->is_a(AttributeNode::node_type)) {
|
||||
AttributeNode *attr_node = static_cast<AttributeNode *>(node);
|
||||
|
||||
std::string real_name;
|
||||
BlenderAttributeType type = blender_attribute_name_split_type(attr_node->get_attribute(),
|
||||
&real_name);
|
||||
|
||||
if (type == BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER) {
|
||||
/* Look up the value. */
|
||||
BL::ViewLayer b_layer = b_depsgraph.view_layer_eval();
|
||||
BL::Scene b_scene = b_depsgraph.scene_eval();
|
||||
float4 value;
|
||||
|
||||
BKE_view_layer_find_rgba_attribute((::Scene *)b_scene.ptr.data,
|
||||
(::ViewLayer *)b_layer.ptr.data,
|
||||
real_name.c_str(),
|
||||
&value.x);
|
||||
|
||||
/* Replace all outgoing links, using appropriate output types. */
|
||||
float val_avg = (value.x + value.y + value.z) / 3.0f;
|
||||
|
||||
foreach (ShaderOutput *output, node->outputs) {
|
||||
float val_float;
|
||||
float3 val_float3;
|
||||
|
||||
if (output->type() == SocketType::FLOAT) {
|
||||
val_float = (output->name() == "Alpha") ? value.w : val_avg;
|
||||
val_float3 = make_float3(val_float);
|
||||
}
|
||||
else {
|
||||
val_float = val_avg;
|
||||
val_float3 = float4_to_float3(value);
|
||||
}
|
||||
|
||||
foreach (ShaderInput *sock, output->links) {
|
||||
if (sock->type() == SocketType::FLOAT) {
|
||||
sock->set(val_float);
|
||||
}
|
||||
else if (SocketType::is_float3(sock->type())) {
|
||||
sock->set(val_float3);
|
||||
}
|
||||
|
||||
sock->constant_folded_in = true;
|
||||
}
|
||||
|
||||
graph->disconnect(output);
|
||||
}
|
||||
|
||||
/* Clear the attribute name to avoid further attempts to look up. */
|
||||
attr_node->set_attribute(ustring());
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
shader_map.set_flag(shader, SHADER_WITH_LAYER_ATTRS);
|
||||
}
|
||||
else {
|
||||
shader_map.clear_flag(shader, SHADER_WITH_LAYER_ATTRS);
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderSync::scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph)
|
||||
{
|
||||
if (shader && shader_map.test_flag(shader, SHADER_WITH_LAYER_ATTRS)) {
|
||||
BL::Scene scene = b_depsgraph.scene_eval();
|
||||
|
||||
return shader_map.check_recalc(scene) || shader_map.check_recalc(scene.world()) ||
|
||||
shader_map.check_recalc(scene.camera());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Sync Materials */
|
||||
|
||||
void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
|
@ -1438,7 +1533,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||
Shader *shader;
|
||||
|
||||
/* test if we need to sync */
|
||||
if (shader_map.add_or_update(&shader, b_mat) || update_all) {
|
||||
if (shader_map.add_or_update(&shader, b_mat) || update_all ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph)) {
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
|
||||
shader->name = b_mat.name().c_str();
|
||||
|
@ -1459,6 +1555,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||
graph->connect(diffuse->output("BSDF"), out->input("Surface"));
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
|
||||
/* settings */
|
||||
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
|
||||
shader->set_use_mis(get_boolean(cmat, "sample_as_light"));
|
||||
|
@ -1515,9 +1613,11 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
|||
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
|
||||
|
||||
Shader *shader = scene->default_background;
|
||||
|
||||
if (world_recalc || update_all || b_world.ptr.data != world_map ||
|
||||
viewport_parameters.shader_modified(new_viewport_parameters)) {
|
||||
Shader *shader = scene->default_background;
|
||||
viewport_parameters.shader_modified(new_viewport_parameters) ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph)) {
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
|
||||
/* create nodes */
|
||||
|
@ -1615,6 +1715,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
|||
background->set_visibility(visibility);
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->tag_update(scene);
|
||||
}
|
||||
|
@ -1681,7 +1783,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||
Shader *shader;
|
||||
|
||||
/* test if we need to sync */
|
||||
if (shader_map.add_or_update(&shader, b_light) || update_all) {
|
||||
if (shader_map.add_or_update(&shader, b_light) || update_all ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph)) {
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
|
||||
/* create nodes */
|
||||
|
@ -1702,6 +1805,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||
graph->connect(emission->output("Emission"), out->input("Surface"));
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->tag_update(scene);
|
||||
}
|
||||
|
|
|
@ -206,6 +206,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (object_is_camera(b_ob)) {
|
||||
shader_map.set_recalc(b_ob);
|
||||
}
|
||||
}
|
||||
/* Mesh */
|
||||
else if (b_id.is_a(&RNA_Mesh)) {
|
||||
|
@ -218,6 +221,11 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||
if (world_map == b_world.ptr.data) {
|
||||
world_recalc = true;
|
||||
}
|
||||
shader_map.set_recalc(b_world);
|
||||
}
|
||||
/* World */
|
||||
else if (b_id.is_a(&RNA_Scene)) {
|
||||
shader_map.set_recalc(b_id);
|
||||
}
|
||||
/* Volume */
|
||||
else if (b_id.is_a(&RNA_Volume)) {
|
||||
|
|
|
@ -120,6 +120,11 @@ class BlenderSync {
|
|||
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
|
||||
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
|
||||
|
||||
bool scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph);
|
||||
void resolve_view_layer_attributes(Shader *shader,
|
||||
ShaderGraph *graph,
|
||||
BL::Depsgraph &b_depsgraph);
|
||||
|
||||
/* Object */
|
||||
Object *sync_object(BL::Depsgraph &b_depsgraph,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
|
@ -207,13 +212,16 @@ class BlenderSync {
|
|||
bool object_is_geometry(BObjectInfo &b_ob_info);
|
||||
bool object_can_have_geometry(BL::Object &b_ob);
|
||||
bool object_is_light(BL::Object &b_ob);
|
||||
bool object_is_camera(BL::Object &b_ob);
|
||||
|
||||
/* variables */
|
||||
BL::RenderEngine b_engine;
|
||||
BL::BlendData b_data;
|
||||
BL::Scene b_scene;
|
||||
|
||||
id_map<void *, Shader> shader_map;
|
||||
enum ShaderFlags { SHADER_WITH_LAYER_ATTRS };
|
||||
|
||||
id_map<void *, Shader, ShaderFlags> shader_map;
|
||||
id_map<ObjectKey, Object> object_map;
|
||||
id_map<void *, Procedural> procedural_map;
|
||||
id_map<GeometryKey, Geometry> geometry_map;
|
||||
|
|
|
@ -274,7 +274,7 @@ endif()
|
|||
###########################################################################
|
||||
|
||||
if(CYCLES_STANDALONE_REPOSITORY AND WITH_CYCLES_PATH_GUIDING)
|
||||
if(EXISTS ${_cycles_lib_dir})
|
||||
if(NOT openpgl_DIR AND EXISTS ${_cycles_lib_dir})
|
||||
set(openpgl_DIR ${_cycles_lib_dir}/openpgl/lib/cmake/openpgl)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -142,7 +142,6 @@ set(SRC
|
|||
${SRC_DUMMY}
|
||||
${SRC_MULTI}
|
||||
${SRC_OPTIX}
|
||||
${SRC_ONEAPI}
|
||||
${SRC_HEADERS}
|
||||
)
|
||||
|
||||
|
@ -188,7 +187,25 @@ if(WITH_CYCLES_DEVICE_METAL)
|
|||
)
|
||||
endif()
|
||||
if (WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if(WIN32)
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/../kernel/cycles_kernel_oneapi.lib)
|
||||
else()
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/../kernel/libcycles_kernel_oneapi.so)
|
||||
endif()
|
||||
list(APPEND LIB
|
||||
${cycles_kernel_oneapi_lib}
|
||||
"$<$<CONFIG:Debug>:${SYCL_LIBRARY_DEBUG}>"
|
||||
"$<$<CONFIG:Release>:${SYCL_LIBRARY}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${SYCL_LIBRARY}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${SYCL_LIBRARY}>"
|
||||
)
|
||||
add_definitions(-DWITH_ONEAPI)
|
||||
list(APPEND SRC
|
||||
${SRC_ONEAPI}
|
||||
)
|
||||
list(APPEND INC_SYS
|
||||
${SYCL_INCLUDE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENIMAGEDENOISE)
|
||||
|
|
|
@ -19,62 +19,12 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef WITH_ONEAPI
|
||||
static OneAPIDLLInterface oneapi_dll;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY(path) (void *)(LoadLibrary(path))
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() GetLastError()
|
||||
# define FREE_SHARED_LIBRARY(handle) FreeLibrary((HMODULE)handle)
|
||||
# define GET_SHARED_LIBRARY_SYMBOL(handle, name) GetProcAddress((HMODULE)handle, name)
|
||||
#elif __linux__
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY(path) dlopen(path, RTLD_NOW)
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() dlerror()
|
||||
# define FREE_SHARED_LIBRARY(handle) dlclose(handle)
|
||||
# define GET_SHARED_LIBRARY_SYMBOL(handle, name) dlsym(handle, name)
|
||||
#endif
|
||||
|
||||
bool device_oneapi_init()
|
||||
{
|
||||
#if !defined(WITH_ONEAPI)
|
||||
return false;
|
||||
#else
|
||||
|
||||
string lib_path = path_get("lib");
|
||||
# ifdef _WIN32
|
||||
lib_path = path_join(lib_path, "cycles_kernel_oneapi.dll");
|
||||
# else
|
||||
lib_path = path_join(lib_path, "cycles_kernel_oneapi.so");
|
||||
# endif
|
||||
void *lib_handle = LOAD_ONEAPI_SHARED_LIBRARY(lib_path.c_str());
|
||||
|
||||
/* This shouldn't happen, but it still makes sense to have a branch for this. */
|
||||
if (lib_handle == NULL) {
|
||||
LOG(ERROR) << "oneAPI kernel shared library cannot be loaded: "
|
||||
<< LOAD_ONEAPI_SHARED_LIBRARY_ERROR();
|
||||
return false;
|
||||
}
|
||||
|
||||
# define DLL_INTERFACE_CALL(function, return_type, ...) \
|
||||
(oneapi_dll.function) = reinterpret_cast<decltype(oneapi_dll.function)>( \
|
||||
GET_SHARED_LIBRARY_SYMBOL(lib_handle, #function)); \
|
||||
if (oneapi_dll.function == NULL) { \
|
||||
LOG(ERROR) << "oneAPI shared library function \"" << #function \
|
||||
<< "\" has not been loaded from kernel shared - disable oneAPI " \
|
||||
"library disable oneAPI implementation due to this"; \
|
||||
FREE_SHARED_LIBRARY(lib_handle); \
|
||||
return false; \
|
||||
}
|
||||
# include "kernel/device/oneapi/dll_interface_template.h"
|
||||
# undef DLL_INTERFACE_CALL
|
||||
|
||||
VLOG_INFO << "oneAPI kernel shared library has been loaded successfully";
|
||||
|
||||
/* We need to have this oneapi kernel shared library during all life-span of the Blender.
|
||||
* So it is not unloaded because of this.
|
||||
* FREE_SHARED_LIBRARY(lib_handle); */
|
||||
|
||||
/* NOTE(@nsirgien): we need to enable JIT cache from here and
|
||||
* right now this cache policy is controlled by env. variables. */
|
||||
/* NOTE(hallade) we also disable use of copy engine as it
|
||||
|
@ -109,17 +59,10 @@ bool device_oneapi_init()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
# undef LOAD_SYCL_SHARED_LIBRARY
|
||||
# undef LOAD_ONEAPI_SHARED_LIBRARY
|
||||
# undef FREE_SHARED_LIBRARY
|
||||
# undef GET_SHARED_LIBRARY_SYMBOL
|
||||
#endif
|
||||
|
||||
Device *device_oneapi_create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
|
||||
{
|
||||
#ifdef WITH_ONEAPI
|
||||
return new OneapiDevice(info, oneapi_dll, stats, profiler);
|
||||
return new OneapiDevice(info, stats, profiler);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
|
@ -165,7 +108,7 @@ static void device_iterator_cb(const char *id, const char *name, int num, void *
|
|||
void device_oneapi_info(vector<DeviceInfo> &devices)
|
||||
{
|
||||
#ifdef WITH_ONEAPI
|
||||
(oneapi_dll.oneapi_iterate_devices)(device_iterator_cb, &devices);
|
||||
OneapiDevice::iterate_devices(device_iterator_cb, &devices);
|
||||
#else /* WITH_ONEAPI */
|
||||
(void)devices;
|
||||
#endif /* WITH_ONEAPI */
|
||||
|
@ -175,10 +118,10 @@ string device_oneapi_capabilities()
|
|||
{
|
||||
string capabilities;
|
||||
#ifdef WITH_ONEAPI
|
||||
char *c_capabilities = (oneapi_dll.oneapi_device_capabilities)();
|
||||
char *c_capabilities = OneapiDevice::device_capabilities();
|
||||
if (c_capabilities) {
|
||||
capabilities = c_capabilities;
|
||||
(oneapi_dll.oneapi_free)(c_capabilities);
|
||||
free(c_capabilities);
|
||||
}
|
||||
#endif
|
||||
return capabilities;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# include "util/debug.h"
|
||||
# include "util/log.h"
|
||||
|
||||
# include "kernel/device/oneapi/kernel.h"
|
||||
# include "kernel/device/oneapi/globals.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -19,26 +19,19 @@ static void queue_error_cb(const char *message, void *user_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
OneapiDevice::OneapiDevice(const DeviceInfo &info,
|
||||
OneAPIDLLInterface &oneapi_dll_object,
|
||||
Stats &stats,
|
||||
Profiler &profiler)
|
||||
OneapiDevice::OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
|
||||
: Device(info, stats, profiler),
|
||||
device_queue_(nullptr),
|
||||
texture_info_(this, "texture_info", MEM_GLOBAL),
|
||||
kg_memory_(nullptr),
|
||||
kg_memory_device_(nullptr),
|
||||
kg_memory_size_(0),
|
||||
oneapi_dll_(oneapi_dll_object)
|
||||
kg_memory_size_(0)
|
||||
{
|
||||
need_texture_info_ = false;
|
||||
|
||||
oneapi_dll_.oneapi_set_error_cb(queue_error_cb, &oneapi_error_string_);
|
||||
oneapi_set_error_cb(queue_error_cb, &oneapi_error_string_);
|
||||
|
||||
/* OneAPI calls should be initialized on this moment. */
|
||||
assert(oneapi_dll_.oneapi_create_queue != nullptr);
|
||||
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_create_queue(device_queue_, info.num);
|
||||
bool is_finished_ok = create_queue(device_queue_, info.num);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI queue initialization error: got runtime exception \"" +
|
||||
oneapi_error_string_ + "\"");
|
||||
|
@ -50,7 +43,7 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info,
|
|||
}
|
||||
|
||||
size_t globals_segment_size;
|
||||
is_finished_ok = oneapi_dll_.oneapi_kernel_globals_size(device_queue_, globals_segment_size);
|
||||
is_finished_ok = kernel_globals_size(device_queue_, globals_segment_size);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI constant memory initialization got runtime exception \"" +
|
||||
oneapi_error_string_ + "\"");
|
||||
|
@ -59,27 +52,27 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info,
|
|||
VLOG_DEBUG << "Successfully created global/constant memory segment (kernel globals object)";
|
||||
}
|
||||
|
||||
kg_memory_ = oneapi_dll_.oneapi_usm_aligned_alloc_host(device_queue_, globals_segment_size, 16);
|
||||
oneapi_dll_.oneapi_usm_memset(device_queue_, kg_memory_, 0, globals_segment_size);
|
||||
kg_memory_ = usm_aligned_alloc_host(device_queue_, globals_segment_size, 16);
|
||||
usm_memset(device_queue_, kg_memory_, 0, globals_segment_size);
|
||||
|
||||
kg_memory_device_ = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, globals_segment_size);
|
||||
kg_memory_device_ = usm_alloc_device(device_queue_, globals_segment_size);
|
||||
|
||||
kg_memory_size_ = globals_segment_size;
|
||||
|
||||
max_memory_on_device_ = oneapi_dll_.oneapi_get_memcapacity(device_queue_);
|
||||
max_memory_on_device_ = get_memcapacity();
|
||||
}
|
||||
|
||||
OneapiDevice::~OneapiDevice()
|
||||
{
|
||||
texture_info_.free();
|
||||
oneapi_dll_.oneapi_usm_free(device_queue_, kg_memory_);
|
||||
oneapi_dll_.oneapi_usm_free(device_queue_, kg_memory_device_);
|
||||
usm_free(device_queue_, kg_memory_);
|
||||
usm_free(device_queue_, kg_memory_device_);
|
||||
|
||||
for (ConstMemMap::iterator mt = const_mem_map_.begin(); mt != const_mem_map_.end(); mt++)
|
||||
delete mt->second;
|
||||
|
||||
if (device_queue_)
|
||||
oneapi_dll_.oneapi_free_queue(device_queue_);
|
||||
free_queue(device_queue_);
|
||||
}
|
||||
|
||||
bool OneapiDevice::check_peer_access(Device * /*peer_device*/)
|
||||
|
@ -95,18 +88,26 @@ BVHLayoutMask OneapiDevice::get_bvh_layout_mask() const
|
|||
bool OneapiDevice::load_kernels(const uint requested_features)
|
||||
{
|
||||
assert(device_queue_);
|
||||
/* NOTE(@nsirgien): oneAPI can support compilation of kernel code with certain feature set
|
||||
* with specialization constants, but it hasn't been implemented yet. */
|
||||
(void)requested_features;
|
||||
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_run_test_kernel(device_queue_);
|
||||
bool is_finished_ok = oneapi_run_test_kernel(device_queue_);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI kernel load: got runtime exception \"" + oneapi_error_string_ + "\"");
|
||||
set_error("oneAPI test kernel execution: got a runtime exception \"" + oneapi_error_string_ +
|
||||
"\"");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
VLOG_INFO << "Runtime compilation done for \"" << info.description << "\"";
|
||||
VLOG_INFO << "Test kernel has been executed successfully for \"" << info.description << "\"";
|
||||
assert(device_queue_);
|
||||
}
|
||||
|
||||
is_finished_ok = oneapi_load_kernels(device_queue_, (const unsigned int)requested_features);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI kernels loading: got a runtime exception \"" + oneapi_error_string_ + "\"");
|
||||
}
|
||||
else {
|
||||
VLOG_INFO << "Kernels loading (compilation) has been done for \"" << info.description << "\"";
|
||||
}
|
||||
|
||||
return is_finished_ok;
|
||||
}
|
||||
|
||||
|
@ -138,7 +139,7 @@ void OneapiDevice::generic_alloc(device_memory &mem)
|
|||
* type has been used for oneAPI device in order to better fit in Cycles architecture. */
|
||||
void *device_pointer = nullptr;
|
||||
if (mem.memory_size() + stats.mem_used < max_memory_on_device_)
|
||||
device_pointer = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, memory_size);
|
||||
device_pointer = usm_alloc_device(device_queue_, memory_size);
|
||||
if (device_pointer == nullptr) {
|
||||
set_error("oneAPI kernel - device memory allocation error for " +
|
||||
string_human_readable_size(mem.memory_size()) +
|
||||
|
@ -163,8 +164,7 @@ void OneapiDevice::generic_copy_to(device_memory &mem)
|
|||
/* Copy operation from host shouldn't be requested if there is no memory allocated on host. */
|
||||
assert(mem.host_pointer);
|
||||
assert(device_queue_);
|
||||
oneapi_dll_.oneapi_usm_memcpy(
|
||||
device_queue_, (void *)mem.device_pointer, (void *)mem.host_pointer, memory_size);
|
||||
usm_memcpy(device_queue_, (void *)mem.device_pointer, (void *)mem.host_pointer, memory_size);
|
||||
}
|
||||
|
||||
/* TODO: Make sycl::queue part of OneapiQueue and avoid using pointers to sycl::queue. */
|
||||
|
@ -178,11 +178,6 @@ string OneapiDevice::oneapi_error_message()
|
|||
return string(oneapi_error_string_);
|
||||
}
|
||||
|
||||
OneAPIDLLInterface OneapiDevice::oneapi_dll_object()
|
||||
{
|
||||
return oneapi_dll_;
|
||||
}
|
||||
|
||||
void *OneapiDevice::kernel_globals_device_pointer()
|
||||
{
|
||||
return kg_memory_device_;
|
||||
|
@ -198,7 +193,7 @@ void OneapiDevice::generic_free(device_memory &mem)
|
|||
mem.device_size = 0;
|
||||
|
||||
assert(device_queue_);
|
||||
oneapi_dll_.oneapi_usm_free(device_queue_, (void *)mem.device_pointer);
|
||||
usm_free(device_queue_, (void *)mem.device_pointer);
|
||||
mem.device_pointer = 0;
|
||||
}
|
||||
|
||||
|
@ -266,8 +261,7 @@ void OneapiDevice::mem_copy_from(device_memory &mem, size_t y, size_t w, size_t
|
|||
if (mem.device_pointer) {
|
||||
char *shifted_host = reinterpret_cast<char *>(mem.host_pointer) + offset;
|
||||
char *shifted_device = reinterpret_cast<char *>(mem.device_pointer) + offset;
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_usm_memcpy(
|
||||
device_queue_, shifted_host, shifted_device, size);
|
||||
bool is_finished_ok = usm_memcpy(device_queue_, shifted_host, shifted_device, size);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI memory operation error: got runtime exception \"" +
|
||||
oneapi_error_string_ + "\"");
|
||||
|
@ -292,7 +286,7 @@ void OneapiDevice::mem_zero(device_memory &mem)
|
|||
}
|
||||
|
||||
assert(device_queue_);
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_usm_memset(
|
||||
bool is_finished_ok = usm_memset(
|
||||
device_queue_, (void *)mem.device_pointer, 0, mem.memory_size());
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI memory operation error: got runtime exception \"" + oneapi_error_string_ +
|
||||
|
@ -349,10 +343,9 @@ void OneapiDevice::const_copy_to(const char *name, void *host, size_t size)
|
|||
memcpy(data->data(), host, size);
|
||||
data->copy_to_device();
|
||||
|
||||
oneapi_dll_.oneapi_set_global_memory(
|
||||
device_queue_, kg_memory_, name, (void *)data->device_pointer);
|
||||
set_global_memory(device_queue_, kg_memory_, name, (void *)data->device_pointer);
|
||||
|
||||
oneapi_dll_.oneapi_usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
|
||||
usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
|
||||
}
|
||||
|
||||
void OneapiDevice::global_alloc(device_memory &mem)
|
||||
|
@ -367,10 +360,9 @@ void OneapiDevice::global_alloc(device_memory &mem)
|
|||
generic_alloc(mem);
|
||||
generic_copy_to(mem);
|
||||
|
||||
oneapi_dll_.oneapi_set_global_memory(
|
||||
device_queue_, kg_memory_, mem.name, (void *)mem.device_pointer);
|
||||
set_global_memory(device_queue_, kg_memory_, mem.name, (void *)mem.device_pointer);
|
||||
|
||||
oneapi_dll_.oneapi_usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
|
||||
usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
|
||||
}
|
||||
|
||||
void OneapiDevice::global_free(device_memory &mem)
|
||||
|
@ -410,18 +402,6 @@ unique_ptr<DeviceQueue> OneapiDevice::gpu_queue_create()
|
|||
return make_unique<OneapiDeviceQueue>(this);
|
||||
}
|
||||
|
||||
int OneapiDevice::get_num_multiprocessors()
|
||||
{
|
||||
assert(device_queue_);
|
||||
return oneapi_dll_.oneapi_get_num_multiprocessors(device_queue_);
|
||||
}
|
||||
|
||||
int OneapiDevice::get_max_num_threads_per_multiprocessor()
|
||||
{
|
||||
assert(device_queue_);
|
||||
return oneapi_dll_.oneapi_get_max_num_threads_per_multiprocessor(device_queue_);
|
||||
}
|
||||
|
||||
bool OneapiDevice::should_use_graphics_interop()
|
||||
{
|
||||
/* NOTE(@nsirgien): oneAPI doesn't yet support direct writing into graphics API objects, so
|
||||
|
@ -432,13 +412,460 @@ bool OneapiDevice::should_use_graphics_interop()
|
|||
void *OneapiDevice::usm_aligned_alloc_host(size_t memory_size, size_t alignment)
|
||||
{
|
||||
assert(device_queue_);
|
||||
return oneapi_dll_.oneapi_usm_aligned_alloc_host(device_queue_, memory_size, alignment);
|
||||
return usm_aligned_alloc_host(device_queue_, memory_size, alignment);
|
||||
}
|
||||
|
||||
void OneapiDevice::usm_free(void *usm_ptr)
|
||||
{
|
||||
assert(device_queue_);
|
||||
return oneapi_dll_.oneapi_usm_free(device_queue_, usm_ptr);
|
||||
return usm_free(device_queue_, usm_ptr);
|
||||
}
|
||||
|
||||
void OneapiDevice::check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_host = false)
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
sycl::info::device_type device_type =
|
||||
queue->get_device().get_info<sycl::info::device::device_type>();
|
||||
sycl::usm::alloc usm_type = get_pointer_type(usm_ptr, queue->get_context());
|
||||
(void)usm_type;
|
||||
assert(usm_type == sycl::usm::alloc::device ||
|
||||
((device_type == sycl::info::device_type::host ||
|
||||
device_type == sycl::info::device_type::cpu || allow_host) &&
|
||||
usm_type == sycl::usm::alloc::host));
|
||||
# endif
|
||||
}
|
||||
|
||||
bool OneapiDevice::create_queue(SyclQueue *&external_queue, int device_index)
|
||||
{
|
||||
bool finished_correct = true;
|
||||
try {
|
||||
std::vector<sycl::device> devices = OneapiDevice::available_devices();
|
||||
if (device_index < 0 || device_index >= devices.size()) {
|
||||
return false;
|
||||
}
|
||||
sycl::queue *created_queue = new sycl::queue(devices[device_index],
|
||||
sycl::property::queue::in_order());
|
||||
external_queue = reinterpret_cast<SyclQueue *>(created_queue);
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
finished_correct = false;
|
||||
oneapi_error_string_ = e.what();
|
||||
}
|
||||
return finished_correct;
|
||||
}
|
||||
|
||||
void OneapiDevice::free_queue(SyclQueue *queue_)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
delete queue;
|
||||
}
|
||||
|
||||
void *OneapiDevice::usm_aligned_alloc_host(SyclQueue *queue_, size_t memory_size, size_t alignment)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
return sycl::aligned_alloc_host(alignment, memory_size, *queue);
|
||||
}
|
||||
|
||||
void *OneapiDevice::usm_alloc_device(SyclQueue *queue_, size_t memory_size)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
return sycl::malloc_device(memory_size, *queue);
|
||||
}
|
||||
|
||||
void OneapiDevice::usm_free(SyclQueue *queue_, void *usm_ptr)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
OneapiDevice::check_usm(queue_, usm_ptr, true);
|
||||
sycl::free(usm_ptr, *queue);
|
||||
}
|
||||
|
||||
bool OneapiDevice::usm_memcpy(SyclQueue *queue_, void *dest, void *src, size_t num_bytes)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
OneapiDevice::check_usm(queue_, dest, true);
|
||||
OneapiDevice::check_usm(queue_, src, true);
|
||||
sycl::event mem_event = queue->memcpy(dest, src, num_bytes);
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
try {
|
||||
/* NOTE(@nsirgien) Waiting on memory operation may give more precise error
|
||||
* messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
|
||||
*/
|
||||
mem_event.wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
oneapi_error_string_ = e.what();
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
sycl::usm::alloc dest_type = get_pointer_type(dest, queue->get_context());
|
||||
sycl::usm::alloc src_type = get_pointer_type(src, queue->get_context());
|
||||
bool from_device_to_host = dest_type == sycl::usm::alloc::host &&
|
||||
src_type == sycl::usm::alloc::device;
|
||||
bool host_or_device_memop_with_offset = dest_type == sycl::usm::alloc::unknown ||
|
||||
src_type == sycl::usm::alloc::unknown;
|
||||
/* NOTE(@sirgienko) Host-side blocking wait on this operation is mandatory, otherwise the host
|
||||
* may not wait until the end of the transfer before using the memory.
|
||||
*/
|
||||
if (from_device_to_host || host_or_device_memop_with_offset)
|
||||
mem_event.wait();
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
|
||||
bool OneapiDevice::usm_memset(SyclQueue *queue_,
|
||||
void *usm_ptr,
|
||||
unsigned char value,
|
||||
size_t num_bytes)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
OneapiDevice::check_usm(queue_, usm_ptr, true);
|
||||
sycl::event mem_event = queue->memset(usm_ptr, value, num_bytes);
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
try {
|
||||
/* NOTE(@nsirgien) Waiting on memory operation may give more precise error
|
||||
* messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
|
||||
*/
|
||||
mem_event.wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
oneapi_error_string_ = e.what();
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
(void)mem_event;
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
|
||||
bool OneapiDevice::queue_synchronize(SyclQueue *queue_)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
try {
|
||||
queue->wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
oneapi_error_string_ = e.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool OneapiDevice::kernel_globals_size(SyclQueue *queue_, size_t &kernel_global_size)
|
||||
{
|
||||
kernel_global_size = sizeof(KernelGlobalsGPU);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OneapiDevice::set_global_memory(SyclQueue *queue_,
|
||||
void *kernel_globals,
|
||||
const char *memory_name,
|
||||
void *memory_device_pointer)
|
||||
{
|
||||
assert(queue_);
|
||||
assert(kernel_globals);
|
||||
assert(memory_name);
|
||||
assert(memory_device_pointer);
|
||||
KernelGlobalsGPU *globals = (KernelGlobalsGPU *)kernel_globals;
|
||||
OneapiDevice::check_usm(queue_, memory_device_pointer);
|
||||
OneapiDevice::check_usm(queue_, kernel_globals, true);
|
||||
|
||||
std::string matched_name(memory_name);
|
||||
|
||||
/* This macro will change global ptr of KernelGlobals via name matching. */
|
||||
# define KERNEL_DATA_ARRAY(type, name) \
|
||||
else if (#name == matched_name) \
|
||||
{ \
|
||||
globals->__##name = (type *)memory_device_pointer; \
|
||||
return; \
|
||||
}
|
||||
if (false) {
|
||||
}
|
||||
else if ("integrator_state" == matched_name) {
|
||||
globals->integrator_state = (IntegratorStateGPU *)memory_device_pointer;
|
||||
return;
|
||||
}
|
||||
KERNEL_DATA_ARRAY(KernelData, data)
|
||||
# include "kernel/data_arrays.h"
|
||||
else
|
||||
{
|
||||
std::cerr << "Can't found global/constant memory with name \"" << matched_name << "\"!"
|
||||
<< std::endl;
|
||||
assert(false);
|
||||
}
|
||||
# undef KERNEL_DATA_ARRAY
|
||||
}
|
||||
|
||||
bool OneapiDevice::enqueue_kernel(KernelContext *kernel_context,
|
||||
int kernel,
|
||||
size_t global_size,
|
||||
void **args)
|
||||
{
|
||||
return oneapi_enqueue_kernel(kernel_context, kernel, global_size, args);
|
||||
}
|
||||
|
||||
/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
|
||||
* since Windows driver 101.3268. */
|
||||
/* The same min compute-runtime version is currently required across Windows and Linux.
|
||||
* For Windows driver 101.3430, compute-runtime version is 23904. */
|
||||
static const int lowest_supported_driver_version_win = 1013430;
|
||||
static const int lowest_supported_driver_version_neo = 23904;
|
||||
|
||||
int OneapiDevice::parse_driver_build_version(const sycl::device &device)
|
||||
{
|
||||
const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
|
||||
int driver_build_version = 0;
|
||||
|
||||
size_t second_dot_position = driver_version.find('.', driver_version.find('.') + 1);
|
||||
if (second_dot_position == std::string::npos) {
|
||||
std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
|
||||
<< "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
|
||||
<< " xx.xx.xxx.xxxx (Windows) for device \""
|
||||
<< device.get_info<sycl::info::device::name>() << "\"." << std::endl;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
size_t third_dot_position = driver_version.find('.', second_dot_position + 1);
|
||||
if (third_dot_position != std::string::npos) {
|
||||
const std::string &third_number_substr = driver_version.substr(
|
||||
second_dot_position + 1, third_dot_position - second_dot_position - 1);
|
||||
const std::string &forth_number_substr = driver_version.substr(third_dot_position + 1);
|
||||
if (third_number_substr.length() == 3 && forth_number_substr.length() == 4)
|
||||
driver_build_version = std::stoi(third_number_substr) * 10000 +
|
||||
std::stoi(forth_number_substr);
|
||||
}
|
||||
else {
|
||||
const std::string &third_number_substr = driver_version.substr(second_dot_position + 1);
|
||||
driver_build_version = std::stoi(third_number_substr);
|
||||
}
|
||||
}
|
||||
catch (std::invalid_argument &) {
|
||||
std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
|
||||
<< "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
|
||||
<< " xx.xx.xxx.xxxx (Windows) for device \""
|
||||
<< device.get_info<sycl::info::device::name>() << "\"." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return driver_build_version;
|
||||
}
|
||||
|
||||
std::vector<sycl::device> OneapiDevice::available_devices()
|
||||
{
|
||||
bool allow_all_devices = false;
|
||||
if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr)
|
||||
allow_all_devices = true;
|
||||
|
||||
/* Host device is useful only for debugging at the moment
|
||||
* so we hide this device with default build settings. */
|
||||
# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
|
||||
bool allow_host = true;
|
||||
# else
|
||||
bool allow_host = false;
|
||||
# endif
|
||||
|
||||
const std::vector<sycl::platform> &oneapi_platforms = sycl::platform::get_platforms();
|
||||
|
||||
std::vector<sycl::device> available_devices;
|
||||
for (const sycl::platform &platform : oneapi_platforms) {
|
||||
/* ignore OpenCL platforms to avoid using the same devices through both Level-Zero and OpenCL.
|
||||
*/
|
||||
if (platform.get_backend() == sycl::backend::opencl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<sycl::device> &oneapi_devices =
|
||||
(allow_all_devices || allow_host) ? platform.get_devices(sycl::info::device_type::all) :
|
||||
platform.get_devices(sycl::info::device_type::gpu);
|
||||
|
||||
for (const sycl::device &device : oneapi_devices) {
|
||||
if (allow_all_devices) {
|
||||
/* still filter out host device if build doesn't support it. */
|
||||
if (allow_host || !device.is_host()) {
|
||||
available_devices.push_back(device);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool filter_out = false;
|
||||
|
||||
/* For now we support all Intel(R) Arc(TM) devices and likely any future GPU,
|
||||
* assuming they have either more than 96 Execution Units or not 7 threads per EU.
|
||||
* Official support can be broaden to older and smaller GPUs once ready. */
|
||||
if (device.is_gpu() && platform.get_backend() == sycl::backend::ext_oneapi_level_zero) {
|
||||
/* Filtered-out defaults in-case these values aren't available through too old L0
|
||||
* runtime. */
|
||||
int number_of_eus = 96;
|
||||
int threads_per_eu = 7;
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
|
||||
number_of_eus = device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
|
||||
}
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
|
||||
threads_per_eu =
|
||||
device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
|
||||
}
|
||||
/* This filters out all Level-Zero supported GPUs from older generation than Arc. */
|
||||
if (number_of_eus <= 96 && threads_per_eu == 7) {
|
||||
filter_out = true;
|
||||
}
|
||||
/* if not already filtered out, check driver version. */
|
||||
if (!filter_out) {
|
||||
int driver_build_version = parse_driver_build_version(device);
|
||||
if ((driver_build_version > 100000 &&
|
||||
driver_build_version < lowest_supported_driver_version_win) ||
|
||||
driver_build_version < lowest_supported_driver_version_neo) {
|
||||
filter_out = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!allow_host && device.is_host()) {
|
||||
filter_out = true;
|
||||
}
|
||||
else if (!allow_all_devices) {
|
||||
filter_out = true;
|
||||
}
|
||||
|
||||
if (!filter_out) {
|
||||
available_devices.push_back(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return available_devices;
|
||||
}
|
||||
|
||||
char *OneapiDevice::device_capabilities()
|
||||
{
|
||||
std::stringstream capabilities;
|
||||
|
||||
const std::vector<sycl::device> &oneapi_devices = available_devices();
|
||||
for (const sycl::device &device : oneapi_devices) {
|
||||
const std::string &name = device.get_info<sycl::info::device::name>();
|
||||
|
||||
capabilities << std::string("\t") << name << "\n";
|
||||
# define WRITE_ATTR(attribute_name, attribute_variable) \
|
||||
capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \
|
||||
<< "\n";
|
||||
# define GET_NUM_ATTR(attribute) \
|
||||
{ \
|
||||
size_t attribute = (size_t)device.get_info<sycl::info::device ::attribute>(); \
|
||||
capabilities << "\t\tsycl::info::device::" #attribute "\t\t\t" << attribute << "\n"; \
|
||||
}
|
||||
|
||||
GET_NUM_ATTR(vendor_id)
|
||||
GET_NUM_ATTR(max_compute_units)
|
||||
GET_NUM_ATTR(max_work_item_dimensions)
|
||||
|
||||
sycl::id<3> max_work_item_sizes =
|
||||
device.get_info<sycl::info::device::max_work_item_sizes<3>>();
|
||||
WRITE_ATTR("max_work_item_sizes_dim0", ((size_t)max_work_item_sizes.get(0)))
|
||||
WRITE_ATTR("max_work_item_sizes_dim1", ((size_t)max_work_item_sizes.get(1)))
|
||||
WRITE_ATTR("max_work_item_sizes_dim2", ((size_t)max_work_item_sizes.get(2)))
|
||||
|
||||
GET_NUM_ATTR(max_work_group_size)
|
||||
GET_NUM_ATTR(max_num_sub_groups)
|
||||
GET_NUM_ATTR(sub_group_independent_forward_progress)
|
||||
|
||||
GET_NUM_ATTR(preferred_vector_width_char)
|
||||
GET_NUM_ATTR(preferred_vector_width_short)
|
||||
GET_NUM_ATTR(preferred_vector_width_int)
|
||||
GET_NUM_ATTR(preferred_vector_width_long)
|
||||
GET_NUM_ATTR(preferred_vector_width_float)
|
||||
GET_NUM_ATTR(preferred_vector_width_double)
|
||||
GET_NUM_ATTR(preferred_vector_width_half)
|
||||
|
||||
GET_NUM_ATTR(native_vector_width_char)
|
||||
GET_NUM_ATTR(native_vector_width_short)
|
||||
GET_NUM_ATTR(native_vector_width_int)
|
||||
GET_NUM_ATTR(native_vector_width_long)
|
||||
GET_NUM_ATTR(native_vector_width_float)
|
||||
GET_NUM_ATTR(native_vector_width_double)
|
||||
GET_NUM_ATTR(native_vector_width_half)
|
||||
|
||||
size_t max_clock_frequency =
|
||||
(size_t)(device.is_host() ? (size_t)0 :
|
||||
device.get_info<sycl::info::device::max_clock_frequency>());
|
||||
WRITE_ATTR("max_clock_frequency", max_clock_frequency)
|
||||
|
||||
GET_NUM_ATTR(address_bits)
|
||||
GET_NUM_ATTR(max_mem_alloc_size)
|
||||
|
||||
/* NOTE(@nsirgien): Implementation doesn't use image support as bindless images aren't
|
||||
* supported so we always return false, even if device supports HW texture usage acceleration.
|
||||
*/
|
||||
bool image_support = false;
|
||||
WRITE_ATTR("image_support", (size_t)image_support)
|
||||
|
||||
GET_NUM_ATTR(max_parameter_size)
|
||||
GET_NUM_ATTR(mem_base_addr_align)
|
||||
GET_NUM_ATTR(global_mem_size)
|
||||
GET_NUM_ATTR(local_mem_size)
|
||||
GET_NUM_ATTR(error_correction_support)
|
||||
GET_NUM_ATTR(profiling_timer_resolution)
|
||||
GET_NUM_ATTR(is_available)
|
||||
|
||||
# undef GET_NUM_ATTR
|
||||
# undef WRITE_ATTR
|
||||
capabilities << "\n";
|
||||
}
|
||||
|
||||
return ::strdup(capabilities.str().c_str());
|
||||
}
|
||||
|
||||
void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr)
|
||||
{
|
||||
int num = 0;
|
||||
std::vector<sycl::device> devices = OneapiDevice::available_devices();
|
||||
for (sycl::device &device : devices) {
|
||||
const std::string &platform_name =
|
||||
device.get_platform().get_info<sycl::info::platform::name>();
|
||||
std::string name = device.get_info<sycl::info::device::name>();
|
||||
std::string id = "ONEAPI_" + platform_name + "_" + name;
|
||||
if (device.has(sycl::aspect::ext_intel_pci_address)) {
|
||||
id.append("_" + device.get_info<sycl::info::device::ext_intel_pci_address>());
|
||||
}
|
||||
(cb)(id.c_str(), name.c_str(), num, user_ptr);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
size_t OneapiDevice::get_memcapacity()
|
||||
{
|
||||
return reinterpret_cast<sycl::queue *>(device_queue_)
|
||||
->get_device()
|
||||
.get_info<sycl::info::device::global_mem_size>();
|
||||
}
|
||||
|
||||
int OneapiDevice::get_num_multiprocessors()
|
||||
{
|
||||
const sycl::device &device = reinterpret_cast<sycl::queue *>(device_queue_)->get_device();
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
|
||||
return device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OneapiDevice::get_max_num_threads_per_multiprocessor()
|
||||
{
|
||||
const sycl::device &device = reinterpret_cast<sycl::queue *>(device_queue_)->get_device();
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
|
||||
device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
|
||||
return device.get_info<sycl::info::device::ext_intel_gpu_eu_simd_width>() *
|
||||
device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
#ifdef WITH_ONEAPI
|
||||
|
||||
# include <CL/sycl.hpp>
|
||||
|
||||
# include "device/device.h"
|
||||
# include "device/oneapi/device.h"
|
||||
# include "device/oneapi/queue.h"
|
||||
# include "kernel/device/oneapi/kernel.h"
|
||||
|
||||
# include "util/map.h"
|
||||
|
||||
|
@ -13,6 +16,11 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
class DeviceQueue;
|
||||
|
||||
typedef void (*OneAPIDeviceIteratorCallback)(const char *id,
|
||||
const char *name,
|
||||
int num,
|
||||
void *user_ptr);
|
||||
|
||||
class OneapiDevice : public Device {
|
||||
private:
|
||||
SyclQueue *device_queue_;
|
||||
|
@ -25,16 +33,12 @@ class OneapiDevice : public Device {
|
|||
void *kg_memory_device_;
|
||||
size_t kg_memory_size_ = (size_t)0;
|
||||
size_t max_memory_on_device_ = (size_t)0;
|
||||
OneAPIDLLInterface oneapi_dll_;
|
||||
std::string oneapi_error_string_;
|
||||
|
||||
public:
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const override;
|
||||
|
||||
OneapiDevice(const DeviceInfo &info,
|
||||
OneAPIDLLInterface &oneapi_dll_object,
|
||||
Stats &stats,
|
||||
Profiler &profiler);
|
||||
OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler);
|
||||
|
||||
virtual ~OneapiDevice();
|
||||
|
||||
|
@ -50,12 +54,8 @@ class OneapiDevice : public Device {
|
|||
|
||||
void generic_free(device_memory &mem);
|
||||
|
||||
SyclQueue *sycl_queue();
|
||||
|
||||
string oneapi_error_message();
|
||||
|
||||
OneAPIDLLInterface oneapi_dll_object();
|
||||
|
||||
void *kernel_globals_device_pointer();
|
||||
|
||||
void mem_alloc(device_memory &mem) override;
|
||||
|
@ -90,13 +90,37 @@ class OneapiDevice : public Device {
|
|||
|
||||
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
|
||||
|
||||
int get_num_multiprocessors();
|
||||
int get_max_num_threads_per_multiprocessor();
|
||||
|
||||
/* NOTE(@nsirgien): Create this methods to avoid some compilation problems on Windows with host
|
||||
* side compilation (MSVC). */
|
||||
void *usm_aligned_alloc_host(size_t memory_size, size_t alignment);
|
||||
void usm_free(void *usm_ptr);
|
||||
|
||||
static std::vector<sycl::device> available_devices();
|
||||
static char *device_capabilities();
|
||||
static int parse_driver_build_version(const sycl::device &device);
|
||||
static void iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr);
|
||||
|
||||
size_t get_memcapacity();
|
||||
int get_num_multiprocessors();
|
||||
int get_max_num_threads_per_multiprocessor();
|
||||
bool queue_synchronize(SyclQueue *queue);
|
||||
bool kernel_globals_size(SyclQueue *queue, size_t &kernel_global_size);
|
||||
void set_global_memory(SyclQueue *queue,
|
||||
void *kernel_globals,
|
||||
const char *memory_name,
|
||||
void *memory_device_pointer);
|
||||
bool enqueue_kernel(KernelContext *kernel_context, int kernel, size_t global_size, void **args);
|
||||
SyclQueue *sycl_queue();
|
||||
|
||||
protected:
|
||||
void check_usm(SyclQueue *queue, const void *usm_ptr, bool allow_host);
|
||||
bool create_queue(SyclQueue *&external_queue, int device_index);
|
||||
void free_queue(SyclQueue *queue);
|
||||
void *usm_aligned_alloc_host(SyclQueue *queue, size_t memory_size, size_t alignment);
|
||||
void *usm_alloc_device(SyclQueue *queue, size_t memory_size);
|
||||
void usm_free(SyclQueue *queue, void *usm_ptr);
|
||||
bool usm_memcpy(SyclQueue *queue, void *dest, void *src, size_t num_bytes);
|
||||
bool usm_memset(SyclQueue *queue, void *usm_ptr, unsigned char value, size_t num_bytes);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Include kernel header to get access to SYCL-specific types, like SyclQueue and
|
||||
* OneAPIDeviceIteratorCallback. */
|
||||
#include "kernel/device/oneapi/kernel.h"
|
||||
|
||||
#ifdef WITH_ONEAPI
|
||||
struct OneAPIDLLInterface {
|
||||
# define DLL_INTERFACE_CALL(function, return_type, ...) \
|
||||
return_type (*function)(__VA_ARGS__) = nullptr;
|
||||
# include "kernel/device/oneapi/dll_interface_template.h"
|
||||
# undef DLL_INTERFACE_CALL
|
||||
};
|
||||
#endif
|
|
@ -22,10 +22,7 @@ struct KernelExecutionInfo {
|
|||
/* OneapiDeviceQueue */
|
||||
|
||||
OneapiDeviceQueue::OneapiDeviceQueue(OneapiDevice *device)
|
||||
: DeviceQueue(device),
|
||||
oneapi_device_(device),
|
||||
oneapi_dll_(device->oneapi_dll_object()),
|
||||
kernel_context_(nullptr)
|
||||
: DeviceQueue(device), oneapi_device_(device), kernel_context_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -81,14 +78,14 @@ bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
|
|||
assert(signed_kernel_work_size >= 0);
|
||||
size_t kernel_work_size = (size_t)signed_kernel_work_size;
|
||||
|
||||
size_t kernel_local_size = oneapi_dll_.oneapi_kernel_preferred_local_size(
|
||||
size_t kernel_local_size = oneapi_kernel_preferred_local_size(
|
||||
kernel_context_->queue, (::DeviceKernel)kernel, kernel_work_size);
|
||||
size_t uniformed_kernel_work_size = round_up(kernel_work_size, kernel_local_size);
|
||||
|
||||
assert(kernel_context_);
|
||||
|
||||
/* Call the oneAPI kernel DLL to launch the requested kernel. */
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_enqueue_kernel(
|
||||
bool is_finished_ok = oneapi_device_->enqueue_kernel(
|
||||
kernel_context_, kernel, uniformed_kernel_work_size, args);
|
||||
|
||||
if (is_finished_ok == false) {
|
||||
|
@ -108,7 +105,7 @@ bool OneapiDeviceQueue::synchronize()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_queue_synchronize(oneapi_device_->sycl_queue());
|
||||
bool is_finished_ok = oneapi_device_->queue_synchronize(oneapi_device_->sycl_queue());
|
||||
if (is_finished_ok == false)
|
||||
oneapi_device_->set_error("oneAPI unknown kernel execution error: got runtime exception \"" +
|
||||
oneapi_device_->oneapi_error_message() + "\"");
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# include "device/queue.h"
|
||||
|
||||
# include "device/oneapi/device.h"
|
||||
# include "device/oneapi/dll_interface.h"
|
||||
# include "kernel/device/oneapi/kernel.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -41,9 +41,7 @@ class OneapiDeviceQueue : public DeviceQueue {
|
|||
|
||||
protected:
|
||||
OneapiDevice *oneapi_device_;
|
||||
OneAPIDLLInterface oneapi_dll_;
|
||||
KernelContext *kernel_context_;
|
||||
bool with_kernel_statistics_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -43,8 +43,11 @@ PathTrace::PathTrace(Device *device,
|
|||
/* Create path tracing work in advance, so that it can be reused by incremental sampling as much
|
||||
* as possible. */
|
||||
device_->foreach_device([&](Device *path_trace_device) {
|
||||
path_trace_works_.emplace_back(PathTraceWork::create(
|
||||
path_trace_device, film, device_scene, &render_cancel_.is_requested));
|
||||
unique_ptr<PathTraceWork> work = PathTraceWork::create(
|
||||
path_trace_device, film, device_scene, &render_cancel_.is_requested);
|
||||
if (work) {
|
||||
path_trace_works_.emplace_back(std::move(work));
|
||||
}
|
||||
});
|
||||
|
||||
work_balance_infos_.resize(path_trace_works_.size());
|
||||
|
|
|
@ -23,6 +23,10 @@ unique_ptr<PathTraceWork> PathTraceWork::create(Device *device,
|
|||
if (device->info.type == DEVICE_CPU) {
|
||||
return make_unique<PathTraceWorkCPU>(device, film, device_scene, cancel_requested_flag);
|
||||
}
|
||||
if (device->info.type == DEVICE_DUMMY) {
|
||||
/* Dummy devices can't perform any work. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return make_unique<PathTraceWorkGPU>(device, film, device_scene, cancel_requested_flag);
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ void PathTraceWorkCPU::cryptomatte_postproces()
|
|||
}
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
/* Note: It seems that this is called before every rendering iteration/progression and not once per
|
||||
/* NOTE: It seems that this is called before every rendering iteration/progression and not once per
|
||||
* rendering. May be we find a way to call it only once per rendering. */
|
||||
void PathTraceWorkCPU::guiding_init_kernel_globals(void *guiding_field,
|
||||
void *sample_data_storage,
|
||||
|
|
|
@ -17,6 +17,9 @@ void work_balance_do_initial(vector<WorkBalanceInfo> &work_balance_infos)
|
|||
work_balance_infos[0].weight = 1.0;
|
||||
return;
|
||||
}
|
||||
else if (num_infos == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* There is no statistics available, so start with an equal distribution. */
|
||||
const double weight = 1.0 / num_infos;
|
||||
|
|
|
@ -718,7 +718,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
if(WIN32)
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.dll)
|
||||
else()
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.so)
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/libcycles_kernel_oneapi.so)
|
||||
endif()
|
||||
|
||||
set(cycles_oneapi_kernel_sources
|
||||
|
@ -760,7 +760,6 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
${SYCL_CPP_FLAGS}
|
||||
)
|
||||
|
||||
|
||||
if (WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
|
||||
list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_ENABLED)
|
||||
endif()
|
||||
|
@ -817,6 +816,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
|
||||
if(WIN32)
|
||||
list(APPEND sycl_compiler_flags
|
||||
-fuse-ld=link
|
||||
-fms-extensions
|
||||
-fms-compatibility
|
||||
-D_WINDLL
|
||||
|
@ -827,36 +827,43 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
-D_CRT_SECURE_NO_DEPRECATE
|
||||
-DONEAPI_EXPORT)
|
||||
|
||||
if(sycl_compiler_compiler_name MATCHES "dpcpp")
|
||||
# The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND "${sycl_compiler_root}/../../env/vars.bat"
|
||||
COMMAND ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
|
||||
if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
|
||||
get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
|
||||
string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
|
||||
get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
|
||||
else()
|
||||
# The open source SYCL compiler just goes by clang++ and does not have such a script.
|
||||
# Set the variables manually.
|
||||
string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
|
||||
if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
|
||||
get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
|
||||
string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
|
||||
get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
|
||||
else()
|
||||
set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
|
||||
endif()
|
||||
list(APPEND sycl_compiler_flags
|
||||
-L "${MSVC_TOOLS_DIR}/lib/x64"
|
||||
-L "${WINDOWS_KIT_DIR}/um/x64"
|
||||
-L "${WINDOWS_KIT_DIR}/ucrt/x64")
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
|
||||
"PATH=${OCLOC_INSTALL_DIR};${sycl_compiler_root}"
|
||||
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
|
||||
endif()
|
||||
list(APPEND sycl_compiler_flags
|
||||
-L "${MSVC_TOOLS_DIR}/lib/x64"
|
||||
-L "${WINDOWS_KIT_DIR}/um/x64"
|
||||
-L "${WINDOWS_KIT_DIR}/ucrt/x64")
|
||||
|
||||
set(sycl_compiler_flags_Release ${sycl_compiler_flags})
|
||||
set(sycl_compiler_flags_Debug ${sycl_compiler_flags})
|
||||
set(sycl_compiler_flags_RelWithDebInfo ${sycl_compiler_flags})
|
||||
set(sycl_compiler_flags_MinSizeRel ${sycl_compiler_flags})
|
||||
list(APPEND sycl_compiler_flags_RelWithDebInfo -g)
|
||||
get_filename_component(sycl_library_debug_name ${SYCL_LIBRARY_DEBUG} NAME_WE)
|
||||
list(APPEND sycl_compiler_flags_Debug
|
||||
-g
|
||||
-D_DEBUG
|
||||
-nostdlib -Xclang --dependent-lib=msvcrtd
|
||||
-Xclang --dependent-lib=${sycl_library_debug_name})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
|
||||
"PATH=${OCLOC_INSTALL_DIR}\;${sycl_compiler_root}"
|
||||
${SYCL_COMPILER}
|
||||
"$<$<CONFIG:Release>:${sycl_compiler_flags_Release}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${sycl_compiler_flags_RelWithDebInfo}>"
|
||||
"$<$<CONFIG:Debug>:${sycl_compiler_flags_Debug}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${sycl_compiler_flags_Release}>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
else()
|
||||
list(APPEND sycl_compiler_flags -fPIC)
|
||||
|
||||
|
@ -868,55 +875,36 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
# libpi_level_zero.so can be placed next to it and get found.
|
||||
list(APPEND sycl_compiler_flags -Wl,-rpath,'$$ORIGIN')
|
||||
|
||||
# The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
|
||||
if(sycl_compiler_compiler_name MATCHES "dpcpp")
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND bash -c \"source ${sycl_compiler_root}/../../env/vars.sh&&${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}\"
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
else()
|
||||
# The open source SYCL compiler just goes by clang++ and does not have such a script.
|
||||
# Set the variables manually.
|
||||
if(NOT IGC_INSTALL_DIR)
|
||||
get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
|
||||
"PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
|
||||
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
if(NOT IGC_INSTALL_DIR)
|
||||
get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${cycles_kernel_oneapi_lib}
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
|
||||
"PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
|
||||
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
endif()
|
||||
|
||||
if(NOT WITH_BLENDER)
|
||||
# For the Cycles standalone put libraries next to the Cycles application.
|
||||
set(cycles_oneapi_target_path ${CYCLES_INSTALL_PATH})
|
||||
else()
|
||||
# For Blender put the libraries next to the Blender executable.
|
||||
#
|
||||
# Note that the installation path in the delayed_install is relative to the versioned folder,
|
||||
# which means we need to go one level up.
|
||||
set(cycles_oneapi_target_path "../")
|
||||
endif()
|
||||
|
||||
# install dynamic libraries required at runtime
|
||||
if(WIN32)
|
||||
set(SYCL_RUNTIME_DEPENDENCIES
|
||||
sycl.dll
|
||||
pi_level_zero.dll
|
||||
)
|
||||
if(NOT WITH_BLENDER)
|
||||
# For the Cycles standalone put libraries next to the Cycles application.
|
||||
delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH})
|
||||
else()
|
||||
# For Blender put the libraries next to the Blender executable.
|
||||
#
|
||||
# Note that the installation path in the delayed_install is relative to the versioned folder,
|
||||
# which means we need to go one level up.
|
||||
delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" "../")
|
||||
endif()
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path})
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
file(GLOB SYCL_RUNTIME_DEPENDENCIES
|
||||
${sycl_compiler_root}/../lib/libsycl.so
|
||||
${sycl_compiler_root}/../lib/libsycl.so.[0-9]
|
||||
${sycl_compiler_root}/../lib/libsycl.so.[0-9].[0-9].[0-9]-[0-9]
|
||||
)
|
||||
list(APPEND SYCL_RUNTIME_DEPENDENCIES ${sycl_compiler_root}/../lib/libpi_level_zero.so)
|
||||
delayed_install("" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path}/lib)
|
||||
endif()
|
||||
|
||||
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cycles_kernel_oneapi_lib}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
add_custom_target(cycles_kernel_oneapi ALL DEPENDS ${cycles_kernel_oneapi_lib})
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2022 Intel Corporation */
|
||||
|
||||
/* device_capabilities() returns a C string that must be free'd with oneapi_free(). */
|
||||
DLL_INTERFACE_CALL(oneapi_device_capabilities, char *)
|
||||
DLL_INTERFACE_CALL(oneapi_free, void, void *)
|
||||
DLL_INTERFACE_CALL(oneapi_get_memcapacity, size_t, SyclQueue *queue)
|
||||
|
||||
DLL_INTERFACE_CALL(oneapi_get_num_multiprocessors, int, SyclQueue *queue)
|
||||
DLL_INTERFACE_CALL(oneapi_get_max_num_threads_per_multiprocessor, int, SyclQueue *queue)
|
||||
DLL_INTERFACE_CALL(oneapi_iterate_devices, void, OneAPIDeviceIteratorCallback cb, void *user_ptr)
|
||||
DLL_INTERFACE_CALL(oneapi_set_error_cb, void, OneAPIErrorCallback, void *user_ptr)
|
||||
|
||||
DLL_INTERFACE_CALL(oneapi_create_queue, bool, SyclQueue *&external_queue, int device_index)
|
||||
DLL_INTERFACE_CALL(oneapi_free_queue, void, SyclQueue *queue)
|
||||
DLL_INTERFACE_CALL(
|
||||
oneapi_usm_aligned_alloc_host, void *, SyclQueue *queue, size_t memory_size, size_t alignment)
|
||||
DLL_INTERFACE_CALL(oneapi_usm_alloc_device, void *, SyclQueue *queue, size_t memory_size)
|
||||
DLL_INTERFACE_CALL(oneapi_usm_free, void, SyclQueue *queue, void *usm_ptr)
|
||||
|
||||
DLL_INTERFACE_CALL(
|
||||
oneapi_usm_memcpy, bool, SyclQueue *queue, void *dest, void *src, size_t num_bytes)
|
||||
DLL_INTERFACE_CALL(oneapi_queue_synchronize, bool, SyclQueue *queue)
|
||||
DLL_INTERFACE_CALL(oneapi_usm_memset,
|
||||
bool,
|
||||
SyclQueue *queue,
|
||||
void *usm_ptr,
|
||||
unsigned char value,
|
||||
size_t num_bytes)
|
||||
|
||||
DLL_INTERFACE_CALL(oneapi_run_test_kernel, bool, SyclQueue *queue)
|
||||
|
||||
/* Operation with Kernel globals structure - map of global/constant allocation - filled before
|
||||
* render/kernel execution As we don't know in cycles `sizeof` this - Cycles will manage just as
|
||||
* pointer. */
|
||||
DLL_INTERFACE_CALL(oneapi_kernel_globals_size, bool, SyclQueue *queue, size_t &kernel_global_size)
|
||||
DLL_INTERFACE_CALL(oneapi_set_global_memory,
|
||||
void,
|
||||
SyclQueue *queue,
|
||||
void *kernel_globals,
|
||||
const char *memory_name,
|
||||
void *memory_device_pointer)
|
||||
|
||||
DLL_INTERFACE_CALL(oneapi_kernel_preferred_local_size,
|
||||
size_t,
|
||||
SyclQueue *queue,
|
||||
const DeviceKernel kernel,
|
||||
const size_t kernel_global_size)
|
||||
DLL_INTERFACE_CALL(oneapi_enqueue_kernel,
|
||||
bool,
|
||||
KernelContext *context,
|
||||
int kernel,
|
||||
size_t global_size,
|
||||
void **args)
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#ifdef WITH_ONEAPI
|
||||
|
||||
/* clang-format off */
|
||||
# include "kernel.h"
|
||||
# include <iostream>
|
||||
# include <map>
|
||||
|
@ -16,163 +15,16 @@
|
|||
# include "kernel/device/oneapi/kernel_templates.h"
|
||||
|
||||
# include "kernel/device/gpu/kernel.h"
|
||||
/* clang-format on */
|
||||
|
||||
static OneAPIErrorCallback s_error_cb = nullptr;
|
||||
static void *s_error_user_ptr = nullptr;
|
||||
|
||||
static std::vector<sycl::device> oneapi_available_devices();
|
||||
|
||||
void oneapi_set_error_cb(OneAPIErrorCallback cb, void *user_ptr)
|
||||
{
|
||||
s_error_cb = cb;
|
||||
s_error_user_ptr = user_ptr;
|
||||
}
|
||||
|
||||
void oneapi_check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_host = false)
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
sycl::info::device_type device_type =
|
||||
queue->get_device().get_info<sycl::info::device::device_type>();
|
||||
sycl::usm::alloc usm_type = get_pointer_type(usm_ptr, queue->get_context());
|
||||
(void)usm_type;
|
||||
assert(usm_type == sycl::usm::alloc::device ||
|
||||
((device_type == sycl::info::device_type::host ||
|
||||
device_type == sycl::info::device_type::is_cpu || allow_host) &&
|
||||
usm_type == sycl::usm::alloc::host));
|
||||
# endif
|
||||
}
|
||||
|
||||
bool oneapi_create_queue(SyclQueue *&external_queue, int device_index)
|
||||
{
|
||||
bool finished_correct = true;
|
||||
try {
|
||||
std::vector<sycl::device> devices = oneapi_available_devices();
|
||||
if (device_index < 0 || device_index >= devices.size()) {
|
||||
return false;
|
||||
}
|
||||
sycl::queue *created_queue = new sycl::queue(devices[device_index],
|
||||
sycl::property::queue::in_order());
|
||||
external_queue = reinterpret_cast<SyclQueue *>(created_queue);
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
finished_correct = false;
|
||||
if (s_error_cb) {
|
||||
s_error_cb(e.what(), s_error_user_ptr);
|
||||
}
|
||||
}
|
||||
return finished_correct;
|
||||
}
|
||||
|
||||
void oneapi_free_queue(SyclQueue *queue_)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
delete queue;
|
||||
}
|
||||
|
||||
void *oneapi_usm_aligned_alloc_host(SyclQueue *queue_, size_t memory_size, size_t alignment)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
return sycl::aligned_alloc_host(alignment, memory_size, *queue);
|
||||
}
|
||||
|
||||
void *oneapi_usm_alloc_device(SyclQueue *queue_, size_t memory_size)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
return sycl::malloc_device(memory_size, *queue);
|
||||
}
|
||||
|
||||
void oneapi_usm_free(SyclQueue *queue_, void *usm_ptr)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
oneapi_check_usm(queue_, usm_ptr, true);
|
||||
sycl::free(usm_ptr, *queue);
|
||||
}
|
||||
|
||||
bool oneapi_usm_memcpy(SyclQueue *queue_, void *dest, void *src, size_t num_bytes)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
oneapi_check_usm(queue_, dest, true);
|
||||
oneapi_check_usm(queue_, src, true);
|
||||
sycl::event mem_event = queue->memcpy(dest, src, num_bytes);
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
try {
|
||||
/* NOTE(@nsirgien) Waiting on memory operation may give more precise error
|
||||
* messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
|
||||
*/
|
||||
mem_event.wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
if (s_error_cb) {
|
||||
s_error_cb(e.what(), s_error_user_ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
sycl::usm::alloc dest_type = get_pointer_type(dest, queue->get_context());
|
||||
sycl::usm::alloc src_type = get_pointer_type(src, queue->get_context());
|
||||
bool from_device_to_host = dest_type == sycl::usm::alloc::host &&
|
||||
src_type == sycl::usm::alloc::device;
|
||||
bool host_or_device_memop_with_offset = dest_type == sycl::usm::alloc::unknown ||
|
||||
src_type == sycl::usm::alloc::unknown;
|
||||
/* NOTE(@sirgienko) Host-side blocking wait on this operation is mandatory, otherwise the host
|
||||
* may not wait until the end of the transfer before using the memory.
|
||||
*/
|
||||
if (from_device_to_host || host_or_device_memop_with_offset)
|
||||
mem_event.wait();
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
|
||||
bool oneapi_usm_memset(SyclQueue *queue_, void *usm_ptr, unsigned char value, size_t num_bytes)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
oneapi_check_usm(queue_, usm_ptr, true);
|
||||
sycl::event mem_event = queue->memset(usm_ptr, value, num_bytes);
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
try {
|
||||
/* NOTE(@nsirgien) Waiting on memory operation may give more precise error
|
||||
* messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
|
||||
*/
|
||||
mem_event.wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
if (s_error_cb) {
|
||||
s_error_cb(e.what(), s_error_user_ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
(void)mem_event;
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
|
||||
bool oneapi_queue_synchronize(SyclQueue *queue_)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
try {
|
||||
queue->wait_and_throw();
|
||||
return true;
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
if (s_error_cb) {
|
||||
s_error_cb(e.what(), s_error_user_ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE(@nsirgien): Execution of this simple kernel will check basic functionality and
|
||||
* also trigger runtime compilation of all existing oneAPI kernels */
|
||||
bool oneapi_run_test_kernel(SyclQueue *queue_)
|
||||
|
@ -216,60 +68,13 @@ bool oneapi_run_test_kernel(SyclQueue *queue_)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool oneapi_kernel_globals_size(SyclQueue *queue_, size_t &kernel_global_size)
|
||||
{
|
||||
kernel_global_size = sizeof(KernelGlobalsGPU);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void oneapi_set_global_memory(SyclQueue *queue_,
|
||||
void *kernel_globals,
|
||||
const char *memory_name,
|
||||
void *memory_device_pointer)
|
||||
{
|
||||
assert(queue_);
|
||||
assert(kernel_globals);
|
||||
assert(memory_name);
|
||||
assert(memory_device_pointer);
|
||||
KernelGlobalsGPU *globals = (KernelGlobalsGPU *)kernel_globals;
|
||||
oneapi_check_usm(queue_, memory_device_pointer);
|
||||
oneapi_check_usm(queue_, kernel_globals, true);
|
||||
|
||||
std::string matched_name(memory_name);
|
||||
|
||||
/* This macro will change global ptr of KernelGlobals via name matching. */
|
||||
# define KERNEL_DATA_ARRAY(type, name) \
|
||||
else if (#name == matched_name) \
|
||||
{ \
|
||||
globals->__##name = (type *)memory_device_pointer; \
|
||||
return; \
|
||||
}
|
||||
if (false) {
|
||||
}
|
||||
else if ("integrator_state" == matched_name) {
|
||||
globals->integrator_state = (IntegratorStateGPU *)memory_device_pointer;
|
||||
return;
|
||||
}
|
||||
KERNEL_DATA_ARRAY(KernelData, data)
|
||||
# include "kernel/data_arrays.h"
|
||||
else
|
||||
{
|
||||
std::cerr << "Can't found global/constant memory with name \"" << matched_name << "\"!"
|
||||
<< std::endl;
|
||||
assert(false);
|
||||
}
|
||||
# undef KERNEL_DATA_ARRAY
|
||||
}
|
||||
|
||||
/* TODO: Move device information to OneapiDevice initialized on creation and use it. */
|
||||
/* TODO: Move below function to oneapi/queue.cpp. */
|
||||
size_t oneapi_kernel_preferred_local_size(SyclQueue *queue_,
|
||||
size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
|
||||
const DeviceKernel kernel,
|
||||
const size_t kernel_global_size)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
assert(queue);
|
||||
(void)kernel_global_size;
|
||||
const static size_t preferred_work_group_size_intersect_shading = 32;
|
||||
const static size_t preferred_work_group_size_technical = 1024;
|
||||
|
@ -311,11 +116,59 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue_,
|
|||
preferred_work_group_size = 512;
|
||||
}
|
||||
|
||||
const size_t limit_work_group_size =
|
||||
queue->get_device().get_info<sycl::info::device::max_work_group_size>();
|
||||
const size_t limit_work_group_size = reinterpret_cast<sycl::queue *>(queue)
|
||||
->get_device()
|
||||
.get_info<sycl::info::device::max_work_group_size>();
|
||||
|
||||
return std::min(limit_work_group_size, preferred_work_group_size);
|
||||
}
|
||||
|
||||
bool oneapi_load_kernels(SyclQueue *queue_, const uint requested_features)
|
||||
{
|
||||
assert(queue_);
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
|
||||
try {
|
||||
sycl::kernel_bundle<sycl::bundle_state::input> all_kernels_bundle =
|
||||
sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(),
|
||||
{queue->get_device()});
|
||||
|
||||
for (const sycl::kernel_id &kernel_id : all_kernels_bundle.get_kernel_ids()) {
|
||||
const std::string &kernel_name = kernel_id.get_name();
|
||||
|
||||
/* NOTE(@nsirgien): Names in this conditions below should match names from
|
||||
* oneapi_call macro in oneapi_enqueue_kernel below */
|
||||
if (((requested_features & KERNEL_FEATURE_VOLUME) == 0) &&
|
||||
kernel_name.find("oneapi_kernel_integrator_shade_volume") != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((requested_features & KERNEL_FEATURE_MNEE) == 0) &&
|
||||
kernel_name.find("oneapi_kernel_integrator_shade_surface_mnee") != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((requested_features & KERNEL_FEATURE_NODE_RAYTRACE) == 0) &&
|
||||
kernel_name.find("oneapi_kernel_integrator_shade_surface_raytrace") !=
|
||||
std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sycl::kernel_bundle<sycl::bundle_state::input> one_kernel_bundle =
|
||||
sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(), {kernel_id});
|
||||
sycl::build(one_kernel_bundle, {queue->get_device()}, sycl::property::queue::in_order());
|
||||
}
|
||||
}
|
||||
catch (sycl::exception const &e) {
|
||||
if (s_error_cb) {
|
||||
s_error_cb(e.what(), s_error_user_ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool oneapi_enqueue_kernel(KernelContext *kernel_context,
|
||||
int kernel,
|
||||
size_t global_size,
|
||||
|
@ -664,266 +517,4 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
|
|||
# endif
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
|
||||
* since Windows driver 101.3268. */
|
||||
/* The same min compute-runtime version is currently required across Windows and Linux.
|
||||
* For Windows driver 101.3430, compute-runtime version is 23904. */
|
||||
static const int lowest_supported_driver_version_win = 1013430;
|
||||
static const int lowest_supported_driver_version_neo = 23904;
|
||||
|
||||
static int parse_driver_build_version(const sycl::device &device)
|
||||
{
|
||||
const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
|
||||
int driver_build_version = 0;
|
||||
|
||||
size_t second_dot_position = driver_version.find('.', driver_version.find('.') + 1);
|
||||
if (second_dot_position == std::string::npos) {
|
||||
std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
|
||||
<< "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
|
||||
<< " xx.xx.xxx.xxxx (Windows) for device \""
|
||||
<< device.get_info<sycl::info::device::name>() << "\"." << std::endl;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
size_t third_dot_position = driver_version.find('.', second_dot_position + 1);
|
||||
if (third_dot_position != std::string::npos) {
|
||||
const std::string &third_number_substr = driver_version.substr(
|
||||
second_dot_position + 1, third_dot_position - second_dot_position - 1);
|
||||
const std::string &forth_number_substr = driver_version.substr(third_dot_position + 1);
|
||||
if (third_number_substr.length() == 3 && forth_number_substr.length() == 4)
|
||||
driver_build_version = std::stoi(third_number_substr) * 10000 +
|
||||
std::stoi(forth_number_substr);
|
||||
}
|
||||
else {
|
||||
const std::string &third_number_substr = driver_version.substr(second_dot_position + 1);
|
||||
driver_build_version = std::stoi(third_number_substr);
|
||||
}
|
||||
}
|
||||
catch (std::invalid_argument &e) {
|
||||
std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
|
||||
<< "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
|
||||
<< " xx.xx.xxx.xxxx (Windows) for device \""
|
||||
<< device.get_info<sycl::info::device::name>() << "\"." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return driver_build_version;
|
||||
}
|
||||
|
||||
static std::vector<sycl::device> oneapi_available_devices()
|
||||
{
|
||||
bool allow_all_devices = false;
|
||||
if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr)
|
||||
allow_all_devices = true;
|
||||
|
||||
/* Host device is useful only for debugging at the moment
|
||||
* so we hide this device with default build settings. */
|
||||
# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
|
||||
bool allow_host = true;
|
||||
# else
|
||||
bool allow_host = false;
|
||||
# endif
|
||||
|
||||
const std::vector<sycl::platform> &oneapi_platforms = sycl::platform::get_platforms();
|
||||
|
||||
std::vector<sycl::device> available_devices;
|
||||
for (const sycl::platform &platform : oneapi_platforms) {
|
||||
/* ignore OpenCL platforms to avoid using the same devices through both Level-Zero and OpenCL.
|
||||
*/
|
||||
if (platform.get_backend() == sycl::backend::opencl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<sycl::device> &oneapi_devices =
|
||||
(allow_all_devices || allow_host) ? platform.get_devices(sycl::info::device_type::all) :
|
||||
platform.get_devices(sycl::info::device_type::gpu);
|
||||
|
||||
for (const sycl::device &device : oneapi_devices) {
|
||||
if (allow_all_devices) {
|
||||
/* still filter out host device if build doesn't support it. */
|
||||
if (allow_host || !device.is_host()) {
|
||||
available_devices.push_back(device);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool filter_out = false;
|
||||
|
||||
/* For now we support all Intel(R) Arc(TM) devices and likely any future GPU,
|
||||
* assuming they have either more than 96 Execution Units or not 7 threads per EU.
|
||||
* Official support can be broaden to older and smaller GPUs once ready. */
|
||||
if (device.is_gpu() && platform.get_backend() == sycl::backend::ext_oneapi_level_zero) {
|
||||
/* Filtered-out defaults in-case these values aren't available through too old L0
|
||||
* runtime. */
|
||||
int number_of_eus = 96;
|
||||
int threads_per_eu = 7;
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
|
||||
number_of_eus = device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
|
||||
}
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
|
||||
threads_per_eu =
|
||||
device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
|
||||
}
|
||||
/* This filters out all Level-Zero supported GPUs from older generation than Arc. */
|
||||
if (number_of_eus <= 96 && threads_per_eu == 7) {
|
||||
filter_out = true;
|
||||
}
|
||||
/* if not already filtered out, check driver version. */
|
||||
if (!filter_out) {
|
||||
int driver_build_version = parse_driver_build_version(device);
|
||||
if ((driver_build_version > 100000 &&
|
||||
driver_build_version < lowest_supported_driver_version_win) ||
|
||||
driver_build_version < lowest_supported_driver_version_neo) {
|
||||
filter_out = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!allow_host && device.is_host()) {
|
||||
filter_out = true;
|
||||
}
|
||||
else if (!allow_all_devices) {
|
||||
filter_out = true;
|
||||
}
|
||||
|
||||
if (!filter_out) {
|
||||
available_devices.push_back(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return available_devices;
|
||||
}
|
||||
|
||||
char *oneapi_device_capabilities()
|
||||
{
|
||||
std::stringstream capabilities;
|
||||
|
||||
const std::vector<sycl::device> &oneapi_devices = oneapi_available_devices();
|
||||
for (const sycl::device &device : oneapi_devices) {
|
||||
const std::string &name = device.get_info<sycl::info::device::name>();
|
||||
|
||||
capabilities << std::string("\t") << name << "\n";
|
||||
# define WRITE_ATTR(attribute_name, attribute_variable) \
|
||||
capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \
|
||||
<< "\n";
|
||||
# define GET_NUM_ATTR(attribute) \
|
||||
{ \
|
||||
size_t attribute = (size_t)device.get_info<sycl::info::device ::attribute>(); \
|
||||
capabilities << "\t\tsycl::info::device::" #attribute "\t\t\t" << attribute << "\n"; \
|
||||
}
|
||||
|
||||
GET_NUM_ATTR(vendor_id)
|
||||
GET_NUM_ATTR(max_compute_units)
|
||||
GET_NUM_ATTR(max_work_item_dimensions)
|
||||
|
||||
sycl::id<3> max_work_item_sizes =
|
||||
device.get_info<sycl::info::device::max_work_item_sizes<3>>();
|
||||
WRITE_ATTR("max_work_item_sizes_dim0", ((size_t)max_work_item_sizes.get(0)))
|
||||
WRITE_ATTR("max_work_item_sizes_dim1", ((size_t)max_work_item_sizes.get(1)))
|
||||
WRITE_ATTR("max_work_item_sizes_dim2", ((size_t)max_work_item_sizes.get(2)))
|
||||
|
||||
GET_NUM_ATTR(max_work_group_size)
|
||||
GET_NUM_ATTR(max_num_sub_groups)
|
||||
GET_NUM_ATTR(sub_group_independent_forward_progress)
|
||||
|
||||
GET_NUM_ATTR(preferred_vector_width_char)
|
||||
GET_NUM_ATTR(preferred_vector_width_short)
|
||||
GET_NUM_ATTR(preferred_vector_width_int)
|
||||
GET_NUM_ATTR(preferred_vector_width_long)
|
||||
GET_NUM_ATTR(preferred_vector_width_float)
|
||||
GET_NUM_ATTR(preferred_vector_width_double)
|
||||
GET_NUM_ATTR(preferred_vector_width_half)
|
||||
|
||||
GET_NUM_ATTR(native_vector_width_char)
|
||||
GET_NUM_ATTR(native_vector_width_short)
|
||||
GET_NUM_ATTR(native_vector_width_int)
|
||||
GET_NUM_ATTR(native_vector_width_long)
|
||||
GET_NUM_ATTR(native_vector_width_float)
|
||||
GET_NUM_ATTR(native_vector_width_double)
|
||||
GET_NUM_ATTR(native_vector_width_half)
|
||||
|
||||
size_t max_clock_frequency =
|
||||
(size_t)(device.is_host() ? (size_t)0 :
|
||||
device.get_info<sycl::info::device::max_clock_frequency>());
|
||||
WRITE_ATTR("max_clock_frequency", max_clock_frequency)
|
||||
|
||||
GET_NUM_ATTR(address_bits)
|
||||
GET_NUM_ATTR(max_mem_alloc_size)
|
||||
|
||||
/* NOTE(@nsirgien): Implementation doesn't use image support as bindless images aren't
|
||||
* supported so we always return false, even if device supports HW texture usage acceleration.
|
||||
*/
|
||||
bool image_support = false;
|
||||
WRITE_ATTR("image_support", (size_t)image_support)
|
||||
|
||||
GET_NUM_ATTR(max_parameter_size)
|
||||
GET_NUM_ATTR(mem_base_addr_align)
|
||||
GET_NUM_ATTR(global_mem_size)
|
||||
GET_NUM_ATTR(local_mem_size)
|
||||
GET_NUM_ATTR(error_correction_support)
|
||||
GET_NUM_ATTR(profiling_timer_resolution)
|
||||
GET_NUM_ATTR(is_available)
|
||||
|
||||
# undef GET_NUM_ATTR
|
||||
# undef WRITE_ATTR
|
||||
capabilities << "\n";
|
||||
}
|
||||
|
||||
return ::strdup(capabilities.str().c_str());
|
||||
}
|
||||
|
||||
void oneapi_free(void *p)
|
||||
{
|
||||
if (p) {
|
||||
::free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void oneapi_iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr)
|
||||
{
|
||||
int num = 0;
|
||||
std::vector<sycl::device> devices = oneapi_available_devices();
|
||||
for (sycl::device &device : devices) {
|
||||
const std::string &platform_name =
|
||||
device.get_platform().get_info<sycl::info::platform::name>();
|
||||
std::string name = device.get_info<sycl::info::device::name>();
|
||||
std::string id = "ONEAPI_" + platform_name + "_" + name;
|
||||
if (device.has(sycl::aspect::ext_intel_pci_address)) {
|
||||
id.append("_" + device.get_info<sycl::info::device::ext_intel_pci_address>());
|
||||
}
|
||||
(cb)(id.c_str(), name.c_str(), num, user_ptr);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
size_t oneapi_get_memcapacity(SyclQueue *queue)
|
||||
{
|
||||
return reinterpret_cast<sycl::queue *>(queue)
|
||||
->get_device()
|
||||
.get_info<sycl::info::device::global_mem_size>();
|
||||
}
|
||||
|
||||
int oneapi_get_num_multiprocessors(SyclQueue *queue)
|
||||
{
|
||||
const sycl::device &device = reinterpret_cast<sycl::queue *>(queue)->get_device();
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
|
||||
return device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int oneapi_get_max_num_threads_per_multiprocessor(SyclQueue *queue)
|
||||
{
|
||||
const sycl::device &device = reinterpret_cast<sycl::queue *>(queue)->get_device();
|
||||
if (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
|
||||
device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
|
||||
return device.get_info<sycl::info::device::ext_intel_gpu_eu_simd_width>() *
|
||||
device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WITH_ONEAPI */
|
||||
|
|
|
@ -25,11 +25,6 @@ enum DeviceKernel : int;
|
|||
|
||||
class SyclQueue;
|
||||
|
||||
typedef void (*OneAPIDeviceIteratorCallback)(const char *id,
|
||||
const char *name,
|
||||
int num,
|
||||
void *user_ptr);
|
||||
|
||||
typedef void (*OneAPIErrorCallback)(const char *error, void *user_ptr);
|
||||
|
||||
struct KernelContext {
|
||||
|
@ -45,13 +40,17 @@ struct KernelContext {
|
|||
extern "C" {
|
||||
# endif
|
||||
|
||||
# define DLL_INTERFACE_CALL(function, return_type, ...) \
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT return_type function(__VA_ARGS__);
|
||||
# include "kernel/device/oneapi/dll_interface_template.h"
|
||||
# undef DLL_INTERFACE_CALL
|
||||
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_run_test_kernel(SyclQueue *queue_);
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT void oneapi_set_error_cb(OneAPIErrorCallback cb, void *user_ptr);
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT size_t oneapi_kernel_preferred_local_size(
|
||||
SyclQueue *queue, const DeviceKernel kernel, const size_t kernel_global_size);
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_enqueue_kernel(KernelContext *context,
|
||||
int kernel,
|
||||
size_t global_size,
|
||||
void **args);
|
||||
CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_load_kernels(SyclQueue *queue,
|
||||
const unsigned int requested_features);
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* WITH_ONEAPI */
|
||||
|
|
|
@ -501,6 +501,11 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
|
|||
ccl_private float &rand)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
/* we do not need to guide almost delta phase functions */
|
||||
if (fabsf(g) >= 0.99f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kg->opgl_volume_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
|
||||
kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
|
||||
|
|
|
@ -239,7 +239,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* We don't want to bake the back face, so make sure the ray direction never
|
||||
* goes behind the geometry (flat) normal. This is a failsafe, and should rarely happen. */
|
||||
* goes behind the geometry (flat) normal. This is a fail-safe, and should rarely happen. */
|
||||
const float true_normal_epsilon = 0.00001f;
|
||||
|
||||
if (dot(D, Ng) <= true_normal_epsilon) {
|
||||
|
|
|
@ -59,6 +59,13 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
|
|||
#ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) = 1.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, path_segment) = nullptr;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, volume_guiding_sampling_prob) = 0.0f;
|
||||
#endif
|
||||
|
||||
#ifdef __MNEE__
|
||||
|
|
|
@ -100,7 +100,7 @@ ccl_device_inline bool sample_is_class_A(int pattern, int sample)
|
|||
if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
|
||||
/* Fallback: assign samples randomly.
|
||||
* This is guaranteed to work "okay" for any sampler, but isn't good.
|
||||
* (Note: the seed constant is just a random number to guard against
|
||||
* (NOTE: the seed constant is just a random number to guard against
|
||||
* possible interactions with other uses of the hash. There's nothing
|
||||
* special about it.)
|
||||
*/
|
||||
|
|
|
@ -43,6 +43,10 @@ Session::Session(const SessionParams ¶ms_, const SceneParams &scene_params)
|
|||
|
||||
device = Device::create(params.device, stats, profiler);
|
||||
|
||||
if (device->have_error()) {
|
||||
progress.set_error(device->error_message());
|
||||
}
|
||||
|
||||
scene = new Scene(scene_params, device);
|
||||
|
||||
/* Configure path tracer. */
|
||||
|
|
|
@ -36,6 +36,10 @@ extern GHOST_SystemHandle GHOST_CreateSystemBackground(void);
|
|||
*/
|
||||
extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug);
|
||||
|
||||
#if !(defined(WIN32) || defined(__APPLE__))
|
||||
extern const char *GHOST_SystemBackend(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Disposes the one and only system.
|
||||
* \param systemhandle: The handle to the system.
|
||||
|
|
|
@ -134,6 +134,15 @@ class GHOST_ISystem {
|
|||
* \return A pointer to the system.
|
||||
*/
|
||||
static GHOST_ISystem *getSystem();
|
||||
/**
|
||||
* Return an identifier for the one and only system.
|
||||
* \warning while it may be tempting this should never be used to check for supported features,
|
||||
* in that case, the GHOST API should be extended to query capabilities.
|
||||
* This is needed for X11/WAYLAND on Unix, without this - there is no convenient way for users to
|
||||
* check if WAYLAND or XWAYLAND are in use since they are dynamically selected at startup.
|
||||
* When dynamically switching between X11/WAYLAND is removed, this function can go too.
|
||||
*/
|
||||
static const char *getSystemBackend();
|
||||
|
||||
static GHOST_TBacktraceFn getBacktraceFn();
|
||||
static void setBacktraceFn(GHOST_TBacktraceFn backtrace_fn);
|
||||
|
@ -515,6 +524,7 @@ class GHOST_ISystem {
|
|||
|
||||
/** The one and only system */
|
||||
static GHOST_ISystem *m_system;
|
||||
static const char *m_system_backend_id;
|
||||
|
||||
/** Function to call that sets the back-trace. */
|
||||
static GHOST_TBacktraceFn m_backtrace_fn;
|
||||
|
|
|
@ -52,6 +52,13 @@ GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
|
|||
return system->disposeSystem();
|
||||
}
|
||||
|
||||
#if !(defined(WIN32) || defined(__APPLE__))
|
||||
const char *GHOST_SystemBackend()
|
||||
{
|
||||
return GHOST_ISystem::getSystemBackend();
|
||||
}
|
||||
#endif
|
||||
|
||||
void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,
|
||||
const char *title,
|
||||
const char *message,
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#endif
|
||||
|
||||
GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
|
||||
const char *GHOST_ISystem::m_system_backend_id = nullptr;
|
||||
|
||||
GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
|
||||
|
||||
|
@ -122,7 +123,10 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
|
|||
m_system = new GHOST_SystemCocoa();
|
||||
#endif
|
||||
|
||||
if ((m_system == nullptr) && verbose) {
|
||||
if (m_system) {
|
||||
m_system_backend_id = backends_attempted[backends_attempted_num - 1];
|
||||
}
|
||||
else if (verbose) {
|
||||
fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
|
||||
for (int i = 0; i < backends_attempted_num; i++) {
|
||||
if (i != 0) {
|
||||
|
@ -186,6 +190,11 @@ GHOST_ISystem *GHOST_ISystem::getSystem()
|
|||
return m_system;
|
||||
}
|
||||
|
||||
const char *GHOST_ISystem::getSystemBackend()
|
||||
{
|
||||
return m_system_backend_id;
|
||||
}
|
||||
|
||||
GHOST_TBacktraceFn GHOST_ISystem::getBacktraceFn()
|
||||
{
|
||||
return GHOST_ISystem::m_backtrace_fn;
|
||||
|
|
|
@ -68,6 +68,12 @@ static void keyboard_handle_key_repeat_cancel(struct GWL_Seat *seat);
|
|||
|
||||
static void output_handle_done(void *data, struct wl_output *wl_output);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Local Defines
|
||||
*
|
||||
* Control local functionality, compositors specific workarounds.
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
|
||||
* Even though this has been fixed, at time of writing it's not yet in a release.
|
||||
|
@ -86,6 +92,22 @@ static void output_handle_done(void *data, struct wl_output *wl_output);
|
|||
static bool use_gnome_confine_hack = false;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* GNOME (mutter 42.5) doesn't follow the WAYLAND spec regarding keyboard handling,
|
||||
* unlike (other compositors: KDE-plasma, River & Sway which work without problems).
|
||||
*
|
||||
* This means GNOME can't know which modifiers are held when activating windows,
|
||||
* so we guess the left modifiers are held.
|
||||
*
|
||||
* This define could be removed without changing any functionality,
|
||||
* it just means GNOME users will see verbose warning messages that alert them about
|
||||
* a known problem that needs to be fixed up-stream.
|
||||
* See: https://gitlab.gnome.org/GNOME/mutter/-/issues/2457
|
||||
*/
|
||||
#define USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Inline Event Codes
|
||||
*
|
||||
|
@ -385,6 +407,13 @@ struct GWL_Seat {
|
|||
/** Keys held matching `xkb_state`. */
|
||||
struct WGL_KeyboardDepressedState key_depressed;
|
||||
|
||||
#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
struct {
|
||||
bool any_mod_held = false;
|
||||
bool any_keys_held_on_enter = false;
|
||||
} key_depressed_suppress_warning;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Cache result of `xkb_keymap_mod_get_index`
|
||||
* so every time a modifier is accessed a string lookup isn't required.
|
||||
|
@ -2303,6 +2332,7 @@ static void keyboard_handle_enter(void *data,
|
|||
uint32_t *key;
|
||||
WL_ARRAY_FOR_EACH (key, keys) {
|
||||
const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
|
||||
CLOG_INFO(LOG, 2, "enter (key_held=%d)", int(key_code));
|
||||
const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, key_code);
|
||||
const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(sym, *key);
|
||||
if (gkey != GHOST_kKeyUnknown) {
|
||||
|
@ -2311,6 +2341,10 @@ static void keyboard_handle_enter(void *data,
|
|||
}
|
||||
|
||||
keyboard_depressed_state_push_events_from_change(seat, key_depressed_prev);
|
||||
|
||||
#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
seat->key_depressed_suppress_warning.any_keys_held_on_enter = keys->size != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2336,6 +2370,11 @@ static void keyboard_handle_leave(void *data,
|
|||
if (seat->key_repeat.timer) {
|
||||
keyboard_handle_key_repeat_cancel(seat);
|
||||
}
|
||||
|
||||
#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
seat->key_depressed_suppress_warning.any_mod_held = false;
|
||||
seat->key_depressed_suppress_warning.any_keys_held_on_enter = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2407,10 +2446,10 @@ static void keyboard_handle_key(void *data,
|
|||
const xkb_keysym_t sym = xkb_state_key_get_one_sym_without_modifiers(
|
||||
seat->xkb_state_empty, seat->xkb_state_empty_with_numlock, key_code);
|
||||
if (sym == XKB_KEY_NoSymbol) {
|
||||
CLOG_INFO(LOG, 2, "key (no symbol, skipped)");
|
||||
CLOG_INFO(LOG, 2, "key (code=%d, state=%u, no symbol, skipped)", int(key_code), state);
|
||||
return;
|
||||
}
|
||||
CLOG_INFO(LOG, 2, "key");
|
||||
CLOG_INFO(LOG, 2, "key (code=%d, state=%u)", int(key_code), state);
|
||||
|
||||
GHOST_TEventType etype = GHOST_kEventUnknown;
|
||||
switch (state) {
|
||||
|
@ -2554,6 +2593,10 @@ static void keyboard_handle_modifiers(void *data,
|
|||
if (seat->key_repeat.timer) {
|
||||
keyboard_handle_key_repeat_reset(seat, true);
|
||||
}
|
||||
|
||||
#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
seat->key_depressed_suppress_warning.any_mod_held = mods_depressed != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_repeat_handle_info(void *data,
|
||||
|
@ -3163,6 +3206,15 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co
|
|||
|
||||
const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
|
||||
bool show_warning = true;
|
||||
#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
|
||||
if ((seat->key_depressed_suppress_warning.any_mod_held == true) &&
|
||||
(seat->key_depressed_suppress_warning.any_keys_held_on_enter == false)) {
|
||||
/* The compositor gave us invalid information, don't show a warning. */
|
||||
show_warning = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Use local #WGL_KeyboardDepressedState to check which key is pressed.
|
||||
* Use XKB as the source of truth, if there is any discrepancy. */
|
||||
for (int i = 0; i < MOD_INDEX_NUM; i++) {
|
||||
|
@ -3178,18 +3230,22 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co
|
|||
* Warn so if this happens it can be investigated. */
|
||||
if (val) {
|
||||
if (UNLIKELY(!(val_l || val_r))) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (held keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
if (show_warning) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (GHOST held keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
}
|
||||
/* Picking the left is arbitrary. */
|
||||
val_l = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (UNLIKELY(val_l || val_r)) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (released keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
if (show_warning) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (GHOST released keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
}
|
||||
val_l = false;
|
||||
val_r = false;
|
||||
}
|
||||
|
@ -4268,19 +4324,41 @@ bool ghost_wl_dynload_libraries()
|
|||
* which will be used as a fallback. */
|
||||
# ifdef WITH_GHOST_X11
|
||||
bool verbose = false;
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
/* When running in Wayland, let the user know if libdecor is the only reason WAYLAND
|
||||
* could not be used. Otherwise it's not obvious why X11 is used as a fallback. */
|
||||
bool verbose_libdecor = getenv("WAYLAND_DISPLAY") != nullptr;
|
||||
# endif
|
||||
# else
|
||||
bool verbose = true;
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
bool verbose_libdecor = true;
|
||||
# endif
|
||||
# endif /* !WITH_GHOST_X11 */
|
||||
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
int8_t libdecor_init = -1;
|
||||
# endif
|
||||
|
||||
if (wayland_dynload_client_init(verbose) && /* `libwayland-client`. */
|
||||
wayland_dynload_cursor_init(verbose) && /* `libwayland-cursor`. */
|
||||
wayland_dynload_egl_init(verbose) && /* `libwayland-egl`. */
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
wayland_dynload_libdecor_init(verbose) && /* `libdecor-0`. */
|
||||
(libdecor_init = wayland_dynload_libdecor_init(verbose_libdecor)) && /* `libdecor-0`. */
|
||||
# endif
|
||||
true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
# if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_GHOST_X11)
|
||||
if (libdecor_init == 0) {
|
||||
/* LIBDECOR was the only reason X11 was used, let the user know they need it installed. */
|
||||
fprintf(stderr,
|
||||
"WAYLAND found but libdecor was not, install libdecor for Wayland support, "
|
||||
"falling back to X11\n");
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
wayland_dynload_libdecor_exit();
|
||||
# endif
|
||||
|
|
|
@ -723,12 +723,11 @@ template<typename Mesh> class Mikktspace {
|
|||
|
||||
void build4RuleGroups()
|
||||
{
|
||||
/* Note: This could be parallelized by grouping all [t, i] pairs into
|
||||
/* NOTE: This could be parallelized by grouping all [t, i] pairs into
|
||||
* shards by hash(triangles[t].vertices[i]). This way, each shard can be processed
|
||||
* independently and in parallel.
|
||||
* However, the groupWithAny logic needs special handling (e.g. lock a mutex when
|
||||
* encountering a groupWithAny triangle, then sort it out, then unlock and proceed).
|
||||
*/
|
||||
* However, the `groupWithAny` logic needs special handling (e.g. lock a mutex when
|
||||
* encountering a `groupWithAny` triangle, then sort it out, then unlock and proceed). */
|
||||
for (uint t = 0; t < nrTriangles; t++) {
|
||||
Triangle &triangle = triangles[t];
|
||||
for (uint i = 0; i < 3; i++) {
|
||||
|
|
|
@ -18997,6 +18997,36 @@
|
|||
id="path4817-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g24638">
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke-linecap:round;-inkscape-stroke:none;opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-linejoin:round"
|
||||
d="m 374.12695,305.31445 c -1.10721,0 -1.93616,0.24199 -2.97851,0.63086 -1.04236,0.38888 -2.18224,0.95849 -3.30078,1.77735 -2.2371,1.63771 -4.46485,4.54533 -4.46485,8.40625 a 3.0581999,3.0581999 0 0 0 3.0586,3.05859 3.0581999,3.0581999 0 0 0 3.05859,-3.05859 c 0,-1.63187 0.77567,-2.603 1.96094,-3.47071 0.59263,-0.43385 1.26841,-0.77311 1.82422,-0.98047 0.5558,-0.20735 1.10962,-0.24804 0.84179,-0.24804 a 3.0581999,3.0581999 0 0 0 3.05664,-3.0586 3.0581999,3.0581999 0 0 0 -3.05664,-3.05664 z"
|
||||
id="path6454-6" />
|
||||
<path
|
||||
style="display:inline;opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
|
||||
d="m 366.4419,316.12916 c 0,-5.49278 6.00534,-7.75723 7.68412,-7.75723"
|
||||
id="path15424"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g24643">
|
||||
<path
|
||||
style="opacity:0.5;fill:#ffffff;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 343.45275,317.52104 4.51631,-3.99333"
|
||||
id="path4694"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 342.44508,318.83525 c 14.125,0.14581 -0.42233,-12.9179 13.5429,-12.85486"
|
||||
id="path6454"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#ffffff;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 350.84964,311.18794 4.21454,-3.72502"
|
||||
id="path19640"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
|
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 2.5 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -978,17 +978,30 @@ def dump_messages(do_messages, do_checks, settings):
|
|||
# Get strings from addons' bl_info.
|
||||
import addon_utils
|
||||
for module in addon_utils.modules():
|
||||
if module.bl_info['support'] != 'OFFICIAL':
|
||||
# Only process official add-ons, i.e. those marked as 'OFFICIAL' and
|
||||
# existing in the system add-ons directory (not user-installed ones).
|
||||
if (module.bl_info['support'] != 'OFFICIAL'
|
||||
or not bpy.path.is_subdir(module.__file__, bpy.utils.system_resource('SCRIPTS'))):
|
||||
continue
|
||||
dump_addon_bl_info(msgs, reports, module, settings)
|
||||
|
||||
# Get strings from addons' categories.
|
||||
system_categories = set()
|
||||
for module in addon_utils.modules():
|
||||
if bpy.path.is_subdir(module.__file__, bpy.utils.system_resource('SCRIPTS')):
|
||||
system_categories.add(module.bl_info['category'])
|
||||
for uid, label, tip in bpy.types.WindowManager.addon_filter.keywords['items'](
|
||||
bpy.context.window_manager,
|
||||
bpy.context,
|
||||
):
|
||||
process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
|
||||
if tip:
|
||||
if label in system_categories:
|
||||
# Only process add-on if it a system one (i.e shipped with Blender). Also,
|
||||
# we do want to translate official categories, even if they have no official add-ons,
|
||||
# hence the different test than below.
|
||||
process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
|
||||
elif tip:
|
||||
# Only special categories get a tip (All and User).
|
||||
process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
|
||||
process_msg(msgs, settings.DEFAULT_CONTEXT, tip, "Add-ons' categories", reports, None, settings)
|
||||
|
||||
# Get strings specific to translations' menu.
|
||||
|
|
|
@ -367,9 +367,9 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
|
|||
"all and invert unselected",
|
||||
"and AMD driver version 22.10 or newer",
|
||||
"and AMD Radeon Pro 21.Q4 driver or newer",
|
||||
"and Linux driver version xx.xx.23570 or newer",
|
||||
"and Linux driver version xx.xx.23904 or newer",
|
||||
"and NVIDIA driver version 470 or newer",
|
||||
"and Windows driver version 101.3268 or newer",
|
||||
"and Windows driver version 101.3430 or newer",
|
||||
"available with",
|
||||
"brown fox",
|
||||
"can't save image while rendering",
|
||||
|
|
|
@ -389,6 +389,8 @@ class SpellChecker:
|
|||
"albedo",
|
||||
"anamorphic",
|
||||
"anisotropic", "anisotropy",
|
||||
"arcminute", "arcminutes",
|
||||
"arcsecond", "arcseconds",
|
||||
"bimanual", # OpenXR?
|
||||
"bitangent",
|
||||
"boid", "boids",
|
||||
|
@ -449,7 +451,7 @@ class SpellChecker:
|
|||
"superellipse",
|
||||
"thumbstick",
|
||||
"tooltip", "tooltips",
|
||||
"trackpad",
|
||||
"touchpad", "trackpad",
|
||||
"tuple",
|
||||
"unicode",
|
||||
"viewport", "viewports",
|
||||
|
@ -650,6 +652,7 @@ class SpellChecker:
|
|||
"mikktspace",
|
||||
"minkowski",
|
||||
"minnaert",
|
||||
"mises", # von Mises-Fisher
|
||||
"moskowitz", # Pierson-Moskowitz
|
||||
"musgrave",
|
||||
"nayar",
|
||||
|
@ -665,6 +668,7 @@ class SpellChecker:
|
|||
"runge",
|
||||
"sobol",
|
||||
"verlet",
|
||||
"von", # von Mises-Fisher
|
||||
"wilkie",
|
||||
"worley",
|
||||
|
||||
|
@ -724,6 +728,7 @@ class SpellChecker:
|
|||
"lmb", "mmb", "rmb",
|
||||
"lscm",
|
||||
"kb",
|
||||
"mis",
|
||||
"mocap",
|
||||
"msgid", "msgids",
|
||||
"mux",
|
||||
|
@ -751,6 +756,7 @@ class SpellChecker:
|
|||
"uuid",
|
||||
"vbo", "vbos",
|
||||
"vfx",
|
||||
"vmm",
|
||||
"vr",
|
||||
"wxyz",
|
||||
"xr",
|
||||
|
|
|
@ -142,8 +142,17 @@ def object_data_add(context, obdata, operator=None, name=None):
|
|||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
else:
|
||||
layer.objects.active = obj_new
|
||||
if obdata and context.preferences.edit.use_enter_edit_mode:
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
if context.preferences.edit.use_enter_edit_mode:
|
||||
if obdata and obdata.library is None:
|
||||
obtype = obj_new.type
|
||||
mode = None
|
||||
if obtype in {'ARMATURE', 'CURVE', 'CURVES', 'FONT', 'LATTICE', 'MESH', 'META', 'SURFACE'}:
|
||||
mode = 'EDIT'
|
||||
elif obtype == 'GPENCIL':
|
||||
mode = 'EDIT_GPENCIL'
|
||||
|
||||
if mode is not None:
|
||||
bpy.ops.object.mode_set(mode=mode)
|
||||
|
||||
return obj_new
|
||||
|
||||
|
|
|
@ -53,6 +53,13 @@ def write_sysinfo(filepath):
|
|||
output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags))
|
||||
output.write("build system: %s\n" % prepr(bpy.app.build_system))
|
||||
|
||||
# Windowing Environment (include when dynamically selectable).
|
||||
from _bpy import _ghost_backend
|
||||
ghost_backend = _ghost_backend()
|
||||
if ghost_backend not in {'NONE', 'DEFAULT'}:
|
||||
output.write("windowing environment: %s\n" % prepr(ghost_backend))
|
||||
del _ghost_backend, ghost_backend
|
||||
|
||||
# Python info.
|
||||
output.write(title("Python"))
|
||||
output.write("version: %s\n" % (sys.version.replace("\n", " ")))
|
||||
|
|
|
@ -3177,6 +3177,15 @@ class WM_MT_splash_about(Menu):
|
|||
bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
|
||||
col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode('ascii'), translate=False)
|
||||
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
|
||||
|
||||
# This isn't useful information on MS-Windows or Apple systems as dynamically switching
|
||||
# between windowing systems is only supported between X11/WAYLAND.
|
||||
from _bpy import _ghost_backend
|
||||
ghost_backend = _ghost_backend()
|
||||
if ghost_backend not in {'NONE', 'DEFAULT'}:
|
||||
col.label(text=iface_("Windowing Environment: %s") % _ghost_backend(), translate=False)
|
||||
del _ghost_backend, ghost_backend
|
||||
|
||||
col.separator(factor=2.0)
|
||||
col.label(text="Blender is free software")
|
||||
col.label(text="Licensed under the GNU General Public License")
|
||||
|
|
|
@ -239,6 +239,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
|
|||
|
||||
class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Emission"
|
||||
bl_translation_context = i18n_contexts.id_particlesettings
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
import bpy
|
||||
from bpy.types import Panel, Header, Menu, UIList
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
contexts as i18n_contexts,
|
||||
)
|
||||
from bl_ui.utils import PresetPanel
|
||||
from bl_ui.properties_grease_pencil_common import (
|
||||
AnnotationDrawingToolsPanel,
|
||||
|
@ -1751,6 +1754,7 @@ class CLIP_MT_marker_pie(Menu):
|
|||
class CLIP_MT_tracking_pie(Menu):
|
||||
# Tracking Operators
|
||||
bl_label = "Tracking"
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
|
|
@ -683,7 +683,7 @@ class SEQUENCER_MT_add(Menu):
|
|||
elif bpy_data_movieclips_len > 0:
|
||||
layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip", icon='TRACKER')
|
||||
else:
|
||||
layout.menu("SEQUENCER_MT_add_empty", text="Clip", icon='TRACKER')
|
||||
layout.menu("SEQUENCER_MT_add_empty", text="Clip", text_ctxt=i18n_contexts.id_movieclip, icon='TRACKER')
|
||||
del bpy_data_movieclips_len
|
||||
|
||||
bpy_data_masks_len = len(bpy.data.masks)
|
||||
|
|
|
@ -272,7 +272,7 @@ class TOPBAR_MT_file(Menu):
|
|||
layout = self.layout
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE_NEW')
|
||||
layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
|
||||
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
|
||||
layout.menu("TOPBAR_MT_file_open_recent")
|
||||
layout.operator("wm.revert_mainfile")
|
||||
|
@ -411,9 +411,16 @@ class TOPBAR_MT_file_defaults(Menu):
|
|||
app_template, has_ext=False))
|
||||
|
||||
layout.operator("wm.save_homefile")
|
||||
props = layout.operator("wm.read_factory_settings")
|
||||
if app_template:
|
||||
display_name = bpy.path.display_name(iface_(app_template))
|
||||
props = layout.operator("wm.read_factory_settings", text="Load Factory Blender Settings")
|
||||
props.app_template = app_template
|
||||
props = layout.operator("wm.read_factory_settings", text="Load Factory %s Settings" % display_name)
|
||||
props.app_template = app_template
|
||||
props.use_factory_startup_app_template_only = True
|
||||
del display_name
|
||||
else:
|
||||
layout.operator("wm.read_factory_settings")
|
||||
|
||||
|
||||
# Include technical operators here which would otherwise have no way for users to access.
|
||||
|
@ -727,7 +734,7 @@ class TOPBAR_MT_file_context_menu(Menu):
|
|||
layout = self.layout
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.menu("TOPBAR_MT_file_new", text="New", text_context=i18n_contexts.id_windowmanager, icon='FILE_NEW')
|
||||
layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
|
||||
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
|
||||
|
||||
layout.separator()
|
||||
|
|
|
@ -105,7 +105,16 @@ class USERPREF_MT_save_load(Menu):
|
|||
sub_revert.operator("wm.read_userpref", text="Revert to Saved Preferences")
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.read_factory_userpref", text="Load Factory Preferences")
|
||||
|
||||
app_template = prefs.app_template
|
||||
if app_template:
|
||||
display_name = bpy.path.display_name(iface_(app_template))
|
||||
layout.operator("wm.read_factory_userpref", text="Load Factory Blender Preferences")
|
||||
props = layout.operator("wm.read_factory_userpref", text="Load Factory %s Preferences" % display_name)
|
||||
props.use_factory_startup_app_template_only = True
|
||||
del display_name
|
||||
else:
|
||||
layout.operator("wm.read_factory_userpref", text="Load Factory Preferences")
|
||||
|
||||
|
||||
class USERPREF_PT_save_preferences(Panel):
|
||||
|
|
|
@ -98,7 +98,7 @@ static int blf_search(const char *name)
|
|||
{
|
||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
const FontBLF *font = global_font[i];
|
||||
if (font && (STREQ(font->name, name))) {
|
||||
if (font && STREQ(font->name, name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ void BLF_unload(const char *name)
|
|||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
FontBLF *font = global_font[i];
|
||||
|
||||
if (font && (STREQ(font->name, name))) {
|
||||
if (font && STREQ(font->name, name)) {
|
||||
BLI_assert(font->reference_count > 0);
|
||||
font->reference_count--;
|
||||
|
||||
|
|
|
@ -498,6 +498,115 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
|
|||
/** \name Text Drawing: Buffer
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Draw glyph `g` into `buf_info` pixels.
|
||||
*/
|
||||
static void blf_glyph_draw_buffer(FontBufInfoBLF *buf_info,
|
||||
GlyphBLF *g,
|
||||
const ft_pix pen_x,
|
||||
const ft_pix pen_y_basis)
|
||||
{
|
||||
const int chx = ft_pix_to_int(pen_x + ft_pix_from_int(g->pos[0]));
|
||||
const int chy = ft_pix_to_int(pen_y_basis + ft_pix_from_int(g->dims[1]));
|
||||
|
||||
ft_pix pen_y = (g->pitch < 0) ? (pen_y_basis + ft_pix_from_int(g->dims[1] - g->pos[1])) :
|
||||
(pen_y_basis - ft_pix_from_int(g->dims[1] - g->pos[1]));
|
||||
|
||||
if ((chx + g->dims[0]) < 0 || /* Out of bounds: left. */
|
||||
chx >= buf_info->dims[0] || /* Out of bounds: right. */
|
||||
(ft_pix_to_int(pen_y) + g->dims[1]) < 0 || /* Out of bounds: bottom. */
|
||||
ft_pix_to_int(pen_y) >= buf_info->dims[1] /* Out of bounds: top. */
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't draw beyond the buffer bounds. */
|
||||
int width_clip = g->dims[0];
|
||||
int height_clip = g->dims[1];
|
||||
int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
|
||||
|
||||
if (width_clip + chx > buf_info->dims[0]) {
|
||||
width_clip -= chx + width_clip - buf_info->dims[0];
|
||||
}
|
||||
if (height_clip + ft_pix_to_int(pen_y) > buf_info->dims[1]) {
|
||||
height_clip -= ft_pix_to_int(pen_y) + height_clip - buf_info->dims[1];
|
||||
}
|
||||
|
||||
/* Clip drawing below the image. */
|
||||
if (pen_y < 0) {
|
||||
yb_start += (g->pitch < 0) ? -ft_pix_to_int(pen_y) : ft_pix_to_int(pen_y);
|
||||
height_clip += ft_pix_to_int(pen_y);
|
||||
pen_y = 0;
|
||||
}
|
||||
|
||||
/* Avoid conversions in the pixel writing loop. */
|
||||
const int pen_y_px = ft_pix_to_int(pen_y);
|
||||
|
||||
const float *b_col_float = buf_info->col_float;
|
||||
const uchar *b_col_char = buf_info->col_char;
|
||||
|
||||
if (buf_info->fbuf) {
|
||||
int yb = yb_start;
|
||||
for (int y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
|
||||
for (int x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
|
||||
const char a_byte = *(g->bitmap + x + (yb * g->pitch));
|
||||
if (a_byte) {
|
||||
const float a = (a_byte / 255.0f) * b_col_float[3];
|
||||
const size_t buf_ofs = (((size_t)(chx + x) +
|
||||
((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
|
||||
(size_t)buf_info->ch);
|
||||
float *fbuf = buf_info->fbuf + buf_ofs;
|
||||
|
||||
float font_pixel[4];
|
||||
font_pixel[0] = b_col_float[0] * a;
|
||||
font_pixel[1] = b_col_float[1] * a;
|
||||
font_pixel[2] = b_col_float[2] * a;
|
||||
font_pixel[3] = a;
|
||||
blend_color_mix_float(fbuf, fbuf, font_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (g->pitch < 0) {
|
||||
yb++;
|
||||
}
|
||||
else {
|
||||
yb--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_info->cbuf) {
|
||||
int yb = yb_start;
|
||||
for (int y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
|
||||
for (int x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
|
||||
const char a_byte = *(g->bitmap + x + (yb * g->pitch));
|
||||
|
||||
if (a_byte) {
|
||||
const float a = (a_byte / 255.0f) * b_col_float[3];
|
||||
const size_t buf_ofs = (((size_t)(chx + x) +
|
||||
((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
|
||||
(size_t)buf_info->ch);
|
||||
uchar *cbuf = buf_info->cbuf + buf_ofs;
|
||||
|
||||
uchar font_pixel[4];
|
||||
font_pixel[0] = b_col_char[0];
|
||||
font_pixel[1] = b_col_char[1];
|
||||
font_pixel[2] = b_col_char[2];
|
||||
font_pixel[3] = unit_float_to_uchar_clamp(a);
|
||||
blend_color_mix_byte(cbuf, cbuf, font_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (g->pitch < 0) {
|
||||
yb++;
|
||||
}
|
||||
else {
|
||||
yb--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity checks are done by BLF_draw_buffer() */
|
||||
static void blf_font_draw_buffer_ex(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
|
@ -513,10 +622,6 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
|
|||
|
||||
/* buffer specific vars */
|
||||
FontBufInfoBLF *buf_info = &font->buf_info;
|
||||
const float *b_col_float = buf_info->col_float;
|
||||
const uchar *b_col_char = buf_info->col_char;
|
||||
int chx, chy;
|
||||
int y, x;
|
||||
|
||||
/* another buffer specific call for color conversion */
|
||||
|
||||
|
@ -528,101 +633,7 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
|
|||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
chx = ft_pix_to_int(pen_x + ft_pix_from_int(g->pos[0]));
|
||||
chy = ft_pix_to_int(pen_y_basis + ft_pix_from_int(g->dims[1]));
|
||||
|
||||
if (g->pitch < 0) {
|
||||
pen_y = pen_y_basis + ft_pix_from_int(g->dims[1] - g->pos[1]);
|
||||
}
|
||||
else {
|
||||
pen_y = pen_y_basis - ft_pix_from_int(g->dims[1] - g->pos[1]);
|
||||
}
|
||||
|
||||
if ((chx + g->dims[0]) >= 0 && chx < buf_info->dims[0] &&
|
||||
(ft_pix_to_int(pen_y) + g->dims[1]) >= 0 && ft_pix_to_int(pen_y) < buf_info->dims[1]) {
|
||||
/* don't draw beyond the buffer bounds */
|
||||
int width_clip = g->dims[0];
|
||||
int height_clip = g->dims[1];
|
||||
int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
|
||||
|
||||
if (width_clip + chx > buf_info->dims[0]) {
|
||||
width_clip -= chx + width_clip - buf_info->dims[0];
|
||||
}
|
||||
if (height_clip + ft_pix_to_int(pen_y) > buf_info->dims[1]) {
|
||||
height_clip -= ft_pix_to_int(pen_y) + height_clip - buf_info->dims[1];
|
||||
}
|
||||
|
||||
/* drawing below the image? */
|
||||
if (pen_y < 0) {
|
||||
yb_start += (g->pitch < 0) ? -ft_pix_to_int(pen_y) : ft_pix_to_int(pen_y);
|
||||
height_clip += ft_pix_to_int(pen_y);
|
||||
pen_y = 0;
|
||||
}
|
||||
|
||||
/* Avoid conversions in the pixel writing loop. */
|
||||
const int pen_y_px = ft_pix_to_int(pen_y);
|
||||
|
||||
if (buf_info->fbuf) {
|
||||
int yb = yb_start;
|
||||
for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
|
||||
for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
|
||||
const char a_byte = *(g->bitmap + x + (yb * g->pitch));
|
||||
if (a_byte) {
|
||||
const float a = (a_byte / 255.0f) * b_col_float[3];
|
||||
const size_t buf_ofs = (((size_t)(chx + x) +
|
||||
((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
|
||||
(size_t)buf_info->ch);
|
||||
float *fbuf = buf_info->fbuf + buf_ofs;
|
||||
|
||||
float font_pixel[4];
|
||||
font_pixel[0] = b_col_float[0] * a;
|
||||
font_pixel[1] = b_col_float[1] * a;
|
||||
font_pixel[2] = b_col_float[2] * a;
|
||||
font_pixel[3] = a;
|
||||
blend_color_mix_float(fbuf, fbuf, font_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (g->pitch < 0) {
|
||||
yb++;
|
||||
}
|
||||
else {
|
||||
yb--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_info->cbuf) {
|
||||
int yb = yb_start;
|
||||
for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
|
||||
for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
|
||||
const char a_byte = *(g->bitmap + x + (yb * g->pitch));
|
||||
|
||||
if (a_byte) {
|
||||
const float a = (a_byte / 255.0f) * b_col_float[3];
|
||||
const size_t buf_ofs = (((size_t)(chx + x) +
|
||||
((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
|
||||
(size_t)buf_info->ch);
|
||||
uchar *cbuf = buf_info->cbuf + buf_ofs;
|
||||
|
||||
uchar font_pixel[4];
|
||||
font_pixel[0] = b_col_char[0];
|
||||
font_pixel[1] = b_col_char[1];
|
||||
font_pixel[2] = b_col_char[2];
|
||||
font_pixel[3] = unit_float_to_uchar_clamp(a);
|
||||
blend_color_mix_byte(cbuf, cbuf, font_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (g->pitch < 0) {
|
||||
yb++;
|
||||
}
|
||||
else {
|
||||
yb--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
blf_glyph_draw_buffer(buf_info, g, pen_x, pen_y_basis);
|
||||
|
||||
pen_x = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
g_prev = g;
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
*/
|
||||
static FT_Fixed to_16dot16(double val)
|
||||
{
|
||||
return (FT_Fixed)(lround(val * 65536.0));
|
||||
return (FT_Fixed)lround(val * 65536.0);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -30,7 +30,7 @@ void BKE_blender_globals_main_replace(struct Main *bmain);
|
|||
* Replace current global Main by the given one, returning the old one.
|
||||
*
|
||||
* \warning Advanced, risky workaround addressing the issue that current RNA is not able to process
|
||||
* correectly non-G_MAIN data, use with (a lot of) care.
|
||||
* correctly non-G_MAIN data, use with (a lot of) care.
|
||||
*/
|
||||
struct Main *BKE_blender_globals_main_swap(struct Main *new_gmain);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ struct ListBase;
|
|||
struct Object;
|
||||
struct ParticleSystem;
|
||||
struct Scene;
|
||||
struct ViewLayer;
|
||||
struct ViewerPath;
|
||||
struct GeometrySet;
|
||||
|
||||
|
@ -83,6 +84,13 @@ bool BKE_object_dupli_find_rgba_attribute(struct Object *ob,
|
|||
const char *name,
|
||||
float r_value[4]);
|
||||
|
||||
/** Look up the RGBA value of a view layer/scene/world shader attribute.
|
||||
* \return true if the attribute was found; if not, r_value is also set to zero. */
|
||||
bool BKE_view_layer_find_rgba_attribute(struct Scene *scene,
|
||||
struct ViewLayer *layer,
|
||||
const char *name,
|
||||
float r_value[4]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -350,14 +350,14 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
|
|||
#ifdef __cplusplus
|
||||
namespace blender::mesh_topology {
|
||||
|
||||
Array<int> build_corner_to_poly_map(Span<MPoly> polys, int loops_num);
|
||||
Array<int> build_loop_to_poly_map(Span<MPoly> polys, int loops_num);
|
||||
|
||||
Array<Vector<int>> build_vert_to_edge_map(Span<MEdge> edges, int verts_num);
|
||||
Array<Vector<int>> build_vert_to_corner_map(Span<MLoop> loops, int verts_num);
|
||||
Array<Vector<int>> build_vert_to_loop_map(Span<MLoop> loops, int verts_num);
|
||||
|
||||
inline int previous_poly_corner(const MPoly &poly, int corner_i)
|
||||
inline int previous_poly_loop(const MPoly &poly, int loop_i)
|
||||
{
|
||||
return corner_i - 1 + (corner_i == poly.loopstart) * poly.totloop;
|
||||
return loop_i - 1 + (loop_i == poly.loopstart) * poly.totloop;
|
||||
}
|
||||
|
||||
} // namespace blender::mesh_topology
|
||||
|
|
|
@ -127,6 +127,7 @@ typedef enum ModifierApplyFlag {
|
|||
* See `OBJECT_OT_modifier_apply` operator. */
|
||||
MOD_APPLY_TO_BASE_MESH = 1 << 4,
|
||||
} ModifierApplyFlag;
|
||||
ENUM_OPERATORS(ModifierApplyFlag, MOD_APPLY_TO_BASE_MESH);
|
||||
|
||||
typedef struct ModifierUpdateDepsgraphContext {
|
||||
struct Scene *scene;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -54,12 +54,13 @@ void multires_modifier_update_hidden(struct DerivedMesh *dm);
|
|||
*/
|
||||
void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob);
|
||||
|
||||
typedef enum {
|
||||
typedef enum MultiresFlags {
|
||||
MULTIRES_USE_LOCAL_MMD = 1,
|
||||
MULTIRES_USE_RENDER_PARAMS = 2,
|
||||
MULTIRES_ALLOC_PAINT_MASK = 4,
|
||||
MULTIRES_IGNORE_SIMPLIFY = 8,
|
||||
} MultiresFlags;
|
||||
ENUM_OPERATORS(MultiresFlags, MULTIRES_IGNORE_SIMPLIFY);
|
||||
|
||||
struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
|
||||
struct MultiresModifierData *mmd,
|
||||
|
|
|
@ -246,6 +246,24 @@ float BKE_nlastrip_compute_frame_from_previous_strip(struct NlaStrip *strip);
|
|||
*/
|
||||
float BKE_nlastrip_compute_frame_to_next_strip(struct NlaStrip *strip);
|
||||
|
||||
/**
|
||||
* Returns the next strip in this strip's NLA track, or a null pointer.
|
||||
*
|
||||
* \param strip The strip to find the next trip from.
|
||||
* \param check_transitions Whether or not to skip transitions.
|
||||
* \return The next strip in the track, or NULL if none are present.
|
||||
*/
|
||||
struct NlaStrip *BKE_nlastrip_next_in_track(struct NlaStrip *strip, bool skip_transitions);
|
||||
|
||||
/**
|
||||
* Returns the previous strip in this strip's NLA track, or a null pointer.
|
||||
*
|
||||
* \param strip The strip to find the previous trip from.
|
||||
* \param check_transitions Whether or not to skip transitions.
|
||||
* \return The previous strip in the track, or NULL if none are present.
|
||||
*/
|
||||
struct NlaStrip *BKE_nlastrip_prev_in_track(struct NlaStrip *strip, bool skip_transitions);
|
||||
|
||||
/* ............ */
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
/* Thread sync primitives used directly. */
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -32,7 +33,7 @@ struct SubsurfModifierData;
|
|||
|
||||
/**************************** External *****************************/
|
||||
|
||||
typedef enum {
|
||||
typedef enum SubsurfFlags {
|
||||
SUBSURF_USE_RENDER_PARAMS = 1,
|
||||
SUBSURF_IS_FINAL_CALC = 2,
|
||||
SUBSURF_FOR_EDIT_MODE = 4,
|
||||
|
@ -41,6 +42,7 @@ typedef enum {
|
|||
SUBSURF_USE_GPU_BACKEND = 32,
|
||||
SUBSURF_IGNORE_SIMPLIFY = 64,
|
||||
} SubsurfFlags;
|
||||
ENUM_OPERATORS(SubsurfFlags, SUBSURF_IGNORE_SIMPLIFY);
|
||||
|
||||
struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
|
||||
struct SubsurfModifierData *smd,
|
||||
|
|
|
@ -226,7 +226,7 @@ set(SRC
|
|||
intern/mesh_wrapper.cc
|
||||
intern/modifier.cc
|
||||
intern/movieclip.c
|
||||
intern/multires.c
|
||||
intern/multires.cc
|
||||
intern/multires_reshape.c
|
||||
intern/multires_reshape_apply_base.c
|
||||
intern/multires_reshape_ccg.c
|
||||
|
@ -270,14 +270,14 @@ set(SRC
|
|||
intern/scene.cc
|
||||
intern/screen.c
|
||||
intern/shader_fx.c
|
||||
intern/shrinkwrap.c
|
||||
intern/shrinkwrap.cc
|
||||
intern/simulation.cc
|
||||
intern/softbody.c
|
||||
intern/sound.c
|
||||
intern/speaker.c
|
||||
intern/studiolight.c
|
||||
intern/subdiv.c
|
||||
intern/subdiv_ccg.c
|
||||
intern/subdiv_ccg.cc
|
||||
intern/subdiv_ccg_mask.c
|
||||
intern/subdiv_ccg_material.c
|
||||
intern/subdiv_converter.c
|
||||
|
@ -288,7 +288,7 @@ set(SRC
|
|||
intern/subdiv_eval.c
|
||||
intern/subdiv_foreach.c
|
||||
intern/subdiv_mesh.cc
|
||||
intern/subdiv_modifier.c
|
||||
intern/subdiv_modifier.cc
|
||||
intern/subdiv_stats.c
|
||||
intern/subdiv_topology.c
|
||||
intern/subsurf_ccg.c
|
||||
|
|
|
@ -3198,7 +3198,7 @@ static void animsys_create_action_track_strip(const AnimData *adt,
|
|||
* (which making new strips doesn't do due to the troublesome nature of that). */
|
||||
calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
|
||||
r_action_strip->start = r_action_strip->actstart;
|
||||
r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
|
||||
r_action_strip->end = IS_EQF(r_action_strip->actstart, r_action_strip->actend) ?
|
||||
(r_action_strip->actstart + 1.0f) :
|
||||
(r_action_strip->actend);
|
||||
|
||||
|
|
|
@ -301,12 +301,22 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
}
|
||||
|
||||
/* check if there's any point in calculating for this vert */
|
||||
if (armature_weight == 0.0f) {
|
||||
return;
|
||||
}
|
||||
if (vert_coords_prev) {
|
||||
if (prevco_weight == 1.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the coord we work on */
|
||||
co = vert_coords_prev ? vert_coords_prev[i] : vert_coords[i];
|
||||
/* get the coord we work on */
|
||||
co = vert_coords_prev[i];
|
||||
}
|
||||
else {
|
||||
if (armature_weight == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the coord we work on */
|
||||
co = vert_coords[i];
|
||||
}
|
||||
|
||||
/* Apply the object's matrix */
|
||||
mul_m4_v3(data->premat, co);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
bUserMenu *BKE_blender_user_menu_find(ListBase *lb, char space_type, const char *context)
|
||||
{
|
||||
LISTBASE_FOREACH (bUserMenu *, um, lb) {
|
||||
if ((space_type == um->space_type) && (STREQ(context, um->context))) {
|
||||
if ((space_type == um->space_type) && STREQ(context, um->context)) {
|
||||
return um;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -713,10 +713,8 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params,
|
|||
plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]);
|
||||
}
|
||||
|
||||
if ((!isect_plane_plane_v3(
|
||||
plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no)) ||
|
||||
(!isect_plane_plane_v3(
|
||||
plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no))) {
|
||||
if (!isect_plane_plane_v3(plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no) ||
|
||||
!isect_plane_plane_v3(plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
|||
DM_TYPE_CDDM,
|
||||
mesh->totvert,
|
||||
mesh->totedge,
|
||||
0 /* mesh->totface */,
|
||||
0 /* `mesh->totface` */,
|
||||
mesh->totloop,
|
||||
mesh->totpoly);
|
||||
|
||||
|
@ -213,7 +213,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
|||
&dm->faceData,
|
||||
cddata_masks.fmask | CD_MASK_ORIGINDEX,
|
||||
alloctype,
|
||||
0 /* mesh->totface */);
|
||||
0 /* `mesh->totface` */);
|
||||
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
|
||||
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
|
||||
|
||||
|
|
|
@ -1130,7 +1130,7 @@ static void cloth_update_springs(ClothModifierData *clmd)
|
|||
* because implicit solver would need reset! */
|
||||
|
||||
/* Activate / Deactivate existing springs */
|
||||
if ((!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED)) &&
|
||||
if (!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED) &&
|
||||
(cloth->verts[spring->ij].goal > ALMOST_ZERO)) {
|
||||
spring->flags &= ~CLOTH_SPRING_FLAG_DEACTIVATE;
|
||||
}
|
||||
|
|
|
@ -949,7 +949,7 @@ bool BKE_collection_has_object(Collection *collection, const Object *ob)
|
|||
return false;
|
||||
}
|
||||
|
||||
return (BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob)));
|
||||
return BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
|
||||
}
|
||||
|
||||
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
|
||||
|
@ -959,7 +959,7 @@ bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
|
|||
}
|
||||
|
||||
const ListBase objects = BKE_collection_object_cache_get(collection);
|
||||
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
|
||||
return BLI_findptr(&objects, ob, offsetof(Base, object));
|
||||
}
|
||||
|
||||
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob)
|
||||
|
@ -969,7 +969,7 @@ bool BKE_collection_has_object_recursive_instanced(Collection *collection, Objec
|
|||
}
|
||||
|
||||
const ListBase objects = BKE_collection_object_cache_instanced_get(collection);
|
||||
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
|
||||
return BLI_findptr(&objects, ob, offsetof(Base, object));
|
||||
}
|
||||
|
||||
static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *collection)
|
||||
|
|
|
@ -1738,7 +1738,7 @@ void BKE_scopes_update(Scopes *scopes,
|
|||
}
|
||||
|
||||
/* hmmmm */
|
||||
if (!(ELEM(ibuf->channels, 3, 4))) {
|
||||
if (!ELEM(ibuf->channels, 3, 4)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -634,7 +634,7 @@ ListBase CTX_data_dir_get(const bContext *C)
|
|||
|
||||
bool CTX_data_equals(const char *member, const char *str)
|
||||
{
|
||||
return (STREQ(member, str));
|
||||
return STREQ(member, str);
|
||||
}
|
||||
|
||||
bool CTX_data_dir(const char *member)
|
||||
|
|
|
@ -464,7 +464,7 @@ static std::string to_manifest(const CryptomatteLayer *layer)
|
|||
else {
|
||||
manifest << ",";
|
||||
}
|
||||
manifest << quoted(item.key) << ":\"" << (item.value.hex_encoded()) << "\"";
|
||||
manifest << quoted(item.key) << ":\"" << item.value.hex_encoded() << "\"";
|
||||
}
|
||||
manifest << "}";
|
||||
return manifest.str();
|
||||
|
|
|
@ -1935,7 +1935,7 @@ static void calc_bevel_sin_cos(
|
|||
t02 = M_PI_2;
|
||||
}
|
||||
else {
|
||||
t02 = (saacos(t02)) / 2.0f;
|
||||
t02 = saacos(t02) / 2.0f;
|
||||
}
|
||||
|
||||
t02 = sinf(t02);
|
||||
|
@ -4085,12 +4085,12 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
|
|||
}
|
||||
|
||||
if (bezt->h1 == HD_VECT) {
|
||||
if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) {
|
||||
if (!(flag & SEL_F1) != !(flag & SEL_F2)) {
|
||||
bezt->h1 = HD_FREE;
|
||||
}
|
||||
}
|
||||
if (bezt->h2 == HD_VECT) {
|
||||
if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) {
|
||||
if (!(flag & SEL_F3) != !(flag & SEL_F2)) {
|
||||
bezt->h2 = HD_FREE;
|
||||
}
|
||||
}
|
||||
|
@ -5101,7 +5101,7 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
|
|||
{
|
||||
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
|
||||
ListBase temp_nurb_lb = {nullptr, nullptr};
|
||||
const bool is_font = (BLI_listbase_is_empty(nurb_lb)) && (cu->len != 0);
|
||||
const bool is_font = BLI_listbase_is_empty(nurb_lb) && (cu->len != 0);
|
||||
/* For font curves we generate temp list of splines.
|
||||
*
|
||||
* This is likely to be fine, this function is not supposed to be called
|
||||
|
|
|
@ -160,7 +160,7 @@ static bool calc_curve_deform(
|
|||
/* Zero the axis which is not used,
|
||||
* the big block of text above now applies to these 3 lines.
|
||||
* The `upflag` argument may be a dummy, set so no rotation is done. */
|
||||
quat_apply_track(quat, axis, (ELEM(axis, 0, 2)) ? 1 : 0);
|
||||
quat_apply_track(quat, axis, ELEM(axis, 0, 2) ? 1 : 0);
|
||||
vec_apply_track(cent, axis);
|
||||
cent[index] = 0.0f;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ BLI_INLINE void value_dissolve(float *r_value,
|
|||
const float scale,
|
||||
const bool is_log)
|
||||
{
|
||||
*r_value = (is_log) ? (*r_value) * (powf(MIN_WETNESS, 1.0f / (1.2f * time / scale))) :
|
||||
*r_value = (is_log) ? (*r_value) * powf(MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
|
||||
(*r_value) - 1.0f / time * scale;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ static void cage_mapped_verts_callback(void *userData,
|
|||
{
|
||||
CageUserData *data = static_cast<CageUserData *>(userData);
|
||||
|
||||
if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
|
||||
if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
|
||||
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
|
||||
copy_v3_v3(data->cos_cage[index], co);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ PartDeflect *BKE_partdeflect_new(int type)
|
|||
pd->pdef_sbift = 0.2f;
|
||||
pd->pdef_sboft = 0.02f;
|
||||
pd->pdef_cfrict = 5.0f;
|
||||
pd->seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
|
||||
pd->seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
|
||||
pd->f_strength = 1.0f;
|
||||
pd->f_damp = 1.0f;
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
|
|||
|
||||
invert_qt_normalized(q1);
|
||||
mul_qt_qtqt(quat, q1, q2);
|
||||
angle = 2.0f * (saacos(quat[0]));
|
||||
angle = 2.0f * saacos(quat[0]);
|
||||
angle = fabsf(angle);
|
||||
|
||||
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
|
||||
|
|
|
@ -2204,9 +2204,9 @@ static void adaptive_domain_adjust(
|
|||
/* add to total shift */
|
||||
add_v3_v3(fds->shift_f, frame_shift_f);
|
||||
/* convert to integer */
|
||||
total_shift[0] = (int)(floorf(fds->shift_f[0]));
|
||||
total_shift[1] = (int)(floorf(fds->shift_f[1]));
|
||||
total_shift[2] = (int)(floorf(fds->shift_f[2]));
|
||||
total_shift[0] = (int)floorf(fds->shift_f[0]);
|
||||
total_shift[1] = (int)floorf(fds->shift_f[1]);
|
||||
total_shift[2] = (int)floorf(fds->shift_f[2]);
|
||||
int temp_shift[3];
|
||||
copy_v3_v3_int(temp_shift, fds->shift);
|
||||
sub_v3_v3v3_int(new_shift, total_shift, fds->shift);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_mapping.h"
|
||||
|
||||
#include "FN_multi_function_builder.hh"
|
||||
|
||||
|
@ -213,11 +214,15 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
|
|||
}
|
||||
|
||||
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
|
||||
for (const int vert_index : IndexRange(mesh.totvert)) {
|
||||
if (loose_verts[vert_index]) {
|
||||
r_values[vert_index] = false;
|
||||
/* The record fact says that the value is true.
|
||||
*Writing to the array from different threads is okay because each thread sets the same value. */
|
||||
threading::parallel_for(loose_verts.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int vert_index : range) {
|
||||
if (loose_verts[vert_index]) {
|
||||
r_values[vert_index] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray &varray)
|
||||
|
@ -413,16 +418,16 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
|
|||
const Span<MLoop> loops = mesh.loops();
|
||||
|
||||
r_values.fill(false);
|
||||
for (const int poly_index : polys.index_range()) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
if (old_values[poly_index]) {
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const MLoop &loop = loops[loop_index];
|
||||
const int vert_index = loop.v;
|
||||
r_values[vert_index] = true;
|
||||
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int poly_index : range) {
|
||||
if (old_values[poly_index]) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
|
||||
r_values[loop.v] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static GVArray adapt_mesh_domain_face_to_point(const Mesh &mesh, const GVArray &varray)
|
||||
|
@ -502,16 +507,16 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
|
|||
const Span<MLoop> loops = mesh.loops();
|
||||
|
||||
r_values.fill(false);
|
||||
for (const int poly_index : polys.index_range()) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
if (old_values[poly_index]) {
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const MLoop &loop = loops[loop_index];
|
||||
const int edge_index = loop.e;
|
||||
r_values[edge_index] = true;
|
||||
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int poly_index : range) {
|
||||
if (old_values[poly_index]) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
|
||||
r_values[loop.e] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &varray)
|
||||
|
@ -619,7 +624,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
|
|||
|
||||
/* For every corner, mix the values from the adjacent edges on the face. */
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
|
||||
const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
|
||||
const MLoop &loop = loops[loop_index];
|
||||
const MLoop &loop_prev = loops[loop_index_prev];
|
||||
mixer.mix_in(loop_index, old_values[loop.e]);
|
||||
|
@ -642,17 +647,19 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
|
|||
|
||||
r_values.fill(false);
|
||||
|
||||
for (const int poly_index : polys.index_range()) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
|
||||
const MLoop &loop = loops[loop_index];
|
||||
const MLoop &loop_prev = loops[loop_index_prev];
|
||||
if (old_values[loop.e] && old_values[loop_prev.e]) {
|
||||
r_values[loop_index] = true;
|
||||
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int poly_index : range) {
|
||||
const MPoly &poly = polys[poly_index];
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
|
||||
const MLoop &loop = loops[loop_index];
|
||||
const MLoop &loop_prev = loops[loop_index_prev];
|
||||
if (old_values[loop.e] && old_values[loop_prev.e]) {
|
||||
r_values[loop_index] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static GVArray adapt_mesh_domain_edge_to_corner(const Mesh &mesh, const GVArray &varray)
|
||||
|
@ -697,14 +704,18 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
|
|||
BLI_assert(r_values.size() == mesh.totvert);
|
||||
const Span<MEdge> edges = mesh.edges();
|
||||
|
||||
/* Multiple threads can write to the same index here, but they are only
|
||||
* writing true, and writing to single bytes is expected to be threadsafe. */
|
||||
r_values.fill(false);
|
||||
for (const int edge_index : edges.index_range()) {
|
||||
const MEdge &edge = edges[edge_index];
|
||||
if (old_values[edge_index]) {
|
||||
r_values[edge.v1] = true;
|
||||
r_values[edge.v2] = true;
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int edge_index : range) {
|
||||
if (old_values[edge_index]) {
|
||||
const MEdge &edge = edges[edge_index];
|
||||
r_values[edge.v1] = true;
|
||||
r_values[edge.v2] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray &varray)
|
||||
|
|
|
@ -83,8 +83,8 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
|
|||
/* Apply local layer transform to all frames. Calc the active frame is not enough
|
||||
* because onion skin can use more frames. This is more slow but required here. */
|
||||
if (gpl_dst->actframe != NULL) {
|
||||
bool transformed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
|
||||
(!is_one_v3(gpl_dst->scale)));
|
||||
bool transformed = (!is_zero_v3(gpl_dst->location) || !is_zero_v3(gpl_dst->rotation) ||
|
||||
!is_one_v3(gpl_dst->scale));
|
||||
if (transformed) {
|
||||
loc_eul_size_to_mat4(
|
||||
gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
|
||||
|
@ -2013,7 +2013,7 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
|
|||
/* Read secondary material to compare with primary material. */
|
||||
ma_secondary = BKE_gpencil_material(ob, idx_secondary + 1);
|
||||
if ((ma_secondary == NULL) ||
|
||||
(BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary)))) {
|
||||
BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary))) {
|
||||
continue;
|
||||
}
|
||||
gp_style_primary = ma_primary->gp_style;
|
||||
|
@ -2063,17 +2063,17 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
|
|||
rgb_to_hsv_compat_v(col, f_hsv_b);
|
||||
|
||||
/* Check stroke and fill color. */
|
||||
if ((!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold)) ||
|
||||
(!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold)) ||
|
||||
(!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold)) ||
|
||||
(!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold)) ||
|
||||
(!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold)) ||
|
||||
(!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold)) ||
|
||||
(!compare_ff(gp_style_primary->stroke_rgba[3],
|
||||
gp_style_secondary->stroke_rgba[3],
|
||||
val_threshold)) ||
|
||||
(!compare_ff(
|
||||
gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold))) {
|
||||
if (!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold) ||
|
||||
!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold) ||
|
||||
!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold) ||
|
||||
!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold) ||
|
||||
!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold) ||
|
||||
!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold) ||
|
||||
!compare_ff(gp_style_primary->stroke_rgba[3],
|
||||
gp_style_secondary->stroke_rgba[3],
|
||||
val_threshold) ||
|
||||
!compare_ff(
|
||||
gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2337,7 +2337,7 @@ bool BKE_gpencil_from_image(
|
|||
static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
|
||||
{
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
if ((gpl->viewlayername[0] != '\0') && (!STREQ(view_layer->name, gpl->viewlayername))) {
|
||||
if ((gpl->viewlayername[0] != '\0') && !STREQ(view_layer->name, gpl->viewlayername)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2412,7 +2412,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
|
|||
int cfra)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
|
||||
const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !GPENCIL_PLAY_ON(gpd));
|
||||
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
|
||||
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
|
||||
|
||||
|
@ -2444,7 +2444,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
|
|||
* generate renders, putting only selected GP layers for each View Layer.
|
||||
* This is used only in final render and never in Viewport. */
|
||||
if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
|
||||
(!STREQ(view_layer->name, gpl->viewlayername))) {
|
||||
!STREQ(view_layer->name, gpl->viewlayername)) {
|
||||
/* Do not skip masks when rendering the view-layer so that it can still be used to clip
|
||||
* other layers. Instead set their opacity to zero. */
|
||||
if (gpencil_is_layer_mask(view_layer, gpd, gpl)) {
|
||||
|
@ -2786,8 +2786,8 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
|
|||
}
|
||||
|
||||
/* Calc local layer transform. Early out if we have non-animated zero transforms. */
|
||||
bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
|
||||
(!is_one_v3(gpl->scale)));
|
||||
bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
|
||||
!is_one_v3(gpl->scale));
|
||||
float tmp_mat[4][4];
|
||||
loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
|
||||
|
@ -2834,7 +2834,7 @@ int BKE_gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_
|
|||
for (int i = 0; i < ob->totcol; i++) {
|
||||
Material *ma = BKE_object_material_get(ob, i + 1);
|
||||
if ((ma != NULL) && (ma->gp_style != NULL) &&
|
||||
(STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
|
||||
STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -722,8 +722,8 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
}
|
||||
|
||||
/* Only do layer transformations for non-zero or animated transforms. */
|
||||
bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
|
||||
(!is_one_v3(gpl->scale)));
|
||||
bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
|
||||
!is_one_v3(gpl->scale));
|
||||
float tmp_mat[4][4];
|
||||
loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
|
||||
|
@ -752,7 +752,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_orig);
|
||||
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
|
||||
(ob_orig->greasepencil_modifiers.first != NULL) &&
|
||||
(!GPENCIL_SIMPLIFY_MODIF(scene)));
|
||||
!GPENCIL_SIMPLIFY_MODIF(scene));
|
||||
if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
|
||||
BLI_assert(ob->data != NULL);
|
||||
return;
|
||||
|
@ -782,7 +782,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
const bool is_multiedit = (bool)(GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !is_render);
|
||||
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
|
||||
(ob->greasepencil_modifiers.first != NULL) &&
|
||||
(!GPENCIL_SIMPLIFY_MODIF(scene)));
|
||||
!GPENCIL_SIMPLIFY_MODIF(scene));
|
||||
if (!do_modifiers) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@ static bool do_add_image_extension(char *string,
|
|||
}
|
||||
#endif
|
||||
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc
|
||||
if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr))) {
|
||||
if (!BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr)) {
|
||||
extension = extension_test;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -824,7 +824,7 @@ bool BKE_image_render_write_exr(ReportList *reports,
|
|||
|
||||
/* We only store RGBA passes as half float, for
|
||||
* others precision loss can be problematic. */
|
||||
const bool pass_RGBA = (STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A"));
|
||||
const bool pass_RGBA = STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A");
|
||||
const bool pass_half_float = half_float && pass_RGBA;
|
||||
|
||||
/* Color-space conversion only happens on RGBA passes. */
|
||||
|
|
|
@ -1542,7 +1542,7 @@ static void icu_to_fcurves(ID *id,
|
|||
}
|
||||
|
||||
/* correct values, by checking if the flag of interest is set */
|
||||
if (((int)(dst->vec[1][1])) & (abp->bit)) {
|
||||
if ((int)(dst->vec[1][1]) & (abp->bit)) {
|
||||
dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -988,7 +988,7 @@ void BKE_main_view_layers_synced_ensure(const Main *bmain)
|
|||
BKE_scene_view_layers_synced_ensure(scene);
|
||||
}
|
||||
|
||||
/* NOTE: This is not (yet?) covered by the dirty tag and deffered resync system */
|
||||
/* NOTE: This is not (yet?) covered by the dirty tag and differed re-sync system */
|
||||
BKE_layer_collection_local_sync_all(bmain);
|
||||
}
|
||||
|
||||
|
|
|
@ -1389,7 +1389,7 @@ bool BKE_lib_override_library_create(Main *bmain,
|
|||
id_hierarchy_root_reference = id_root_reference;
|
||||
}
|
||||
|
||||
/* While in theory it _should_ be enough to ensure sync of given viewlayer (if any), or at least
|
||||
/* While in theory it _should_ be enough to ensure sync of given view-layer (if any), or at least
|
||||
* of given scene, think for now it's better to get a fully synced Main at this point, this code
|
||||
* may do some very wide remapping/data access in some cases. */
|
||||
BKE_main_view_layers_synced_ensure(bmain);
|
||||
|
|
|
@ -1282,8 +1282,8 @@ BLI_INLINE uint layer_bucket_index_from_xy(MaskRasterLayer *layer, const float x
|
|||
{
|
||||
BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy));
|
||||
|
||||
return ((uint)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) +
|
||||
(((uint)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x);
|
||||
return (uint)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0]) +
|
||||
((uint)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1]) * layer->buckets_x);
|
||||
}
|
||||
|
||||
static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2])
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue