xref: /aosp_15_r20/external/skia/src/gpu/ganesh/d3d/GrD3DRenderTarget.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/GrD3DRenderTarget.h"
9 
10 #include "include/gpu/ganesh/GrBackendSurface.h"
11 #include "include/gpu/ganesh/d3d/GrD3DTypes.h"
12 #include "src/gpu/KeyBuilder.h"
13 #include "src/gpu/ganesh/GrRenderTarget.h"
14 #include "src/gpu/ganesh/d3d/GrD3DGpu.h"
15 #include "src/gpu/ganesh/d3d/GrD3DResourceProvider.h"
16 #include "src/gpu/ganesh/d3d/GrD3DTextureResource.h"
17 #include "src/gpu/ganesh/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,std::string_view label)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                                      std::string_view label)
31         : GrSurface(gpu, dimensions, info.fProtected, label)
32         , GrD3DTextureResource(info, std::move(state))
33         // for the moment we only support 1:1 color to stencil
34         , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected, label)
35         , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
36         , fColorRenderTargetView(colorRenderTargetView)
37         , fResolveRenderTargetView(resolveRenderTargetView) {
38     SkASSERT(info.fProtected == msaaInfo.fProtected);
39     SkASSERT(msaaInfo.fSampleCount > 1);
40     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
41 }
42 
43 // We're virtually derived from GrSurface (via GrRenderTarget) so its
44 // 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,std::string_view label)45 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
46                                      SkISize dimensions,
47                                      const GrD3DTextureResourceInfo& info,
48                                      sk_sp<GrD3DResourceState> state,
49                                      const GrD3DTextureResourceInfo& msaaInfo,
50                                      sk_sp<GrD3DResourceState> msaaState,
51                                      const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
52                                      const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
53                                      std::string_view label)
54         : GrSurface(gpu, dimensions, info.fProtected, label)
55         , GrD3DTextureResource(info, std::move(state))
56         // for the moment we only support 1:1 color to stencil
57         , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected, label)
58         , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
59         , fColorRenderTargetView(colorRenderTargetView)
60         , fResolveRenderTargetView(resolveRenderTargetView) {
61     SkASSERT(info.fProtected == msaaInfo.fProtected);
62     SkASSERT(msaaInfo.fSampleCount > 1);
63 }
64 
65 // We're virtually derived from GrSurface (via GrRenderTarget) so its
66 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & renderTargetView,Wrapped,std::string_view label)67 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
68                                      SkISize dimensions,
69                                      const GrD3DTextureResourceInfo& info,
70                                      sk_sp<GrD3DResourceState> state,
71                                      const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
72                                      Wrapped,
73                                      std::string_view label)
74         : GrSurface(gpu, dimensions, info.fProtected, label)
75         , GrD3DTextureResource(info, std::move(state))
76         , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected, label)
77         , fMSAATextureResource(nullptr)
78         , fColorRenderTargetView(renderTargetView) {
79     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
80 }
81 
82 // We're virtually derived from GrSurface (via GrRenderTarget) so its
83 // constructor must be explicitly called.
GrD3DRenderTarget(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & renderTargetView,std::string_view label)84 GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
85                                      SkISize dimensions,
86                                      const GrD3DTextureResourceInfo& info,
87                                      sk_sp<GrD3DResourceState> state,
88                                      const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
89                                      std::string_view label)
90         : GrSurface(gpu, dimensions, info.fProtected, label)
91         , GrD3DTextureResource(info, std::move(state))
92         , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected, label)
93         , fMSAATextureResource(nullptr)
94         , fColorRenderTargetView(renderTargetView) {}
95 
MakeWrappedRenderTarget(GrD3DGpu * gpu,SkISize dimensions,int sampleCnt,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state)96 sk_sp<GrD3DRenderTarget> GrD3DRenderTarget::MakeWrappedRenderTarget(
97             GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
98             sk_sp<GrD3DResourceState> state) {
99     SkASSERT(info.fResource.get());
100     SkASSERT(info.fLevelCount == 1);
101     SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1);
102 
103     int wrappedTextureSampleCnt = static_cast<int>(info.fSampleCount);
104     if (sampleCnt != wrappedTextureSampleCnt && wrappedTextureSampleCnt != 1) {
105         return nullptr;
106     }
107 
108     GrD3DDescriptorHeap::CPUHandle renderTargetView =
109             gpu->resourceProvider().createRenderTargetView(info.fResource.get());
110 
111     // create msaa surface if necessary
112     GrD3DRenderTarget* d3dRT;
113     if (sampleCnt != wrappedTextureSampleCnt) {
114         GrD3DTextureResourceInfo msInfo;
115         sk_sp<GrD3DResourceState> msState;
116         // for wrapped MSAA surface we assume clear to white
117         SkColor4f clearColor = { 1, 1, 1, 1 };
118         std::tie(msInfo, msState) =
119                 GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);
120 
121         GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
122                 gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());
123 
124         d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state), msInfo,
125                                       std::move(msState), msaaRenderTargetView, renderTargetView,
126                                       kWrapped,
127                                       /*label=*/"MakeWrappedRenderTargetWithMSAASurface");
128     } else {
129         d3dRT = new GrD3DRenderTarget(
130                 gpu, dimensions, info, std::move(state), renderTargetView, kWrapped,
131                 /*label=*/"MakeWrappedRenderTarget");
132     }
133 
134     return sk_sp<GrD3DRenderTarget>(d3dRT);
135 }
136 
~GrD3DRenderTarget()137 GrD3DRenderTarget::~GrD3DRenderTarget() {
138     // either release or abandon should have been called by the owner of this object.
139     SkASSERT(!fMSAATextureResource);
140 }
141 
msaaTextureResource() const142 const GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() const {
143     if (this->numSamples() == 1) {
144         SkASSERT(!fMSAATextureResource);
145         return nullptr;
146     }
147     if (fMSAATextureResource) {
148         return fMSAATextureResource.get();
149     }
150     SkASSERT(!fMSAATextureResource);
151     return this;
152 }
153 
msaaTextureResource()154 GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() {
155     auto* constThis = const_cast<const GrD3DRenderTarget*>(this);
156     return const_cast<GrD3DTextureResource*>(constThis->msaaTextureResource());
157 }
158 
releaseInternalObjects()159 void GrD3DRenderTarget::releaseInternalObjects() {
160     GrD3DGpu* gpu = this->getD3DGpu();
161 
162     if (fMSAATextureResource) {
163         fMSAATextureResource->releaseResource(gpu);
164         fMSAATextureResource.reset();
165         gpu->resourceProvider().recycleRenderTargetView(fResolveRenderTargetView);
166     }
167 
168     gpu->resourceProvider().recycleRenderTargetView(fColorRenderTargetView);
169 }
170 
onRelease()171 void GrD3DRenderTarget::onRelease() {
172     this->releaseInternalObjects();
173     this->releaseResource(this->getD3DGpu());
174     GrRenderTarget::onRelease();
175 }
176 
onAbandon()177 void GrD3DRenderTarget::onAbandon() {
178     this->releaseInternalObjects();
179     this->releaseResource(this->getD3DGpu());
180     GrRenderTarget::onAbandon();
181 }
182 
getBackendRenderTarget() const183 GrBackendRenderTarget GrD3DRenderTarget::getBackendRenderTarget() const {
184     return GrBackendRenderTarget(this->width(), this->height(), fInfo, this->grD3DResourceState());
185 }
186 
getD3DGpu() const187 GrD3DGpu* GrD3DRenderTarget::getD3DGpu() const {
188     SkASSERT(!this->wasDestroyed());
189     return static_cast<GrD3DGpu*>(this->getGpu());
190 }
191 
stencilDxgiFormat() const192 DXGI_FORMAT GrD3DRenderTarget::stencilDxgiFormat() const {
193     if (auto stencil = this->getStencilAttachment()) {
194         auto d3dStencil = static_cast<GrD3DAttachment*>(stencil);
195         return d3dStencil->dxgiFormat();
196     }
197     return DXGI_FORMAT_UNKNOWN;
198 }
199 
genKey(skgpu::KeyBuilder * b) const200 void GrD3DRenderTarget::genKey(skgpu::KeyBuilder* b) const {
201     b->add32(this->dxgiFormat());
202     b->add32(this->numSamples());
203     b->add32(this->stencilDxgiFormat());
204 #ifdef SK_DEBUG
205     if (const GrAttachment* stencil = this->getStencilAttachment()) {
206         SkASSERT(stencil->numSamples() == this->numSamples());
207     }
208 #endif
209     b->add32(this->sampleQualityPattern());
210 }
211 
onSetLabel()212 void GrD3DRenderTarget::onSetLabel() {
213     SkASSERT(this->d3dResource());
214     if (!this->getLabel().empty()) {
215         if (fMSAATextureResource) {
216             SkASSERT(fMSAATextureResource->d3dResource());
217             const std::wstring suffix = GrD3DMultiByteToWide(this->getLabel());
218             const std::wstring msaaLabel = L"_Skia_MSAA_" + suffix;
219             fMSAATextureResource->d3dResource()->SetName(msaaLabel.c_str());
220             const std::wstring resolveLabel = L"_Skia_Resolve_" + suffix;
221             this->d3dResource()->SetName(resolveLabel.c_str());
222         } else {
223             const std::wstring label = L"_Skia_" + GrD3DMultiByteToWide(this->getLabel());
224             this->d3dResource()->SetName(label.c_str());
225         }
226     }
227 }
228