1#include "ANGLETest.h" 2 3// Needed for Sleep() 4#include <Windows.h> 5 6class OcclusionQueriesTest : public ANGLETest 7{ 8protected: 9 OcclusionQueriesTest() 10 { 11 setWindowWidth(128); 12 setWindowHeight(128); 13 setConfigRedBits(8); 14 setConfigGreenBits(8); 15 setConfigBlueBits(8); 16 setConfigAlphaBits(8); 17 setConfigDepthBits(24); 18 19 mProgram = 0; 20 } 21 22 virtual void SetUp() 23 { 24 ANGLETest::SetUp(); 25 26 const std::string passthroughVS = SHADER_SOURCE 27 ( 28 attribute highp vec4 position; 29 void main(void) 30 { 31 gl_Position = position; 32 } 33 ); 34 35 const std::string passthroughPS = SHADER_SOURCE 36 ( 37 precision highp float; 38 void main(void) 39 { 40 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 41 } 42 ); 43 44 mProgram = CompileProgram(passthroughVS, passthroughPS); 45 if (mProgram == 0) 46 { 47 FAIL() << "shader compilation failed."; 48 } 49 } 50 51 virtual void TearDown() 52 { 53 glDeleteProgram(mProgram); 54 55 ANGLETest::TearDown(); 56 } 57 58 GLuint mProgram; 59}; 60 61TEST_F(OcclusionQueriesTest, IsOccluded) 62{ 63 glDepthMask(GL_TRUE); 64 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 65 66 // draw a quad at depth 0.3 67 glEnable(GL_DEPTH_TEST); 68 glUseProgram(mProgram); 69 drawQuad(mProgram, "position", 0.3f); 70 glUseProgram(0); 71 72 EXPECT_GL_NO_ERROR(); 73 74 GLuint query = 0; 75 glGenQueriesEXT(1, &query); 76 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); 77 drawQuad(mProgram, "position", 0.8f); // this quad should be occluded by first quad 78 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 79 80 EXPECT_GL_NO_ERROR(); 81 82 swapBuffers(); 83 84 GLuint ready = GL_FALSE; 85 while (ready == GL_FALSE) 86 { 87 Sleep(0); 88 glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); 89 } 90 91 GLuint result = GL_TRUE; 92 glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result); 93 94 EXPECT_GL_NO_ERROR(); 95 96 glDeleteQueriesEXT(1, &query); 97 98 EXPECT_EQ(result, GL_FALSE); 99} 100 101TEST_F(OcclusionQueriesTest, IsNotOccluded) 102{ 103 glDepthMask(GL_TRUE); 104 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 105 106 EXPECT_GL_NO_ERROR(); 107 108 GLuint query = 0; 109 glGenQueriesEXT(1, &query); 110 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); 111 drawQuad(mProgram, "position", 0.8f); // this quad should not be occluded 112 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 113 114 EXPECT_GL_NO_ERROR(); 115 116 swapBuffers(); 117 118 GLuint result = GL_TRUE; 119 glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result); // will block waiting for result 120 121 EXPECT_GL_NO_ERROR(); 122 123 glDeleteQueriesEXT(1, &query); 124 125 EXPECT_EQ(result, GL_TRUE); 126} 127 128TEST_F(OcclusionQueriesTest, Errors) 129{ 130 glDepthMask(GL_TRUE); 131 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 132 133 EXPECT_GL_NO_ERROR(); 134 135 GLuint query = 0; 136 GLuint query2 = 0; 137 glGenQueriesEXT(1, &query); 138 139 EXPECT_EQ(glIsQueryEXT(query), GL_FALSE); 140 EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE); 141 142 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0); // can't pass 0 as query id 143 EXPECT_GL_ERROR(GL_INVALID_OPERATION); 144 145 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); 146 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // can't initiate a query while one's already active 147 EXPECT_GL_ERROR(GL_INVALID_OPERATION); 148 149 EXPECT_EQ(glIsQueryEXT(query), GL_TRUE); 150 EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE); // have not called begin 151 152 drawQuad(mProgram, "position", 0.8f); // this quad should not be occluded 153 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // no active query for this target 154 EXPECT_GL_ERROR(GL_INVALID_OPERATION); 155 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 156 157 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query); // can't begin a query as a different type than previously used 158 EXPECT_GL_ERROR(GL_INVALID_OPERATION); 159 160 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // have to call genqueries first 161 EXPECT_EQ(glGetError(), GL_INVALID_OPERATION); 162 163 glGenQueriesEXT(1, &query2); 164 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // should be ok now 165 EXPECT_EQ(glIsQueryEXT(query2), GL_TRUE); 166 167 drawQuad(mProgram, "position", 0.3f); // this should draw in front of other quad 168 glDeleteQueriesEXT(1, &query2); // should delete when query becomes inactive 169 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // should not incur error; should delete query + 1 at end of execution. 170 EXPECT_GL_NO_ERROR(); 171 172 swapBuffers(); 173 174 EXPECT_GL_NO_ERROR(); 175 176 GLuint ready = GL_FALSE; 177 glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); // this query is now deleted 178 EXPECT_GL_ERROR(GL_INVALID_OPERATION); 179 180 EXPECT_GL_NO_ERROR(); 181} 182