1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // QueryObjectValidation.cpp : Tests between gl.*Query.* functions and interactions with
7 // EGL_CONTEXT_OPENGL_NO_ERROR_KHR
8 #include <gtest/gtest.h>
9
10 #include "test_utils/ANGLETest.h"
11 #include "util/EGLWindow.h"
12 #include "util/test_utils.h"
13
14 namespace angle
15 {
16
17 using QueryObjectTestParams = std::tuple<angle::PlatformParameters, bool>;
18
PrintToStringParamName(const::testing::TestParamInfo<QueryObjectTestParams> & info)19 std::string PrintToStringParamName(const ::testing::TestParamInfo<QueryObjectTestParams> &info)
20 {
21 std::stringstream ss;
22 ss << std::get<0>(info.param);
23 if (std::get<1>(info.param))
24 {
25 ss << "__ValidationDisabled";
26 }
27 else
28 {
29 ss << "__ValidationEnabled";
30 }
31 return ss.str();
32 }
33
34 class QueryObjectTest : public ANGLETest<QueryObjectTestParams>
35 {
36 protected:
QueryObjectTest()37 QueryObjectTest() : mQueryObjectName(0), mQueryResult(false)
38 {
39 setNoErrorEnabled(testing::get<1>(GetParam()));
40 }
41
createQuery()42 void createQuery()
43 {
44 glGenQueries(1, &mQueryObjectName);
45 ASSERT_NE(mQueryObjectName, (GLuint)0u);
46 ASSERT_GL_NO_ERROR();
47 }
48
testSetUp()49 void testSetUp() override { createQuery(); }
50
testTearDown()51 void testTearDown() override
52 {
53 if (mQueryObjectName)
54 {
55 glDeleteQueries(1, &mQueryObjectName);
56 }
57 }
58
59 GLuint mQueryObjectName = 0;
60 GLuint mQueryResult = 0;
61 };
62
63 class QueryObjectTestES32 : public QueryObjectTest
64 {};
65
66 // Test if a generated query is a query before glBeginQuery
TEST_P(QueryObjectTest,QueryObjectIsQuery)67 TEST_P(QueryObjectTest, QueryObjectIsQuery)
68 {
69 GLboolean isQueryResult = glIsQuery(mQueryObjectName);
70 ASSERT_GL_NO_ERROR();
71 ASSERT_FALSE(isQueryResult);
72 }
73
74 // Negative test for glGetQueryObjectuiv before glBegin with GL_QUERY_RESULT
TEST_P(QueryObjectTest,QueryObjectResultBeforeBegin)75 TEST_P(QueryObjectTest, QueryObjectResultBeforeBegin)
76 {
77 glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT, &mQueryResult);
78
79 bool isNoError = testing::get<1>(GetParam());
80 if (isNoError)
81 {
82 ASSERT_GL_NO_ERROR();
83 }
84 else
85 {
86 ASSERT_EQ(glGetError(), (GLenum)GL_INVALID_OPERATION);
87 }
88 }
89
90 // Negative test for glGetQueryObjectuiv before glBegin with GL_QUERY_RESULT_AVAILABLE
TEST_P(QueryObjectTest,QueryObjectResultAvailableBeforeBegin)91 TEST_P(QueryObjectTest, QueryObjectResultAvailableBeforeBegin)
92 {
93 glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
94
95 bool isNoError = testing::get<1>(GetParam());
96 if (isNoError)
97 {
98 ASSERT_GL_NO_ERROR();
99 }
100 else
101 {
102 ASSERT_EQ(glGetError(), (GLenum)GL_INVALID_OPERATION);
103 }
104 }
105
106 // Test glGetQueryObjectuiv after glEndQuery
TEST_P(QueryObjectTest,QueryObjectResultAfterEnd)107 TEST_P(QueryObjectTest, QueryObjectResultAfterEnd)
108 {
109 glBeginQuery(GL_ANY_SAMPLES_PASSED, mQueryObjectName);
110 ASSERT_GL_NO_ERROR();
111
112 glEndQuery(GL_ANY_SAMPLES_PASSED);
113 ASSERT_GL_NO_ERROR();
114
115 glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
116 }
117
118 // Test glGetQueryObjectuiv after glEndQuery with GL_PRIMITIVES_GENERATED
TEST_P(QueryObjectTestES32,QueryObjectResultAfterEndPrimitivesGenerated)119 TEST_P(QueryObjectTestES32, QueryObjectResultAfterEndPrimitivesGenerated)
120 {
121 // TODO(anglebug.com/42263969): Allow GL_PRIMITIVES_GENERATED query objects
122 // when transform feedback is not active
123 ANGLE_SKIP_TEST_IF(IsVulkan());
124 glBeginQuery(GL_PRIMITIVES_GENERATED, mQueryObjectName);
125 ASSERT_GL_NO_ERROR();
126
127 glEndQuery(GL_PRIMITIVES_GENERATED);
128 ASSERT_GL_NO_ERROR();
129
130 while (mQueryResult != GL_TRUE)
131 {
132 glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
133 ASSERT_GL_NO_ERROR();
134 angle::Sleep(50);
135 }
136
137 GLboolean isQueryResult = glIsQuery(mQueryObjectName);
138 ASSERT_GL_NO_ERROR();
139 ASSERT_TRUE(isQueryResult);
140 }
141
142 static const bool noErrorFlags[] = {true, false};
143
144 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(QueryObjectTest);
145 ANGLE_INSTANTIATE_TEST_COMBINE_1(QueryObjectTest,
146 PrintToStringParamName,
147 testing::ValuesIn(noErrorFlags),
148 ANGLE_ALL_TEST_PLATFORMS_ES3);
149
150 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(QueryObjectTestES32);
151 ANGLE_INSTANTIATE_TEST_COMBINE_1(QueryObjectTestES32,
152 PrintToStringParamName,
153 testing::ValuesIn(noErrorFlags),
154 ANGLE_ALL_TEST_PLATFORMS_ES32);
155
156 } // namespace angle
157