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