blob: fa9327c78844300a702a9b5ca56b0f76cf0f5df0 [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
jvanverthfd359ca2016-03-18 11:57:24 -070015#include "vk/GrVkTypes.h"
16
Greg Daniel164a9f02016-02-22 09:56:40 -050017#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
18
19GrVkTextureRenderTarget*
20GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
21 const GrSurfaceDesc& desc,
22 GrGpuResource::LifeCycle lifeCycle,
23 VkFormat format,
24 const GrVkImage::Resource* imageResource) {
25
26 VkImage image = imageResource->fImage;
27 // Create the texture ImageView
28 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
29 GrVkImageView::kColor_Type);
30 if (!imageView) {
31 return nullptr;
32 }
33
34 VkFormat pixelFormat;
35 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
36
37 VkImage colorImage;
38
39 // create msaa surface if necessary
40 const GrVkImage::Resource* msaaImageResource = nullptr;
41 const GrVkImageView* resolveAttachmentView = nullptr;
42 if (desc.fSampleCnt) {
43 GrVkImage::ImageDesc msImageDesc;
44 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
45 msImageDesc.fFormat = pixelFormat;
46 msImageDesc.fWidth = desc.fWidth;
47 msImageDesc.fHeight = desc.fHeight;
48 msImageDesc.fLevels = 1;
49 msImageDesc.fSamples = desc.fSampleCnt;
50 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
51 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
52 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
53
54 msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc);
55
56 if (!msaaImageResource) {
57 imageView->unref(gpu);
58 return nullptr;
59 }
60
61 // Set color attachment image
62 colorImage = msaaImageResource->fImage;
63
64 // Create resolve attachment view if necessary.
65 // If the format matches, this is the same as the texture imageView.
66 if (pixelFormat == format) {
67 resolveAttachmentView = imageView;
68 resolveAttachmentView->ref();
69 } else {
70 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
71 GrVkImageView::kColor_Type);
72 if (!resolveAttachmentView) {
73 msaaImageResource->unref(gpu);
74 imageView->unref(gpu);
75 return nullptr;
76 }
77 }
78 } else {
79 // Set color attachment image
80 colorImage = imageResource->fImage;
81 }
82
83 const GrVkImageView* colorAttachmentView;
84 // Get color attachment view.
85 // If the format matches and there's no multisampling,
86 // this is the same as the texture imageView
87 if (pixelFormat == format && !resolveAttachmentView) {
88 colorAttachmentView = imageView;
89 colorAttachmentView->ref();
90 } else {
91 colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
92 GrVkImageView::kColor_Type);
93 if (!colorAttachmentView) {
94 if (msaaImageResource) {
95 resolveAttachmentView->unref(gpu);
96 msaaImageResource->unref(gpu);
97 }
98 imageView->unref(gpu);
99 return nullptr;
100 }
101 }
102
103 GrVkTextureRenderTarget* texRT;
104 if (msaaImageResource) {
105 texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
106 imageResource, imageView, msaaImageResource,
107 colorAttachmentView,
108 resolveAttachmentView);
109 msaaImageResource->unref(gpu);
110 } else {
111 texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
112 imageResource, imageView,
113 colorAttachmentView);
114 }
115 return texRT;
116}
117
118GrVkTextureRenderTarget*
119GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
120 const GrSurfaceDesc& desc,
121 GrGpuResource::LifeCycle lifeCycle,
122 const GrVkImage::ImageDesc& imageDesc) {
123 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
124 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
125
126 const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(gpu, imageDesc);
127
128 if (!imageRsrc) {
129 return nullptr;
130 }
131
132 GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
133 imageDesc.fFormat, imageRsrc);
134 // Create() will increment the refCount of the image resource if it succeeds
135 imageRsrc->unref(gpu);
136
137 return trt;
138}
139
140GrVkTextureRenderTarget*
141GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
142 const GrSurfaceDesc& desc,
143 GrGpuResource::LifeCycle lifeCycle,
144 VkFormat format,
jvanverthfd359ca2016-03-18 11:57:24 -0700145 const GrVkTextureInfo* info) {
146 SkASSERT(info);
147 // Wrapped textures require both image and allocation (because they can be mapped)
148 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500149
jvanverthfd359ca2016-03-18 11:57:24 -0700150 GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
151 ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
152
153 const GrVkImage::Resource* imageResource = new GrVkImage::Resource(info->fImage,
154 info->fAlloc,
155 flags);
156 if (!imageResource) {
157 return nullptr;
158 }
159
160 GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
161 format, imageResource);
162 if (trt) {
163 trt->fCurrentLayout = info->fImageLayout;
164 }
165 // Create() will increment the refCount of the image resource if it succeeds
166 imageResource->unref(gpu);
167
168 return trt;
169
Greg Daniel164a9f02016-02-22 09:56:40 -0500170}
171