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