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