1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2018 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 Built-in function tests for uniform constants.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fShaderUniformIntegerFunctionTests.hpp"
25 #include "glsShaderExecUtil.hpp"
26 #include "glwFunctions.hpp"
27 #include "tcuTestLog.hpp"
28 #include <iostream>
29
30 namespace deqp
31 {
32 namespace gles31
33 {
34 namespace Functional
35 {
36
37 using std::vector;
38 using std::string;
39 using tcu::TestLog;
40 using namespace gls::ShaderExecUtil;
41
42 class UniformIntegerFunctionCase : public TestCase
43 {
44 public:
45 UniformIntegerFunctionCase (Context& context, const char* description, int inputValue, glu::Precision precision, glu::ShaderType shaderType);
46 ~UniformIntegerFunctionCase (void);
47
48 void init (void);
49 void deinit (void);
50 IterateResult iterate (void);
51 virtual const char* getFunctionName() = 0;
52 virtual int computeExpectedResult(deInt32 value) = 0;
53
54 protected:
55 UniformIntegerFunctionCase (const UniformIntegerFunctionCase& other);
56 UniformIntegerFunctionCase& operator= (const UniformIntegerFunctionCase& other);
57
58 private:
59 ShaderSpec m_spec;
60 glu::ShaderType m_shaderType;
61 int m_input;
62 int m_value;
63 ShaderExecutor* m_executor;
64 };
65
66 static std::string getCaseName (glu::Precision precision, glu::ShaderType shaderType);
67
UniformIntegerFunctionCase(Context & context,const char * description,int inputValue,glu::Precision precision,glu::ShaderType shaderType)68 UniformIntegerFunctionCase::UniformIntegerFunctionCase(Context& context, const char* description, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
69 : TestCase(context, getCaseName(precision, shaderType).c_str(), description)
70 , m_shaderType(shaderType)
71 , m_input(inputValue)
72 , m_value(0)
73 , m_executor(DE_NULL)
74 {
75 m_spec.version = glu::GLSL_VERSION_310_ES;
76
77 std::ostringstream oss;
78 glu::VarType varType(glu::TYPE_INT, precision);
79 oss << "uniform " << glu::declare(varType, "value", 0) << ";\n";
80 m_spec.globalDeclarations = oss.str();
81 m_spec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_INT, glu::PRECISION_LOWP)));
82 m_spec.outputs.push_back(Symbol("comparison", glu::VarType(glu::TYPE_BOOL, glu::PRECISION_LAST)));
83 }
84
~UniformIntegerFunctionCase(void)85 UniformIntegerFunctionCase::~UniformIntegerFunctionCase(void)
86 {
87 UniformIntegerFunctionCase::deinit();
88 }
89
deinit(void)90 void UniformIntegerFunctionCase::deinit(void)
91 {
92 delete m_executor;
93 m_executor = DE_NULL;
94 }
95
init(void)96 void UniformIntegerFunctionCase::init(void)
97 {
98 std::ostringstream oss;
99 oss <<
100 "result = " << getFunctionName() << "(value);\n"
101 "comparison = (" << getFunctionName() << "(value) == " << computeExpectedResult(m_input) << ");\n";
102 m_spec.source = oss.str();
103
104 DE_ASSERT(!m_executor);
105 m_executor = createExecutor(m_context.getRenderContext(), m_shaderType, m_spec);
106 m_testCtx.getLog() << m_executor;
107
108 if (!m_executor->isOk())
109 throw tcu::TestError("Compile failed");
110
111 m_value = m_context.getRenderContext().getFunctions().getUniformLocation(m_executor->getProgram(), "value");
112 }
113
iterate(void)114 tcu::TestNode::IterateResult UniformIntegerFunctionCase::iterate(void)
115 {
116 deInt32 result;
117 deBool comparison;
118 vector<void*> outputPointers (2);
119
120 outputPointers[0]= &result;
121 outputPointers[1] = &comparison;
122
123 m_executor->useProgram();
124 m_context.getRenderContext().getFunctions().uniform1i(m_value, m_input);
125 m_executor->execute(1, DE_NULL, &outputPointers[0]);
126
127 int expectedResult = computeExpectedResult(m_input);
128 if (result != expectedResult) {
129 m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for " << getFunctionName() << "(" << m_input << ") == " << expectedResult << TestLog::EndMessage;
130 m_testCtx.getLog() << TestLog::Message << "input: " << m_input << TestLog::EndMessage;
131 m_testCtx.getLog() << TestLog::Message << "result: " << result << TestLog::EndMessage;
132 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
133 return STOP;
134 } else if (!comparison) {
135 m_testCtx.getLog() << TestLog::Message << "ERROR: result is as expected, but not when use in condition statement (" << getFunctionName() << "(" << m_input << ") == " << expectedResult << ") == true" << TestLog::EndMessage;
136 m_testCtx.getLog() << TestLog::Message << "input:" << m_input << TestLog::EndMessage;
137 m_testCtx.getLog() << TestLog::Message << "result: " << result << TestLog::EndMessage;
138 m_testCtx.getLog() << TestLog::Message << "comparison: " << comparison << TestLog::EndMessage;
139 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
140 return STOP;
141 }
142 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
143 return STOP;
144 }
145
getCaseName(glu::Precision precision,glu::ShaderType shaderType)146 static std::string getCaseName (glu::Precision precision, glu::ShaderType shaderType)
147 {
148 return string(getPrecisionName(precision)) + getShaderTypePostfix(shaderType);
149 }
150
151 class FindMSBEdgeCase : public UniformIntegerFunctionCase {
152 public:
FindMSBEdgeCase(Context & context,int inputValue,glu::Precision precision,glu::ShaderType shaderType)153 FindMSBEdgeCase(Context& context, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
154 : UniformIntegerFunctionCase(context, "findMSB", inputValue, precision, shaderType)
155 {
156 }
157
158 protected:
getFunctionName()159 const char* getFunctionName() {
160 return "findMSB";
161 }
162
computeExpectedResult(deInt32 input)163 int computeExpectedResult(deInt32 input) {
164 return de::findMSB(input);
165 }
166 };
167
168 class FindLSBEdgeCase : public UniformIntegerFunctionCase {
169 public:
FindLSBEdgeCase(Context & context,int inputValue,glu::Precision precision,glu::ShaderType shaderType)170 FindLSBEdgeCase(Context& context, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
171 : UniformIntegerFunctionCase(context, "findLSB", inputValue, precision, shaderType)
172 {
173 }
174
175 protected:
getFunctionName()176 const char* getFunctionName() {
177 return "findLSB";
178 }
179
computeExpectedResult(deInt32 input)180 int computeExpectedResult(deInt32 input) {
181 return de::findLSB(input);
182 }
183 };
184
185
186 template<class TestClass>
addFunctionCases(TestCaseGroup * parent,const char * functionName,int input)187 static void addFunctionCases (TestCaseGroup* parent, const char* functionName, int input)
188 {
189 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), functionName, functionName);
190 parent->addChild(group);
191 for (int prec = glu::PRECISION_LOWP; prec <= glu::PRECISION_HIGHP; prec++)
192 {
193 for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; shaderTypeNdx++)
194 {
195 if (executorSupported(glu::ShaderType(shaderTypeNdx)))
196 {
197 group->addChild(new TestClass(parent->getContext(), input, glu::Precision(prec), glu::ShaderType(shaderTypeNdx)));
198 }
199 }
200 }
201 }
202
ShaderUniformIntegerFunctionTests(Context & context)203 ShaderUniformIntegerFunctionTests::ShaderUniformIntegerFunctionTests(Context& context)
204 : TestCaseGroup(context, "uniform", "Function on uniform")
205 {
206 }
207
~ShaderUniformIntegerFunctionTests()208 ShaderUniformIntegerFunctionTests::~ShaderUniformIntegerFunctionTests()
209 {
210 }
init()211 void ShaderUniformIntegerFunctionTests::init()
212 {
213 addFunctionCases<FindMSBEdgeCase>(this, "findMSBZero", 0);
214 addFunctionCases<FindMSBEdgeCase>(this, "findMSBMinusOne", -1);
215 addFunctionCases<FindLSBEdgeCase>(this, "findLSBZero", 0);
216 addFunctionCases<FindLSBEdgeCase>(this, "findLSBMinusOne", -1);
217 }
218
219 }
220 }
221 }
222