blob: 4ae2ebe86194467db59a01905d10b20a7566ef02 [file] [log] [blame]
Greg Daniel6c6caf42020-05-29 12:11:05 -04001/*
2 * Copyright 2020 Google LLC
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 "include/core/SkImage.h"
9#include "include/gpu/GrBackendSurface.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040010#include "include/gpu/GrDirectContext.h"
Greg Daniel6c6caf42020-05-29 12:11:05 -040011#include "include/gpu/vk/GrVkTypes.h"
Greg Daniel1db8e792020-06-09 17:29:32 -040012#include "src/gpu/GrContextPriv.h"
Greg Daniel6c6caf42020-05-29 12:11:05 -040013#include "src/gpu/GrTexture.h"
14#include "src/gpu/GrTextureProxy.h"
15#include "src/image/SkImage_Base.h"
16#include "tests/Test.h"
17
18#ifdef SK_VULKAN
Greg Daniel1db8e792020-06-09 17:29:32 -040019#include "src/gpu/vk/GrVkGpu.h"
Greg Daniel6c6caf42020-05-29 12:11:05 -040020#include "src/gpu/vk/GrVkTexture.h"
21
22DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendSurfaceMutableStateTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -040023 auto context = ctxInfo.directContext();
Greg Daniel6c6caf42020-05-29 12:11:05 -040024
25 GrBackendFormat format = GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
26 GrBackendTexture backendTex = context->createBackendTexture(
27 32, 32, format, GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
28
29 REPORTER_ASSERT(reporter, backendTex.isValid());
30
31 GrVkImageInfo info;
32 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
33 VkImageLayout initLayout = info.fImageLayout;
34 uint32_t initQueue = info.fCurrentQueueFamily;
35 GrBackendSurfaceMutableState initState(initLayout, initQueue);
36
37 // Verify that setting that state via a copy of a backendTexture is reflected in all the
38 // backendTextures.
39 GrBackendTexture backendTexCopy = backendTex;
40 REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info));
41 REPORTER_ASSERT(reporter, initLayout == info.fImageLayout);
42 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
43
44 GrBackendSurfaceMutableState newState(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
45 VK_QUEUE_FAMILY_IGNORED);
46 backendTexCopy.setMutableState(newState);
47
48 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
49 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout);
50 REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily);
51
52 REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info));
53 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout);
54 REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily);
55
56 // Setting back to the init state since we didn't actually change it
57 backendTex.setMutableState(initState);
58
59 sk_sp<SkImage> wrappedImage = SkImage::MakeFromTexture(context, backendTex,
60 kTopLeft_GrSurfaceOrigin,
61 kRGBA_8888_SkColorType,
62 kPremul_SkAlphaType, nullptr);
63
64 const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(context);
65 REPORTER_ASSERT(reporter, view);
66 REPORTER_ASSERT(reporter, view->proxy()->isInstantiated());
67 GrTexture* texture = view->proxy()->peekTexture();
68 REPORTER_ASSERT(reporter, texture);
69
70 // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture
71 GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
72 REPORTER_ASSERT(reporter, initLayout == vkTexture->currentLayout());
73 REPORTER_ASSERT(reporter, initQueue == vkTexture->currentQueueFamilyIndex());
74 vkTexture->updateImageLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
75
76 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
77 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout);
78 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
79
80 GrBackendTexture backendTexImage = wrappedImage->getBackendTexture(false);
81 REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info));
82 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout);
83 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
84
85 // Verify that modifying the layout via the GrBackendTexutre is reflected in the GrVkTexture
86 backendTexImage.setMutableState(newState);
87 REPORTER_ASSERT(reporter,
88 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == vkTexture->currentLayout());
89 REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily);
90
91 vkTexture->setQueueFamilyIndex(initQueue);
92 vkTexture->updateImageLayout(initLayout);
93
94 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
95 REPORTER_ASSERT(reporter, initLayout == info.fImageLayout);
96 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
97
98 REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info));
99 REPORTER_ASSERT(reporter, initLayout == info.fImageLayout);
100 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
101
102 REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info));
103 REPORTER_ASSERT(reporter, initLayout == info.fImageLayout);
104 REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily);
105
Greg Daniel1db8e792020-06-09 17:29:32 -0400106 // Test using the setBackendTextureStateAPI. Unlike the previous test this will actually add
107 // real transitions to the image so we need to be careful about doing actual valid transitions.
108 GrVkGpu* gpu = static_cast<GrVkGpu*>(context->priv().getGpu());
109
110 context->setBackendTextureState(backendTex, newState);
111
112 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
113 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout);
114 REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily);
115
116 // To test queue transitions, we don't have any other valid queue available so instead we try
117 // to transition to external queue.
118 if (gpu->vkCaps().supportsExternalMemory()) {
119 GrBackendSurfaceMutableState externalState(VK_IMAGE_LAYOUT_GENERAL,
120 VK_QUEUE_FAMILY_EXTERNAL);
121
122 context->setBackendTextureState(backendTex, externalState);
123
124 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
125 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout);
126 REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_EXTERNAL == info.fCurrentQueueFamily);
127
128 context->submit();
129
130 GrBackendSurfaceMutableState externalState2(VK_IMAGE_LAYOUT_GENERAL, initQueue);
131 context->setBackendTextureState(backendTex, externalState2);
132
133 REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
134 REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout);
135 REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily);
136 }
137
138 // We must submit this work before we try to delete the backend texture.
139 context->submit(true);
140
Greg Daniel6c6caf42020-05-29 12:11:05 -0400141 context->deleteBackendTexture(backendTex);
142}
143
144#endif