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