tor-browser

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

ResourceManager11.h (14466B)


      1 //
      2 // Copyright 2017 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 // ResourceManager11:
      7 //   Centralized point of allocation for all D3D11 Resources.
      8 
      9 #ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
     10 #define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
     11 
     12 #include <array>
     13 #include <atomic>
     14 #include <memory>
     15 
     16 #include "common/MemoryBuffer.h"
     17 #include "common/angleutils.h"
     18 #include "common/debug.h"
     19 #include "libANGLE/Error.h"
     20 #include "libANGLE/renderer/serial_utils.h"
     21 
     22 namespace rx
     23 {
     24 // These two methods are declared here to prevent circular includes.
     25 namespace d3d11
     26 {
     27 HRESULT SetDebugName(ID3D11DeviceChild *resource,
     28                     const char *internalName,
     29                     const std::string *khrDebugName);
     30 
     31 template <typename T>
     32 HRESULT SetDebugName(angle::ComPtr<T> &resource,
     33                     const char *internalName,
     34                     const std::string *khrDebugName)
     35 {
     36    return SetDebugName(resource.Get(), internalName, khrDebugName);
     37 }
     38 }  // namespace d3d11
     39 
     40 namespace d3d
     41 {
     42 class Context;
     43 }  // namespace d3d
     44 
     45 class Renderer11;
     46 class ResourceManager11;
     47 template <typename T>
     48 class SharedResource11;
     49 class TextureHelper11;
     50 
     51 using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>;
     52 using ShaderData        = WrappedArray<uint8_t>;
     53 
     54 // Format: ResourceType, D3D11 type, DESC type, init data type.
     55 #define ANGLE_RESOURCE_TYPE_OP(NAME, OP)                                                       \
     56    OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void)                             \
     57    OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA)            \
     58    OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void)                             \
     59    OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void)       \
     60    OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC,          \
     61       ID3D11Resource)                                                                         \
     62    OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData,                                 \
     63       const std::vector<D3D11_SO_DECLARATION_ENTRY>)                                          \
     64    OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData)              \
     65    OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void)                                 \
     66    OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void)                                       \
     67    OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void)              \
     68    OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC,          \
     69       ID3D11Resource)                                                                         \
     70    OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void)                       \
     71    OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC,    \
     72       ID3D11Resource)                                                                         \
     73    OP(NAME, UnorderedAccessView, ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC, \
     74       ID3D11Resource)                                                                         \
     75    OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA)   \
     76    OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA)   \
     77    OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void)
     78 
     79 #define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE,
     80 
     81 enum class ResourceType
     82 {
     83    ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last
     84 };
     85 
     86 #undef ANGLE_RESOURCE_TYPE_LIST
     87 
     88 constexpr size_t ResourceTypeIndex(ResourceType resourceType)
     89 {
     90    return static_cast<size_t>(resourceType);
     91 }
     92 
     93 constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last);
     94 
     95 #define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
     96                                                                                       \
     97    template <>                                                                        \
     98    struct NAME<ResourceType::RESTYPE>                                                 \
     99    {                                                                                  \
    100        using Value = D3D11TYPE;                                                       \
    101    };
    102 
    103 #define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    104                                                                                      \
    105    template <>                                                                       \
    106    struct NAME<ResourceType::RESTYPE>                                                \
    107    {                                                                                 \
    108        using Value = DESCTYPE;                                                       \
    109    };
    110 
    111 #define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    112                                                                                           \
    113    template <>                                                                            \
    114    struct NAME<ResourceType::RESTYPE>                                                     \
    115    {                                                                                      \
    116        using Value = INITDATATYPE;                                                        \
    117    };
    118 
    119 #define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \
    120    template <ResourceType Param>             \
    121    struct NAME;                              \
    122    ANGLE_RESOURCE_TYPE_OP(NAME, OP)          \
    123                                              \
    124    template <ResourceType Param>             \
    125    struct NAME                               \
    126    {};                                       \
    127                                              \
    128    template <ResourceType Param>             \
    129    using Get##NAME = typename NAME<Param>::Value;
    130 
    131 ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11)
    132 ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC)
    133 ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA)
    134 
    135 #undef ANGLE_RESOURCE_TYPE_TO_D3D11
    136 #undef ANGLE_RESOURCE_TYPE_TO_DESC
    137 #undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA
    138 #undef ANGLE_RESOURCE_TYPE_TO_TYPE
    139 
    140 #define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP) \
    141    template <typename Param>                 \
    142    struct NAME;                              \
    143    ANGLE_RESOURCE_TYPE_OP(NAME, OP)          \
    144                                              \
    145    template <typename Param>                 \
    146    struct NAME                               \
    147    {};                                       \
    148                                              \
    149    template <typename Param>                 \
    150    constexpr ResourceType Get##NAME()        \
    151    {                                         \
    152        return NAME<Param>::Value;            \
    153    }
    154 
    155 #define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    156                                                                                       \
    157    template <>                                                                        \
    158    struct NAME<D3D11TYPE>                                                             \
    159    {                                                                                  \
    160        static constexpr ResourceType Value = ResourceType::RESTYPE;                   \
    161    };
    162 
    163 ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE)
    164 
    165 #undef ANGLE_D3D11_TO_RESOURCE_TYPE
    166 #undef ANGLE_TYPE_TO_RESOURCE_TYPE
    167 
    168 template <typename T>
    169 using GetDescFromD3D11 = GetDescType<ResourceTypeFromD3D11<T>::Value>;
    170 
    171 template <typename T>
    172 using GetInitDataFromD3D11 = GetInitDataType<ResourceTypeFromD3D11<T>::Value>;
    173 
    174 template <typename T>
    175 constexpr size_t ResourceTypeIndex()
    176 {
    177    return static_cast<size_t>(GetResourceTypeFromD3D11<T>());
    178 }
    179 
    180 template <typename T>
    181 struct TypedData
    182 {
    183    TypedData() {}
    184    ~TypedData();
    185 
    186    T *object                  = nullptr;
    187    ResourceManager11 *manager = nullptr;
    188 };
    189 
    190 // Smart pointer type. Wraps the resource and a factory for safe deletion.
    191 template <typename T, template <class> class Pointer, typename DataT>
    192 class Resource11Base : angle::NonCopyable
    193 {
    194  public:
    195    T *get() const { return mData->object; }
    196    T *const *getPointer() const { return &mData->object; }
    197 
    198    void setInternalName(const char *name)
    199    {
    200        mInternalDebugName = name;
    201        UpdateDebugNameWithD3D();
    202    }
    203 
    204    void setKHRDebugLabel(const std::string *label)
    205    {
    206        mKhrDebugName = label;
    207        UpdateDebugNameWithD3D();
    208    }
    209 
    210    void setLabels(const char *name, const std::string *label)
    211    {
    212        mInternalDebugName = name;
    213        mKhrDebugName      = label;
    214        UpdateDebugNameWithD3D();
    215    }
    216 
    217    void set(T *object)
    218    {
    219        ASSERT(!valid());
    220        mData->object = object;
    221    }
    222 
    223    bool valid() const { return (mData->object != nullptr); }
    224 
    225    void reset()
    226    {
    227        if (valid())
    228            mData.reset(new DataT());
    229    }
    230 
    231    ResourceSerial getSerial() const
    232    {
    233        return ResourceSerial(reinterpret_cast<uintptr_t>(mData->object));
    234    }
    235 
    236  protected:
    237    friend class TextureHelper11;
    238 
    239    Resource11Base() : mData(new DataT()) {}
    240 
    241    Resource11Base(Resource11Base &&movedObj) : mData(new DataT())
    242    {
    243        std::swap(mData, movedObj.mData);
    244    }
    245 
    246    virtual ~Resource11Base() { mData.reset(); }
    247 
    248    Resource11Base &operator=(Resource11Base &&movedObj)
    249    {
    250        std::swap(mData, movedObj.mData);
    251        return *this;
    252    }
    253 
    254    Pointer<DataT> mData;
    255 
    256  private:
    257    void UpdateDebugNameWithD3D()
    258    {
    259        d3d11::SetDebugName(mData->object, mInternalDebugName, mKhrDebugName);
    260    }
    261 
    262    const std::string *mKhrDebugName = nullptr;
    263    const char *mInternalDebugName   = nullptr;
    264 };
    265 
    266 template <typename T>
    267 using UniquePtr = typename std::unique_ptr<T, std::default_delete<T>>;
    268 
    269 template <typename ResourceT>
    270 class Resource11 : public Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>
    271 {
    272  public:
    273    Resource11() {}
    274    Resource11(Resource11 &&other)
    275        : Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>(std::move(other))
    276    {}
    277    Resource11 &operator=(Resource11 &&other)
    278    {
    279        std::swap(this->mData, other.mData);
    280        return *this;
    281    }
    282 
    283  private:
    284    template <typename T>
    285    friend class SharedResource11;
    286    friend class ResourceManager11;
    287 
    288    Resource11(ResourceT *object, ResourceManager11 *manager)
    289    {
    290        this->mData->object  = object;
    291        this->mData->manager = manager;
    292    }
    293 };
    294 
    295 template <typename T>
    296 class SharedResource11 : public Resource11Base<T, std::shared_ptr, TypedData<T>>
    297 {
    298  public:
    299    SharedResource11() {}
    300    SharedResource11(SharedResource11 &&movedObj)
    301        : Resource11Base<T, std::shared_ptr, TypedData<T>>(std::move(movedObj))
    302    {}
    303 
    304    SharedResource11 &operator=(SharedResource11 &&other)
    305    {
    306        std::swap(this->mData, other.mData);
    307        return *this;
    308    }
    309 
    310    SharedResource11 makeCopy() const
    311    {
    312        SharedResource11 copy;
    313        copy.mData = this->mData;
    314        return std::move(copy);
    315    }
    316 
    317  private:
    318    friend class ResourceManager11;
    319    SharedResource11(Resource11<T> &&obj) : Resource11Base<T, std::shared_ptr, TypedData<T>>()
    320    {
    321        std::swap(this->mData->manager, obj.mData->manager);
    322 
    323        // Can't use std::swap because of ID3D11Resource.
    324        auto temp           = this->mData->object;
    325        this->mData->object = obj.mData->object;
    326        obj.mData->object   = static_cast<T *>(temp);
    327    }
    328 };
    329 
    330 class ResourceManager11 final : angle::NonCopyable
    331 {
    332  public:
    333    ResourceManager11();
    334    ~ResourceManager11();
    335 
    336    template <typename T>
    337    angle::Result allocate(d3d::Context *context,
    338                           Renderer11 *renderer,
    339                           const GetDescFromD3D11<T> *desc,
    340                           GetInitDataFromD3D11<T> *initData,
    341                           Resource11<T> *resourceOut);
    342 
    343    template <typename T>
    344    angle::Result allocate(d3d::Context *context,
    345                           Renderer11 *renderer,
    346                           const GetDescFromD3D11<T> *desc,
    347                           GetInitDataFromD3D11<T> *initData,
    348                           SharedResource11<T> *sharedRes)
    349    {
    350        Resource11<T> res;
    351        ANGLE_TRY(allocate(context, renderer, desc, initData, &res));
    352        *sharedRes = std::move(res);
    353        return angle::Result::Continue;
    354    }
    355 
    356    template <typename T>
    357    void onRelease(T *resource)
    358    {
    359        onReleaseGeneric(GetResourceTypeFromD3D11<T>(), resource);
    360    }
    361 
    362    void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource);
    363 
    364    void setAllocationsInitialized(bool initialize);
    365 
    366  private:
    367    void incrResource(ResourceType resourceType, uint64_t memorySize);
    368    void decrResource(ResourceType resourceType, uint64_t memorySize);
    369 
    370    template <typename T>
    371    GetInitDataFromD3D11<T> *createInitDataIfNeeded(const GetDescFromD3D11<T> *desc);
    372 
    373    bool mInitializeAllocations;
    374 
    375    std::array<std::atomic_size_t, NumResourceTypes> mAllocatedResourceCounts;
    376    std::array<std::atomic_uint64_t, NumResourceTypes> mAllocatedResourceDeviceMemory;
    377    angle::MemoryBuffer mZeroMemory;
    378 
    379    std::vector<D3D11_SUBRESOURCE_DATA> mShadowInitData;
    380 };
    381 
    382 template <typename ResourceT>
    383 TypedData<ResourceT>::~TypedData()
    384 {
    385    if (object)
    386    {
    387        // We can have a nullptr factory when holding passed-in resources.
    388        if (manager)
    389        {
    390            manager->onRelease(object);
    391        }
    392        object->Release();
    393    }
    394 }
    395 
    396 #define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    397    using RESTYPE = Resource11<D3D11TYPE>;
    398 
    399 namespace d3d11
    400 {
    401 ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS)
    402 
    403 using SharedSRV = SharedResource11<ID3D11ShaderResourceView>;
    404 using SharedUAV = SharedResource11<ID3D11UnorderedAccessView>;
    405 }  // namespace d3d11
    406 
    407 #undef ANGLE_RESOURCE_TYPE_CLASS
    408 
    409 }  // namespace rx
    410 
    411 #endif  // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_