55#ifndef __NBL_ASSET_MATERIAL_COMPILER_V2_IR_H_INCLUDED__
66#define __NBL_ASSET_MATERIAL_COMPILER_V2_IR_H_INCLUDED__
77
8- #include " IRNode.h"
9- #include < nbl/asset/ICPUImageView.h>
10- #include < nbl/asset/ICPUSampler.h>
118#include < nbl/core/IReferenceCounted.h>
129#include < nbl/core/containers/refctd_dynamic_array.h>
1310
1411namespace nbl ::asset::material_compiler::v2::ir {
1512
16- // Visit the tree of nodes with specified node as root in DFS order.
17- template <typename Visitor>
18- NBL_FORCE_INLINE void traverse_node_tree_dfs (NodeHandle root, Visitor visitor) {
19- core::vector<NodeHandle> worklist;
20- worklist.push_back (root);
21- while (!worklist.empty ()) {
22- NodeHandle cur = worklist.back ();
23- worklist.pop_back ();
24- visitor (cur);
25- for (OffsetToValue value_offset : cur->get_value_offsets ())
26- if (cur->value (value_offset).is_node ())
27- worklist.push_back (cur->value (value_offset).get_node ());
28- }
29- }
30-
3113// Traverse the tree of nodes in reverse bfs order which
3214// gurantess we visit all nodes gets depended by upper level
3315// nodes are visited beforehand. (kahn's algorithm)
@@ -54,20 +36,9 @@ NBL_FORCE_INLINE void traverse_node_tree_topological(NodeHandle root,
5436using INodeCacheSet =
5537 core::unordered_set<NodeHandle, NodeHandleHasher, NodeHandleComparor>;
5638
57- class NBL_API IRDAG : public core::IReferenceCounted {
39+ class NBL_API IRDAG : public core::IReferenceCounted
40+ {
5841public:
59- IRDAG () {}
60-
61- ~IRDAG () {}
62-
63- INodeHash get_hash () const {
64- INodeHash hash_value = 0 ;
65- for (NodeHandle root : root_nodes) {
66- hash_value ^= root->get_hash ();
67- }
68- return hash_value;
69- }
70-
7142 // Insert subdag into this DAG
7243 NodeHandle insert_subdag (IRDAG &dag) {
7344 assert (dag.root_nodes .size () == 1 ); // we must have only one root
@@ -102,125 +73,8 @@ class NBL_API IRDAG : public core::IReferenceCounted {
10273 return nodes.create <ST>(std::forward<Args>(args)...);
10374 }
10475
105- TextureHandle create_texture (const TextureSource &texture) {
106- auto it = texture_cache.find (texture);
107- if (it != texture_cache.end ())
108- return it->second ;
109- return texture_cache[texture] = textures.create <TextureSource>(
110- texture.image , texture.sampler , texture.scale );
111- }
112-
113- void add_root (NodeHandle node) { root_nodes.push_back (node); }
114-
115- void remove_node (NodeHandle node) { nodes.remove (node); }
116-
117- const core::set<NodeHandle> &get_nodes () const { return nodes.get_handles (); }
118-
119- const core::vector<NodeHandle> &get_roots () const { return root_nodes; }
120-
121- private:
122- template <typename T, typename MemMgr> class CHandleManager {
123- public:
124- using HandleId = Handle<T>::HandleId;
125-
126- ~CHandleManager () {
127- while (!handles.empty ())
128- remove (*handles.rbegin ());
129- }
130-
131- template <typename ST, typename ... Args> Handle<T> create (Args &&...args) {
132- ST *ptr = alloc<ST>(std::forward<Args>(args)...);
133- ptrdiff_t offset = reinterpret_cast <uint8_t *>(ptr) - mem_mgr.get_base ();
134- HandleId new_id = offset;
135- return Handle<T>(reinterpret_cast <uint8_t *>(mem_mgr.get_base ()), new_id);
136- }
137-
138- void remove (Handle<T> handle) {
139- T &obj = *handle;
140- obj.~T ();
141- handles.erase (handle);
142- }
143-
144- const core::set<Handle<T>> &get_handles () const { return handles; }
145-
146- private:
147- template <typename ST, typename ... Args> ST *alloc (Args &&...args) {
148- uint8_t *ptr = mem_mgr.alloc (sizeof (ST));
149- return new (ptr) ST (std::forward<Args>(args)...);
150- }
151-
152- core::set<Handle<T>> handles;
153- MemMgr mem_mgr;
15476 };
15577
156- class SBackingMemManager {
157- _NBL_STATIC_INLINE_CONSTEXPR size_t INITIAL_MEM_SIZE = 1ull << 20 ;
158- _NBL_STATIC_INLINE_CONSTEXPR size_t MAX_MEM_SIZE = 1ull << 20 ;
159- _NBL_STATIC_INLINE_CONSTEXPR size_t ALIGNMENT = _NBL_SIMD_ALIGNMENT;
160-
161- uint8_t *mem;
162- size_t currSz;
163- using addr_alctr_t = core::LinearAddressAllocator<uint32_t >;
164- addr_alctr_t addrAlctr;
165-
166- public:
167- SBackingMemManager ()
168- : mem(nullptr ), currSz(INITIAL_MEM_SIZE),
169- addrAlctr (nullptr , 0u , 0u , ALIGNMENT, MAX_MEM_SIZE) {
170- mem = reinterpret_cast <uint8_t *>(_NBL_ALIGNED_MALLOC (currSz, ALIGNMENT));
171- }
172- ~SBackingMemManager () { _NBL_ALIGNED_FREE (mem); }
173-
174- uint8_t *get_base () const { return mem; }
175-
176- uint8_t *alloc (size_t bytes) {
177- auto addr = addrAlctr.alloc_addr (bytes, ALIGNMENT);
178- assert (addr != addr_alctr_t ::invalid_address);
179- // TODO reallocation will invalidate all pointers to nodes, so...
180- // 1) never reallocate (just have reasonably big buffer for nodes)
181- // 2) make some node_handle class that will work as pointer but is based
182- // on offset instead of actual address
183- if (addr + bytes > currSz) {
184- size_t newSz = currSz << 1 ;
185- if (newSz > MAX_MEM_SIZE) {
186- addrAlctr.free_addr (addr, bytes);
187- return nullptr ;
188- }
189-
190- void *newMem = _NBL_ALIGNED_MALLOC (newSz, ALIGNMENT);
191- memcpy (newMem, mem, currSz);
192- _NBL_ALIGNED_FREE (mem);
193- mem = reinterpret_cast <uint8_t *>(newMem);
194- currSz = newSz;
195- }
196-
197- return mem + addr;
198- }
199-
200- uint32_t getAllocatedSize () const { return addrAlctr.get_allocated_size (); }
201-
202- void freeLastAllocatedBytes (uint32_t _bytes) {
203- assert (addrAlctr.get_allocated_size () >= _bytes);
204- const uint32_t newCursor = addrAlctr.get_allocated_size () - _bytes;
205- addrAlctr.reset (newCursor);
206- }
207- };
208-
209- core::vector<NodeHandle> root_nodes;
210- CHandleManager<INode, SBackingMemManager> nodes;
211- CHandleManager<TextureSource, SBackingMemManager> textures;
212- core::unordered_map<TextureSource, TextureHandle, TextureSourceHasher,
213- TextureSourceComparor>
214- texture_cache;
215- };
216-
217- NBL_FORCE_INLINE void dead_strip_pass (IRDAG &dag) {
218- core::set<NodeHandle> dead = dag.get_nodes ();
219- for (NodeHandle root : dag.get_roots ())
220- traverse_node_tree_dfs (root, [&](NodeHandle node) { dead.erase (node); });
221- for (NodeHandle node : dead)
222- dag.remove_node (node);
223- }
22478
22579NBL_FORCE_INLINE void subexpression_elimination_pass (IRDAG &dag) {
22680 INodeCacheSet cache;
0 commit comments