blob: e44e85a647af480c58e89dfbb1cee7ef2acc4063 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
egdanieldd97b852016-04-28 09:30:39 -070015#include "SkMipMap.h"
jvanverth62340062016-04-26 08:01:44 -070016
jvanverthfd359ca2016-03-18 11:57:24 -070017#include "vk/GrVkTypes.h"
18
Greg Daniel164a9f02016-02-22 09:56:40 -050019#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
20
kkinnunen2e6055b2016-04-22 01:48:29 -070021template<typename ResourceType>
22GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
23 ResourceType resourceType,
24 const GrSurfaceDesc& desc,
25 VkFormat format,
26 const GrVkImage::Resource* imageResource) {
Greg Daniel164a9f02016-02-22 09:56:40 -050027 VkImage image = imageResource->fImage;
28 // Create the texture ImageView
jvanverth62340062016-04-26 08:01:44 -070029 uint32_t mipLevels = 1;
30 //TODO: does a mipmapped textureRenderTarget make sense?
31 //if (desc.fIsMipMapped) {
32 // mipLevels = SkMipMap::ComputeLevelCount(this->width(), this->height());
33 //}
Greg Daniel164a9f02016-02-22 09:56:40 -050034 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
jvanverth62340062016-04-26 08:01:44 -070035 GrVkImageView::kColor_Type, mipLevels);
Greg Daniel164a9f02016-02-22 09:56:40 -050036 if (!imageView) {
37 return nullptr;
38 }
39
40 VkFormat pixelFormat;
41 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
42
43 VkImage colorImage;
44
45 // create msaa surface if necessary
46 const GrVkImage::Resource* msaaImageResource = nullptr;
47 const GrVkImageView* resolveAttachmentView = nullptr;
48 if (desc.fSampleCnt) {
49 GrVkImage::ImageDesc msImageDesc;
50 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
51 msImageDesc.fFormat = pixelFormat;
52 msImageDesc.fWidth = desc.fWidth;
53 msImageDesc.fHeight = desc.fHeight;
54 msImageDesc.fLevels = 1;
55 msImageDesc.fSamples = desc.fSampleCnt;
56 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
57 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
58 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
59
60 msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc);
61
62 if (!msaaImageResource) {
63 imageView->unref(gpu);
64 return nullptr;
65 }
66
67 // Set color attachment image
68 colorImage = msaaImageResource->fImage;
69
70 // Create resolve attachment view if necessary.
71 // If the format matches, this is the same as the texture imageView.
72 if (pixelFormat == format) {
73 resolveAttachmentView = imageView;
74 resolveAttachmentView->ref();
75 } else {
76 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -070077 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -050078 if (!resolveAttachmentView) {
79 msaaImageResource->unref(gpu);
80 imageView->unref(gpu);
81 return nullptr;
82 }
83 }
84 } else {
85 // Set color attachment image
86 colorImage = imageResource->fImage;
87 }
88
89 const GrVkImageView* colorAttachmentView;
90 // Get color attachment view.
91 // If the format matches and there's no multisampling,
92 // this is the same as the texture imageView
93 if (pixelFormat == format && !resolveAttachmentView) {
94 colorAttachmentView = imageView;
95 colorAttachmentView->ref();
96 } else {
97 colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -070098 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -050099 if (!colorAttachmentView) {
100 if (msaaImageResource) {
101 resolveAttachmentView->unref(gpu);
102 msaaImageResource->unref(gpu);
103 }
104 imageView->unref(gpu);
105 return nullptr;
106 }
107 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500108 GrVkTextureRenderTarget* texRT;
109 if (msaaImageResource) {
kkinnunen2e6055b2016-04-22 01:48:29 -0700110 texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500111 imageResource, imageView, msaaImageResource,
112 colorAttachmentView,
113 resolveAttachmentView);
114 msaaImageResource->unref(gpu);
115 } else {
kkinnunen2e6055b2016-04-22 01:48:29 -0700116 texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500117 imageResource, imageView,
118 colorAttachmentView);
119 }
120 return texRT;
121}
122
123GrVkTextureRenderTarget*
124GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700125 SkBudgeted budgeted,
126 const GrSurfaceDesc& desc,
127 const GrVkImage::ImageDesc& imageDesc) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500128 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
129 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
130
131 const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(gpu, imageDesc);
132
133 if (!imageRsrc) {
134 return nullptr;
135 }
136
kkinnunen2e6055b2016-04-22 01:48:29 -0700137 GrVkTextureRenderTarget* trt = Create(gpu, budgeted, desc, imageDesc.fFormat,
138 imageRsrc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500139 // Create() will increment the refCount of the image resource if it succeeds
140 imageRsrc->unref(gpu);
141
142 return trt;
143}
144
145GrVkTextureRenderTarget*
146GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
147 const GrSurfaceDesc& desc,
kkinnunen2e6055b2016-04-22 01:48:29 -0700148 GrWrapOwnership ownership,
halcanary9d524f22016-03-29 09:03:52 -0700149 VkFormat format,
jvanverthfd359ca2016-03-18 11:57:24 -0700150 const GrVkTextureInfo* info) {
151 SkASSERT(info);
152 // Wrapped textures require both image and allocation (because they can be mapped)
153 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500154
jvanverthfd359ca2016-03-18 11:57:24 -0700155 GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
156 ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
157
jvanverthfe170d22016-03-22 13:15:44 -0700158 const GrVkImage::Resource* imageResource;
kkinnunen2e6055b2016-04-22 01:48:29 -0700159 if (kBorrow_GrWrapOwnership == ownership) {
egdaniel58a8d922016-04-21 08:03:10 -0700160 imageResource = new GrVkImage::BorrowedResource(info->fImage,
161 info->fAlloc,
162 flags,
163 info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -0700164 } else {
egdaniel58a8d922016-04-21 08:03:10 -0700165 imageResource = new GrVkImage::Resource(info->fImage, info->fAlloc, flags, info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -0700166 }
jvanverthfd359ca2016-03-18 11:57:24 -0700167 if (!imageResource) {
168 return nullptr;
169 }
kkinnunen2e6055b2016-04-22 01:48:29 -0700170 GrVkTextureRenderTarget* trt = Create(gpu, kWrapped, desc, format, imageResource);
jvanverthfd359ca2016-03-18 11:57:24 -0700171 if (trt) {
172 trt->fCurrentLayout = info->fImageLayout;
173 }
174 // Create() will increment the refCount of the image resource if it succeeds
175 imageResource->unref(gpu);
176
177 return trt;
Greg Daniel164a9f02016-02-22 09:56:40 -0500178}