/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrD3DResourceProvider_DEFINED #define GrD3DResourceProvider_DEFINED #include "include/gpu/d3d/GrD3DTypes.h" #include "include/private/SkTArray.h" #include "include/private/SkTHash.h" #include "src/core/SkLRUCache.h" #include "src/gpu/GrProgramDesc.h" #include "src/gpu/GrRingBuffer.h" #include "src/gpu/d3d/GrD3DCommandSignature.h" #include "src/gpu/d3d/GrD3DCpuDescriptorManager.h" #include "src/gpu/d3d/GrD3DDescriptorTableManager.h" #include "src/gpu/d3d/GrD3DPipeline.h" #include "src/gpu/d3d/GrD3DRootSignature.h" #include "src/gpu/d3d/GrD3DUtil.h" #include class GrD3DCommandSignature; class GrD3DDirectCommandList; class GrD3DGpu; class GrD3DPipelineState; class GrD3DRenderTarget; class GrSamplerState; class GrD3DResourceProvider { public: GrD3DResourceProvider(GrD3DGpu*); void destroyResources(); std::unique_ptr findOrCreateDirectCommandList(); void recycleDirectCommandList(std::unique_ptr); sk_sp findOrCreateRootSignature(int numTextureSamplers, int numUAVs = 0); sk_sp findOrCreateCommandSignature(GrD3DCommandSignature::ForIndexed, unsigned int slot); GrD3DDescriptorHeap::CPUHandle createRenderTargetView(ID3D12Resource* textureResource); void recycleRenderTargetView(const GrD3DDescriptorHeap::CPUHandle&); GrD3DDescriptorHeap::CPUHandle createDepthStencilView(ID3D12Resource* textureResource); void recycleDepthStencilView(const GrD3DDescriptorHeap::CPUHandle&); GrD3DDescriptorHeap::CPUHandle createConstantBufferView(ID3D12Resource* bufferResource, size_t offset, size_t size); GrD3DDescriptorHeap::CPUHandle createShaderResourceView(ID3D12Resource* resource, unsigned int mostDetailedMip = 0, unsigned int mipLevels = -1); GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(ID3D12Resource* resource, unsigned int mipSlice); void recycleShaderView(const GrD3DDescriptorHeap::CPUHandle&); D3D12_CPU_DESCRIPTOR_HANDLE findOrCreateCompatibleSampler(const GrSamplerState& params); sk_sp findOrCreateShaderViewTable( const std::vector& shaderViews); sk_sp findOrCreateSamplerTable( const std::vector& samplers); GrD3DDescriptorTableManager* descriptorTableMgr() { return &fDescriptorTableManager; } GrD3DPipelineState* findOrCreateCompatiblePipelineState(GrD3DRenderTarget*, const GrProgramInfo&); sk_sp findOrCreateMipmapPipeline(); D3D12_GPU_VIRTUAL_ADDRESS uploadConstantData(void* data, size_t size); void prepForSubmit(); void markPipelineStateUniformsDirty() { fPipelineStateCache->markPipelineStateUniformsDirty(); } #if GR_TEST_UTILS void resetShaderCacheForTesting() const { fPipelineStateCache->release(); } #endif private: #ifdef SK_DEBUG #define GR_PIPELINE_STATE_CACHE_STATS #endif class PipelineStateCache : public ::SkNoncopyable { public: PipelineStateCache(GrD3DGpu* gpu); ~PipelineStateCache(); void release(); GrD3DPipelineState* refPipelineState(GrD3DRenderTarget*, const GrProgramInfo&); void markPipelineStateUniformsDirty(); private: struct Entry; struct DescHash { uint32_t operator()(const GrProgramDesc& desc) const { return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); } }; SkLRUCache, DescHash> fMap; GrD3DGpu* fGpu; #ifdef GR_PIPELINE_STATE_CACHE_STATS int fTotalRequests; int fCacheMisses; #endif }; class DescriptorTableCache : public ::SkNoncopyable { public: DescriptorTableCache(GrD3DGpu* gpu) : fGpu(gpu), fMap(64) { // Initialize the array we pass into CopyDescriptors for ranges. // At the moment any descriptor we pass into CopyDescriptors is only itself, // not the beginning of a range, so each range size is always 1. for (int i = 0; i < kRangeSizesCount; ++i) { fRangeSizes[i] = 1; } } ~DescriptorTableCache() = default; void release(); typedef std::function(GrD3DGpu*, unsigned int)> CreateFunc; sk_sp findOrCreateDescTable( const std::vector&, CreateFunc); private: GrD3DGpu* fGpu; typedef std::vector DescTableKey; typedef sk_sp DescTableValue; struct DescTableHash { uint32_t operator()(DescTableKey key) const { return SkOpts::hash_fn(key.data(), key.size()*sizeof(D3D12_CPU_DESCRIPTOR_HANDLE), 0); } }; SkLRUCache fMap; static constexpr int kRangeSizesCount = 8; unsigned int fRangeSizes[kRangeSizesCount]; }; GrD3DGpu* fGpu; SkSTArray<4, std::unique_ptr> fAvailableDirectCommandLists; SkSTArray<4, sk_sp> fRootSignatures; SkSTArray<2, sk_sp> fCommandSignatures; GrD3DCpuDescriptorManager fCpuDescriptorManager; GrD3DDescriptorTableManager fDescriptorTableManager; std::unique_ptr fPipelineStateCache; sk_sp fMipmapPipeline; SkTHashMap fSamplers; DescriptorTableCache fShaderResourceDescriptorTableCache; DescriptorTableCache fSamplerDescriptorTableCache; }; #endif