Initial commit.

This commit is contained in:
hal8174 2024-04-23 10:14:24 +02:00
commit d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions

View file

@ -0,0 +1,124 @@
## Copyright 2009-2021 Intel Corporation
## SPDX-License-Identifier: Apache-2.0
IF (EMBREE_TUTORIALS_GLFW)
SET(IMGUI_LIBRARY imgui)
ENDIF()
ADD_LIBRARY(tutorial STATIC tutorial.cpp application.cpp scene.cpp tutorial_device.cpp scene_device.cpp)
TARGET_LINK_LIBRARIES(tutorial sys math lexers scenegraph lights embree tasking ${GUI_LIBRARIES})
SET_PROPERTY(TARGET tutorial PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET tutorial APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
IF (EMBREE_SYCL_SUPPORT)
ADD_LIBRARY(tutorial_sycl STATIC tutorial.cpp application.cpp scene.cpp tutorial_device.cpp scene_device.cpp)
TARGET_LINK_LIBRARIES(tutorial_sycl sys math lexers scenegraph lights_sycl embree tasking ze_wrapper ${GUI_LIBRARIES})
SET_PROPERTY(TARGET tutorial_sycl PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET tutorial_sycl APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST} ${CMAKE_CXX_FLAGS_SYCL}")
TARGET_COMPILE_DEFINITIONS(tutorial_sycl PUBLIC EMBREE_SYCL_TUTORIAL)
ENDIF()
option(EMBREE_USE_GOOGLE_BENCHMARK "Use google benchmark (note: set benchmark_DIR to benchmark_install_dir/lib/cmake/benchmark)" OFF)
option(EMBREE_BUILD_GOOGLE_BENCHMARK_FROM_SOURCE "Force to download, build, and staticly link Google Benchmark" OFF)
IF(EMBREE_USE_GOOGLE_BENCHMARK)
IF (NOT EMBREE_BUILD_GOOGLE_BENCHMARK_FROM_SOURCE)
FIND_PACKAGE(benchmark QUIET)
ENDIF()
IF(NOT benchmark_FOUND)
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
MESSAGE("-- google benchmark installation not found. download and build from source")
INCLUDE(FetchContent)
SET(FETCHCONTENT_QUIET OFF)
SET(BENCHMARK_BUILD_32_BITS OFF CACHE INTERNAL "")
SET(BENCHMARK_DOWNLOAD_DEPENDENCIES ON CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_ASSEMBLY_TESTS OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_DOXYGEN OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_EXCEPTIONS ON CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_INSTALL OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_LIBPFM OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_LTO OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "")
SET(BENCHMARK_ENABLE_WERROR ON CACHE INTERNAL "")
SET(BENCHMARK_FORCE_WERROR OFF CACHE INTERNAL "")
SET(BENCHMARK_INSTALL_DOCS OFF CACHE INTERNAL "")
SET(BENCHMARK_USE_BUNDLED_GTEST OFF CACHE INTERNAL "")
SET(BENCHMARK_USE_LIBCXX OFF CACHE INTERNAL "")
SET(BUILD_GMOCK OFF CACHE INTERNAL "")
FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.7.1
)
FetchContent_GetProperties(benchmark)
if(NOT benchmark_POPULATED)
FetchContent_Populate(benchmark)
# We want to build google benchmark and link statically, so no need to
# install it as part of the Embree install targets.
add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
MARK_AS_ADVANCED(FETCHCONTENT_BASE_DIR)
MARK_AS_ADVANCED(FETCHCONTENT_FULLY_DISCONNECTED)
MARK_AS_ADVANCED(FETCHCONTENT_QUIET)
MARK_AS_ADVANCED(FETCHCONTENT_UPDATES_DISCONNECTED)
MARK_AS_ADVANCED(FETCHCONTENT_SOURCE_DIR_BENCHMARK)
MARK_AS_ADVANCED(FETCHCONTENT_UPDATES_DISCONNECTED_BENCHMARK)
ELSE()
MESSAGE("-- google benchmark installation at ${benchmark_DIR}.")
ENDIF()
ENDIF()
ADD_LIBRARY(embree_benchmark STATIC benchmark.cpp)
SET_PROPERTY(TARGET embree_benchmark PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET embree_benchmark APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
IF(EMBREE_USE_GOOGLE_BENCHMARK)
TARGET_COMPILE_DEFINITIONS(embree_benchmark PUBLIC USE_GOOGLE_BENCHMARK)
TARGET_LINK_LIBRARIES(embree_benchmark benchmark::benchmark benchmark::benchmark_main)
ENDIF()
TARGET_LINK_LIBRARIES(tutorial embree_benchmark)
IF (EMBREE_SYCL_SUPPORT)
TARGET_LINK_LIBRARIES(tutorial_sycl embree_benchmark)
ENDIF()
ADD_LIBRARY(noise STATIC noise.cpp)
SET_PROPERTY(TARGET noise PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET noise APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
IF (EMBREE_ISPC_SUPPORT)
ADD_ISPC_LIBRARY(tutorial_ispc STATIC tutorial.cpp application.cpp scene.cpp tutorial_device.ispc scene_device.cpp tasksys.cpp)
TARGET_LINK_LIBRARIES(tutorial_ispc sys math lexers scenegraph lights_ispc embree tasking ${GUI_LIBRARIES})
SET_PROPERTY(TARGET tutorial_ispc PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET tutorial_ispc APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
ADD_ISPC_LIBRARY(noise_ispc STATIC noise.ispc)
SET_TARGET_PROPERTIES(noise_ispc PROPERTIES LINKER_LANGUAGE CXX)
SET_PROPERTY(TARGET noise_ispc PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET noise_ispc APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
TARGET_LINK_LIBRARIES(tutorial_ispc embree_benchmark)
ENDIF()
IF(WIN32)
GET_TARGET_PROPERTY(DLL_PATH_RELEASE tasking IMPORTED_LOCATION_RELEASE)
GET_TARGET_PROPERTY(DLL_PATH_DEBUG tasking IMPORTED_LOCATION_DEBUG)
IF (DLL_PATH_DEBUG OR DLL_PATH_RELEASE)
SET(DLL_PATH $<$<CONFIG:Debug>:${DLL_PATH_DEBUG}>$<$<NOT:$<CONFIG:Debug>>:${DLL_PATH_RELEASE}>)
ADD_CUSTOM_COMMAND(TARGET tutorial POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_PATH} $<TARGET_FILE_DIR:tutorial>
COMMENT "Copying TBB DLL" VERBATIM
)
ENDIF()
ENDIF()
ADD_CUSTOM_COMMAND(TARGET tutorial POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/../../models" "$<TARGET_FILE_DIR:tutorial>/models"
COMMENT "Copying example models")

View file

@ -0,0 +1,187 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "application.h"
#if defined(_WIN32)
# include <stdio.h>
# include <conio.h>
# include <windows.h>
#endif
namespace embree
{
Application* Application::instance = nullptr;
void waitForKeyPressedUnderWindows()
{
#if defined(_WIN32)
HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(hStdOutput, &csbi)) {
printf("GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
return;
}
/* do not pause when running on a shell */
if (csbi.dwCursorPosition.X != 0 || csbi.dwCursorPosition.Y != 0)
return;
/* only pause if running in separate console window. */
printf("\n\tPress any key to exit...\n");
int ch = _getch();
_unused(ch);
#endif
}
Application::Application(int features)
: rtcore(""), verbosity(0),
features((Features)features),
log_delta(false),
start_time(getSeconds()),
last_time(start_time),
last_virtual_memory(0),
last_resident_memory(0)
{
if (instance)
throw std::runtime_error("internal error: application already created");
instance = this;
registerOption("help", [this] (Ref<ParseStream> cin, const FileName& path) {
printCommandLineHelp();
exit(1);
}, "--help: prints help for all supported command line options");
if (features & FEATURE_RTCORE)
{
registerOption("rtcore", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += "," + cin->getString();
}, "--rtcore <string>: uses <string> to configure Embree device");
registerOption("threads", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += ",threads=" + toString(cin->getInt());
}, "--threads <int>: number of threads to use");
registerOption("affinity", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += ",set_affinity=1";
}, "--affinity: affinitize threads");
registerOption("set_affinity", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += ",set_affinity=" + cin->getString();
}, "--set_affinity <0/1>: enables or disables affinitizing of threads");
registerOptionAlias("set_affinity","set-affinity");
registerOption("start_threads", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += ",start_threads=" + cin->getString();
}, "--start_threads <0/1>: starts threads at device creation time if set to 1");
registerOptionAlias("start_threads","start-threads");
registerOption("verbose", [this] (Ref<ParseStream> cin, const FileName& path) {
verbosity = cin->getInt();
rtcore += ",verbose=" + toString(verbosity);
}, "--verbose <int>: sets verbosity level");
registerOption("delta", [this] (Ref<ParseStream> cin, const FileName& path) {
log_delta = true;
}, "--delta: print delta numbers in log");
registerOption("isa", [this] (Ref<ParseStream> cin, const FileName& path) {
rtcore += ",isa=" + cin->getString();
}, "--isa <string>: selects instruction set to use:\n"
" sse: select SSE codepath\n"
" sse2: select SSE2 codepath\n"
" sse3: select SSE3 codepath\n"
" ssse3: select SSSE3 codepath\n"
" sse4.1: select SSE4.1 codepath\n"
" sse4.2: select SSE4.2 codepath\n"
" avx: select AVX codepath\n"
" avxi: select AVXI codepath\n"
" avx2: select AVX2 codepath\n"
" avx512: select AVX512 codepath\n");
}
}
Application::~Application()
{
assert(instance == this);
instance = nullptr;
}
void Application::log(int verbose, const std::string& str)
{
if (verbosity < verbose)
return;
double time = getSeconds();
ssize_t virtual_memory = getVirtualMemoryBytes();
ssize_t resident_memory = getResidentMemoryBytes();
double log_time = log_delta ? time-last_time : time-start_time;
ssize_t log_virtual_memory = log_delta ? virtual_memory-last_virtual_memory : virtual_memory;
ssize_t log_resident_memory = log_delta ? resident_memory-last_resident_memory : resident_memory;
std::cout << "[ "
<< std::setw(8) << std::setprecision(3) << std::fixed << log_time << "s, "
<< std::setw(8) << std::setprecision(2) << std::fixed << double(log_virtual_memory)/1E6 << " MB virtual, "
<< std::setw(8) << std::setprecision(2) << std::fixed << double(log_resident_memory)/1E6 << " MB resident ] "
<< str << std::fixed
<< std::endl << std::flush;
last_time = time;
last_virtual_memory = virtual_memory;
last_resident_memory = resident_memory;
}
void CommandLineParser::registerOptionAlias(const std::string& name, const std::string& alternativeName) {
commandLineOptionMap[alternativeName] = commandLineOptionMap[name];
}
void CommandLineParser::parseCommandLine(int argc, char** argv)
{
/* create stream for parsing */
Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv));
/* parse command line */
parseCommandLine(stream, FileName());
}
void CommandLineParser::parseCommandLine(Ref<ParseStream> cin, const FileName& path)
{
while (true)
{
std::string tag = cin->getString();
if (tag == "") return;
std::string tag0 = tag;
/* remove - or -- and lookup command line option */
if (tag.find("-") == 0)
{
tag = tag.substr(1);
if (tag.find("-") == 0) tag = tag.substr(1);
auto option = commandLineOptionMap.find(tag);
/* process command line option */
if (option != commandLineOptionMap.end()) {
option->second->parse(cin,path);
continue;
}
}
if (verbosity != SILENT) {
/* handle unknown command line options */
std::cerr << "unknown command line parameter: " << tag0 << " ";
while (cin->peek() != "" && cin->peek()[0] != '-') std::cerr << cin->getString() << " ";
std::cerr << std::endl;
}
}
}
void CommandLineParser::printCommandLineHelp()
{
for (auto& c : commandLineOptionList) {
std::cout << c->description << std::endl;
}
}
}

View file

@ -0,0 +1,127 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../default.h"
namespace embree
{
void waitForKeyPressedUnderWindows();
struct CommandLineParser
{
enum Verbosity {
NORMAL = 0,
SILENT
};
CommandLineParser(Verbosity verbosity = NORMAL) : verbosity(verbosity) {}
/* virtual interface for command line option processing */
struct CommandLineOption : public RefCount
{
CommandLineOption (const std::string& description)
: description(description) {}
virtual void parse(Ref<ParseStream> cin, const FileName& path) = 0;
std::string description;
};
/* helper class to provide parsing function via lambda function */
template<typename F>
struct CommandLineOptionClosure : public CommandLineOption
{
CommandLineOptionClosure (std::string description, const F& f)
: CommandLineOption(description), f(f) {}
virtual void parse(Ref<ParseStream> cin, const FileName& path) {
f(cin,path);
}
F f;
};
/* registers a command line option */
template<typename F>
void registerOption(const std::string& name, const F& f, const std::string& description)
{
Ref<CommandLineOption> closure = new CommandLineOptionClosure<F>(description,f);
commandLineOptionList.push_back(closure);
commandLineOptionMap[name] = closure;
}
/* registers an alias for a command line option */
void registerOptionAlias(const std::string& name, const std::string& alternativeName);
/* command line parsing */
void parseCommandLine(int argc, char** argv);
void parseCommandLine(Ref<ParseStream> cin, const FileName& path);
/* prints help for all supported command line options */
void printCommandLineHelp();
/* command line options database */
std::vector< Ref<CommandLineOption> > commandLineOptionList;
std::map<std::string,Ref<CommandLineOption> > commandLineOptionMap;
Verbosity verbosity;
};
class Application
{
public:
enum Features { FEATURE_RTCORE = 1, FEATURE_SYCL = 4 };
Application (int features);
virtual ~Application();
static Application* instance;
/* print log message */
void log(int verbose, const std::string& str);
template<typename F>
void registerOption(const std::string& name, const F& f, const std::string& description) {
commandLineParser.registerOption<F>(name, f, description);
}
/* registers an alias for a command line option */
void registerOptionAlias(const std::string& name, const std::string& alternativeName) {
commandLineParser.registerOptionAlias(name, alternativeName);
}
/* command line parsing */
void parseCommandLine(int argc, char** argv) {
commandLineParser.parseCommandLine(argc, argv);
}
void parseCommandLine(Ref<ParseStream> cin, const FileName& path) {
commandLineParser.parseCommandLine(cin, path);
}
/* prints help for all supported command line options */
void printCommandLineHelp() {
commandLineParser.printCommandLineHelp();
}
public:
/* virtual main function, contains all tutorial logic */
virtual int main(int argc, char** argv) = 0;
public:
std::string rtcore; // embree configuration
int verbosity; // verbosity of output
Features features;
CommandLineParser commandLineParser;
public:
bool log_delta; // whether to print delta stats
double start_time; // start time of application
double last_time; // last log time of application
ssize_t last_virtual_memory; // last virtual memory usage
ssize_t last_resident_memory; // last resident memory usage
};
}

