1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSemaphore.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ContextType.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/TestContext.h"
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
38*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
39*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
40*c8dee2aaSAndroid Build Coastguard Worker
41*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
42*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLFunctions.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLInterface.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
47*c8dee2aaSAndroid Build Coastguard Worker #endif
48*c8dee2aaSAndroid Build Coastguard Worker
49*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
50*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSemaphore.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkCommandPool.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkGpu.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkUtil.h"
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu { struct VulkanInterface; }
59*c8dee2aaSAndroid Build Coastguard Worker
60*c8dee2aaSAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR
61*c8dee2aaSAndroid Build Coastguard Worker // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
62*c8dee2aaSAndroid Build Coastguard Worker #undef CreateSemaphore
63*c8dee2aaSAndroid Build Coastguard Worker #endif
64*c8dee2aaSAndroid Build Coastguard Worker #endif
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
67*c8dee2aaSAndroid Build Coastguard Worker
68*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker static const int MAIN_W = 8, MAIN_H = 16;
71*c8dee2aaSAndroid Build Coastguard Worker static const int CHILD_W = 16, CHILD_H = 16;
72*c8dee2aaSAndroid Build Coastguard Worker
check_pixels(skiatest::Reporter * reporter,const SkBitmap & bitmap)73*c8dee2aaSAndroid Build Coastguard Worker void check_pixels(skiatest::Reporter* reporter, const SkBitmap& bitmap) {
74*c8dee2aaSAndroid Build Coastguard Worker const uint32_t* canvasPixels = static_cast<const uint32_t*>(bitmap.getPixels());
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker bool failureFound = false;
77*c8dee2aaSAndroid Build Coastguard Worker SkPMColor expectedPixel;
78*c8dee2aaSAndroid Build Coastguard Worker for (int cy = 0; cy < CHILD_H && !failureFound; ++cy) {
79*c8dee2aaSAndroid Build Coastguard Worker for (int cx = 0; cx < CHILD_W && !failureFound; ++cx) {
80*c8dee2aaSAndroid Build Coastguard Worker SkPMColor canvasPixel = canvasPixels[cy * CHILD_W + cx];
81*c8dee2aaSAndroid Build Coastguard Worker if (cy < CHILD_H / 2) {
82*c8dee2aaSAndroid Build Coastguard Worker if (cx < CHILD_W / 2) {
83*c8dee2aaSAndroid Build Coastguard Worker expectedPixel = 0xFF0000FF; // Red
84*c8dee2aaSAndroid Build Coastguard Worker } else {
85*c8dee2aaSAndroid Build Coastguard Worker expectedPixel = 0xFFFF0000; // Blue
86*c8dee2aaSAndroid Build Coastguard Worker }
87*c8dee2aaSAndroid Build Coastguard Worker } else {
88*c8dee2aaSAndroid Build Coastguard Worker expectedPixel = 0xFF00FF00; // Green
89*c8dee2aaSAndroid Build Coastguard Worker }
90*c8dee2aaSAndroid Build Coastguard Worker if (expectedPixel != canvasPixel) {
91*c8dee2aaSAndroid Build Coastguard Worker failureFound = true;
92*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Wrong color at %d, %d. Got 0x%08x when we expected 0x%08x",
93*c8dee2aaSAndroid Build Coastguard Worker cx, cy, canvasPixel, expectedPixel);
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker }
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
draw_child(skiatest::Reporter * reporter,const sk_gpu_test::ContextInfo & childInfo,const GrBackendTexture & backendTexture,const GrBackendSemaphore & semaphore)99*c8dee2aaSAndroid Build Coastguard Worker void draw_child(skiatest::Reporter* reporter,
100*c8dee2aaSAndroid Build Coastguard Worker const sk_gpu_test::ContextInfo& childInfo,
101*c8dee2aaSAndroid Build Coastguard Worker const GrBackendTexture& backendTexture,
102*c8dee2aaSAndroid Build Coastguard Worker const GrBackendSemaphore& semaphore) {
103*c8dee2aaSAndroid Build Coastguard Worker
104*c8dee2aaSAndroid Build Coastguard Worker childInfo.testContext()->makeCurrent();
105*c8dee2aaSAndroid Build Coastguard Worker
106*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo childII = SkImageInfo::Make(CHILD_W, CHILD_H, kRGBA_8888_SkColorType,
107*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType);
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker auto childDContext = childInfo.directContext();
110*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> childSurface(SkSurfaces::RenderTarget(
111*c8dee2aaSAndroid Build Coastguard Worker childDContext, skgpu::Budgeted::kNo, childII, 0, kTopLeft_GrSurfaceOrigin, nullptr));
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> childImage = SkImages::BorrowTextureFrom(childDContext,
114*c8dee2aaSAndroid Build Coastguard Worker backendTexture,
115*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
116*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
117*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
118*c8dee2aaSAndroid Build Coastguard Worker nullptr,
119*c8dee2aaSAndroid Build Coastguard Worker nullptr,
120*c8dee2aaSAndroid Build Coastguard Worker nullptr);
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* childCanvas = childSurface->getCanvas();
123*c8dee2aaSAndroid Build Coastguard Worker childCanvas->clear(SK_ColorRED);
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker childSurface->wait(1, &semaphore);
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker childCanvas->drawImage(childImage, CHILD_W/2, 0);
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
130*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorGREEN);
131*c8dee2aaSAndroid Build Coastguard Worker SkIRect rect = SkIRect::MakeLTRB(0, CHILD_H/2, CHILD_W, CHILD_H);
132*c8dee2aaSAndroid Build Coastguard Worker childCanvas->drawIRect(rect, paint);
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker // read pixels
135*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
136*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocPixels(childII);
137*c8dee2aaSAndroid Build Coastguard Worker childSurface->readPixels(bitmap, 0, 0);
138*c8dee2aaSAndroid Build Coastguard Worker
139*c8dee2aaSAndroid Build Coastguard Worker check_pixels(reporter, bitmap);
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker enum class FlushType { kSurface, kImage, kContext };
143*c8dee2aaSAndroid Build Coastguard Worker
surface_semaphore_test(skiatest::Reporter * reporter,const sk_gpu_test::ContextInfo & mainInfo,const sk_gpu_test::ContextInfo & childInfo1,const sk_gpu_test::ContextInfo & childInfo2,FlushType flushType)144*c8dee2aaSAndroid Build Coastguard Worker void surface_semaphore_test(skiatest::Reporter* reporter,
145*c8dee2aaSAndroid Build Coastguard Worker const sk_gpu_test::ContextInfo& mainInfo,
146*c8dee2aaSAndroid Build Coastguard Worker const sk_gpu_test::ContextInfo& childInfo1,
147*c8dee2aaSAndroid Build Coastguard Worker const sk_gpu_test::ContextInfo& childInfo2,
148*c8dee2aaSAndroid Build Coastguard Worker FlushType flushType) {
149*c8dee2aaSAndroid Build Coastguard Worker auto mainCtx = mainInfo.directContext();
150*c8dee2aaSAndroid Build Coastguard Worker if (!mainCtx->priv().caps()->backendSemaphoreSupport()) {
151*c8dee2aaSAndroid Build Coastguard Worker return;
152*c8dee2aaSAndroid Build Coastguard Worker }
153*c8dee2aaSAndroid Build Coastguard Worker
154*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
155*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType);
156*c8dee2aaSAndroid Build Coastguard Worker
157*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> mainSurface(SkSurfaces::RenderTarget(
158*c8dee2aaSAndroid Build Coastguard Worker mainCtx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
159*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* mainCanvas = mainSurface->getCanvas();
160*c8dee2aaSAndroid Build Coastguard Worker auto blueSurface = mainSurface->makeSurface(ii);
161*c8dee2aaSAndroid Build Coastguard Worker blueSurface->getCanvas()->clear(SK_ColorBLUE);
162*c8dee2aaSAndroid Build Coastguard Worker auto blueImage = blueSurface->makeImageSnapshot();
163*c8dee2aaSAndroid Build Coastguard Worker blueSurface.reset();
164*c8dee2aaSAndroid Build Coastguard Worker mainCanvas->drawImage(blueImage, 0, 0);
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<GrBackendSemaphore> semaphores(2);
167*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
168*c8dee2aaSAndroid Build Coastguard Worker if (GrBackendApi::kVulkan == mainInfo.backend()) {
169*c8dee2aaSAndroid Build Coastguard Worker // Initialize the secondary semaphore instead of having Ganesh create one internally
170*c8dee2aaSAndroid Build Coastguard Worker GrVkGpu* gpu = static_cast<GrVkGpu*>(mainCtx->priv().getGpu());
171*c8dee2aaSAndroid Build Coastguard Worker VkDevice device = gpu->device();
172*c8dee2aaSAndroid Build Coastguard Worker
173*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore vkSem;
174*c8dee2aaSAndroid Build Coastguard Worker
175*c8dee2aaSAndroid Build Coastguard Worker VkSemaphoreCreateInfo createInfo;
176*c8dee2aaSAndroid Build Coastguard Worker createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
177*c8dee2aaSAndroid Build Coastguard Worker createInfo.pNext = nullptr;
178*c8dee2aaSAndroid Build Coastguard Worker createInfo.flags = 0;
179*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL_ERRCHECK(gpu, CreateSemaphore(device, &createInfo, nullptr, &vkSem));
180*c8dee2aaSAndroid Build Coastguard Worker
181*c8dee2aaSAndroid Build Coastguard Worker semaphores[1] = GrBackendSemaphores::MakeVk(vkSem);
182*c8dee2aaSAndroid Build Coastguard Worker }
183*c8dee2aaSAndroid Build Coastguard Worker #endif
184*c8dee2aaSAndroid Build Coastguard Worker
185*c8dee2aaSAndroid Build Coastguard Worker GrFlushInfo info;
186*c8dee2aaSAndroid Build Coastguard Worker info.fNumSemaphores = 2;
187*c8dee2aaSAndroid Build Coastguard Worker info.fSignalSemaphores = semaphores.get();
188*c8dee2aaSAndroid Build Coastguard Worker switch (flushType) {
189*c8dee2aaSAndroid Build Coastguard Worker case FlushType::kSurface:
190*c8dee2aaSAndroid Build Coastguard Worker mainCtx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, info);
191*c8dee2aaSAndroid Build Coastguard Worker break;
192*c8dee2aaSAndroid Build Coastguard Worker case FlushType::kImage:
193*c8dee2aaSAndroid Build Coastguard Worker mainCtx->flush(blueImage, info);
194*c8dee2aaSAndroid Build Coastguard Worker break;
195*c8dee2aaSAndroid Build Coastguard Worker case FlushType::kContext:
196*c8dee2aaSAndroid Build Coastguard Worker mainCtx->flush(info);
197*c8dee2aaSAndroid Build Coastguard Worker break;
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker mainCtx->submit();
200*c8dee2aaSAndroid Build Coastguard Worker
201*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture backendTexture = SkSurfaces::GetBackendTexture(
202*c8dee2aaSAndroid Build Coastguard Worker mainSurface.get(), SkSurface::BackendHandleAccess::kFlushRead);
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker draw_child(reporter, childInfo1, backendTexture, semaphores[0]);
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
207*c8dee2aaSAndroid Build Coastguard Worker if (GrBackendApi::kVulkan == mainInfo.backend()) {
208*c8dee2aaSAndroid Build Coastguard Worker // In Vulkan we need to make sure we are sending the correct VkImageLayout in with the
209*c8dee2aaSAndroid Build Coastguard Worker // backendImage. After the first child draw the layout gets changed to SHADER_READ, so
210*c8dee2aaSAndroid Build Coastguard Worker // we just manually set that here.
211*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextures::SetVkImageLayout(&backendTexture,
212*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
213*c8dee2aaSAndroid Build Coastguard Worker }
214*c8dee2aaSAndroid Build Coastguard Worker #endif
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker draw_child(reporter, childInfo2, backendTexture, semaphores[1]);
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(SurfaceSemaphores,reporter,options,CtsEnforcement::kApiLevel_T)219*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(SurfaceSemaphores, reporter, options, CtsEnforcement::kApiLevel_T) {
220*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
221*c8dee2aaSAndroid Build Coastguard Worker static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
222*c8dee2aaSAndroid Build Coastguard Worker #else
223*c8dee2aaSAndroid Build Coastguard Worker static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
224*c8dee2aaSAndroid Build Coastguard Worker #endif
225*c8dee2aaSAndroid Build Coastguard Worker
226*c8dee2aaSAndroid Build Coastguard Worker for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
227*c8dee2aaSAndroid Build Coastguard Worker for (auto flushType : {FlushType::kSurface, FlushType::kImage, FlushType::kContext}) {
228*c8dee2aaSAndroid Build Coastguard Worker skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
229*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
230*c8dee2aaSAndroid Build Coastguard Worker // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
231*c8dee2aaSAndroid Build Coastguard Worker // desktop since tests do not account for not fixing http://skbug.com/2809
232*c8dee2aaSAndroid Build Coastguard Worker if (contextType == skgpu::ContextType::kGL ||
233*c8dee2aaSAndroid Build Coastguard Worker contextType == skgpu::ContextType::kGLES) {
234*c8dee2aaSAndroid Build Coastguard Worker if (contextType != kNativeGLType) {
235*c8dee2aaSAndroid Build Coastguard Worker continue;
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker }
238*c8dee2aaSAndroid Build Coastguard Worker #else
239*c8dee2aaSAndroid Build Coastguard Worker sk_ignore_unused_variable(kNativeGLType); // Do something to avoid unused variable
240*c8dee2aaSAndroid Build Coastguard Worker #endif
241*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GrContextFactory factory(options);
242*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);
243*c8dee2aaSAndroid Build Coastguard Worker if (!skgpu::IsRenderingContext(contextType)) {
244*c8dee2aaSAndroid Build Coastguard Worker continue;
245*c8dee2aaSAndroid Build Coastguard Worker }
246*c8dee2aaSAndroid Build Coastguard Worker skiatest::ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
247*c8dee2aaSAndroid Build Coastguard Worker if (ctxInfo.directContext()) {
248*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::ContextInfo child1 =
249*c8dee2aaSAndroid Build Coastguard Worker factory.getSharedContextInfo(ctxInfo.directContext(), 0);
250*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::ContextInfo child2 =
251*c8dee2aaSAndroid Build Coastguard Worker factory.getSharedContextInfo(ctxInfo.directContext(), 1);
252*c8dee2aaSAndroid Build Coastguard Worker if (!child1.directContext() || !child2.directContext()) {
253*c8dee2aaSAndroid Build Coastguard Worker continue;
254*c8dee2aaSAndroid Build Coastguard Worker }
255*c8dee2aaSAndroid Build Coastguard Worker
256*c8dee2aaSAndroid Build Coastguard Worker surface_semaphore_test(reporter, ctxInfo, child1, child2, flushType);
257*c8dee2aaSAndroid Build Coastguard Worker }
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker }
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)262*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest,
263*c8dee2aaSAndroid Build Coastguard Worker reporter,
264*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
265*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
266*c8dee2aaSAndroid Build Coastguard Worker auto ctx = ctxInfo.directContext();
267*c8dee2aaSAndroid Build Coastguard Worker if (!ctx->priv().caps()->backendSemaphoreSupport()) {
268*c8dee2aaSAndroid Build Coastguard Worker // For example, the GL backend does not support these.
269*c8dee2aaSAndroid Build Coastguard Worker return;
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker
272*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
273*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType);
274*c8dee2aaSAndroid Build Coastguard Worker
275*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> mainSurface(SkSurfaces::RenderTarget(
276*c8dee2aaSAndroid Build Coastguard Worker ctx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
277*c8dee2aaSAndroid Build Coastguard Worker
278*c8dee2aaSAndroid Build Coastguard Worker // Flush surface once without semaphores to make sure there is no pending IO for it.
279*c8dee2aaSAndroid Build Coastguard Worker ctx->flushAndSubmit(mainSurface.get(), GrSyncCpu::kNo);
280*c8dee2aaSAndroid Build Coastguard Worker
281*c8dee2aaSAndroid Build Coastguard Worker GrBackendSemaphore semaphore;
282*c8dee2aaSAndroid Build Coastguard Worker GrFlushInfo flushInfo;
283*c8dee2aaSAndroid Build Coastguard Worker flushInfo.fNumSemaphores = 1;
284*c8dee2aaSAndroid Build Coastguard Worker flushInfo.fSignalSemaphores = &semaphore;
285*c8dee2aaSAndroid Build Coastguard Worker GrSemaphoresSubmitted submitted =
286*c8dee2aaSAndroid Build Coastguard Worker ctx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, flushInfo);
287*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, GrSemaphoresSubmitted::kYes == submitted);
288*c8dee2aaSAndroid Build Coastguard Worker ctx->submit();
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
291*c8dee2aaSAndroid Build Coastguard Worker if (GrBackendApi::kVulkan == ctxInfo.backend()) {
292*c8dee2aaSAndroid Build Coastguard Worker GrVkGpu* gpu = static_cast<GrVkGpu*>(ctx->priv().getGpu());
293*c8dee2aaSAndroid Build Coastguard Worker const skgpu::VulkanInterface* interface = gpu->vkInterface();
294*c8dee2aaSAndroid Build Coastguard Worker VkDevice device = gpu->device();
295*c8dee2aaSAndroid Build Coastguard Worker VkQueue queue = gpu->queue();
296*c8dee2aaSAndroid Build Coastguard Worker GrVkCommandPool* cmdPool = gpu->cmdPool();
297*c8dee2aaSAndroid Build Coastguard Worker VkCommandBuffer cmdBuffer;
298*c8dee2aaSAndroid Build Coastguard Worker
299*c8dee2aaSAndroid Build Coastguard Worker // Create Command Buffer
300*c8dee2aaSAndroid Build Coastguard Worker const VkCommandBufferAllocateInfo cmdInfo = {
301*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
302*c8dee2aaSAndroid Build Coastguard Worker nullptr, // pNext
303*c8dee2aaSAndroid Build Coastguard Worker cmdPool->vkCommandPool(), // commandPool
304*c8dee2aaSAndroid Build Coastguard Worker VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
305*c8dee2aaSAndroid Build Coastguard Worker 1 // bufferCount
306*c8dee2aaSAndroid Build Coastguard Worker };
307*c8dee2aaSAndroid Build Coastguard Worker
308*c8dee2aaSAndroid Build Coastguard Worker VkResult err = GR_VK_CALL(interface, AllocateCommandBuffers(device, &cmdInfo, &cmdBuffer));
309*c8dee2aaSAndroid Build Coastguard Worker if (err) {
310*c8dee2aaSAndroid Build Coastguard Worker return;
311*c8dee2aaSAndroid Build Coastguard Worker }
312*c8dee2aaSAndroid Build Coastguard Worker
313*c8dee2aaSAndroid Build Coastguard Worker VkCommandBufferBeginInfo cmdBufferBeginInfo;
314*c8dee2aaSAndroid Build Coastguard Worker memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
315*c8dee2aaSAndroid Build Coastguard Worker cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
316*c8dee2aaSAndroid Build Coastguard Worker cmdBufferBeginInfo.pNext = nullptr;
317*c8dee2aaSAndroid Build Coastguard Worker cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
318*c8dee2aaSAndroid Build Coastguard Worker cmdBufferBeginInfo.pInheritanceInfo = nullptr;
319*c8dee2aaSAndroid Build Coastguard Worker
320*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL_ERRCHECK(gpu, BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
321*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL_ERRCHECK(gpu, EndCommandBuffer(cmdBuffer));
322*c8dee2aaSAndroid Build Coastguard Worker
323*c8dee2aaSAndroid Build Coastguard Worker VkFenceCreateInfo fenceInfo;
324*c8dee2aaSAndroid Build Coastguard Worker VkFence fence;
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
327*c8dee2aaSAndroid Build Coastguard Worker fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
328*c8dee2aaSAndroid Build Coastguard Worker err = GR_VK_CALL(interface, CreateFence(device, &fenceInfo, nullptr, &fence));
329*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!err);
330*c8dee2aaSAndroid Build Coastguard Worker
331*c8dee2aaSAndroid Build Coastguard Worker VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
332*c8dee2aaSAndroid Build Coastguard Worker VkSubmitInfo submitInfo;
333*c8dee2aaSAndroid Build Coastguard Worker memset(&submitInfo, 0, sizeof(VkSubmitInfo));
334*c8dee2aaSAndroid Build Coastguard Worker submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
335*c8dee2aaSAndroid Build Coastguard Worker submitInfo.pNext = nullptr;
336*c8dee2aaSAndroid Build Coastguard Worker submitInfo.waitSemaphoreCount = 1;
337*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore vkSem = GrBackendSemaphores::GetVkSemaphore(semaphore);
338*c8dee2aaSAndroid Build Coastguard Worker submitInfo.pWaitSemaphores = &vkSem;
339*c8dee2aaSAndroid Build Coastguard Worker submitInfo.pWaitDstStageMask = &waitStages;
340*c8dee2aaSAndroid Build Coastguard Worker submitInfo.commandBufferCount = 1;
341*c8dee2aaSAndroid Build Coastguard Worker submitInfo.pCommandBuffers = &cmdBuffer;
342*c8dee2aaSAndroid Build Coastguard Worker submitInfo.signalSemaphoreCount = 0;
343*c8dee2aaSAndroid Build Coastguard Worker submitInfo.pSignalSemaphores = nullptr;
344*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL_ERRCHECK(gpu, QueueSubmit(queue, 1, &submitInfo, fence));
345*c8dee2aaSAndroid Build Coastguard Worker
346*c8dee2aaSAndroid Build Coastguard Worker err = GR_VK_CALL(interface, WaitForFences(device, 1, &fence, true, 3000000000));
347*c8dee2aaSAndroid Build Coastguard Worker
348*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, err != VK_TIMEOUT);
349*c8dee2aaSAndroid Build Coastguard Worker
350*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL(interface, DestroyFence(device, fence, nullptr));
351*c8dee2aaSAndroid Build Coastguard Worker GR_VK_CALL(interface, DestroySemaphore(device, vkSem, nullptr));
352*c8dee2aaSAndroid Build Coastguard Worker // If the above test fails the wait semaphore will never be signaled which can cause the
353*c8dee2aaSAndroid Build Coastguard Worker // device to hang when tearing down (even if just tearing down GL). So we Fail here to
354*c8dee2aaSAndroid Build Coastguard Worker // kill things.
355*c8dee2aaSAndroid Build Coastguard Worker if (err == VK_TIMEOUT) {
356*c8dee2aaSAndroid Build Coastguard Worker SK_ABORT("Waiting on semaphore indefinitely");
357*c8dee2aaSAndroid Build Coastguard Worker }
358*c8dee2aaSAndroid Build Coastguard Worker }
359*c8dee2aaSAndroid Build Coastguard Worker #endif
360*c8dee2aaSAndroid Build Coastguard Worker }
361