Path: blob/main_old/src/tests/gl_tests/FenceSyncTests.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "test_utils/ANGLETest.h"7#include "test_utils/gl_raii.h"89using namespace angle;1011class FenceNVTest : public ANGLETest12{13protected:14FenceNVTest()15{16setWindowWidth(128);17setWindowHeight(128);18setConfigRedBits(8);19setConfigGreenBits(8);20setConfigBlueBits(8);21setConfigAlphaBits(8);22setConfigDepthBits(24);23}24};2526class FenceSyncTest : public ANGLETest27{28public:29static constexpr uint32_t kSize = 1024;3031protected:32FenceSyncTest()33{34setWindowWidth(kSize);35setWindowHeight(kSize);36setConfigRedBits(8);37setConfigGreenBits(8);38setConfigBlueBits(8);39setConfigAlphaBits(8);40setConfigDepthBits(24);41}42};4344// FenceNV objects should respond false to glIsFenceNV until they've been set45TEST_P(FenceNVTest, IsFence)46{47ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));4849GLuint fence = 0;50glGenFencesNV(1, &fence);51EXPECT_GL_NO_ERROR();5253EXPECT_GL_FALSE(glIsFenceNV(fence));54EXPECT_GL_NO_ERROR();5556glSetFenceNV(fence, GL_ALL_COMPLETED_NV);57EXPECT_GL_NO_ERROR();5859EXPECT_GL_TRUE(glIsFenceNV(fence));60EXPECT_GL_NO_ERROR();61}6263// Test error cases for all FenceNV functions64TEST_P(FenceNVTest, Errors)65{66ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));6768EXPECT_GL_TRUE(glTestFenceNV(10)) << "glTestFenceNV should still return TRUE for an invalid "69"fence and generate an INVALID_OPERATION";70EXPECT_GL_ERROR(GL_INVALID_OPERATION);7172GLuint fence = 20;7374// glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the75// fences pointer76glGenFencesNV(-1, &fence);77EXPECT_GL_ERROR(GL_INVALID_VALUE);78EXPECT_EQ(20u, fence);7980// Generate a real fence81glGenFencesNV(1, &fence);82EXPECT_GL_NO_ERROR();8384EXPECT_GL_TRUE(glTestFenceNV(fence)) << "glTestFenceNV should still return TRUE for a fence "85"that is not started and generate an INVALID_OPERATION";86EXPECT_GL_ERROR(GL_INVALID_OPERATION);8788// glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not89// modify the params90GLint result = 30;91glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result);92EXPECT_GL_ERROR(GL_INVALID_OPERATION);93EXPECT_EQ(30, result);9495glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result);96EXPECT_GL_ERROR(GL_INVALID_OPERATION);97EXPECT_EQ(30, result);9899// glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV100glSetFenceNV(fence, 0);101EXPECT_GL_ERROR(GL_INVALID_ENUM);102103// glSetFenceNV should generate INVALID_OPERATION for an invalid fence104glSetFenceNV(10, GL_ALL_COMPLETED_NV);105EXPECT_GL_ERROR(GL_INVALID_OPERATION);106}107108// Test that basic usage works and doesn't generate errors or crash109TEST_P(FenceNVTest, BasicOperations)110{111ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_fence"));112113glClearColor(1.0f, 0.0f, 1.0f, 1.0f);114115constexpr size_t kFenceCount = 20;116GLuint fences[kFenceCount] = {0};117glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences);118EXPECT_GL_NO_ERROR();119120for (GLuint fence : fences)121{122glClear(GL_COLOR_BUFFER_BIT);123glSetFenceNV(fence, GL_ALL_COMPLETED_NV);124}125126// Finish the last fence, all fences before should be marked complete127glFinishFenceNV(fences[kFenceCount - 1]);128129for (GLuint fence : fences)130{131GLint status = 0;132glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status);133EXPECT_GL_NO_ERROR();134135// Fence should be complete now that Finish has been called136EXPECT_GL_TRUE(status);137}138139EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);140}141142// Sync objects should respond true to IsSync after they are created with glFenceSync143TEST_P(FenceSyncTest, IsSync)144{145GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);146EXPECT_GL_NO_ERROR();147148EXPECT_GL_TRUE(glIsSync(sync));149EXPECT_GL_FALSE(glIsSync(reinterpret_cast<GLsync>(40)));150}151152// Test error cases for all Sync function153TEST_P(FenceSyncTest, Errors)154{155GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);156157// DeleteSync generates INVALID_VALUE when the sync is not valid158glDeleteSync(reinterpret_cast<GLsync>(20));159EXPECT_GL_ERROR(GL_INVALID_VALUE);160161// glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE162EXPECT_EQ(0, glFenceSync(0, 0));163EXPECT_GL_ERROR(GL_INVALID_ENUM);164165// glFenceSync generates GL_INVALID_ENUM if the flags is not 0166EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10));167EXPECT_GL_ERROR(GL_INVALID_VALUE);168169// glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more170// than just GL_SYNC_FLUSH_COMMANDS_BIT171EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0));172EXPECT_GL_ERROR(GL_INVALID_VALUE);173174// glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is175// not valid176EXPECT_GLENUM_EQ(GL_WAIT_FAILED,177glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0));178EXPECT_GL_ERROR(GL_INVALID_VALUE);179180// glWaitSync generates GL_INVALID_VALUE if flags is non-zero181glWaitSync(sync, 1, GL_TIMEOUT_IGNORED);182EXPECT_GL_ERROR(GL_INVALID_VALUE);183184// glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED185glWaitSync(sync, 0, 0);186EXPECT_GL_ERROR(GL_INVALID_VALUE);187188// glWaitSync generates GL_INVALID_VALUE if the sync object is not valid189glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED);190EXPECT_GL_ERROR(GL_INVALID_VALUE);191192// glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be193// untouched194GLsizei length = 20;195GLint value = 30;196glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value);197EXPECT_GL_ERROR(GL_INVALID_VALUE);198EXPECT_EQ(20, length);199EXPECT_EQ(30, value);200201// glGetSynciv generates GL_INVALID_VALUE if the sync object is not valid, results should be202// untouched203glGetSynciv(reinterpret_cast<GLsync>(30), GL_OBJECT_TYPE, 1, &length, &value);204EXPECT_GL_ERROR(GL_INVALID_VALUE);205EXPECT_EQ(20, length);206EXPECT_EQ(30, value);207}208209// Test usage of glGetSynciv210TEST_P(FenceSyncTest, BasicQueries)211{212GLsizei length = 0;213GLint value = 0;214GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);215216glGetSynciv(sync, GL_SYNC_CONDITION, 1, &length, &value);217EXPECT_GL_NO_ERROR();218EXPECT_EQ(GL_SYNC_GPU_COMMANDS_COMPLETE, value);219220glGetSynciv(sync, GL_OBJECT_TYPE, 1, &length, &value);221EXPECT_GL_NO_ERROR();222EXPECT_EQ(GL_SYNC_FENCE, value);223224glGetSynciv(sync, GL_SYNC_FLAGS, 1, &length, &value);225EXPECT_GL_NO_ERROR();226EXPECT_EQ(0, value);227}228229// Test that basic usage works and doesn't generate errors or crash230TEST_P(FenceSyncTest, BasicOperations)231{232glClearColor(1.0f, 0.0f, 1.0f, 1.0f);233234GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);235236glClear(GL_COLOR_BUFFER_BIT);237glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);238EXPECT_GL_NO_ERROR();239240GLsizei length = 0;241GLint value = 0;242unsigned int loopCount = 0;243244glFlush();245246// Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop247while (value != GL_SIGNALED && loopCount <= 1000000)248{249loopCount++;250251glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value);252ASSERT_GL_NO_ERROR();253}254255ASSERT_GLENUM_EQ(GL_SIGNALED, value);256257for (size_t i = 0; i < 20; i++)258{259glClear(GL_COLOR_BUFFER_BIT);260glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);261EXPECT_GL_NO_ERROR();262}263}264265// Test that multiple fences and draws can be issued266TEST_P(FenceSyncTest, MultipleFenceDraw)267{268constexpr int kNumIterations = 10;269constexpr int kNumDraws = 5;270271// Create a texture/FBO to draw to272GLTexture texture;273glBindTexture(GL_TEXTURE_2D, texture.get());274glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);275ASSERT_GL_NO_ERROR();276GLFramebuffer fbo;277glBindFramebuffer(GL_FRAMEBUFFER, fbo);278glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);279ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);280281ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());282ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());283284bool drawGreen = true;285for (int numIterations = 0; numIterations < kNumIterations; ++numIterations)286{287glBindFramebuffer(GL_FRAMEBUFFER, fbo);288ASSERT_GL_NO_ERROR();289290for (int i = 0; i < kNumDraws; ++i)291{292GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);293ASSERT_GL_NO_ERROR();294295drawGreen = !drawGreen;296GLuint program = 0;297if (drawGreen)298{299program = greenProgram.get();300}301else302{303program = redProgram.get();304}305drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.0f);306ASSERT_GL_NO_ERROR();307308glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);309EXPECT_GL_NO_ERROR();310glDeleteSync(sync);311ASSERT_GL_NO_ERROR();312}313314// Blit to the default FBO315glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);316glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);317glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);318ASSERT_GL_NO_ERROR();319swapBuffers();320321glBindFramebuffer(GL_FRAMEBUFFER, fbo);322GLColor color;323if (drawGreen)324{325color = GLColor::green;326}327else328{329color = GLColor::red;330}331EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, color);332}333}334335ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FenceNVTest);336337GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FenceSyncTest);338ANGLE_INSTANTIATE_TEST_ES3(FenceSyncTest);339340341