diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp')
-rwxr-xr-x | gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp b/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp new file mode 100755 index 000000000..1568509f6 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp @@ -0,0 +1,282 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class FenceNVTest : public ANGLETest +{ + protected: + FenceNVTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } +}; + +class FenceSyncTest : public ANGLETest +{ + protected: + FenceSyncTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } +}; + +// FenceNV objects should respond false to glIsFenceNV until they've been set +TEST_P(FenceNVTest, IsFence) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + GLuint fence = 0; + glGenFencesNV(1, &fence); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_FALSE, glIsFenceNV(fence)); + EXPECT_GL_NO_ERROR(); + + glSetFenceNV(fence, GL_ALL_COMPLETED_NV); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_TRUE, glIsFenceNV(fence)); + EXPECT_GL_NO_ERROR(); +} + +// Test error cases for all FenceNV functions +TEST_P(FenceNVTest, Errors) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + // glTestFenceNV should still return TRUE for an invalid fence and generate an INVALID_OPERATION + EXPECT_EQ(GL_TRUE, glTestFenceNV(10)); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + GLuint fence = 20; + + // glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the fences pointer + glGenFencesNV(-1, &fence); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20u, fence); + + // Generate a real fence + glGenFencesNV(1, &fence); + EXPECT_GL_NO_ERROR(); + + // glTestFenceNV should still return TRUE for a fence that is not started and generate an INVALID_OPERATION + EXPECT_EQ(GL_TRUE, glTestFenceNV(fence)); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not modify the params + GLint result = 30; + glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + EXPECT_EQ(30, result); + + glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + EXPECT_EQ(30, result); + + // glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV + glSetFenceNV(fence, 0); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // glSetFenceNV should generate INVALID_OPERATION for an invalid fence + glSetFenceNV(10, GL_ALL_COMPLETED_NV); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test that basic usage works and doesn't generate errors or crash +TEST_P(FenceNVTest, BasicOperations) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + + GLuint fences[20] = { 0 }; + glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences); + EXPECT_GL_NO_ERROR(); + + for (GLuint fence : fences) + { + glSetFenceNV(fence, GL_ALL_COMPLETED_NV); + + glClear(GL_COLOR_BUFFER_BIT); + } + + glFinish(); + + for (GLuint fence : fences) + { + GLint status = 0; + glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status); + EXPECT_GL_NO_ERROR(); + + // Fence should be complete now that Finish has been called + EXPECT_EQ(GL_TRUE, status); + } + + EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255); +} + +// FenceSync objects should respond true to IsSync after they are created with glFenceSync +TEST_P(FenceSyncTest, IsSync) +{ + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_TRUE, glIsSync(sync)); + EXPECT_EQ(GL_FALSE, glIsSync(reinterpret_cast<GLsync>(40))); +} + +// Test error cases for all FenceSync function +TEST_P(FenceSyncTest, Errors) +{ + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + // DeleteSync generates INVALID_VALUE when the sync is not valid + glDeleteSync(reinterpret_cast<GLsync>(20)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE + EXPECT_EQ(0, glFenceSync(0, 0)); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // glFenceSync generates GL_INVALID_ENUM if the flags is not 0 + EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more than just GL_SYNC_FLUSH_COMMANDS_BIT + EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is not valid + EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if flags is non-zero + glWaitSync(sync, 1, GL_TIMEOUT_IGNORED); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED + glWaitSync(sync, 0, 0); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if the sync object is not valid + glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be untouched + GLsizei length = 20; + GLint value = 30; + glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20, length); + EXPECT_EQ(30, value); + + // glGetSynciv generates GL_INVALID_VALUE if the sync object tis not valid, results should be untouched + glGetSynciv(reinterpret_cast<GLsync>(30), GL_OBJECT_TYPE, 1, &length, &value); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20, length); + EXPECT_EQ(30, value); +} + +// Test usage of glGetSynciv +TEST_P(FenceSyncTest, BasicQueries) +{ + GLsizei length = 0; + GLint value = 0; + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + glGetSynciv(sync, GL_SYNC_CONDITION, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(GL_SYNC_GPU_COMMANDS_COMPLETE, value); + + glGetSynciv(sync, GL_OBJECT_TYPE, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(GL_SYNC_FENCE, value); + + glGetSynciv(sync, GL_SYNC_FLAGS, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(0, value); +} + +// Test that basic usage works and doesn't generate errors or crash +TEST_P(FenceSyncTest, BasicOperations) +{ + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + glClear(GL_COLOR_BUFFER_BIT); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + EXPECT_GL_NO_ERROR(); + + GLsizei length = 0; + GLint value = 0; + unsigned int loopCount = 0; + + glFlush(); + + // Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop + while (value != GL_SIGNALED && loopCount <= 1000000) + { + loopCount++; + + glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value); + ASSERT_GL_NO_ERROR(); + } + + ASSERT_GLENUM_EQ(GL_SIGNALED, value); + + for (size_t i = 0; i < 20; i++) + { + glClear(GL_COLOR_BUFFER_BIT); + glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); + EXPECT_GL_NO_ERROR(); + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(FenceNVTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(FenceSyncTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); |