diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h new file mode 100644 index 0000000000..0bdde9f8b6 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h @@ -0,0 +1,366 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceManager11: +// Centralized point of allocation for all D3D11 Resources. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ + +#include <array> +#include <memory> + +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" +#include "common/debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ +// These two methods are declared here to prevent circular includes. +namespace d3d11 +{ +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); + +template <typename T> +HRESULT SetDebugName(angle::ComPtr<T> &resource, const char *name) +{ + return SetDebugName(resource.Get(), name); +} +} // namespace d3d11 + +class Renderer11; +class ResourceManager11; +template <typename T> +class SharedResource11; +class TextureHelper11; + +using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>; +using ShaderData = WrappedArray<uint8_t>; + +// Format: ResourceType, D3D11 type, DESC type, init data type. +#define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \ + OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \ + OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \ + OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \ + const std::vector<D3D11_SO_DECLARATION_ENTRY>) \ + OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \ + OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \ + OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \ + OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \ + OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \ + OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void) + +#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE, + +enum class ResourceType +{ + ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last +}; + +#undef ANGLE_RESOURCE_TYPE_LIST + +constexpr size_t ResourceTypeIndex(ResourceType resourceType) +{ + return static_cast<size_t>(resourceType); +} + +constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last); + +#define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME<ResourceType::RESTYPE> \ + { \ + using Value = D3D11TYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME<ResourceType::RESTYPE> \ + { \ + using Value = DESCTYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME<ResourceType::RESTYPE> \ + { \ + using Value = INITDATATYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \ + template <ResourceType Param> \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ +template<ResourceType Param> struct NAME \ + { \ + }; \ + \ +template<ResourceType Param> using Get##NAME = typename NAME<Param>::Value; + +ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11) +ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC) +ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA) + +#undef ANGLE_RESOURCE_TYPE_TO_D3D11 +#undef ANGLE_RESOURCE_TYPE_TO_DESC +#undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA +#undef ANGLE_RESOURCE_TYPE_TO_TYPE + +#define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP) \ + template <typename Param> \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ +template<typename Param> struct NAME \ + { \ + }; \ + \ +template<typename Param> constexpr ResourceType Get##NAME() \ + { \ + return NAME<Param>::Value; \ + } + +#define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME<D3D11TYPE> \ + { \ + static constexpr ResourceType Value = ResourceType::RESTYPE; \ + }; + +ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE) + +#undef ANGLE_D3D11_TO_RESOURCE_TYPE +#undef ANGLE_TYPE_TO_RESOURCE_TYPE + +template <typename T> +using GetDescFromD3D11 = GetDescType<ResourceTypeFromD3D11<T>::Value>; + +template <typename T> +using GetInitDataFromD3D11 = GetInitDataType<ResourceTypeFromD3D11<T>::Value>; + +template <typename T> +constexpr size_t ResourceTypeIndex() +{ + return static_cast<size_t>(GetResourceTypeFromD3D11<T>()); +} + +template <typename T> +struct TypedData +{ + TypedData() {} + ~TypedData(); + + T *object = nullptr; + ResourceManager11 *manager = nullptr; +}; + +// Smart pointer type. Wraps the resource and a factory for safe deletion. +template <typename T, template <class> class Pointer, typename DataT> +class Resource11Base : angle::NonCopyable +{ + public: + T *get() const { return mData->object; } + T *const *getPointer() const { return &mData->object; } + + void setDebugName(const char *name) { d3d11::SetDebugName(mData->object, name); } + + void set(T *object) + { + ASSERT(!valid()); + mData->object = object; + } + + bool valid() const { return (mData->object != nullptr); } + + void reset() + { + if (valid()) + mData.reset(new DataT()); + } + + ResourceSerial getSerial() const + { + return ResourceSerial(reinterpret_cast<uintptr_t>(mData->object)); + } + + protected: + friend class TextureHelper11; + + Resource11Base() : mData(new DataT()) {} + + Resource11Base(Resource11Base &&movedObj) : mData(new DataT()) + { + std::swap(mData, movedObj.mData); + } + + virtual ~Resource11Base() { mData.reset(); } + + Resource11Base &operator=(Resource11Base &&movedObj) + { + std::swap(mData, movedObj.mData); + return *this; + } + + Pointer<DataT> mData; +}; + +template <typename T> +using UniquePtr = typename std::unique_ptr<T, std::default_delete<T>>; + +template <typename ResourceT> +class Resource11 : public Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>> +{ + public: + Resource11() {} + Resource11(Resource11 &&other) + : Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>(std::move(other)) + { + } + Resource11 &operator=(Resource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + private: + template <typename T> + friend class SharedResource11; + friend class ResourceManager11; + + Resource11(ResourceT *object, ResourceManager11 *manager) + { + this->mData->object = object; + this->mData->manager = manager; + } +}; + +template <typename T> +class SharedResource11 : public Resource11Base<T, std::shared_ptr, TypedData<T>> +{ + public: + SharedResource11() {} + SharedResource11(SharedResource11 &&movedObj) + : Resource11Base<T, std::shared_ptr, TypedData<T>>(std::move(movedObj)) + { + } + + SharedResource11 &operator=(SharedResource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + SharedResource11 makeCopy() const + { + SharedResource11 copy; + copy.mData = this->mData; + return std::move(copy); + } + + private: + friend class ResourceManager11; + SharedResource11(Resource11<T> &&obj) : Resource11Base<T, std::shared_ptr, TypedData<T>>() + { + std::swap(this->mData->manager, obj.mData->manager); + + // Can't use std::swap because of ID3D11Resource. + auto temp = this->mData->object; + this->mData->object = obj.mData->object; + obj.mData->object = static_cast<T *>(temp); + } +}; + +class ResourceManager11 final : angle::NonCopyable +{ + public: + ResourceManager11(); + ~ResourceManager11(); + + template <typename T> + gl::Error allocate(Renderer11 *renderer, + const GetDescFromD3D11<T> *desc, + GetInitDataFromD3D11<T> *initData, + Resource11<T> *resourceOut); + + template <typename T> + gl::Error allocate(Renderer11 *renderer, + const GetDescFromD3D11<T> *desc, + GetInitDataFromD3D11<T> *initData, + SharedResource11<T> *sharedRes) + { + Resource11<T> res; + ANGLE_TRY(allocate(renderer, desc, initData, &res)); + *sharedRes = std::move(res); + return gl::NoError(); + } + + template <typename T> + void onRelease(T *resource) + { + onReleaseGeneric(GetResourceTypeFromD3D11<T>(), resource); + } + + void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource); + + void setAllocationsInitialized(bool initialize); + + private: + void incrResource(ResourceType resourceType, uint64_t memorySize); + void decrResource(ResourceType resourceType, uint64_t memorySize); + + template <typename T> + GetInitDataFromD3D11<T> *createInitDataIfNeeded(const GetDescFromD3D11<T> *desc); + + bool mInitializeAllocations; + + std::array<size_t, NumResourceTypes> mAllocatedResourceCounts; + std::array<uint64_t, NumResourceTypes> mAllocatedResourceDeviceMemory; + angle::MemoryBuffer mZeroMemory; + + std::vector<D3D11_SUBRESOURCE_DATA> mShadowInitData; +}; + +template <typename ResourceT> +TypedData<ResourceT>::~TypedData() +{ + if (object) + { + // We can have a nullptr factory when holding passed-in resources. + if (manager) + { + manager->onRelease(object); + } + object->Release(); + } +} + +#define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + using RESTYPE = Resource11<D3D11TYPE>; + +namespace d3d11 +{ +ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS) + +using SharedSRV = SharedResource11<ID3D11ShaderResourceView>; +} // namespace d3d11 + +#undef ANGLE_RESOURCE_TYPE_CLASS + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ |