blob: 5d1f213b154b80e5d47960eb72eb38ebab674c4d [file] [log] [blame]
Timothy Liange30739a2018-07-31 10:51:17 -04001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6*/
7
8#ifndef GrMtlResourceProvider_DEFINED
9#define GrMtlResourceProvider_DEFINED
10
Jim Van Verthbbf85f92019-06-20 12:38:38 -040011#include "include/private/SkSpinlock.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/private/SkTArray.h"
13#include "src/core/SkLRUCache.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050014#include "src/gpu/GrProgramDesc.h"
Jim Van Verth75c53262019-04-26 12:23:51 -040015#include "src/gpu/mtl/GrMtlDepthStencil.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
Jim Van Verth75c53262019-04-26 12:23:51 -040017#include "src/gpu/mtl/GrMtlSampler.h"
Timothy Liange30739a2018-07-31 10:51:17 -040018
Aaron O'Mullan829b6a02019-07-08 01:31:14 +020019#import <Metal/Metal.h>
Timothy Liange30739a2018-07-31 10:51:17 -040020
21class GrMtlGpu;
Jim Van Verthbbf85f92019-06-20 12:38:38 -040022class GrMtlCommandBuffer;
Timothy Liange30739a2018-07-31 10:51:17 -040023
24class GrMtlResourceProvider {
25public:
Jim Van Verth1223e7f2019-02-28 17:38:35 -050026 GrMtlResourceProvider(GrMtlGpu* gpu);
Timothy Liange30739a2018-07-31 10:51:17 -040027
Robert Phillips901aff02019-10-08 12:32:56 -040028 GrMtlPipelineState* findOrCreateCompatiblePipelineState(GrRenderTarget*,
Robert Phillipsfcaae482019-11-07 10:17:03 -050029 const GrProgramInfo&);
Jim Van Verth1223e7f2019-02-28 17:38:35 -050030
Jim Van Verth75c53262019-04-26 12:23:51 -040031 // Finds or creates a compatible MTLDepthStencilState based on the GrStencilSettings.
32 GrMtlDepthStencil* findOrCreateCompatibleDepthStencilState(const GrStencilSettings&,
33 GrSurfaceOrigin);
34
35 // Finds or creates a compatible MTLSamplerState based on the GrSamplerState.
Brian Salomonccb61422020-01-09 10:46:36 -050036 GrMtlSampler* findOrCreateCompatibleSampler(GrSamplerState);
Jim Van Verth75c53262019-04-26 12:23:51 -040037
Jim Van Verthd44c0de2019-07-30 18:25:32 +000038 id<MTLBuffer> getDynamicBuffer(size_t size, size_t* offset);
39 void addBufferCompletionHandler(GrMtlCommandBuffer* cmdBuffer);
Jim Van Verth35a67eb2019-05-03 10:58:40 -040040
Jim Van Verthcf23f582019-05-22 09:46:57 -040041 // Destroy any cached resources. To be called before releasing the MtlDevice.
42 void destroyResources();
43
Timothy Liange30739a2018-07-31 10:51:17 -040044private:
Jim Van Verth1223e7f2019-02-28 17:38:35 -050045#ifdef SK_DEBUG
46#define GR_PIPELINE_STATE_CACHE_STATS
47#endif
48
49 class PipelineStateCache : public ::SkNoncopyable {
50 public:
51 PipelineStateCache(GrMtlGpu* gpu);
52 ~PipelineStateCache();
53
Jim Van Verthcf23f582019-05-22 09:46:57 -040054 void release();
Robert Phillipsfcaae482019-11-07 10:17:03 -050055 GrMtlPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&);
Jim Van Verth1223e7f2019-02-28 17:38:35 -050056
57 private:
Jim Van Verth1223e7f2019-02-28 17:38:35 -050058 struct Entry;
59
60 struct DescHash {
61 uint32_t operator()(const GrProgramDesc& desc) const {
62 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
63 }
64 };
65
Robert Phillips03e4c952019-11-26 16:20:22 -050066 SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
Jim Van Verth1223e7f2019-02-28 17:38:35 -050067
Robert Phillips03e4c952019-11-26 16:20:22 -050068 GrMtlGpu* fGpu;
Jim Van Verth1223e7f2019-02-28 17:38:35 -050069
70#ifdef GR_PIPELINE_STATE_CACHE_STATS
71 int fTotalRequests;
72 int fCacheMisses;
73#endif
74 };
75
Jim Van Verthbbf85f92019-06-20 12:38:38 -040076 // Buffer allocator
77 class BufferSuballocator : public SkRefCnt {
78 public:
Jim Van Verthd44c0de2019-07-30 18:25:32 +000079 BufferSuballocator(id<MTLDevice> device, size_t size);
Jim Van Verthbbf85f92019-06-20 12:38:38 -040080 ~BufferSuballocator() {
81 fBuffer = nil;
82 fTotalSize = 0;
83 }
84
85 id<MTLBuffer> getAllocation(size_t size, size_t* offset);
86 void addCompletionHandler(GrMtlCommandBuffer* cmdBuffer);
87 size_t size() { return fTotalSize; }
88
89 private:
90 id<MTLBuffer> fBuffer;
91 size_t fTotalSize;
Jim Van Verth5e8f3892019-07-01 15:11:29 -040092 size_t fHead SK_GUARDED_BY(fMutex); // where we start allocating
93 size_t fTail SK_GUARDED_BY(fMutex); // where we start deallocating
Jim Van Verthbbf85f92019-06-20 12:38:38 -040094 SkSpinlock fMutex;
95 };
Jim Van Verthd44c0de2019-07-30 18:25:32 +000096 static constexpr size_t kBufferSuballocatorStartSize = 1024*1024;
Jim Van Verthbbf85f92019-06-20 12:38:38 -040097
Timothy Liange30739a2018-07-31 10:51:17 -040098 GrMtlGpu* fGpu;
Jim Van Verth1223e7f2019-02-28 17:38:35 -050099
100 // Cache of GrMtlPipelineStates
101 std::unique_ptr<PipelineStateCache> fPipelineStateCache;
Jim Van Verth75c53262019-04-26 12:23:51 -0400102
103 SkTDynamicHash<GrMtlSampler, GrMtlSampler::Key> fSamplers;
104 SkTDynamicHash<GrMtlDepthStencil, GrMtlDepthStencil::Key> fDepthStencilStates;
Jim Van Verth35a67eb2019-05-03 10:58:40 -0400105
Jim Van Verthd44c0de2019-07-30 18:25:32 +0000106 // This is ref-counted because we might delete the GrContext before the command buffer
107 // finishes. The completion handler will retain a reference to this so it won't get
Jim Van Verthbbf85f92019-06-20 12:38:38 -0400108 // deleted along with the GrContext.
Jim Van Verthd44c0de2019-07-30 18:25:32 +0000109 sk_sp<BufferSuballocator> fBufferSuballocator;
Jim Van Verth22098812019-08-07 11:22:13 -0400110 size_t fBufferSuballocatorMaxSize;
Timothy Liange30739a2018-07-31 10:51:17 -0400111};
112
113#endif