1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Multisample interpolation state query tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fShaderMultisampleInterpolationStateQueryTests.hpp"
25 #include "tcuTestLog.hpp"
26 #include "gluCallLogWrapper.hpp"
27 #include "gluContextInfo.hpp"
28 #include "gluRenderContext.hpp"
29 #include "glsStateQueryUtil.hpp"
30 #include "glwEnums.hpp"
31 #include "glwFunctions.hpp"
32 
33 namespace deqp
34 {
35 namespace gles31
36 {
37 namespace Functional
38 {
39 namespace
40 {
41 
42 using namespace gls::StateQueryUtil;
43 
44 class InterpolationOffsetCase : public TestCase
45 {
46 public:
47     enum TestType
48     {
49         TEST_MIN_OFFSET = 0,
50         TEST_MAX_OFFSET,
51 
52         TEST_LAST
53     };
54 
55     InterpolationOffsetCase(Context &context, const char *name, const char *desc, QueryType verifier,
56                             TestType testType);
57     ~InterpolationOffsetCase(void);
58 
59     void init(void);
60     IterateResult iterate(void);
61 
62 private:
63     const QueryType m_verifier;
64     const TestType m_testType;
65 };
66 
InterpolationOffsetCase(Context & context,const char * name,const char * desc,QueryType verifier,TestType testType)67 InterpolationOffsetCase::InterpolationOffsetCase(Context &context, const char *name, const char *desc,
68                                                  QueryType verifier, TestType testType)
69     : TestCase(context, name, desc)
70     , m_verifier(verifier)
71     , m_testType(testType)
72 {
73     DE_ASSERT(m_testType < TEST_LAST);
74 }
75 
~InterpolationOffsetCase(void)76 InterpolationOffsetCase::~InterpolationOffsetCase(void)
77 {
78 }
79 
init(void)80 void InterpolationOffsetCase::init(void)
81 {
82     auto ctxType            = m_context.getRenderContext().getType();
83     const bool isES32orGL45 = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
84                               glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
85 
86     if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
87         throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
88 }
89 
iterate(void)90 InterpolationOffsetCase::IterateResult InterpolationOffsetCase::iterate(void)
91 {
92     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
93     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
94     gl.enableLogging(true);
95 
96     if (m_testType == TEST_MAX_OFFSET)
97     {
98         glw::GLfloat fragmentInterpolationOffsetBits = 0.0;
99         gl.glGetFloatv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
100         GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
101 
102         glw::GLfloat ULP = 1.0f / powf(2, fragmentInterpolationOffsetBits);
103 
104         verifyStateFloatMin(result, gl, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 0.5f - ULP, m_verifier);
105     }
106     else if (m_testType == TEST_MIN_OFFSET)
107         verifyStateFloatMax(result, gl, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, -0.5f, m_verifier);
108     else
109         DE_ASSERT(false);
110 
111     result.setTestContextResult(m_testCtx);
112     return STOP;
113 }
114 
115 class FragmentInterpolationOffsetBitsCase : public TestCase
116 {
117 public:
118     FragmentInterpolationOffsetBitsCase(Context &context, const char *name, const char *desc, QueryType verifier);
119     ~FragmentInterpolationOffsetBitsCase(void);
120 
121     void init(void);
122     IterateResult iterate(void);
123 
124 private:
125     const QueryType m_verifier;
126 };
127 
FragmentInterpolationOffsetBitsCase(Context & context,const char * name,const char * desc,QueryType verifier)128 FragmentInterpolationOffsetBitsCase::FragmentInterpolationOffsetBitsCase(Context &context, const char *name,
129                                                                          const char *desc, QueryType verifier)
130     : TestCase(context, name, desc)
131     , m_verifier(verifier)
132 {
133 }
134 
~FragmentInterpolationOffsetBitsCase(void)135 FragmentInterpolationOffsetBitsCase::~FragmentInterpolationOffsetBitsCase(void)
136 {
137 }
138 
init(void)139 void FragmentInterpolationOffsetBitsCase::init(void)
140 {
141     auto ctxType            = m_context.getRenderContext().getType();
142     const bool isES32orGL45 = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
143                               glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
144 
145     if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
146         throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
147 }
148 
iterate(void)149 FragmentInterpolationOffsetBitsCase::IterateResult FragmentInterpolationOffsetBitsCase::iterate(void)
150 {
151     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
152     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
153     gl.enableLogging(true);
154 
155     verifyStateIntegerMin(result, gl, GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, 4, m_verifier);
156 
157     result.setTestContextResult(m_testCtx);
158     return STOP;
159 }
160 
161 } // namespace
162 
ShaderMultisampleInterpolationStateQueryTests(Context & context)163 ShaderMultisampleInterpolationStateQueryTests::ShaderMultisampleInterpolationStateQueryTests(Context &context)
164     : TestCaseGroup(context, "multisample_interpolation", "Test multisample interpolation states")
165 {
166 }
167 
~ShaderMultisampleInterpolationStateQueryTests(void)168 ShaderMultisampleInterpolationStateQueryTests::~ShaderMultisampleInterpolationStateQueryTests(void)
169 {
170 }
171 
init(void)172 void ShaderMultisampleInterpolationStateQueryTests::init(void)
173 {
174     static const struct Verifier
175     {
176         QueryType verifier;
177         const char *name;
178         const char *desc;
179     } verifiers[] = {
180         {QUERY_BOOLEAN, "get_boolean", "Test using getBoolean"},
181         {QUERY_INTEGER, "get_integer", "Test using getInteger"},
182         {QUERY_FLOAT, "get_float", "Test using getFloat"},
183         {QUERY_INTEGER64, "get_integer64", "Test using getInteger64"},
184     };
185 
186     // .min_fragment_interpolation_offset
187     {
188         tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "min_fragment_interpolation_offset",
189                                                                  "Test MIN_FRAGMENT_INTERPOLATION_OFFSET");
190         addChild(group);
191 
192         for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
193             group->addChild(new InterpolationOffsetCase(m_context, verifiers[verifierNdx].name,
194                                                         verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier,
195                                                         InterpolationOffsetCase::TEST_MIN_OFFSET));
196     }
197 
198     // .max_fragment_interpolation_offset
199     {
200         tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "max_fragment_interpolation_offset",
201                                                                  "Test MAX_FRAGMENT_INTERPOLATION_OFFSET");
202         addChild(group);
203 
204         for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
205             group->addChild(new InterpolationOffsetCase(m_context, verifiers[verifierNdx].name,
206                                                         verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier,
207                                                         InterpolationOffsetCase::TEST_MAX_OFFSET));
208     }
209 
210     // .fragment_interpolation_offset_bits
211     {
212         tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "fragment_interpolation_offset_bits",
213                                                                  "Test FRAGMENT_INTERPOLATION_OFFSET_BITS");
214         addChild(group);
215 
216         for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
217             group->addChild(new FragmentInterpolationOffsetBitsCase(
218                 m_context, verifiers[verifierNdx].name, verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier));
219     }
220 }
221 
222 } // namespace Functional
223 } // namespace gles31
224 } // namespace deqp
225