View file

@ -0,0 +1,257 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <sstream>
#include <fstream>
#include <memory>
#include "benchmark.h"
#ifdef USE_GOOGLE_BENCHMARK
#include <benchmark/benchmark.h>
#endif
namespace embree {
//////////////////////////////////////////////
// util functions for command line handling //
//////////////////////////////////////////////
struct CommandLine
{
typedef std::unordered_set<std::unique_ptr<std::string>> StringPool;
typedef std::unordered_set<std::unique_ptr<std::vector<char*>>> CommandLinePool;
static StringPool string_pool;
static CommandLinePool command_line_pool;
CommandLine() : cl(nullptr) { }
CommandLine(int argc, char** argv) : cl(nullptr)
{
auto cl_iter = command_line_pool.emplace(std::unique_ptr<std::vector<char*>>(new std::vector<char*>()));
cl = cl_iter.first->get();
for (size_t i = 0; i < argc; ++i) {
auto pair = string_pool.emplace(std::unique_ptr<std::string>{new std::string(argv[i])});
cl->emplace_back(&(*pair.first->get())[0]);
}
}
void add(std::vector<std::string> const& args)
{
for (std::string const& str : args) {
auto pair = string_pool.emplace(std::unique_ptr<std::string>{new std::string(str)});
cl->emplace_back(&(*pair.first->get())[0]);
}
}
int argc() { return cl->size(); }
char** argv() { return cl->data(); }
private:
std::vector<char*>* cl;
};
CommandLine::StringPool CommandLine::string_pool;
CommandLine::CommandLinePool CommandLine::command_line_pool;
bool endsWith(std::string const &str, std::string const &suffix)
{
if (str.length() <= suffix.length())
return false;
return str.substr(str.length() - suffix.length(), str.length() - 1) == suffix;
}
bool startsWith(std::string const &str, std::string const &prefix)
{
if (str.length() <= prefix.length())
return false;
return (str.rfind(prefix, 0) == 0);
}
std::string removeQuotes(std::string const &str)
{
std::string res = str;
if (startsWith(res, "\""))
res = res.substr(1, res.length());
if (endsWith(res, "\""))
res = res.substr(0, res.length() - 1);
return res;
}
std::string getFileName(std::string const &path)
{
const size_t b = (path.rfind("/") == std::string::npos) ? 0 : path.rfind("/") + 1;
return path.substr(b, path.rfind(".") - b);
}
void printCommandLine(int argc, char** argv)
{
for (int i = 0; i < argc; ++i)
std::cout << argv[i] << (i < argc-1 ? " " : "");
if (argc > 0) std::cout << std::endl;
}
//////////////////////////////////////////////
//////////////////////////////////////////////
int TutorialBenchmark::main(int argc, char** argv, std::string name)
{
commandLineParser.parseCommandLine(argc, argv);
updateCommandLine(argc, argv);
CommandLine commandLine(argc, argv);
#if USE_GOOGLE_BENCHMARK
if (!params.legacy && params.minTimeOrIterations > 0)
commandLine.add({"--benchmark_min_time=" + std::to_string(params.minTimeOrIterations)});
if (!params.legacy && params.repetitions > 0)
commandLine.add({"--benchmark_repetitions=" + std::to_string(params.repetitions)});
#endif
argc = commandLine.argc();
argv = commandLine.argv();
#ifdef USE_GOOGLE_BENCHMARK
if (!params.legacy)
::benchmark::Initialize(&argc, argv);
#endif
commandLine = CommandLine(argc, argv);
postParseCommandLine();
std::string benchmark_name = name;
if (endsWith(inputFile, ".xml")) {
benchmark_name = getFileName(inputFile);
}
else if (endsWith(inputFile, ".ecs")) {
benchmark_name = getFileName(inputFile);
}
if (params.name != "")
benchmark_name = params.name;
registerBenchmark(benchmark_name, commandLine.argc(), commandLine.argv());
#ifdef USE_GOOGLE_BENCHMARK
if (!params.legacy)
::benchmark::RunSpecifiedBenchmarks();
#endif
return 0;
}
// remove the processed commdand line options
void TutorialBenchmark::updateCommandLine(int& argc, char** argv)
{
for (std::string const& str : processedCommandLineOptions)
{
for (int i = 0; i < argc; ++i) {
if (std::string(argv[i]) == str) {
int remove = 1;
int j = i+1;
while(j < argc && !startsWith(std::string(argv[j]), "-")) {
remove++;
j++;
}
argc -= remove;
for (j = i; j < argc; ++j) {
argv[j] = argv[j+remove];
}
}
}
}
}
void TutorialBenchmark::postParseCommandLine()
{
}
void callBenchFunc(benchmark::State& state, int argc, char** argv, BenchParams benchParams, BenchFunc benchFunc)
{
BenchState benchState;
benchState.state = &state;
benchFunc(benchState, benchParams, argc, argv);
}
void TutorialBenchmark::registerBenchmark(std::string const& name, int argc, char** argv)
{
#ifdef USE_GOOGLE_BENCHMARK
if (params.legacy) {
std::cout << "BENCHMARK SCENE: " << name << std::endl;
BenchState benchState;
func(benchState, params, argc, argv);
}
else {
::benchmark::RegisterBenchmark(name.c_str(), callBenchFunc, argc, argv, params, func)->Unit(::benchmark::TimeUnit::kMillisecond);
}
#else
std::cout << "BENCHMARK SCENE: " << name << std::endl;
BenchState benchState;
func(benchState, params, argc, argv);
#endif
}
void callBuildBenchFunc(benchmark::State& state, int argc, char** argv, BenchParams benchParams, BuildBenchParams buildBenchParams, BuildBenchFunc buildBenchFunc)
{
BenchState benchState;
benchState.state = &state;
buildBenchFunc(benchState, benchParams, buildBenchParams, argc, argv);
}
void TutorialBuildBenchmark::registerBuildBenchmark(std::string name, BuildBenchType buildBenchType, int argc, char** argv)
{
if (buildParams.buildBenchType & buildBenchType) {
// attach benchmark name if more than one bit in buildBenchMask is set
bool attach = (buildParams.buildBenchType & (buildParams.buildBenchType - 1)) != 0;
if (attach) name += "_" + getBuildBenchTypeString(buildBenchType);
BuildBenchParams p = buildParams;
p.buildBenchType = buildBenchType;
#ifdef USE_GOOGLE_BENCHMARK
if (params.legacy) {
std::cout << "BENCHMARK SCENE: " << name << std::endl;
BenchState benchState;
buildBenchFunc(benchState, params, p, argc, argv);
}
else {
::benchmark::RegisterBenchmark(name.c_str(), callBuildBenchFunc, argc, argv, params, p, buildBenchFunc)->Unit(::benchmark::TimeUnit::kMillisecond);
}
#else
std::cout << "BENCHMARK SCENE: " << name << std::endl;
BenchState benchState;
buildBenchFunc(benchState, params, p, argc, argv);
#endif
}
}
void TutorialBuildBenchmark::registerBenchmark(std::string const& name, int argc, char** argv)
{
registerBuildBenchmark(name, BuildBenchType::UPDATE_DYNAMIC_DEFORMABLE, argc, argv);
registerBuildBenchmark(name, BuildBenchType::UPDATE_DYNAMIC_DYNAMIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::UPDATE_DYNAMIC_STATIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_DYNAMIC_DEFORMABLE, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_DYNAMIC_DYNAMIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_DYNAMIC_STATIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_STATIC_STATIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_HIGH_QUALITY_STATIC_STATIC, argc, argv);
registerBuildBenchmark(name, BuildBenchType::CREATE_USER_THREADS_STATIC_STATIC, argc, argv);
}
void TutorialBuildBenchmark::postParseCommandLine()
{
if (buildParams.userThreads > 0) {
buildParams.buildBenchType = BuildBenchType::CREATE_USER_THREADS_STATIC_STATIC;
} else {
buildParams.buildBenchType = (BuildBenchType)(buildParams.buildBenchType & ~(BuildBenchType::CREATE_USER_THREADS_STATIC_STATIC));
}
}
}

View file

@ -0,0 +1,165 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "application.h"
namespace benchmark
{
class State;
}
namespace embree {
enum BuildBenchType {
UPDATE_DYNAMIC_DEFORMABLE = 1,
UPDATE_DYNAMIC_DYNAMIC = 2,
UPDATE_DYNAMIC_STATIC = 4,
CREATE_DYNAMIC_DEFORMABLE = 8,
CREATE_DYNAMIC_DYNAMIC = 16,
CREATE_DYNAMIC_STATIC = 32,
CREATE_STATIC_STATIC = 64,
CREATE_HIGH_QUALITY_STATIC_STATIC = 128,
CREATE_USER_THREADS_STATIC_STATIC = 256,
ALL = 511
};
static MAYBE_UNUSED BuildBenchType getBuildBenchType(std::string const& str)
{
if (str == "update_dynamic_deformable") return BuildBenchType::UPDATE_DYNAMIC_DEFORMABLE;
else if (str == "update_dynamic_dynamic") return BuildBenchType::UPDATE_DYNAMIC_DYNAMIC;
else if (str == "update_dynamic_static") return BuildBenchType::UPDATE_DYNAMIC_STATIC;
else if (str == "create_dynamic_deformable") return BuildBenchType::CREATE_DYNAMIC_DEFORMABLE;
else if (str == "create_dynamic_dynamic") return BuildBenchType::CREATE_DYNAMIC_DYNAMIC;
else if (str == "create_dynamic_static") return BuildBenchType::CREATE_DYNAMIC_STATIC;
else if (str == "create_static_static") return BuildBenchType::CREATE_STATIC_STATIC;
else if (str == "create_high_quality_static_static") return BuildBenchType::CREATE_HIGH_QUALITY_STATIC_STATIC;
else if (str == "create_user_threads_static_static") return BuildBenchType::CREATE_USER_THREADS_STATIC_STATIC;
return BuildBenchType::ALL;
}
static MAYBE_UNUSED std::string getBuildBenchTypeString(BuildBenchType type)
{
if (type == BuildBenchType::UPDATE_DYNAMIC_DEFORMABLE) return "update_dynamic_deformable";
else if (type == BuildBenchType::UPDATE_DYNAMIC_DYNAMIC) return "update_dynamic_dynamic";
else if (type == BuildBenchType::UPDATE_DYNAMIC_STATIC) return "update_dynamic_static";
else if (type == BuildBenchType::CREATE_DYNAMIC_DEFORMABLE) return "create_dynamic_deformable";
else if (type == BuildBenchType::CREATE_DYNAMIC_DYNAMIC) return "create_dynamic_dynamic";
else if (type == BuildBenchType::CREATE_DYNAMIC_STATIC) return "create_dynamic_static";
else if (type == BuildBenchType::CREATE_STATIC_STATIC) return "create_static_static";
else if (type == BuildBenchType::CREATE_HIGH_QUALITY_STATIC_STATIC) return "create_high_quality_static_static";
else if (type == BuildBenchType::CREATE_USER_THREADS_STATIC_STATIC) return "create_user_threads_static_static";
return "all";
}
struct BenchState {
benchmark::State* state;
};
struct BenchParams {
int skipIterations = 0;
int minTimeOrIterations = 0;
int repetitions = 0;
bool legacy = false;
std::string name = "";
};
struct BuildBenchParams {
BuildBenchType buildBenchType = BuildBenchType::ALL;
int userThreads = 0;
};
using BenchFunc = void(*)(BenchState& state, BenchParams& params, int argc, char** argv);
using BuildBenchFunc = void(*)(BenchState& state, BenchParams& params, BuildBenchParams& buildParams, int argc, char** argv);
struct TutorialBenchmark
{
static bool benchmark(int argc, char** argv) {
for (int i = 0; i < argc; ++i)
if (std::string(argv[i]) == "--benchmark")
return true;
return false;
}
TutorialBenchmark(BenchFunc func) :
commandLineParser(CommandLineParser(CommandLineParser::SILENT)),
func(func)
{
commandLineParser.registerOption("help", [this] (Ref<ParseStream> cin, const FileName& path) {
commandLineParser.printCommandLineHelp();
exit(1);
}, "--help: prints help for all supported command line options");
commandLineParser.registerOption("i", [&] (Ref<ParseStream> cin, const FileName& path) {
inputFile = cin->getString();
}, "-i <filepath>: .xml ");
commandLineParser.registerOption("c", [&] (Ref<ParseStream> cin, const FileName& path) {
inputFile = cin->getString();
}, "-c <filepath>: .ecs ");
commandLineParser.registerOption("benchmark", [&] (Ref<ParseStream> cin, const FileName& path) {
params.skipIterations = cin->getInt();
params.minTimeOrIterations = cin->getInt();
processedCommandLineOptions.push_back("--benchmark");
}, "--benchmark <N> <M>: run benchmark for M seconds (M iterations in legacy mode) with N iterations warm-up");
commandLineParser.registerOption("legacy", [&] (Ref<ParseStream> cin, const FileName& path) {
params.legacy = true;
processedCommandLineOptions.push_back("--legacy");
}, "--legacy: run old benchmark version (without google benchmark)");
commandLineParser.registerOption("benchmark_repetitions", [&] (Ref<ParseStream> cin, const FileName& path) {
params.repetitions = cin->getInt();
processedCommandLineOptions.push_back("--benchmark_repetitions");
}, "--benchmark_repetitions <R>: run R repetitions when using google benchmark");
commandLineParser.registerOption("benchmark_name", [&] (Ref<ParseStream> cin, const FileName& path) {
params.name = cin->getString();
processedCommandLineOptions.push_back("--benchmark_name");
}, "--benchmark_name <string>: override name of the benchmark");
}
TutorialBenchmark() : TutorialBenchmark(nullptr)
{
}
int main(int argc, char** argv, std::string name = "default");
protected:
CommandLineParser commandLineParser;
// remove the processed commdand line options
void updateCommandLine(int& argc, char** argv);
virtual void postParseCommandLine();
std::string inputFile = "";
std::vector<std::string> processedCommandLineOptions;
BenchParams params;
virtual void registerBenchmark(std::string const& name, int argc, char** argv);
private:
BenchFunc func;
};
struct TutorialBuildBenchmark : public TutorialBenchmark
{
TutorialBuildBenchmark(BuildBenchFunc func) : TutorialBenchmark(), buildBenchFunc(func)
{
commandLineParser.registerOption("benchmark_type", [&] (Ref<ParseStream> cin, const FileName& path) {
std::string str = cin->getString();
buildParams.buildBenchType = getBuildBenchType(str);
processedCommandLineOptions.push_back("--benchmark_type");
}, "--benchmark_type <string>: select which build types to benchmark");
commandLineParser.registerOption("user_threads", [this] (Ref<ParseStream> cin, const FileName& path) {
buildParams.userThreads = cin->getInt();
}, "--user_threads <int>: invokes user thread benchmark with specified number of application provided build threads");
}
private:
void postParseCommandLine() override;
void registerBenchmark(std::string const& name, int argc, char** argv) override;
void registerBuildBenchmark(std::string name, BuildBenchType buildBenchType, int argc, char** argv);
BuildBenchParams buildParams;
BuildBenchFunc buildBenchFunc;
};
}

