| // | |
| // 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) | |
| { | |
| ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_NV_fence")); | |
| GLuint fence = 0; | |
| glGenFencesNV(1, &fence); | |
| EXPECT_GL_NO_ERROR(); | |
| EXPECT_GL_FALSE(glIsFenceNV(fence)); | |
| EXPECT_GL_NO_ERROR(); | |
| glSetFenceNV(fence, GL_ALL_COMPLETED_NV); | |
| EXPECT_GL_NO_ERROR(); | |
| EXPECT_GL_TRUE(glIsFenceNV(fence)); | |
| EXPECT_GL_NO_ERROR(); | |
| } | |
| // Test error cases for all FenceNV functions | |
| TEST_P(FenceNVTest, Errors) | |
| { | |
| ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_NV_fence")); | |
| EXPECT_GL_TRUE(glTestFenceNV(10)) << "glTestFenceNV should still return TRUE for an invalid " | |
| "fence and generate an INVALID_OPERATION"; | |
| 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(); | |
| EXPECT_GL_TRUE(glTestFenceNV(fence)) << "glTestFenceNV should still return TRUE for a fence " | |
| "that is not started and generate an INVALID_OPERATION"; | |
| 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) | |
| { | |
| ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_NV_fence")); | |
| 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_GL_TRUE(status); | |
| } | |
| EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255); | |
| } | |
| // Sync 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_GL_TRUE(glIsSync(sync)); | |
| EXPECT_GL_FALSE(glIsSync(reinterpret_cast<GLsync>(40))); | |
| } | |
| // Test error cases for all Sync 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) | |
| { | |
| 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()); |