• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GrD3DRenderTarget.h"
9 
10 #include "include/gpu/GrBackendSurface.h"
11 #include "include/gpu/d3d/GrD3DTypes.h"
12 #include "src/gpu/GrRenderTarget.h"
13 #include "src/gpu/KeyBuilder.h"
14 #include "src/gpu/d3d/GrD3DGpu.h"
15 #include "src/gpu/d3d/GrD3DResourceProvider.h"
16 #include "src/gpu/d3d/GrD3DTextureResource.h"
17 #include "src/gpu/d3d/GrD3DUtil.h"
18 
19 // We're virtually derived from GrSurface (via GrRenderTarget) so its
20 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DTextureResourceInfo & msaaInfo,sk_sp<GrD3DResourceState> msaaState,const GrD3DDescriptorHeap::CPUHandle & colorRenderTargetView,const GrD3DDescriptorHeap::CPUHandle & resolveRenderTargetView,Wrapped)21 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
22                                      SkISize dimensions,
23                                      const GrD3DTextureResourceInfo& info,
24                                      sk_sp<GrD3DResourceState> state,
25                                      const GrD3DTextureResourceInfo& msaaInfo,
26                                      sk_sp<GrD3DResourceState> msaaState,
27                                      const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
28                                      const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
29                                      Wrapped)
30         : GrSurface(gpu, dimensions, info.fProtected)
31         , GrD3DTextureResource(info, std::move(state))
32         // for the moment we only support 1:1 color to stencil
33         , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected)
34         , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
35         , fColorRenderTargetView(colorRenderTargetView)
36         , fResolveRenderTargetView(resolveRenderTargetView) {
37     SkASSERT(info.fProtected == msaaInfo.fProtected);
38     SkASSERT(msaaInfo.fSampleCount > 1);
39     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
40 }
41 
42 // We're virtually derived from GrSurface (via GrRenderTarget) so its
43 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DTextureResourceInfo & msaaInfo,sk_sp<GrD3DResourceState> msaaState,const GrD3DDescriptorHeap::CPUHandle & colorRenderTargetView,const GrD3DDescriptorHeap::CPUHandle & resolveRenderTargetView)44 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
45                                      SkISize dimensions,
46                                      const GrD3DTextureResourceInfo& info,
47                                      sk_sp<GrD3DResourceState> state,
48                                      const GrD3DTextureResourceInfo& msaaInfo,
49                                      sk_sp<GrD3DResourceState> msaaState,
50                                      const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
51                                      const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView)
52         : GrSurface(gpu, dimensions, info.fProtected)
53         , GrD3DTextureResource(info, std::move(state))
54         // for the moment we only support 1:1 color to stencil
55         , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected)
56         , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
57         , fColorRenderTargetView(colorRenderTargetView)
58         , fResolveRenderTargetView(resolveRenderTargetView) {
59     SkASSERT(info.fProtected == msaaInfo.fProtected);
60     SkASSERT(msaaInfo.fSampleCount > 1);
61 }
62 
63 // We're virtually derived from GrSurface (via GrRenderTarget) so its
64 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & renderTargetView,Wrapped)65 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
66                                      SkISize dimensions,
67                                      const GrD3DTextureResourceInfo& info,
68                                      sk_sp<GrD3DResourceState> state,
69                                      const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
70                                      Wrapped)
71         : GrSurface(gpu, dimensions, info.fProtected)
72         , GrD3DTextureResource(info, std::move(state))
73         , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected)
74         , fMSAATextureResource(nullptr)
75         , fColorRenderTargetView(renderTargetView) {
76     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
77 }
78 
79 // We're virtually derived from GrSurface (via GrRenderTarget) so its
80 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & renderTargetView)81 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
82                                      SkISize dimensions,
83                                      const GrD3DTextureResourceInfo& info,
84                                      sk_sp<GrD3DResourceState> state,
85                                      const GrD3DDescriptorHeap::CPUHandle& renderTargetView)
86         : GrSurface(gpu, dimensions, info.fProtected)
87         , GrD3DTextureResource(info, std::move(state))
88         , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected)
89         , fMSAATextureResource(nullptr)
90         , fColorRenderTargetView(renderTargetView) {}
91 
MakeWrappedRenderTarget(GrD3DGpu * gpu,SkISize dimensions,int sampleCnt,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state)92 sk_sp<GrD3DRenderTarget> GrD3DRenderTarget::MakeWrappedRenderTarget(
93             GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
94             sk_sp<GrD3DResourceState> state) {
95     SkASSERT(info.fResource.get());
96     SkASSERT(info.fLevelCount == 1);
97     SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1);
98 
99     int wrappedTextureSampleCnt = static_cast<int>(info.fSampleCount);
100     if (sampleCnt != wrappedTextureSampleCnt && wrappedTextureSampleCnt != 1) {
101         return nullptr;
102     }
103 
104     GrD3DDescriptorHeap::CPUHandle renderTargetView =
105             gpu->resourceProvider().createRenderTargetView(info.fResource.get());
106 
107     // create msaa surface if necessary
108     GrD3DRenderTarget* d3dRT;
109     if (sampleCnt != wrappedTextureSampleCnt) {
110         GrD3DTextureResourceInfo msInfo;
111         sk_sp<GrD3DResourceState> msState;
112         // for wrapped MSAA surface we assume clear to white
113         SkColor4f clearColor = { 1, 1, 1, 1 };
114         std::tie(msInfo, msState) =
115                 GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);
116 
117         GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
118                 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
119 
120         d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state), msInfo,
121                                       std::move(msState), msaaRenderTargetView, renderTargetView,
122                                       kWrapped);
123     } else {
124         d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state), renderTargetView,
125                                       kWrapped);
126     }
127 
128     return sk_sp<GrD3DRenderTarget>(d3dRT);
129 }
130 
~GrD3DRenderTarget()131 GrD3DRenderTarget::~GrD3DRenderTarget() {
132     // either release or abandon should have been called by the owner of this object.
133     SkASSERT(!fMSAATextureResource);
134 }
135 
msaaTextureResource() const136 const GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() const {
137     if (this->numSamples() == 1) {
138         SkASSERT(!fMSAATextureResource);
139         return nullptr;
140     }
141     if (fMSAATextureResource) {
142         return fMSAATextureResource.get();
143     }
144     SkASSERT(!fMSAATextureResource);
145     return this;
146 }
147 
msaaTextureResource()148 GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() {
149     auto* constThis = const_cast<const GrD3DRenderTarget*>(this);
150     return const_cast<GrD3DTextureResource*>(constThis->msaaTextureResource());
151 }
152 
releaseInternalObjects()153 void GrD3DRenderTarget::releaseInternalObjects() {
154     GrD3DGpu* gpu = this->getD3DGpu();
155 
156     if (fMSAATextureResource) {
157         fMSAATextureResource->releaseResource(gpu);
158         fMSAATextureResource.reset();
159         gpu->resourceProvider().recycleRenderTargetView(fResolveRenderTargetView);
160     }
161 
162     gpu->resourceProvider().recycleRenderTargetView(fColorRenderTargetView);
163 }
164 
onRelease()165 void GrD3DRenderTarget::onRelease() {
166     this->releaseInternalObjects();
167     this->releaseResource(this->getD3DGpu());
168     GrRenderTarget::onRelease();
169 }
170 
onAbandon()171 void GrD3DRenderTarget::onAbandon() {
172     this->releaseInternalObjects();
173     this->releaseResource(this->getD3DGpu());
174     GrRenderTarget::onAbandon();
175 }
176 
getBackendRenderTarget() const177 GrBackendRenderTarget GrD3DRenderTarget::getBackendRenderTarget() const {
178     return GrBackendRenderTarget(this->width(), this->height(), fInfo, this->grD3DResourceState());
179 }
180 
getD3DGpu() const181 GrD3DGpu* GrD3DRenderTarget::getD3DGpu() const {
182     SkASSERT(!this->wasDestroyed());
183     return static_cast<GrD3DGpu*>(this->getGpu());
184 }
185 
stencilDxgiFormat() const186 DXGI_FORMAT GrD3DRenderTarget::stencilDxgiFormat() const {
187     if (auto stencil = this->getStencilAttachment()) {
188         auto d3dStencil = static_cast<GrD3DAttachment*>(stencil);
189         return d3dStencil->dxgiFormat();
190     }
191     return DXGI_FORMAT_UNKNOWN;
192 }
193 
genKey(skgpu::KeyBuilder * b) const194 void GrD3DRenderTarget::genKey(skgpu::KeyBuilder* b) const {
195     b->add32(this->dxgiFormat());
196     b->add32(this->numSamples());
197     b->add32(this->stencilDxgiFormat());
198 #ifdef SK_DEBUG
199     if (const GrAttachment* stencil = this->getStencilAttachment()) {
200         SkASSERT(stencil->numSamples() == this->numSamples());
201     }
202 #endif
203     b->add32(this->sampleQualityPattern());
204 }
205