Path: blob/master/thirdparty/embree/kernels/common/scene.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "default.h"6#include "device.h"7#include "builder.h"8#include "scene_triangle_mesh.h"9#include "scene_quad_mesh.h"10#include "scene_user_geometry.h"11#include "scene_instance.h"12#include "scene_instance_array.h"13#include "scene_curves.h"14#include "scene_line_segments.h"15#include "scene_subdiv_mesh.h"16#include "scene_grid_mesh.h"17#include "scene_points.h"18#include "../subdiv/tessellation_cache.h"1920#include "acceln.h"21#include "geometry.h"2223#if defined(EMBREE_SYCL_SUPPORT)24#include "../sycl/rthwif_embree_builder.h"25#endif2627#if !defined(EMBREE_SYCL_SUPPORT)28namespace sycl {29struct queue;30}31#endif32namespace embree33{34struct TaskGroup;3536/*! Base class all scenes are derived from */37class __aligned(16) Scene : public AccelN38{39public:40template<typename Ty, bool mblur = false>41class Iterator42{43public:44Iterator () {}4546Iterator (Scene* scene, bool all = false)47: scene(scene), all(all) {}4849__forceinline Ty* at(const size_t i)50{51Geometry* geom = scene->geometries[i].ptr;52if (geom == nullptr) return nullptr;53if (!all && !geom->isEnabled()) return nullptr;54const size_t mask = geom->getTypeMask() & Ty::geom_type;55if (!(mask)) return nullptr;56if ((geom->numTimeSteps != 1) != mblur) return nullptr;57return (Ty*) geom;58}5960__forceinline Ty* operator[] (const size_t i) {61return at(i);62}6364__forceinline size_t numPrimitives() const {65return scene->getNumPrimitives(Ty::geom_type,mblur);66}6768__forceinline size_t maxPrimitivesPerGeometry()69{70size_t ret = 0;71for (size_t i=0; i<scene->size(); i++) {72Ty* mesh = at(i);73if (mesh == nullptr) continue;74ret = max(ret,mesh->size());75}76return ret;77}7879__forceinline unsigned int maxGeomID()80{81unsigned int ret = 0;82for (size_t i=0; i<scene->size(); i++) {83Ty* mesh = at(i);84if (mesh == nullptr) continue;85ret = max(ret,(unsigned int)i);86}87return ret;88}8990__forceinline unsigned maxTimeStepsPerGeometry()91{92unsigned ret = 0;93for (size_t i=0; i<scene->size(); i++) {94Ty* mesh = at(i);95if (mesh == nullptr) continue;96ret = max(ret,mesh->numTimeSteps);97}98return ret;99}100101__forceinline size_t size() const {102return scene->size();103}104105106private:107Scene* scene;108bool all;109};110111class Iterator2112{113public:114Iterator2 () {}115116Iterator2 (Scene* scene, Geometry::GTypeMask typemask, bool mblur)117: scene(scene), typemask(typemask), mblur(mblur) {}118119__forceinline Geometry* at(const size_t i)120{121Geometry* geom = scene->geometries[i].ptr;122if (geom == nullptr) return nullptr;123if (!geom->isEnabled()) return nullptr;124if (!(geom->getTypeMask() & typemask)) return nullptr;125if ((geom->numTimeSteps != 1) != mblur) return nullptr;126return geom;127}128129__forceinline Geometry* operator[] (const size_t i) {130return at(i);131}132133__forceinline size_t size() const {134return scene->size();135}136137private:138Scene* scene;139Geometry::GTypeMask typemask;140bool mblur;141};142143public:144145/*! Scene construction */146Scene (Device* device);147148/*! Scene destruction */149~Scene () noexcept;150151private:152153/*! class is non-copyable */154Scene (const Scene& other) DELETED; // do not implement155Scene& operator= (const Scene& other) DELETED; // do not implement156157public:158void createTriangleAccel();159void createTriangleMBAccel();160void createQuadAccel();161void createQuadMBAccel();162void createHairAccel();163void createHairMBAccel();164void createSubdivAccel();165void createSubdivMBAccel();166void createUserGeometryAccel();167void createUserGeometryMBAccel();168void createInstanceAccel();169void createInstanceMBAccel();170void createInstanceExpensiveAccel();171void createInstanceExpensiveMBAccel();172void createInstanceArrayAccel();173void createInstanceArrayMBAccel();174void createGridAccel();175void createGridMBAccel();176177/*! prints statistics about the scene */178void printStatistics();179180/*! clears the scene */181void clear();182183/*! detaches some geometry */184void detachGeometry(size_t geomID);185186void setBuildQuality(RTCBuildQuality quality_flags);187RTCBuildQuality getBuildQuality() const;188189void setSceneFlags(RTCSceneFlags scene_flags);190RTCSceneFlags getSceneFlags() const;191192void build_cpu_accels();193void build_gpu_accels();194void commit_internal (bool join);195#if defined(EMBREE_SYCL_SUPPORT)196sycl::event commit (bool join, sycl::queue queue);197#endif198void commit (bool join);199void commit_task ();200void build () {}201202Scene* getTraversable();203204/* return number of geometries */205#if defined(__SYCL_DEVICE_ONLY__)206__forceinline size_t size() const { return num_geometries; }207#else208__forceinline size_t size() const { return geometries.size(); }209#endif210211/* bind geometry to the scene */212unsigned int bind (unsigned geomID, Ref<Geometry> geometry);213214/* determines if scene is modified */215__forceinline bool isModified() const { return modified; }216217/* sets modified flag */218__forceinline void setModified(bool f = true) {219modified = f;220}221222__forceinline bool hasMotionBlur() const { return maxTimeSegments > 1; };223224__forceinline uint32_t getMaxTimeSegments() const { return maxTimeSegments; };225226#if !defined(__SYCL_DEVICE_ONLY__)227__forceinline bool isGeometryModified(size_t geomID)228{229Ref<Geometry>& g = geometries[geomID];230if (!g) return false;231return g->getModCounter() > geometryModCounters_[geomID];232}233#endif234235protected:236237void checkIfModifiedAndSet ();238239public:240241#if defined(__SYCL_DEVICE_ONLY__)242/* get mesh by ID */243__forceinline Geometry* get(size_t i) { return geometries_device[i]; }244__forceinline const Geometry* get(size_t i) const { return geometries_device[i]; }245246template<typename Mesh>247__forceinline Mesh* get(size_t i) {248return (Mesh*)geometries_device[i];249}250template<typename Mesh>251__forceinline const Mesh* get(size_t i) const {252return (Mesh*)geometries_device[i];253}254255template<typename Mesh>256__forceinline Mesh* getSafe(size_t i) {257if (geometries_device[i] == nullptr) return nullptr;258if (!(geometries_device[i]->getTypeMask() & Mesh::geom_type)) return nullptr;259else return (Mesh*) geometries_device[i];260}261#else262/* get mesh by ID */263__forceinline Geometry* get(size_t i) { assert(i < geometries.size()); return geometries[i].ptr; }264__forceinline const Geometry* get(size_t i) const { assert(i < geometries.size()); return geometries[i].ptr; }265266template<typename Mesh>267__forceinline Mesh* get(size_t i) {268assert(i < geometries.size());269assert(geometries[i]->getTypeMask() & Mesh::geom_type);270return (Mesh*)geometries[i].ptr;271}272template<typename Mesh>273__forceinline const Mesh* get(size_t i) const {274assert(i < geometries.size());275assert(geometries[i]->getTypeMask() & Mesh::geom_type);276return (Mesh*)geometries[i].ptr;277}278279template<typename Mesh>280__forceinline Mesh* getSafe(size_t i) {281assert(i < geometries.size());282if (geometries[i] == null) return nullptr;283if (!(geometries[i]->getTypeMask() & Mesh::geom_type)) return nullptr;284else return (Mesh*) geometries[i].ptr;285}286#endif287288289#if !defined(__SYCL_DEVICE_ONLY__)290__forceinline Ref<Geometry> get_locked(size_t i) {291Lock<MutexSys> lock(geometriesMutex);292assert(i < geometries.size());293return geometries[i];294}295#endif296297/* flag decoding */298__forceinline bool isFastAccel() const { return !isCompactAccel() && !isRobustAccel(); }299__forceinline bool isCompactAccel() const { return scene_flags & RTC_SCENE_FLAG_COMPACT; }300__forceinline bool isRobustAccel() const { return scene_flags & RTC_SCENE_FLAG_ROBUST; }301__forceinline bool isStaticAccel() const { return !(scene_flags & RTC_SCENE_FLAG_DYNAMIC); }302__forceinline bool isDynamicAccel() const { return scene_flags & RTC_SCENE_FLAG_DYNAMIC; }303304__forceinline bool hasArgumentFilterFunction() const {305return scene_flags & RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS;306}307308__forceinline bool hasGeometryFilterFunction() {309return world.numFilterFunctions != 0;310}311312__forceinline bool hasFilterFunction() {313return hasArgumentFilterFunction() || hasGeometryFilterFunction();314}315316void* createQBVH6Accel();317318#if defined(EMBREE_SYCL_SUPPORT)319private:320void syncWithDevice();321sycl::event syncWithDevice(sycl::queue queue);322#endif323324public:325Device* device;326Scene* scene_device;327328public:329IDPool<unsigned,0xFFFFFFFE> id_pool;330Device::vector<Ref<Geometry>> geometries = device; //!< list of all user geometries331avector<unsigned int> geometryModCounters_;332Device::vector<float*> vertices = device;333334public:335/* these are to detect if we need to recreate the acceleration structures */336bool flags_modified;337unsigned int enabled_geometry_types;338339RTCSceneFlags scene_flags;340RTCBuildQuality quality_flags;341MutexSys buildMutex;342MutexSys geometriesMutex;343344#if defined(EMBREE_SYCL_SUPPORT)345public:346AccelBuffer accelBuffer;347#endif348349private:350bool modified; //!< true if scene got modified351uint32_t maxTimeSegments; //!< maximal number of motion blur time segments in scene352353#if defined(EMBREE_SYCL_SUPPORT)354Geometry** geometries_device; //!< list of all geometries on device355char* geometry_data_device; //!< data buffer of all geometries on device356size_t num_geometries;357size_t geometry_data_byte_size;358359// host buffers used for creating representation of scene/geometry for device360// will be freed after scene commit if the scene is static, otherwise the361// buffers will stay for quicker rebuild.362size_t *offsets;363Geometry **geometries_host;364char *geometry_data_host;365#endif366367public:368369std::unique_ptr<TaskGroup> taskGroup;370371public:372struct BuildProgressMonitorInterface : public BuildProgressMonitor {373BuildProgressMonitorInterface(Scene* scene)374: scene(scene) {}375void operator() (size_t dn) const { scene->progressMonitor(double(dn)); }376private:377Scene* scene;378};379BuildProgressMonitorInterface progressInterface;380RTCProgressMonitorFunction progress_monitor_function;381void* progress_monitor_ptr;382std::atomic<size_t> progress_monitor_counter;383void progressMonitor(double nprims);384void setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr);385386private:387GeometryCounts world; //!< counts for geometry388389public:390391__forceinline size_t numPrimitives() const {392return world.size();393}394395__forceinline size_t getNumPrimitives(Geometry::GTypeMask mask, bool mblur) const396{397size_t count = 0;398399if (mask & Geometry::MTY_TRIANGLE_MESH)400count += mblur ? world.numMBTriangles : world.numTriangles;401402if (mask & Geometry::MTY_QUAD_MESH)403count += mblur ? world.numMBQuads : world.numQuads;404405if (mask & Geometry::MTY_CURVE2)406count += mblur ? world.numMBLineSegments : world.numLineSegments;407408if (mask & Geometry::MTY_CURVE4)409count += mblur ? world.numMBBezierCurves : world.numBezierCurves;410411if (mask & Geometry::MTY_POINTS)412count += mblur ? world.numMBPoints : world.numPoints;413414if (mask & Geometry::MTY_SUBDIV_MESH)415count += mblur ? world.numMBSubdivPatches : world.numSubdivPatches;416417if (mask & Geometry::MTY_USER_GEOMETRY)418count += mblur ? world.numMBUserGeometries : world.numUserGeometries;419420if (mask & Geometry::MTY_INSTANCE_CHEAP)421count += mblur ? world.numMBInstancesCheap : world.numInstancesCheap;422423if (mask & Geometry::MTY_INSTANCE_EXPENSIVE)424count += mblur ? world.numMBInstancesExpensive : world.numInstancesExpensive;425426if (mask & Geometry::MTY_INSTANCE_ARRAY)427count += mblur ? world.numMBInstanceArrays : world.numInstanceArrays;428429if (mask & Geometry::MTY_GRID_MESH)430count += mblur ? world.numMBGrids : world.numGrids;431432return count;433}434435__forceinline size_t getNumSubPrimitives(Geometry::GTypeMask mask, bool mblur) const436{437size_t count = 0;438439if (mask & Geometry::MTY_GRID_MESH)440count += mblur ? world.numMBSubGrids : world.numSubGrids;441442Geometry::GTypeMask new_mask = (Geometry::GTypeMask)(mask & ~Geometry::MTY_GRID_MESH);443count += getNumPrimitives(new_mask, mblur);444445return count;446}447448template<typename Mesh, bool mblur>449__forceinline unsigned getNumTimeSteps()450{451if (!mblur)452return 1;453454Scene::Iterator<Mesh,mblur> iter(this);455return iter.maxTimeStepsPerGeometry();456}457458template<typename Mesh, bool mblur>459__forceinline unsigned int getMaxGeomID()460{461Scene::Iterator<Mesh,mblur> iter(this);462return iter.maxGeomID();463}464};465}466467468