View file

@ -0,0 +1,151 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "tutorial.h"
#include "statistics.h"
#include "benchmark.h"
#ifdef USE_GOOGLE_BENCHMARK
#include <benchmark/benchmark.h>
#endif
/* ray statistics */
#if !defined(TASKING_PPL) // not supported with PPL because threadIndex is not unique and atomics are too expensive
#define RAY_STATS
#endif
namespace embree
{
template<class Tutorial>
static void renderBenchmarkLegacy(BenchState& state, BenchParams& params ,int argc, char** argv);
template<class Tutorial>
static void renderBenchFunc(BenchState& state, BenchParams& params ,int argc, char** argv)
{
#ifdef USE_GOOGLE_BENCHMARK
if (params.legacy) {
renderBenchmarkLegacy<Tutorial>(state, params, argc, argv);
return;
}
Tutorial tutorial;
tutorial.interactive = false;
tutorial.main(argc,argv);
tutorial.resize(tutorial.width, tutorial.height);
ISPCCamera ispccamera = tutorial.camera.getISPCCamera(tutorial.width, tutorial.height);
for (size_t i = 0; i < params.skipIterations; i++)
{
tutorial.initRayStats();
tutorial.render(tutorial.pixels,tutorial.width,tutorial.height,0.0f,ispccamera);
}
size_t numRays = 0;
for (auto _ : *state.state)
{
tutorial.initRayStats();
tutorial.render(tutorial.pixels,tutorial.width,tutorial.height,0.0f,ispccamera);
numRays += tutorial.getNumRays();
}
state.state->SetItemsProcessed(state.state->iterations());
state.state->counters["Rays/s"] = benchmark::Counter(numRays, benchmark::Counter::kIsRate);
#else
renderBenchmarkLegacy<Tutorial>(state, params, argc, argv);
#endif
}
template<class Tutorial>
static void renderBenchmarkLegacy(BenchState& state, BenchParams& params ,int argc, char** argv)
{
Tutorial tutorial;
tutorial.interactive = false;
tutorial.main(argc,argv);
tutorial.resize(tutorial.width, tutorial.height);
ISPCCamera ispccamera = tutorial.camera.getISPCCamera(tutorial.width, tutorial.height);
IOStreamStateRestorer cout_state(std::cout);
std::cout.setf(std::ios::fixed, std::ios::floatfield);
std::cout.precision(4);
//Statistics stat;
FilteredStatistics fpsStat(0.5f,0.0f);
FilteredStatistics mraypsStat(0.5f,0.0f);
{
size_t numTotalFrames = params.skipIterations + params.minTimeOrIterations;
for (size_t i=0; i<params.skipIterations; i++)
{
tutorial.initRayStats();
double t0 = getSeconds();
tutorial.render(tutorial.pixels,tutorial.width,tutorial.height,0.0f,ispccamera);
double t1 = getSeconds();
double dt = t1-t0;
if (ispccamera.render_time != 0.0)
dt = ispccamera.render_time;
std::cout << "frame [" << std::setw(3) << i << " / " << std::setw(3) << numTotalFrames << "]: " << std::setw(8) << 1.0/dt << " fps (skipped)" << std::endl << std::flush;
}
for (size_t i=params.skipIterations; i<numTotalFrames; i++)
{
tutorial.initRayStats();
double t0 = getSeconds();
tutorial.render(tutorial.pixels,tutorial.width,tutorial.height,0.0f,ispccamera);
double t1 = getSeconds();
double dt = t1-t0;
if (ispccamera.render_time != 0.0)
dt = ispccamera.render_time;
float fps = float(1.0/dt);
fpsStat.add(fps);
float mrayps = float(double(tutorial.getNumRays())/(1000000.0*dt));
mraypsStat.add(mrayps);
if (numTotalFrames >= 1024 && (i % 64 == 0))
{
double rate = 0;
if (fpsStat.getAvg()) rate = 100.0f*fpsStat.getSigma()/fpsStat.getAvg();
std::cout << "frame [" << std::setw(3) << i << " / " << std::setw(3) << numTotalFrames << "]: "
<< std::setw(8) << fps << " fps, "
<< "min = " << std::setw(8) << fpsStat.getMin() << " fps, "
<< "avg = " << std::setw(8) << fpsStat.getAvg() << " fps, "
<< "max = " << std::setw(8) << fpsStat.getMax() << " fps, "
<< "sigma = " << std::setw(6) << fpsStat.getSigma() << " (" << rate << "%)" << std::endl << std::flush;
}
}
double rate = 0;
if (fpsStat.getAvg()) rate = 100.0f*fpsStat.getAvgSigma()/fpsStat.getAvg();
std::cout << "frame [" << std::setw(3) << params.skipIterations << " - " << std::setw(3) << numTotalFrames << "]: "
<< " "
<< "min = " << std::setw(8) << fpsStat.getMin() << " fps, "
<< "avg = " << std::setw(8) << fpsStat.getAvg() << " fps, "
<< "max = " << std::setw(8) << fpsStat.getMax() << " fps, "
<< "sigma = " << std::setw(6) << fpsStat.getAvgSigma() << " (" << rate << "%)" << std::endl;
}
std::cout << "BENCHMARK_RENDER_MIN " << fpsStat.getMin() << std::endl;
std::cout << "BENCHMARK_RENDER_AVG " << fpsStat.getAvg() << std::endl;
std::cout << "BENCHMARK_RENDER_MAX " << fpsStat.getMax() << std::endl;
std::cout << "BENCHMARK_RENDER_SIGMA " << fpsStat.getSigma() << std::endl;
std::cout << "BENCHMARK_RENDER_AVG_SIGMA " << fpsStat.getAvgSigma() << std::endl;
#if defined(RAY_STATS)
std::cout << "BENCHMARK_RENDER_MRAYPS_MIN " << mraypsStat.getMin() << std::endl;
std::cout << "BENCHMARK_RENDER_MRAYPS_AVG " << mraypsStat.getAvg() << std::endl;
std::cout << "BENCHMARK_RENDER_MRAYPS_MAX " << mraypsStat.getMax() << std::endl;
std::cout << "BENCHMARK_RENDER_MRAYPS_SIGMA " << mraypsStat.getSigma() << std::endl;
std::cout << "BENCHMARK_RENDER_MRAYPS_AVG_SIGMA " << mraypsStat.getAvgSigma() << std::endl;
#endif
std::cout << std::flush;
}
}

View file

@ -0,0 +1,140 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/sys/platform.h"
#include "../../../common/sys/ref.h"
#include "../../../common/math/emath.h"
#include "../../../common/math/vec3.h"
#include "../../../common/math/affinespace.h"
#include "../scenegraph/scenegraph.h"
#include <sstream>
namespace embree
{
/* camera settings */
struct Camera
{
enum Handedness {
LEFT_HANDED,
RIGHT_HANDED
};
struct ISPCCamera
{
public:
ISPCCamera (const AffineSpace3f& xfm)
: xfm(xfm) {}
public:
AffineSpace3f xfm;
float render_time = 0.0f;
};
public:
Camera ()
: from(0.0001f,0.0001f,-3.0f), to(0,0,0), up(0,1,0), fov(90), handedness(RIGHT_HANDED) {}
Camera (const Vec3fa& from, const Vec3fa& to, const Vec3fa& up, float fov, Handedness handedness)
: from(from), to(to), up(up), fov(fov), handedness(handedness) {}
Camera (const SceneGraph::PerspectiveCameraData& cam, Handedness handedness)
: from(cam.from), to(cam.to), up(cam.up), fov(cam.fov), handedness(handedness) {}
std::string str() const
{
std::stringstream stream;
stream.precision(10);
stream << "--vp " << from.x << " " << from.y << " " << from.z << " "
<< "--vi " << to.x << " " << to.y << " " << to.z << " "
<< "--vu " << up.x << " " << up.y << " " << up.z << " "
<< "--fov " << fov << " "
<< (handedness == LEFT_HANDED ? "--lefthanded" : "--righthanded");
return stream.str();
}
AffineSpace3fa camera2world ()
{
AffineSpace3fa local2world = AffineSpace3fa::lookat(from, to, up);
if (!(local2world == local2world))
throw std::runtime_error("invalid camera specified");
if (handedness == RIGHT_HANDED)
local2world.l.vx = -local2world.l.vx;
return local2world;
}
AffineSpace3fa world2camera () { return rcp(camera2world()); }
Vec3fa world2camera(const Vec3fa& p) { return xfmPoint(world2camera(),p); }
Vec3fa camera2world(const Vec3fa& p) { return xfmPoint(camera2world(),p); }
ISPCCamera getISPCCamera (size_t width, size_t height)
{
const float fovScale = 1.0f/tanf(deg2rad(0.5f*fov));
const AffineSpace3fa local2world = camera2world();
Vec3fa vx = local2world.l.vx;
Vec3fa vy = -local2world.l.vy;
Vec3fa vz = -0.5f*width*local2world.l.vx + 0.5f*height*local2world.l.vy + 0.5f*height*fovScale*local2world.l.vz;
Vec3fa p = local2world.p;
return ISPCCamera(AffineSpace3f(vx,vy,vz,p));
}
void move (float dx, float dy, float dz)
{
AffineSpace3fa xfm = camera2world();
Vec3fa ds = xfmVector(xfm,Vec3fa(dx,dy,dz));
from += ds;
to += ds;
}
void rotate (float dtheta, float dphi)
{
if (handedness == RIGHT_HANDED) dtheta *= -1.0f;
const Vec3fa up1 = normalize(up);
Vec3fa view1 = normalize(to-from);
view1 = xfmVector(AffineSpace3fa::rotate(up1, dtheta), view1);
const float phi = acosf(dot(view1, up1));
const float dphi2 = phi - clamp(phi-dphi, 0.001f*float(pi), 0.999f*float(pi));
view1 = xfmVector(AffineSpace3fa::rotate(cross(view1, up1), dphi2), view1);
to = from + length(to-from) * view1;
}
void rotateOrbit (float dtheta, float dphi)
{
if (handedness == RIGHT_HANDED) dtheta *= -1.0f;
const Vec3fa up1 = normalize(up);
Vec3fa view1 = normalize(to-from);
view1 = xfmVector(AffineSpace3fa::rotate(up1, dtheta), view1);
const float phi = acosf(dot(view1, up1));
const float dphi2 = phi - clamp(phi-dphi, 0.001f*float(pi), 0.999f*float(pi));
view1 = xfmVector(AffineSpace3fa::rotate(cross(view1, up1), dphi2), view1);
from = to - length(to-from) * view1;
}
void dolly (float ds)
{
float dollySpeed = 0.01f;
float k = powf((1.0f-dollySpeed), ds);
from += length(to-from) * (1-k) * normalize(to-from);
}
public:
Vec3fa from; //!< position of camera
Vec3fa to; //!< look at point
Vec3fa up; //!< up vector
float fov; //!< field of view
Handedness handedness;
};
typedef Camera::ISPCCamera ISPCCamera;
}
#if __SYCL_COMPILER_VERSION >= 20210801
namespace sycl {
template<> struct is_device_copyable<embree::Camera::ISPCCamera> : std::true_type {};
template<> struct is_device_copyable<const embree::Camera::ISPCCamera> : std::true_type {};
}
#endif

View file

@ -0,0 +1,12 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/affinespace.isph"
struct ISPCCamera
{
AffineSpace3f xfm;
float render_time;
};

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.h"
namespace embree
{
/* noise functions */
float noise(const Vec3fa& p);
Vec3fa noise3D(const Vec3fa& p);
}

View file

