1 /*
2 * Copyright 2020 Google LLC
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 #include "src/gpu/ganesh/d3d/GrD3DTextureRenderTarget.h"
9
10 #include "src/gpu/ganesh/GrTexture.h"
11 #include "src/gpu/ganesh/d3d/GrD3DGpu.h"
12
GrD3DTextureRenderTarget(GrD3DGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,const GrD3DTextureResourceInfo & msaaInfo,sk_sp<GrD3DResourceState> msaaState,const GrD3DDescriptorHeap::CPUHandle & colorRenderTargetView,const GrD3DDescriptorHeap::CPUHandle & resolveRenderTargetView,GrMipmapStatus mipmapStatus,std::string_view label)13 GrD3DTextureRenderTarget::GrD3DTextureRenderTarget(
14 GrD3DGpu* gpu,
15 skgpu::Budgeted budgeted,
16 SkISize dimensions,
17 const GrD3DTextureResourceInfo& info,
18 sk_sp<GrD3DResourceState> state,
19 const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
20 const GrD3DTextureResourceInfo& msaaInfo,
21 sk_sp<GrD3DResourceState> msaaState,
22 const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
23 const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
24 GrMipmapStatus mipmapStatus,
25 std::string_view label)
26 : GrSurface(gpu, dimensions, info.fProtected, label)
27 , GrD3DTextureResource(info, state)
28 , GrD3DTexture(gpu, dimensions, info, state, shaderResourceView, mipmapStatus, label)
29 , GrD3DRenderTarget(gpu,
30 dimensions,
31 info,
32 state,
33 msaaInfo,
34 std::move(msaaState),
35 colorRenderTargetView,
36 resolveRenderTargetView,
37 label) {
38 SkASSERT(info.fProtected == msaaInfo.fProtected);
39 this->registerWithCache(budgeted);
40 }
41
GrD3DTextureRenderTarget(GrD3DGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,const GrD3DDescriptorHeap::CPUHandle & renderTargetView,GrMipmapStatus mipmapStatus,std::string_view label)42 GrD3DTextureRenderTarget::GrD3DTextureRenderTarget(
43 GrD3DGpu* gpu,
44 skgpu::Budgeted budgeted,
45 SkISize dimensions,
46 const GrD3DTextureResourceInfo& info,
47 sk_sp<GrD3DResourceState> state,
48 const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
49 const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
50 GrMipmapStatus mipmapStatus,
51 std::string_view label)
52 : GrSurface(gpu, dimensions, info.fProtected, label)
53 , GrD3DTextureResource(info, state)
54 , GrD3DTexture(gpu, dimensions, info, state, shaderResourceView, mipmapStatus, label)
55 , GrD3DRenderTarget(gpu, dimensions, info, state, renderTargetView, label) {
56 this->registerWithCache(budgeted);
57 }
58
GrD3DTextureRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,const GrD3DTextureResourceInfo & msaaInfo,sk_sp<GrD3DResourceState> msaaState,const GrD3DDescriptorHeap::CPUHandle & colorRenderTargetView,const GrD3DDescriptorHeap::CPUHandle & resolveRenderTargetView,GrMipmapStatus mipmapStatus,GrWrapCacheable cacheable,std::string_view label)59 GrD3DTextureRenderTarget::GrD3DTextureRenderTarget(
60 GrD3DGpu* gpu,
61 SkISize dimensions,
62 const GrD3DTextureResourceInfo& info,
63 sk_sp<GrD3DResourceState> state,
64 const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
65 const GrD3DTextureResourceInfo& msaaInfo,
66 sk_sp<GrD3DResourceState> msaaState,
67 const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
68 const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
69 GrMipmapStatus mipmapStatus,
70 GrWrapCacheable cacheable,
71 std::string_view label)
72 : GrSurface(gpu, dimensions, info.fProtected, label)
73 , GrD3DTextureResource(info, state)
74 , GrD3DTexture(gpu, dimensions, info, state, shaderResourceView, mipmapStatus, label)
75 , GrD3DRenderTarget(gpu,
76 dimensions,
77 info,
78 state,
79 msaaInfo,
80 std::move(msaaState),
81 colorRenderTargetView,
82 resolveRenderTargetView,
83 label) {
84 SkASSERT(info.fProtected == msaaInfo.fProtected);
85 this->registerWithCacheWrapped(cacheable);
86 }
87
GrD3DTextureRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,const GrD3DDescriptorHeap::CPUHandle & renderTargetView,GrMipmapStatus mipmapStatus,GrWrapCacheable cacheable,std::string_view label)88 GrD3DTextureRenderTarget::GrD3DTextureRenderTarget(
89 GrD3DGpu* gpu,
90 SkISize dimensions,
91 const GrD3DTextureResourceInfo& info,
92 sk_sp<GrD3DResourceState> state,
93 const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
94 const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
95 GrMipmapStatus mipmapStatus,
96 GrWrapCacheable cacheable,
97 std::string_view label)
98 : GrSurface(gpu, dimensions, info.fProtected, label)
99 , GrD3DTextureResource(info, state)
100 , GrD3DTexture(gpu, dimensions, info, state, shaderResourceView, mipmapStatus, label)
101 , GrD3DRenderTarget(gpu, dimensions, info, state, renderTargetView, label) {
102 this->registerWithCacheWrapped(cacheable);
103 }
104
MakeNewTextureRenderTarget(GrD3DGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,int sampleCnt,const D3D12_RESOURCE_DESC & resourceDesc,GrProtected isProtected,GrMipmapStatus mipmapStatus,std::string_view label)105 sk_sp<GrD3DTextureRenderTarget> GrD3DTextureRenderTarget::MakeNewTextureRenderTarget(
106 GrD3DGpu* gpu,
107 skgpu::Budgeted budgeted,
108 SkISize dimensions,
109 int sampleCnt,
110 const D3D12_RESOURCE_DESC& resourceDesc,
111 GrProtected isProtected,
112 GrMipmapStatus mipmapStatus,
113 std::string_view label) {
114 GrD3DTextureResourceInfo info;
115 D3D12_RESOURCE_STATES initialState = sampleCnt > 1 ? D3D12_RESOURCE_STATE_RESOLVE_DEST
116 : D3D12_RESOURCE_STATE_RENDER_TARGET;
117
118 D3D12_CLEAR_VALUE clearValue = {};
119 clearValue.Format = resourceDesc.Format;
120 clearValue.Color[0] = 0;
121 clearValue.Color[1] = 0;
122 clearValue.Color[2] = 0;
123 clearValue.Color[3] = 0;
124
125 if (!GrD3DTextureResource::InitTextureResourceInfo(gpu, resourceDesc, initialState,
126 isProtected, &clearValue, &info)) {
127 return nullptr;
128 }
129 sk_sp<GrD3DResourceState> state(new GrD3DResourceState(
130 static_cast<D3D12_RESOURCE_STATES>(info.fResourceState)));
131
132 const GrD3DDescriptorHeap::CPUHandle shaderResourceView =
133 gpu->resourceProvider().createShaderResourceView(info.fResource.get());
134
135 const GrD3DDescriptorHeap::CPUHandle renderTargetView =
136 gpu->resourceProvider().createRenderTargetView(info.fResource.get());
137
138 if (sampleCnt > 1) {
139 GrD3DTextureResourceInfo msInfo;
140 sk_sp<GrD3DResourceState> msState;
141 // created MSAA surface we assume will be used for masks, so clear to transparent black
142 SkColor4f clearColor = { 0, 0, 0, 0 };
143 std::tie(msInfo, msState) =
144 GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);
145 if (!msInfo.fResource || !msState) {
146 return nullptr;
147 }
148
149 const GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
150 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
151
152 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(gpu,
153 budgeted,
154 dimensions,
155 info,
156 std::move(state),
157 shaderResourceView,
158 msInfo,
159 std::move(msState),
160 msaaRenderTargetView,
161 renderTargetView,
162 mipmapStatus,
163 label);
164 return sk_sp<GrD3DTextureRenderTarget>(trt);
165 } else {
166 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(gpu,
167 budgeted,
168 dimensions,
169 info,
170 std::move(state),
171 shaderResourceView,
172 renderTargetView,
173 mipmapStatus,
174 label);
175 return sk_sp<GrD3DTextureRenderTarget>(trt);
176 }
177 }
178
MakeWrappedTextureRenderTarget(GrD3DGpu * gpu,SkISize dimensions,int sampleCnt,GrWrapCacheable cacheable,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state)179 sk_sp<GrD3DTextureRenderTarget> GrD3DTextureRenderTarget::MakeWrappedTextureRenderTarget(
180 GrD3DGpu* gpu,
181 SkISize dimensions,
182 int sampleCnt,
183 GrWrapCacheable cacheable,
184 const GrD3DTextureResourceInfo& info,
185 sk_sp<GrD3DResourceState> state) {
186 // TODO: If a client uses their own heap to allocate, how do we manage that?
187 // Adopted textures require both image and allocation because we're responsible for freeing
188 //SkASSERT(VK_NULL_HANDLE != info.fImage &&
189 // (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
190
191 GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kDirty
192 : GrMipmapStatus::kNotAllocated;
193
194 const GrD3DDescriptorHeap::CPUHandle shaderResourceView =
195 gpu->resourceProvider().createShaderResourceView(info.fResource.get());
196
197 const GrD3DDescriptorHeap::CPUHandle renderTargetView =
198 gpu->resourceProvider().createRenderTargetView(info.fResource.get());
199
200 if (sampleCnt > 1) {
201 GrD3DTextureResourceInfo msInfo;
202 sk_sp<GrD3DResourceState> msState;
203 // for wrapped MSAA surface we assume clear to white
204 SkColor4f clearColor = { 1, 1, 1, 1 };
205 std::tie(msInfo, msState) =
206 GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);
207 if (!msInfo.fResource || !msState) {
208 return nullptr;
209 }
210
211 const GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
212 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
213
214 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(
215 gpu,
216 dimensions,
217 info,
218 std::move(state),
219 shaderResourceView,
220 msInfo,
221 std::move(msState),
222 msaaRenderTargetView,
223 renderTargetView,
224 mipmapStatus,
225 cacheable,
226 /*label=*/"MakeWrappedTextureRenderTargetWithMSAASurface");
227 return sk_sp<GrD3DTextureRenderTarget>(trt);
228 } else {
229 return sk_sp<GrD3DTextureRenderTarget>(
230 new GrD3DTextureRenderTarget(gpu,
231 dimensions,
232 info,
233 std::move(state),
234 shaderResourceView,
235 renderTargetView,
236 mipmapStatus,
237 cacheable,
238 /*label=*/"MakeWrappedTextureRenderTarget"));
239 }
240 }
241
onGpuMemorySize() const242 size_t GrD3DTextureRenderTarget::onGpuMemorySize() const {
243 int numColorSamples = this->numSamples();
244 if (numColorSamples > 1) {
245 // Add one to account for the resolve VkImage.
246 ++numColorSamples;
247 }
248 return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
249 numColorSamples, // TODO: this still correct?
250 this->mipmapped());
251 }
252
onSetLabel()253 void GrD3DTextureRenderTarget::onSetLabel() {
254 GrD3DRenderTarget::onSetLabel();
255 }
256
257