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 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
     16 
     17 GrVkTextureRenderTarget*
     18 GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
     19                                 const GrSurfaceDesc& desc,
     20                                 GrGpuResource::LifeCycle lifeCycle,
     21                                 VkFormat format,
     22                                 const GrVkImage::Resource* imageResource) {
     23 
     24     VkImage image = imageResource->fImage;
     25     // Create the texture ImageView
     26     const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
     27                                                            GrVkImageView::kColor_Type);
     28     if (!imageView) {
     29         return nullptr;
     30     }
     31 
     32     VkFormat pixelFormat;
     33     GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
     34 
     35     VkImage colorImage;
     36 
     37     // create msaa surface if necessary
     38     const GrVkImage::Resource* msaaImageResource = nullptr;
     39     const GrVkImageView* resolveAttachmentView = nullptr;
     40     if (desc.fSampleCnt) {
     41         GrVkImage::ImageDesc msImageDesc;
     42         msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
     43         msImageDesc.fFormat = pixelFormat;
     44         msImageDesc.fWidth = desc.fWidth;
     45         msImageDesc.fHeight = desc.fHeight;
     46         msImageDesc.fLevels = 1;
     47         msImageDesc.fSamples = desc.fSampleCnt;
     48         msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
     49         msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
     50         msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
     51 
     52         msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc);
     53 
     54         if (!msaaImageResource) {
     55             imageView->unref(gpu);
     56             return nullptr;
     57         }
     58 
     59         // Set color attachment image
     60         colorImage = msaaImageResource->fImage;
     61 
     62         // Create resolve attachment view if necessary.
     63         // If the format matches, this is the same as the texture imageView.
     64         if (pixelFormat == format) {
     65             resolveAttachmentView = imageView;
     66             resolveAttachmentView->ref();
     67         } else {
     68             resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
     69                                                           GrVkImageView::kColor_Type);
     70             if (!resolveAttachmentView) {
     71                 msaaImageResource->unref(gpu);
     72                 imageView->unref(gpu);
     73                 return nullptr;
     74             }
     75         }
     76     } else {
     77         // Set color attachment image
     78         colorImage = imageResource->fImage;
     79     }
     80 
     81     const GrVkImageView* colorAttachmentView;
     82     // Get color attachment view.
     83     // If the format matches and there's no multisampling,
     84     // this is the same as the texture imageView
     85     if (pixelFormat == format && !resolveAttachmentView) {
     86         colorAttachmentView = imageView;
     87         colorAttachmentView->ref();
     88     } else {
     89         colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
     90                                                     GrVkImageView::kColor_Type);
     91         if (!colorAttachmentView) {
     92             if (msaaImageResource) {
     93                 resolveAttachmentView->unref(gpu);
     94                 msaaImageResource->unref(gpu);
     95             }
     96             imageView->unref(gpu);
     97             return nullptr;
     98         }
     99     }
    100 
    101     GrVkTextureRenderTarget* texRT;
    102     if (msaaImageResource) {
    103         texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
    104                                             imageResource, imageView, msaaImageResource,
    105                                             colorAttachmentView,
    106                                             resolveAttachmentView);
    107         msaaImageResource->unref(gpu);
    108     } else {
    109         texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
    110                                             imageResource, imageView,
    111                                             colorAttachmentView);
    112     }
    113     return texRT;
    114 }
    115 
    116 GrVkTextureRenderTarget*
    117 GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
    118                                                      const GrSurfaceDesc& desc,
    119                                                      GrGpuResource::LifeCycle lifeCycle,
    120                                                      const GrVkImage::ImageDesc& imageDesc) {
    121     SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    122     SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
    123 
    124     const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(gpu, imageDesc);
    125 
    126     if (!imageRsrc) {
    127         return nullptr;
    128     }
    129 
    130     GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
    131                                                                    imageDesc.fFormat, imageRsrc);
    132     // Create() will increment the refCount of the image resource if it succeeds
    133     imageRsrc->unref(gpu);
    134 
    135     return trt;
    136 }
    137 
    138 GrVkTextureRenderTarget*
    139 GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
    140                                                           const GrSurfaceDesc& desc,
    141                                                           GrGpuResource::LifeCycle lifeCycle,
    142                                                           VkFormat format,
    143                                                           GrVkImage::Resource* imageRsrc) {
    144     SkASSERT(imageRsrc);
    145 
    146     // Note: we assume the caller will unref the imageResource
    147     // Create() will increment the refCount, and we'll unref when we're done with it
    148     return GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle, format, imageRsrc);
    149 }
    150 
    151