@ -0,0 +1,161 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "noise.isph"
static uniform int p[513] = {
151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
151
};
static uniform float g1[128] = {
-0.20707, 0.680971, -0.293328, -0.106833, -0.362614, 0.772857, -0.968834, 0.16818, -0.681263, -0.232568, 0.382009, -0.882282, 0.799709, -0.672908, -0.681857, 0.0661294, 0.208288, 0.165398, -0.460058, -0.219044, -0.413199, 0.484755, -0.402949, -0.848924, -0.190035, 0.714756, 0.883937, 0.325661, 0.692952, -0.99449, -0.0752415, 0.065192, 0.575753, -0.468776, 0.965505, -0.38643, 0.20171, 0.217431, -0.575122, 0.77179, -0.390686, -0.69628, -0.324676, -0.225046, 0.28722, 0.507107, 0.207232, 0.0632565, -0.0812794, 0.304977, -0.345638, 0.892741, -0.26392, 0.887781, -0.985143, 0.0331999, -0.454458, -0.951402, 0.183909, -0.590073, 0.755387, -0.881263, -0.478315, -0.394342, 0.78299, -0.00360388, 0.420051, -0.427172, 0.729847, 0.351081, -0.0830201, 0.919271, 0.549351, -0.246897, -0.542722, -0.290932, -0.399364, 0.339532, 0.437933, 0.131909, 0.648931, -0.218776, 0.637533, 0.688017, -0.639064, 0.886792, -0.150226, 0.0413316, -0.868712, 0.827016, 0.765169, 0.522728, -0.202155, 0.376514, 0.523097, -0.189982, -0.749498, -0.0307322, -0.555075, 0.746242, 0.0576438, -0.997172, 0.721028, -0.962605, 0.629784, -0.514232, -0.370856, 0.931465, 0.87112, 0.618863, -0.0157817, -0.559729, 0.152707, -0.421942, -0.357866, -0.477353, -0.652024, -0.996365, -0.910432, -0.517651, -0.169098, 0.403249, -0.556309, 0.00782069, -0.86594, -0.213873, -0.0410469, -0.563716
};
static uniform float g2[128*2] = {
0.605609, 0.538399, 0.796519, -0.944204, 0.908294, 0.756016, 0.0977536, -0.863638, 0.842196, -0.744751, -0.932081, 0.932392, -0.588525, 0.516884, 0.841188, -0.978497, -0.608649, -0.868011, 0.992137, -0.772425, 0.963049, -0.0478757, 0.953878, 0.889467, 0.562174, 0.624644, -0.356598, -0.520726, -0.821833, 0.99985, 0.234183, -0.9791, -0.971815, -0.0979374, -0.108159, -0.34927, -0.592124, -0.775632, 0.97228, 0.753819, 0.941608, 0.578291, 0.852108, -0.760312, -0.784772, 0.0223242, -0.606013, -0.980319, 0.252581, -0.575064, 0.884701, 0.943763, 0.737344, 0.938496, 0.0466562, -0.994566, 0.989782, 0.988368, -0.546155, 0.279211, -0.69504, 0.931229, 0.99768, -0.325874, -0.630157, -0.999936, -0.968623, -0.226805, -0.750428, -0.450961, 0.257868, 0.968011, -0.988005, -0.713965, 0.991007, -0.61059, 0.950437, -0.483042, -0.98105, -0.915356, -0.892527, -0.772958, -0.9081, 0.55692, 0.906075, 0.937419, 0.454624, -0.991582, 0.400857, 0.855933, -0.672619, 0.0713424, 0.593249, -0.378286, -0.997369, -0.827112, 0.708222, -0.995343, 0.985069, 0.698711, -0.180105, 0.999961, -0.768451, 0.993107, -0.918024, 0.0446961, 0.91882, 0.97691, -0.393915, 0.364803, 0.0495592, 0.186545, -0.461553, -0.242776, 0.901952, -0.0710866, 0.888101, 0.999935, 0.277688, 0.0554235, 0.506599, -0.299293, 0.984394, -0.999698, 0.408822, -0.782639, 0.128596, 0.198834, 0.981707, 0.864566, 0.808197, 0.352335, 0.970484, -0.667503, 0.330243, 0.208392, 0.191539, -0.938943, 0.895002, 0.910575, -0.537691, -0.98548, -0.721635, -0.335382, -0.424701, -0.960452, 0.595047, 0.783579, -0.937749, 0.529096, -0.997906, -0.581313, -0.899828, -0.88461, 0.989469, 0.91872, -0.850793, 0.955954, 0.715768, -0.736686, 0.80392, -0.717276, -0.788579, 0.987003, -0.839648, 0.885176, -0.998929, -0.0376033, -0.578371, -0.718771, 0.906081, 0.239947, -0.803563, -0.00826282, 0.991011, -0.0057943, -0.349232, 0.65319, 0.992067, -0.953535, 0.893781, 0.661689, 0.957253, -0.425442, -0.866609, 0.712892, -0.807777, 0.89632, -0.595147, -0.0224999, -0.643786, 0.545815, -0.870124, -0.696306, -0.99902, 0.773648, -0.806008, -0.931319, -0.780114, -0.552154, -0.933812, -0.563108, -0.619909, 0.966532, 0.692454, 0.993284, 0.338885, -0.75104, 0.237272, -0.713619, -0.160187, -0.199242, -0.371265, -0.781439, -0.914125, -0.944104, 0.169525, -0.984403, 0.976056, -0.265228, 0.94232, 0.993906, -0.877517, -0.89618, 0.611817, -0.106758, 0.680403, 0.163329, -0.325386, -0.0687362, -0.901164, 0.460314, 0.999981, -0.0408026, 0.850356, -0.763343, -0.170806, -0.102919, 0.581564, 0.688634, 0.284368, -0.276419, 0.616641, -0.929771, 0.927865, 0.440373, 0.153446, 0.840456, 0.996966, 0.867209, -0.135077, -0.493238, -0.577193, 0.0588088, 0.715215, 0.0143633
};
static uniform float g3[128*4] = {
-0.582745, 0.443494, -0.680971, 0, -0.601153, 0.791961, 0.106833, 0, -0.265466, 0.576385, -0.772857, 0, 0.981035, 0.0963612, -0.16818, 0, 0.524388, 0.819103, 0.232568, 0, -0.170518, -0.43875, 0.882282, 0, 0.598053, -0.435348, 0.672908, 0, 0.53956, 0.839346, -0.0661294, 0, -0.782511, -0.600267, -0.165398, 0, -0.122114, 0.968043, 0.219044, 0, -0.235567, 0.842331, -0.484755, 0, -0.158657, 0.504139, 0.848924, 0, -0.578396, 0.39317, -0.714756, 0, 0.883328, -0.337159, -0.325661, 0, 0.0597264, -0.0861552, 0.99449, 0, -0.970124, 0.233685, -0.0651921, 0, 0.208238, -0.858421, 0.468776, 0, 0.916908, -0.0997567, 0.38643, 0, -0.786568, -0.577957, -0.217431, 0, 0.14868, 0.618251, -0.77179, 0, -0.24168, 0.675858, 0.69628, 0, -0.50994, 0.83025, 0.225046, 0, -0.534183, -0.676382, -0.507107, 0, -0.793861, -0.6048, -0.0632565, 0, -0.92148, 0.240548, -0.304977, 0, -0.210037, 0.39862, -0.892741, 0, -0.310918, 0.339375, -0.887781, 0, 0.99836, 0.0466305, -0.0331999, 0, -0.0439099, 0.304806, 0.951402, 0, -0.676304, -0.440938, 0.590073, 0, 0.339805, -0.328495, 0.881263, 0, -0.0625568, 0.916832, 0.394342, 0, 0.776463, -0.630153, 0.00360388, 0, -0.224717, -0.8758, 0.427172, 0, 0.618879, -0.70266, -0.351081, 0, -0.380313, 0.101503, -0.919271, 0, 0.149639, -0.957418, 0.246897, 0, 0.128024, 0.948139, 0.290932, 0, -0.292448, 0.893976, -0.339532, 0, -0.192062, -0.972477, -0.131909, 0, 0.44007, -0.870905, 0.218776, 0, 0.303887, -0.659003, -0.688017, 0, 0.195552, 0.41876, -0.886792, 0, -0.889922, 0.454236, -0.0413315, 0, 0.515034, 0.225353, -0.827016, 0, 0.63084, -0.573408, -0.522728, 0, -0.745779, 0.549592, -0.376514, 0, 0.0711763, -0.979204, 0.189982, 0, 0.705657, 0.707887, 0.0307322, 0, 0.114603, 0.655735, -0.746242, 0, -0.0739232, -0.0135353, 0.997172, 0, 0.173356, -0.20818, 0.962605, 0, 0.34008, -0.787344, 0.514232, 0, -0.143596, 0.334295, -0.931465, 0, 0.721989, -0.30942, -0.618863, 0, -0.827657, 0.0410685, 0.559729, 0, -0.804277, -0.418454, 0.421942, 0, -0.379459, 0.792556, 0.477353, 0, 0.0391537, 0.0756503, 0.996365, 0, 0.821943, 0.237588, 0.517651, 0, -0.788974, 0.463584, -0.403249, 0, 0.175972, 0.984364, -0.00782073, 0, 0.891497, 0.399363, 0.213873, 0, -0.819111, 0.106216, 0.563716, 0, 0.105511, 0.544028, -0.832406, 0, -0.464551, 0.63753, 0.614612, 0, 0.232387, 0.935154, -0.267363, 0, 0.777619, 0.272068, -0.566823, 0, 0.975331, 0.190338, 0.111807, 0, 0.224313, 0.450072, -0.86436, 0, 0.841897, -0.536898, 0.0543103, 0, 0.637123, -0.664145, -0.391135, 0, 0.901675, -0.422984, 0.0898189, 0, -0.496241, 0.367413, -0.786608, 0, -0.255468, -0.689763, -0.677469, 0, -0.0616459, -0.951141, -0.302539, 0, -0.431011, -0.889035, -0.154425, 0, -0.0711688, 0.486502, -0.870776, 0, -0.223359, -0.36162, 0.905175, 0, -0.678546, 0.695482, -0.23639, 0, 0.576553, 0.77934, 0.245389, 0, -0.194568, -0.24951, 0.948624, 0, 0.28962, -0.447736, 0.845962, 0, -0.0403821, -0.871893, 0.488028, 0, 0.790972, -0.560788, 0.244705, 0, -0.34553, 0.739953, 0.57713, 0, -0.516376, -0.697122, 0.49737, 0, 0.115998, 0.859293, 0.498156, 0, 0.643831, -0.239955, 0.72657, 0, -0.125114, 0.987348, -0.0974144, 0, -0.306452, 0.610699, -0.73016, 0, -0.269845, 0.893027, -0.360119, 0, 0.328563, -0.570628, -0.752615, 0, -0.306918, -0.42057, 0.853769, 0, 0.699245, -0.51785, 0.492837, 0, -0.558362, -0.469763, -0.68378, 0, 0.476563, -0.841398, 0.254826, 0, 0.0276172, -0.623206, 0.78157, 0, 0.587723, -0.800313, -0.118659, 0, 0.594035, -0.740708, 0.313806, 0, -0.340185, -0.887929, 0.309605, 0, 0.312245, -0.246681, -0.917416, 0, 0.194206, 0.186398, -0.963089, 0, 0.915704, 0.329835, -0.229553, 0, 0.94133, 0.229917, 0.247055, 0, -0.888253, -0.144148, 0.436152, 0, -0.906917, -0.362625, -0.214486, 0, 0.403108, -0.908884, 0.10693, 0, 0.983963, 0.169256, 0.056292, 0, -0.197949, 0.888236, 0.414553, 0, 0.0879741, 0.247673, 0.964841, 0, 0.474384, -0.868071, -0.146331, 0, 0.699884, 0.541342, -0.465953, 0, 0.610965, 0.567249, 0.552223, 0, 0.830508, -0.285788, -0.478103, 0, 0.328573, -0.683076, -0.652263, 0, -0.00537775, 0.873381, 0.487009, 0, -0.51289, 0.828835, 0.223557, 0, -0.871168, -0.15102, 0.467182, 0, -0.545561, 0.390016, -0.741789, 0, 0.874063, 0.259258, 0.410852, 0, -0.781555, 0.612184, -0.120005, 0, -0.284928, 0.708938, -0.645154, 0, -0.568809, 0.0883274, 0.817713, 0, -0.0429388, 0.549957, -0.834088, 0, 0.933296, -0.127233, 0.335813, 0, 0.698149, -0.493464, 0.51873, 0, -0.603413, 0.617495, -0.504572, 0
};
inline float fade(float t) {
return (t * t * t) * (t * (t * 6 - 15) + 10);
}
/*inline float fade(float t) {
return t * t * (3 - t * 2);
}*/
inline float grad(int hash, float x) {
return x*g1[hash&127];
}
inline float grad(int hash, float x, float y) {
int h = hash&127;
return x*g2[2*h+0]+y*g2[2*h+1];
}
inline float grad(int hash, float x, float y, float z) {
int h = hash&127;
return x*g3[4*h+0]+y*g3[4*h+1]+z*g3[4*h+2];
}
float noise(float x)
{
float fx = floor(x);
int X = (int)fx & 255;
x -= fx;
float u = fade(x);
float g00 = grad(p[X ],x );
float g10 = grad(p[X+1],x-1);
return lerp(u,g00,g10);
}
float noise(float x, float y)
{
float fx = floor(x);
float fy = floor(y);
int X = (int)fx & 255;
int Y = (int)fy & 255;
x -= fx;
y -= fy;
float u = fade(x);
float v = fade(y);
int p00 = p[X ]+Y;
int p10 = p[X+1]+Y;
int p01 = p[X ]+Y+1;
int p11 = p[X+1]+Y+1;
float g00 = grad(p[p00],x ,y );
float g10 = grad(p[p10],x-1,y );
float g01 = grad(p[p01],x ,y-1);
float g11 = grad(p[p11],x-1,y-1);
return lerp(v,lerp(u,g00,g10),lerp(u,g01,g11));
}
float noise(const Vec3f& pos)
{
float x = pos.x;
float y = pos.y;
float z = pos.z;
float fx = floor(x);
float fy = floor(y);
float fz = floor(z);
int X = (int)fx & 255;
int Y = (int)fy & 255;
int Z = (int)fz & 255;
x -= fx;
y -= fy;
z -= fz;
float u = fade(x);
float v = fade(y);
float w = fade(z);
int p00 = p[X]+Y;
int p000 = p[p00]+Z;
int p010 = p[p00+1]+Z;
int p001 = p000+1;
int p011 = p010+1;
int p10 = p[X+1]+Y;
int p100 = p[p10]+Z;
int p110 = p[p10+1]+Z;
int p101 = p100+1;
int p111 = p110+1;
float g000 = grad(p[p000],x ,y ,z );
float g100 = grad(p[p100],x-1,y ,z );
float g010 = grad(p[p010],x ,y-1,z );
float g110 = grad(p[p110],x-1,y-1,z );
float g001 = grad(p[p001],x ,y ,z-1);
float g101 = grad(p[p101],x-1,y ,z-1);
float g011 = grad(p[p011],x ,y-1,z-1);
float g111 = grad(p[p111],x-1,y-1,z-1);
return lerp(w,
lerp(v,lerp(u,g000,g100),lerp(u,g010,g110)),
lerp(v,lerp(u,g001,g101),lerp(u,g011,g111)));
}
Vec3f noise3D(const Vec3f& p)
{
float x = noise(p.x+128.0f);
float y = noise(p.y+64.0f);
float z = noise(p.z+192.0f);
return make_Vec3f(x,y,z);
}
export void dummy_noise_ispc() {} // just to avoid compile warning "libnoise.a(noise.dev.o) has no symbols" under MacOSX

View file

@ -0,0 +1,10 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.isph"
/* noise functions */
float noise(const Vec3f& p);
Vec3f noise3D(const Vec3f& p);

