xref: /aosp_15_r20/external/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
9*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker class OcclusionQueriesTest : public ANGLETest<>
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker   protected:
OcclusionQueriesTest()18*8975f5c5SAndroid Build Coastguard Worker     OcclusionQueriesTest() : mProgram(0), mRNG(1)
19*8975f5c5SAndroid Build Coastguard Worker     {
20*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
21*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
22*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
27*8975f5c5SAndroid Build Coastguard Worker     }
28*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()29*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
30*8975f5c5SAndroid Build Coastguard Worker     {
31*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
32*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mProgram);
33*8975f5c5SAndroid Build Coastguard Worker     }
34*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()35*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { glDeleteProgram(mProgram); }
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
38*8975f5c5SAndroid Build Coastguard Worker     RNG mRNG;
39*8975f5c5SAndroid Build Coastguard Worker };
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker class OcclusionQueriesTestES3 : public OcclusionQueriesTest
42*8975f5c5SAndroid Build Coastguard Worker {};
43*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(OcclusionQueriesTest,IsOccluded)44*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, IsOccluded)
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
47*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
48*8975f5c5SAndroid Build Coastguard Worker 
49*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
50*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker     // draw a quad at depth 0.3
53*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
54*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
55*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.3f);
56*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
61*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
62*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(),
63*8975f5c5SAndroid Build Coastguard Worker              0.8f);  // this quad should be occluded by first quad
64*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker     GLuint ready = GL_FALSE;
71*8975f5c5SAndroid Build Coastguard Worker     while (ready == GL_FALSE)
72*8975f5c5SAndroid Build Coastguard Worker     {
73*8975f5c5SAndroid Build Coastguard Worker         angle::Sleep(0);
74*8975f5c5SAndroid Build Coastguard Worker         glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
75*8975f5c5SAndroid Build Coastguard Worker     }
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
78*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
79*8975f5c5SAndroid Build Coastguard Worker 
80*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
81*8975f5c5SAndroid Build Coastguard Worker 
82*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(OcclusionQueriesTest,IsNotOccluded)85*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, IsNotOccluded)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
88*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
91*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
96*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
97*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded
98*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
105*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);  // will block waiting for result
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker // Test that glClear should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest,ClearNotCounted)113*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, ClearNotCounted)
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
116*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
117*8975f5c5SAndroid Build Coastguard Worker 
118*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
119*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
122*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query[2];
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker     // First query
129*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[0]);
130*8975f5c5SAndroid Build Coastguard Worker     // Full screen clear
131*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker     // View port clear
134*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
135*8975f5c5SAndroid Build Coastguard Worker     glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
136*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SCISSOR_TEST);
137*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     // Second query
144*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[1]);
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker     // View port clear
147*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker     // View port clear
150*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
151*8975f5c5SAndroid Build Coastguard Worker     glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
152*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SCISSOR_TEST);
153*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker     // this quad should not be occluded
156*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker     // Clear again
159*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker     // this quad should not be occluded
162*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 1.0);
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
169*8975f5c5SAndroid Build Coastguard Worker 
170*8975f5c5SAndroid Build Coastguard Worker     GLuint result[2] = {GL_TRUE, GL_TRUE};
171*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[0], GL_QUERY_RESULT_EXT,
172*8975f5c5SAndroid Build Coastguard Worker                            &result[0]);  // will block waiting for result
173*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[1], GL_QUERY_RESULT_EXT,
174*8975f5c5SAndroid Build Coastguard Worker                            &result[1]);  // will block waiting for result
175*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result[0]);
178*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result[1]);
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker // Test that masked glClear should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest,MaskedClearNotCounted)182*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, MaskedClearNotCounted)
183*8975f5c5SAndroid Build Coastguard Worker {
184*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
185*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
186*8975f5c5SAndroid Build Coastguard Worker 
187*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
188*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D());
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     // Masked clear
193*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
194*8975f5c5SAndroid Build Coastguard Worker     glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
195*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
196*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
197*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
202*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
203*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
204*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
207*8975f5c5SAndroid Build Coastguard Worker }
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker // Test that copies should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest,CopyNotCounted)210*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, CopyNotCounted)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
213*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
216*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D());
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     // Unrelated draw before the query starts.
221*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker     // Copy to a texture with a different format from backbuffer
224*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
225*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
226*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
227*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, getWindowWidth(), getWindowHeight(), 0);
228*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
229*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
234*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
235*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
236*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
237*8975f5c5SAndroid Build Coastguard Worker 
238*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker // Test that blit should not be counted by occlusion query.
TEST_P(OcclusionQueriesTestES3,BlitNotCounted)242*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTestES3, BlitNotCounted)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
245*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263669
248*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kSize = 64;
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer srcFbo;
253*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, srcFbo);
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker     GLTexture srcTex;
256*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, srcTex);
257*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
258*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTex, 0);
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer dstFbo;
261*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker     GLTexture dstTex;
264*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, dstTex);
265*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSize, kSize, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
266*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);
267*8975f5c5SAndroid Build Coastguard Worker 
268*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker     // Unrelated draw before the query starts.
271*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     // Blit flipped and with different formats.
274*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
275*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, 64, 64, 64, 64, 0, 0, GL_COLOR_BUFFER_BIT, GL_LINEAR);
276*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
277*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
278*8975f5c5SAndroid Build Coastguard Worker 
279*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
282*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
283*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
284*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker 
289*8975f5c5SAndroid Build Coastguard Worker // Test that multisampled-render-to-texture unresolve should not be counted by occlusion query.
TEST_P(OcclusionQueriesTestES3,UnresolveNotCounted)290*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTestES3, UnresolveNotCounted)
291*8975f5c5SAndroid Build Coastguard Worker {
292*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kSize = 64;
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fboMS;
297*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker     // Create multisampled framebuffer to draw into
300*8975f5c5SAndroid Build Coastguard Worker     GLTexture textureMS;
301*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, textureMS);
302*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
303*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
304*8975f5c5SAndroid Build Coastguard Worker                                          textureMS, 0, 4);
305*8975f5c5SAndroid Build Coastguard Worker 
306*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer depthMS;
307*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
308*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, kSize, kSize);
309*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
310*8975f5c5SAndroid Build Coastguard Worker 
311*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     // Draw red into the multisampled color buffer.
314*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
315*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker     // Create a texture and copy into it, forcing a resolve of the color buffer.
318*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
319*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
320*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     // Make a draw call that will fail the depth test, and therefore shouldn't contribute to
325*8975f5c5SAndroid Build Coastguard Worker     // occlusion query.
326*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
327*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
328*8975f5c5SAndroid Build Coastguard Worker     glDepthFunc(GL_NEVER);
329*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
330*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
331*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
332*8975f5c5SAndroid Build Coastguard Worker 
333*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
336*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
337*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
338*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
339*8975f5c5SAndroid Build Coastguard Worker 
340*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
341*8975f5c5SAndroid Build Coastguard Worker }
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker // Test that reusing a query should reset its value to zero if no draw calls are emitted in the
344*8975f5c5SAndroid Build Coastguard Worker // second pass.
TEST_P(OcclusionQueriesTest,RewriteDrawNoDrawToZero)345*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, RewriteDrawNoDrawToZero)
346*8975f5c5SAndroid Build Coastguard Worker {
347*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
348*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
349*8975f5c5SAndroid Build Coastguard Worker 
350*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
351*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
352*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
353*8975f5c5SAndroid Build Coastguard Worker 
354*8975f5c5SAndroid Build Coastguard Worker     // draw a quad at depth 0.3
355*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
356*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
357*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
358*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.3f);
359*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
360*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
363*8975f5c5SAndroid Build Coastguard Worker 
364*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
365*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
366*8975f5c5SAndroid Build Coastguard Worker 
367*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
368*8975f5c5SAndroid Build Coastguard Worker 
369*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker     GLuint ready = GL_FALSE;
372*8975f5c5SAndroid Build Coastguard Worker     while (ready == GL_FALSE)
373*8975f5c5SAndroid Build Coastguard Worker     {
374*8975f5c5SAndroid Build Coastguard Worker         angle::Sleep(0);
375*8975f5c5SAndroid Build Coastguard Worker         glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
376*8975f5c5SAndroid Build Coastguard Worker     }
377*8975f5c5SAndroid Build Coastguard Worker 
378*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
379*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
380*8975f5c5SAndroid Build Coastguard Worker 
381*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
382*8975f5c5SAndroid Build Coastguard Worker 
383*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
384*8975f5c5SAndroid Build Coastguard Worker }
385*8975f5c5SAndroid Build Coastguard Worker 
386*8975f5c5SAndroid Build Coastguard Worker // Test that changing framebuffers work
TEST_P(OcclusionQueriesTest,FramebufferBindingChange)387*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, FramebufferBindingChange)
388*8975f5c5SAndroid Build Coastguard Worker {
389*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
390*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kSize = 4;
393*8975f5c5SAndroid Build Coastguard Worker 
394*8975f5c5SAndroid Build Coastguard Worker     // Create two framebuffers, and make sure they are synced.
395*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo[2];
396*8975f5c5SAndroid Build Coastguard Worker     GLTexture color[2];
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     for (size_t index = 0; index < 2; ++index)
399*8975f5c5SAndroid Build Coastguard Worker     {
400*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, color[index]);
401*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
402*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo[index]);
405*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color[index],
406*8975f5c5SAndroid Build Coastguard Worker                                0);
407*8975f5c5SAndroid Build Coastguard Worker 
408*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0, index, 1 - index, 1);
409*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
410*8975f5c5SAndroid Build Coastguard Worker 
411*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, index ? GLColor::green : GLColor::blue);
412*8975f5c5SAndroid Build Coastguard Worker     }
413*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
414*8975f5c5SAndroid Build Coastguard Worker 
415*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, kSize, kSize);
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker     // Start an occlusion query and issue a draw call to each framebuffer.
418*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
419*8975f5c5SAndroid Build Coastguard Worker 
420*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
421*8975f5c5SAndroid Build Coastguard Worker 
422*8975f5c5SAndroid Build Coastguard Worker     for (size_t index = 0; index < 2; ++index)
423*8975f5c5SAndroid Build Coastguard Worker     {
424*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo[index]);
425*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
426*8975f5c5SAndroid Build Coastguard Worker     }
427*8975f5c5SAndroid Build Coastguard Worker 
428*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
429*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
430*8975f5c5SAndroid Build Coastguard Worker 
431*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_FALSE;
432*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
433*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
434*8975f5c5SAndroid Build Coastguard Worker 
435*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
436*8975f5c5SAndroid Build Coastguard Worker }
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker // Test that switching framebuffers without actually drawing, then issuing a masked clear while a
439*8975f5c5SAndroid Build Coastguard Worker // query is active works.
TEST_P(OcclusionQueriesTestES3,SwitchFramebuffersThenMaskedClear)440*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTestES3, SwitchFramebuffersThenMaskedClear)
441*8975f5c5SAndroid Build Coastguard Worker {
442*8975f5c5SAndroid Build Coastguard Worker     constexpr GLint kSize = 10;
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo1, fbo2;
445*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rbo1, rbo2;
446*8975f5c5SAndroid Build Coastguard Worker 
447*8975f5c5SAndroid Build Coastguard Worker     // Set up two framebuffers
448*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rbo1);
449*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kSize, kSize);
450*8975f5c5SAndroid Build Coastguard Worker 
451*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
452*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo1);
453*8975f5c5SAndroid Build Coastguard Worker 
454*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
455*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kSize, kSize);
456*8975f5c5SAndroid Build Coastguard Worker 
457*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
458*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo2);
459*8975f5c5SAndroid Build Coastguard Worker 
460*8975f5c5SAndroid Build Coastguard Worker     // Start render pass on fbo1
461*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
462*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
463*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker     // Begin a query
466*8975f5c5SAndroid Build Coastguard Worker     GLQuery query;
467*8975f5c5SAndroid Build Coastguard Worker     glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
468*8975f5c5SAndroid Build Coastguard Worker 
469*8975f5c5SAndroid Build Coastguard Worker     // Switch to another render pass and clear.  In the Vulkan backend, this clear is deferred, so
470*8975f5c5SAndroid Build Coastguard Worker     // while the framebuffer binding is synced, the previous render pass is not necessarily closed.
471*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
472*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_STENCIL_BUFFER_BIT);
473*8975f5c5SAndroid Build Coastguard Worker 
474*8975f5c5SAndroid Build Coastguard Worker     // Switch back to the original render pass and issue a masked stencil clear.  In the Vulkan
475*8975f5c5SAndroid Build Coastguard Worker     // backend, this is done with a draw call.
476*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
477*8975f5c5SAndroid Build Coastguard Worker     glStencilMask(0xAA);
478*8975f5c5SAndroid Build Coastguard Worker     glClearStencil(0xF4);
479*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_STENCIL_BUFFER_BIT);
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     // Verify the clear worked.
482*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer color;
483*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, color);
484*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
485*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
486*8975f5c5SAndroid Build Coastguard Worker 
487*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_STENCIL_TEST);
488*8975f5c5SAndroid Build Coastguard Worker     glStencilFunc(GL_ALWAYS, 0xA4, 0xFF);
489*8975f5c5SAndroid Build Coastguard Worker     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
490*8975f5c5SAndroid Build Coastguard Worker     glStencilMask(0xFF);
491*8975f5c5SAndroid Build Coastguard Worker 
492*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
493*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
494*8975f5c5SAndroid Build Coastguard Worker 
495*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
496*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
497*8975f5c5SAndroid Build Coastguard Worker }
498*8975f5c5SAndroid Build Coastguard Worker 
499*8975f5c5SAndroid Build Coastguard Worker // Test that an empty query after a positive query returns false
TEST_P(OcclusionQueriesTest,EmptyQueryAfterCompletedQuery)500*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, EmptyQueryAfterCompletedQuery)
501*8975f5c5SAndroid Build Coastguard Worker {
502*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
503*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
504*8975f5c5SAndroid Build Coastguard Worker 
505*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
506*8975f5c5SAndroid Build Coastguard Worker 
507*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
508*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
509*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
510*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
511*8975f5c5SAndroid Build Coastguard Worker 
512*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_FALSE;
513*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
514*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
515*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(result);
516*8975f5c5SAndroid Build Coastguard Worker 
517*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
518*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
519*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker     result = GL_FALSE;
522*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
523*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
524*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(result);
525*8975f5c5SAndroid Build Coastguard Worker }
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker // Some Metal drivers do not automatically clear visibility buffer
528*8975f5c5SAndroid Build Coastguard Worker // at the beginning of a render pass. This test makes two queries
529*8975f5c5SAndroid Build Coastguard Worker // that would use the same internal visibility buffer at the same
530*8975f5c5SAndroid Build Coastguard Worker // offset and checks the query results.
TEST_P(OcclusionQueriesTest,EmptyQueryAfterCompletedQueryInterleaved)531*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, EmptyQueryAfterCompletedQueryInterleaved)
532*8975f5c5SAndroid Build Coastguard Worker {
533*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
534*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
535*8975f5c5SAndroid Build Coastguard Worker 
536*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
537*8975f5c5SAndroid Build Coastguard Worker 
538*8975f5c5SAndroid Build Coastguard Worker     // Make a draw call to start a new render pass
539*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);
540*8975f5c5SAndroid Build Coastguard Worker 
541*8975f5c5SAndroid Build Coastguard Worker     // Begin a query and make another draw call
542*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
543*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);
544*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
545*8975f5c5SAndroid Build Coastguard Worker 
546*8975f5c5SAndroid Build Coastguard Worker     // Check the query result to end command encoding
547*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_FALSE;
548*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
549*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(result);
550*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
551*8975f5c5SAndroid Build Coastguard Worker 
552*8975f5c5SAndroid Build Coastguard Worker     // Make a draw call to start a new render pass
553*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);
554*8975f5c5SAndroid Build Coastguard Worker 
555*8975f5c5SAndroid Build Coastguard Worker     // Begin and immediately resolve a new query; it must return false
556*8975f5c5SAndroid Build Coastguard Worker     result = GL_FALSE;
557*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
558*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
559*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
560*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(result);
561*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
562*8975f5c5SAndroid Build Coastguard Worker }
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker // Test multiple occlusion queries.
TEST_P(OcclusionQueriesTest,MultiQueries)565*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, MultiQueries)
566*8975f5c5SAndroid Build Coastguard Worker {
567*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
568*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
569*8975f5c5SAndroid Build Coastguard Worker 
570*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
571*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() || IsD3D11());
572*8975f5c5SAndroid Build Coastguard Worker 
573*8975f5c5SAndroid Build Coastguard Worker     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
574*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query[5];
577*8975f5c5SAndroid Build Coastguard Worker 
578*8975f5c5SAndroid Build Coastguard Worker     // First query
579*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[0]);
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
584*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
585*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
586*8975f5c5SAndroid Build Coastguard Worker 
587*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
588*8975f5c5SAndroid Build Coastguard Worker 
589*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded
590*8975f5c5SAndroid Build Coastguard Worker 
591*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
592*8975f5c5SAndroid Build Coastguard Worker 
593*8975f5c5SAndroid Build Coastguard Worker     // Due to implementation might skip in-renderpass flush, we are using glFinish here to force a
594*8975f5c5SAndroid Build Coastguard Worker     // flush. A flush shound't clear the query result.
595*8975f5c5SAndroid Build Coastguard Worker     glFinish();
596*8975f5c5SAndroid Build Coastguard Worker 
597*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
598*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), -2, 0.25f);  // this quad should be occluded
599*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
600*8975f5c5SAndroid Build Coastguard Worker     // First query ends
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f,
603*8975f5c5SAndroid Build Coastguard Worker              0.25f);  // this quad should not be occluded
604*8975f5c5SAndroid Build Coastguard Worker 
605*8975f5c5SAndroid Build Coastguard Worker     // Second query
606*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[1]);
607*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
608*8975f5c5SAndroid Build Coastguard Worker              0.25f);  // this quad should be occluded
609*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker     // Third query
612*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[2]);
613*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
614*8975f5c5SAndroid Build Coastguard Worker              0.5f);  // this quad should not be occluded
615*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
616*8975f5c5SAndroid Build Coastguard Worker     // ------------
617*8975f5c5SAndroid Build Coastguard Worker     glFinish();
618*8975f5c5SAndroid Build Coastguard Worker 
619*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
620*8975f5c5SAndroid Build Coastguard Worker     glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
621*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SCISSOR_TEST);
622*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
623*8975f5c5SAndroid Build Coastguard Worker              0.5f);  // this quad should not be occluded
624*8975f5c5SAndroid Build Coastguard Worker 
625*8975f5c5SAndroid Build Coastguard Worker     // Fourth query: begin query then end then begin again
626*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[3]);
627*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
628*8975f5c5SAndroid Build Coastguard Worker              1);  // this quad should not be occluded
629*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
630*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[3]);
631*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
632*8975f5c5SAndroid Build Coastguard Worker     // glClear should not be counted toward query);
633*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
634*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
635*8975f5c5SAndroid Build Coastguard Worker 
636*8975f5c5SAndroid Build Coastguard Worker     // Fifth query spans across frames
637*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[4]);
638*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f,
639*8975f5c5SAndroid Build Coastguard Worker              0.25f);  // this quad should not be occluded
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
642*8975f5c5SAndroid Build Coastguard Worker 
643*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
644*8975f5c5SAndroid Build Coastguard Worker 
645*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
646*8975f5c5SAndroid Build Coastguard Worker              0.5f);  // this quad should not be occluded
647*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
648*8975f5c5SAndroid Build Coastguard Worker 
649*8975f5c5SAndroid Build Coastguard Worker     GLuint result = GL_TRUE;
650*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[0], GL_QUERY_RESULT_EXT,
651*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
652*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
653*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[1], GL_QUERY_RESULT_EXT,
656*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
657*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
658*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
659*8975f5c5SAndroid Build Coastguard Worker 
660*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[2], GL_QUERY_RESULT_EXT,
661*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
662*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
663*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[3], GL_QUERY_RESULT_EXT,
666*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
667*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
668*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
669*8975f5c5SAndroid Build Coastguard Worker 
670*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query[4], GL_QUERY_RESULT_EXT,
671*8975f5c5SAndroid Build Coastguard Worker                            &result);  // will block waiting for result
672*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
673*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
674*8975f5c5SAndroid Build Coastguard Worker }
675*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(OcclusionQueriesTest,Errors)676*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, Errors)
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
679*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
680*8975f5c5SAndroid Build Coastguard Worker 
681*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
682*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
683*8975f5c5SAndroid Build Coastguard Worker 
684*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
685*8975f5c5SAndroid Build Coastguard Worker 
686*8975f5c5SAndroid Build Coastguard Worker     GLuint query  = 0;
687*8975f5c5SAndroid Build Coastguard Worker     GLuint query2 = 0;
688*8975f5c5SAndroid Build Coastguard Worker     glGenQueriesEXT(1, &query);
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(glIsQueryEXT(query));
691*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(glIsQueryEXT(query2));
692*8975f5c5SAndroid Build Coastguard Worker 
693*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);  // can't pass 0 as query id
694*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
695*8975f5c5SAndroid Build Coastguard Worker 
696*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
697*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
698*8975f5c5SAndroid Build Coastguard Worker                     query2);  // can't initiate a query while one's already active
699*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
700*8975f5c5SAndroid Build Coastguard Worker 
701*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(glIsQueryEXT(query));
702*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(glIsQueryEXT(query2));  // have not called begin
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded
705*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);      // no active query for this target
706*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
707*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
708*8975f5c5SAndroid Build Coastguard Worker 
709*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
710*8975f5c5SAndroid Build Coastguard Worker                     query);  // can't begin a query as a different type than previously used
711*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
712*8975f5c5SAndroid Build Coastguard Worker 
713*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
714*8975f5c5SAndroid Build Coastguard Worker                     query2);  // have to call genqueries first
715*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
716*8975f5c5SAndroid Build Coastguard Worker 
717*8975f5c5SAndroid Build Coastguard Worker     glGenQueriesEXT(1, &query2);
718*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2);  // should be ok now
719*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(glIsQueryEXT(query2));
720*8975f5c5SAndroid Build Coastguard Worker 
721*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(),
722*8975f5c5SAndroid Build Coastguard Worker              0.3f);                  // this should draw in front of other quad
723*8975f5c5SAndroid Build Coastguard Worker     glDeleteQueriesEXT(1, &query2);  // should delete when query becomes inactive
724*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);  // should not incur error; should delete
725*8975f5c5SAndroid Build Coastguard Worker                                                             // query + 1 at end of execution.
726*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
727*8975f5c5SAndroid Build Coastguard Worker 
728*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
731*8975f5c5SAndroid Build Coastguard Worker 
732*8975f5c5SAndroid Build Coastguard Worker     GLuint ready = GL_FALSE;
733*8975f5c5SAndroid Build Coastguard Worker     glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT,
734*8975f5c5SAndroid Build Coastguard Worker                            &ready);  // this query is now deleted
735*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
736*8975f5c5SAndroid Build Coastguard Worker 
737*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
738*8975f5c5SAndroid Build Coastguard Worker }
739*8975f5c5SAndroid Build Coastguard Worker 
740*8975f5c5SAndroid Build Coastguard Worker // Test that running multiple simultaneous queries from multiple EGL contexts returns the correct
741*8975f5c5SAndroid Build Coastguard Worker // result for each query.  Helps expose bugs in ANGLE's virtual contexts.
TEST_P(OcclusionQueriesTest,MultiContext)742*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, MultiContext)
743*8975f5c5SAndroid Build Coastguard Worker {
744*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
745*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
746*8975f5c5SAndroid Build Coastguard Worker 
747*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): Suppression for http://anglebug.com/42261759
748*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());
749*8975f5c5SAndroid Build Coastguard Worker 
750*8975f5c5SAndroid Build Coastguard Worker     // Test skipped because the D3D backends cannot support simultaneous queries on multiple
751*8975f5c5SAndroid Build Coastguard Worker     // contexts yet.
752*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(GetParam() == ES2_D3D9() || GetParam() == ES2_D3D11() ||
753*8975f5c5SAndroid Build Coastguard Worker                        GetParam() == ES3_D3D11());
754*8975f5c5SAndroid Build Coastguard Worker 
755*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
756*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
757*8975f5c5SAndroid Build Coastguard Worker 
758*8975f5c5SAndroid Build Coastguard Worker     // draw a quad at depth 0.5
759*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
760*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
761*8975f5c5SAndroid Build Coastguard Worker 
762*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window = getEGLWindow();
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
765*8975f5c5SAndroid Build Coastguard Worker     EGLConfig config   = window->getConfig();
766*8975f5c5SAndroid Build Coastguard Worker     EGLSurface surface = window->getSurface();
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker     EGLint contextAttributes[] = {
769*8975f5c5SAndroid Build Coastguard Worker         EGL_CONTEXT_MAJOR_VERSION_KHR,
770*8975f5c5SAndroid Build Coastguard Worker         GetParam().majorVersion,
771*8975f5c5SAndroid Build Coastguard Worker         EGL_CONTEXT_MINOR_VERSION_KHR,
772*8975f5c5SAndroid Build Coastguard Worker         GetParam().minorVersion,
773*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
774*8975f5c5SAndroid Build Coastguard Worker     };
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker     const size_t passCount = 5;
777*8975f5c5SAndroid Build Coastguard Worker     struct ContextInfo
778*8975f5c5SAndroid Build Coastguard Worker     {
779*8975f5c5SAndroid Build Coastguard Worker         EGLContext context;
780*8975f5c5SAndroid Build Coastguard Worker         GLuint program;
781*8975f5c5SAndroid Build Coastguard Worker         GLuint query;
782*8975f5c5SAndroid Build Coastguard Worker         bool visiblePasses[passCount];
783*8975f5c5SAndroid Build Coastguard Worker         bool shouldPass;
784*8975f5c5SAndroid Build Coastguard Worker     };
785*8975f5c5SAndroid Build Coastguard Worker 
786*8975f5c5SAndroid Build Coastguard Worker     ContextInfo contexts[] = {
787*8975f5c5SAndroid Build Coastguard Worker         {
788*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
789*8975f5c5SAndroid Build Coastguard Worker             0,
790*8975f5c5SAndroid Build Coastguard Worker             0,
791*8975f5c5SAndroid Build Coastguard Worker             {false, false, false, false, false},
792*8975f5c5SAndroid Build Coastguard Worker             false,
793*8975f5c5SAndroid Build Coastguard Worker         },
794*8975f5c5SAndroid Build Coastguard Worker         {
795*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
796*8975f5c5SAndroid Build Coastguard Worker             0,
797*8975f5c5SAndroid Build Coastguard Worker             0,
798*8975f5c5SAndroid Build Coastguard Worker             {false, true, false, true, false},
799*8975f5c5SAndroid Build Coastguard Worker             true,
800*8975f5c5SAndroid Build Coastguard Worker         },
801*8975f5c5SAndroid Build Coastguard Worker         {
802*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
803*8975f5c5SAndroid Build Coastguard Worker             0,
804*8975f5c5SAndroid Build Coastguard Worker             0,
805*8975f5c5SAndroid Build Coastguard Worker             {false, false, false, false, false},
806*8975f5c5SAndroid Build Coastguard Worker             false,
807*8975f5c5SAndroid Build Coastguard Worker         },
808*8975f5c5SAndroid Build Coastguard Worker         {
809*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
810*8975f5c5SAndroid Build Coastguard Worker             0,
811*8975f5c5SAndroid Build Coastguard Worker             0,
812*8975f5c5SAndroid Build Coastguard Worker             {true, true, false, true, true},
813*8975f5c5SAndroid Build Coastguard Worker             true,
814*8975f5c5SAndroid Build Coastguard Worker         },
815*8975f5c5SAndroid Build Coastguard Worker         {
816*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
817*8975f5c5SAndroid Build Coastguard Worker             0,
818*8975f5c5SAndroid Build Coastguard Worker             0,
819*8975f5c5SAndroid Build Coastguard Worker             {false, true, true, true, true},
820*8975f5c5SAndroid Build Coastguard Worker             true,
821*8975f5c5SAndroid Build Coastguard Worker         },
822*8975f5c5SAndroid Build Coastguard Worker         {
823*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
824*8975f5c5SAndroid Build Coastguard Worker             0,
825*8975f5c5SAndroid Build Coastguard Worker             0,
826*8975f5c5SAndroid Build Coastguard Worker             {true, false, false, true, false},
827*8975f5c5SAndroid Build Coastguard Worker             true,
828*8975f5c5SAndroid Build Coastguard Worker         },
829*8975f5c5SAndroid Build Coastguard Worker         {
830*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
831*8975f5c5SAndroid Build Coastguard Worker             0,
832*8975f5c5SAndroid Build Coastguard Worker             0,
833*8975f5c5SAndroid Build Coastguard Worker             {false, false, false, false, false},
834*8975f5c5SAndroid Build Coastguard Worker             false,
835*8975f5c5SAndroid Build Coastguard Worker         },
836*8975f5c5SAndroid Build Coastguard Worker         {
837*8975f5c5SAndroid Build Coastguard Worker             EGL_NO_CONTEXT,
838*8975f5c5SAndroid Build Coastguard Worker             0,
839*8975f5c5SAndroid Build Coastguard Worker             0,
840*8975f5c5SAndroid Build Coastguard Worker             {false, false, false, false, false},
841*8975f5c5SAndroid Build Coastguard Worker             false,
842*8975f5c5SAndroid Build Coastguard Worker         },
843*8975f5c5SAndroid Build Coastguard Worker     };
844*8975f5c5SAndroid Build Coastguard Worker 
845*8975f5c5SAndroid Build Coastguard Worker     for (auto &context : contexts)
846*8975f5c5SAndroid Build Coastguard Worker     {
847*8975f5c5SAndroid Build Coastguard Worker         context.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
848*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(context.context, EGL_NO_CONTEXT);
849*8975f5c5SAndroid Build Coastguard Worker 
850*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(display, surface, surface, context.context);
851*8975f5c5SAndroid Build Coastguard Worker 
852*8975f5c5SAndroid Build Coastguard Worker         context.program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
853*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(context.program, 0u);
854*8975f5c5SAndroid Build Coastguard Worker 
855*8975f5c5SAndroid Build Coastguard Worker         glDepthMask(GL_FALSE);
856*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_DEPTH_TEST);
857*8975f5c5SAndroid Build Coastguard Worker 
858*8975f5c5SAndroid Build Coastguard Worker         glGenQueriesEXT(1, &context.query);
859*8975f5c5SAndroid Build Coastguard Worker         glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, context.query);
860*8975f5c5SAndroid Build Coastguard Worker 
861*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
862*8975f5c5SAndroid Build Coastguard Worker     }
863*8975f5c5SAndroid Build Coastguard Worker 
864*8975f5c5SAndroid Build Coastguard Worker     for (size_t pass = 0; pass < passCount; pass++)
865*8975f5c5SAndroid Build Coastguard Worker     {
866*8975f5c5SAndroid Build Coastguard Worker         for (const auto &context : contexts)
867*8975f5c5SAndroid Build Coastguard Worker         {
868*8975f5c5SAndroid Build Coastguard Worker             eglMakeCurrent(display, surface, surface, context.context);
869*8975f5c5SAndroid Build Coastguard Worker 
870*8975f5c5SAndroid Build Coastguard Worker             float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f)
871*8975f5c5SAndroid Build Coastguard Worker                                                       : mRNG.randomFloatBetween(0.6f, 1.0f);
872*8975f5c5SAndroid Build Coastguard Worker             drawQuad(context.program, essl1_shaders::PositionAttrib(), depth);
873*8975f5c5SAndroid Build Coastguard Worker 
874*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
875*8975f5c5SAndroid Build Coastguard Worker         }
876*8975f5c5SAndroid Build Coastguard Worker     }
877*8975f5c5SAndroid Build Coastguard Worker 
878*8975f5c5SAndroid Build Coastguard Worker     for (const auto &context : contexts)
879*8975f5c5SAndroid Build Coastguard Worker     {
880*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(display, surface, surface, context.context);
881*8975f5c5SAndroid Build Coastguard Worker         glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
882*8975f5c5SAndroid Build Coastguard Worker 
883*8975f5c5SAndroid Build Coastguard Worker         GLuint result = GL_TRUE;
884*8975f5c5SAndroid Build Coastguard Worker         glGetQueryObjectuivEXT(context.query, GL_QUERY_RESULT_EXT, &result);
885*8975f5c5SAndroid Build Coastguard Worker 
886*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
887*8975f5c5SAndroid Build Coastguard Worker 
888*8975f5c5SAndroid Build Coastguard Worker         GLuint expectation = context.shouldPass ? GL_TRUE : GL_FALSE;
889*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectation, result);
890*8975f5c5SAndroid Build Coastguard Worker     }
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, surface, surface, window->getContext());
893*8975f5c5SAndroid Build Coastguard Worker 
894*8975f5c5SAndroid Build Coastguard Worker     for (auto &context : contexts)
895*8975f5c5SAndroid Build Coastguard Worker     {
896*8975f5c5SAndroid Build Coastguard Worker         eglDestroyContext(display, context.context);
897*8975f5c5SAndroid Build Coastguard Worker         context.context = EGL_NO_CONTEXT;
898*8975f5c5SAndroid Build Coastguard Worker     }
899*8975f5c5SAndroid Build Coastguard Worker }
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker // Test multiple occlusion queries in flight. This test provoked a bug in the Metal backend that
902*8975f5c5SAndroid Build Coastguard Worker // resulted in an infinite loop when trying to flush the command buffer when the maximum number of
903*8975f5c5SAndroid Build Coastguard Worker // inflight render passes was reached.
TEST_P(OcclusionQueriesTest,ManyQueriesInFlight)904*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesTest, ManyQueriesInFlight)
905*8975f5c5SAndroid Build Coastguard Worker {
906*8975f5c5SAndroid Build Coastguard Worker     constexpr int kManyQueryCount = 100;
907*8975f5c5SAndroid Build Coastguard Worker 
908*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
909*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));
910*8975f5c5SAndroid Build Coastguard Worker 
911*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263499
912*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() || IsD3D11());
913*8975f5c5SAndroid Build Coastguard Worker 
914*8975f5c5SAndroid Build Coastguard Worker     GLQueryEXT query;
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
917*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_TRUE);
918*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
919*8975f5c5SAndroid Build Coastguard Worker 
920*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rbo[2];
921*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
922*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 32, 32);
923*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
924*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 32, 32);
925*8975f5c5SAndroid Build Coastguard Worker 
926*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
927*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
928*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
929*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
930*8975f5c5SAndroid Build Coastguard Worker 
931*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
932*8975f5c5SAndroid Build Coastguard Worker 
933*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
934*8975f5c5SAndroid Build Coastguard Worker 
935*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
936*8975f5c5SAndroid Build Coastguard Worker 
937*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kManyQueryCount; i++)
938*8975f5c5SAndroid Build Coastguard Worker     {
939*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
940*8975f5c5SAndroid Build Coastguard Worker         glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
941*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, essl1_shaders::PositionAttrib(), 1.0f - 2.0f * i / kManyQueryCount);
942*8975f5c5SAndroid Build Coastguard Worker         glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
943*8975f5c5SAndroid Build Coastguard Worker 
944*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
945*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
946*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);
947*8975f5c5SAndroid Build Coastguard Worker     }
948*8975f5c5SAndroid Build Coastguard Worker 
949*8975f5c5SAndroid Build Coastguard Worker     glFinish();
950*8975f5c5SAndroid Build Coastguard Worker 
951*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
952*8975f5c5SAndroid Build Coastguard Worker }
953*8975f5c5SAndroid Build Coastguard Worker 
954*8975f5c5SAndroid Build Coastguard Worker class OcclusionQueriesNoSurfaceTestES3 : public ANGLETestBase,
955*8975f5c5SAndroid Build Coastguard Worker                                          public ::testing::TestWithParam<angle::PlatformParameters>
956*8975f5c5SAndroid Build Coastguard Worker {
957*8975f5c5SAndroid Build Coastguard Worker   protected:
OcclusionQueriesNoSurfaceTestES3()958*8975f5c5SAndroid Build Coastguard Worker     OcclusionQueriesNoSurfaceTestES3()
959*8975f5c5SAndroid Build Coastguard Worker         : ANGLETestBase(GetParam()), mUnusedConfig(0), mUnusedDisplay(nullptr)
960*8975f5c5SAndroid Build Coastguard Worker     {
961*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(kWidth);
962*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(kHeight);
963*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
964*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
965*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
966*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
967*8975f5c5SAndroid Build Coastguard Worker         setDeferContextInit(true);
968*8975f5c5SAndroid Build Coastguard Worker     }
969*8975f5c5SAndroid Build Coastguard Worker 
970*8975f5c5SAndroid Build Coastguard Worker     static constexpr int kWidth  = 300;
971*8975f5c5SAndroid Build Coastguard Worker     static constexpr int kHeight = 300;
972*8975f5c5SAndroid Build Coastguard Worker 
SetUp()973*8975f5c5SAndroid Build Coastguard Worker     void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }
TearDown()974*8975f5c5SAndroid Build Coastguard Worker     void TearDown() override { ANGLETestBase::ANGLETestTearDown(); }
975*8975f5c5SAndroid Build Coastguard Worker 
swapBuffers()976*8975f5c5SAndroid Build Coastguard Worker     void swapBuffers() override {}
977*8975f5c5SAndroid Build Coastguard Worker 
978*8975f5c5SAndroid Build Coastguard Worker     EGLConfig mUnusedConfig;
979*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay mUnusedDisplay;
980*8975f5c5SAndroid Build Coastguard Worker };
981*8975f5c5SAndroid Build Coastguard Worker 
982*8975f5c5SAndroid Build Coastguard Worker // This test provked a bug in the Metal backend that only happened
983*8975f5c5SAndroid Build Coastguard Worker // when there was no surfaces on the EGLContext and a query had
984*8975f5c5SAndroid Build Coastguard Worker // just ended after a draw and then switching to a different
985*8975f5c5SAndroid Build Coastguard Worker // context.
TEST_P(OcclusionQueriesNoSurfaceTestES3,SwitchingContextsWithQuery)986*8975f5c5SAndroid Build Coastguard Worker TEST_P(OcclusionQueriesNoSurfaceTestES3, SwitchingContextsWithQuery)
987*8975f5c5SAndroid Build Coastguard Worker {
988*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window = getEGLWindow();
989*8975f5c5SAndroid Build Coastguard Worker 
990*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
991*8975f5c5SAndroid Build Coastguard Worker     EGLConfig config   = window->getConfig();
992*8975f5c5SAndroid Build Coastguard Worker 
993*8975f5c5SAndroid Build Coastguard Worker     EGLint contextAttributes[] = {
994*8975f5c5SAndroid Build Coastguard Worker         EGL_CONTEXT_MAJOR_VERSION_KHR,
995*8975f5c5SAndroid Build Coastguard Worker         GetParam().majorVersion,
996*8975f5c5SAndroid Build Coastguard Worker         EGL_CONTEXT_MINOR_VERSION_KHR,
997*8975f5c5SAndroid Build Coastguard Worker         GetParam().minorVersion,
998*8975f5c5SAndroid Build Coastguard Worker         EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE,
999*8975f5c5SAndroid Build Coastguard Worker         EGL_TRUE,
1000*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
1001*8975f5c5SAndroid Build Coastguard Worker     };
1002*8975f5c5SAndroid Build Coastguard Worker 
1003*8975f5c5SAndroid Build Coastguard Worker     // The following GL objects are implicitly deleted in
1004*8975f5c5SAndroid Build Coastguard Worker     // ContextInfo's destructor before the EGLContext is manually destroyed
1005*8975f5c5SAndroid Build Coastguard Worker     struct ContextInfo
1006*8975f5c5SAndroid Build Coastguard Worker     {
1007*8975f5c5SAndroid Build Coastguard Worker         EGLContext context;
1008*8975f5c5SAndroid Build Coastguard Worker         GLBuffer buf;
1009*8975f5c5SAndroid Build Coastguard Worker         GLProgram program;
1010*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer fb;
1011*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
1012*8975f5c5SAndroid Build Coastguard Worker         GLQuery query;
1013*8975f5c5SAndroid Build Coastguard Worker     };
1014*8975f5c5SAndroid Build Coastguard Worker 
1015*8975f5c5SAndroid Build Coastguard Worker     // ContextInfo contains objects that clean themselves on destruction.
1016*8975f5c5SAndroid Build Coastguard Worker     // We want these objects to stick around until the test ends.
1017*8975f5c5SAndroid Build Coastguard Worker     std::vector<ContextInfo *> pairs;
1018*8975f5c5SAndroid Build Coastguard Worker 
1019*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 2; ++i)
1020*8975f5c5SAndroid Build Coastguard Worker     {
1021*8975f5c5SAndroid Build Coastguard Worker         ContextInfo *infos[] = {
1022*8975f5c5SAndroid Build Coastguard Worker             new ContextInfo(),
1023*8975f5c5SAndroid Build Coastguard Worker             new ContextInfo(),
1024*8975f5c5SAndroid Build Coastguard Worker         };
1025*8975f5c5SAndroid Build Coastguard Worker 
1026*8975f5c5SAndroid Build Coastguard Worker         for (ContextInfo *pinfo : infos)
1027*8975f5c5SAndroid Build Coastguard Worker         {
1028*8975f5c5SAndroid Build Coastguard Worker             pairs.push_back(pinfo);
1029*8975f5c5SAndroid Build Coastguard Worker             ContextInfo &info = *pinfo;
1030*8975f5c5SAndroid Build Coastguard Worker 
1031*8975f5c5SAndroid Build Coastguard Worker             info.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
1032*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(info.context, EGL_NO_CONTEXT);
1033*8975f5c5SAndroid Build Coastguard Worker 
1034*8975f5c5SAndroid Build Coastguard Worker             // Make context current context with no draw and read surface.
1035*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info.context));
1036*8975f5c5SAndroid Build Coastguard Worker 
1037*8975f5c5SAndroid Build Coastguard Worker             // Create something to draw to.
1038*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, info.fb);
1039*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, info.tex);
1040*8975f5c5SAndroid Build Coastguard Worker             glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
1041*8975f5c5SAndroid Build Coastguard Worker             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, info.tex,
1042*8975f5c5SAndroid Build Coastguard Worker                                    0);
1043*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1044*8975f5c5SAndroid Build Coastguard Worker 
1045*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1046*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
1047*8975f5c5SAndroid Build Coastguard Worker             glFlush();
1048*8975f5c5SAndroid Build Coastguard Worker         }
1049*8975f5c5SAndroid Build Coastguard Worker 
1050*8975f5c5SAndroid Build Coastguard Worker         // Setup an shader and quad buffer
1051*8975f5c5SAndroid Build Coastguard Worker         for (ContextInfo *pinfo : infos)
1052*8975f5c5SAndroid Build Coastguard Worker         {
1053*8975f5c5SAndroid Build Coastguard Worker             ContextInfo &info = *pinfo;
1054*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info.context));
1055*8975f5c5SAndroid Build Coastguard Worker 
1056*8975f5c5SAndroid Build Coastguard Worker             constexpr char kVS[] = R"(
1057*8975f5c5SAndroid Build Coastguard Worker             attribute vec4 position;
1058*8975f5c5SAndroid Build Coastguard Worker             void main() {
1059*8975f5c5SAndroid Build Coastguard Worker               gl_Position = position;
1060*8975f5c5SAndroid Build Coastguard Worker             }
1061*8975f5c5SAndroid Build Coastguard Worker           )";
1062*8975f5c5SAndroid Build Coastguard Worker 
1063*8975f5c5SAndroid Build Coastguard Worker             constexpr char kFS[] = R"(
1064*8975f5c5SAndroid Build Coastguard Worker           precision mediump float;
1065*8975f5c5SAndroid Build Coastguard Worker           void main() {
1066*8975f5c5SAndroid Build Coastguard Worker             gl_FragColor = vec4(1, 0, 0, 1);
1067*8975f5c5SAndroid Build Coastguard Worker           }
1068*8975f5c5SAndroid Build Coastguard Worker           )";
1069*8975f5c5SAndroid Build Coastguard Worker 
1070*8975f5c5SAndroid Build Coastguard Worker             info.program.makeRaster(kVS, kFS);
1071*8975f5c5SAndroid Build Coastguard Worker             glUseProgram(info.program);
1072*8975f5c5SAndroid Build Coastguard Worker 
1073*8975f5c5SAndroid Build Coastguard Worker             constexpr float vertices[] = {
1074*8975f5c5SAndroid Build Coastguard Worker                 -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1075*8975f5c5SAndroid Build Coastguard Worker             };
1076*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, info.buf);
1077*8975f5c5SAndroid Build Coastguard Worker             glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
1078*8975f5c5SAndroid Build Coastguard Worker             glEnableVertexAttribArray(0);
1079*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
1080*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
1081*8975f5c5SAndroid Build Coastguard Worker         }
1082*8975f5c5SAndroid Build Coastguard Worker 
1083*8975f5c5SAndroid Build Coastguard Worker         ContextInfo &info1 = *infos[0];
1084*8975f5c5SAndroid Build Coastguard Worker         ContextInfo &info2 = *infos[1];
1085*8975f5c5SAndroid Build Coastguard Worker 
1086*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
1087*8975f5c5SAndroid Build Coastguard Worker 
1088*8975f5c5SAndroid Build Coastguard Worker         glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, info1.query);
1089*8975f5c5SAndroid Build Coastguard Worker         glFlush();
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
1092*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1093*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
1094*8975f5c5SAndroid Build Coastguard Worker 
1095*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1096*8975f5c5SAndroid Build Coastguard Worker 
1097*8975f5c5SAndroid Build Coastguard Worker         glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
1098*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1099*8975f5c5SAndroid Build Coastguard Worker 
1100*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
1101*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1102*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
1103*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
1104*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
1105*8975f5c5SAndroid Build Coastguard Worker     }
1106*8975f5c5SAndroid Build Coastguard Worker 
1107*8975f5c5SAndroid Build Coastguard Worker     // destroy GL objects on the correct context.
1108*8975f5c5SAndroid Build Coastguard Worker     for (ContextInfo *pinfo : pairs)
1109*8975f5c5SAndroid Build Coastguard Worker     {
1110*8975f5c5SAndroid Build Coastguard Worker         EGLContext context = pinfo->context;
1111*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, nullptr, nullptr, context));
1112*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1113*8975f5c5SAndroid Build Coastguard Worker         delete pinfo;
1114*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1115*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(eglDestroyContext(display, context));
1116*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EGL_SUCCESS();
1117*8975f5c5SAndroid Build Coastguard Worker     }
1118*8975f5c5SAndroid Build Coastguard Worker }
1119*8975f5c5SAndroid Build Coastguard Worker 
1120*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(OcclusionQueriesTest);
1121*8975f5c5SAndroid Build Coastguard Worker 
1122*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OcclusionQueriesTestES3);
1123*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(
1124*8975f5c5SAndroid Build Coastguard Worker     OcclusionQueriesTestES3,
1125*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::PreferSubmitOnAnySamplesPassedQueryEnd));
1126*8975f5c5SAndroid Build Coastguard Worker 
1127*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OcclusionQueriesNoSurfaceTestES3);
1128*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(OcclusionQueriesNoSurfaceTestES3);
1129