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