View file

@ -0,0 +1,173 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/sampling.h"
namespace embree {
/*! \addtogroup rivl_render_embree_ivl */
/*! @{ */
/*! Reflects a viewing vector V at a normal N. */
inline Vec3fa reflect(const Vec3fa& V, const Vec3fa& N) { return 2.0f*dot(V,N)*N-V; }
#ifdef ISPC
inline Vec3fa reflect(const Vec3fa& V, const Vec3fa& N) { return 2.0f*dot(V,N)*N-V; }
inline Vec3fa reflect(const Vec3fa& V, const Vec3fa& N) { return 2.0f*dot(V,N)*N-V; }
inline Vec3fa reflect(const Vec3fa& V, const Vec3fa& N) { return 2.0f*dot(V,N)*N-V; }
#endif
/*! Reflects a viewing vector V at a normal N. Cosine between V
* and N is given as input. */
inline Vec3fa reflect(const Vec3fa &V, const Vec3fa &N, const float cosi) {
return 2.0f*cosi*N-V;
}
// =======================================================
/*!Refracts a viewing vector V at a normal N using the relative
* refraction index eta. Eta is refraction index of outside medium
* (where N points into) divided by refraction index of the inside
* medium. The vectors V and N have to point towards the same side
* of the surface. The cosine between V and N is given as input and
* the cosine of -N and transmission ray is computed as output. */
inline Sample3f refract(const Vec3fa& V, const Vec3fa& N, const float eta,
const float cosi, float &cost)
{
const float k = 1.0f-eta*eta*(1.0f-cosi*cosi);
if (k < 0.0f) { cost = 0.0f; return make_Sample3f(Vec3fa(0.f),0.0f); }
cost = sqrt(k);
return make_Sample3f(eta*(cosi*N-V)-cost*N, sqr(eta));
}
/*! Computes fresnel coefficient for media interface with relative
* refraction index eta. Eta is the outside refraction index
* divided by the inside refraction index. Both cosines have to be
* positive. */
inline float fresnelDielectric(const float cosi, const float cost, const float eta)
{
const float Rper = (eta*cosi - cost) * rcp(eta*cosi + cost);
const float Rpar = ( cosi - eta*cost) * rcp( cosi + eta*cost);
return 0.5f*(Rpar*Rpar + Rper*Rper);
}
/*! Computes fresnel coefficient for media interface with relative
* refraction index eta. Eta is the outside refraction index
* divided by the inside refraction index. The cosine has to be
* positive. */
inline float fresnelDielectric(const float cosi, const float eta)
{
const float k = 1.0f-eta*eta*(1.0f-cosi*cosi);
if (k < 0.0f) return 1.0f;
const float cost = sqrt(k);
return fresnelDielectric(cosi, cost, eta);
}
/*! Computes fresnel coefficient for conductor medium with complex
* refraction index (eta,k). The cosine has to be positive. */
inline Vec3fa fresnelConductor(const float cosi, const Vec3fa& eta, const Vec3fa& k)
{
const Vec3fa tmp = eta*eta + k*k;
const Vec3fa Rpar = (tmp * (cosi*cosi) - 2.0f*eta*cosi + Vec3fa(1.0f)) *
rcp(tmp * (cosi*cosi) + 2.0f*eta*cosi + Vec3fa(1.0f));
const Vec3fa Rper = (tmp - 2.0f*eta*cosi + Vec3fa(cosi*cosi)) *
rcp(tmp + 2.0f*eta*cosi + Vec3fa(cosi*cosi));
return 0.5f * (Rpar + Rper);
}
// =======================================================
struct FresnelConductor {
Vec3fa eta; //!< Real part of refraction index
Vec3fa k; //!< Imaginary part of refraction index
};
inline Vec3fa eval(const FresnelConductor& This, const float cosTheta) {
return fresnelConductor(cosTheta,This.eta,This.k);
}
inline FresnelConductor make_FresnelConductor(const Vec3fa& eta, const Vec3fa& k) {
FresnelConductor m; m.eta = eta; m.k = k; return m;
}
#if defined(ISPC)
inline FresnelConductor make_FresnelConductor(const Vec3fa& eta, const Vec3fa& k) {
FresnelConductor m; m.eta = eta; m.k = k; return m;
}
#endif
// =======================================================
struct FresnelDielectric
{
/*! refraction index of the medium the incident ray travels in */
float etai;
/*! refraction index of the medium the outgoing transmission rays
* travels in */
float etat;
};
inline Vec3fa eval(const FresnelDielectric& This, const float cosTheta) {
return Vec3fa(fresnelDielectric(cosTheta,This.etai/This.etat));
}
inline FresnelDielectric make_FresnelDielectric(const float etai, const float etat) {
FresnelDielectric m; m.etai = etai; m.etat = etat; return m;
}
#if defined(ISPC)
inline FresnelDielectric make_FresnelDielectric(const float etai, const float etat) {
FresnelDielectric m; m.etai = etai; m.etat = etat; return m;
}
#endif
// =======================================================
struct PowerCosineDistribution {
float exp;
};
inline float eval(const PowerCosineDistribution &This, const float cosThetaH) {
return (This.exp+2) * (1.0f/(2.0f*(float(M_PI)))) * pow(abs(cosThetaH), This.exp);
}
#if defined(ISPC)
inline float eval(const PowerCosineDistribution &This, const float cosThetaH) {
return (This.exp+2) * (1.0f/(2.0f*(float(M_PI)))) * pow(abs(cosThetaH), This.exp);
}
#endif
/*! Samples the power cosine distribution. */
inline void sample(const PowerCosineDistribution& This, const Vec3fa& wo, const Vec3fa& N, Sample3f &wi, const Vec2f s)
{
Vec3fa dir = powerCosineSampleHemisphere(This.exp,s);
Sample3f wh;
wh.v = frame(N) * dir;
wh.pdf = powerCosineSampleHemispherePDF(dir,This.exp);
Sample3f r = make_Sample3f(reflect(wo,wh.v),1.0f);
wi = make_Sample3f(r.v,wh.pdf/(4.0f*abs(dot(wo,wh.v))));
}
/*! Samples the power cosine distribution. */
#if defined(ISPC)
inline void sample(const PowerCosineDistribution& This, const Vec3fa& wo, const Vec3fa& N, Sample3f &wi, const Vec2f s)
{
Vec3fa dir = powerCosineSampleHemisphere(This.exp,s);
Sample3f wh;
wh.v = frame(N) * dir;
wh.pdf = powerCosineSampleHemispherePDF(dir,This.exp);
Sample3f r = make_Sample3f(reflect(wo,wh.v),1.0f);
wi = make_Sample3f(r.v,wh.pdf/(4.0f*abs(dot(wo,wh.v))));
}
#endif
inline PowerCosineDistribution make_PowerCosineDistribution(const float _exp) {
PowerCosineDistribution m; m.exp = _exp; return m;
}
#if defined(ISPC)
inline PowerCosineDistribution make_PowerCosineDistribution(const float _exp) {
PowerCosineDistribution m; m.exp = _exp; return m;
}
#endif
} // namespace embree

View file

@ -0,0 +1,169 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/sampling.isph"
/*! \addtogroup rivl_render_embree_ivl */
/*! @{ */
/*! Reflects a viewing vector V at a normal N. */
inline uniform Vec3f reflect(const uniform Vec3f& V, const uniform Vec3f& N) { return 2.0f*dot(V,N)*N-V; }
#ifdef ISPC
inline varying Vec3f reflect(const uniform Vec3f& V, const varying Vec3f& N) { return 2.0f*dot(V,N)*N-V; }
inline varying Vec3f reflect(const varying Vec3f& V, const uniform Vec3f& N) { return 2.0f*dot(V,N)*N-V; }
inline varying Vec3f reflect(const varying Vec3f& V, const varying Vec3f& N) { return 2.0f*dot(V,N)*N-V; }
#endif
/*! Reflects a viewing vector V at a normal N. Cosine between V
* and N is given as input. */
inline Vec3f reflect(const Vec3f &V, const Vec3f &N, const float cosi) {
return 2.0f*cosi*N-V;
}
// =======================================================
/*!Refracts a viewing vector V at a normal N using the relative
* refraction index eta. Eta is refraction index of outside medium
* (where N points into) divided by refraction index of the inside
* medium. The vectors V and N have to point towards the same side
* of the surface. The cosine between V and N is given as input and
* the cosine of -N and transmission ray is computed as output. */
inline Sample3f refract(const Vec3f& V, const Vec3f& N, const float eta,
const float cosi, float &cost)
{
const float k = 1.0f-eta*eta*(1.0f-cosi*cosi);
if (k < 0.0f) { cost = 0.0f; return make_Sample3f(make_Vec3f(0.f),0.0f); }
cost = sqrt(k);
return make_Sample3f(eta*(cosi*N-V)-cost*N, sqr(eta));
}
/*! Computes fresnel coefficient for media interface with relative
* refraction index eta. Eta is the outside refraction index
* divided by the inside refraction index. Both cosines have to be
* positive. */
inline float fresnelDielectric(const float cosi, const float cost, const float eta)
{
const float Rper = (eta*cosi - cost) * rcp(eta*cosi + cost);
const float Rpar = ( cosi - eta*cost) * rcp( cosi + eta*cost);
return 0.5f*(Rpar*Rpar + Rper*Rper);
}
/*! Computes fresnel coefficient for media interface with relative
* refraction index eta. Eta is the outside refraction index
* divided by the inside refraction index. The cosine has to be
* positive. */
inline float fresnelDielectric(const float cosi, const float eta)
{
const float k = 1.0f-eta*eta*(1.0f-cosi*cosi);
if (k < 0.0f) return 1.0f;
const float cost = sqrt(k);
return fresnelDielectric(cosi, cost, eta);
}
/*! Computes fresnel coefficient for conductor medium with complex
* refraction index (eta,k). The cosine has to be positive. */
inline Vec3f fresnelConductor(const float cosi, const Vec3f& eta, const Vec3f& k)
{
const Vec3f tmp = eta*eta + k*k;
const Vec3f Rpar = (tmp * (cosi*cosi) - 2.0f*eta*cosi + make_Vec3f(1.0f)) *
rcp(tmp * (cosi*cosi) + 2.0f*eta*cosi + make_Vec3f(1.0f));
const Vec3f Rper = (tmp - 2.0f*eta*cosi + make_Vec3f(cosi*cosi)) *
rcp(tmp + 2.0f*eta*cosi + make_Vec3f(cosi*cosi));
return 0.5f * (Rpar + Rper);
}
// =======================================================
struct FresnelConductor {
Vec3f eta; //!< Real part of refraction index
Vec3f k; //!< Imaginary part of refraction index
};
inline Vec3f eval(varying const FresnelConductor& This, const float cosTheta) {
return fresnelConductor(cosTheta,This.eta,This.k);
}
inline uniform FresnelConductor make_FresnelConductor(const uniform Vec3f& eta, const uniform Vec3f& k) {
uniform FresnelConductor m; m.eta = eta; m.k = k; return m;
}
#if defined(ISPC)
inline varying FresnelConductor make_FresnelConductor(const varying Vec3f& eta, const varying Vec3f& k) {
varying FresnelConductor m; m.eta = eta; m.k = k; return m;
}
#endif
// =======================================================
struct FresnelDielectric
{
/*! refraction index of the medium the incident ray travels in */
float etai;
/*! refraction index of the medium the outgoing transmission rays
* travels in */
float etat;
};
inline Vec3f eval(const uniform FresnelDielectric& This, const float cosTheta) {
return make_Vec3f(fresnelDielectric(cosTheta,This.etai/This.etat));
}
inline uniform FresnelDielectric make_FresnelDielectric(const uniform float etai, const uniform float etat) {
uniform FresnelDielectric m; m.etai = etai; m.etat = etat; return m;
}
#if defined(ISPC)
inline varying FresnelDielectric make_FresnelDielectric(const varying float etai, const varying float etat) {
varying FresnelDielectric m; m.etai = etai; m.etat = etat; return m;
}
#endif
// =======================================================
struct PowerCosineDistribution {
float exp;
};
inline float eval(const uniform PowerCosineDistribution &This, const float cosThetaH) {
return (This.exp+2) * (1.0f/(2.0f*(M_PI))) * pow(abs(cosThetaH), This.exp);
}
#if defined(ISPC)
inline float eval(const varying PowerCosineDistribution &This, const float cosThetaH) {
return (This.exp+2) * (1.0f/(2.0f*(M_PI))) * pow(abs(cosThetaH), This.exp);
}
#endif
/*! Samples the power cosine distribution. */
inline void sample(const uniform PowerCosineDistribution& This, const Vec3f& wo, const Vec3f& N, Sample3f &wi, const Vec2f s)
{
Vec3f dir = powerCosineSampleHemisphere(This.exp,s);
Sample3f wh;
wh.v = frame(N) * dir;
wh.pdf = powerCosineSampleHemispherePDF(dir,This.exp);
Sample3f r = make_Sample3f(reflect(wo,wh.v),1.0f);
wi = make_Sample3f(r.v,wh.pdf/(4.0f*abs(dot(wo,wh.v))));
}
/*! Samples the power cosine distribution. */
#if defined(ISPC)
inline void sample(const varying PowerCosineDistribution& This, const Vec3f& wo, const Vec3f& N, Sample3f &wi, const Vec2f s)
{
Vec3f dir = powerCosineSampleHemisphere(This.exp,s);
Sample3f wh;
wh.v = frame(N) * dir;
wh.pdf = powerCosineSampleHemispherePDF(dir,This.exp);
Sample3f r = make_Sample3f(reflect(wo,wh.v),1.0f);
wi = make_Sample3f(r.v,wh.pdf/(4.0f*abs(dot(wo,wh.v))));
}
#endif
inline uniform PowerCosineDistribution make_PowerCosineDistribution(const uniform float _exp) {
uniform PowerCosineDistribution m; m.exp = _exp; return m;
}
#if defined(ISPC)
inline varying PowerCosineDistribution make_PowerCosineDistribution(const varying float _exp) {
varying PowerCosineDistribution m; m.exp = _exp; return m;
}
#endif

View file

