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