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 "GrTexturePriv.h" 12 #include "GrVkGpu.h" 13 #include "GrVkImageView.h" 14 #include "GrVkUtil.h" 15 16 #include "SkMipMap.h" 17 18 #include "vk/GrVkTypes.h" 19 20 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) 21 22 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, 23 SkBudgeted budgeted, 24 const GrSurfaceDesc& desc, 25 const GrVkImageInfo& info, 26 const GrVkImageView* texView, 27 const GrVkImageInfo& msaaInfo, 28 const GrVkImageView* colorAttachmentView, 29 const GrVkImageView* resolveAttachmentView) 30 : GrSurface(gpu, desc) 31 , GrVkImage(info, GrVkImage::kNot_Wrapped) 32 , GrVkTexture(gpu, desc, info, texView, GrVkImage::kNot_Wrapped) 33 , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView, 34 resolveAttachmentView, GrVkImage::kNot_Wrapped) { 35 this->registerWithCache(budgeted); 36 } 37 38 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, 39 SkBudgeted budgeted, 40 const GrSurfaceDesc& desc, 41 const GrVkImageInfo& info, 42 const GrVkImageView* texView, 43 const GrVkImageView* colorAttachmentView) 44 : GrSurface(gpu, desc) 45 , GrVkImage(info, GrVkImage::kNot_Wrapped) 46 , GrVkTexture(gpu, desc, info, texView, GrVkImage::kNot_Wrapped) 47 , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, GrVkImage::kNot_Wrapped) { 48 this->registerWithCache(budgeted); 49 } 50 51 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, 52 const GrSurfaceDesc& desc, 53 const GrVkImageInfo& info, 54 const GrVkImageView* texView, 55 const GrVkImageInfo& msaaInfo, 56 const GrVkImageView* colorAttachmentView, 57 const GrVkImageView* resolveAttachmentView, 58 GrVkImage::Wrapped wrapped) 59 : GrSurface(gpu, desc) 60 , GrVkImage(info, wrapped) 61 , GrVkTexture(gpu, desc, info, texView, wrapped) 62 , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView, 63 resolveAttachmentView, wrapped) { 64 this->registerWithCacheWrapped(); 65 } 66 67 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, 68 const GrSurfaceDesc& desc, 69 const GrVkImageInfo& info, 70 const GrVkImageView* texView, 71 const GrVkImageView* colorAttachmentView, 72 GrVkImage::Wrapped wrapped) 73 : GrSurface(gpu, desc) 74 , GrVkImage(info, wrapped) 75 , GrVkTexture(gpu, desc, info, texView, wrapped) 76 , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, wrapped) { 77 this->registerWithCacheWrapped(); 78 } 79 80 81 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu, 82 const GrSurfaceDesc& desc, 83 const GrVkImageInfo& info, 84 SkBudgeted budgeted, 85 GrVkImage::Wrapped wrapped) { 86 VkImage image = info.fImage; 87 // Create the texture ImageView 88 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat, 89 GrVkImageView::kColor_Type, 90 info.fLevelCount); 91 if (!imageView) { 92 return nullptr; 93 } 94 95 VkFormat pixelFormat; 96 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat); 97 98 VkImage colorImage; 99 100 // create msaa surface if necessary 101 GrVkImageInfo msInfo; 102 const GrVkImageView* resolveAttachmentView = nullptr; 103 if (desc.fSampleCnt) { 104 GrVkImage::ImageDesc msImageDesc; 105 msImageDesc.fImageType = VK_IMAGE_TYPE_2D; 106 msImageDesc.fFormat = pixelFormat; 107 msImageDesc.fWidth = desc.fWidth; 108 msImageDesc.fHeight = desc.fHeight; 109 msImageDesc.fLevels = 1; 110 msImageDesc.fSamples = desc.fSampleCnt; 111 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; 112 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 113 VK_IMAGE_USAGE_TRANSFER_DST_BIT | 114 VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 115 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 116 117 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) { 118 imageView->unref(gpu); 119 return nullptr; 120 } 121 122 // Set color attachment image 123 colorImage = msInfo.fImage; 124 125 // Create resolve attachment view. 126 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat, 127 GrVkImageView::kColor_Type, 128 info.fLevelCount); 129 if (!resolveAttachmentView) { 130 GrVkImage::DestroyImageInfo(gpu, &msInfo); 131 imageView->unref(gpu); 132 return nullptr; 133 } 134 } else { 135 // Set color attachment image 136 colorImage = info.fImage; 137 } 138 139 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat, 140 GrVkImageView::kColor_Type, 1); 141 if (!colorAttachmentView) { 142 if (desc.fSampleCnt) { 143 resolveAttachmentView->unref(gpu); 144 GrVkImage::DestroyImageInfo(gpu, &msInfo); 145 } 146 imageView->unref(gpu); 147 return nullptr; 148 } 149 150 sk_sp<GrVkTextureRenderTarget> texRT; 151 if (desc.fSampleCnt) { 152 if (GrVkImage::kNot_Wrapped == wrapped) { 153 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 154 gpu, budgeted, desc, 155 info, imageView, msInfo, 156 colorAttachmentView, 157 resolveAttachmentView)); 158 } else { 159 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 160 gpu, desc, 161 info, imageView, msInfo, 162 colorAttachmentView, 163 resolveAttachmentView, wrapped)); 164 } 165 } else { 166 if (GrVkImage::kNot_Wrapped == wrapped) { 167 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 168 gpu, budgeted, desc, 169 info, imageView, 170 colorAttachmentView)); 171 } else { 172 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 173 gpu, desc, 174 info, imageView, 175 colorAttachmentView, wrapped)); 176 } 177 } 178 return texRT; 179 } 180 181 sk_sp<GrVkTextureRenderTarget> 182 GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu, 183 SkBudgeted budgeted, 184 const GrSurfaceDesc& desc, 185 const GrVkImage::ImageDesc& imageDesc) { 186 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); 187 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT); 188 189 GrVkImageInfo info; 190 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) { 191 return nullptr; 192 } 193 194 sk_sp<GrVkTextureRenderTarget> trt = Make(gpu, desc, info, budgeted, GrVkImage::kNot_Wrapped); 195 if (!trt) { 196 GrVkImage::DestroyImageInfo(gpu, &info); 197 } 198 199 return trt; 200 } 201 202 sk_sp<GrVkTextureRenderTarget> 203 GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu, 204 const GrSurfaceDesc& desc, 205 GrWrapOwnership ownership, 206 const GrVkImageInfo* info) { 207 SkASSERT(info); 208 // Wrapped textures require both image and allocation (because they can be mapped) 209 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory); 210 211 GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped 212 : GrVkImage::kAdopted_Wrapped; 213 214 return Make(gpu, desc, *info, SkBudgeted::kNo, wrapped); 215 } 216 217 bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) { 218 VkFormat pixelFormat; 219 GrPixelConfigToVkFormat(this->config(), &pixelFormat); 220 if (this->numStencilSamples()) { 221 const GrVkImageView* resolveAttachmentView = 222 GrVkImageView::Create(gpu, 223 newInfo.fImage, 224 pixelFormat, 225 GrVkImageView::kColor_Type, 226 newInfo.fLevelCount); 227 if (!resolveAttachmentView) { 228 return false; 229 } 230 fResolveAttachmentView->unref(gpu); 231 fResolveAttachmentView = resolveAttachmentView; 232 } else { 233 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, 234 newInfo.fImage, 235 pixelFormat, 236 GrVkImageView::kColor_Type, 237 1); 238 if (!colorAttachmentView) { 239 return false; 240 } 241 fColorAttachmentView->unref(gpu); 242 fColorAttachmentView = colorAttachmentView; 243 } 244 245 this->createFramebuffer(gpu); 246 return true; 247 } 248 249 size_t GrVkTextureRenderTarget::onGpuMemorySize() const { 250 // The plus 1 is to account for the resolve texture. 251 int numColorSamples = this->numColorSamples() + 1; 252 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 253 numColorSamples, // TODO: this still correct? 254 this->texturePriv().hasMipMaps()); 255 } 256