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