1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h"
9cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImageView.h"
10cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkSamplerYcbcrConversion.h"
11cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h"
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_cisk_sp<const GrVkImageView> GrVkImageView::Make(GrVkGpu* gpu,
14cb93a386Sopenharmony_ci                                               VkImage image,
15cb93a386Sopenharmony_ci                                               VkFormat format,
16cb93a386Sopenharmony_ci                                               Type viewType, uint32_t miplevels,
17cb93a386Sopenharmony_ci                                               const GrVkYcbcrConversionInfo& ycbcrInfo) {
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci    void* pNext = nullptr;
20cb93a386Sopenharmony_ci    VkSamplerYcbcrConversionInfo conversionInfo;
21cb93a386Sopenharmony_ci    GrVkSamplerYcbcrConversion* ycbcrConversion = nullptr;
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci    if (ycbcrInfo.isValid()) {
24cb93a386Sopenharmony_ci        SkASSERT(gpu->vkCaps().supportsYcbcrConversion() && format == ycbcrInfo.fFormat);
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci        ycbcrConversion =
27cb93a386Sopenharmony_ci                gpu->resourceProvider().findOrCreateCompatibleSamplerYcbcrConversion(ycbcrInfo);
28cb93a386Sopenharmony_ci        if (!ycbcrConversion) {
29cb93a386Sopenharmony_ci            return nullptr;
30cb93a386Sopenharmony_ci        }
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci        conversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
33cb93a386Sopenharmony_ci        conversionInfo.pNext = nullptr;
34cb93a386Sopenharmony_ci        conversionInfo.conversion = ycbcrConversion->ycbcrConversion();
35cb93a386Sopenharmony_ci        pNext = &conversionInfo;
36cb93a386Sopenharmony_ci    }
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci    VkImageViewASTCDecodeModeEXT astcDecodeMode;
39cb93a386Sopenharmony_ci    if (format == VK_FORMAT_ASTC_4x4_UNORM_BLOCK || format == VK_FORMAT_ASTC_6x6_UNORM_BLOCK ||
40cb93a386Sopenharmony_ci        format == VK_FORMAT_ASTC_8x8_UNORM_BLOCK) {
41cb93a386Sopenharmony_ci        astcDecodeMode.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT;
42cb93a386Sopenharmony_ci        astcDecodeMode.pNext = nullptr;
43cb93a386Sopenharmony_ci        astcDecodeMode.decodeMode = VK_FORMAT_R8G8B8A8_UNORM;
44cb93a386Sopenharmony_ci        pNext = &astcDecodeMode;
45cb93a386Sopenharmony_ci    }
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci    VkImageView imageView;
48cb93a386Sopenharmony_ci    // Create the VkImageView
49cb93a386Sopenharmony_ci    VkImageViewCreateInfo viewInfo = {
50cb93a386Sopenharmony_ci        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // sType
51cb93a386Sopenharmony_ci        pNext,                                                  // pNext
52cb93a386Sopenharmony_ci        0,                                                      // flags
53cb93a386Sopenharmony_ci        image,                                                  // image
54cb93a386Sopenharmony_ci        VK_IMAGE_VIEW_TYPE_2D,                                  // viewType
55cb93a386Sopenharmony_ci        format,                                                 // format
56cb93a386Sopenharmony_ci        { VK_COMPONENT_SWIZZLE_IDENTITY,
57cb93a386Sopenharmony_ci          VK_COMPONENT_SWIZZLE_IDENTITY,
58cb93a386Sopenharmony_ci          VK_COMPONENT_SWIZZLE_IDENTITY,
59cb93a386Sopenharmony_ci          VK_COMPONENT_SWIZZLE_IDENTITY },                      // components
60cb93a386Sopenharmony_ci        { VK_IMAGE_ASPECT_COLOR_BIT, 0, miplevels, 0, 1 },      // subresourceRange
61cb93a386Sopenharmony_ci    };
62cb93a386Sopenharmony_ci    if (kStencil_Type == viewType) {
63cb93a386Sopenharmony_ci        viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
64cb93a386Sopenharmony_ci    }
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    VkResult err;
67cb93a386Sopenharmony_ci    GR_VK_CALL_RESULT(gpu, err, CreateImageView(gpu->device(), &viewInfo, nullptr, &imageView));
68cb93a386Sopenharmony_ci    if (err) {
69cb93a386Sopenharmony_ci        return nullptr;
70cb93a386Sopenharmony_ci    }
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    return sk_sp<const GrVkImageView>(new GrVkImageView(gpu, imageView, ycbcrConversion));
73cb93a386Sopenharmony_ci}
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_civoid GrVkImageView::freeGPUData() const {
76cb93a386Sopenharmony_ci    GR_VK_CALL(fGpu->vkInterface(), DestroyImageView(fGpu->device(), fImageView, nullptr));
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ci    if (fYcbcrConversion) {
79cb93a386Sopenharmony_ci        fYcbcrConversion->unref();
80cb93a386Sopenharmony_ci    }
81cb93a386Sopenharmony_ci}
82cb93a386Sopenharmony_ci
83