blob: d2e890f780a1f4336a51466acab87f8e5b936115 [file] [log] [blame]
Jim Van Verth05d09192020-03-20 11:23:39 -04001
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
Jim Van Verth8e751472020-03-31 11:34:00 -040012// 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
Greg Daniel84261652021-09-19 17:53:40 -040022// prepared to rename those identifiers.
Jim Van Verth05d09192020-03-20 11:23:39 -040023
Jim Van Verth1b89eb72020-09-23 16:29:51 -040024#include "include/core/SkRefCnt.h"
Greg Daniel0e32aa82021-08-31 12:07:54 -040025#include "include/gpu/GrTypes.h"
Jim Van Verth8e751472020-03-31 11:34:00 -040026#include <d3d12.h>
Jim Van Verth9aa9a682020-04-01 10:13:48 -040027#include <dxgi1_4.h>
28
Jim Van Verth1b89eb72020-09-23 16:29:51 -040029class GrD3DGpu;
30
Jim Van Verth5fba9ae2020-09-21 17:18:04 -040031 /** Check if the argument is non-null, and if so, call obj->AddRef() and return obj.
32 */
33template <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 */
42template <typename T> static inline void GrSafeComRelease(T* obj) {
43 if (obj) {
44 obj->Release();
45 }
46}
47
48template <typename T> class gr_cp {
49public:
50 using element_type = T;
51
52 constexpr gr_cp() : fObject(nullptr) {}
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 */
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 */
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 */
72 explicit gr_cp(T* obj) {
73 fObject = obj;
74 }
75
76 /**
77 * Calls Release() on the underlying object pointer.
78 */
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
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 */
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 */
137 T* SK_WARN_UNUSED_RESULT release() {
138 T* obj = fObject;
139 fObject = nullptr;
140 return obj;
141 }
142
143private:
144 T* fObject;
145};
146
147template <typename T> inline bool operator==(const gr_cp<T>& a,
148 const gr_cp<T>& b) {
149 return a.get() == b.get();
150}
151
152template <typename T> inline bool operator!=(const gr_cp<T>& a,
153 const gr_cp<T>& b) {
154 return a.get() != b.get();
155}
Jim Van Verth05d09192020-03-20 11:23:39 -0400156
Jim Van Verth1b89eb72020-09-23 16:29:51 -0400157// interface classes for the GPU memory allocator
158class GrD3DAlloc : public SkRefCnt {
159public:
160 ~GrD3DAlloc() override = default;
161};
162
163class GrD3DMemoryAllocator : public SkRefCnt {
164public:
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;
Jim Van Verthc36ccb62021-04-19 07:49:26 -0400169 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;
Jim Van Verth1b89eb72020-09-23 16:29:51 -0400174};
175
Jim Van Verthaa90dad2020-03-30 15:00:39 -0400176// 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.
Jim Van Verth6ec56882020-03-26 11:47:26 -0400179struct GrD3DTextureResourceInfo {
Brian Salomon718ae762020-09-29 16:52:49 -0400180 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;
Jim Van Verth05d09192020-03-20 11:23:39 -0400188
Brian Salomon718ae762020-09-29 16:52:49 -0400189 GrD3DTextureResourceInfo() = default;
Jim Van Verth05d09192020-03-20 11:23:39 -0400190
Jim Van Verth5fba9ae2020-09-21 17:18:04 -0400191 GrD3DTextureResourceInfo(ID3D12Resource* resource,
Jim Van Verth1b89eb72020-09-23 16:29:51 -0400192 const sk_sp<GrD3DAlloc> alloc,
Jim Van Verth8e751472020-03-31 11:34:00 -0400193 D3D12_RESOURCE_STATES resourceState,
Jim Van Verth6ec56882020-03-26 11:47:26 -0400194 DXGI_FORMAT format,
Brian Salomon718ae762020-09-29 16:52:49 -0400195 uint32_t sampleCount,
Jim Van Verth6ec56882020-03-26 11:47:26 -0400196 uint32_t levelCount,
Greg Danielc9624d52020-04-13 15:36:31 -0400197 unsigned int sampleQualityLevel,
Jim Van Verth6ec56882020-03-26 11:47:26 -0400198 GrProtected isProtected = GrProtected::kNo)
199 : fResource(resource)
Jim Van Verth1b89eb72020-09-23 16:29:51 -0400200 , fAlloc(alloc)
Jim Van Verth05d09192020-03-20 11:23:39 -0400201 , fResourceState(resourceState)
202 , fFormat(format)
Brian Salomon718ae762020-09-29 16:52:49 -0400203 , fSampleCount(sampleCount)
Jim Van Verth05d09192020-03-20 11:23:39 -0400204 , fLevelCount(levelCount)
Jim Van Verth765c5922020-08-10 17:23:50 -0400205 , fSampleQualityPattern(sampleQualityLevel)
Jim Van Verth05d09192020-03-20 11:23:39 -0400206 , fProtected(isProtected) {}
207
Jim Van Verth6ec56882020-03-26 11:47:26 -0400208 GrD3DTextureResourceInfo(const GrD3DTextureResourceInfo& info,
Greg Daniel0e32aa82021-08-31 12:07:54 -0400209 D3D12_RESOURCE_STATES resourceState)
Jim Van Verth6ec56882020-03-26 11:47:26 -0400210 : fResource(info.fResource)
Jim Van Verth1b89eb72020-09-23 16:29:51 -0400211 , fAlloc(info.fAlloc)
Greg Daniel0e32aa82021-08-31 12:07:54 -0400212 , fResourceState(resourceState)
Jim Van Verth05d09192020-03-20 11:23:39 -0400213 , fFormat(info.fFormat)
Brian Salomon718ae762020-09-29 16:52:49 -0400214 , fSampleCount(info.fSampleCount)
Jim Van Verth05d09192020-03-20 11:23:39 -0400215 , fLevelCount(info.fLevelCount)
Jim Van Verth765c5922020-08-10 17:23:50 -0400216 , fSampleQualityPattern(info.fSampleQualityPattern)
Jim Van Verth05d09192020-03-20 11:23:39 -0400217 , fProtected(info.fProtected) {}
218
Jim Van Verth05d09192020-03-20 11:23:39 -0400219#if GR_TEST_UTILS
Jim Van Verth6ec56882020-03-26 11:47:26 -0400220 bool operator==(const GrD3DTextureResourceInfo& that) const {
221 return fResource == that.fResource && fResourceState == that.fResourceState &&
Brian Salomon718ae762020-09-29 16:52:49 -0400222 fFormat == that.fFormat && fSampleCount == that.fSampleCount &&
223 fLevelCount == that.fLevelCount &&
Jim Van Verth765c5922020-08-10 17:23:50 -0400224 fSampleQualityPattern == that.fSampleQualityPattern && fProtected == that.fProtected;
Jim Van Verth05d09192020-03-20 11:23:39 -0400225 }
226#endif
227};
228
Jim Van Verthc1a67b52020-06-25 13:10:29 -0400229struct GrD3DFenceInfo {
230 GrD3DFenceInfo()
231 : fFence(nullptr)
232 , fValue(0) {
233 }
234
Jim Van Verth5fba9ae2020-09-21 17:18:04 -0400235 gr_cp<ID3D12Fence> fFence;
236 uint64_t fValue; // signal value for the fence
Jim Van Verthc1a67b52020-06-25 13:10:29 -0400237};
238
Greg Daniel84261652021-09-19 17:53:40 -0400239struct GrD3DSurfaceInfo {
240 uint32_t fSampleCount = 1;
241 uint32_t fLevelCount = 0;
242 GrProtected fProtected = GrProtected::kNo;
243
244 DXGI_FORMAT fFormat = DXGI_FORMAT_UNKNOWN;
245 unsigned int fSampleQualityPattern = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
246};
247
Jim Van Verth05d09192020-03-20 11:23:39 -0400248#endif