• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
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/vk/GrVkTextureRenderTarget.h"
9 
10 #include "include/core/SkSize.h"
11 #include "include/core/SkTypes.h"
12 #include "include/gpu/GpuTypes.h"
13 #include "include/gpu/MutableTextureState.h"
14 #include "include/gpu/ganesh/GrDirectContext.h"
15 #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
16 #include "include/gpu/ganesh/vk/GrVkTypes.h"
17 #include "include/gpu/vk/VulkanTypes.h"
18 #include "src/gpu/ganesh/GrAttachment.h"
19 #include "src/gpu/ganesh/GrDirectContextPriv.h"
20 #include "src/gpu/ganesh/GrResourceProvider.h"
21 #include "src/gpu/ganesh/GrSurface.h"
22 #include "src/gpu/ganesh/vk/GrVkGpu.h"
23 #include "src/gpu/ganesh/vk/GrVkImage.h"
24 #include "src/gpu/ganesh/vk/GrVkUtil.h"
25 
26 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
27 
GrVkTextureRenderTarget(GrVkGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,sk_sp<GrVkImage> texture,sk_sp<GrVkImage> colorAttachment,sk_sp<GrVkImage> resolveAttachment,GrMipmapStatus mipmapStatus,std::string_view label)28 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
29                                                  skgpu::Budgeted budgeted,
30                                                  SkISize dimensions,
31                                                  sk_sp<GrVkImage> texture,
32                                                  sk_sp<GrVkImage> colorAttachment,
33                                                  sk_sp<GrVkImage> resolveAttachment,
34                                                  GrMipmapStatus mipmapStatus,
35                                                  std::string_view label)
36         : GrSurface(gpu,
37                     dimensions,
38                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
39                     label)
40         , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus, label)
41         , GrVkRenderTarget(gpu,
42                            dimensions,
43                            std::move(colorAttachment),
44                            std::move(resolveAttachment),
45                            CreateType::kFromTextureRT,
46                            label) {
47 #ifdef SKIA_OHOS
48     GrVkImage* image = textureImage();
49     if (image && image->GetBudgeted() == skgpu::Budgeted::kYes) {
50         this->registerWithCache(skgpu::Budgeted::kNo);
51     } else {
52         this->registerWithCache(budgeted);
53     }
54 #else
55     this->registerWithCache(budgeted);
56 #endif
57 }
58 
GrVkTextureRenderTarget(GrVkGpu * gpu,SkISize dimensions,sk_sp<GrVkImage> texture,sk_sp<GrVkImage> colorAttachment,sk_sp<GrVkImage> resolveAttachment,GrMipmapStatus mipmapStatus,GrWrapCacheable cacheable,std::string_view label)59 GrVkTextureRenderTarget::GrVkTextureRenderTarget(
60         GrVkGpu* gpu,
61         SkISize dimensions,
62         sk_sp<GrVkImage> texture,
63         sk_sp<GrVkImage> colorAttachment,
64         sk_sp<GrVkImage> resolveAttachment,
65         GrMipmapStatus mipmapStatus,
66         GrWrapCacheable cacheable,
67         std::string_view label)
68         : GrSurface(gpu,
69                     dimensions,
70                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
71                     label)
72         , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus, label)
73         , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
74                            std::move(resolveAttachment), CreateType::kFromTextureRT, label) {
75     this->registerWithCacheWrapped(cacheable);
76 }
77 
create_rt_attachments(GrVkGpu * gpu,SkISize dimensions,VkFormat format,int sampleCnt,GrProtected isProtected,sk_sp<GrVkImage> texture,sk_sp<GrVkImage> * colorAttachment,sk_sp<GrVkImage> * resolveAttachment)78 bool create_rt_attachments(GrVkGpu* gpu, SkISize dimensions, VkFormat format, int sampleCnt,
79                            GrProtected isProtected,
80                            sk_sp<GrVkImage> texture,
81                            sk_sp<GrVkImage>* colorAttachment,
82                            sk_sp<GrVkImage>* resolveAttachment) {
83     if (sampleCnt > 1) {
84         auto rp = gpu->getContext()->priv().resourceProvider();
85         sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment(
86                 dimensions, GrBackendFormats::MakeVk(format), sampleCnt, isProtected,
87                 GrMemoryless::kNo);
88         if (!msaaAttachment) {
89             return false;
90         }
91         *colorAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release()));
92         *resolveAttachment = std::move(texture);
93     } else {
94         *colorAttachment = std::move(texture);
95     }
96     return true;
97 }
98 
MakeNewTextureRenderTarget(GrVkGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,VkFormat format,uint32_t mipLevels,int sampleCnt,GrMipmapStatus mipmapStatus,GrProtected isProtected,std::string_view label)99 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
100         GrVkGpu* gpu,
101         skgpu::Budgeted budgeted,
102         SkISize dimensions,
103         VkFormat format,
104         uint32_t mipLevels,
105         int sampleCnt,
106         GrMipmapStatus mipmapStatus,
107         GrProtected isProtected,
108         std::string_view label) {
109     sk_sp<GrVkImage> texture = GrVkImage::MakeTexture(gpu,
110                                                       dimensions,
111                                                       format,
112                                                       mipLevels,
113                                                       GrRenderable::kYes,
114                                                       /*numSamples=*/1,
115                                                       budgeted,
116                                                       isProtected);
117     if (!texture) {
118         return nullptr;
119     }
120 
121     sk_sp<GrVkImage> colorAttachment;
122     sk_sp<GrVkImage> resolveAttachment;
123     if (!create_rt_attachments(gpu, dimensions, format, sampleCnt, isProtected, texture,
124                                &colorAttachment, &resolveAttachment)) {
125         return nullptr;
126     }
127     SkASSERT(colorAttachment);
128     SkASSERT(sampleCnt == 1 || resolveAttachment);
129     return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(gpu,
130                                                                       budgeted,
131                                                                       dimensions,
132                                                                       std::move(texture),
133                                                                       std::move(colorAttachment),
134                                                                       std::move(resolveAttachment),
135                                                                       mipmapStatus,
136                                                                       label));
137 }
138 
MakeWrappedTextureRenderTarget(GrVkGpu * gpu,SkISize dimensions,int sampleCnt,GrWrapOwnership wrapOwnership,GrWrapCacheable cacheable,const GrVkImageInfo & info,sk_sp<skgpu::MutableTextureState> mutableState)139 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
140         GrVkGpu* gpu,
141         SkISize dimensions,
142         int sampleCnt,
143         GrWrapOwnership wrapOwnership,
144         GrWrapCacheable cacheable,
145         const GrVkImageInfo& info,
146         sk_sp<skgpu::MutableTextureState> mutableState) {
147     // Adopted textures require both image and allocation because we're responsible for freeing
148     SkASSERT(VK_NULL_HANDLE != info.fImage &&
149              (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
150 
151     GrAttachment::UsageFlags textureUsageFlags = GrAttachment::UsageFlags::kTexture;
152     if (info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
153         textureUsageFlags |= GrAttachment::UsageFlags::kColorAttachment;
154     }
155 
156     sk_sp<GrVkImage> texture = GrVkImage::MakeWrapped(gpu,
157                                                       dimensions,
158                                                       info,
159                                                       std::move(mutableState),
160                                                       textureUsageFlags,
161                                                       wrapOwnership,
162                                                       cacheable,
163                                                       "VkImage_MakeWrappedTextureRenderTarget");
164     if (!texture) {
165         return nullptr;
166     }
167 
168     sk_sp<GrVkImage> colorAttachment;
169     sk_sp<GrVkImage> resolveAttachment;
170     if (!create_rt_attachments(gpu, dimensions, info.fFormat, sampleCnt, info.fProtected, texture,
171                                &colorAttachment, &resolveAttachment)) {
172         return nullptr;
173     }
174     SkASSERT(colorAttachment);
175     SkASSERT(sampleCnt == 1 || resolveAttachment);
176 
177     GrMipmapStatus mipmapStatus =
178             info.fLevelCount > 1 ? GrMipmapStatus::kDirty : GrMipmapStatus::kNotAllocated;
179 
180     return sk_sp<GrVkTextureRenderTarget>(
181             new GrVkTextureRenderTarget(gpu,
182                                         dimensions,
183                                         std::move(texture),
184                                         std::move(colorAttachment),
185                                         std::move(resolveAttachment),
186                                         mipmapStatus,
187                                         cacheable,
188                                         /*label=*/"Vk_MakeWrappedTextureRenderTarget"));
189 }
190 
onGpuMemorySize() const191 size_t GrVkTextureRenderTarget::onGpuMemorySize() const {
192     // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
193     // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
194     // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
195     // attachment to give its own size since we don't have GrGpuResources owning other
196     // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
197     // the msaa and stencil attachments track their own size because they do get cached separately.
198     // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
199     // the owned attachments will have no size and be uncached.
200 #ifdef SK_DEBUG
201     // The nonMSAA attachment (either color or resolve depending on numSamples should have size of
202     // zero since it is a texture attachment.
203     SkASSERT(this->nonMSAAAttachment()->gpuMemorySize() == 0);
204     if (this->numSamples() > 1) {
205         // Msaa attachment should have a valid size
206         SkASSERT(this->colorAttachment()->gpuMemorySize() ==
207                  GrSurface::ComputeSize(this->backendFormat(),
208                                         this->dimensions(),
209                                         this->numSamples(),
210                                         skgpu::Mipmapped::kNo));
211     }
212 #endif
213     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
214                                   1 /*colorSamplesPerPixel*/, this->mipmapped());
215 }
216 
dumpMemoryStatistics(SkTraceMemoryDump * traceMemoryDump) const217 void GrVkTextureRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
218     SkString resourceName = this->getResourceName();
219     resourceName.append("/texture_renderbuffer");
220     if (textureImage()->isBorrowed() && !textureImage()->isRealAlloc()) {
221         this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "External RenderTarget",
222             this->gpuMemorySize());
223     } else {
224         this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "RenderTarget",
225             this->gpuMemorySize());
226     }
227 }
228