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 "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::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*
    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>
    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 
    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