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