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
146 const GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
147 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
148
149 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(gpu,
150 budgeted,
151 dimensions,
152 info,
153 std::move(state),
154 shaderResourceView,
155 msInfo,
156 std::move(msState),
157 msaaRenderTargetView,
158 renderTargetView,
159 mipmapStatus,
160 label);
161 return sk_sp<GrD3DTextureRenderTarget>(trt);
162 } else {
163 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(gpu,
164 budgeted,
165 dimensions,
166 info,
167 std::move(state),
168 shaderResourceView,
169 renderTargetView,
170 mipmapStatus,
171 label);
172 return sk_sp<GrD3DTextureRenderTarget>(trt);
173 }
174 }
175
MakeWrappedTextureRenderTarget(GrD3DGpu * gpu,SkISize dimensions,int sampleCnt,GrWrapCacheable cacheable,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state)176 sk_sp<GrD3DTextureRenderTarget> GrD3DTextureRenderTarget::MakeWrappedTextureRenderTarget(
177 GrD3DGpu* gpu,
178 SkISize dimensions,
179 int sampleCnt,
180 GrWrapCacheable cacheable,
181 const GrD3DTextureResourceInfo& info,
182 sk_sp<GrD3DResourceState> state) {
183 // TODO: If a client uses their own heap to allocate, how do we manage that?
184 // Adopted textures require both image and allocation because we're responsible for freeing
185 //SkASSERT(VK_NULL_HANDLE != info.fImage &&
186 // (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
187
188 GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kDirty
189 : GrMipmapStatus::kNotAllocated;
190
191 const GrD3DDescriptorHeap::CPUHandle shaderResourceView =
192 gpu->resourceProvider().createShaderResourceView(info.fResource.get());
193
194 const GrD3DDescriptorHeap::CPUHandle renderTargetView =
195 gpu->resourceProvider().createRenderTargetView(info.fResource.get());
196
197 if (sampleCnt > 1) {
198 GrD3DTextureResourceInfo msInfo;
199 sk_sp<GrD3DResourceState> msState;
200 // for wrapped MSAA surface we assume clear to white
201 SkColor4f clearColor = { 1, 1, 1, 1 };
202 std::tie(msInfo, msState) =
203 GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);
204
205 const GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
206 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
207
208 GrD3DTextureRenderTarget* trt = new GrD3DTextureRenderTarget(
209 gpu,
210 dimensions,
211 info,
212 std::move(state),
213 shaderResourceView,
214 msInfo,
215 std::move(msState),
216 msaaRenderTargetView,
217 renderTargetView,
218 mipmapStatus,
219 cacheable,
220 /*label=*/"MakeWrappedTextureRenderTargetWithMSAASurface");
221 return sk_sp<GrD3DTextureRenderTarget>(trt);
222 } else {
223 return sk_sp<GrD3DTextureRenderTarget>(
224 new GrD3DTextureRenderTarget(gpu,
225 dimensions,
226 info,
227 std::move(state),
228 shaderResourceView,
229 renderTargetView,
230 mipmapStatus,
231 cacheable,
232 /*label=*/"MakeWrappedTextureRenderTarget"));
233 }
234 }
235
onGpuMemorySize() const236 size_t GrD3DTextureRenderTarget::onGpuMemorySize() const {
237 int numColorSamples = this->numSamples();
238 if (numColorSamples > 1) {
239 // Add one to account for the resolve VkImage.
240 ++numColorSamples;
241 }
242 return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
243 numColorSamples, // TODO: this still correct?
244 this->mipmapped());
245 }
246
onSetLabel()247 void GrD3DTextureRenderTarget::onSetLabel() {
248 GrD3DRenderTarget::onSetLabel();
249 }
250
251