tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Buffer11.h (9658B)


      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);
     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    {
    141        BufferCacheEntry() : storage(nullptr), lruCount(0) {}
    142 
    143        BufferStorage *storage;
    144        unsigned int lruCount;
    145    };
    146 
    147    struct StructuredBufferKey
    148    {
    149        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_