NvBlastChunkHierarchy.h
Go to the documentation of this file.
1 // This code contains NVIDIA Confidential Information and is disclosed to you
2 // under a form of NVIDIA software license agreement provided separately to you.
3 //
4 // Notice
5 // NVIDIA Corporation and its licensors retain all intellectual property and
6 // proprietary rights in and to this software and related documentation and
7 // any modifications thereto. Any use, reproduction, disclosure, or
8 // distribution of this software and related documentation without an express
9 // license agreement from NVIDIA Corporation is strictly prohibited.
10 //
11 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
12 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
13 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
14 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
15 //
16 // Information and code furnished is believed to be accurate and reliable.
17 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
18 // information or for any infringement of patents or other rights of third parties that may
19 // result from its use. No license is granted by implication or otherwise under any patent
20 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
21 // This code supersedes and replaces all information previously supplied.
22 // NVIDIA Corporation products are not authorized for use as critical
23 // components in life support devices or systems without express written approval of
24 // NVIDIA Corporation.
25 //
26 // Copyright (c) 2016-2020 NVIDIA Corporation. All rights reserved.
27 
28 
29 #ifndef NVBLASTCHUNKHIERARCHY_H
30 #define NVBLASTCHUNKHIERARCHY_H
31 
32 
33 #include "NvBlastIndexFns.h"
34 #include "NvBlastDLink.h"
35 #include "NvBlast.h"
36 #include "NvBlastAssert.h"
37 #include "NvBlastIteratorBase.h"
38 
39 
40 namespace Nv
41 {
42 namespace Blast
43 {
44 
49 class ChunkDepthFirstIt : public IteratorBase<uint32_t>
50 {
51 public:
53  ChunkDepthFirstIt(const NvBlastChunk* chunks, uint32_t startChunkIndex, uint32_t chunkIndexLimit) :
54  IteratorBase<uint32_t>(startChunkIndex), m_chunks(chunks), m_stop(startChunkIndex), m_limit(chunkIndexLimit)
55  {
56  if (m_curr >= m_limit)
57  {
58  m_curr = invalidIndex<uint32_t>();
59  }
60  }
61 
63  uint32_t operator ++ ()
64  {
66  const NvBlastChunk* chunk = m_chunks + m_curr;
67  if (chunk->childIndexStop > chunk->firstChildIndex && chunk->firstChildIndex < m_limit)
68  {
69  m_curr = chunk->firstChildIndex;
70  }
71  else
72  {
73  for (;;)
74  {
75  if (m_curr == m_stop)
76  {
77  m_curr = invalidIndex<uint32_t>();
78  break;
79  }
80  NVBLAST_ASSERT(!isInvalidIndex(chunk->parentChunkIndex)); // This should not be possible with this search
81  const NvBlastChunk* parentChunk = m_chunks + chunk->parentChunkIndex;
82  if (++m_curr < parentChunk->childIndexStop)
83  {
84  break; // Sibling chunk is valid, that's the next chunk
85  }
86  m_curr = chunk->parentChunkIndex;
87  chunk = parentChunk;
88  }
89  }
90  return m_curr;
91  }
92 
93 private:
94  const NvBlastChunk* m_chunks;
95  uint32_t m_stop;
96  uint32_t m_limit;
97 };
98 
99 
106 (
107 uint32_t* chunkIndices,
108 uint32_t chunkIndicesSize,
109 const NvBlastChunk* chunks,
110 uint32_t chunkIndex,
111 bool includeRoot = true,
112 uint32_t chunkIndexLimit = invalidIndex<uint32_t>()
113 )
114 {
115  if (chunkIndicesSize == 0)
116  {
117  return 0;
118  }
119  uint32_t chunkIndexCount = 0;
120  bool rootHandled = false;
121  if (includeRoot)
122  {
123  chunkIndices[chunkIndexCount++] = chunkIndex;
124  rootHandled = true;
125  }
126  for (uint32_t curr = 0; !rootHandled || curr < chunkIndexCount;)
127  {
128  const NvBlastChunk& chunk = chunks[rootHandled ? chunkIndices[curr] : chunkIndex];
129  if (chunk.firstChildIndex < chunkIndexLimit)
130  {
131  const uint32_t childIndexStop = chunk.childIndexStop < chunkIndexLimit ? chunk.childIndexStop : chunkIndexLimit;
132  const uint32_t childIndexBufferStop = chunk.firstChildIndex + (chunkIndicesSize - chunkIndexCount);
133  const uint32_t stop = childIndexStop < childIndexBufferStop ? childIndexStop : childIndexBufferStop;
134  for (uint32_t childIndex = chunk.firstChildIndex; childIndex < stop; ++childIndex)
135  {
136  chunkIndices[chunkIndexCount++] = childIndex;
137  }
138  }
139  if (rootHandled)
140  {
141  ++curr;
142  }
143  rootHandled = true;
144  }
145  return chunkIndexCount;
146 }
147 
148 
152 template<class VisibilityRep>
154 (
155 VisibilityRep* actors,
156 IndexDLink<uint32_t>* visibleChunkIndexLinks,
157 uint32_t* chunkActorIndices,
158 uint32_t actorIndex,
159 uint32_t supportChunkIndex,
160 const NvBlastChunk* chunks,
161 uint32_t upperSupportChunkCount
162 )
163 {
164  uint32_t chunkIndex = supportChunkIndex;
165  uint32_t chunkActorIndex = chunkActorIndices[supportChunkIndex];
166  uint32_t newChunkActorIndex = actorIndex;
167  VisibilityRep& thisActor = actors[actorIndex];
168 
169  do
170  {
171  if (chunkActorIndex == newChunkActorIndex)
172  {
173  break; // Nothing to do
174  }
175 
176  const uint32_t parentChunkIndex = chunks[chunkIndex].parentChunkIndex;
177  const uint32_t parentChunkActorIndex = parentChunkIndex != invalidIndex<uint32_t>() ? chunkActorIndices[parentChunkIndex] : invalidIndex<uint32_t>();
178  const bool chunkVisible = chunkActorIndex != parentChunkActorIndex;
179 
180  // If the chunk is visible, it needs to be removed from its old actor's visibility list
181  if (chunkVisible && !isInvalidIndex(chunkActorIndex))
182  {
183  VisibilityRep& chunkActor = actors[chunkActorIndex];
184  IndexDList<uint32_t>().removeFromList(chunkActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, chunkIndex);
185  --chunkActor.m_visibleChunkCount;
186  }
187 
188  // Now update the chunk's actor index
189  const uint32_t oldChunkActorIndex = chunkActorIndices[chunkIndex];
190  chunkActorIndices[chunkIndex] = newChunkActorIndex;
191  if (newChunkActorIndex != invalidIndex<uint32_t>() && parentChunkActorIndex != newChunkActorIndex)
192  {
193  // The chunk is now visible. Add it to this actor's visibility list
194  IndexDList<uint32_t>().insertListHead(thisActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, chunkIndex);
195  ++thisActor.m_visibleChunkCount;
196  // Remove its children from this actor's visibility list
197  if (actorIndex != oldChunkActorIndex)
198  {
199  const NvBlastChunk& chunk = chunks[chunkIndex];
200  if (chunk.firstChildIndex < upperSupportChunkCount) // Only need to deal with upper-support children
201  {
202  for (uint32_t childChunkIndex = chunk.firstChildIndex; childChunkIndex < chunk.childIndexStop; ++childChunkIndex)
203  {
204  if (chunkActorIndices[childChunkIndex] == actorIndex)
205  {
206  IndexDList<uint32_t>().removeFromList(thisActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, childChunkIndex);
207  --thisActor.m_visibleChunkCount;
208  }
209  }
210  }
211  }
212  }
213 
214  if (parentChunkIndex != invalidIndex<uint32_t>())
215  {
216  // If all of its siblings have the same index, then the parent will too. Otherwise, the parent will have an invalid index and its children will be visible
217  const NvBlastChunk& parentChunk = chunks[parentChunkIndex];
218  bool uniform = true;
219  for (uint32_t childChunkIndex = parentChunk.firstChildIndex; uniform && childChunkIndex < parentChunk.childIndexStop; ++childChunkIndex)
220  {
221  uniform = (newChunkActorIndex == chunkActorIndices[childChunkIndex]);
222  }
223  if (!uniform)
224  {
225  newChunkActorIndex = invalidIndex<uint32_t>();
226  for (uint32_t childChunkIndex = parentChunk.firstChildIndex; childChunkIndex < parentChunk.childIndexStop; ++childChunkIndex)
227  {
228  const uint32_t childChunkActorIndex = chunkActorIndices[childChunkIndex];
229  if (childChunkActorIndex != invalidIndex<uint32_t>() && childChunkActorIndex == parentChunkActorIndex)
230  {
231  // The child was invisible. Add it to its actor's visibility list
232  VisibilityRep& childChunkActor = actors[childChunkActorIndex];
233  IndexDList<uint32_t>().insertListHead(childChunkActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, childChunkIndex);
234  ++childChunkActor.m_visibleChunkCount;
235  }
236  }
237  }
238  }
239 
240  // Climb the hierarchy
241  chunkIndex = parentChunkIndex;
242  chunkActorIndex = parentChunkActorIndex;
243  } while (chunkIndex != invalidIndex<uint32_t>());
244 }
245 
246 } // namespace Blast
247 } // namespace Nv
248 
249 
250 #endif // ifndef NVBLASTCHUNKHIERARCHY_H
ChunkDepthFirstIt(const NvBlastChunk *chunks, uint32_t startChunkIndex, uint32_t chunkIndexLimit)
Definition: NvBlastChunkHierarchy.h:53
Definition: NvBlastChunkHierarchy.h:49
uint32_t m_curr
Definition: NvBlastIteratorBase.h:58
NV_INLINE bool isInvalidIndex(T index)
Definition: NvBlastIndexFns.h:57
NV_INLINE uint32_t enumerateChunkHierarchyBreadthFirst(uint32_t *chunkIndices, uint32_t chunkIndicesSize, const NvBlastChunk *chunks, uint32_t chunkIndex, bool includeRoot=true, uint32_t chunkIndexLimit=invalidIndex< uint32_t >())
Definition: NvBlastChunkHierarchy.h:106
#define NVBLAST_ASSERT(exp)
Definition: NvBlastAssert.h:37
uint32_t childIndexStop
Definition: NvBlastTypes.h:177
#define NV_INLINE
Definition: NvPreprocessor.h:350
Definition: NvBlastDLink.h:50
Definition: NvBlastTypes.h:152
uint32_t parentChunkIndex
Definition: NvBlastTypes.h:167
void updateVisibleChunksFromSupportChunk(VisibilityRep *actors, IndexDLink< uint32_t > *visibleChunkIndexLinks, uint32_t *chunkActorIndices, uint32_t actorIndex, uint32_t supportChunkIndex, const NvBlastChunk *chunks, uint32_t upperSupportChunkCount)
Definition: NvBlastChunkHierarchy.h:154
Definition: NvBlastIteratorBase.h:45
Definition: NvBlastArray.h:37
uint32_t operator++()
Definition: NvBlastChunkHierarchy.h:63
uint32_t firstChildIndex
Definition: NvBlastTypes.h:172