• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
10 #define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
11 
12 #include <array>
13 #include <map>
14 
15 #include "libANGLE/angletypes.h"
16 #include "libANGLE/renderer/d3d/BufferD3D.h"
17 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
18 
19 namespace gl
20 {
21 class FramebufferAttachment;
22 }
23 
24 namespace rx
25 {
26 struct PackPixelsParams;
27 class Renderer11;
28 struct SourceIndexData;
29 struct TranslatedAttribute;
30 
31 // The order of this enum governs priority of 'getLatestBufferStorage'.
32 enum BufferUsage
33 {
34     BUFFER_USAGE_SYSTEM_MEMORY,
35     BUFFER_USAGE_STAGING,
36     BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
37     BUFFER_USAGE_INDEX,
38     BUFFER_USAGE_INDIRECT,
39     BUFFER_USAGE_PIXEL_UNPACK,
40     BUFFER_USAGE_PIXEL_PACK,
41     BUFFER_USAGE_UNIFORM,
42     BUFFER_USAGE_STRUCTURED,
43     BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
44     BUFFER_USAGE_RAW_UAV,
45     BUFFER_USAGE_TYPED_UAV,
46 
47     BUFFER_USAGE_COUNT,
48 };
49 
50 typedef size_t DataRevision;
51 
52 class Buffer11 : public BufferD3D
53 {
54   public:
55     Buffer11(const gl::BufferState &state, Renderer11 *renderer);
56     ~Buffer11() override;
57 
58     angle::Result getBuffer(const gl::Context *context,
59                             BufferUsage usage,
60                             ID3D11Buffer **bufferOut);
61     angle::Result getEmulatedIndexedBuffer(const gl::Context *context,
62                                            SourceIndexData *indexInfo,
63                                            const TranslatedAttribute &attribute,
64                                            GLint startVertex,
65                                            ID3D11Buffer **bufferOut);
66     angle::Result getConstantBufferRange(const gl::Context *context,
67                                          GLintptr offset,
68                                          GLsizeiptr size,
69                                          const d3d11::Buffer **bufferOut,
70                                          UINT *firstConstantOut,
71                                          UINT *numConstantsOut);
72     angle::Result getStructuredBufferRangeSRV(const gl::Context *context,
73                                               unsigned int offset,
74                                               unsigned int size,
75                                               unsigned int structureByteStride,
76                                               const d3d11::ShaderResourceView **srvOut);
77     angle::Result getSRV(const gl::Context *context,
78                          DXGI_FORMAT srvFormat,
79                          const d3d11::ShaderResourceView **srvOut);
80     angle::Result getRawUAVRange(const gl::Context *context,
81                                  GLintptr offset,
82                                  GLsizeiptr size,
83                                  d3d11::UnorderedAccessView **uavOut);
84 
85     angle::Result getTypedUAVRange(const gl::Context *context,
86                                    GLintptr offset,
87                                    GLsizeiptr size,
88                                    DXGI_FORMAT format,
89                                    d3d11::UnorderedAccessView **uavOut);
90 
91     angle::Result markRawBufferUsage(const gl::Context *context);
92     angle::Result markTypedBufferUsage(const gl::Context *context);
isMapped()93     bool isMapped() const { return mMappedStorage != nullptr; }
94     angle::Result packPixels(const gl::Context *context,
95                              const gl::FramebufferAttachment &readAttachment,
96                              const PackPixelsParams &params);
97     size_t getTotalCPUBufferMemoryBytes() const;
98 
99     // BufferD3D implementation
100     size_t getSize() const override;
101     bool supportsDirectBinding() const override;
102     angle::Result getData(const gl::Context *context, const uint8_t **outData) override;
103     void initializeStaticData(const gl::Context *context) override;
104     void invalidateStaticData(const gl::Context *context) override;
105 
106     // BufferImpl implementation
107     angle::Result setData(const gl::Context *context,
108                           gl::BufferBinding target,
109                           const void *data,
110                           size_t size,
111                           gl::BufferUsage usage) override;
112     angle::Result setSubData(const gl::Context *context,
113                              gl::BufferBinding target,
114                              const void *data,
115                              size_t size,
116                              size_t offset) override;
117     angle::Result copySubData(const gl::Context *context,
118                               BufferImpl *source,
119                               GLintptr sourceOffset,
120                               GLintptr destOffset,
121                               GLsizeiptr size) override;
122     angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override;
123     angle::Result mapRange(const gl::Context *context,
124                            size_t offset,
125                            size_t length,
126                            GLbitfield access,
127                            void **mapPtr) override;
128     angle::Result unmap(const gl::Context *context, GLboolean *result) override;
129     angle::Result markTransformFeedbackUsage(const gl::Context *context) override;
130 
131   private:
132     class BufferStorage;
133     class EmulatedIndexedStorage;
134     class NativeStorage;
135     class PackStorage;
136     class SystemMemoryStorage;
137     class StructuredBufferStorage;
138 
139     struct BufferCacheEntry
140     {
BufferCacheEntryBufferCacheEntry141         BufferCacheEntry() : storage(nullptr), lruCount(0) {}
142 
143         BufferStorage *storage;
144         unsigned int lruCount;
145     };
146 
147     struct StructuredBufferKey
148     {
StructuredBufferKeyStructuredBufferKey149         StructuredBufferKey(unsigned int offsetIn, unsigned int structureByteStrideIn)
150             : offset(offsetIn), structureByteStride(structureByteStrideIn)
151         {}
152         bool operator<(const StructuredBufferKey &rhs) const
153         {
154             return std::tie(offset, structureByteStride) <
155                    std::tie(rhs.offset, rhs.structureByteStride);
156         }
157         unsigned int offset;
158         unsigned int structureByteStride;
159     };
160 
161     void markBufferUsage(BufferUsage usage);
162     angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage);
163     angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage);
164 
165     angle::Result updateBufferStorage(const gl::Context *context,
166                                       BufferStorage *storage,
167                                       size_t sourceOffset,
168                                       size_t storageSize);
169 
170     angle::Result getNativeStorageForUAV(const gl::Context *context,
171                                          Buffer11::NativeStorage **storageOut);
172 
173     template <typename StorageOutT>
174     angle::Result getBufferStorage(const gl::Context *context,
175                                    BufferUsage usage,
176                                    StorageOutT **storageOut);
177 
178     template <typename StorageOutT>
179     angle::Result getStagingStorage(const gl::Context *context, StorageOutT **storageOut);
180 
181     angle::Result getLatestBufferStorage(const gl::Context *context,
182                                          BufferStorage **storageOut) const;
183 
184     angle::Result getConstantBufferRangeStorage(const gl::Context *context,
185                                                 GLintptr offset,
186                                                 GLsizeiptr size,
187                                                 NativeStorage **storageOut);
188 
189     BufferStorage *allocateStorage(BufferUsage usage);
190     void updateDeallocThreshold(BufferUsage usage);
191 
192     // Free the storage if we decide it isn't being used very often.
193     angle::Result checkForDeallocation(const gl::Context *context, BufferUsage usage);
194 
195     // For some cases of uniform buffer storage, we can't deallocate system memory storage.
196     bool canDeallocateSystemMemory() const;
197 
198     // Updates data revisions and latest storage.
199     void onCopyStorage(BufferStorage *dest, BufferStorage *source);
200     void onStorageUpdate(BufferStorage *updatedStorage);
201 
202     Renderer11 *mRenderer;
203     size_t mSize;
204 
205     BufferStorage *mMappedStorage;
206 
207     // Buffer storages are sorted by usage. It's important that the latest buffer storage picks
208     // the lowest usage in the case where two storages are tied on data revision - this ensures
209     // we never do anything dangerous like map a uniform buffer over a staging or system memory
210     // copy.
211     std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
212     BufferStorage *mLatestBufferStorage;
213 
214     // These two arrays are used to track when to free unused storage.
215     std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
216     std::array<unsigned int, BUFFER_USAGE_COUNT> mIdleness;
217 
218     // Cache of D3D11 constant buffer for specific ranges of buffer data.
219     // This is used to emulate UBO ranges on 11.0 devices.
220     // Constant buffers are indexed by there start offset.
221     typedef std::map<GLintptr /*offset*/, BufferCacheEntry> BufferCache;
222     BufferCache mConstantBufferRangeStoragesCache;
223     size_t mConstantBufferStorageAdditionalSize;
224     unsigned int mMaxConstantBufferLruCount;
225 
226     typedef std::map<StructuredBufferKey, BufferCacheEntry> StructuredBufferCache;
227     StructuredBufferCache mStructuredBufferRangeStoragesCache;
228     size_t mStructuredBufferStorageAdditionalSize;
229     unsigned int mMaxStructuredBufferLruCount;
230 };
231 
232 }  // namespace rx
233 
234 #endif  // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
235