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