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