blob: 8dcc3684747ef35151fab6bc88f973c47661f9ca [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 "GrVkTexture.h"
9#include "GrVkGpu.h"
10#include "GrVkImageView.h"
11#include "GrVkUtil.h"
12
jvanverthfd359ca2016-03-18 11:57:24 -070013#include "vk/GrVkTypes.h"
14
Greg Daniel164a9f02016-02-22 09:56:40 -050015#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
16
17// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
18GrVkTexture::GrVkTexture(GrVkGpu* gpu,
19 const GrSurfaceDesc& desc,
20 GrGpuResource::LifeCycle lifeCycle,
21 const GrVkImage::Resource* imageResource,
22 const GrVkImageView* view)
23 : GrSurface(gpu, lifeCycle, desc)
24 , GrVkImage(imageResource)
cdalton9c3f1432016-03-11 10:07:37 -080025 , INHERITED(gpu, lifeCycle, desc, kSampler2D_GrSLType,
26 false) // false because we don't upload MIP data in Vk yet
Greg Daniel164a9f02016-02-22 09:56:40 -050027 , fTextureView(view) {
28 this->registerWithCache();
29}
30
31// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
32GrVkTexture::GrVkTexture(GrVkGpu* gpu,
33 const GrSurfaceDesc& desc,
34 GrGpuResource::LifeCycle lifeCycle,
35 const GrVkImage::Resource* imageResource,
36 const GrVkImageView* view,
37 Derived)
38 : GrSurface(gpu, lifeCycle, desc)
39 , GrVkImage(imageResource)
cdalton9c3f1432016-03-11 10:07:37 -080040 , INHERITED(gpu, lifeCycle, desc, kSampler2D_GrSLType,
41 false) // false because we don't upload MIP data in Vk yet
Greg Daniel164a9f02016-02-22 09:56:40 -050042 , fTextureView(view) {}
43
44
45GrVkTexture* GrVkTexture::Create(GrVkGpu* gpu,
46 const GrSurfaceDesc& desc,
47 GrGpuResource::LifeCycle lifeCycle,
48 VkFormat format,
49 const GrVkImage::Resource* imageResource) {
50 VkImage image = imageResource->fImage;
51 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
52 GrVkImageView::kColor_Type);
53 if (!imageView) {
54 return nullptr;
55 }
56
57 return new GrVkTexture(gpu, desc, lifeCycle, imageResource, imageView);
58}
59
60GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc,
61 GrGpuResource::LifeCycle lifeCycle,
62 const GrVkImage::ImageDesc& imageDesc) {
63 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
64
65 const GrVkImage::Resource* imageResource = GrVkImage::CreateResource(gpu, imageDesc);
66 if (!imageResource) {
67 return nullptr;
68 }
69
70 GrVkTexture* texture = Create(gpu, desc, lifeCycle, imageDesc.fFormat, imageResource);
71 // Create() will increment the refCount of the image resource if it succeeds
72 imageResource->unref(gpu);
73
74 return texture;
75}
76
77GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc,
78 GrGpuResource::LifeCycle lifeCycle,
halcanary9d524f22016-03-29 09:03:52 -070079 VkFormat format,
jvanverthfd359ca2016-03-18 11:57:24 -070080 const GrVkTextureInfo* info) {
81 SkASSERT(info);
82 // Wrapped textures require both image and allocation (because they can be mapped)
83 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
Greg Daniel164a9f02016-02-22 09:56:40 -050084
jvanverthfd359ca2016-03-18 11:57:24 -070085 GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
86 ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
87
jvanverthfe170d22016-03-22 13:15:44 -070088 const GrVkImage::Resource* imageResource;
89 if (kBorrowed_LifeCycle == lifeCycle) {
egdaniel58a8d922016-04-21 08:03:10 -070090 imageResource = new GrVkImage::BorrowedResource(info->fImage,
91 info->fAlloc,
92 flags,
93 info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -070094 } else {
egdaniel58a8d922016-04-21 08:03:10 -070095 imageResource = new GrVkImage::Resource(info->fImage, info->fAlloc, flags, info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -070096 }
jvanverthfd359ca2016-03-18 11:57:24 -070097 if (!imageResource) {
98 return nullptr;
99 }
100
101 GrVkTexture* texture = Create(gpu, desc, lifeCycle, format, imageResource);
102 if (texture) {
103 texture->fCurrentLayout = info->fImageLayout;
104 }
105 // Create() will increment the refCount of the image resource if it succeeds
106 imageResource->unref(gpu);
107
108 return texture;
Greg Daniel164a9f02016-02-22 09:56:40 -0500109}
110
111GrVkTexture::~GrVkTexture() {
112 // either release or abandon should have been called by the owner of this object.
113 SkASSERT(!fTextureView);
114}
115
116void GrVkTexture::onRelease() {
117 // we create this and don't hand it off, so we should always destroy it
118 if (fTextureView) {
119 fTextureView->unref(this->getVkGpu());
120 fTextureView = nullptr;
121 }
122
123 if (this->shouldFreeResources()) {
124 this->releaseImage(this->getVkGpu());
125 } else {
126 this->abandonImage();
127 }
128
129 INHERITED::onRelease();
130}
131
132void GrVkTexture::onAbandon() {
133 if (fTextureView) {
134 fTextureView->unrefAndAbandon();
135 fTextureView = nullptr;
136 }
137
138 this->abandonImage();
139 INHERITED::onAbandon();
140}
141
142GrBackendObject GrVkTexture::getTextureHandle() const {
143 // Currently just passing back the pointer to the Resource as the handle
144 return (GrBackendObject)&fResource;
145}
146
147GrVkGpu* GrVkTexture::getVkGpu() const {
148 SkASSERT(!this->wasDestroyed());
149 return static_cast<GrVkGpu*>(this->getGpu());
150}