@ -0,0 +1,65 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "scene.h"
namespace embree
{
extern "C" int g_instancing_mode;
TutorialScene::TutorialScene() {
}
TutorialScene::~TutorialScene() {
}
void TutorialScene::add(Ref<SceneGraph::GroupNode> group)
{
for (auto& node : group->children)
{
if (Ref<SceneGraph::LightNode> lightNode = node.dynamicCast<SceneGraph::LightNode>()) {
lights.push_back(lightNode);
}
else if (Ref<SceneGraph::PerspectiveCameraNode> cameraNode = node.dynamicCast<SceneGraph::PerspectiveCameraNode>()) {
cameras.push_back(cameraNode);
}
else {
geometries.push_back(node);
}
}
}
unsigned TutorialScene::materialID(Ref<SceneGraph::MaterialNode> material)
{
if (material->id == -1) {
materials.push_back(material);
material->id = unsigned(materials.size()-1);
}
return material->id;
}
void TutorialScene::print_camera_names ()
{
if (cameras.size() == 0) {
std::cout << "no cameras inside the scene" << std::endl;
return;
}
for (size_t i=0; i<cameras.size(); i++)
std::cout << "camera " << i << ": " << cameras[i]->name << std::endl;
}
Ref<SceneGraph::PerspectiveCameraNode> TutorialScene::getDefaultCamera()
{
if (cameras.size()) return cameras[0];
return nullptr;
}
Ref<SceneGraph::PerspectiveCameraNode> TutorialScene::getCamera(const std::string& name)
{
for (size_t i=0; i<cameras.size(); i++)
if (cameras[i]->name == name) return cameras[i];
THROW_RUNTIME_ERROR("camera \"" + name +"\" not found");
}
};

View file

@ -0,0 +1,29 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../default.h"
#include "../scenegraph/scenegraph.h"
namespace embree
{
/*! Flattened scene used inside tutorials */
struct TutorialScene
{
TutorialScene();
~TutorialScene();
void add (Ref<SceneGraph::GroupNode> node);
unsigned materialID(Ref<SceneGraph::MaterialNode> material);
void print_camera_names ();
Ref<SceneGraph::PerspectiveCameraNode> getDefaultCamera();
Ref<SceneGraph::PerspectiveCameraNode> getCamera(const std::string& name);
public:
std::vector<Ref<SceneGraph::PerspectiveCameraNode>> cameras; //!< list of all cameras
std::vector<Ref<SceneGraph::MaterialNode>> materials; //!< list of materials
std::vector<Ref<SceneGraph::Node> > geometries; //!< list of geometries
std::vector<Ref<SceneGraph::LightNode>> lights; //!< list of lights
};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,426 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#if !defined(ISPC)
#include "../math/sampling.h"
#include "../lights/light.h"
#include "../lights/ambient_light.h"
#include "../lights/directional_light.h"
#include "../lights/point_light.h"
#include "../lights/quad_light.h"
#include "../lights/spot_light.h"
#include "scene.h"
#else
#include "../lights/light.isph"
#endif
#include "../scenegraph/texture.h"
#include "../scenegraph/materials.h"
#if !defined(ISPC)
#define CPPTUTORIAL
#include "../scenegraph/materials.h"
#undef CPPTUTORIAL
namespace embree
{
#endif
struct ISPCTriangle
{
unsigned int v0; /*< first triangle vertex */
unsigned int v1; /*< second triangle vertex */
unsigned int v2; /*< third triangle vertex */
};
struct ISPCQuad
{
unsigned int v0; /*< first triangle vertex */
unsigned int v1; /*< second triangle vertex */
unsigned int v2; /*< third triangle vertex */
unsigned int v3; /*< fourth triangle vertex */
};
struct ISPCHair
{
unsigned int vertex;
unsigned int id;
};
struct ISPCGrid
{
unsigned int startVtxID;
unsigned int lineOffset;
#if !defined(ISPC)
unsigned short resX,resY; // max is a 32k x 32k grid
#else
int16 resX,resY;
#endif
};
enum ISPCType { TRIANGLE_MESH, SUBDIV_MESH, CURVES, INSTANCE, INSTANCE_ARRAY, GROUP, QUAD_MESH, GRID_MESH, POINTS };
struct ISPCGeometry
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCGeometry (ISPCType type) : type(type), geometry(nullptr), materialID(-1), visited(false) {}
~ISPCGeometry () { if (geometry) rtcReleaseGeometry(geometry); }
#endif
ISPCType type;
RTCGeometry geometry;
unsigned int materialID;
bool visited;
};
#if !defined(ISPC)
enum TEXTURE_FORMAT {
Texture_RGBA8 = 1,
Texture_RGB8 = 2,
Texture_FLOAT32 = 3,
};
#endif
struct ISPCTriangleMesh
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCTriangleMesh (RTCDevice device, unsigned int numTriangles, unsigned int numPositions, bool hasNormals, bool hasTexcoords, unsigned int numTimeSteps = 1);
ISPCTriangleMesh (RTCDevice device, TutorialScene* scene_in, Ref<SceneGraph::TriangleMeshNode> in);
~ISPCTriangleMesh ();
void commit();
private:
ISPCTriangleMesh (const ISPCTriangleMesh& other) DELETED; // do not implement
ISPCTriangleMesh& operator= (const ISPCTriangleMesh& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< vertex position array
Vec3fa** normals; //!< vertex normal array
Vec2f* texcoords; //!< vertex texcoord array
ISPCTriangle* triangles; //!< list of triangles
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numTriangles;
};
struct ISPCQuadMesh
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCQuadMesh (RTCDevice device, TutorialScene* scene_in, Ref<SceneGraph::QuadMeshNode> in);
~ISPCQuadMesh ();
void commit();
private:
ISPCQuadMesh (const ISPCQuadMesh& other) DELETED; // do not implement
ISPCQuadMesh& operator= (const ISPCQuadMesh& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< vertex position array
Vec3fa** normals; //!< vertex normal array
Vec2f* texcoords; //!< vertex texcoord array
ISPCQuad* quads; //!< list of quads
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numQuads;
};
struct ISPCSubdivMesh
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCSubdivMesh (RTCDevice device, TutorialScene* scene_in, Ref<SceneGraph::SubdivMeshNode> in);
~ISPCSubdivMesh ();
void commit();
private:
ISPCSubdivMesh (const ISPCSubdivMesh& other) DELETED; // do not implement
ISPCSubdivMesh& operator= (const ISPCSubdivMesh& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< vertex positions
Vec3fa** normals; //!< face vertex normals
Vec2f* texcoords; //!< face texture coordinates
unsigned int* position_indices; //!< position indices for all faces
unsigned int* normal_indices; //!< normal indices for all faces
unsigned int* texcoord_indices; //!< texcoord indices for all faces
RTCSubdivisionMode position_subdiv_mode;
RTCSubdivisionMode normal_subdiv_mode;
RTCSubdivisionMode texcoord_subdiv_mode;
unsigned int* verticesPerFace; //!< number of indices of each face
unsigned int* holes; //!< face ID of holes
float* subdivlevel; //!< subdivision level
Vec2i* edge_creases; //!< crease index pairs
float* edge_crease_weights; //!< weight for each crease
unsigned int* vertex_creases; //!< indices of vertex creases
float* vertex_crease_weights; //!< weight for each vertex crease
unsigned int* face_offsets;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numFaces;
unsigned int numEdges;
unsigned int numEdgeCreases;
unsigned int numVertexCreases;
unsigned int numHoles;
unsigned int numNormals;
unsigned int numTexCoords;
};
struct ISPCHairSet
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCHairSet (RTCDevice device, TutorialScene* scene_in, RTCGeometryType type, Ref<SceneGraph::HairSetNode> in);
~ISPCHairSet();
void commit();
private:
ISPCHairSet (const ISPCHairSet& other) DELETED; // do not implement
ISPCHairSet& operator= (const ISPCHairSet& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< hair control points (x,y,z,r)
Vec3fa** normals; //!< normal control points (x,y,z,r)
Vec3fa** tangents; //!< tangent control points (x,y,z,r)
Vec3fa** dnormals; //!< normal derivative control points (x,y,z,r)
ISPCHair* hairs; //!< for each hair, index to first control point
#if !defined(ISPC)
unsigned char* flags; //!< end cap flags per segment
#else
uint8* flags; //!< end cap flags per segment
#endif
RTCGeometryType type;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numHairs;
unsigned int numHairCurves;
unsigned int tessellation_rate;
};
struct ISPCPointSet
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCPointSet (RTCDevice device, TutorialScene* scene_in, RTCGeometryType type, Ref<SceneGraph::PointSetNode> in);
~ISPCPointSet();
void commit();
private:
ISPCPointSet (const ISPCPointSet& other) DELETED; // do not implement
ISPCPointSet& operator= (const ISPCPointSet& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< hair control points (x,y,z,r)
Vec3fa** normals; //!< normal control points (x,y,z,r)
RTCGeometryType type;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
};
struct ISPCGridMesh
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCGridMesh (RTCDevice device, TutorialScene* scene_in, Ref<SceneGraph::GridMeshNode> in);
~ISPCGridMesh ();
void commit();
private:
ISPCGridMesh (const ISPCGridMesh& other) DELETED; // do not implement
ISPCGridMesh& operator= (const ISPCGridMesh& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
Vec3fa** positions; //!< vertex position array
ISPCGrid* grids; //!< list of quads
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numGrids;
};
struct ISPCInstance
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCInstance (RTCDevice device, unsigned int numTimeSteps = 1);
ISPCInstance (RTCDevice device, TutorialScene* scene, Ref<SceneGraph::TransformNode> in);
~ISPCInstance();
void commit();
private:
ISPCInstance (const ISPCInstance& other) DELETED; // do not implement
ISPCInstance& operator= (const ISPCInstance& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
ISPCGeometry* child;
float startTime;
float endTime;
unsigned int numTimeSteps;
bool quaternion;
AffineSpace3fa* spaces;
};
struct ISPCInstanceArray
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCInstanceArray(RTCDevice device, unsigned int numTimeSteps = 1);
ISPCInstanceArray(RTCDevice device, TutorialScene* scene, Ref<SceneGraph::MultiTransformNode> in);
~ISPCInstanceArray();
void commit();
private:
ISPCInstanceArray(const ISPCInstanceArray& other) DELETED; // do not implement
ISPCInstanceArray& operator= (const ISPCInstanceArray& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
ISPCGeometry* child;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numInstances;
bool quaternion;
AffineSpace3fa** spaces_array;
};
struct ISPCGroup
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCGroup (RTCDevice device, unsigned int numGeometries);
ISPCGroup (RTCDevice device, TutorialScene* scene, Ref<SceneGraph::GroupNode> in);
~ISPCGroup();
void commit();
private:
ISPCGroup (const ISPCGroup& other) DELETED; // do not implement
ISPCGroup& operator= (const ISPCGroup& other) DELETED; // do not implement
public:
#endif
ISPCGeometry geom;
RTCScene scene;
ISPCGeometry** geometries;
unsigned int numGeometries;
unsigned int requiredInstancingDepth; // instancing depth required for this group
};
struct ISPCScene
{
#if !defined(ISPC)
ALIGNED_STRUCT_USM_(16);
ISPCScene(RTCDevice device, unsigned int numGeometries, unsigned int numMaterials, unsigned int numLights);
ISPCScene(RTCDevice device, TutorialScene* in);
~ISPCScene();
void commit();
static ISPCGeometry* convertGeometry (RTCDevice device, TutorialScene* scene, Ref<SceneGraph::Node> in);
static Light* convertLight(Ref<SceneGraph::LightNode> in);
static Light* createLight(Ref<SceneGraph::LightNode> in);
template<typename LightNode> static void updateLight(const LightNode& in, Light* out);
static void updateLight(const Ref<SceneGraph::LightNode>& in, Light* out);
private:
ISPCScene (const ISPCScene& other) DELETED; // do not implement
ISPCScene& operator= (const ISPCScene& other) DELETED; // do not implement
public:
#endif
RTCScene scene;
ISPCGeometry** geometries; //!< list of geometries
ISPCMaterial** materials; //!< material list
unsigned int numGeometries; //!< number of geometries
unsigned int numMaterials; //!< number of materials
Light** lights; //!< list of lights
unsigned int numLights; //!< number of lights
void* tutorialScene;
};
#if !defined(ISPC)
typedef void (*AssignShaderTy)(ISPCGeometry* geometry);
extern "C" { extern AssignShaderTy assignShadersFunc; };
#else
typedef unmasked void (*AssignShaderTy)(uniform ISPCGeometry* uniform geometry);
extern uniform AssignShaderTy assignShadersFunc;
#endif
#if !defined(ISPC)
extern "C" void UpdateScene(ISPCScene* scene_in, float time);
extern "C" RTCScene ConvertScene(RTCDevice g_device, ISPCScene* scene_in, RTCBuildQuality quality, RTCSceneFlags flags = RTC_SCENE_FLAG_NONE, RTCFeatureFlags *used_features_out=nullptr);
#else
unmasked extern "C" void UpdateScene(ISPCScene* uniform scene_in, uniform float time);
unmasked extern "C" RTCScene ConvertScene (RTCDevice g_device, ISPCScene* uniform scene_in, uniform RTCBuildQuality quality, uniform RTCSceneFlags flags = RTC_SCENE_FLAG_NONE, RTCFeatureFlags * uniform used_features_out=NULL);
#endif
#if !defined(ISPC)
}
#endif

View file

@ -0,0 +1,88 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../default.h"
#include <algorithm>
namespace embree
{
/* calculates min/avg/max and sigma */
struct Statistics
{
public:
Statistics()
: v(0.0f), v2(0.0f), vmin(pos_inf), vmax(neg_inf), N(0) {}
void add(float a)
{
v += a;
v2 += a*a;
vmin = min(vmin,a);
vmax = max(vmax,a);
N++;
}
float getSigma() const
{
if (N == 0) return 0.0f;
else return (float) sqrt(max(0.0,v2/N - sqr(v/N)));
}
float getAvgSigma() const // standard deviation of average
{
if (N == 0) return 0.0f;
else return getSigma()/sqrt(float(N));
}
float getMin() const { return vmin; }
float getMax() const { return vmax; }
float getAvg() const
{
if (N == 0) return 0.0f;
else return float(v/N);
}
private:
double v; // sum of all values
double v2; // sum of squares of all values
float vmin; // min of all values
float vmax; // max of all values
size_t N; // number of values
};
/* filters outlyers out */
struct FilteredStatistics
{
public:
FilteredStatistics(float fskip_small, float fskip_large)
: fskip_small(fskip_small), fskip_large(fskip_large) {}
void add(float a)
{
v.push_back(a);
std::sort(v.begin(),v.end(),std::less<float>());
size_t skip_small = (size_t) floor(0.5*fskip_small*double(v.size()));
size_t skip_large = (size_t) floor(0.5*fskip_large*double(v.size()));
stat = Statistics();
for (size_t i=skip_small; i<v.size()-skip_large; i++)
stat.add(v[i]);
}
float getSigma() const { return stat.getSigma(); }
float getAvgSigma() const { return stat.getAvgSigma(); }
float getMin() const { return stat.getMin(); }
float getMax() const { return stat.getMax(); }
float getAvg() const { return stat.getAvg(); }
Statistics getStatistics() const { return stat; }
private:
float fskip_small; // fraction of small outlyers to filter out
float fskip_large; // fraction of large outlyers to filter out
std::vector<float> v;
Statistics stat;
};
}

