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