• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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