xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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_RAW_UAV,
44     BUFFER_USAGE_TYPED_UAV,
45 
46     BUFFER_USAGE_COUNT,
47 };
48 
49 typedef size_t DataRevision;
50 
51 class Buffer11 : public BufferD3D
52 {
53   public:
54     Buffer11(const gl::BufferState &state, Renderer11 *renderer);
55     ~Buffer11() override;
56 
57     angle::Result getBuffer(const gl::Context *context,
58                             BufferUsage usage,
59                             ID3D11Buffer **bufferOut);
60     angle::Result getConstantBufferRange(const gl::Context *context,
61                                          GLintptr offset,
62                                          GLsizeiptr size,
63                                          const d3d11::Buffer **bufferOut,
64                                          UINT *firstConstantOut,
65                                          UINT *numConstantsOut);
66     angle::Result getStructuredBufferRangeSRV(const gl::Context *context,
67                                               unsigned int offset,
68                                               unsigned int size,
69                                               unsigned int structureByteStride,
70                                               const d3d11::ShaderResourceView **srvOut);
71     angle::Result getSRV(const gl::Context *context,
72                          DXGI_FORMAT srvFormat,
73                          const d3d11::ShaderResourceView **srvOut);
74     angle::Result getRawUAVRange(const gl::Context *context,
75                                  GLintptr offset,
76                                  GLsizeiptr size,
77                                  d3d11::UnorderedAccessView **uavOut);
78 
79     angle::Result getTypedUAVRange(const gl::Context *context,
80                                    GLintptr offset,
81                                    GLsizeiptr size,
82                                    DXGI_FORMAT format,
83                                    d3d11::UnorderedAccessView **uavOut);
84 
85     angle::Result markRawBufferUsage(const gl::Context *context);
86     angle::Result markTypedBufferUsage(const gl::Context *context);
isMapped()87     bool isMapped() const { return mMappedStorage != nullptr; }
88     angle::Result packPixels(const gl::Context *context,
89                              const gl::FramebufferAttachment &readAttachment,
90                              const PackPixelsParams &params);
91     size_t getTotalCPUBufferMemoryBytes() const;
92 
93     // BufferD3D implementation
94     size_t getSize() const override;
95     bool supportsDirectBinding() const override;
96     angle::Result getData(const gl::Context *context, const uint8_t **outData) override;
97     void initializeStaticData(const gl::Context *context) override;
98     void invalidateStaticData(const gl::Context *context) override;
99 
100     // BufferImpl implementation
101     angle::Result setData(const gl::Context *context,
102                           gl::BufferBinding target,
103                           const void *data,
104                           size_t size,
105                           gl::BufferUsage usage) override;
106     angle::Result setSubData(const gl::Context *context,
107                              gl::BufferBinding target,
108                              const void *data,
109                              size_t size,
110                              size_t offset) override;
111     angle::Result copySubData(const gl::Context *context,
112                               BufferImpl *source,
113                               GLintptr sourceOffset,
114                               GLintptr destOffset,
115                               GLsizeiptr size) override;
116     angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override;
117     angle::Result mapRange(const gl::Context *context,
118                            size_t offset,
119                            size_t length,
120                            GLbitfield access,
121                            void **mapPtr) override;
122     angle::Result unmap(const gl::Context *context, GLboolean *result) override;
123     angle::Result markTransformFeedbackUsage(const gl::Context *context) override;
124 
125   private:
126     class BufferStorage;
127     class EmulatedIndexedStorage;
128     class NativeStorage;
129     class PackStorage;
130     class SystemMemoryStorage;
131     class StructuredBufferStorage;
132 
133     struct BufferCacheEntry
134     {
BufferCacheEntryBufferCacheEntry135         BufferCacheEntry() : storage(nullptr), lruCount(0) {}
136 
137         BufferStorage *storage;
138         unsigned int lruCount;
139     };
140 
141     struct StructuredBufferKey
142     {
StructuredBufferKeyStructuredBufferKey143         StructuredBufferKey(unsigned int offsetIn, unsigned int structureByteStrideIn)
144             : offset(offsetIn), structureByteStride(structureByteStrideIn)
145         {}
146         bool operator<(const StructuredBufferKey &rhs) const
147         {
148             return std::tie(offset, structureByteStride) <
149                    std::tie(rhs.offset, rhs.structureByteStride);
150         }
151         unsigned int offset;
152         unsigned int structureByteStride;
153     };
154 
155     void markBufferUsage(BufferUsage usage);
156     angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage);
157     angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage);
158 
159     angle::Result updateBufferStorage(const gl::Context *context,
160                                       BufferStorage *storage,
161                                       size_t sourceOffset,
162                                       size_t storageSize);
163 
164     angle::Result getNativeStorageForUAV(const gl::Context *context,
165                                          Buffer11::NativeStorage **storageOut);
166 
167     template <typename StorageOutT>
168     angle::Result getBufferStorage(const gl::Context *context,
169                                    BufferUsage usage,
170                                    StorageOutT **storageOut);
171 
172     template <typename StorageOutT>
173     angle::Result getStagingStorage(const gl::Context *context, StorageOutT **storageOut);
174 
175     angle::Result getLatestBufferStorage(const gl::Context *context,
176                                          BufferStorage **storageOut) const;
177 
178     angle::Result getConstantBufferRangeStorage(const gl::Context *context,
179                                                 GLintptr offset,
180                                                 GLsizeiptr size,
181                                                 NativeStorage **storageOut);
182 
183     BufferStorage *allocateStorage(BufferUsage usage);
184     void updateDeallocThreshold(BufferUsage usage);
185 
186     // Free the storage if we decide it isn't being used very often.
187     angle::Result checkForDeallocation(const gl::Context *context, BufferUsage usage);
188 
189     // For some cases of uniform buffer storage, we can't deallocate system memory storage.
190     bool canDeallocateSystemMemory() const;
191 
192     // Updates data revisions and latest storage.
193     void onCopyStorage(BufferStorage *dest, BufferStorage *source);
194     void onStorageUpdate(BufferStorage *updatedStorage);
195 
196     Renderer11 *mRenderer;
197     size_t mSize;
198 
199     BufferStorage *mMappedStorage;
200 
201     // Buffer storages are sorted by usage. It's important that the latest buffer storage picks
202     // the lowest usage in the case where two storages are tied on data revision - this ensures
203     // we never do anything dangerous like map a uniform buffer over a staging or system memory
204     // copy.
205     std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
206     BufferStorage *mLatestBufferStorage;
207 
208     // These two arrays are used to track when to free unused storage.
209     std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
210     std::array<unsigned int, BUFFER_USAGE_COUNT> mIdleness;
211 
212     // Cache of D3D11 constant buffer for specific ranges of buffer data.
213     // This is used to emulate UBO ranges on 11.0 devices.
214     // Constant buffers are indexed by there start offset.
215     typedef std::map<GLintptr /*offset*/, BufferCacheEntry> BufferCache;
216     BufferCache mConstantBufferRangeStoragesCache;
217     size_t mConstantBufferStorageAdditionalSize;
218     unsigned int mMaxConstantBufferLruCount;
219 
220     typedef std::map<StructuredBufferKey, BufferCacheEntry> StructuredBufferCache;
221     StructuredBufferCache mStructuredBufferRangeStoragesCache;
222     size_t mStructuredBufferStorageAdditionalSize;
223     unsigned int mMaxStructuredBufferLruCount;
224 };
225 
226 }  // namespace rx
227 
228 #endif  // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
229