HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
executorInvalidationData.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_EXEC_VDF_EXECUTOR_INVALIDATION_DATA_H
8 #define PXR_EXEC_VDF_EXECUTOR_INVALIDATION_DATA_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/api.h"
15 #include "pxr/exec/vdf/mask.h"
16 #include "pxr/exec/vdf/types.h"
17 
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 ///
22 /// \brief
23 ///
25 {
26  // The possible invalidation states.
27  enum class _MaskState {
28  AllZeros, // All valid
29  AllOnes, // All invalid
30  Sparse // Mask denotes validity
31  };
32 
33 public:
34 
35  /// The value invalidation timestamps shall initially assume.
36  ///
38 
39  /// Noncopyable.
40  ///
43  const VdfExecutorInvalidationData &) = delete;
44 
45  /// Constructor.
46  ///
47  VdfExecutorInvalidationData() : _maskState(_MaskState::AllOnes) {}
48 
49  /// Destructor.
50  ///
52 
53  /// Reset the data to its original, newly constructed state.
54  ///
55  VDF_API
56  void Reset();
57 
58  /// Clones this VdfExecutorInvalidationData instance to \p dest.
59  ///
60  VDF_API
61  void Clone(VdfExecutorInvalidationData *dest) const;
62 
63  /// Returns \c true if the corresponding output has been marked invalid for
64  /// the elements identified by \p invalidationMask. \p wasTouched indicates
65  /// whether the data has been touched during evaluation.
66  ///
67  inline bool IsInvalid(
68  const VdfMask &invalidationMask,
69  const bool wasTouched) const;
70 
71  /// Marks the corresponding output as invalid for the elements identified
72  /// by \p invalidationMask. \p wasTouched indicates whether the data has
73  /// been touched during evaluation.
74  ///
75  /// Returns \c true if the data has been invalidated. If the data was
76  /// already invalid for all bits in \p invalidationMask, this method
77  /// returns \c false.
78  ///
79  inline bool Invalidate(
80  const VdfMask &invalidationMask,
81  const bool wasTouched);
82 
83 private:
84 
85  // Apply the invalidation mask, setting the invalidation mask state
86  // and sparse invalidation mask, if required.
87  inline void _ApplyInvalidationMask(const VdfMask &invalidationMask);
88 
89  // Mask that remembers which elements have been invalidated. This mask
90  // is not an up-to-date record of which elements are valid. It is purely
91  // a log used to prevent subsequent redundant invalidation, and it is
92  // sometimes conservatively reset so as to cause potentially redundant
93  // invalidation.
94  VdfMask _mask;
95 
96  // The invalidation mask state, denoting an entirely valid, entirely
97  // invalid or sparsely invalid buffer. For sparsely invalid buffers,
98  // the invalidation mask becomes relevant.
99  _MaskState _maskState;
100 
101 };
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 
105 void
106 VdfExecutorInvalidationData::_ApplyInvalidationMask(
107  const VdfMask &invalidationMask)
108 {
109  // If the invalidation mask is an all-ones mask, simply set the
110  // corresponding invalidation mask state.
111  if (invalidationMask.IsAllOnes()) {
112  _maskState = _MaskState::AllOnes;
113  return;
114  }
115 
116  // Set the passed in invalidation mask, if the current mask is all zeros,
117  // or the mask sizes mismatch (note, this includes the current mask being
118  // an empty mask).
119  if (_maskState == _MaskState::AllZeros ||
120  _mask.GetSize() != invalidationMask.GetSize()) {
121  _mask = invalidationMask;
122  _maskState = _MaskState::Sparse;
123  }
124 
125  // Append the current invalidation mask, and set the invalidation mask
126  // state based on whether the new mask is all ones or sparse.
127  else {
128  _mask |= invalidationMask;
129  _maskState = _mask.IsAllOnes()
132 
133  }
134 }
135 
136 bool
138  const VdfMask &invalidationMask,
139  const bool wasTouched) const
140 {
141  // If the buffer was touched, the corresponding output is not invalid.
142  if (wasTouched) {
143  return false;
144  }
145 
146  // If everything is invalid, or if the passed invalidation mask is empty,
147  // the corresponding output is invalid.
148  if (_maskState == _MaskState::AllOnes ||
149  invalidationMask.IsAllZeros()) {
150  return true;
151  }
152 
153  // If the bits set in the passed mask are all already set in the mask
154  // we are holding, the corresponding output is invalid.
155  else if (_maskState == _MaskState::Sparse &&
156  _mask.GetSize() == invalidationMask.GetSize() &&
157  _mask.Contains(invalidationMask)) {
158  return true;
159  }
160 
161  // The corresponding output is not invalid for the given mask.
162  return false;
163 }
164 
165 bool
167  const VdfMask &invalidationMask,
168  const bool wasTouched)
169 {
170  // If the buffer was touched, make sure to reset the invalidation mask.
171  if (wasTouched) {
172  _maskState = _MaskState::AllZeros;
173  }
174 
175  // If everything is invalid or if the passed invalidation mask is empty,
176  // there's no invalidation to do.
177  if (_maskState == _MaskState::AllOnes ||
178  invalidationMask.IsAllZeros()) {
179  return false;
180  }
181 
182  // If the bits set in the passed mask are all already set in the mask
183  // we were holding, there's no invalidation to do.
184  else if (_maskState == _MaskState::Sparse &&
185  _mask.GetSize() == invalidationMask.GetSize() &&
186  _mask.Contains(invalidationMask)) {
187  return false;
188  }
189 
190  // Update the invalidation state and invalidation mask.
191  _ApplyInvalidationMask(invalidationMask);
192 
193  // Return true, indicating that we did some invalidation.
194  return true;
195 }
196 
198 
199 #endif
bool IsInvalid(const VdfMask &invalidationMask, const bool wasTouched) const
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
bool Invalidate(const VdfMask &invalidationMask, const bool wasTouched)
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
#define VDF_API
Definition: api.h:25
static constexpr VdfInvalidationTimestamp InitialInvalidationTimestamp
VDF_API void Clone(VdfExecutorInvalidationData *dest) const
bool Contains(const VdfMask &mask) const
Definition: mask.h:186
VdfExecutorInvalidationData & operator=(const VdfExecutorInvalidationData &)=delete
bool IsAllZeros() const
Definition: mask.h:206
size_t GetSize() const
Definition: mask.h:158
unsigned int VdfInvalidationTimestamp
Type of the timestamp that identifies the most recent round of invalidation.
Definition: types.h:74
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool IsAllOnes() const
Definition: mask.h:196