Home | History | Annotate | Download | only in vk
      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