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