1/*
2 * Copyright 2016 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// This is a GPU-backend specific test. It relies on static intializers to work
9
10#include "SkTypes.h"
11
12#if SK_SUPPORT_GPU && defined(SK_VULKAN)
13
14#include "GrContextFactory.h"
15#include "GrTest.h"
16#include "GrTexture.h"
17
18#include "Test.h"
19#include "vk/GrVkCaps.h"
20#include "vk/GrVkGpu.h"
21#include "vk/GrVkMemory.h"
22#include "vk/GrVkTypes.h"
23
24using sk_gpu_test::GrContextFactory;
25
26const int kW = 1024;
27const int kH = 1024;
28const GrPixelConfig kPixelConfig = kRGBA_8888_GrPixelConfig;
29
30void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) {
31
32    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
33
34    GrBackendObject backendObj = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig,
35                                                                      false);
36    const GrVkImageInfo* imageInfo = reinterpret_cast<const GrVkImageInfo*>(backendObj);
37
38    GrBackendTexture backendTex = GrBackendTexture(kW, kH, *imageInfo);
39    sk_sp<GrTexture> tex = gpu->wrapBackendTexture(backendTex,
40                                                   kTopLeft_GrSurfaceOrigin,
41                                                   kNone_GrBackendTextureFlag,
42                                                   0,
43                                                   kBorrow_GrWrapOwnership);
44    REPORTER_ASSERT(reporter, tex);
45
46    // image is null
47    GrVkImageInfo backendCopy = *imageInfo;
48    backendCopy.fImage = VK_NULL_HANDLE;
49    backendTex = GrBackendTexture(kW, kH, backendCopy);
50    tex = gpu->wrapBackendTexture(backendTex,
51                                  kTopLeft_GrSurfaceOrigin,
52                                  kNone_GrBackendTextureFlag,
53                                  0,
54                                  kBorrow_GrWrapOwnership);
55    REPORTER_ASSERT(reporter, !tex);
56    tex = gpu->wrapBackendTexture(backendTex,
57                                  kTopLeft_GrSurfaceOrigin,
58                                  kNone_GrBackendTextureFlag,
59                                  0,
60                                  kAdopt_GrWrapOwnership);
61    REPORTER_ASSERT(reporter, !tex);
62
63    // alloc is null
64    backendCopy.fImage = imageInfo->fImage;
65    backendCopy.fAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
66    backendTex = GrBackendTexture(kW, kH, backendCopy);
67    tex = gpu->wrapBackendTexture(backendTex,
68                                  kTopLeft_GrSurfaceOrigin,
69                                  kNone_GrBackendTextureFlag,
70                                  0,
71                                  kBorrow_GrWrapOwnership);
72    REPORTER_ASSERT(reporter, !tex);
73    tex = gpu->wrapBackendTexture(backendTex,
74                                  kTopLeft_GrSurfaceOrigin,
75                                  kNone_GrBackendTextureFlag,
76                                  0,
77                                  kAdopt_GrWrapOwnership);
78    REPORTER_ASSERT(reporter, !tex);
79    // check adopt creation
80    backendCopy.fAlloc = imageInfo->fAlloc;
81    backendTex = GrBackendTexture(kW, kH, backendCopy);
82    tex = gpu->wrapBackendTexture(backendTex,
83                                  kTopLeft_GrSurfaceOrigin,
84                                  kNone_GrBackendTextureFlag,
85                                  0,
86                                  kAdopt_GrWrapOwnership);
87
88    REPORTER_ASSERT(reporter, tex);
89
90    gpu->deleteTestingOnlyBackendTexture(backendObj, true);
91}
92
93void wrap_rt_test(skiatest::Reporter* reporter, GrContext* context) {
94    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
95
96    GrBackendObject backendObj = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig,
97                                                                      true);
98    const GrVkImageInfo* backendTex = reinterpret_cast<const GrVkImageInfo*>(backendObj);
99
100    GrBackendRenderTarget backendRT(kW, kH, 0, 0, *backendTex);
101
102    sk_sp<GrRenderTarget> rt = gpu->wrapBackendRenderTarget(backendRT, kTopLeft_GrSurfaceOrigin);
103    REPORTER_ASSERT(reporter, rt);
104
105    // image is null
106    GrVkImageInfo backendCopy = *backendTex;
107    backendCopy.fImage = VK_NULL_HANDLE;
108    GrBackendRenderTarget backendRT2(kW, kH, 0, 0, backendCopy);
109    rt = gpu->wrapBackendRenderTarget(backendRT2, kTopLeft_GrSurfaceOrigin);
110    REPORTER_ASSERT(reporter, !rt);
111
112    // alloc is null
113    backendCopy.fImage = backendTex->fImage;
114    backendCopy.fAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
115    // can wrap null alloc
116    GrBackendRenderTarget backendRT3(kW, kH, 0, 0, backendCopy);
117    rt = gpu->wrapBackendRenderTarget(backendRT3, kTopLeft_GrSurfaceOrigin);
118    REPORTER_ASSERT(reporter, rt);
119
120    // When we wrapBackendRenderTarget it is always borrowed, so we must make sure to free the
121    // resource when we're done.
122    gpu->deleteTestingOnlyBackendTexture(backendObj, false);
123}
124
125void wrap_trt_test(skiatest::Reporter* reporter, GrContext* context) {
126    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
127
128    GrBackendObject backendObj = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig,
129                                                                      true);
130    const GrVkImageInfo* imageInfo = reinterpret_cast<const GrVkImageInfo*>(backendObj);
131
132    GrBackendTexture backendTex = GrBackendTexture(kW, kH, *imageInfo);
133    sk_sp<GrTexture> tex = gpu->wrapBackendTexture(backendTex,
134                                                   kTopLeft_GrSurfaceOrigin,
135                                                   kRenderTarget_GrBackendTextureFlag,
136                                                   0,
137                                                   kBorrow_GrWrapOwnership);
138    REPORTER_ASSERT(reporter, tex);
139
140    // image is null
141    GrVkImageInfo backendCopy = *imageInfo;
142    backendCopy.fImage = VK_NULL_HANDLE;
143    backendTex = GrBackendTexture(kW, kH, backendCopy);
144    tex = gpu->wrapBackendTexture(backendTex,
145                                  kTopLeft_GrSurfaceOrigin,
146                                  kRenderTarget_GrBackendTextureFlag,
147                                  0,
148                                  kBorrow_GrWrapOwnership);
149    REPORTER_ASSERT(reporter, !tex);
150    tex = gpu->wrapBackendTexture(backendTex,
151                                  kTopLeft_GrSurfaceOrigin,
152                                  kRenderTarget_GrBackendTextureFlag,
153                                  0,
154                                  kAdopt_GrWrapOwnership);
155    REPORTER_ASSERT(reporter, !tex);
156
157    // alloc is null
158    backendCopy.fImage = imageInfo->fImage;
159    backendCopy.fAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
160    backendTex = GrBackendTexture(kW, kH, backendCopy);
161    tex = gpu->wrapBackendTexture(backendTex,
162                                  kTopLeft_GrSurfaceOrigin,
163                                  kRenderTarget_GrBackendTextureFlag,
164                                  0,
165                                  kBorrow_GrWrapOwnership);
166    REPORTER_ASSERT(reporter, !tex);
167    tex = gpu->wrapBackendTexture(backendTex,
168                                  kTopLeft_GrSurfaceOrigin,
169                                  kRenderTarget_GrBackendTextureFlag,
170                                  0,
171                                  kAdopt_GrWrapOwnership);
172    REPORTER_ASSERT(reporter, !tex);
173
174    // check adopt creation
175    backendCopy.fAlloc = imageInfo->fAlloc;
176    backendTex = GrBackendTexture(kW, kH, backendCopy);
177    tex = gpu->wrapBackendTexture(backendTex,
178                                  kTopLeft_GrSurfaceOrigin,
179                                  kRenderTarget_GrBackendTextureFlag,
180                                  0,
181                                  kAdopt_GrWrapOwnership);
182    REPORTER_ASSERT(reporter, tex);
183
184    gpu->deleteTestingOnlyBackendTexture(backendObj, true);
185}
186
187DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkWrapTests, reporter, ctxInfo) {
188    wrap_tex_test(reporter, ctxInfo.grContext());
189    wrap_rt_test(reporter, ctxInfo.grContext());
190    wrap_trt_test(reporter, ctxInfo.grContext());
191}
192
193#endif
194