summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/FenceSyncTests.cpp282
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());