View file

@ -0,0 +1,36 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "../../../common/algorithms/parallel_for.h"
namespace embree
{
/* Signature of ispc-generated 'task' functions */
typedef void (*ISPCTaskFunc)(void* data, int threadIndex, int threadCount, int taskIndex, int taskCount);
extern "C" void* ISPCAlloc(void** taskPtr, int64_t size, int32_t alignment)
{
if (*taskPtr == nullptr) *taskPtr = new std::vector<void*>;
std::vector<void*>* lst = (std::vector<void*>*)(*taskPtr);
void* ptr = alignedMalloc((size_t)size,alignment);
lst->push_back(ptr);
return ptr;
}
extern "C" void ISPCSync(void* task)
{
std::vector<void*>* lst = (std::vector<void*>*)task;
for (size_t i=0; i<lst->size(); i++) alignedFree((*lst)[i]);
delete lst;
}
extern "C" void ISPCLaunch(void** taskPtr, void* func, void* data, int count)
{
parallel_for(0, count,[&] (const range<int>& r) {
const int threadIndex = (int) TaskScheduler::threadIndex();
const int threadCount = (int) TaskScheduler::threadCount();
for (int i=r.begin(); i<r.end(); i++)
((ISPCTaskFunc)func)(data,threadIndex,threadCount,i,count);
});
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,257 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../default.h"
#include "application.h"
#include "camera.h"
#include "scene.h"
#include "scene_device.h"
#if defined(USE_GLFW)
/* include GLFW for window management */
#include <GLFW/glfw3.h>
/* include ImGUI */
#include "../imgui/imgui.h"
#include "../imgui/backends/imgui_impl_glfw.h"
#include "../imgui/backends/imgui_impl_opengl2.h"
#endif
namespace embree
{
/* functions provided by each tutorial */
extern "C" void device_init(const char* cfg);
extern "C" void device_resize(int width, int height);
extern "C" void device_render(unsigned* pixels, const unsigned width, const unsigned height, const float time, const ISPCCamera& camera);
extern "C" bool device_pick(const float x, const float y, const ISPCCamera& camera, Vec3fa& hitPos);
//extern "C" void device_key_pressed (int key);
extern "C" void device_cleanup();
template<typename Ty>
struct Averaged
{
Averaged (size_t N, double dt)
: N(N), dt(dt) {}
void add(double v)
{
values.push_front(std::make_pair(getSeconds(),v));
if (values.size() > N) values.resize(N);
}
Ty get() const
{
if (values.size() == 0) return zero;
double t_begin = values[0].first-dt;
Ty sum(zero);
size_t num(0);
for (size_t i=0; i<values.size(); i++) {
if (values[i].first >= t_begin) {
sum += values[i].second;
num++;
}
}
if (num == 0) return 0;
else return sum/Ty(num);
}
std::deque<std::pair<double,Ty>> values;
size_t N;
double dt;
};
class TutorialApplication : public Application
{
public:
TutorialApplication (const std::string& tutorialName, const int features, int width = 512, int height = 512);
virtual ~TutorialApplication();
private:
TutorialApplication (const TutorialApplication& other) DELETED; // do not implement
TutorialApplication& operator= (const TutorialApplication& other) DELETED; // do not implement
public:
/* starts tutorial */
void run(int argc, char** argv);
/* virtual main function, contains all tutorial logic */
virtual int main(int argc, char** argv);
/* creates the Embree device */
void create_device();
/* callback called after command line parsing finished */
virtual void postParseCommandLine() {}
/* render to file mode */
void renderToFile(const FileName& fileName);
/* compare rendering to reference image */
void compareToReferenceImage(const FileName& fileName);
/* passes parameters to the backend */
void set_parameter(size_t parm, ssize_t val);
/* resize framebuffer */
void resize(unsigned width, unsigned height);
/* set scene to use */
void set_scene (TutorialScene* in);
#if defined(USE_GLFW)
public:
/* create a fullscreen window */
GLFWwindow* createFullScreenWindow();
/* create a standard window of specified size */
GLFWwindow* createStandardWindow(int width, int height);
void setCallbackFunctions(GLFWwindow* window);
/* interactive rendering using GLFW window */
void renderInteractive();
/* GLFW callback functions */
public:
virtual void keypressed(int key);
virtual void keyboardFunc(GLFWwindow* window, int key, int scancode, int action, int mods);
virtual void clickFunc(GLFWwindow* window, int button, int action, int mods);
virtual void motionFunc(GLFWwindow* window, double x, double y);
virtual void displayFunc();
virtual void reshapeFunc(GLFWwindow* window, int width, int height);
virtual void drawGUI() {};
public:
GLFWwindow* window = nullptr;
#endif
public:
virtual void render(unsigned* pixels, const unsigned width, const unsigned height, const float time, const ISPCCamera& camera);
public:
std::string tutorialName;
/* render settings */
Ref<SceneGraph::PerspectiveCameraNode> animated_camera;
Camera camera;
/* framebuffer settings */
unsigned width;
unsigned height;
unsigned* pixels;
/* image output settings */
FileName outputImageFilename;
FileName referenceImageFilename;
float referenceImageThreshold; // threshold when we consider images to differ
unsigned int numFrames = 1; // render as many frames on output or compare mode
/* window settings */
bool interactive;
bool fullscreen;
unsigned window_width;
unsigned window_height;
double time0;
int debug_int0;
int debug_int1;
int mouseMode;
double clickX, clickY;
float speed;
Vec3f moveDelta;
bool animate; // if mblur off -> animate on/off
float render_time; // if animate off -> render this time
bool command_line_camera;
bool print_frame_rate;
Averaged<double> avg_render_time;
Averaged<double> avg_frame_time;
Averaged<double> avg_mrayps;
bool print_camera;
int debug0;
int debug1;
int debug2;
int debug3;
RTCRayQueryFlags iflags_coherent;
RTCRayQueryFlags iflags_incoherent;
std::unique_ptr<ISPCScene> ispc_scene;
private:
#if defined(EMBREE_SYCL_SUPPORT)
public:
sycl::queue* queue = nullptr;
sycl::device* device = nullptr;
sycl::context* context = nullptr;
bool jit_cache = true;
#endif
public:
/* ray statistics */
void initRayStats();
int64_t getNumRays();
public:
static TutorialApplication* instance;
};
class SceneLoadingTutorialApplication : public TutorialApplication
{
public:
SceneLoadingTutorialApplication (const std::string& tutorialName, int features);
virtual int main(int argc, char** argv);
bool scene_empty_post_parse() const {
return scene->size() == 0 && sceneFilename.size() == 0 && futures.size() == 0;
}
public:
TutorialScene obj_scene;
Ref<SceneGraph::GroupNode> scene;
enum SceneGraphOperations
{
CONVERT_TRIANGLES_TO_QUADS,
CONVERT_BEZIER_TO_LINES,
CONVERT_BEZIER_TO_BSPLINE,
CONVERT_BEZIER_TO_HERMITE,
CONVERT_BSPLINE_TO_BEZIER,
CONVERT_FLAT_TO_ROUND_CURVES,
CONVERT_ROUND_TO_FLAT_CURVES,
MERGE_QUADS_TO_GRIDS,
CONVERT_QUADS_TO_GRIDS,
CONVERT_GRIDS_TO_QUADS,
CONVERT_MBLUR_TO_NONMBLUR,
};
std::vector<SceneGraphOperations> sgop;
std::vector<std::function<void()>> futures; // future scene graph operations
float convert_tris_to_quads_prop;
unsigned grid_resX, grid_resY;
bool remove_mblur;
bool remove_non_mblur;
std::vector<FileName> sceneFilename;
std::vector<FileName> keyFramesFilenames;
SceneGraph::InstancingMode instancing_mode;
std::string subdiv_mode;
bool print_scene_cameras;
std::string camera_name;
};
}

View file

@ -0,0 +1,131 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "tutorial_device.h"
#include "../math/random_sampler.h"
#include "../math/sampling.h"
#include "scene_device.h"
namespace embree {
/* the scene to render */
extern RTCScene g_scene;
extern "C" float g_debug;
/* returns the point seen through specified pixel */
extern "C" bool device_pick(const float x,
const float y,
const ISPCCamera& camera,
Vec3fa& hitPos)
{
/* initialize ray */
Ray1 ray;
ray.org = Vec3ff(camera.xfm.p);
ray.dir = Vec3ff(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz));
ray.tnear() = 0.0f;
ray.tfar = inf;
ray.geomID = RTC_INVALID_GEOMETRY_ID;
ray.primID = RTC_INVALID_GEOMETRY_ID;
ray.mask = -1;
ray.time() = g_debug;
/* intersect ray with scene */
rtcIntersect1(g_scene,RTCRayHit1_(ray));
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
hitPos = Vec3fa(0.0f,0.0f,0.0f);
return false;
}
else {
hitPos = ray.org + ray.tfar*ray.dir;
return true;
}
}
Vec2f getTextureCoordinatesSubdivMesh(void* _mesh, const unsigned int primID, const float u, const float v)
{
ISPCSubdivMesh *mesh = (ISPCSubdivMesh *)_mesh;
Vec2f st;
st.x = u;
st.y = v;
if (mesh && mesh->texcoord_indices)
{
assert(primID < mesh->numFaces);
const unsigned int face_offset = mesh->face_offsets[primID];
if (mesh->verticesPerFace[primID] == 3)
{
const unsigned int t0 = mesh->texcoord_indices[face_offset+0];
const unsigned int t1 = mesh->texcoord_indices[face_offset+1];
const unsigned int t2 = mesh->texcoord_indices[face_offset+2];
const Vec2f txt0 = mesh->texcoords[t0];
const Vec2f txt1 = mesh->texcoords[t1];
const Vec2f txt2 = mesh->texcoords[t2];
const float w = 1.0f - u - v;
st = w * txt0 + u * txt1 + v * txt2;
}
else if (mesh->verticesPerFace[primID] == 4)
{
const unsigned int t0 = mesh->texcoord_indices[face_offset+0];
const unsigned int t1 = mesh->texcoord_indices[face_offset+1];
const unsigned int t2 = mesh->texcoord_indices[face_offset+2];
const unsigned int t3 = mesh->texcoord_indices[face_offset+3];
const Vec2f txt0 = mesh->texcoords[t0];
const Vec2f txt1 = mesh->texcoords[t1];
const Vec2f txt2 = mesh->texcoords[t2];
const Vec2f txt3 = mesh->texcoords[t3];
const float u0 = u;
const float v0 = v;
const float u1 = 1.0f - u;
const float v1 = 1.0f - v;
st = u1*v1 * txt0 + u0*v1* txt1 + u0*v0 * txt2 + u1*v0* txt3;
}
}
return st;
}
float getTextureTexel1f(const Texture* texture, float s, float t)
{
if (!texture) return 0.0f;
int iu = (int)floor(s * (float)(texture->width));
iu = iu % texture->width; if (iu < 0) iu += texture->width;
int iv = (int)floor(t * (float)(texture->height));
iv = iv % texture->height; if (iv < 0) iv += texture->height;
if (texture->format == Texture::FLOAT32)
{
float *data = (float *)texture->data;
return data[iv*texture->width + iu];
}
else if (texture->format == Texture::RGBA8)
{
const int offset = (iv * texture->width + iu) * 4;
unsigned char * t = (unsigned char*)texture->data;
return t[offset+0]*(1.0f/255.0f);
}
return 0.0f;
}
Vec3fa getTextureTexel3f(const Texture* texture, float s, float t)
{
if (!texture) return Vec3fa(0.0f,0.0f,0.0f);
int iu = (int)floor(s * (float)(texture->width));
iu = iu % texture->width; if (iu < 0) iu += texture->width;
int iv = (int)floor(t * (float)(texture->height));
iv = iv % texture->height; if (iv < 0) iv += texture->height;
if (texture->format == Texture::RGBA8)
{
const int offset = (iv * texture->width + iu) * 4;
unsigned char * t = (unsigned char*)texture->data;
const unsigned char r = t[offset+0];
const unsigned char g = t[offset+1];
const unsigned char b = t[offset+2];
return Vec3fa( (float)r * 1.0f/255.0f, (float)g * 1.0f/255.0f, (float)b * 1.0f/255.0f );
}
return Vec3fa(0.0f,0.0f,0.0f);
}
} // namespace embree

View file

