1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_ST_VBO_SIMPLE_MEMORY_MANAGER_H
25 #define PXR_IMAGING_HD_ST_VBO_SIMPLE_MEMORY_MANAGER_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hdSt/bufferArrayRange.h"
30 #include "pxr/imaging/hdSt/resourceRegistry.h"
31 #include "pxr/imaging/hd/version.h"
32 #include "pxr/imaging/hd/strategyBase.h"
33 #include "pxr/imaging/hd/bufferArray.h"
34 #include "pxr/imaging/hd/bufferSpec.h"
35 #include "pxr/imaging/hd/bufferSource.h"
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 class HdStResourceRegistry;
40 
41 /// \class HdStVBOSimpleMemoryManager
42 ///
43 /// VBO simple memory manager.
44 ///
45 /// This class doesn't perform any aggregation.
46 ///
47 class HdStVBOSimpleMemoryManager : public HdAggregationStrategy
48 {
49 public:
HdStVBOSimpleMemoryManager(HdStResourceRegistry * resourceRegistry)50     HdStVBOSimpleMemoryManager(HdStResourceRegistry* resourceRegistry)
51         : _resourceRegistry(resourceRegistry) {}
52 
53     /// Factory for creating HdBufferArray managed by
54     /// HdStVBOSimpleMemoryManager.
55     HDST_API
56     virtual HdBufferArraySharedPtr CreateBufferArray(
57         TfToken const &role,
58         HdBufferSpecVector const &bufferSpecs,
59         HdBufferArrayUsageHint usageHint);
60 
61     /// Factory for creating HdBufferArrayRange
62     HDST_API
63     virtual HdBufferArrayRangeSharedPtr CreateBufferArrayRange();
64 
65     /// Returns id for given bufferSpecs to be used for aggregation
66     HDST_API
67     virtual HdAggregationStrategy::AggregationId ComputeAggregationId(
68         HdBufferSpecVector const &bufferSpecs,
69         HdBufferArrayUsageHint usageHint) const;
70 
71     /// Returns the buffer specs from a given buffer array
72     virtual HdBufferSpecVector GetBufferSpecs(
73         HdBufferArraySharedPtr const &bufferArray) const;
74 
75     /// Returns the size of the GPU memory used by the passed buffer array
76     virtual size_t GetResourceAllocation(
77         HdBufferArraySharedPtr const &bufferArray,
78         VtDictionary &result) const;
79 
80 protected:
81     class _SimpleBufferArray;
82 
83     /// \class _SimpleBufferArrayRange
84     ///
85     /// Specialized buffer array range for SimpleBufferArray.
86     ///
87     class _SimpleBufferArrayRange final : public HdStBufferArrayRange
88     {
89     public:
90         /// Constructor.
_SimpleBufferArrayRange(HdStResourceRegistry * resourceRegistry)91         _SimpleBufferArrayRange(HdStResourceRegistry* resourceRegistry)
92             : HdStBufferArrayRange(resourceRegistry)
93             , _bufferArray(nullptr)
94             , _numElements(0) {
95         }
96 
97         /// Returns true if this range is valid
IsValid()98         bool IsValid() const override {
99             return (bool)_bufferArray;
100         }
101 
102         /// Returns true is the range has been assigned to a buffer
103         HDST_API
104         bool IsAssigned() const override;
105 
106         /// Returns true if this range is marked as immutable.
107         bool IsImmutable() const override;
108 
109         /// Returns true if this needs a staging buffer for CPU to GPU copies.
110         bool RequiresStaging() const override;
111 
112         /// Resize memory area for this range. Returns true if it causes container
113         /// buffer reallocation.
Resize(int numElements)114         bool Resize(int numElements) override {
115             _numElements = numElements;
116             return _bufferArray->Resize(numElements);
117         }
118 
119         /// Copy source data into buffer
120         HDST_API
121         void CopyData(HdBufferSourceSharedPtr const &bufferSource) override;
122 
123         /// Read back the buffer content
124         HDST_API
125         VtValue ReadData(TfToken const &name) const override;
126 
127         /// Returns the offset at which this range begins in the underlying
128         /// buffer array in terms of elements.
GetElementOffset()129         int GetElementOffset() const override {
130             return 0;
131         }
132 
133         /// Returns the byte offset at which this range begins in the underlying
134         /// buffer array for the given resource.
GetByteOffset(TfToken const & resourceName)135         int GetByteOffset(TfToken const& resourceName) const override {
136             TF_UNUSED(resourceName);
137             return 0;
138         }
139 
140         /// Returns the number of elements allocated
GetNumElements()141         size_t GetNumElements() const override {
142             return _numElements;
143         }
144 
145         /// Returns the capacity of allocated area for this range
GetCapacity()146         int GetCapacity() const {
147             return _bufferArray->GetCapacity();
148         }
149 
150         /// Returns the version of the buffer array.
GetVersion()151         size_t GetVersion() const override {
152             return _bufferArray->GetVersion();
153         }
154 
155         /// Increment the version of the buffer array.
IncrementVersion()156         void IncrementVersion() override {
157             _bufferArray->IncrementVersion();
158         }
159 
160         /// Returns the max number of elements
161         HDST_API
162         size_t GetMaxNumElements() const override;
163 
164         /// Returns the usage hint from the underlying buffer array
165         HDST_API
166         HdBufferArrayUsageHint GetUsageHint() const override;
167 
168         /// Returns the GPU resource. If the buffer array contains more than one
169         /// resource, this method raises a coding error.
170         HDST_API
171         HdStBufferResourceSharedPtr GetResource() const override;
172 
173         /// Returns the named GPU resource.
174         HDST_API
175         HdStBufferResourceSharedPtr GetResource(TfToken const& name) override;
176 
177         /// Returns the list of all named GPU resources for this bufferArrayRange.
178         HDST_API
179         HdStBufferResourceNamedList const& GetResources() const override;
180 
181         /// Sets the buffer array associated with this buffer;
182         HDST_API
183         void SetBufferArray(HdBufferArray *bufferArray) override;
184 
185         /// Debug dump
186         HDST_API
187         void DebugDump(std::ostream &out) const override;
188 
189         /// Make this range invalid
Invalidate()190         void Invalidate() {
191             _bufferArray = NULL;
192         }
193 
194     protected:
195         /// Returns the aggregation container
196         HDST_API
197         const void *_GetAggregation() const override;
198 
199         /// Adds a new, named GPU resource and returns it.
200         HDST_API
201         HdStBufferResourceSharedPtr _AddResource(TfToken const& name,
202                                                    HdTupleType tupleType,
203                                                    int offset,
204                                                    int stride);
205 
206     private:
207         _SimpleBufferArray * _bufferArray;
208         size_t _numElements;
209     };
210 
211     using _SimpleBufferArraySharedPtr =
212         std::shared_ptr<_SimpleBufferArray>;
213     using _SimpleBufferArrayRangeSharedPtr =
214         std::shared_ptr<_SimpleBufferArrayRange>;
215     using _SimpleBufferArrayRangePtr =
216         std::weak_ptr<_SimpleBufferArrayRange>;
217 
218     /// \class _SimpleBufferArray
219     ///
220     /// Simple buffer array (non-aggregated).
221     ///
222     class _SimpleBufferArray final : public HdBufferArray
223     {
224     public:
225         /// Constructor.
226         HDST_API
227         _SimpleBufferArray(HdStResourceRegistry* resourceRegistry,
228                            TfToken const &role,
229                            HdBufferSpecVector const &bufferSpecs,
230                            HdBufferArrayUsageHint usageHint);
231 
232         /// Destructor. It invalidates _range
233         HDST_API
234         ~_SimpleBufferArray() override;
235 
236         /// perform compaction if necessary, returns true if it becomes empty.
237         HDST_API
238         bool GarbageCollect() override;
239 
240         /// Debug output
241         HDST_API
242         void DebugDump(std::ostream &out) const override;
243 
244         /// Set to resize buffers. Actual reallocation happens on Reallocate()
245         HDST_API
246         bool Resize(int numElements);
247 
248         /// Performs reallocation.
249         /// GLX context has to be set when calling this function.
250         HDST_API
251         void Reallocate(
252                 std::vector<HdBufferArrayRangeSharedPtr> const &ranges,
253                 HdBufferArraySharedPtr const &curRangeOwner) override;
254 
255         /// Returns the maximum number of elements capacity.
256         HDST_API
257         size_t GetMaxNumElements() const override;
258 
259         /// Returns current capacity. It could be different from numElements.
GetCapacity()260         int GetCapacity() const {
261             return _capacity;
262         }
263 
264         /// TODO: We need to distinguish between the primvar types here, we should
265         /// tag each HdBufferSource and HdBufferResource with Constant, Uniform,
266         /// Varying, Vertex, or FaceVarying and provide accessors for the specific
267         /// buffer types.
268 
269         /// Returns the GPU resource. If the buffer array contains more than one
270         /// resource, this method raises a coding error.
271         HDST_API
272         HdStBufferResourceSharedPtr GetResource() const;
273 
274         /// Returns the named GPU resource. This method returns the first found
275         /// resource. In HD_SAFE_MODE it checks all underlying GL buffers
276         /// in _resourceMap and raises a coding error if there are more than
277         /// one GL buffers exist.
278         HDST_API
279         HdStBufferResourceSharedPtr GetResource(TfToken const& name);
280 
281         /// Returns the list of all named GPU resources for this bufferArray.
GetResources()282         HdStBufferResourceNamedList const& GetResources() const {return _resourceList;}
283 
284         /// Reconstructs the bufferspecs and returns it (for buffer splitting)
285         HDST_API
286         HdBufferSpecVector GetBufferSpecs() const;
287 
288     protected:
289         HDST_API
290         void _DeallocateResources();
291 
292         /// Adds a new, named GPU resource and returns it.
293         HDST_API
294         HdStBufferResourceSharedPtr _AddResource(TfToken const& name,
295                                                    HdTupleType tupleType,
296                                                    int offset,
297                                                    int stride);
298     private:
299         HdStResourceRegistry* const _resourceRegistry;
300         int _capacity;
301         size_t _maxBytesPerElement;
302 
303         HdStBufferResourceNamedList _resourceList;
304 
_GetRangeSharedPtr()305         _SimpleBufferArrayRangeSharedPtr _GetRangeSharedPtr() const {
306             return GetRangeCount() > 0
307                 ? std::static_pointer_cast<_SimpleBufferArrayRange>(GetRange(0).lock())
308                 : _SimpleBufferArrayRangeSharedPtr();
309         }
310     };
311 
312     HdStResourceRegistry* const _resourceRegistry;
313 };
314 
315 PXR_NAMESPACE_CLOSE_SCOPE
316 
317 #endif  // PXR_IMAGING_HD_ST_VBO_SIMPLE_MEMORY_MANAGER_H
318