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 "GrVkGpu.h"
      9 #include "GrVkImage.h"
     10 #include "GrVkMemory.h"
     11 #include "GrVkUtil.h"
     12 
     13 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
     14 
     15 void GrVkImage::setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout,
     16                                VkAccessFlags srcAccessMask,
     17                                VkAccessFlags dstAccessMask,
     18                                VkPipelineStageFlags srcStageMask,
     19                                VkPipelineStageFlags dstStageMask,
     20                                bool byRegion) {
     21     SkASSERT(VK_IMAGE_LAYOUT_GENERAL != newLayout || VK_IMAGE_LAYOUT_PREINITIALIZED != newLayout);
     22     // Is this reasonable? Could someone want to keep the same layout but use the masks to force
     23     // a barrier on certain things?
     24     if (newLayout == fCurrentLayout) {
     25         return;
     26     }
     27 
     28     VkImageMemoryBarrier imageMemoryBarrier = {
     29         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
     30         NULL,                                     // pNext
     31         srcAccessMask,                            // outputMask
     32         dstAccessMask,                            // inputMask
     33         fCurrentLayout,                           // oldLayout
     34         newLayout,                                // newLayout
     35         VK_QUEUE_FAMILY_IGNORED,                  // srcQueueFamilyIndex
     36         VK_QUEUE_FAMILY_IGNORED,                  // dstQueueFamilyIndex
     37         fResource->fImage,                        // image
     38         { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
     39     };
     40 
     41     // TODO: restrict to area of image we're interested in
     42     gpu->addImageMemoryBarrier(srcStageMask, dstStageMask, byRegion, &imageMemoryBarrier);
     43 
     44     fCurrentLayout = newLayout;
     45 }
     46 
     47 const GrVkImage::Resource* GrVkImage::CreateResource(const GrVkGpu* gpu,
     48                                                      const ImageDesc& imageDesc) {
     49     VkImage image = 0;
     50     VkDeviceMemory alloc;
     51 
     52     VkResult err;
     53 
     54     VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageDesc.fImageTiling)
     55         ? VK_IMAGE_LAYOUT_PREINITIALIZED
     56         : VK_IMAGE_LAYOUT_UNDEFINED;
     57 
     58     // Create Image
     59     VkSampleCountFlagBits vkSamples;
     60     if (!GrSampleCountToVkSampleCount(imageDesc.fSamples, &vkSamples)) {
     61         return nullptr;
     62     }
     63     const VkImageCreateInfo imageCreateInfo = {
     64         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,         // sType
     65         NULL,                                        // pNext
     66         0,                                           // VkImageCreateFlags
     67         imageDesc.fImageType,                        // VkImageType
     68         imageDesc.fFormat,                           // VkFormat
     69         { imageDesc.fWidth, imageDesc.fHeight, 1 },  // VkExtent3D
     70         imageDesc.fLevels,                           // mipLevels
     71         1,                                           // arrayLayers
     72         vkSamples,                                   // samples
     73         imageDesc.fImageTiling,                      // VkImageTiling
     74         imageDesc.fUsageFlags,                       // VkImageUsageFlags
     75         VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode
     76         0,                                           // queueFamilyCount
     77         0,                                           // pQueueFamilyIndices
     78         initialLayout                                // initialLayout
     79     };
     80 
     81     err = VK_CALL(gpu, CreateImage(gpu->device(), &imageCreateInfo, nullptr, &image));
     82     SkASSERT(!err);
     83 
     84     if (!GrVkMemory::AllocAndBindImageMemory(gpu, image, imageDesc.fMemProps, &alloc)) {
     85         VK_CALL(gpu, DestroyImage(gpu->device(), image, nullptr));
     86         return nullptr;
     87     }
     88 
     89     GrVkImage::Resource::Flags flags =
     90         (VK_IMAGE_TILING_LINEAR == imageDesc.fImageTiling) ? Resource::kLinearTiling_Flag
     91                                                            : Resource::kNo_Flags;
     92 
     93     return (new GrVkImage::Resource(image, alloc, flags));
     94 }
     95 
     96 GrVkImage::~GrVkImage() {
     97     // should have been released or abandoned first
     98     SkASSERT(!fResource);
     99 }
    100 
    101 void GrVkImage::releaseImage(const GrVkGpu* gpu) {
    102     if (fResource) {
    103         fResource->unref(gpu);
    104         fResource = nullptr;
    105     }
    106 }
    107 
    108 void GrVkImage::abandonImage() {
    109     if (fResource) {
    110         fResource->unrefAndAbandon();
    111         fResource = nullptr;
    112     }
    113 }
    114 
    115 void GrVkImage::Resource::freeGPUData(const GrVkGpu* gpu) const {
    116     VK_CALL(gpu, DestroyImage(gpu->device(), fImage, nullptr));
    117     VK_CALL(gpu, FreeMemory(gpu->device(), fAlloc, nullptr));
    118 }