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
17GrVkTextureRenderTarget*
18GrVkTextureRenderTarget::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
116GrVkTextureRenderTarget*
117GrVkTextureRenderTarget::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
138GrVkTextureRenderTarget*
139GrVkTextureRenderTarget::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