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 "GrVkTextureRenderTarget.h"
9
10 #include "GrRenderTargetPriv.h"
11 #include "GrVkGpu.h"
12 #include "GrVkImageView.h"
13 #include "GrVkUtil.h"
14
15 #include "SkMipMap.h"
16
17 #include "vk/GrVkTypes.h"
18
19 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
20
Create(GrVkGpu * gpu,const GrSurfaceDesc & desc,const GrVkImageInfo & info,SkBudgeted budgeted,GrVkImage::Wrapped wrapped)21 GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
22 const GrSurfaceDesc& desc,
23 const GrVkImageInfo& info,
24 SkBudgeted budgeted,
25 GrVkImage::Wrapped wrapped) {
26 VkImage image = info.fImage;
27 // Create the texture ImageView
28 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
29 GrVkImageView::kColor_Type,
30 info.fLevelCount);
31 if (!imageView) {
32 return nullptr;
33 }
34
35 VkFormat pixelFormat;
36 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
37
38 VkImage colorImage;
39
40 // create msaa surface if necessary
41 GrVkImageInfo msInfo;
42 const GrVkImageView* resolveAttachmentView = nullptr;
43 if (desc.fSampleCnt) {
44 GrVkImage::ImageDesc msImageDesc;
45 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
46 msImageDesc.fFormat = pixelFormat;
47 msImageDesc.fWidth = desc.fWidth;
48 msImageDesc.fHeight = desc.fHeight;
49 msImageDesc.fLevels = 1;
50 msImageDesc.fSamples = desc.fSampleCnt;
51 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
52 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
53 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
54 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
55 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
56
57 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
58 imageView->unref(gpu);
59 return nullptr;
60 }
61
62 // Set color attachment image
63 colorImage = msInfo.fImage;
64
65 // Create resolve attachment view.
66 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
67 GrVkImageView::kColor_Type,
68 info.fLevelCount);
69 if (!resolveAttachmentView) {
70 GrVkImage::DestroyImageInfo(gpu, &msInfo);
71 imageView->unref(gpu);
72 return nullptr;
73 }
74 } else {
75 // Set color attachment image
76 colorImage = info.fImage;
77 }
78
79 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
80 GrVkImageView::kColor_Type, 1);
81 if (!colorAttachmentView) {
82 if (desc.fSampleCnt) {
83 resolveAttachmentView->unref(gpu);
84 GrVkImage::DestroyImageInfo(gpu, &msInfo);
85 }
86 imageView->unref(gpu);
87 return nullptr;
88 }
89
90 GrVkTextureRenderTarget* texRT;
91 if (desc.fSampleCnt) {
92 if (GrVkImage::kNot_Wrapped == wrapped) {
93 texRT = new GrVkTextureRenderTarget(gpu, budgeted, desc,
94 info, imageView, msInfo,
95 colorAttachmentView,
96 resolveAttachmentView);
97 } else {
98 texRT = new GrVkTextureRenderTarget(gpu, desc,
99 info, imageView, msInfo,
100 colorAttachmentView,
101 resolveAttachmentView, wrapped);
102 }
103 } else {
104 if (GrVkImage::kNot_Wrapped == wrapped) {
105 texRT = new GrVkTextureRenderTarget(gpu, budgeted, desc,
106 info, imageView,
107 colorAttachmentView);
108 } else {
109 texRT = new GrVkTextureRenderTarget(gpu, desc,
110 info, imageView,
111 colorAttachmentView, wrapped);
112 }
113 }
114 return texRT;
115 }
116
117 GrVkTextureRenderTarget*
CreateNewTextureRenderTarget(GrVkGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const GrVkImage::ImageDesc & imageDesc)118 GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
119 SkBudgeted budgeted,
120 const GrSurfaceDesc& desc,
121 const GrVkImage::ImageDesc& imageDesc) {
122 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
123 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
124
125 GrVkImageInfo info;
126 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
127 return nullptr;
128 }
129
130 GrVkTextureRenderTarget* trt = Create(gpu, desc, info, budgeted, GrVkImage::kNot_Wrapped);
131 if (!trt) {
132 GrVkImage::DestroyImageInfo(gpu, &info);
133 }
134
135 return trt;
136 }
137
138 sk_sp<GrVkTextureRenderTarget>
MakeWrappedTextureRenderTarget(GrVkGpu * gpu,const GrSurfaceDesc & desc,GrWrapOwnership ownership,const GrVkImageInfo * info)139 GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu,
140 const GrSurfaceDesc& desc,
141 GrWrapOwnership ownership,
142 const GrVkImageInfo* info) {
143 SkASSERT(info);
144 // Wrapped textures require both image and allocation (because they can be mapped)
145 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory);
146 SkASSERT(kAdoptAndCache_GrWrapOwnership != ownership); // Not supported
147
148 GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
149 : GrVkImage::kAdopted_Wrapped;
150
151 return sk_sp<GrVkTextureRenderTarget>(Create(gpu, desc, *info, SkBudgeted::kNo, wrapped));
152 }
153
updateForMipmap(GrVkGpu * gpu,const GrVkImageInfo & newInfo)154 bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) {
155 VkFormat pixelFormat;
156 GrPixelConfigToVkFormat(fDesc.fConfig, &pixelFormat);
157 if (fDesc.fSampleCnt) {
158 const GrVkImageView* resolveAttachmentView =
159 GrVkImageView::Create(gpu,
160 newInfo.fImage,
161 pixelFormat,
162 GrVkImageView::kColor_Type,
163 newInfo.fLevelCount);
164 if (!resolveAttachmentView) {
165 return false;
166 }
167 fResolveAttachmentView->unref(gpu);
168 fResolveAttachmentView = resolveAttachmentView;
169 } else {
170 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu,
171 newInfo.fImage,
172 pixelFormat,
173 GrVkImageView::kColor_Type,
174 1);
175 if (!colorAttachmentView) {
176 return false;
177 }
178 fColorAttachmentView->unref(gpu);
179 fColorAttachmentView = colorAttachmentView;
180 }
181
182 this->createFramebuffer(gpu);
183 return true;
184 }
185
186