xref: /aosp_15_r20/external/deqp/modules/glshared/glsRandomShaderCase.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL (ES) Module
3*35238bceSAndroid Build Coastguard Worker  * -----------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Random shader test case.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "glsRandomShaderCase.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker #include "rsgProgramGenerator.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "rsgProgramExecutor.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker #include "glw.h"
45*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker using std::map;
48*35238bceSAndroid Build Coastguard Worker using std::pair;
49*35238bceSAndroid Build Coastguard Worker using std::string;
50*35238bceSAndroid Build Coastguard Worker using std::vector;
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker namespace deqp
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace gls
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker enum
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker     VIEWPORT_WIDTH  = 64,
60*35238bceSAndroid Build Coastguard Worker     VIEWPORT_HEIGHT = 64,
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker     TEXTURE_2D_WIDTH     = 64,
63*35238bceSAndroid Build Coastguard Worker     TEXTURE_2D_HEIGHT    = 64,
64*35238bceSAndroid Build Coastguard Worker     TEXTURE_2D_FORMAT    = GL_RGBA,
65*35238bceSAndroid Build Coastguard Worker     TEXTURE_2D_DATA_TYPE = GL_UNSIGNED_BYTE,
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker     TEXTURE_CUBE_SIZE      = 16,
68*35238bceSAndroid Build Coastguard Worker     TEXTURE_CUBE_FORMAT    = GL_RGBA,
69*35238bceSAndroid Build Coastguard Worker     TEXTURE_CUBE_DATA_TYPE = GL_UNSIGNED_BYTE,
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker     TEXTURE_WRAP_S = GL_CLAMP_TO_EDGE,
72*35238bceSAndroid Build Coastguard Worker     TEXTURE_WRAP_T = GL_CLAMP_TO_EDGE,
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker     TEXTURE_MIN_FILTER = GL_LINEAR,
75*35238bceSAndroid Build Coastguard Worker     TEXTURE_MAG_FILTER = GL_LINEAR
76*35238bceSAndroid Build Coastguard Worker };
77*35238bceSAndroid Build Coastguard Worker 
VertexArray(const rsg::ShaderInput * input,int numVertices)78*35238bceSAndroid Build Coastguard Worker VertexArray::VertexArray(const rsg::ShaderInput *input, int numVertices)
79*35238bceSAndroid Build Coastguard Worker     : m_input(input)
80*35238bceSAndroid Build Coastguard Worker     , m_vertices(input->getVariable()->getType().getNumElements() * numVertices)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker 
TextureManager(void)84*35238bceSAndroid Build Coastguard Worker TextureManager::TextureManager(void)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker 
~TextureManager(void)88*35238bceSAndroid Build Coastguard Worker TextureManager::~TextureManager(void)
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker 
bindTexture(int unit,const glu::Texture2D * tex2D)92*35238bceSAndroid Build Coastguard Worker void TextureManager::bindTexture(int unit, const glu::Texture2D *tex2D)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker     m_tex2D[unit] = tex2D;
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker 
bindTexture(int unit,const glu::TextureCube * texCube)97*35238bceSAndroid Build Coastguard Worker void TextureManager::bindTexture(int unit, const glu::TextureCube *texCube)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker     m_texCube[unit] = texCube;
100*35238bceSAndroid Build Coastguard Worker }
101*35238bceSAndroid Build Coastguard Worker 
getBindings2D(void) const102*35238bceSAndroid Build Coastguard Worker inline vector<pair<int, const glu::Texture2D *>> TextureManager::getBindings2D(void) const
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker     vector<pair<int, const glu::Texture2D *>> bindings;
105*35238bceSAndroid Build Coastguard Worker     for (map<int, const glu::Texture2D *>::const_iterator i = m_tex2D.begin(); i != m_tex2D.end(); i++)
106*35238bceSAndroid Build Coastguard Worker         bindings.push_back(*i);
107*35238bceSAndroid Build Coastguard Worker     return bindings;
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker 
getBindingsCube(void) const110*35238bceSAndroid Build Coastguard Worker inline vector<pair<int, const glu::TextureCube *>> TextureManager::getBindingsCube(void) const
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker     vector<pair<int, const glu::TextureCube *>> bindings;
113*35238bceSAndroid Build Coastguard Worker     for (map<int, const glu::TextureCube *>::const_iterator i = m_texCube.begin(); i != m_texCube.end(); i++)
114*35238bceSAndroid Build Coastguard Worker         bindings.push_back(*i);
115*35238bceSAndroid Build Coastguard Worker     return bindings;
116*35238bceSAndroid Build Coastguard Worker }
117*35238bceSAndroid Build Coastguard Worker 
RandomShaderCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,const rsg::ProgramParameters & params)118*35238bceSAndroid Build Coastguard Worker RandomShaderCase::RandomShaderCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
119*35238bceSAndroid Build Coastguard Worker                                    const char *description, const rsg::ProgramParameters &params)
120*35238bceSAndroid Build Coastguard Worker     : tcu::TestCase(testCtx, name, description)
121*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
122*35238bceSAndroid Build Coastguard Worker     , m_parameters(params)
123*35238bceSAndroid Build Coastguard Worker     , m_gridWidth(1)
124*35238bceSAndroid Build Coastguard Worker     , m_gridHeight(1)
125*35238bceSAndroid Build Coastguard Worker     , m_vertexShader(rsg::Shader::TYPE_VERTEX)
126*35238bceSAndroid Build Coastguard Worker     , m_fragmentShader(rsg::Shader::TYPE_FRAGMENT)
127*35238bceSAndroid Build Coastguard Worker     , m_tex2D(DE_NULL)
128*35238bceSAndroid Build Coastguard Worker     , m_texCube(DE_NULL)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker }
131*35238bceSAndroid Build Coastguard Worker 
~RandomShaderCase(void)132*35238bceSAndroid Build Coastguard Worker RandomShaderCase::~RandomShaderCase(void)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker     delete m_tex2D;
135*35238bceSAndroid Build Coastguard Worker     delete m_texCube;
136*35238bceSAndroid Build Coastguard Worker }
137*35238bceSAndroid Build Coastguard Worker 
init(void)138*35238bceSAndroid Build Coastguard Worker void RandomShaderCase::init(void)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker     // Generate shaders
141*35238bceSAndroid Build Coastguard Worker     rsg::ProgramGenerator programGenerator;
142*35238bceSAndroid Build Coastguard Worker     programGenerator.generate(m_parameters, m_vertexShader, m_fragmentShader);
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker     checkShaderLimits(m_vertexShader);
145*35238bceSAndroid Build Coastguard Worker     checkShaderLimits(m_fragmentShader);
146*35238bceSAndroid Build Coastguard Worker     checkProgramLimits(m_vertexShader, m_fragmentShader);
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker     // Compute uniform values
149*35238bceSAndroid Build Coastguard Worker     std::vector<const rsg::ShaderInput *> unifiedUniforms;
150*35238bceSAndroid Build Coastguard Worker     de::Random rnd(m_parameters.seed);
151*35238bceSAndroid Build Coastguard Worker     rsg::computeUnifiedUniforms(m_vertexShader, m_fragmentShader, unifiedUniforms);
152*35238bceSAndroid Build Coastguard Worker     rsg::computeUniformValues(rnd, m_uniforms, unifiedUniforms);
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker     // Generate vertices
155*35238bceSAndroid Build Coastguard Worker     const vector<rsg::ShaderInput *> &inputs = m_vertexShader.getInputs();
156*35238bceSAndroid Build Coastguard Worker     int numVertices                          = (m_gridWidth + 1) * (m_gridHeight + 1);
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::ShaderInput *>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
159*35238bceSAndroid Build Coastguard Worker     {
160*35238bceSAndroid Build Coastguard Worker         const rsg::ShaderInput *input         = *i;
161*35238bceSAndroid Build Coastguard Worker         rsg::ConstValueRangeAccess valueRange = input->getValueRange();
162*35238bceSAndroid Build Coastguard Worker         int numComponents                     = input->getVariable()->getType().getNumElements();
163*35238bceSAndroid Build Coastguard Worker         VertexArray vtxArray(input, numVertices);
164*35238bceSAndroid Build Coastguard Worker         bool isPosition = string(input->getVariable()->getName()) == "dEQP_Position";
165*35238bceSAndroid Build Coastguard Worker 
166*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(input->getVariable()->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT);
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker         for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
169*35238bceSAndroid Build Coastguard Worker         {
170*35238bceSAndroid Build Coastguard Worker             int y      = vtxNdx / (m_gridWidth + 1);
171*35238bceSAndroid Build Coastguard Worker             int x      = vtxNdx - y * (m_gridWidth + 1);
172*35238bceSAndroid Build Coastguard Worker             float xf   = (float)x / (float)m_gridWidth;
173*35238bceSAndroid Build Coastguard Worker             float yf   = (float)y / (float)m_gridHeight;
174*35238bceSAndroid Build Coastguard Worker             float *dst = &vtxArray.getVertices()[vtxNdx * numComponents];
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker             if (isPosition)
177*35238bceSAndroid Build Coastguard Worker             {
178*35238bceSAndroid Build Coastguard Worker                 // Position attribute gets special interpolation handling.
179*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(numComponents == 4);
180*35238bceSAndroid Build Coastguard Worker                 dst[0] = -1.0f + xf * 2.0f;
181*35238bceSAndroid Build Coastguard Worker                 dst[1] = 1.0f + yf * -2.0f;
182*35238bceSAndroid Build Coastguard Worker                 dst[2] = 0.0f;
183*35238bceSAndroid Build Coastguard Worker                 dst[3] = 1.0f;
184*35238bceSAndroid Build Coastguard Worker             }
185*35238bceSAndroid Build Coastguard Worker             else
186*35238bceSAndroid Build Coastguard Worker             {
187*35238bceSAndroid Build Coastguard Worker                 for (int compNdx = 0; compNdx < numComponents; compNdx++)
188*35238bceSAndroid Build Coastguard Worker                 {
189*35238bceSAndroid Build Coastguard Worker                     float minVal = valueRange.getMin().component(compNdx).asFloat();
190*35238bceSAndroid Build Coastguard Worker                     float maxVal = valueRange.getMax().component(compNdx).asFloat();
191*35238bceSAndroid Build Coastguard Worker                     float xd, yd;
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker                     rsg::getVertexInterpolationCoords(xd, yd, xf, yf, compNdx);
194*35238bceSAndroid Build Coastguard Worker 
195*35238bceSAndroid Build Coastguard Worker                     float f = (xd + yd) / 2.0f;
196*35238bceSAndroid Build Coastguard Worker 
197*35238bceSAndroid Build Coastguard Worker                     dst[compNdx] = minVal + f * (maxVal - minVal);
198*35238bceSAndroid Build Coastguard Worker                 }
199*35238bceSAndroid Build Coastguard Worker             }
200*35238bceSAndroid Build Coastguard Worker         }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker         m_vertexArrays.push_back(vtxArray);
203*35238bceSAndroid Build Coastguard Worker     }
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker     // Generate indices
206*35238bceSAndroid Build Coastguard Worker     int numQuads   = m_gridWidth * m_gridHeight;
207*35238bceSAndroid Build Coastguard Worker     int numIndices = numQuads * 6;
208*35238bceSAndroid Build Coastguard Worker     m_indices.resize(numIndices);
209*35238bceSAndroid Build Coastguard Worker     for (int quadNdx = 0; quadNdx < numQuads; quadNdx++)
210*35238bceSAndroid Build Coastguard Worker     {
211*35238bceSAndroid Build Coastguard Worker         int quadY = quadNdx / (m_gridWidth);
212*35238bceSAndroid Build Coastguard Worker         int quadX = quadNdx - quadY * m_gridWidth;
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 0] = (uint16_t)(quadX + quadY * (m_gridWidth + 1));
215*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 1] = (uint16_t)(quadX + (quadY + 1) * (m_gridWidth + 1));
216*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 2] = (uint16_t)(quadX + quadY * (m_gridWidth + 1) + 1);
217*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 3] = (uint16_t)(m_indices[quadNdx * 6 + 2]);
218*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 4] = (uint16_t)(m_indices[quadNdx * 6 + 1]);
219*35238bceSAndroid Build Coastguard Worker         m_indices[quadNdx * 6 + 5] = (uint16_t)(quadX + (quadY + 1) * (m_gridWidth + 1) + 1);
220*35238bceSAndroid Build Coastguard Worker     }
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker     // Create textures.
223*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::VariableValue>::const_iterator uniformIter = m_uniforms.begin(); uniformIter != m_uniforms.end();
224*35238bceSAndroid Build Coastguard Worker          uniformIter++)
225*35238bceSAndroid Build Coastguard Worker     {
226*35238bceSAndroid Build Coastguard Worker         const rsg::VariableType &type = uniformIter->getVariable()->getType();
227*35238bceSAndroid Build Coastguard Worker 
228*35238bceSAndroid Build Coastguard Worker         if (!type.isSampler())
229*35238bceSAndroid Build Coastguard Worker             continue;
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker         int unitNdx = uniformIter->getValue().asInt(0);
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker         if (type == rsg::VariableType(rsg::VariableType::TYPE_SAMPLER_2D, 1))
234*35238bceSAndroid Build Coastguard Worker             m_texManager.bindTexture(unitNdx, getTex2D());
235*35238bceSAndroid Build Coastguard Worker         else if (type == rsg::VariableType(rsg::VariableType::TYPE_SAMPLER_CUBE, 1))
236*35238bceSAndroid Build Coastguard Worker             m_texManager.bindTexture(unitNdx, getTexCube());
237*35238bceSAndroid Build Coastguard Worker         else
238*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
239*35238bceSAndroid Build Coastguard Worker     }
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker 
getNumSamplerUniforms(const std::vector<rsg::ShaderInput * > & uniforms)242*35238bceSAndroid Build Coastguard Worker static int getNumSamplerUniforms(const std::vector<rsg::ShaderInput *> &uniforms)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker     int numSamplers = 0;
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker     for (std::vector<rsg::ShaderInput *>::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
247*35238bceSAndroid Build Coastguard Worker     {
248*35238bceSAndroid Build Coastguard Worker         if ((*it)->getVariable()->getType().isSampler())
249*35238bceSAndroid Build Coastguard Worker             ++numSamplers;
250*35238bceSAndroid Build Coastguard Worker     }
251*35238bceSAndroid Build Coastguard Worker 
252*35238bceSAndroid Build Coastguard Worker     return numSamplers;
253*35238bceSAndroid Build Coastguard Worker }
254*35238bceSAndroid Build Coastguard Worker 
checkShaderLimits(const rsg::Shader & shader) const255*35238bceSAndroid Build Coastguard Worker void RandomShaderCase::checkShaderLimits(const rsg::Shader &shader) const
256*35238bceSAndroid Build Coastguard Worker {
257*35238bceSAndroid Build Coastguard Worker     const int numRequiredSamplers = getNumSamplerUniforms(shader.getUniforms());
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker     if (numRequiredSamplers > 0)
260*35238bceSAndroid Build Coastguard Worker     {
261*35238bceSAndroid Build Coastguard Worker         const GLenum pname = (shader.getType() == rsg::Shader::TYPE_VERTEX) ? (GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) :
262*35238bceSAndroid Build Coastguard Worker                                                                               (GL_MAX_TEXTURE_IMAGE_UNITS);
263*35238bceSAndroid Build Coastguard Worker         int numSupported   = -1;
264*35238bceSAndroid Build Coastguard Worker         GLenum error;
265*35238bceSAndroid Build Coastguard Worker 
266*35238bceSAndroid Build Coastguard Worker         m_renderCtx.getFunctions().getIntegerv(pname, &numSupported);
267*35238bceSAndroid Build Coastguard Worker         error = m_renderCtx.getFunctions().getError();
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker         if (error != GL_NO_ERROR)
270*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Limit query failed: " + de::toString(glu::getErrorStr(error)));
271*35238bceSAndroid Build Coastguard Worker 
272*35238bceSAndroid Build Coastguard Worker         if (numSupported < numRequiredSamplers)
273*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Shader requires " + de::toString(numRequiredSamplers) +
274*35238bceSAndroid Build Coastguard Worker                                          " sampler(s). Implementation supports " + de::toString(numSupported));
275*35238bceSAndroid Build Coastguard Worker     }
276*35238bceSAndroid Build Coastguard Worker }
277*35238bceSAndroid Build Coastguard Worker 
checkProgramLimits(const rsg::Shader & vtxShader,const rsg::Shader & frgShader) const278*35238bceSAndroid Build Coastguard Worker void RandomShaderCase::checkProgramLimits(const rsg::Shader &vtxShader, const rsg::Shader &frgShader) const
279*35238bceSAndroid Build Coastguard Worker {
280*35238bceSAndroid Build Coastguard Worker     const int numRequiredCombinedSamplers =
281*35238bceSAndroid Build Coastguard Worker         getNumSamplerUniforms(vtxShader.getUniforms()) + getNumSamplerUniforms(frgShader.getUniforms());
282*35238bceSAndroid Build Coastguard Worker 
283*35238bceSAndroid Build Coastguard Worker     if (numRequiredCombinedSamplers > 0)
284*35238bceSAndroid Build Coastguard Worker     {
285*35238bceSAndroid Build Coastguard Worker         int numSupported = -1;
286*35238bceSAndroid Build Coastguard Worker         GLenum error;
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker         m_renderCtx.getFunctions().getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numSupported);
289*35238bceSAndroid Build Coastguard Worker         error = m_renderCtx.getFunctions().getError();
290*35238bceSAndroid Build Coastguard Worker 
291*35238bceSAndroid Build Coastguard Worker         if (error != GL_NO_ERROR)
292*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Limit query failed: " + de::toString(glu::getErrorStr(error)));
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker         if (numSupported < numRequiredCombinedSamplers)
295*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Program requires " + de::toString(numRequiredCombinedSamplers) +
296*35238bceSAndroid Build Coastguard Worker                                          " sampler(s). Implementation supports " + de::toString(numSupported));
297*35238bceSAndroid Build Coastguard Worker     }
298*35238bceSAndroid Build Coastguard Worker }
299*35238bceSAndroid Build Coastguard Worker 
getTex2D(void)300*35238bceSAndroid Build Coastguard Worker const glu::Texture2D *RandomShaderCase::getTex2D(void)
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker     if (!m_tex2D)
303*35238bceSAndroid Build Coastguard Worker     {
304*35238bceSAndroid Build Coastguard Worker         m_tex2D = new glu::Texture2D(m_renderCtx, TEXTURE_2D_FORMAT, TEXTURE_2D_DATA_TYPE, TEXTURE_2D_WIDTH,
305*35238bceSAndroid Build Coastguard Worker                                      TEXTURE_2D_HEIGHT);
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker         m_tex2D->getRefTexture().allocLevel(0);
308*35238bceSAndroid Build Coastguard Worker         tcu::fillWithComponentGradients(m_tex2D->getRefTexture().getLevel(0), tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f),
309*35238bceSAndroid Build Coastguard Worker                                         tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
310*35238bceSAndroid Build Coastguard Worker         m_tex2D->upload();
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker         // Setup parameters.
313*35238bceSAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, m_tex2D->getGLTexture());
314*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, TEXTURE_WRAP_S);
315*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, TEXTURE_WRAP_T);
316*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TEXTURE_MIN_FILTER);
317*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TEXTURE_MAG_FILTER);
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
320*35238bceSAndroid Build Coastguard Worker     }
321*35238bceSAndroid Build Coastguard Worker 
322*35238bceSAndroid Build Coastguard Worker     return m_tex2D;
323*35238bceSAndroid Build Coastguard Worker }
324*35238bceSAndroid Build Coastguard Worker 
getTexCube(void)325*35238bceSAndroid Build Coastguard Worker const glu::TextureCube *RandomShaderCase::getTexCube(void)
326*35238bceSAndroid Build Coastguard Worker {
327*35238bceSAndroid Build Coastguard Worker     if (!m_texCube)
328*35238bceSAndroid Build Coastguard Worker     {
329*35238bceSAndroid Build Coastguard Worker         m_texCube = new glu::TextureCube(m_renderCtx, TEXTURE_CUBE_FORMAT, TEXTURE_CUBE_DATA_TYPE, TEXTURE_CUBE_SIZE);
330*35238bceSAndroid Build Coastguard Worker 
331*35238bceSAndroid Build Coastguard Worker         static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] = {
332*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)}, // negative x
333*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // positive x
334*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(-1.0f, 0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // negative y
335*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(-1.0f, -1.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // positive y
336*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)}, // negative z
337*35238bceSAndroid Build Coastguard Worker             {tcu::Vec4(0.0f, 0.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)}     // positive z
338*35238bceSAndroid Build Coastguard Worker         };
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker         // Fill level 0.
341*35238bceSAndroid Build Coastguard Worker         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
342*35238bceSAndroid Build Coastguard Worker         {
343*35238bceSAndroid Build Coastguard Worker             m_texCube->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
344*35238bceSAndroid Build Coastguard Worker             tcu::fillWithComponentGradients(m_texCube->getRefTexture().getLevelFace(0, (tcu::CubeFace)face),
345*35238bceSAndroid Build Coastguard Worker                                             gradients[face][0], gradients[face][1]);
346*35238bceSAndroid Build Coastguard Worker         }
347*35238bceSAndroid Build Coastguard Worker 
348*35238bceSAndroid Build Coastguard Worker         m_texCube->upload();
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker         // Setup parameters.
351*35238bceSAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_CUBE_MAP, m_texCube->getGLTexture());
352*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, TEXTURE_WRAP_S);
353*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, TEXTURE_WRAP_T);
354*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, TEXTURE_MIN_FILTER);
355*35238bceSAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, TEXTURE_MAG_FILTER);
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
358*35238bceSAndroid Build Coastguard Worker     }
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker     return m_texCube;
361*35238bceSAndroid Build Coastguard Worker }
362*35238bceSAndroid Build Coastguard Worker 
deinit(void)363*35238bceSAndroid Build Coastguard Worker void RandomShaderCase::deinit(void)
364*35238bceSAndroid Build Coastguard Worker {
365*35238bceSAndroid Build Coastguard Worker     delete m_tex2D;
366*35238bceSAndroid Build Coastguard Worker     delete m_texCube;
367*35238bceSAndroid Build Coastguard Worker 
368*35238bceSAndroid Build Coastguard Worker     m_tex2D   = DE_NULL;
369*35238bceSAndroid Build Coastguard Worker     m_texCube = DE_NULL;
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker     // Free up memory
372*35238bceSAndroid Build Coastguard Worker     m_vertexArrays.clear();
373*35238bceSAndroid Build Coastguard Worker     m_indices.clear();
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker namespace
377*35238bceSAndroid Build Coastguard Worker {
378*35238bceSAndroid Build Coastguard Worker 
setUniformValue(int location,rsg::ConstValueAccess value)379*35238bceSAndroid Build Coastguard Worker void setUniformValue(int location, rsg::ConstValueAccess value)
380*35238bceSAndroid Build Coastguard Worker {
381*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(float));
382*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(int));
383*35238bceSAndroid Build Coastguard Worker 
384*35238bceSAndroid Build Coastguard Worker     switch (value.getType().getBaseType())
385*35238bceSAndroid Build Coastguard Worker     {
386*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_FLOAT:
387*35238bceSAndroid Build Coastguard Worker         switch (value.getType().getNumElements())
388*35238bceSAndroid Build Coastguard Worker         {
389*35238bceSAndroid Build Coastguard Worker         case 1:
390*35238bceSAndroid Build Coastguard Worker             glUniform1fv(location, 1, (float *)value.value().getValuePtr());
391*35238bceSAndroid Build Coastguard Worker             break;
392*35238bceSAndroid Build Coastguard Worker         case 2:
393*35238bceSAndroid Build Coastguard Worker             glUniform2fv(location, 1, (float *)value.value().getValuePtr());
394*35238bceSAndroid Build Coastguard Worker             break;
395*35238bceSAndroid Build Coastguard Worker         case 3:
396*35238bceSAndroid Build Coastguard Worker             glUniform3fv(location, 1, (float *)value.value().getValuePtr());
397*35238bceSAndroid Build Coastguard Worker             break;
398*35238bceSAndroid Build Coastguard Worker         case 4:
399*35238bceSAndroid Build Coastguard Worker             glUniform4fv(location, 1, (float *)value.value().getValuePtr());
400*35238bceSAndroid Build Coastguard Worker             break;
401*35238bceSAndroid Build Coastguard Worker         default:
402*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Unsupported type");
403*35238bceSAndroid Build Coastguard Worker         }
404*35238bceSAndroid Build Coastguard Worker         break;
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_INT:
407*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_BOOL:
408*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_SAMPLER_2D:
409*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_SAMPLER_CUBE:
410*35238bceSAndroid Build Coastguard Worker         switch (value.getType().getNumElements())
411*35238bceSAndroid Build Coastguard Worker         {
412*35238bceSAndroid Build Coastguard Worker         case 1:
413*35238bceSAndroid Build Coastguard Worker             glUniform1iv(location, 1, (int *)value.value().getValuePtr());
414*35238bceSAndroid Build Coastguard Worker             break;
415*35238bceSAndroid Build Coastguard Worker         case 2:
416*35238bceSAndroid Build Coastguard Worker             glUniform2iv(location, 1, (int *)value.value().getValuePtr());
417*35238bceSAndroid Build Coastguard Worker             break;
418*35238bceSAndroid Build Coastguard Worker         case 3:
419*35238bceSAndroid Build Coastguard Worker             glUniform3iv(location, 1, (int *)value.value().getValuePtr());
420*35238bceSAndroid Build Coastguard Worker             break;
421*35238bceSAndroid Build Coastguard Worker         case 4:
422*35238bceSAndroid Build Coastguard Worker             glUniform4iv(location, 1, (int *)value.value().getValuePtr());
423*35238bceSAndroid Build Coastguard Worker             break;
424*35238bceSAndroid Build Coastguard Worker         default:
425*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Unsupported type");
426*35238bceSAndroid Build Coastguard Worker         }
427*35238bceSAndroid Build Coastguard Worker         break;
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker     default:
430*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unsupported type");
431*35238bceSAndroid Build Coastguard Worker     }
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker 
operator <<(tcu::MessageBuilder & message,rsg::ConstValueAccess value)434*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder &operator<<(tcu::MessageBuilder &message, rsg::ConstValueAccess value)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker     const char *scalarType = DE_NULL;
437*35238bceSAndroid Build Coastguard Worker     const char *vecType    = DE_NULL;
438*35238bceSAndroid Build Coastguard Worker 
439*35238bceSAndroid Build Coastguard Worker     switch (value.getType().getBaseType())
440*35238bceSAndroid Build Coastguard Worker     {
441*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_FLOAT:
442*35238bceSAndroid Build Coastguard Worker         scalarType = "float";
443*35238bceSAndroid Build Coastguard Worker         vecType    = "vec";
444*35238bceSAndroid Build Coastguard Worker         break;
445*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_INT:
446*35238bceSAndroid Build Coastguard Worker         scalarType = "int";
447*35238bceSAndroid Build Coastguard Worker         vecType    = "ivec";
448*35238bceSAndroid Build Coastguard Worker         break;
449*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_BOOL:
450*35238bceSAndroid Build Coastguard Worker         scalarType = "bool";
451*35238bceSAndroid Build Coastguard Worker         vecType    = "bvec";
452*35238bceSAndroid Build Coastguard Worker         break;
453*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_SAMPLER_2D:
454*35238bceSAndroid Build Coastguard Worker         scalarType = "sampler2D";
455*35238bceSAndroid Build Coastguard Worker         break;
456*35238bceSAndroid Build Coastguard Worker     case rsg::VariableType::TYPE_SAMPLER_CUBE:
457*35238bceSAndroid Build Coastguard Worker         scalarType = "samplerCube";
458*35238bceSAndroid Build Coastguard Worker         break;
459*35238bceSAndroid Build Coastguard Worker     default:
460*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unsupported type.");
461*35238bceSAndroid Build Coastguard Worker     }
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker     int numElements = value.getType().getNumElements();
464*35238bceSAndroid Build Coastguard Worker     if (numElements == 1)
465*35238bceSAndroid Build Coastguard Worker         message << scalarType << "(";
466*35238bceSAndroid Build Coastguard Worker     else
467*35238bceSAndroid Build Coastguard Worker         message << vecType << numElements << "(";
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker     for (int elementNdx = 0; elementNdx < numElements; elementNdx++)
470*35238bceSAndroid Build Coastguard Worker     {
471*35238bceSAndroid Build Coastguard Worker         if (elementNdx > 0)
472*35238bceSAndroid Build Coastguard Worker             message << ", ";
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker         switch (value.getType().getBaseType())
475*35238bceSAndroid Build Coastguard Worker         {
476*35238bceSAndroid Build Coastguard Worker         case rsg::VariableType::TYPE_FLOAT:
477*35238bceSAndroid Build Coastguard Worker             message << value.component(elementNdx).asFloat();
478*35238bceSAndroid Build Coastguard Worker             break;
479*35238bceSAndroid Build Coastguard Worker         case rsg::VariableType::TYPE_INT:
480*35238bceSAndroid Build Coastguard Worker             message << value.component(elementNdx).asInt();
481*35238bceSAndroid Build Coastguard Worker             break;
482*35238bceSAndroid Build Coastguard Worker         case rsg::VariableType::TYPE_BOOL:
483*35238bceSAndroid Build Coastguard Worker             message << (value.component(elementNdx).asBool() ? "true" : "false");
484*35238bceSAndroid Build Coastguard Worker             break;
485*35238bceSAndroid Build Coastguard Worker         case rsg::VariableType::TYPE_SAMPLER_2D:
486*35238bceSAndroid Build Coastguard Worker             message << value.component(elementNdx).asInt();
487*35238bceSAndroid Build Coastguard Worker             break;
488*35238bceSAndroid Build Coastguard Worker         case rsg::VariableType::TYPE_SAMPLER_CUBE:
489*35238bceSAndroid Build Coastguard Worker             message << value.component(elementNdx).asInt();
490*35238bceSAndroid Build Coastguard Worker             break;
491*35238bceSAndroid Build Coastguard Worker         default:
492*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
493*35238bceSAndroid Build Coastguard Worker         }
494*35238bceSAndroid Build Coastguard Worker     }
495*35238bceSAndroid Build Coastguard Worker 
496*35238bceSAndroid Build Coastguard Worker     message << ")";
497*35238bceSAndroid Build Coastguard Worker 
498*35238bceSAndroid Build Coastguard Worker     return message;
499*35238bceSAndroid Build Coastguard Worker }
500*35238bceSAndroid Build Coastguard Worker 
operator <<(tcu::MessageBuilder & message,rsg::ConstValueRangeAccess valueRange)501*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder &operator<<(tcu::MessageBuilder &message, rsg::ConstValueRangeAccess valueRange)
502*35238bceSAndroid Build Coastguard Worker {
503*35238bceSAndroid Build Coastguard Worker     return message << valueRange.getMin() << " -> " << valueRange.getMax();
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker } // namespace
507*35238bceSAndroid Build Coastguard Worker 
iterate(void)508*35238bceSAndroid Build Coastguard Worker RandomShaderCase::IterateResult RandomShaderCase::iterate(void)
509*35238bceSAndroid Build Coastguard Worker {
510*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = m_testCtx.getLog();
511*35238bceSAndroid Build Coastguard Worker 
512*35238bceSAndroid Build Coastguard Worker     // Compile program
513*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_renderCtx,
514*35238bceSAndroid Build Coastguard Worker                                glu::makeVtxFragSources(m_vertexShader.getSource(), m_fragmentShader.getSource()));
515*35238bceSAndroid Build Coastguard Worker     log << program;
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker     if (!program.isOk())
518*35238bceSAndroid Build Coastguard Worker     {
519*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
520*35238bceSAndroid Build Coastguard Worker         return STOP;
521*35238bceSAndroid Build Coastguard Worker     }
522*35238bceSAndroid Build Coastguard Worker 
523*35238bceSAndroid Build Coastguard Worker     // Compute random viewport
524*35238bceSAndroid Build Coastguard Worker     de::Random rnd(m_parameters.seed);
525*35238bceSAndroid Build Coastguard Worker     int viewportWidth  = de::min<int>(VIEWPORT_WIDTH, m_renderCtx.getRenderTarget().getWidth());
526*35238bceSAndroid Build Coastguard Worker     int viewportHeight = de::min<int>(VIEWPORT_HEIGHT, m_renderCtx.getRenderTarget().getHeight());
527*35238bceSAndroid Build Coastguard Worker     int viewportX      = rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWidth);
528*35238bceSAndroid Build Coastguard Worker     int viewportY      = rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHeight);
529*35238bceSAndroid Build Coastguard Worker     bool hasAlpha      = m_renderCtx.getRenderTarget().getPixelFormat().alphaBits > 0;
530*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel rendered(tcu::TextureFormat(hasAlpha ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB,
531*35238bceSAndroid Build Coastguard Worker                                                   tcu::TextureFormat::UNORM_INT8),
532*35238bceSAndroid Build Coastguard Worker                                viewportWidth, viewportHeight);
533*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel reference(tcu::TextureFormat(hasAlpha ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB,
534*35238bceSAndroid Build Coastguard Worker                                                    tcu::TextureFormat::UNORM_INT8),
535*35238bceSAndroid Build Coastguard Worker                                 viewportWidth, viewportHeight);
536*35238bceSAndroid Build Coastguard Worker 
537*35238bceSAndroid Build Coastguard Worker     // Reference program executor.
538*35238bceSAndroid Build Coastguard Worker     rsg::ProgramExecutor executor(reference.getAccess(), m_gridWidth, m_gridHeight);
539*35238bceSAndroid Build Coastguard Worker 
540*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glUseProgram(program.getProgram()));
541*35238bceSAndroid Build Coastguard Worker 
542*35238bceSAndroid Build Coastguard Worker     // Set up attributes
543*35238bceSAndroid Build Coastguard Worker     for (vector<VertexArray>::const_iterator attribIter = m_vertexArrays.begin(); attribIter != m_vertexArrays.end();
544*35238bceSAndroid Build Coastguard Worker          attribIter++)
545*35238bceSAndroid Build Coastguard Worker     {
546*35238bceSAndroid Build Coastguard Worker         GLint location = glGetAttribLocation(program.getProgram(), attribIter->getName());
547*35238bceSAndroid Build Coastguard Worker 
548*35238bceSAndroid Build Coastguard Worker         // Print to log.
549*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "attribute[" << location << "]: " << attribIter->getName() << " = "
550*35238bceSAndroid Build Coastguard Worker             << attribIter->getValueRange() << tcu::TestLog::EndMessage;
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker         if (location >= 0)
553*35238bceSAndroid Build Coastguard Worker         {
554*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(location, attribIter->getNumComponents(), GL_FLOAT, GL_FALSE, 0,
555*35238bceSAndroid Build Coastguard Worker                                   &attribIter->getVertices()[0]);
556*35238bceSAndroid Build Coastguard Worker             glEnableVertexAttribArray(location);
557*35238bceSAndroid Build Coastguard Worker         }
558*35238bceSAndroid Build Coastguard Worker     }
559*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("After attribute setup");
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker     // Uniforms
562*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::VariableValue>::const_iterator uniformIter = m_uniforms.begin(); uniformIter != m_uniforms.end();
563*35238bceSAndroid Build Coastguard Worker          uniformIter++)
564*35238bceSAndroid Build Coastguard Worker     {
565*35238bceSAndroid Build Coastguard Worker         GLint location = glGetUniformLocation(program.getProgram(), uniformIter->getVariable()->getName());
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "uniform[" << location << "]: " << uniformIter->getVariable()->getName()
568*35238bceSAndroid Build Coastguard Worker             << " = " << uniformIter->getValue() << tcu::TestLog::EndMessage;
569*35238bceSAndroid Build Coastguard Worker 
570*35238bceSAndroid Build Coastguard Worker         if (location >= 0)
571*35238bceSAndroid Build Coastguard Worker             setUniformValue(location, uniformIter->getValue());
572*35238bceSAndroid Build Coastguard Worker     }
573*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("After uniform setup");
574*35238bceSAndroid Build Coastguard Worker 
575*35238bceSAndroid Build Coastguard Worker     // Textures
576*35238bceSAndroid Build Coastguard Worker     vector<pair<int, const glu::Texture2D *>> tex2DBindings     = m_texManager.getBindings2D();
577*35238bceSAndroid Build Coastguard Worker     vector<pair<int, const glu::TextureCube *>> texCubeBindings = m_texManager.getBindingsCube();
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker     for (vector<pair<int, const glu::Texture2D *>>::const_iterator i = tex2DBindings.begin(); i != tex2DBindings.end();
580*35238bceSAndroid Build Coastguard Worker          i++)
581*35238bceSAndroid Build Coastguard Worker     {
582*35238bceSAndroid Build Coastguard Worker         int unitNdx                   = i->first;
583*35238bceSAndroid Build Coastguard Worker         const glu::Texture2D *texture = i->second;
584*35238bceSAndroid Build Coastguard Worker 
585*35238bceSAndroid Build Coastguard Worker         glActiveTexture(GL_TEXTURE0 + unitNdx);
586*35238bceSAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture->getGLTexture());
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker         executor.setTexture(unitNdx, &texture->getRefTexture(),
589*35238bceSAndroid Build Coastguard Worker                             glu::mapGLSampler(TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE_MIN_FILTER, TEXTURE_MAG_FILTER));
590*35238bceSAndroid Build Coastguard Worker     }
591*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("After 2D texture setup");
592*35238bceSAndroid Build Coastguard Worker 
593*35238bceSAndroid Build Coastguard Worker     for (vector<pair<int, const glu::TextureCube *>>::const_iterator i = texCubeBindings.begin();
594*35238bceSAndroid Build Coastguard Worker          i != texCubeBindings.end(); i++)
595*35238bceSAndroid Build Coastguard Worker     {
596*35238bceSAndroid Build Coastguard Worker         int unitNdx                     = i->first;
597*35238bceSAndroid Build Coastguard Worker         const glu::TextureCube *texture = i->second;
598*35238bceSAndroid Build Coastguard Worker 
599*35238bceSAndroid Build Coastguard Worker         glActiveTexture(GL_TEXTURE0 + unitNdx);
600*35238bceSAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_CUBE_MAP, texture->getGLTexture());
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker         executor.setTexture(unitNdx, &texture->getRefTexture(),
603*35238bceSAndroid Build Coastguard Worker                             glu::mapGLSampler(TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE_MIN_FILTER, TEXTURE_MAG_FILTER));
604*35238bceSAndroid Build Coastguard Worker     }
605*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("After cubemap setup");
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker     // Draw and read
608*35238bceSAndroid Build Coastguard Worker     glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
609*35238bceSAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, (GLsizei)m_indices.size(), GL_UNSIGNED_SHORT, &m_indices[0]);
610*35238bceSAndroid Build Coastguard Worker     glFlush();
611*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("Draw");
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker     // Render reference while GPU is doing work
614*35238bceSAndroid Build Coastguard Worker     executor.execute(m_vertexShader, m_fragmentShader, m_uniforms);
615*35238bceSAndroid Build Coastguard Worker 
616*35238bceSAndroid Build Coastguard Worker     if (rendered.getFormat().order != tcu::TextureFormat::RGBA ||
617*35238bceSAndroid Build Coastguard Worker         rendered.getFormat().type != tcu::TextureFormat::UNORM_INT8)
618*35238bceSAndroid Build Coastguard Worker     {
619*35238bceSAndroid Build Coastguard Worker         // Read as GL_RGBA8
620*35238bceSAndroid Build Coastguard Worker         tcu::TextureLevel readBuf(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
621*35238bceSAndroid Build Coastguard Worker                                   rendered.getWidth(), rendered.getHeight());
622*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_renderCtx, viewportX, viewportY, readBuf.getAccess());
623*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_MSG("Read pixels");
624*35238bceSAndroid Build Coastguard Worker         tcu::copy(rendered, readBuf);
625*35238bceSAndroid Build Coastguard Worker     }
626*35238bceSAndroid Build Coastguard Worker     else
627*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_renderCtx, viewportX, viewportY, rendered.getAccess());
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker     // Compare
630*35238bceSAndroid Build Coastguard Worker     {
631*35238bceSAndroid Build Coastguard Worker         float threshold = 0.02f;
632*35238bceSAndroid Build Coastguard Worker         bool imagesOk   = tcu::fuzzyCompare(log, "Result", "Result images", reference.getAccess(), rendered.getAccess(),
633*35238bceSAndroid Build Coastguard Worker                                             threshold, tcu::COMPARE_LOG_RESULT);
634*35238bceSAndroid Build Coastguard Worker 
635*35238bceSAndroid Build Coastguard Worker         if (imagesOk)
636*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
637*35238bceSAndroid Build Coastguard Worker         else
638*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
639*35238bceSAndroid Build Coastguard Worker     }
640*35238bceSAndroid Build Coastguard Worker 
641*35238bceSAndroid Build Coastguard Worker     return STOP;
642*35238bceSAndroid Build Coastguard Worker }
643*35238bceSAndroid Build Coastguard Worker 
644*35238bceSAndroid Build Coastguard Worker } // namespace gls
645*35238bceSAndroid Build Coastguard Worker } // namespace deqp
646