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