diff options
author | Greg Daniel <egdaniel@google.com> | 2017-07-20 15:47:30 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-20 20:26:28 +0000 |
commit | dba7e7ccfbab1c99b8a3f81156cecdb630d7d03a (patch) | |
tree | 1254893d643a529bcc916393c77991bbf705c5c3 /tests | |
parent | c7d295ecf712dece58ae6654721b3708fd8a40d6 (diff) |
Add test for flushing empty surface with semaphores
Bug: skia:
Change-Id: I8d7dcb29c5b4c460aa5137842caf6563448ba5d3
Reviewed-on: https://skia-review.googlesource.com/25181
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/SurfaceSemaphoreTest.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/tests/SurfaceSemaphoreTest.cpp b/tests/SurfaceSemaphoreTest.cpp index 72e8e05401..7b22e1cf33 100644 --- a/tests/SurfaceSemaphoreTest.cpp +++ b/tests/SurfaceSemaphoreTest.cpp @@ -17,8 +17,18 @@ #include "SkCanvas.h" #include "SkSurface.h" +#include "gl/GrGLGpu.h" +#include "gl/GrGLUtil.h" + #ifdef SK_VULKAN +#include "vk/GrVkGpu.h" #include "vk/GrVkTypes.h" +#include "vk/GrVkUtil.h" + +#ifdef VK_USE_PLATFORM_WIN32_KHR +// windows wants to define this as CreateSemaphoreA or CreateSemaphoreW + #undef CreateSemaphore + #endif #endif static const int MAIN_W = 8, MAIN_H = 16; @@ -172,4 +182,105 @@ DEF_GPUTEST(SurfaceSemaphores, reporter, factory) { } } +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest, reporter, ctxInfo) { + GrContext* ctx = ctxInfo.grContext(); + if (!ctx->caps()->fenceSyncSupport()) { + return; + } + + const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType, + kPremul_SkAlphaType); + + sk_sp<SkSurface> mainSurface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, + ii, 0, kTopLeft_GrSurfaceOrigin, + nullptr)); + + // Flush surface once without semaphores to make sure there is no peneding IO for it. + mainSurface->flush(); + + GrBackendSemaphore semaphore; + REPORTER_ASSERT(reporter, mainSurface->flushAndSignalSemaphores(1, &semaphore)); + + if (kOpenGL_GrBackend == ctxInfo.backend()) { + GrGLGpu* gpu = static_cast<GrGLGpu*>(ctx->getGpu()); + const GrGLInterface* interface = gpu->glInterface(); + GrGLsync sync = semaphore.glSync(); + REPORTER_ASSERT(reporter, sync); + bool result; + GR_GL_CALL_RET(interface, result, IsSync(sync)); + REPORTER_ASSERT(reporter, result); + } + +#ifdef SK_VULKAN + if (kVulkan_GrBackend == ctxInfo.backend()) { + GrVkGpu* gpu = static_cast<GrVkGpu*>(ctx->getGpu()); + const GrVkInterface* interface = gpu->vkInterface(); + VkDevice device = gpu->device(); + VkQueue queue = gpu->queue(); + VkCommandPool cmdPool = gpu->cmdPool(); + VkCommandBuffer cmdBuffer; + + // Create Command Buffer + const VkCommandBufferAllocateInfo cmdInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType + nullptr, // pNext + cmdPool, // commandPool + VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level + 1 // bufferCount + }; + + VkResult err = GR_VK_CALL(interface, AllocateCommandBuffers(device, &cmdInfo, &cmdBuffer)); + if (err) { + return; + } + + VkCommandBufferBeginInfo cmdBufferBeginInfo; + memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo)); + cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdBufferBeginInfo.pNext = nullptr; + cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdBufferBeginInfo.pInheritanceInfo = nullptr; + + GR_VK_CALL_ERRCHECK(interface, BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo)); + GR_VK_CALL_ERRCHECK(interface, EndCommandBuffer(cmdBuffer)); + + VkFenceCreateInfo fenceInfo; + VkFence fence; + + memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo)); + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + err = GR_VK_CALL(interface, CreateFence(device, &fenceInfo, nullptr, &fence)); + SkASSERT(!err); + + VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + VkSubmitInfo submitInfo; + memset(&submitInfo, 0, sizeof(VkSubmitInfo)); + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 1; + VkSemaphore vkSem = semaphore.vkSemaphore(); + submitInfo.pWaitSemaphores = &vkSem; + submitInfo.pWaitDstStageMask = &waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &cmdBuffer; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pSignalSemaphores = nullptr; + GR_VK_CALL_ERRCHECK(interface, QueueSubmit(queue, 1, &submitInfo, fence)); + + err = GR_VK_CALL(interface, WaitForFences(device, 1, &fence, true, 3000000000)); + + REPORTER_ASSERT(reporter, err != VK_TIMEOUT); + + GR_VK_CALL(interface, DestroyFence(device, fence, nullptr)); + GR_VK_CALL(interface, DestroySemaphore(device, vkSem, nullptr)); + // If the above test fails the wait semaphore will never be signaled which can cause the + // device to hang when tearing down (even if just tearing down GL). So we Fail here to + // kill things. + if (err == VK_TIMEOUT) { + SkFAIL("Waiting on semaphore indefinitely"); + } + } +#endif +} + #endif |