xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fLightAmountTest.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.0 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 Light amount test.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es2fLightAmountTest.hpp"
25 #include "tcuStringTemplate.hpp"
26 #include "gluDefs.hpp"
27 #include "gluShaderProgram.hpp"
28 #include "tcuTestLog.hpp"
29 #include "deStringUtil.hpp"
30 #include "deInt32.h"
31 #include "deRandom.h"
32 
33 #include <stdio.h>
34 #include <vector>
35 
36 #include "glw.h"
37 
38 using namespace std;
39 
40 namespace deqp
41 {
42 namespace gles2
43 {
44 namespace Functional
45 {
46 
47 const char *s_noLightsVertexShader = "uniform mat4 u_modelviewMatrix;\n"
48                                      "uniform mat4 u_modelviewProjectionMatrix;\n"
49                                      "uniform mat3 u_normalMatrix;\n"
50                                      "\n"
51                                      "attribute vec4 a_position;\n"
52                                      "attribute vec3 a_normal;\n"
53                                      "\n"
54                                      "varying vec3 v_color;\n"
55                                      "\n"
56                                      "void main()\n"
57                                      "{\n"
58                                      "    v_color = vec3(0.0);\n"
59                                      "    gl_Position = u_modelviewProjectionMatrix * a_position;\n"
60                                      "}\n";
61 
62 const char *s_vertexShaderTemplate =
63     "struct Light\n"
64     "{\n"
65     "    vec3    position;\n"
66     "    vec3    diffuse;\n"
67     "    vec3    specular;\n"
68     "    vec3    attenuation;\n"
69     "};\n"
70     "uniform Light u_lights[${NUM_DIR_LIGHTS} + ${NUM_OMNI_LIGHTS}];\n"
71     "uniform mat4 u_modelviewMatrix;\n"
72     "uniform mat4 u_modelviewProjectionMatrix;\n"
73     "uniform mat3 u_normalMatrix;\n"
74     "\n"
75     "attribute vec4 a_position;\n"
76     "attribute vec3 a_normal;\n"
77     "\n"
78     "varying vec3 v_color;\n"
79     "\n"
80     "float computeAttenuation(vec3 dirToLight, vec3 attenuation)\n"
81     "{\n"
82     "    float dist = length(dirToLight);\n"
83     "    return 1.0 / (attenuation.x + attenuation.y*dist + attenuation.z*dist*dist);\n"
84     "}\n"
85     "\n"
86     "vec3 computeDirLight(int ndx, vec3 position, vec3 normal)\n"
87     "{\n"
88     "    Light light = u_lights[ndx];\n"
89     "    float cosAngle = dot(light.position, normal);\n"
90     "    return cosAngle * light.diffuse;\n"
91     "}\n"
92     "\n"
93     "vec3 computeOmniLight(int ndx, vec3 position, vec3 normal)\n"
94     "{\n"
95     "    Light light = u_lights[ndx];\n"
96     "    vec3 dirToLight = light.position - position;\n"
97     "    float cosAngle = dot(normalize(dirToLight), normal);\n"
98     "    float atten = computeAttenuation(dirToLight, light.attenuation);\n"
99     "    return atten * cosAngle * light.diffuse;\n"
100     "}\n"
101     "\n"
102     "void main()\n"
103     "{\n"
104     "    vec3 lightSpacePos = vec3(u_modelviewMatrix * a_position);\n"
105     "    vec3 lightNormal = normalize(u_normalMatrix * a_normal);\n"
106     "    vec3 color = vec3(0.0);\n"
107     "    for (int i = 0; i < ${NUM_DIR_LIGHTS}; i++)\n"
108     "        color += computeDirLight(i, lightSpacePos, lightNormal);\n"
109     "    for (int i = 0; i < ${NUM_OMNI_LIGHTS}; i++)\n"
110     "        color += computeOmniLight(${NUM_DIR_LIGHTS}+i, lightSpacePos, lightNormal);\n"
111     "    v_color = color;\n"
112     "    gl_Position = u_modelviewProjectionMatrix * a_position;\n"
113     "}\n";
114 
115 const char *s_fragmentShaderTemplate = "varying highp vec3 v_color;\n"
116                                        "\n"
117                                        "void main()\n"
118                                        "{\n"
119                                        "    gl_FragColor = vec4(v_color, 1.0);\n"
120                                        "}\n";
121 
122 class LightAmountCase : public TestCase
123 {
124 public:
LightAmountCase(Context & context,const char * name,int numDirectionalLights,int numOmniLights,int numSpotLights)125     LightAmountCase(Context &context, const char *name, int numDirectionalLights, int numOmniLights, int numSpotLights)
126         : TestCase(context, name, name)
127         , m_numDirectionalLights(numDirectionalLights)
128         , m_numOmniLights(numOmniLights)
129         , m_numSpotLights(numSpotLights)
130     {
131     }
132 
133     virtual IterateResult iterate(void);
134 
135 private:
136     int m_numDirectionalLights;
137     int m_numOmniLights;
138     int m_numSpotLights;
139 };
140 
iterate(void)141 TestCase::IterateResult LightAmountCase::iterate(void)
142 {
143     GLU_CHECK_MSG("LightAmountTest::iterate() begin");
144 
145     string vertexShaderSource;
146     string fragmentShaderSource;
147 
148     // Fill in shader template parameters.
149     {
150         bool hasAnyLights = ((m_numDirectionalLights + m_numOmniLights + m_numSpotLights) != 0);
151 
152         tcu::StringTemplate vertexTemplate(hasAnyLights ? s_vertexShaderTemplate : s_noLightsVertexShader);
153         tcu::StringTemplate fragmentTemplate(s_fragmentShaderTemplate);
154 
155         map<string, string> params;
156         params.insert(pair<string, string>("NUM_DIR_LIGHTS", de::toString(m_numDirectionalLights)));
157         params.insert(pair<string, string>("NUM_OMNI_LIGHTS", de::toString(m_numOmniLights)));
158         params.insert(pair<string, string>("NUM_SPOT_LIGHTS", de::toString(m_numSpotLights)));
159 
160         vertexShaderSource   = vertexTemplate.specialize(params);
161         fragmentShaderSource = fragmentTemplate.specialize(params);
162     }
163 
164     // Create shader and program objects.
165     glu::ShaderProgram program(m_context.getRenderContext(),
166                                glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
167     m_testCtx.getLog() << program;
168 
169     // Draw something? Check results?
170     glUseProgram(program.getProgram());
171 
172     bool testOk = program.isOk();
173 
174     GLU_CHECK_MSG("LightAmountTest::iterate() end");
175 
176     m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, testOk ? "Pass" : "Fail");
177     return TestCase::STOP;
178 }
179 
180 //
181 
LightAmountTest(Context & context)182 LightAmountTest::LightAmountTest(Context &context) : TestCaseGroup(context, "light_amount", "Light Amount Stress Tests")
183 {
184 }
185 
~LightAmountTest(void)186 LightAmountTest::~LightAmountTest(void)
187 {
188 }
189 
init(void)190 void LightAmountTest::init(void)
191 {
192     //                                        name                dir, omni, spot
193     addChild(new LightAmountCase(m_context, "none", 0, 0, 0));
194     addChild(new LightAmountCase(m_context, "1dir", 1, 0, 0));
195     addChild(new LightAmountCase(m_context, "2dir", 2, 0, 0));
196     addChild(new LightAmountCase(m_context, "4dir", 4, 0, 0));
197     addChild(new LightAmountCase(m_context, "6dir", 6, 0, 0));
198     addChild(new LightAmountCase(m_context, "8dir", 8, 0, 0));
199     addChild(new LightAmountCase(m_context, "10dir", 10, 0, 0));
200     addChild(new LightAmountCase(m_context, "12dir", 12, 0, 0));
201     addChild(new LightAmountCase(m_context, "14dir", 14, 0, 0));
202     addChild(new LightAmountCase(m_context, "16dir", 16, 0, 0));
203     addChild(new LightAmountCase(m_context, "1omni", 0, 1, 0));
204     addChild(new LightAmountCase(m_context, "2omni", 0, 2, 0));
205     addChild(new LightAmountCase(m_context, "4omni", 0, 4, 0));
206     addChild(new LightAmountCase(m_context, "6omni", 0, 6, 0));
207     addChild(new LightAmountCase(m_context, "8omni", 0, 8, 0));
208     addChild(new LightAmountCase(m_context, "10omni", 0, 10, 0));
209     addChild(new LightAmountCase(m_context, "12omni", 0, 12, 0));
210     addChild(new LightAmountCase(m_context, "14omni", 0, 14, 0));
211     addChild(new LightAmountCase(m_context, "16omni", 0, 16, 0));
212     // addChild(new LightAmountCase(m_context, "1spot", 0, 0, 1 ));
213     // addChild(new LightAmountCase(m_context, "2spot", 0, 0, 2 ));
214     // addChild(new LightAmountCase(m_context, "4spot", 0, 0, 4 ));
215     // addChild(new LightAmountCase(m_context, "6spot", 0, 0, 6 ));
216     // addChild(new LightAmountCase(m_context, "8spot", 0, 0, 8 ));
217     // addChild(new LightAmountCase(m_context, "1dir_1omni", 1, 1, 0 ));
218     // addChild(new LightAmountCase(m_context, "2dir_2omni", 2, 2, 0 ));
219     // addChild(new LightAmountCase(m_context, "4dir_4omni", 4, 4, 0 ));
220     // addChild(new LightAmountCase(m_context, "1dir_1spot", 1, 0, 1 ));
221     // addChild(new LightAmountCase(m_context, "2dir_2spot", 2, 0, 2 ));
222     // addChild(new LightAmountCase(m_context, "4dir_4spot", 4, 0, 4 ));
223     // addChild(new LightAmountCase(m_context, "1omni_1spot", 0, 1, 1 ));
224     // addChild(new LightAmountCase(m_context, "2omni_2spot", 0, 2, 2 ));
225     // addChild(new LightAmountCase(m_context, "4omni_4spot", 0, 4, 4 ));
226     // addChild(new LightAmountCase(m_context, "1dir_1omni_1spot", 1, 1, 1 ));
227     // addChild(new LightAmountCase(m_context, "2dir_2omni_2spot", 2, 2, 2 ));
228     // addChild(new LightAmountCase(m_context, "4dir_2omni_2spot", 4, 2, 2 ));
229     // addChild(new LightAmountCase(m_context, "2dir_4omni_2spot", 2, 4, 2 ));
230     // addChild(new LightAmountCase(m_context, "2dir_2omni_4spot", 2, 2, 4 ));
231     // addChild(new LightAmountCase(m_context, "4dir_4omni_4spot", 4, 4, 4 ));
232 }
233 
234 } // namespace Functional
235 } // namespace gles2
236 } // namespace deqp
237