xref: /aosp_15_r20/external/skia/src/gpu/ganesh/d3d/GrD3DTexture.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DTexture.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DGpu.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DUtil.h"
13*c8dee2aaSAndroid Build Coastguard Worker 
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/d3d/GrD3DTypes.h"
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrD3DTexture(GrD3DGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,GrMipmapStatus mipmapStatus,std::string_view label)17*c8dee2aaSAndroid Build Coastguard Worker GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu,
18*c8dee2aaSAndroid Build Coastguard Worker                            skgpu::Budgeted budgeted,
19*c8dee2aaSAndroid Build Coastguard Worker                            SkISize dimensions,
20*c8dee2aaSAndroid Build Coastguard Worker                            const GrD3DTextureResourceInfo& info,
21*c8dee2aaSAndroid Build Coastguard Worker                            sk_sp<GrD3DResourceState> state,
22*c8dee2aaSAndroid Build Coastguard Worker                            const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
23*c8dee2aaSAndroid Build Coastguard Worker                            GrMipmapStatus mipmapStatus,
24*c8dee2aaSAndroid Build Coastguard Worker                            std::string_view label)
25*c8dee2aaSAndroid Build Coastguard Worker         : GrSurface(gpu, dimensions, info.fProtected, label)
26*c8dee2aaSAndroid Build Coastguard Worker         , GrD3DTextureResource(info, std::move(state))
27*c8dee2aaSAndroid Build Coastguard Worker         , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus, label)
28*c8dee2aaSAndroid Build Coastguard Worker         , fShaderResourceView(shaderResourceView) {
29*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
30*c8dee2aaSAndroid Build Coastguard Worker     this->registerWithCache(budgeted);
31*c8dee2aaSAndroid Build Coastguard Worker     if (GrDxgiFormatIsCompressed(info.fFormat)) {
32*c8dee2aaSAndroid Build Coastguard Worker         this->setReadOnly();
33*c8dee2aaSAndroid Build Coastguard Worker     }
34*c8dee2aaSAndroid Build Coastguard Worker }
35*c8dee2aaSAndroid Build Coastguard Worker 
GrD3DTexture(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,GrMipmapStatus mipmapStatus,GrWrapCacheable cacheable,GrIOType ioType,std::string_view label)36*c8dee2aaSAndroid Build Coastguard Worker GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu, SkISize dimensions, const GrD3DTextureResourceInfo& info,
37*c8dee2aaSAndroid Build Coastguard Worker                            sk_sp<GrD3DResourceState> state,
38*c8dee2aaSAndroid Build Coastguard Worker                            const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
39*c8dee2aaSAndroid Build Coastguard Worker                            GrMipmapStatus mipmapStatus, GrWrapCacheable cacheable,
40*c8dee2aaSAndroid Build Coastguard Worker                            GrIOType ioType,
41*c8dee2aaSAndroid Build Coastguard Worker                            std::string_view label)
42*c8dee2aaSAndroid Build Coastguard Worker         : GrSurface(gpu, dimensions, info.fProtected, label)
43*c8dee2aaSAndroid Build Coastguard Worker         , GrD3DTextureResource(info, std::move(state))
44*c8dee2aaSAndroid Build Coastguard Worker         , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus, label)
45*c8dee2aaSAndroid Build Coastguard Worker         , fShaderResourceView(shaderResourceView) {
46*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
47*c8dee2aaSAndroid Build Coastguard Worker     if (ioType == kRead_GrIOType) {
48*c8dee2aaSAndroid Build Coastguard Worker         this->setReadOnly();
49*c8dee2aaSAndroid Build Coastguard Worker     }
50*c8dee2aaSAndroid Build Coastguard Worker     this->registerWithCacheWrapped(cacheable);
51*c8dee2aaSAndroid Build Coastguard Worker }
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrD3DTexture(GrD3DGpu * gpu,SkISize dimensions,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state,const GrD3DDescriptorHeap::CPUHandle & shaderResourceView,GrMipmapStatus mipmapStatus,std::string_view label)54*c8dee2aaSAndroid Build Coastguard Worker GrD3DTexture::GrD3DTexture(GrD3DGpu* gpu,
55*c8dee2aaSAndroid Build Coastguard Worker                            SkISize dimensions,
56*c8dee2aaSAndroid Build Coastguard Worker                            const GrD3DTextureResourceInfo& info,
57*c8dee2aaSAndroid Build Coastguard Worker                            sk_sp<GrD3DResourceState> state,
58*c8dee2aaSAndroid Build Coastguard Worker                            const GrD3DDescriptorHeap::CPUHandle& shaderResourceView,
59*c8dee2aaSAndroid Build Coastguard Worker                            GrMipmapStatus mipmapStatus,
60*c8dee2aaSAndroid Build Coastguard Worker                            std::string_view label)
61*c8dee2aaSAndroid Build Coastguard Worker         : GrSurface(gpu, dimensions, info.fProtected, label)
62*c8dee2aaSAndroid Build Coastguard Worker         , GrD3DTextureResource(info, state)
63*c8dee2aaSAndroid Build Coastguard Worker         , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus, label)
64*c8dee2aaSAndroid Build Coastguard Worker         , fShaderResourceView(shaderResourceView) {
65*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
66*c8dee2aaSAndroid Build Coastguard Worker }
67*c8dee2aaSAndroid Build Coastguard Worker 
MakeNewTexture(GrD3DGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,const D3D12_RESOURCE_DESC & desc,GrProtected isProtected,GrMipmapStatus mipmapStatus,std::string_view label)68*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DTexture> GrD3DTexture::MakeNewTexture(GrD3DGpu* gpu,
69*c8dee2aaSAndroid Build Coastguard Worker                                                  skgpu::Budgeted budgeted,
70*c8dee2aaSAndroid Build Coastguard Worker                                                  SkISize dimensions,
71*c8dee2aaSAndroid Build Coastguard Worker                                                  const D3D12_RESOURCE_DESC& desc,
72*c8dee2aaSAndroid Build Coastguard Worker                                                  GrProtected isProtected,
73*c8dee2aaSAndroid Build Coastguard Worker                                                  GrMipmapStatus mipmapStatus,
74*c8dee2aaSAndroid Build Coastguard Worker                                                  std::string_view label) {
75*c8dee2aaSAndroid Build Coastguard Worker     GrD3DTextureResourceInfo info;
76*c8dee2aaSAndroid Build Coastguard Worker     if (!GrD3DTextureResource::InitTextureResourceInfo(gpu, desc,
77*c8dee2aaSAndroid Build Coastguard Worker                                                        D3D12_RESOURCE_STATE_COPY_DEST,
78*c8dee2aaSAndroid Build Coastguard Worker                                                        isProtected, nullptr, &info)) {
79*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
80*c8dee2aaSAndroid Build Coastguard Worker     }
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrD3DResourceState> state(
83*c8dee2aaSAndroid Build Coastguard Worker             new GrD3DResourceState(static_cast<D3D12_RESOURCE_STATES>(info.fResourceState)));
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker     GrD3DDescriptorHeap::CPUHandle shaderResourceView =
86*c8dee2aaSAndroid Build Coastguard Worker             gpu->resourceProvider().createShaderResourceView(info.fResource.get());
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker     GrD3DTexture* tex = new GrD3DTexture(gpu, budgeted, dimensions, info, std::move(state),
89*c8dee2aaSAndroid Build Coastguard Worker                                          shaderResourceView,
90*c8dee2aaSAndroid Build Coastguard Worker                                          mipmapStatus,
91*c8dee2aaSAndroid Build Coastguard Worker                                          label);
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrD3DTexture>(tex);
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker 
MakeWrappedTexture(GrD3DGpu * gpu,SkISize dimensions,GrWrapCacheable cacheable,GrIOType ioType,const GrD3DTextureResourceInfo & info,sk_sp<GrD3DResourceState> state)96*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DTexture> GrD3DTexture::MakeWrappedTexture(GrD3DGpu* gpu,
97*c8dee2aaSAndroid Build Coastguard Worker                                                      SkISize dimensions,
98*c8dee2aaSAndroid Build Coastguard Worker                                                      GrWrapCacheable cacheable,
99*c8dee2aaSAndroid Build Coastguard Worker                                                      GrIOType ioType,
100*c8dee2aaSAndroid Build Coastguard Worker                                                      const GrD3DTextureResourceInfo& info,
101*c8dee2aaSAndroid Build Coastguard Worker                                                      sk_sp<GrD3DResourceState> state) {
102*c8dee2aaSAndroid Build Coastguard Worker     // TODO: If a client uses their own heap to allocate, how do we manage that?
103*c8dee2aaSAndroid Build Coastguard Worker     // Adopted textures require both image and allocation because we're responsible for freeing
104*c8dee2aaSAndroid Build Coastguard Worker     //SkASSERT(info.fTexture &&
105*c8dee2aaSAndroid Build Coastguard Worker     //         (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
106*c8dee2aaSAndroid Build Coastguard Worker 
107*c8dee2aaSAndroid Build Coastguard Worker     GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kValid
108*c8dee2aaSAndroid Build Coastguard Worker                                                        : GrMipmapStatus::kNotAllocated;
109*c8dee2aaSAndroid Build Coastguard Worker 
110*c8dee2aaSAndroid Build Coastguard Worker     GrD3DDescriptorHeap::CPUHandle shaderResourceView =
111*c8dee2aaSAndroid Build Coastguard Worker             gpu->resourceProvider().createShaderResourceView(info.fResource.get());
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrD3DTexture>(new GrD3DTexture(gpu, dimensions, info, std::move(state),
114*c8dee2aaSAndroid Build Coastguard Worker                                                 shaderResourceView, mipmapStatus, cacheable,
115*c8dee2aaSAndroid Build Coastguard Worker                                                 ioType,
116*c8dee2aaSAndroid Build Coastguard Worker                                                 /*label=*/"D3DWrappedTexture"));
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker 
MakeAliasingTexture(GrD3DGpu * gpu,sk_sp<GrD3DTexture> originalTexture,const D3D12_RESOURCE_DESC & newDesc,D3D12_RESOURCE_STATES resourceState)119*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DTexture> GrD3DTexture::MakeAliasingTexture(GrD3DGpu* gpu,
120*c8dee2aaSAndroid Build Coastguard Worker                                                       sk_sp<GrD3DTexture> originalTexture,
121*c8dee2aaSAndroid Build Coastguard Worker                                                       const D3D12_RESOURCE_DESC& newDesc,
122*c8dee2aaSAndroid Build Coastguard Worker                                                       D3D12_RESOURCE_STATES resourceState) {
123*c8dee2aaSAndroid Build Coastguard Worker     GrD3DTextureResourceInfo info = originalTexture->fInfo;
124*c8dee2aaSAndroid Build Coastguard Worker     info.fResource = gpu->memoryAllocator()->createAliasingResource(info.fAlloc, 0, &newDesc,
125*c8dee2aaSAndroid Build Coastguard Worker                                                                     resourceState, nullptr);
126*c8dee2aaSAndroid Build Coastguard Worker     if (!info.fResource) {
127*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
128*c8dee2aaSAndroid Build Coastguard Worker     }
129*c8dee2aaSAndroid Build Coastguard Worker     info.fResourceState = resourceState;
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrD3DResourceState> state(
132*c8dee2aaSAndroid Build Coastguard Worker         new GrD3DResourceState(static_cast<D3D12_RESOURCE_STATES>(resourceState)));
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     GrD3DDescriptorHeap::CPUHandle shaderResourceView =
135*c8dee2aaSAndroid Build Coastguard Worker         gpu->resourceProvider().createShaderResourceView(info.fResource.get());
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker     GrD3DTexture* tex = new GrD3DTexture(gpu,
138*c8dee2aaSAndroid Build Coastguard Worker                                          skgpu::Budgeted::kNo,
139*c8dee2aaSAndroid Build Coastguard Worker                                          originalTexture->dimensions(),
140*c8dee2aaSAndroid Build Coastguard Worker                                          info,
141*c8dee2aaSAndroid Build Coastguard Worker                                          std::move(state),
142*c8dee2aaSAndroid Build Coastguard Worker                                          shaderResourceView,
143*c8dee2aaSAndroid Build Coastguard Worker                                          originalTexture->mipmapStatus(),
144*c8dee2aaSAndroid Build Coastguard Worker                                          /*label=*/"AliasingTexture");
145*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrD3DTexture>(tex);
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker 
onRelease()148*c8dee2aaSAndroid Build Coastguard Worker void GrD3DTexture::onRelease() {
149*c8dee2aaSAndroid Build Coastguard Worker     GrD3DGpu* gpu = this->getD3DGpu();
150*c8dee2aaSAndroid Build Coastguard Worker     gpu->resourceProvider().recycleShaderView(fShaderResourceView);
151*c8dee2aaSAndroid Build Coastguard Worker     this->releaseResource(gpu);
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker     INHERITED::onRelease();
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker 
onAbandon()156*c8dee2aaSAndroid Build Coastguard Worker void GrD3DTexture::onAbandon() {
157*c8dee2aaSAndroid Build Coastguard Worker     GrD3DGpu* gpu = this->getD3DGpu();
158*c8dee2aaSAndroid Build Coastguard Worker     gpu->resourceProvider().recycleShaderView(fShaderResourceView);
159*c8dee2aaSAndroid Build Coastguard Worker     this->releaseResource(gpu);
160*c8dee2aaSAndroid Build Coastguard Worker     INHERITED::onAbandon();
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker 
getBackendTexture() const163*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture GrD3DTexture::getBackendTexture() const {
164*c8dee2aaSAndroid Build Coastguard Worker     return GrBackendTexture(this->width(), this->height(), fInfo, this->grD3DResourceState());
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker 
getD3DGpu() const167*c8dee2aaSAndroid Build Coastguard Worker GrD3DGpu* GrD3DTexture::getD3DGpu() const {
168*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!this->wasDestroyed());
169*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<GrD3DGpu*>(this->getGpu());
170*c8dee2aaSAndroid Build Coastguard Worker }
171*c8dee2aaSAndroid Build Coastguard Worker 
onSetLabel()172*c8dee2aaSAndroid Build Coastguard Worker void GrD3DTexture::onSetLabel() {
173*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(this->d3dResource());
174*c8dee2aaSAndroid Build Coastguard Worker     if (!this->getLabel().empty()) {
175*c8dee2aaSAndroid Build Coastguard Worker         const std::wstring label = L"_Skia_" + GrD3DMultiByteToWide(this->getLabel());
176*c8dee2aaSAndroid Build Coastguard Worker         this->d3dResource()->SetName(label.c_str());
177*c8dee2aaSAndroid Build Coastguard Worker     }
178*c8dee2aaSAndroid Build Coastguard Worker }
179