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