• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2020 Google LLC
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef GrD3DTypes_DEFINED
10 #define GrD3DTypes_DEFINED
11 
12 // This file includes d3d12.h, which in turn includes windows.h, which redefines many
13 // common identifiers such as:
14 // * interface
15 // * small
16 // * near
17 // * far
18 // * CreateSemaphore
19 // * MemoryBarrier
20 //
21 // You should only include this header if you need the Direct3D definitions and are
22 // prepared to rename those identifiers. Otherwise use GrD3DTypesMinimal.h.
23 
24 #include "include/core/SkRefCnt.h"
25 #include "include/gpu/d3d/GrD3DTypesMinimal.h"
26 #include <d3d12.h>
27 #include <dxgi1_4.h>
28 
29 class GrD3DGpu;
30 
31  /** Check if the argument is non-null, and if so, call obj->AddRef() and return obj.
32   */
GrSafeComAddRef(T * obj)33 template <typename T> static inline T* GrSafeComAddRef(T* obj) {
34     if (obj) {
35         obj->AddRef();
36     }
37     return obj;
38 }
39 
40 /** Check if the argument is non-null, and if so, call obj->Release()
41  */
GrSafeComRelease(T * obj)42 template <typename T> static inline void GrSafeComRelease(T* obj) {
43     if (obj) {
44         obj->Release();
45     }
46 }
47 
48 template <typename T> class gr_cp {
49 public:
50     using element_type = T;
51 
gr_cp()52     constexpr gr_cp() : fObject(nullptr) {}
gr_cp(std::nullptr_t)53     constexpr gr_cp(std::nullptr_t) : fObject(nullptr) {}
54 
55     /**
56      *  Shares the underlying object by calling AddRef(), so that both the argument and the newly
57      *  created gr_cp both have a reference to it.
58      */
gr_cp(const gr_cp<T> & that)59     gr_cp(const gr_cp<T>& that) : fObject(GrSafeComAddRef(that.get())) {}
60 
61     /**
62      *  Move the underlying object from the argument to the newly created gr_cp. Afterwards only
63      *  the new gr_cp will have a reference to the object, and the argument will point to null.
64      *  No call to AddRef() or Release() will be made.
65      */
gr_cp(gr_cp<T> && that)66     gr_cp(gr_cp<T>&& that) : fObject(that.release()) {}
67 
68     /**
69      *  Adopt the bare object into the newly created gr_cp.
70      *  No call to AddRef() or Release() will be made.
71      */
gr_cp(T * obj)72     explicit gr_cp(T* obj) {
73         fObject = obj;
74     }
75 
76     /**
77      *  Calls Release() on the underlying object pointer.
78      */
~gr_cp()79     ~gr_cp() {
80         GrSafeComRelease(fObject);
81         SkDEBUGCODE(fObject = nullptr);
82     }
83 
84     /**
85      *  Shares the underlying object referenced by the argument by calling AddRef() on it. If this
86      *  gr_cp previously had a reference to an object (i.e. not null) it will call Release()
87      *  on that object.
88      */
89     gr_cp<T>& operator=(const gr_cp<T>& that) {
90         if (this != &that) {
91             this->reset(GrSafeComAddRef(that.get()));
92         }
93         return *this;
94     }
95 
96     /**
97      *  Move the underlying object from the argument to the gr_cp. If the gr_cp
98      *  previously held a reference to another object, Release() will be called on that object.
99      *  No call to AddRef() will be made.
100      */
101     gr_cp<T>& operator=(gr_cp<T>&& that) {
102         this->reset(that.release());
103         return *this;
104     }
105 
106     explicit operator bool() const { return this->get() != nullptr; }
107 
get()108     T* get() const { return fObject; }
109     T* operator->() const { return fObject; }
110     T** operator&() { return &fObject; }
111 
112     /**
113      *  Adopt the new object, and call Release() on any previously held object (if not null).
114      *  No call to AddRef() will be made.
115      */
116     void reset(T* object = nullptr) {
117         T* oldObject = fObject;
118         fObject = object;
119         GrSafeComRelease(oldObject);
120     }
121 
122     /**
123      *  Shares the new object by calling AddRef() on it. If this gr_cp previously had a
124      *  reference to an object (i.e. not null) it will call Release() on that object.
125      */
retain(T * object)126     void retain(T* object) {
127         if (this->fObject != object) {
128             this->reset(GrSafeComAddRef(object));
129         }
130     }
131 
132     /**
133      *  Return the original object, and set the internal object to nullptr.
134      *  The caller must assume ownership of the object, and manage its reference count directly.
135      *  No call to Release() will be made.
136      */
release()137     T* SK_WARN_UNUSED_RESULT release() {
138         T* obj = fObject;
139         fObject = nullptr;
140         return obj;
141     }
142 
143 private:
144     T* fObject;
145 };
146 
147 template <typename T> inline bool operator==(const gr_cp<T>& a,
148                                              const gr_cp<T>& b) {
149     return a.get() == b.get();
150 }
151 
152 template <typename T> inline bool operator!=(const gr_cp<T>& a,
153                                              const gr_cp<T>& b) {
154     return a.get() != b.get();
155 }
156 
157 // interface classes for the GPU memory allocator
158 class GrD3DAlloc : public SkRefCnt {
159 public:
160     ~GrD3DAlloc() override = default;
161 };
162 
163 class GrD3DMemoryAllocator : public SkRefCnt {
164 public:
165     virtual gr_cp<ID3D12Resource> createResource(D3D12_HEAP_TYPE, const D3D12_RESOURCE_DESC*,
166                                                  D3D12_RESOURCE_STATES initialResourceState,
167                                                  sk_sp<GrD3DAlloc>* allocation,
168                                                  const D3D12_CLEAR_VALUE*) = 0;
169     virtual gr_cp<ID3D12Resource> createAliasingResource(sk_sp<GrD3DAlloc>& allocation,
170                                                          uint64_t localOffset,
171                                                          const D3D12_RESOURCE_DESC*,
172                                                          D3D12_RESOURCE_STATES initialResourceState,
173                                                          const D3D12_CLEAR_VALUE*) = 0;
174 };
175 
176 // Note: there is no notion of Borrowed or Adopted resources in the D3D backend,
177 // so Ganesh will ref fResource once it's asked to wrap it.
178 // Clients are responsible for releasing their own ref to avoid memory leaks.
179 struct GrD3DTextureResourceInfo {
180     gr_cp<ID3D12Resource>    fResource             = nullptr;
181     sk_sp<GrD3DAlloc>        fAlloc                = nullptr;
182     D3D12_RESOURCE_STATES    fResourceState        = D3D12_RESOURCE_STATE_COMMON;
183     DXGI_FORMAT              fFormat               = DXGI_FORMAT_UNKNOWN;
184     uint32_t                 fSampleCount          = 1;
185     uint32_t                 fLevelCount           = 0;
186     unsigned int             fSampleQualityPattern = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
187     GrProtected              fProtected            = GrProtected::kNo;
188 
189     GrD3DTextureResourceInfo() = default;
190 
191     GrD3DTextureResourceInfo(ID3D12Resource* resource,
192                              const sk_sp<GrD3DAlloc> alloc,
193                              D3D12_RESOURCE_STATES resourceState,
194                              DXGI_FORMAT format,
195                              uint32_t sampleCount,
196                              uint32_t levelCount,
197                              unsigned int sampleQualityLevel,
198                              GrProtected isProtected = GrProtected::kNo)
fResourceGrD3DTextureResourceInfo199             : fResource(resource)
200             , fAlloc(alloc)
201             , fResourceState(resourceState)
202             , fFormat(format)
203             , fSampleCount(sampleCount)
204             , fLevelCount(levelCount)
205             , fSampleQualityPattern(sampleQualityLevel)
206             , fProtected(isProtected) {}
207 
GrD3DTextureResourceInfoGrD3DTextureResourceInfo208     GrD3DTextureResourceInfo(const GrD3DTextureResourceInfo& info,
209                              GrD3DResourceStateEnum resourceState)
210             : fResource(info.fResource)
211             , fAlloc(info.fAlloc)
212             , fResourceState(static_cast<D3D12_RESOURCE_STATES>(resourceState))
213             , fFormat(info.fFormat)
214             , fSampleCount(info.fSampleCount)
215             , fLevelCount(info.fLevelCount)
216             , fSampleQualityPattern(info.fSampleQualityPattern)
217             , fProtected(info.fProtected) {}
218 
219 #if GR_TEST_UTILS
220     bool operator==(const GrD3DTextureResourceInfo& that) const {
221         return fResource == that.fResource && fResourceState == that.fResourceState &&
222                fFormat == that.fFormat && fSampleCount == that.fSampleCount &&
223                fLevelCount == that.fLevelCount &&
224                fSampleQualityPattern == that.fSampleQualityPattern && fProtected == that.fProtected;
225     }
226 #endif
227 };
228 
229 struct GrD3DFenceInfo {
GrD3DFenceInfoGrD3DFenceInfo230     GrD3DFenceInfo()
231         : fFence(nullptr)
232         , fValue(0) {
233     }
234 
235     gr_cp<ID3D12Fence> fFence;
236     uint64_t           fValue;  // signal value for the fence
237 };
238 
239 #endif
240