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