@ -0,0 +1,158 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#define _CRT_SECURE_NO_WARNINGS
/* size of screen tiles */
#define TILE_SIZE_X 8
#define TILE_SIZE_Y 8
/* vertex and triangle layout */
struct Vertex { float x,y,z,r; }; // FIXME: rename to Vertex4f
struct Triangle { int v0, v1, v2; };
#include "../device_default.h"
/* include optional vector library */
#include "../math/math.h"
#include "../math/vec.h"
#include "../math/affinespace.h"
#include "../core/ray.h"
#include "camera.h"
#include "scene_device.h"
#include "noise.h"
#if !defined(ISPC)
#include "../../../common/algorithms/parallel_for.h"
namespace embree {
#endif
#if defined(EMBREE_SYCL_TUTORIAL)
inline sycl::nd_range<2> make_nd_range(unsigned int size0, unsigned int size1)
{
const sycl::range<2> wg_size = sycl::range<2>(4,4);
/* align iteration space to work group size */
size0 = ((size0 + wg_size[0] - 1) / wg_size[0]) * wg_size[0];
size1 = ((size1 + wg_size[1] - 1) / wg_size[1]) * wg_size[1];
return sycl::nd_range(sycl::range(size0,size1),wg_size);
}
#endif
enum Shader {
SHADER_DEFAULT,
SHADER_EYELIGHT,
SHADER_OCCLUSION,
SHADER_UV,
SHADER_TEXCOORDS,
SHADER_TEXCOORDS_GRID,
SHADER_NG,
SHADER_CYCLES,
SHADER_GEOMID,
SHADER_GEOMID_PRIMID,
SHADER_AO
};
extern "C" RTCDevice g_device;
extern "C" RTCRayQueryFlags g_iflags_coherent;
extern "C" RTCRayQueryFlags g_iflags_incoherent;
extern "C" Shader shader;
/* error reporting function */
void error_handler(void* userPtr, RTCError code, const char* str = nullptr);
/* returns time stamp counter */
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
inline int64_t get_tsc() { return 0; }
#else
extern "C" int64_t get_tsc();
#endif
/* face forward for shading normals */
inline Vec3fa faceforward( const Vec3fa& N, const Vec3fa& I, const Vec3fa& Ng ) {
Vec3fa NN = N; return dot(I, Ng) < 0 ? NN : neg(NN);
}
/* GLFW keys codes */
#if !defined(GLFW_KEY_F1)
#define GLFW_KEY_F1 290
#define GLFW_KEY_F2 291
#define GLFW_KEY_F3 292
#define GLFW_KEY_F4 293
#define GLFW_KEY_F5 294
#define GLFW_KEY_F6 295
#define GLFW_KEY_F7 296
#define GLFW_KEY_F8 297
#define GLFW_KEY_F9 298
#define GLFW_KEY_F10 299
#define GLFW_KEY_F11 300
#define GLFW_KEY_F12 301
#endif
extern "C" void device_key_pressed_default(int key);
extern "C" void (* key_pressed_handler)(int key);
extern "C" void renderFrameStandard(int* pixels,
const unsigned int width,
const unsigned int height,
const float time,
const ISPCCamera& camera);
unsigned int getNumHWThreads();
#if defined(ISPC)
#define ALIGNED_STRUCT_(x)
#define __aligned(x)
#define MAYBE_UNUSED
#endif
/* draws progress bar */
extern "C" void progressStart();
extern "C" bool progressMonitor(void* ptr, const double n);
extern "C" void progressEnd();
SYCL_EXTERNAL Vec2f getTextureCoordinatesSubdivMesh(void* mesh, const unsigned int primID, const float u, const float v);
SYCL_EXTERNAL float getTextureTexel1f(const Texture* texture, float u, float v);
SYCL_EXTERNAL Vec3fa getTextureTexel3f(const Texture* texture, float u, float v);
enum ISPCInstancingMode { ISPC_INSTANCING_NONE, ISPC_INSTANCING_GEOMETRY, ISPC_INSTANCING_GROUP };
/* ray statistics */
#if !defined(TASKING_PPL) // not supported with PPL because threadIndex is not unique and atomics are too expensive
#define RAY_STATS
#endif
struct RayStats
{
int numRays;
int pad[32-1];
};
#if defined(RAY_STATS)
#if defined(ISPC)
inline void RayStats_addRay(RayStats& stats) { stats.numRays += popcnt(1); }
inline void RayStats_addShadowRay(RayStats& stats) { stats.numRays += popcnt(1); }
#else // C++
__forceinline void RayStats_addRay(RayStats& stats) { stats.numRays++; }
__forceinline void RayStats_addShadowRay(RayStats& stats) { stats.numRays++; }
#endif
#else // disabled
inline void RayStats_addRay(RayStats& stats) {}
inline void RayStats_addShadowRay(RayStats& stats) {}
#endif
extern "C" RayStats* g_stats;
inline bool nativePacketSupported(RTCDevice device)
{
if (sizeof(float) == 1*4) return true;
else if (sizeof(float) == 4*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED);
else if (sizeof(float) == 8*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED);
else if (sizeof(float) == 16*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED);
else return false;
}
} // namespace embree

View file

@ -0,0 +1,127 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "tutorial_device.isph"
#include "../math/random_sampler.isph"
#include "../math/sampling.isph"
#include "scene_device.h"
/* the scene to render */
extern RTCScene g_scene;
extern uniform float g_debug;
/* returns the point seen through specified pixel */
export uniform bool device_pick(const uniform float x,
const uniform float y,
const uniform ISPCCamera& camera,
uniform Vec3f& hitPos)
{
/* initialize ray */
uniform Ray1 ray;
ray.org = make_Vec3f_(camera.xfm.p);
ray.dir = make_Vec3f_(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz));
ray.tnear = 0.0f;
ray.tfar = inf;
ray.geomID = RTC_INVALID_GEOMETRY_ID;
ray.primID = RTC_INVALID_GEOMETRY_ID;
ray.mask = -1;
ray.time = g_debug;
/* intersect ray with scene */
rtcIntersect1(g_scene,RTCRayHit1_(ray));
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
hitPos = make_Vec3f(0.0f,0.0f,0.0f);
return false;
}
else {
hitPos = ray.org + ray.tfar*ray.dir;
return true;
}
}
Vec2f getTextureCoordinatesSubdivMesh(void* uniform _mesh, const unsigned int primID, const float u, const float v)
{
uniform ISPCSubdivMesh *uniform mesh = (uniform ISPCSubdivMesh *uniform )_mesh;
Vec2f st;
st.x = u;
st.y = v;
if (mesh && mesh->texcoord_indices)
{
assert(primID < mesh->numFaces);
const unsigned int face_offset = mesh->face_offsets[primID];
if (mesh->verticesPerFace[primID] == 3)
{
const unsigned int t0 = mesh->texcoord_indices[face_offset+0];
const unsigned int t1 = mesh->texcoord_indices[face_offset+1];
const unsigned int t2 = mesh->texcoord_indices[face_offset+2];
const Vec2f txt0 = mesh->texcoords[t0];
const Vec2f txt1 = mesh->texcoords[t1];
const Vec2f txt2 = mesh->texcoords[t2];
const float w = 1.0f - u - v;
st = w * txt0 + u * txt1 + v * txt2;
}
else if (mesh->verticesPerFace[primID] == 4)
{
const unsigned int t0 = mesh->texcoord_indices[face_offset+0];
const unsigned int t1 = mesh->texcoord_indices[face_offset+1];
const unsigned int t2 = mesh->texcoord_indices[face_offset+2];
const unsigned int t3 = mesh->texcoord_indices[face_offset+3];
const Vec2f txt0 = mesh->texcoords[t0];
const Vec2f txt1 = mesh->texcoords[t1];
const Vec2f txt2 = mesh->texcoords[t2];
const Vec2f txt3 = mesh->texcoords[t3];
const float u0 = u;
const float v0 = v;
const float u1 = 1.0f - u;
const float v1 = 1.0f - v;
st = u1*v1 * txt0 + u0*v1* txt1 + u0*v0 * txt2 + u1*v0* txt3;
}
}
return st;
}
float getTextureTexel1f(const uniform Texture* uniform texture, float s, float t)
{
if (!texture) return 0.0f;
int iu = (int)floor(s * (float)(texture->width));
iu = iu % texture->width; if (iu < 0) iu += texture->width;
int iv = (int)floor(t * (float)(texture->height));
iv = iv % texture->height; if (iv < 0) iv += texture->height;
if (texture->format == Texture_FLOAT32)
{
uniform float *uniform data = (uniform float *uniform)texture->data;
return data[iv*texture->width + iu];
}
else if (texture->format == Texture_RGBA8)
{
const int offset = (iv * texture->width + iu) * 4;
uniform unsigned int8 * uniform t = (uniform unsigned int8* uniform)texture->data;
return t[offset+0]*(1.0f/255.0f);
}
return 0.0f;
}
Vec3f getTextureTexel3f(const uniform Texture* uniform texture, float s, float t)
{
if (!texture) return make_Vec3f(0.0f,0.0f,0.0f);
int iu = (int)floor(s * (float)(texture->width));
iu = iu % texture->width; if (iu < 0) iu += texture->width;
int iv = (int)floor(t * (float)(texture->height));
iv = iv % texture->height; if (iv < 0) iv += texture->height;
if (texture->format == Texture_RGBA8)
{
const int offset = (iv * texture->width + iu) * 4;
uniform unsigned int8 * uniform t = (uniform unsigned int8* uniform)texture->data;
const unsigned int8 r = t[offset+0];
const unsigned int8 g = t[offset+1];
const unsigned int8 b = t[offset+2];
return make_Vec3f( (float)r * 1.0f/255.0f, (float)g * 1.0f/255.0f, (float)b * 1.0f/255.0f );
}
return make_Vec3f(0.0f,0.0f,0.0f);
}

View file

@ -0,0 +1,168 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#define _CRT_SECURE_NO_WARNINGS
/* size of screen tiles */
#define TILE_SIZE_X 8
#define TILE_SIZE_Y 8
/* vertex and triangle layout */
struct Vertex { float x,y,z,r; }; // FIXME: rename to Vertex4f
struct Triangle { int v0, v1, v2; };
#include "../device_default.isph"
/* include optional vector library */
#include "../math/math.isph"
#include "../math/vec.isph"
#include "../math/affinespace.isph"
#include "../core/ray.isph"
#include "camera.isph"
#include "scene_device.h"
#include "noise.isph"
#if !defined(ISPC)
#include "../../../common/algorithms/parallel_for.h"
#endif
#if defined(EMBREE_SYCL_TUTORIAL)
inline sycl::nd_range<2> make_nd_range(unsigned int size0, unsigned int size1)
{
const sycl::range<2> wg_size = sycl::range<2>(4,4);
/* align iteration space to work group size */
size0 = ((size0 + wg_size[0] - 1) / wg_size[0]) * wg_size[0];
size1 = ((size1 + wg_size[1] - 1) / wg_size[1]) * wg_size[1];
return sycl::nd_range(sycl::range(size0,size1),wg_size);
}
#endif
enum Shader {
SHADER_DEFAULT,
SHADER_EYELIGHT,
SHADER_OCCLUSION,
SHADER_UV,
SHADER_TEXCOORDS,
SHADER_TEXCOORDS_GRID,
SHADER_NG,
SHADER_CYCLES,
SHADER_GEOMID,
SHADER_GEOMID_PRIMID,
SHADER_AO
};
extern RTCDevice g_device;
extern uniform RTCRayQueryFlags g_iflags_coherent;
extern uniform RTCRayQueryFlags g_iflags_incoherent;
extern uniform Shader shader;
/* error reporting function */
unmasked void error_handler(void* uniform userPtr, uniform RTCError code, const uniform int8* uniform str = NULL);
/* returns time stamp counter */
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
inline int64 get_tsc() { return 0; }
#else
extern "C" uniform int64 get_tsc();
#endif
#if defined(__WIN32__) && defined(__INTEL_LLVM_COMPILER)
/* declare some standard library functions */
extern "C" __declspec(dllimport) void abort ();
extern "C" __declspec(dllimport) void exit(int);
extern "C" __declspec(dllimport) int puts ( const char* str );
extern "C" __declspec(dllimport) int putchar ( int character );
#else
/* declare some standard library functions */
extern "C" void abort ();
extern "C" void exit(uniform int);
extern "C" uniform int puts ( const uniform int8* uniform str );
extern "C" uniform int putchar ( uniform int character );
#endif
/* face forward for shading normals */
inline Vec3f faceforward( const Vec3f& N, const Vec3f& I, const Vec3f& Ng ) {
Vec3f NN = N; return dot(I, Ng) < 0 ? NN : neg(NN);
}
/* GLFW keys codes */
#if !defined(GLFW_KEY_F1)
#define GLFW_KEY_F1 290
#define GLFW_KEY_F2 291
#define GLFW_KEY_F3 292
#define GLFW_KEY_F4 293
#define GLFW_KEY_F5 294
#define GLFW_KEY_F6 295
#define GLFW_KEY_F7 296
#define GLFW_KEY_F8 297
#define GLFW_KEY_F9 298
#define GLFW_KEY_F10 299
#define GLFW_KEY_F11 300
#define GLFW_KEY_F12 301
#endif
extern void device_key_pressed_default(uniform int key);
extern void (* uniform key_pressed_handler)(uniform int key);
export void renderFrameStandard(uniform int* uniform pixels,
const uniform unsigned int width,
const uniform unsigned int height,
const uniform float time,
const uniform ISPCCamera& camera);
uniform unsigned int getNumHWThreads();
#if defined(ISPC)
#define ALIGNED_STRUCT_(x)
#define __aligned(x)
#define MAYBE_UNUSED
#endif
/* draws progress bar */
extern "C" unmasked void progressStart();
extern "C" unmasked uniform bool progressMonitor(void* uniform ptr, const uniform double n);
extern "C" unmasked void progressEnd();
SYCL_EXTERNAL Vec2f getTextureCoordinatesSubdivMesh(void* uniform mesh, const unsigned int primID, const float u, const float v);
SYCL_EXTERNAL float getTextureTexel1f(const uniform Texture* uniform texture, float u, float v);
SYCL_EXTERNAL Vec3f getTextureTexel3f(const uniform Texture* uniform texture, float u, float v);
enum ISPCInstancingMode { ISPC_INSTANCING_NONE, ISPC_INSTANCING_GEOMETRY, ISPC_INSTANCING_GROUP };
/* ray statistics */
#if !defined(TASKING_PPL) // not supported with PPL because threadIndex is not unique and atomics are too expensive
#define RAY_STATS
#endif
struct RayStats
{
int numRays;
int pad[32-1];
};
#if defined(RAY_STATS)
#if defined(ISPC)
inline void RayStats_addRay(uniform RayStats& stats) { stats.numRays += popcnt(lanemask()); }
inline void RayStats_addShadowRay(uniform RayStats& stats) { stats.numRays += popcnt(lanemask()); }
#else // C++
__forceinline void RayStats_addRay(RayStats& stats) { stats.numRays++; }
__forceinline void RayStats_addShadowRay(RayStats& stats) { stats.numRays++; }
#endif
#else // disabled
inline void RayStats_addRay(uniform RayStats& stats) {}
inline void RayStats_addShadowRay(uniform RayStats& stats) {}
#endif
extern uniform RayStats* uniform g_stats;
inline bool nativePacketSupported(RTCDevice device)
{
if (sizeof(float) == 1*4) return true;
else if (sizeof(float) == 4*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED);
else if (sizeof(float) == 8*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED);
else if (sizeof(float) == 16*4) return rtcGetDeviceProperty(device,RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED);
else return false;
}