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