1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 2.0 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 Shader API tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es2fShaderApiTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es2fApiCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
34*35238bceSAndroid Build Coastguard Worker
35*35238bceSAndroid Build Coastguard Worker #include "deString.h"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker
40*35238bceSAndroid Build Coastguard Worker #include <string>
41*35238bceSAndroid Build Coastguard Worker #include <vector>
42*35238bceSAndroid Build Coastguard Worker #include <map>
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker using namespace glw; // GL types
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker namespace deqp
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace gles2
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker namespace Functional
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker namespace
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker enum ShaderSourceCaseFlags
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker CASE_EXPLICIT_SOURCE_LENGTHS = 1,
61*35238bceSAndroid Build Coastguard Worker CASE_RANDOM_NULL_TERMINATED = 2
62*35238bceSAndroid Build Coastguard Worker };
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker struct ShaderSources
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker std::vector<std::string> strings;
67*35238bceSAndroid Build Coastguard Worker std::vector<int> lengths;
68*35238bceSAndroid Build Coastguard Worker };
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker // Simple shaders
71*35238bceSAndroid Build Coastguard Worker
getSimpleShaderSource(const glu::ShaderType shaderType)72*35238bceSAndroid Build Coastguard Worker const char *getSimpleShaderSource(const glu::ShaderType shaderType)
73*35238bceSAndroid Build Coastguard Worker {
74*35238bceSAndroid Build Coastguard Worker const char *simpleVertexShaderSource = "void main (void) { gl_Position = vec4(0.0); }\n";
75*35238bceSAndroid Build Coastguard Worker const char *simpleFragmentShaderSource = "void main (void) { gl_FragColor = vec4(0.0); }\n";
76*35238bceSAndroid Build Coastguard Worker
77*35238bceSAndroid Build Coastguard Worker switch (shaderType)
78*35238bceSAndroid Build Coastguard Worker {
79*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
80*35238bceSAndroid Build Coastguard Worker return simpleVertexShaderSource;
81*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
82*35238bceSAndroid Build Coastguard Worker return simpleFragmentShaderSource;
83*35238bceSAndroid Build Coastguard Worker default:
84*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
85*35238bceSAndroid Build Coastguard Worker }
86*35238bceSAndroid Build Coastguard Worker
87*35238bceSAndroid Build Coastguard Worker return 0;
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker
setShaderSources(glu::Shader & shader,const ShaderSources & sources)90*35238bceSAndroid Build Coastguard Worker void setShaderSources(glu::Shader &shader, const ShaderSources &sources)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker std::vector<const char *> cStrings(sources.strings.size(), 0);
93*35238bceSAndroid Build Coastguard Worker
94*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < sources.strings.size(); ndx++)
95*35238bceSAndroid Build Coastguard Worker cStrings[ndx] = sources.strings[ndx].c_str();
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker if (sources.lengths.size() > 0)
98*35238bceSAndroid Build Coastguard Worker shader.setSources((int)cStrings.size(), &cStrings[0], &sources.lengths[0]);
99*35238bceSAndroid Build Coastguard Worker else
100*35238bceSAndroid Build Coastguard Worker shader.setSources((int)cStrings.size(), &cStrings[0], 0);
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker
sliceSourceString(const std::string & in,ShaderSources & out,const int numSlices,const size_t paddingLength=0)103*35238bceSAndroid Build Coastguard Worker void sliceSourceString(const std::string &in, ShaderSources &out, const int numSlices, const size_t paddingLength = 0)
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numSlices > 0);
106*35238bceSAndroid Build Coastguard Worker
107*35238bceSAndroid Build Coastguard Worker const size_t sliceSize = in.length() / numSlices;
108*35238bceSAndroid Build Coastguard Worker const size_t sliceSizeRemainder = in.length() - (sliceSize * numSlices);
109*35238bceSAndroid Build Coastguard Worker const std::string padding(paddingLength, 'E');
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numSlices; i++)
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker out.strings.push_back(in.substr(i * sliceSize, sliceSize) + padding);
114*35238bceSAndroid Build Coastguard Worker
115*35238bceSAndroid Build Coastguard Worker if (paddingLength > 0)
116*35238bceSAndroid Build Coastguard Worker out.lengths.push_back((int)sliceSize);
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker if (sliceSizeRemainder > 0)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker const std::string lastString = in.substr(numSlices * sliceSize);
122*35238bceSAndroid Build Coastguard Worker const int lastStringLength = (int)lastString.length();
123*35238bceSAndroid Build Coastguard Worker
124*35238bceSAndroid Build Coastguard Worker out.strings.push_back(lastString + padding);
125*35238bceSAndroid Build Coastguard Worker
126*35238bceSAndroid Build Coastguard Worker if (paddingLength > 0)
127*35238bceSAndroid Build Coastguard Worker out.lengths.push_back(lastStringLength);
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker
queryShaderInfo(glu::RenderContext & renderCtx,uint32_t shader,glu::ShaderInfo & info)131*35238bceSAndroid Build Coastguard Worker void queryShaderInfo(glu::RenderContext &renderCtx, uint32_t shader, glu::ShaderInfo &info)
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = renderCtx.getFunctions();
134*35238bceSAndroid Build Coastguard Worker
135*35238bceSAndroid Build Coastguard Worker info.compileOk = false;
136*35238bceSAndroid Build Coastguard Worker info.compileTimeUs = 0;
137*35238bceSAndroid Build Coastguard Worker info.infoLog.clear();
138*35238bceSAndroid Build Coastguard Worker
139*35238bceSAndroid Build Coastguard Worker // Query source, status & log.
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker int compileStatus = 0;
142*35238bceSAndroid Build Coastguard Worker int sourceLen = 0;
143*35238bceSAndroid Build Coastguard Worker int infoLogLen = 0;
144*35238bceSAndroid Build Coastguard Worker int unusedLen;
145*35238bceSAndroid Build Coastguard Worker
146*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
147*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLen);
148*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
149*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");
150*35238bceSAndroid Build Coastguard Worker
151*35238bceSAndroid Build Coastguard Worker info.compileOk = compileStatus != GL_FALSE;
152*35238bceSAndroid Build Coastguard Worker
153*35238bceSAndroid Build Coastguard Worker if (sourceLen > 0)
154*35238bceSAndroid Build Coastguard Worker {
155*35238bceSAndroid Build Coastguard Worker std::vector<char> source(sourceLen);
156*35238bceSAndroid Build Coastguard Worker gl.getShaderSource(shader, (int)source.size(), &unusedLen, &source[0]);
157*35238bceSAndroid Build Coastguard Worker info.source = std::string(&source[0], sourceLen);
158*35238bceSAndroid Build Coastguard Worker }
159*35238bceSAndroid Build Coastguard Worker
160*35238bceSAndroid Build Coastguard Worker if (infoLogLen > 0)
161*35238bceSAndroid Build Coastguard Worker {
162*35238bceSAndroid Build Coastguard Worker std::vector<char> infoLog(infoLogLen);
163*35238bceSAndroid Build Coastguard Worker gl.getShaderInfoLog(shader, (int)infoLog.size(), &unusedLen, &infoLog[0]);
164*35238bceSAndroid Build Coastguard Worker info.infoLog = std::string(&infoLog[0], infoLogLen);
165*35238bceSAndroid Build Coastguard Worker }
166*35238bceSAndroid Build Coastguard Worker }
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker
169*35238bceSAndroid Build Coastguard Worker // Shader source generator
170*35238bceSAndroid Build Coastguard Worker
171*35238bceSAndroid Build Coastguard Worker class SourceGenerator
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker public:
~SourceGenerator(void)174*35238bceSAndroid Build Coastguard Worker virtual ~SourceGenerator(void)
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker
178*35238bceSAndroid Build Coastguard Worker virtual std::string next(const glu::ShaderType shaderType) = 0;
179*35238bceSAndroid Build Coastguard Worker virtual bool finished(const glu::ShaderType shaderType) const = 0;
180*35238bceSAndroid Build Coastguard Worker };
181*35238bceSAndroid Build Coastguard Worker
182*35238bceSAndroid Build Coastguard Worker class ConstantShaderGenerator : public SourceGenerator
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker public:
ConstantShaderGenerator(de::Random & rnd)185*35238bceSAndroid Build Coastguard Worker ConstantShaderGenerator(de::Random &rnd) : m_rnd(rnd)
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker }
~ConstantShaderGenerator(void)188*35238bceSAndroid Build Coastguard Worker ~ConstantShaderGenerator(void)
189*35238bceSAndroid Build Coastguard Worker {
190*35238bceSAndroid Build Coastguard Worker }
191*35238bceSAndroid Build Coastguard Worker
finished(const glu::ShaderType shaderType) const192*35238bceSAndroid Build Coastguard Worker bool finished(const glu::ShaderType shaderType) const
193*35238bceSAndroid Build Coastguard Worker {
194*35238bceSAndroid Build Coastguard Worker DE_UNREF(shaderType);
195*35238bceSAndroid Build Coastguard Worker return false;
196*35238bceSAndroid Build Coastguard Worker }
197*35238bceSAndroid Build Coastguard Worker
198*35238bceSAndroid Build Coastguard Worker std::string next(const glu::ShaderType shaderType);
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker private:
201*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
202*35238bceSAndroid Build Coastguard Worker };
203*35238bceSAndroid Build Coastguard Worker
next(const glu::ShaderType shaderType)204*35238bceSAndroid Build Coastguard Worker std::string ConstantShaderGenerator::next(const glu::ShaderType shaderType)
205*35238bceSAndroid Build Coastguard Worker {
206*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shaderType == glu::SHADERTYPE_VERTEX || shaderType == glu::SHADERTYPE_FRAGMENT);
207*35238bceSAndroid Build Coastguard Worker
208*35238bceSAndroid Build Coastguard Worker const float value = m_rnd.getFloat(0.0f, 1.0f);
209*35238bceSAndroid Build Coastguard Worker const std::string valueString = de::toString(value);
210*35238bceSAndroid Build Coastguard Worker const std::string outputName = (shaderType == glu::SHADERTYPE_VERTEX) ? "gl_Position" : "gl_FragColor";
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker std::string source = "#version 100\n"
213*35238bceSAndroid Build Coastguard Worker "void main (void) { " +
214*35238bceSAndroid Build Coastguard Worker outputName + " = vec4(" + valueString + "); }\n";
215*35238bceSAndroid Build Coastguard Worker
216*35238bceSAndroid Build Coastguard Worker return source;
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker
219*35238bceSAndroid Build Coastguard Worker // Shader allocation utility
220*35238bceSAndroid Build Coastguard Worker
221*35238bceSAndroid Build Coastguard Worker class ShaderAllocator
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker public:
224*35238bceSAndroid Build Coastguard Worker ShaderAllocator(glu::RenderContext &context, SourceGenerator &generator);
225*35238bceSAndroid Build Coastguard Worker ~ShaderAllocator(void);
226*35238bceSAndroid Build Coastguard Worker
227*35238bceSAndroid Build Coastguard Worker bool hasShader(const glu::ShaderType shaderType);
228*35238bceSAndroid Build Coastguard Worker
229*35238bceSAndroid Build Coastguard Worker void setSource(const glu::ShaderType shaderType);
230*35238bceSAndroid Build Coastguard Worker
231*35238bceSAndroid Build Coastguard Worker glu::Shader &createShader(const glu::ShaderType shaderType);
232*35238bceSAndroid Build Coastguard Worker void deleteShader(const glu::ShaderType shaderType);
233*35238bceSAndroid Build Coastguard Worker
get(const glu::ShaderType shaderType)234*35238bceSAndroid Build Coastguard Worker glu::Shader &get(const glu::ShaderType shaderType)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker DE_ASSERT(hasShader(shaderType));
237*35238bceSAndroid Build Coastguard Worker return *m_shaders[shaderType];
238*35238bceSAndroid Build Coastguard Worker }
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker private:
241*35238bceSAndroid Build Coastguard Worker const glu::RenderContext &m_context;
242*35238bceSAndroid Build Coastguard Worker SourceGenerator &m_srcGen;
243*35238bceSAndroid Build Coastguard Worker std::map<glu::ShaderType, glu::Shader *> m_shaders;
244*35238bceSAndroid Build Coastguard Worker };
245*35238bceSAndroid Build Coastguard Worker
ShaderAllocator(glu::RenderContext & context,SourceGenerator & generator)246*35238bceSAndroid Build Coastguard Worker ShaderAllocator::ShaderAllocator(glu::RenderContext &context, SourceGenerator &generator)
247*35238bceSAndroid Build Coastguard Worker : m_context(context)
248*35238bceSAndroid Build Coastguard Worker , m_srcGen(generator)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker }
251*35238bceSAndroid Build Coastguard Worker
~ShaderAllocator(void)252*35238bceSAndroid Build Coastguard Worker ShaderAllocator::~ShaderAllocator(void)
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker for (std::map<glu::ShaderType, glu::Shader *>::iterator shaderIter = m_shaders.begin();
255*35238bceSAndroid Build Coastguard Worker shaderIter != m_shaders.end(); shaderIter++)
256*35238bceSAndroid Build Coastguard Worker delete shaderIter->second;
257*35238bceSAndroid Build Coastguard Worker m_shaders.clear();
258*35238bceSAndroid Build Coastguard Worker }
259*35238bceSAndroid Build Coastguard Worker
hasShader(const glu::ShaderType shaderType)260*35238bceSAndroid Build Coastguard Worker bool ShaderAllocator::hasShader(const glu::ShaderType shaderType)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker if (m_shaders.find(shaderType) != m_shaders.end())
263*35238bceSAndroid Build Coastguard Worker return true;
264*35238bceSAndroid Build Coastguard Worker else
265*35238bceSAndroid Build Coastguard Worker return false;
266*35238bceSAndroid Build Coastguard Worker }
267*35238bceSAndroid Build Coastguard Worker
createShader(const glu::ShaderType shaderType)268*35238bceSAndroid Build Coastguard Worker glu::Shader &ShaderAllocator::createShader(const glu::ShaderType shaderType)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!this->hasShader(shaderType));
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker glu::Shader *const shader = new glu::Shader(m_context, shaderType);
273*35238bceSAndroid Build Coastguard Worker
274*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType] = shader;
275*35238bceSAndroid Build Coastguard Worker this->setSource(shaderType);
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker return *shader;
278*35238bceSAndroid Build Coastguard Worker }
279*35238bceSAndroid Build Coastguard Worker
deleteShader(const glu::ShaderType shaderType)280*35238bceSAndroid Build Coastguard Worker void ShaderAllocator::deleteShader(const glu::ShaderType shaderType)
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker DE_ASSERT(this->hasShader(shaderType));
283*35238bceSAndroid Build Coastguard Worker
284*35238bceSAndroid Build Coastguard Worker delete m_shaders[shaderType];
285*35238bceSAndroid Build Coastguard Worker m_shaders.erase(shaderType);
286*35238bceSAndroid Build Coastguard Worker }
287*35238bceSAndroid Build Coastguard Worker
setSource(const glu::ShaderType shaderType)288*35238bceSAndroid Build Coastguard Worker void ShaderAllocator::setSource(const glu::ShaderType shaderType)
289*35238bceSAndroid Build Coastguard Worker {
290*35238bceSAndroid Build Coastguard Worker DE_ASSERT(this->hasShader(shaderType));
291*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_srcGen.finished(shaderType));
292*35238bceSAndroid Build Coastguard Worker
293*35238bceSAndroid Build Coastguard Worker const std::string source = m_srcGen.next(shaderType);
294*35238bceSAndroid Build Coastguard Worker const char *const cSource = source.c_str();
295*35238bceSAndroid Build Coastguard Worker
296*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType]->setSources(1, &cSource, 0);
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker
299*35238bceSAndroid Build Coastguard Worker // Logging utilities
300*35238bceSAndroid Build Coastguard Worker
logShader(TestLog & log,glu::RenderContext & renderCtx,glu::Shader & shader)301*35238bceSAndroid Build Coastguard Worker void logShader(TestLog &log, glu::RenderContext &renderCtx, glu::Shader &shader)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker glu::ShaderInfo info;
304*35238bceSAndroid Build Coastguard Worker queryShaderInfo(renderCtx, shader.getShader(), info);
305*35238bceSAndroid Build Coastguard Worker
306*35238bceSAndroid Build Coastguard Worker log << TestLog::Shader(getLogShaderType(shader.getType()), info.source, info.compileOk, info.infoLog);
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker
logProgram(TestLog & log,glu::RenderContext & renderCtx,glu::Program & program,ShaderAllocator & shaders)309*35238bceSAndroid Build Coastguard Worker void logProgram(TestLog &log, glu::RenderContext &renderCtx, glu::Program &program, ShaderAllocator &shaders)
310*35238bceSAndroid Build Coastguard Worker {
311*35238bceSAndroid Build Coastguard Worker log << TestLog::ShaderProgram(program.getLinkStatus(), program.getInfoLog());
312*35238bceSAndroid Build Coastguard Worker
313*35238bceSAndroid Build Coastguard Worker for (int shaderTypeInt = 0; shaderTypeInt < glu::SHADERTYPE_LAST; shaderTypeInt++)
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType = (glu::ShaderType)shaderTypeInt;
316*35238bceSAndroid Build Coastguard Worker
317*35238bceSAndroid Build Coastguard Worker if (shaders.hasShader(shaderType))
318*35238bceSAndroid Build Coastguard Worker logShader(log, renderCtx, shaders.get(shaderType));
319*35238bceSAndroid Build Coastguard Worker }
320*35238bceSAndroid Build Coastguard Worker
321*35238bceSAndroid Build Coastguard Worker log << TestLog::EndShaderProgram;
322*35238bceSAndroid Build Coastguard Worker }
323*35238bceSAndroid Build Coastguard Worker
logVertexFragmentProgram(TestLog & log,glu::RenderContext & renderCtx,glu::Program & program,glu::Shader & vertShader,glu::Shader & fragShader)324*35238bceSAndroid Build Coastguard Worker void logVertexFragmentProgram(TestLog &log, glu::RenderContext &renderCtx, glu::Program &program,
325*35238bceSAndroid Build Coastguard Worker glu::Shader &vertShader, glu::Shader &fragShader)
326*35238bceSAndroid Build Coastguard Worker {
327*35238bceSAndroid Build Coastguard Worker DE_ASSERT(vertShader.getType() == glu::SHADERTYPE_VERTEX && fragShader.getType() == glu::SHADERTYPE_FRAGMENT);
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker log << TestLog::ShaderProgram(program.getLinkStatus(), program.getInfoLog());
330*35238bceSAndroid Build Coastguard Worker
331*35238bceSAndroid Build Coastguard Worker logShader(log, renderCtx, vertShader);
332*35238bceSAndroid Build Coastguard Worker logShader(log, renderCtx, fragShader);
333*35238bceSAndroid Build Coastguard Worker
334*35238bceSAndroid Build Coastguard Worker log << TestLog::EndShaderProgram;
335*35238bceSAndroid Build Coastguard Worker }
336*35238bceSAndroid Build Coastguard Worker
337*35238bceSAndroid Build Coastguard Worker } // namespace
338*35238bceSAndroid Build Coastguard Worker
339*35238bceSAndroid Build Coastguard Worker // Simple glCreateShader() case
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker class CreateShaderCase : public ApiCase
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker public:
CreateShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)344*35238bceSAndroid Build Coastguard Worker CreateShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
345*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
346*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
347*35238bceSAndroid Build Coastguard Worker {
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker
test(void)350*35238bceSAndroid Build Coastguard Worker void test(void)
351*35238bceSAndroid Build Coastguard Worker {
352*35238bceSAndroid Build Coastguard Worker const GLuint shaderObject = glCreateShader(glu::getGLShaderType(m_shaderType));
353*35238bceSAndroid Build Coastguard Worker
354*35238bceSAndroid Build Coastguard Worker TCU_CHECK(shaderObject != 0);
355*35238bceSAndroid Build Coastguard Worker
356*35238bceSAndroid Build Coastguard Worker glDeleteShader(shaderObject);
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker
359*35238bceSAndroid Build Coastguard Worker private:
360*35238bceSAndroid Build Coastguard Worker const glu::ShaderType m_shaderType;
361*35238bceSAndroid Build Coastguard Worker };
362*35238bceSAndroid Build Coastguard Worker
363*35238bceSAndroid Build Coastguard Worker // Simple glCompileShader() case
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker class CompileShaderCase : public ApiCase
366*35238bceSAndroid Build Coastguard Worker {
367*35238bceSAndroid Build Coastguard Worker public:
CompileShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)368*35238bceSAndroid Build Coastguard Worker CompileShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
369*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
370*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
371*35238bceSAndroid Build Coastguard Worker {
372*35238bceSAndroid Build Coastguard Worker }
373*35238bceSAndroid Build Coastguard Worker
checkCompileStatus(const GLuint shaderObject)374*35238bceSAndroid Build Coastguard Worker bool checkCompileStatus(const GLuint shaderObject)
375*35238bceSAndroid Build Coastguard Worker {
376*35238bceSAndroid Build Coastguard Worker GLint compileStatus = -1;
377*35238bceSAndroid Build Coastguard Worker glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &compileStatus);
378*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
379*35238bceSAndroid Build Coastguard Worker
380*35238bceSAndroid Build Coastguard Worker return (compileStatus == GL_TRUE);
381*35238bceSAndroid Build Coastguard Worker }
382*35238bceSAndroid Build Coastguard Worker
test(void)383*35238bceSAndroid Build Coastguard Worker void test(void)
384*35238bceSAndroid Build Coastguard Worker {
385*35238bceSAndroid Build Coastguard Worker const char *shaderSource = getSimpleShaderSource(m_shaderType);
386*35238bceSAndroid Build Coastguard Worker const GLuint shaderObject = glCreateShader(glu::getGLShaderType(m_shaderType));
387*35238bceSAndroid Build Coastguard Worker
388*35238bceSAndroid Build Coastguard Worker TCU_CHECK(shaderObject != 0);
389*35238bceSAndroid Build Coastguard Worker
390*35238bceSAndroid Build Coastguard Worker glShaderSource(shaderObject, 1, &shaderSource, 0);
391*35238bceSAndroid Build Coastguard Worker glCompileShader(shaderObject);
392*35238bceSAndroid Build Coastguard Worker
393*35238bceSAndroid Build Coastguard Worker TCU_CHECK(checkCompileStatus(shaderObject));
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker glDeleteShader(shaderObject);
396*35238bceSAndroid Build Coastguard Worker }
397*35238bceSAndroid Build Coastguard Worker
398*35238bceSAndroid Build Coastguard Worker private:
399*35238bceSAndroid Build Coastguard Worker const glu::ShaderType m_shaderType;
400*35238bceSAndroid Build Coastguard Worker };
401*35238bceSAndroid Build Coastguard Worker
402*35238bceSAndroid Build Coastguard Worker // Base class for simple program API tests
403*35238bceSAndroid Build Coastguard Worker
404*35238bceSAndroid Build Coastguard Worker class SimpleProgramCase : public ApiCase
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker public:
SimpleProgramCase(Context & context,const char * name,const char * desc)407*35238bceSAndroid Build Coastguard Worker SimpleProgramCase(Context &context, const char *name, const char *desc)
408*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
409*35238bceSAndroid Build Coastguard Worker , m_vertShader(0)
410*35238bceSAndroid Build Coastguard Worker , m_fragShader(0)
411*35238bceSAndroid Build Coastguard Worker , m_program(0)
412*35238bceSAndroid Build Coastguard Worker {
413*35238bceSAndroid Build Coastguard Worker }
414*35238bceSAndroid Build Coastguard Worker
~SimpleProgramCase(void)415*35238bceSAndroid Build Coastguard Worker virtual ~SimpleProgramCase(void)
416*35238bceSAndroid Build Coastguard Worker {
417*35238bceSAndroid Build Coastguard Worker }
418*35238bceSAndroid Build Coastguard Worker
compileShaders(void)419*35238bceSAndroid Build Coastguard Worker virtual void compileShaders(void)
420*35238bceSAndroid Build Coastguard Worker {
421*35238bceSAndroid Build Coastguard Worker const char *vertSource = getSimpleShaderSource(glu::SHADERTYPE_VERTEX);
422*35238bceSAndroid Build Coastguard Worker const char *fragSource = getSimpleShaderSource(glu::SHADERTYPE_FRAGMENT);
423*35238bceSAndroid Build Coastguard Worker
424*35238bceSAndroid Build Coastguard Worker const GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
425*35238bceSAndroid Build Coastguard Worker const GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
426*35238bceSAndroid Build Coastguard Worker
427*35238bceSAndroid Build Coastguard Worker TCU_CHECK(vertShader != 0);
428*35238bceSAndroid Build Coastguard Worker TCU_CHECK(fragShader != 0);
429*35238bceSAndroid Build Coastguard Worker
430*35238bceSAndroid Build Coastguard Worker glShaderSource(vertShader, 1, &vertSource, 0);
431*35238bceSAndroid Build Coastguard Worker glCompileShader(vertShader);
432*35238bceSAndroid Build Coastguard Worker
433*35238bceSAndroid Build Coastguard Worker glShaderSource(fragShader, 1, &fragSource, 0);
434*35238bceSAndroid Build Coastguard Worker glCompileShader(fragShader);
435*35238bceSAndroid Build Coastguard Worker
436*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
437*35238bceSAndroid Build Coastguard Worker
438*35238bceSAndroid Build Coastguard Worker m_vertShader = vertShader;
439*35238bceSAndroid Build Coastguard Worker m_fragShader = fragShader;
440*35238bceSAndroid Build Coastguard Worker }
441*35238bceSAndroid Build Coastguard Worker
linkProgram(void)442*35238bceSAndroid Build Coastguard Worker void linkProgram(void)
443*35238bceSAndroid Build Coastguard Worker {
444*35238bceSAndroid Build Coastguard Worker const GLuint program = glCreateProgram();
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker TCU_CHECK(program != 0);
447*35238bceSAndroid Build Coastguard Worker
448*35238bceSAndroid Build Coastguard Worker glAttachShader(program, m_vertShader);
449*35238bceSAndroid Build Coastguard Worker glAttachShader(program, m_fragShader);
450*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
451*35238bceSAndroid Build Coastguard Worker
452*35238bceSAndroid Build Coastguard Worker glLinkProgram(program);
453*35238bceSAndroid Build Coastguard Worker
454*35238bceSAndroid Build Coastguard Worker m_program = program;
455*35238bceSAndroid Build Coastguard Worker }
456*35238bceSAndroid Build Coastguard Worker
cleanup(void)457*35238bceSAndroid Build Coastguard Worker void cleanup(void)
458*35238bceSAndroid Build Coastguard Worker {
459*35238bceSAndroid Build Coastguard Worker glDeleteShader(m_vertShader);
460*35238bceSAndroid Build Coastguard Worker glDeleteShader(m_fragShader);
461*35238bceSAndroid Build Coastguard Worker glDeleteProgram(m_program);
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker
464*35238bceSAndroid Build Coastguard Worker protected:
465*35238bceSAndroid Build Coastguard Worker GLuint m_vertShader;
466*35238bceSAndroid Build Coastguard Worker GLuint m_fragShader;
467*35238bceSAndroid Build Coastguard Worker GLuint m_program;
468*35238bceSAndroid Build Coastguard Worker };
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker // glDeleteShader() case
471*35238bceSAndroid Build Coastguard Worker
472*35238bceSAndroid Build Coastguard Worker class DeleteShaderCase : public SimpleProgramCase
473*35238bceSAndroid Build Coastguard Worker {
474*35238bceSAndroid Build Coastguard Worker public:
DeleteShaderCase(Context & context,const char * name,const char * desc)475*35238bceSAndroid Build Coastguard Worker DeleteShaderCase(Context &context, const char *name, const char *desc) : SimpleProgramCase(context, name, desc)
476*35238bceSAndroid Build Coastguard Worker {
477*35238bceSAndroid Build Coastguard Worker }
478*35238bceSAndroid Build Coastguard Worker
checkDeleteStatus(GLuint shader)479*35238bceSAndroid Build Coastguard Worker bool checkDeleteStatus(GLuint shader)
480*35238bceSAndroid Build Coastguard Worker {
481*35238bceSAndroid Build Coastguard Worker GLint deleteStatus = -1;
482*35238bceSAndroid Build Coastguard Worker glGetShaderiv(shader, GL_DELETE_STATUS, &deleteStatus);
483*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
484*35238bceSAndroid Build Coastguard Worker
485*35238bceSAndroid Build Coastguard Worker return (deleteStatus == GL_TRUE);
486*35238bceSAndroid Build Coastguard Worker }
487*35238bceSAndroid Build Coastguard Worker
deleteShaders(void)488*35238bceSAndroid Build Coastguard Worker void deleteShaders(void)
489*35238bceSAndroid Build Coastguard Worker {
490*35238bceSAndroid Build Coastguard Worker glDeleteShader(m_vertShader);
491*35238bceSAndroid Build Coastguard Worker glDeleteShader(m_fragShader);
492*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
493*35238bceSAndroid Build Coastguard Worker }
494*35238bceSAndroid Build Coastguard Worker
test(void)495*35238bceSAndroid Build Coastguard Worker void test(void)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker compileShaders();
498*35238bceSAndroid Build Coastguard Worker linkProgram();
499*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
500*35238bceSAndroid Build Coastguard Worker
501*35238bceSAndroid Build Coastguard Worker deleteShaders();
502*35238bceSAndroid Build Coastguard Worker
503*35238bceSAndroid Build Coastguard Worker TCU_CHECK(checkDeleteStatus(m_vertShader) && checkDeleteStatus(m_fragShader));
504*35238bceSAndroid Build Coastguard Worker
505*35238bceSAndroid Build Coastguard Worker glDeleteProgram(m_program);
506*35238bceSAndroid Build Coastguard Worker
507*35238bceSAndroid Build Coastguard Worker TCU_CHECK(!(glIsShader(m_vertShader) || glIsShader(m_fragShader)));
508*35238bceSAndroid Build Coastguard Worker }
509*35238bceSAndroid Build Coastguard Worker };
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker // Simple glLinkProgram() case
512*35238bceSAndroid Build Coastguard Worker
513*35238bceSAndroid Build Coastguard Worker class LinkVertexFragmentCase : public SimpleProgramCase
514*35238bceSAndroid Build Coastguard Worker {
515*35238bceSAndroid Build Coastguard Worker public:
LinkVertexFragmentCase(Context & context,const char * name,const char * desc)516*35238bceSAndroid Build Coastguard Worker LinkVertexFragmentCase(Context &context, const char *name, const char *desc)
517*35238bceSAndroid Build Coastguard Worker : SimpleProgramCase(context, name, desc)
518*35238bceSAndroid Build Coastguard Worker {
519*35238bceSAndroid Build Coastguard Worker }
520*35238bceSAndroid Build Coastguard Worker
checkLinkStatus(const GLuint programObject)521*35238bceSAndroid Build Coastguard Worker bool checkLinkStatus(const GLuint programObject)
522*35238bceSAndroid Build Coastguard Worker {
523*35238bceSAndroid Build Coastguard Worker GLint linkStatus = -1;
524*35238bceSAndroid Build Coastguard Worker glGetProgramiv(programObject, GL_LINK_STATUS, &linkStatus);
525*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
526*35238bceSAndroid Build Coastguard Worker
527*35238bceSAndroid Build Coastguard Worker return (linkStatus == GL_TRUE);
528*35238bceSAndroid Build Coastguard Worker }
529*35238bceSAndroid Build Coastguard Worker
test(void)530*35238bceSAndroid Build Coastguard Worker void test(void)
531*35238bceSAndroid Build Coastguard Worker {
532*35238bceSAndroid Build Coastguard Worker compileShaders();
533*35238bceSAndroid Build Coastguard Worker linkProgram();
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Linking failed.");
536*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(checkLinkStatus(m_program), "Fail, expected LINK_STATUS to be TRUE.");
537*35238bceSAndroid Build Coastguard Worker
538*35238bceSAndroid Build Coastguard Worker cleanup();
539*35238bceSAndroid Build Coastguard Worker }
540*35238bceSAndroid Build Coastguard Worker };
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker class ShaderSourceReplaceCase : public ApiCase
543*35238bceSAndroid Build Coastguard Worker {
544*35238bceSAndroid Build Coastguard Worker public:
ShaderSourceReplaceCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)545*35238bceSAndroid Build Coastguard Worker ShaderSourceReplaceCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
546*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
547*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker }
550*35238bceSAndroid Build Coastguard Worker
generateFirstSource(void)551*35238bceSAndroid Build Coastguard Worker std::string generateFirstSource(void)
552*35238bceSAndroid Build Coastguard Worker {
553*35238bceSAndroid Build Coastguard Worker return getSimpleShaderSource(m_shaderType);
554*35238bceSAndroid Build Coastguard Worker }
555*35238bceSAndroid Build Coastguard Worker
generateSecondSource(void)556*35238bceSAndroid Build Coastguard Worker std::string generateSecondSource(void)
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker std::string str;
559*35238bceSAndroid Build Coastguard Worker
560*35238bceSAndroid Build Coastguard Worker str = "#version 100\n";
561*35238bceSAndroid Build Coastguard Worker str += "precision highp float;\n\n";
562*35238bceSAndroid Build Coastguard Worker
563*35238bceSAndroid Build Coastguard Worker str += "void main()\n";
564*35238bceSAndroid Build Coastguard Worker str += "{\n";
565*35238bceSAndroid Build Coastguard Worker str += " float variable = 1.0;\n";
566*35238bceSAndroid Build Coastguard Worker
567*35238bceSAndroid Build Coastguard Worker if (m_shaderType == glu::SHADERTYPE_VERTEX)
568*35238bceSAndroid Build Coastguard Worker str += " gl_Position = vec4(variable);\n";
569*35238bceSAndroid Build Coastguard Worker else if (m_shaderType == glu::SHADERTYPE_FRAGMENT)
570*35238bceSAndroid Build Coastguard Worker str += " gl_FragColor = vec4(variable);\n";
571*35238bceSAndroid Build Coastguard Worker
572*35238bceSAndroid Build Coastguard Worker str += "}\n";
573*35238bceSAndroid Build Coastguard Worker
574*35238bceSAndroid Build Coastguard Worker return str;
575*35238bceSAndroid Build Coastguard Worker }
576*35238bceSAndroid Build Coastguard Worker
getSourceLength(glu::Shader & shader)577*35238bceSAndroid Build Coastguard Worker GLint getSourceLength(glu::Shader &shader)
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker GLint sourceLength = 0;
580*35238bceSAndroid Build Coastguard Worker glGetShaderiv(shader.getShader(), GL_SHADER_SOURCE_LENGTH, &sourceLength);
581*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
582*35238bceSAndroid Build Coastguard Worker
583*35238bceSAndroid Build Coastguard Worker return sourceLength;
584*35238bceSAndroid Build Coastguard Worker }
585*35238bceSAndroid Build Coastguard Worker
readSource(glu::Shader & shader)586*35238bceSAndroid Build Coastguard Worker std::string readSource(glu::Shader &shader)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker const GLint sourceLength = getSourceLength(shader);
589*35238bceSAndroid Build Coastguard Worker std::vector<char> sourceBuffer(sourceLength + 1);
590*35238bceSAndroid Build Coastguard Worker
591*35238bceSAndroid Build Coastguard Worker glGetShaderSource(shader.getShader(), (GLsizei)sourceBuffer.size(), 0, &sourceBuffer[0]);
592*35238bceSAndroid Build Coastguard Worker
593*35238bceSAndroid Build Coastguard Worker return std::string(&sourceBuffer[0]);
594*35238bceSAndroid Build Coastguard Worker }
595*35238bceSAndroid Build Coastguard Worker
verifyShaderSourceReplaced(glu::Shader & shader,const std::string & firstSource,const std::string & secondSource)596*35238bceSAndroid Build Coastguard Worker void verifyShaderSourceReplaced(glu::Shader &shader, const std::string &firstSource,
597*35238bceSAndroid Build Coastguard Worker const std::string &secondSource)
598*35238bceSAndroid Build Coastguard Worker {
599*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
600*35238bceSAndroid Build Coastguard Worker const std::string result = readSource(shader);
601*35238bceSAndroid Build Coastguard Worker
602*35238bceSAndroid Build Coastguard Worker if (result == firstSource)
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Fail, source was not replaced." << TestLog::EndMessage;
605*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader source nor replaced");
606*35238bceSAndroid Build Coastguard Worker }
607*35238bceSAndroid Build Coastguard Worker else if (result != secondSource)
608*35238bceSAndroid Build Coastguard Worker {
609*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Fail, invalid shader source." << TestLog::EndMessage;
610*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid source");
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker }
613*35238bceSAndroid Build Coastguard Worker
test(void)614*35238bceSAndroid Build Coastguard Worker void test(void)
615*35238bceSAndroid Build Coastguard Worker {
616*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
617*35238bceSAndroid Build Coastguard Worker
618*35238bceSAndroid Build Coastguard Worker glu::Shader shader(m_context.getRenderContext(), m_shaderType);
619*35238bceSAndroid Build Coastguard Worker
620*35238bceSAndroid Build Coastguard Worker const std::string firstSourceStr = generateFirstSource();
621*35238bceSAndroid Build Coastguard Worker const std::string secondSourceStr = generateSecondSource();
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker const char *firstSource = firstSourceStr.c_str();
624*35238bceSAndroid Build Coastguard Worker const char *secondSource = secondSourceStr.c_str();
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Setting shader source." << TestLog::EndMessage;
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker shader.setSources(1, &firstSource, 0);
629*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
630*35238bceSAndroid Build Coastguard Worker
631*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Replacing shader source." << TestLog::EndMessage;
632*35238bceSAndroid Build Coastguard Worker
633*35238bceSAndroid Build Coastguard Worker shader.setSources(1, &secondSource, 0);
634*35238bceSAndroid Build Coastguard Worker GLU_CHECK();
635*35238bceSAndroid Build Coastguard Worker
636*35238bceSAndroid Build Coastguard Worker verifyShaderSourceReplaced(shader, firstSourceStr, secondSourceStr);
637*35238bceSAndroid Build Coastguard Worker }
638*35238bceSAndroid Build Coastguard Worker
639*35238bceSAndroid Build Coastguard Worker private:
640*35238bceSAndroid Build Coastguard Worker glu::ShaderType m_shaderType;
641*35238bceSAndroid Build Coastguard Worker };
642*35238bceSAndroid Build Coastguard Worker
643*35238bceSAndroid Build Coastguard Worker // glShaderSource() split source case
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker class ShaderSourceSplitCase : public ApiCase
646*35238bceSAndroid Build Coastguard Worker {
647*35238bceSAndroid Build Coastguard Worker public:
ShaderSourceSplitCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType,const int numSlices,const uint32_t flags=0)648*35238bceSAndroid Build Coastguard Worker ShaderSourceSplitCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType,
649*35238bceSAndroid Build Coastguard Worker const int numSlices, const uint32_t flags = 0)
650*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
651*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(getName()) ^ 0x4fb2337d)
652*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
653*35238bceSAndroid Build Coastguard Worker , m_numSlices(numSlices)
654*35238bceSAndroid Build Coastguard Worker , m_explicitLengths((flags & CASE_EXPLICIT_SOURCE_LENGTHS) != 0)
655*35238bceSAndroid Build Coastguard Worker , m_randomNullTerm((flags & CASE_RANDOM_NULL_TERMINATED) != 0)
656*35238bceSAndroid Build Coastguard Worker {
657*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
658*35238bceSAndroid Build Coastguard Worker }
659*35238bceSAndroid Build Coastguard Worker
~ShaderSourceSplitCase(void)660*35238bceSAndroid Build Coastguard Worker virtual ~ShaderSourceSplitCase(void)
661*35238bceSAndroid Build Coastguard Worker {
662*35238bceSAndroid Build Coastguard Worker }
663*35238bceSAndroid Build Coastguard Worker
generateFullSource(void)664*35238bceSAndroid Build Coastguard Worker std::string generateFullSource(void)
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker std::string str;
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker str = "#version 100\n";
669*35238bceSAndroid Build Coastguard Worker str += "precision highp float;\n\n";
670*35238bceSAndroid Build Coastguard Worker
671*35238bceSAndroid Build Coastguard Worker str += "void main()\n";
672*35238bceSAndroid Build Coastguard Worker str += "{\n";
673*35238bceSAndroid Build Coastguard Worker str += " float variable = 1.0;\n";
674*35238bceSAndroid Build Coastguard Worker
675*35238bceSAndroid Build Coastguard Worker if (m_shaderType == glu::SHADERTYPE_VERTEX)
676*35238bceSAndroid Build Coastguard Worker str += " gl_Position = vec4(variable);\n";
677*35238bceSAndroid Build Coastguard Worker else if (m_shaderType == glu::SHADERTYPE_FRAGMENT)
678*35238bceSAndroid Build Coastguard Worker str += " gl_FragColor = vec4(variable);\n";
679*35238bceSAndroid Build Coastguard Worker
680*35238bceSAndroid Build Coastguard Worker str += "}\n";
681*35238bceSAndroid Build Coastguard Worker
682*35238bceSAndroid Build Coastguard Worker return str;
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker
insertRandomNullTermStrings(ShaderSources & sources)685*35238bceSAndroid Build Coastguard Worker void insertRandomNullTermStrings(ShaderSources &sources)
686*35238bceSAndroid Build Coastguard Worker {
687*35238bceSAndroid Build Coastguard Worker const int numInserts = de::max(m_numSlices >> 2, 1);
688*35238bceSAndroid Build Coastguard Worker std::vector<int> indices(sources.strings.size(), 0);
689*35238bceSAndroid Build Coastguard Worker
690*35238bceSAndroid Build Coastguard Worker DE_ASSERT(sources.lengths.size() > 0);
691*35238bceSAndroid Build Coastguard Worker DE_ASSERT(sources.lengths.size() == sources.strings.size());
692*35238bceSAndroid Build Coastguard Worker
693*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)sources.strings.size(); i++)
694*35238bceSAndroid Build Coastguard Worker indices[i] = i;
695*35238bceSAndroid Build Coastguard Worker
696*35238bceSAndroid Build Coastguard Worker m_rnd.shuffle(indices.begin(), indices.end());
697*35238bceSAndroid Build Coastguard Worker
698*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numInserts; i++)
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker const int ndx = indices[i];
701*35238bceSAndroid Build Coastguard Worker const int unpaddedLength = sources.lengths[ndx];
702*35238bceSAndroid Build Coastguard Worker const std::string unpaddedString = sources.strings[ndx].substr(0, unpaddedLength);
703*35238bceSAndroid Build Coastguard Worker
704*35238bceSAndroid Build Coastguard Worker sources.strings[ndx] = unpaddedString;
705*35238bceSAndroid Build Coastguard Worker sources.lengths[ndx] = m_rnd.getInt(-10, -1);
706*35238bceSAndroid Build Coastguard Worker }
707*35238bceSAndroid Build Coastguard Worker }
708*35238bceSAndroid Build Coastguard Worker
generateSources(ShaderSources & sources)709*35238bceSAndroid Build Coastguard Worker void generateSources(ShaderSources &sources)
710*35238bceSAndroid Build Coastguard Worker {
711*35238bceSAndroid Build Coastguard Worker const size_t paddingLength = (m_explicitLengths ? 10 : 0);
712*35238bceSAndroid Build Coastguard Worker std::string str = generateFullSource();
713*35238bceSAndroid Build Coastguard Worker
714*35238bceSAndroid Build Coastguard Worker sliceSourceString(str, sources, m_numSlices, paddingLength);
715*35238bceSAndroid Build Coastguard Worker
716*35238bceSAndroid Build Coastguard Worker if (m_randomNullTerm)
717*35238bceSAndroid Build Coastguard Worker insertRandomNullTermStrings(sources);
718*35238bceSAndroid Build Coastguard Worker }
719*35238bceSAndroid Build Coastguard Worker
buildProgram(glu::Shader & shader)720*35238bceSAndroid Build Coastguard Worker void buildProgram(glu::Shader &shader)
721*35238bceSAndroid Build Coastguard Worker {
722*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
723*35238bceSAndroid Build Coastguard Worker glu::RenderContext &renderCtx = m_context.getRenderContext();
724*35238bceSAndroid Build Coastguard Worker
725*35238bceSAndroid Build Coastguard Worker const glu::ShaderType supportShaderType =
726*35238bceSAndroid Build Coastguard Worker (m_shaderType == glu::SHADERTYPE_FRAGMENT ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT);
727*35238bceSAndroid Build Coastguard Worker const char *supportShaderSource = getSimpleShaderSource(supportShaderType);
728*35238bceSAndroid Build Coastguard Worker glu::Shader supportShader(renderCtx, supportShaderType);
729*35238bceSAndroid Build Coastguard Worker
730*35238bceSAndroid Build Coastguard Worker glu::Program program(renderCtx);
731*35238bceSAndroid Build Coastguard Worker
732*35238bceSAndroid Build Coastguard Worker supportShader.setSources(1, &supportShaderSource, 0);
733*35238bceSAndroid Build Coastguard Worker supportShader.compile();
734*35238bceSAndroid Build Coastguard Worker
735*35238bceSAndroid Build Coastguard Worker program.attachShader(shader.getShader());
736*35238bceSAndroid Build Coastguard Worker program.attachShader(supportShader.getShader());
737*35238bceSAndroid Build Coastguard Worker
738*35238bceSAndroid Build Coastguard Worker program.link();
739*35238bceSAndroid Build Coastguard Worker
740*35238bceSAndroid Build Coastguard Worker if (m_shaderType == glu::SHADERTYPE_VERTEX)
741*35238bceSAndroid Build Coastguard Worker logVertexFragmentProgram(log, renderCtx, program, shader, supportShader);
742*35238bceSAndroid Build Coastguard Worker else
743*35238bceSAndroid Build Coastguard Worker logVertexFragmentProgram(log, renderCtx, program, supportShader, shader);
744*35238bceSAndroid Build Coastguard Worker }
745*35238bceSAndroid Build Coastguard Worker
test(void)746*35238bceSAndroid Build Coastguard Worker void test(void)
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
749*35238bceSAndroid Build Coastguard Worker glu::RenderContext &renderCtx = m_context.getRenderContext();
750*35238bceSAndroid Build Coastguard Worker
751*35238bceSAndroid Build Coastguard Worker ShaderSources sources;
752*35238bceSAndroid Build Coastguard Worker glu::Shader shader(renderCtx, m_shaderType);
753*35238bceSAndroid Build Coastguard Worker
754*35238bceSAndroid Build Coastguard Worker generateSources(sources);
755*35238bceSAndroid Build Coastguard Worker setShaderSources(shader, sources);
756*35238bceSAndroid Build Coastguard Worker shader.compile();
757*35238bceSAndroid Build Coastguard Worker
758*35238bceSAndroid Build Coastguard Worker buildProgram(shader);
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker if (!shader.getCompileStatus())
761*35238bceSAndroid Build Coastguard Worker {
762*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Compilation failed." << TestLog::EndMessage;
763*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
764*35238bceSAndroid Build Coastguard Worker }
765*35238bceSAndroid Build Coastguard Worker }
766*35238bceSAndroid Build Coastguard Worker
767*35238bceSAndroid Build Coastguard Worker private:
768*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
769*35238bceSAndroid Build Coastguard Worker
770*35238bceSAndroid Build Coastguard Worker glu::ShaderType m_shaderType;
771*35238bceSAndroid Build Coastguard Worker const int m_numSlices;
772*35238bceSAndroid Build Coastguard Worker
773*35238bceSAndroid Build Coastguard Worker const bool m_explicitLengths;
774*35238bceSAndroid Build Coastguard Worker const bool m_randomNullTerm;
775*35238bceSAndroid Build Coastguard Worker };
776*35238bceSAndroid Build Coastguard Worker
777*35238bceSAndroid Build Coastguard Worker // Base class for program state persistence cases
778*35238bceSAndroid Build Coastguard Worker
779*35238bceSAndroid Build Coastguard Worker class ProgramStateCase : public ApiCase
780*35238bceSAndroid Build Coastguard Worker {
781*35238bceSAndroid Build Coastguard Worker public:
782*35238bceSAndroid Build Coastguard Worker ProgramStateCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType);
~ProgramStateCase(void)783*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateCase(void)
784*35238bceSAndroid Build Coastguard Worker {
785*35238bceSAndroid Build Coastguard Worker }
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker void buildProgram(glu::Program &program, ShaderAllocator &shaders);
788*35238bceSAndroid Build Coastguard Worker void verify(glu::Program &program, const glu::ProgramInfo &reference);
789*35238bceSAndroid Build Coastguard Worker
790*35238bceSAndroid Build Coastguard Worker void test(void);
791*35238bceSAndroid Build Coastguard Worker
792*35238bceSAndroid Build Coastguard Worker virtual void executeForProgram(glu::Program &program, ShaderAllocator &shaders) = 0;
793*35238bceSAndroid Build Coastguard Worker
794*35238bceSAndroid Build Coastguard Worker protected:
795*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
796*35238bceSAndroid Build Coastguard Worker const glu::ShaderType m_shaderType;
797*35238bceSAndroid Build Coastguard Worker };
798*35238bceSAndroid Build Coastguard Worker
ProgramStateCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)799*35238bceSAndroid Build Coastguard Worker ProgramStateCase::ProgramStateCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
800*35238bceSAndroid Build Coastguard Worker : ApiCase(context, name, desc)
801*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(name) ^ 0x713de0ca)
802*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
803*35238bceSAndroid Build Coastguard Worker {
804*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
805*35238bceSAndroid Build Coastguard Worker }
806*35238bceSAndroid Build Coastguard Worker
buildProgram(glu::Program & program,ShaderAllocator & shaders)807*35238bceSAndroid Build Coastguard Worker void ProgramStateCase::buildProgram(glu::Program &program, ShaderAllocator &shaders)
808*35238bceSAndroid Build Coastguard Worker {
809*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
810*35238bceSAndroid Build Coastguard Worker
811*35238bceSAndroid Build Coastguard Worker glu::Shader &vertShader = shaders.createShader(glu::SHADERTYPE_VERTEX);
812*35238bceSAndroid Build Coastguard Worker glu::Shader &fragShader = shaders.createShader(glu::SHADERTYPE_FRAGMENT);
813*35238bceSAndroid Build Coastguard Worker
814*35238bceSAndroid Build Coastguard Worker vertShader.compile();
815*35238bceSAndroid Build Coastguard Worker fragShader.compile();
816*35238bceSAndroid Build Coastguard Worker
817*35238bceSAndroid Build Coastguard Worker program.attachShader(vertShader.getShader());
818*35238bceSAndroid Build Coastguard Worker program.attachShader(fragShader.getShader());
819*35238bceSAndroid Build Coastguard Worker program.link();
820*35238bceSAndroid Build Coastguard Worker
821*35238bceSAndroid Build Coastguard Worker logProgram(log, m_context.getRenderContext(), program, shaders);
822*35238bceSAndroid Build Coastguard Worker }
823*35238bceSAndroid Build Coastguard Worker
verify(glu::Program & program,const glu::ProgramInfo & reference)824*35238bceSAndroid Build Coastguard Worker void ProgramStateCase::verify(glu::Program &program, const glu::ProgramInfo &reference)
825*35238bceSAndroid Build Coastguard Worker {
826*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
827*35238bceSAndroid Build Coastguard Worker const glu::ProgramInfo &programInfo = program.getInfo();
828*35238bceSAndroid Build Coastguard Worker
829*35238bceSAndroid Build Coastguard Worker if (!programInfo.linkOk)
830*35238bceSAndroid Build Coastguard Worker {
831*35238bceSAndroid Build Coastguard Worker log << TestLog::Message
832*35238bceSAndroid Build Coastguard Worker << "Fail, link status may only change as a result of linking or loading a program binary."
833*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
834*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Link status changed");
835*35238bceSAndroid Build Coastguard Worker }
836*35238bceSAndroid Build Coastguard Worker
837*35238bceSAndroid Build Coastguard Worker if (programInfo.linkTimeUs != reference.linkTimeUs)
838*35238bceSAndroid Build Coastguard Worker {
839*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Fail, reported link time changed." << TestLog::EndMessage;
840*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Link time changed");
841*35238bceSAndroid Build Coastguard Worker }
842*35238bceSAndroid Build Coastguard Worker
843*35238bceSAndroid Build Coastguard Worker if (programInfo.infoLog != reference.infoLog)
844*35238bceSAndroid Build Coastguard Worker {
845*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Fail, program infolog changed." << TestLog::EndMessage;
846*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Infolog changed");
847*35238bceSAndroid Build Coastguard Worker }
848*35238bceSAndroid Build Coastguard Worker }
849*35238bceSAndroid Build Coastguard Worker
test(void)850*35238bceSAndroid Build Coastguard Worker void ProgramStateCase::test(void)
851*35238bceSAndroid Build Coastguard Worker {
852*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
853*35238bceSAndroid Build Coastguard Worker glu::RenderContext &renderCtx = m_context.getRenderContext();
854*35238bceSAndroid Build Coastguard Worker
855*35238bceSAndroid Build Coastguard Worker ConstantShaderGenerator sourceGen(m_rnd);
856*35238bceSAndroid Build Coastguard Worker
857*35238bceSAndroid Build Coastguard Worker ShaderAllocator shaders(renderCtx, sourceGen);
858*35238bceSAndroid Build Coastguard Worker glu::Program program(renderCtx);
859*35238bceSAndroid Build Coastguard Worker
860*35238bceSAndroid Build Coastguard Worker buildProgram(program, shaders);
861*35238bceSAndroid Build Coastguard Worker
862*35238bceSAndroid Build Coastguard Worker if (program.getLinkStatus())
863*35238bceSAndroid Build Coastguard Worker {
864*35238bceSAndroid Build Coastguard Worker glu::ProgramInfo programInfo = program.getInfo();
865*35238bceSAndroid Build Coastguard Worker
866*35238bceSAndroid Build Coastguard Worker executeForProgram(program, shaders);
867*35238bceSAndroid Build Coastguard Worker
868*35238bceSAndroid Build Coastguard Worker verify(program, programInfo);
869*35238bceSAndroid Build Coastguard Worker
870*35238bceSAndroid Build Coastguard Worker logProgram(log, renderCtx, program, shaders);
871*35238bceSAndroid Build Coastguard Worker }
872*35238bceSAndroid Build Coastguard Worker else
873*35238bceSAndroid Build Coastguard Worker {
874*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Fail, couldn't link program." << TestLog::EndMessage;
875*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Linking failed");
876*35238bceSAndroid Build Coastguard Worker }
877*35238bceSAndroid Build Coastguard Worker }
878*35238bceSAndroid Build Coastguard Worker
879*35238bceSAndroid Build Coastguard Worker // Program state case utilities
880*35238bceSAndroid Build Coastguard Worker
881*35238bceSAndroid Build Coastguard Worker namespace
882*35238bceSAndroid Build Coastguard Worker {
883*35238bceSAndroid Build Coastguard Worker
884*35238bceSAndroid Build Coastguard Worker template <class T>
addProgramStateCase(TestCaseGroup * group,Context & context,const std::string & name,const std::string & desc)885*35238bceSAndroid Build Coastguard Worker void addProgramStateCase(TestCaseGroup *group, Context &context, const std::string &name, const std::string &desc)
886*35238bceSAndroid Build Coastguard Worker {
887*35238bceSAndroid Build Coastguard Worker for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
888*35238bceSAndroid Build Coastguard Worker {
889*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType = (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
890*35238bceSAndroid Build Coastguard Worker const std::string shaderTypeName = getShaderTypeName(shaderType);
891*35238bceSAndroid Build Coastguard Worker
892*35238bceSAndroid Build Coastguard Worker const std::string caseName = name + "_" + shaderTypeName;
893*35238bceSAndroid Build Coastguard Worker const std::string caseDesc = "Build program, " + desc + ", for " + shaderTypeName + " shader.";
894*35238bceSAndroid Build Coastguard Worker
895*35238bceSAndroid Build Coastguard Worker group->addChild(new T(context, caseName.c_str(), caseDesc.c_str(), shaderType));
896*35238bceSAndroid Build Coastguard Worker }
897*35238bceSAndroid Build Coastguard Worker }
898*35238bceSAndroid Build Coastguard Worker
899*35238bceSAndroid Build Coastguard Worker } // namespace
900*35238bceSAndroid Build Coastguard Worker
901*35238bceSAndroid Build Coastguard Worker // Specialized program state cases
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker class ProgramStateDetachShaderCase : public ProgramStateCase
904*35238bceSAndroid Build Coastguard Worker {
905*35238bceSAndroid Build Coastguard Worker public:
ProgramStateDetachShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)906*35238bceSAndroid Build Coastguard Worker ProgramStateDetachShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
907*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
908*35238bceSAndroid Build Coastguard Worker {
909*35238bceSAndroid Build Coastguard Worker }
910*35238bceSAndroid Build Coastguard Worker
~ProgramStateDetachShaderCase(void)911*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateDetachShaderCase(void)
912*35238bceSAndroid Build Coastguard Worker {
913*35238bceSAndroid Build Coastguard Worker }
914*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)915*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
916*35238bceSAndroid Build Coastguard Worker {
917*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
918*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
919*35238bceSAndroid Build Coastguard Worker
920*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Detaching " + std::string(getShaderTypeName(m_shaderType)) + " shader"
921*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
922*35238bceSAndroid Build Coastguard Worker program.detachShader(caseShader.getShader());
923*35238bceSAndroid Build Coastguard Worker }
924*35238bceSAndroid Build Coastguard Worker };
925*35238bceSAndroid Build Coastguard Worker
926*35238bceSAndroid Build Coastguard Worker class ProgramStateReattachShaderCase : public ProgramStateCase
927*35238bceSAndroid Build Coastguard Worker {
928*35238bceSAndroid Build Coastguard Worker public:
ProgramStateReattachShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)929*35238bceSAndroid Build Coastguard Worker ProgramStateReattachShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
930*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
931*35238bceSAndroid Build Coastguard Worker {
932*35238bceSAndroid Build Coastguard Worker }
933*35238bceSAndroid Build Coastguard Worker
~ProgramStateReattachShaderCase(void)934*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateReattachShaderCase(void)
935*35238bceSAndroid Build Coastguard Worker {
936*35238bceSAndroid Build Coastguard Worker }
937*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)938*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
939*35238bceSAndroid Build Coastguard Worker {
940*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
941*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
942*35238bceSAndroid Build Coastguard Worker
943*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Reattaching " + std::string(getShaderTypeName(m_shaderType)) + " shader"
944*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
945*35238bceSAndroid Build Coastguard Worker program.detachShader(caseShader.getShader());
946*35238bceSAndroid Build Coastguard Worker program.attachShader(caseShader.getShader());
947*35238bceSAndroid Build Coastguard Worker }
948*35238bceSAndroid Build Coastguard Worker };
949*35238bceSAndroid Build Coastguard Worker
950*35238bceSAndroid Build Coastguard Worker class ProgramStateDeleteShaderCase : public ProgramStateCase
951*35238bceSAndroid Build Coastguard Worker {
952*35238bceSAndroid Build Coastguard Worker public:
ProgramStateDeleteShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)953*35238bceSAndroid Build Coastguard Worker ProgramStateDeleteShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
954*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
955*35238bceSAndroid Build Coastguard Worker {
956*35238bceSAndroid Build Coastguard Worker }
957*35238bceSAndroid Build Coastguard Worker
~ProgramStateDeleteShaderCase(void)958*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateDeleteShaderCase(void)
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker }
961*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)962*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
963*35238bceSAndroid Build Coastguard Worker {
964*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
965*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
966*35238bceSAndroid Build Coastguard Worker
967*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Deleting " + std::string(getShaderTypeName(m_shaderType)) + " shader"
968*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
969*35238bceSAndroid Build Coastguard Worker program.detachShader(caseShader.getShader());
970*35238bceSAndroid Build Coastguard Worker shaders.deleteShader(m_shaderType);
971*35238bceSAndroid Build Coastguard Worker }
972*35238bceSAndroid Build Coastguard Worker };
973*35238bceSAndroid Build Coastguard Worker
974*35238bceSAndroid Build Coastguard Worker class ProgramStateReplaceShaderCase : public ProgramStateCase
975*35238bceSAndroid Build Coastguard Worker {
976*35238bceSAndroid Build Coastguard Worker public:
ProgramStateReplaceShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)977*35238bceSAndroid Build Coastguard Worker ProgramStateReplaceShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
978*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
979*35238bceSAndroid Build Coastguard Worker {
980*35238bceSAndroid Build Coastguard Worker }
981*35238bceSAndroid Build Coastguard Worker
~ProgramStateReplaceShaderCase(void)982*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateReplaceShaderCase(void)
983*35238bceSAndroid Build Coastguard Worker {
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)986*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
987*35238bceSAndroid Build Coastguard Worker {
988*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
989*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
990*35238bceSAndroid Build Coastguard Worker
991*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Deleting and replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader"
992*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
993*35238bceSAndroid Build Coastguard Worker program.detachShader(caseShader.getShader());
994*35238bceSAndroid Build Coastguard Worker shaders.deleteShader(m_shaderType);
995*35238bceSAndroid Build Coastguard Worker program.attachShader(shaders.createShader(m_shaderType).getShader());
996*35238bceSAndroid Build Coastguard Worker }
997*35238bceSAndroid Build Coastguard Worker };
998*35238bceSAndroid Build Coastguard Worker
999*35238bceSAndroid Build Coastguard Worker class ProgramStateRecompileShaderCase : public ProgramStateCase
1000*35238bceSAndroid Build Coastguard Worker {
1001*35238bceSAndroid Build Coastguard Worker public:
ProgramStateRecompileShaderCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)1002*35238bceSAndroid Build Coastguard Worker ProgramStateRecompileShaderCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
1003*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
1004*35238bceSAndroid Build Coastguard Worker {
1005*35238bceSAndroid Build Coastguard Worker }
1006*35238bceSAndroid Build Coastguard Worker
~ProgramStateRecompileShaderCase(void)1007*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateRecompileShaderCase(void)
1008*35238bceSAndroid Build Coastguard Worker {
1009*35238bceSAndroid Build Coastguard Worker }
1010*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)1011*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
1012*35238bceSAndroid Build Coastguard Worker {
1013*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
1014*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
1015*35238bceSAndroid Build Coastguard Worker
1016*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Recompiling " + std::string(getShaderTypeName(m_shaderType)) + " shader"
1017*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1018*35238bceSAndroid Build Coastguard Worker caseShader.compile();
1019*35238bceSAndroid Build Coastguard Worker DE_UNREF(program);
1020*35238bceSAndroid Build Coastguard Worker }
1021*35238bceSAndroid Build Coastguard Worker };
1022*35238bceSAndroid Build Coastguard Worker
1023*35238bceSAndroid Build Coastguard Worker class ProgramStateReplaceSourceCase : public ProgramStateCase
1024*35238bceSAndroid Build Coastguard Worker {
1025*35238bceSAndroid Build Coastguard Worker public:
ProgramStateReplaceSourceCase(Context & context,const char * name,const char * desc,glu::ShaderType shaderType)1026*35238bceSAndroid Build Coastguard Worker ProgramStateReplaceSourceCase(Context &context, const char *name, const char *desc, glu::ShaderType shaderType)
1027*35238bceSAndroid Build Coastguard Worker : ProgramStateCase(context, name, desc, shaderType)
1028*35238bceSAndroid Build Coastguard Worker {
1029*35238bceSAndroid Build Coastguard Worker }
1030*35238bceSAndroid Build Coastguard Worker
~ProgramStateReplaceSourceCase(void)1031*35238bceSAndroid Build Coastguard Worker virtual ~ProgramStateReplaceSourceCase(void)
1032*35238bceSAndroid Build Coastguard Worker {
1033*35238bceSAndroid Build Coastguard Worker }
1034*35238bceSAndroid Build Coastguard Worker
executeForProgram(glu::Program & program,ShaderAllocator & shaders)1035*35238bceSAndroid Build Coastguard Worker void executeForProgram(glu::Program &program, ShaderAllocator &shaders)
1036*35238bceSAndroid Build Coastguard Worker {
1037*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
1038*35238bceSAndroid Build Coastguard Worker glu::Shader &caseShader = shaders.get(m_shaderType);
1039*35238bceSAndroid Build Coastguard Worker
1040*35238bceSAndroid Build Coastguard Worker log << TestLog::Message
1041*35238bceSAndroid Build Coastguard Worker << "Replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader source and recompiling"
1042*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1043*35238bceSAndroid Build Coastguard Worker shaders.setSource(m_shaderType);
1044*35238bceSAndroid Build Coastguard Worker caseShader.compile();
1045*35238bceSAndroid Build Coastguard Worker DE_UNREF(program);
1046*35238bceSAndroid Build Coastguard Worker }
1047*35238bceSAndroid Build Coastguard Worker };
1048*35238bceSAndroid Build Coastguard Worker
1049*35238bceSAndroid Build Coastguard Worker // Test group
1050*35238bceSAndroid Build Coastguard Worker
ShaderApiTests(Context & context)1051*35238bceSAndroid Build Coastguard Worker ShaderApiTests::ShaderApiTests(Context &context) : TestCaseGroup(context, "shader_api", "Shader API Cases")
1052*35238bceSAndroid Build Coastguard Worker {
1053*35238bceSAndroid Build Coastguard Worker }
1054*35238bceSAndroid Build Coastguard Worker
~ShaderApiTests(void)1055*35238bceSAndroid Build Coastguard Worker ShaderApiTests::~ShaderApiTests(void)
1056*35238bceSAndroid Build Coastguard Worker {
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker
init(void)1059*35238bceSAndroid Build Coastguard Worker void ShaderApiTests::init(void)
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker // create and delete shaders
1062*35238bceSAndroid Build Coastguard Worker {
1063*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createDeleteGroup = new TestCaseGroup(m_context, "create_delete", "glCreateShader() tests");
1064*35238bceSAndroid Build Coastguard Worker addChild(createDeleteGroup);
1065*35238bceSAndroid Build Coastguard Worker
1066*35238bceSAndroid Build Coastguard Worker createDeleteGroup->addChild(new CreateShaderCase(m_context, "create_vertex_shader",
1067*35238bceSAndroid Build Coastguard Worker "Create vertex shader object", glu::SHADERTYPE_VERTEX));
1068*35238bceSAndroid Build Coastguard Worker createDeleteGroup->addChild(new CreateShaderCase(m_context, "create_fragment_shader",
1069*35238bceSAndroid Build Coastguard Worker "Create fragment shader object", glu::SHADERTYPE_FRAGMENT));
1070*35238bceSAndroid Build Coastguard Worker
1071*35238bceSAndroid Build Coastguard Worker createDeleteGroup->addChild(
1072*35238bceSAndroid Build Coastguard Worker new DeleteShaderCase(m_context, "delete_vertex_fragment", "Delete vertex shader and fragment shader"));
1073*35238bceSAndroid Build Coastguard Worker }
1074*35238bceSAndroid Build Coastguard Worker
1075*35238bceSAndroid Build Coastguard Worker // compile and link
1076*35238bceSAndroid Build Coastguard Worker {
1077*35238bceSAndroid Build Coastguard Worker TestCaseGroup *compileLinkGroup = new TestCaseGroup(m_context, "compile_link", "Compile and link tests");
1078*35238bceSAndroid Build Coastguard Worker addChild(compileLinkGroup);
1079*35238bceSAndroid Build Coastguard Worker
1080*35238bceSAndroid Build Coastguard Worker compileLinkGroup->addChild(
1081*35238bceSAndroid Build Coastguard Worker new CompileShaderCase(m_context, "compile_vertex_shader", "Compile vertex shader", glu::SHADERTYPE_VERTEX));
1082*35238bceSAndroid Build Coastguard Worker compileLinkGroup->addChild(new CompileShaderCase(m_context, "compile_fragment_shader",
1083*35238bceSAndroid Build Coastguard Worker "Compile fragment shader", glu::SHADERTYPE_FRAGMENT));
1084*35238bceSAndroid Build Coastguard Worker
1085*35238bceSAndroid Build Coastguard Worker compileLinkGroup->addChild(
1086*35238bceSAndroid Build Coastguard Worker new LinkVertexFragmentCase(m_context, "link_vertex_fragment", "Link vertex and fragment shaders"));
1087*35238bceSAndroid Build Coastguard Worker }
1088*35238bceSAndroid Build Coastguard Worker
1089*35238bceSAndroid Build Coastguard Worker // shader source
1090*35238bceSAndroid Build Coastguard Worker {
1091*35238bceSAndroid Build Coastguard Worker TestCaseGroup *shaderSourceGroup = new TestCaseGroup(m_context, "shader_source", "glShaderSource() tests");
1092*35238bceSAndroid Build Coastguard Worker addChild(shaderSourceGroup);
1093*35238bceSAndroid Build Coastguard Worker
1094*35238bceSAndroid Build Coastguard Worker for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
1095*35238bceSAndroid Build Coastguard Worker {
1096*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType = (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
1097*35238bceSAndroid Build Coastguard Worker
1098*35238bceSAndroid Build Coastguard Worker const std::string caseName =
1099*35238bceSAndroid Build Coastguard Worker std::string("replace_source") + ((shaderType == glu::SHADERTYPE_FRAGMENT) ? "_fragment" : "_vertex");
1100*35238bceSAndroid Build Coastguard Worker const std::string caseDesc = std::string("Replace source code of ") +
1101*35238bceSAndroid Build Coastguard Worker ((shaderType == glu::SHADERTYPE_FRAGMENT) ? "fragment" : "vertex") +
1102*35238bceSAndroid Build Coastguard Worker " shader.";
1103*35238bceSAndroid Build Coastguard Worker
1104*35238bceSAndroid Build Coastguard Worker shaderSourceGroup->addChild(
1105*35238bceSAndroid Build Coastguard Worker new ShaderSourceReplaceCase(m_context, caseName.c_str(), caseDesc.c_str(), shaderType));
1106*35238bceSAndroid Build Coastguard Worker }
1107*35238bceSAndroid Build Coastguard Worker
1108*35238bceSAndroid Build Coastguard Worker for (int stringLengthsInt = 0; stringLengthsInt < 3; stringLengthsInt++)
1109*35238bceSAndroid Build Coastguard Worker for (int caseNdx = 1; caseNdx <= 3; caseNdx++)
1110*35238bceSAndroid Build Coastguard Worker for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
1111*35238bceSAndroid Build Coastguard Worker {
1112*35238bceSAndroid Build Coastguard Worker const int numSlices = 1 << caseNdx;
1113*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType =
1114*35238bceSAndroid Build Coastguard Worker (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
1115*35238bceSAndroid Build Coastguard Worker
1116*35238bceSAndroid Build Coastguard Worker const bool explicitLengths = (stringLengthsInt != 0);
1117*35238bceSAndroid Build Coastguard Worker const bool randomNullTerm = (stringLengthsInt == 2);
1118*35238bceSAndroid Build Coastguard Worker
1119*35238bceSAndroid Build Coastguard Worker const uint32_t flags = (explicitLengths ? CASE_EXPLICIT_SOURCE_LENGTHS : 0) |
1120*35238bceSAndroid Build Coastguard Worker (randomNullTerm ? CASE_RANDOM_NULL_TERMINATED : 0);
1121*35238bceSAndroid Build Coastguard Worker
1122*35238bceSAndroid Build Coastguard Worker const std::string caseName =
1123*35238bceSAndroid Build Coastguard Worker "split_source_" + de::toString(numSlices) +
1124*35238bceSAndroid Build Coastguard Worker (randomNullTerm ? "_random_negative_length" :
1125*35238bceSAndroid Build Coastguard Worker (explicitLengths ? "_specify_lengths" : "_null_terminated")) +
1126*35238bceSAndroid Build Coastguard Worker ((shaderType == glu::SHADERTYPE_FRAGMENT) ? "_fragment" : "_vertex");
1127*35238bceSAndroid Build Coastguard Worker
1128*35238bceSAndroid Build Coastguard Worker const std::string caseDesc =
1129*35238bceSAndroid Build Coastguard Worker std::string((shaderType == glu::SHADERTYPE_FRAGMENT) ? "Fragment" : "Vertex") +
1130*35238bceSAndroid Build Coastguard Worker " shader source split into " + de::toString(numSlices) + " pieces" +
1131*35238bceSAndroid Build Coastguard Worker (explicitLengths ? ", using explicitly specified string lengths" : "") +
1132*35238bceSAndroid Build Coastguard Worker (randomNullTerm ? " with random negative length values" : "");
1133*35238bceSAndroid Build Coastguard Worker
1134*35238bceSAndroid Build Coastguard Worker shaderSourceGroup->addChild(new ShaderSourceSplitCase(m_context, caseName.c_str(), caseDesc.c_str(),
1135*35238bceSAndroid Build Coastguard Worker shaderType, numSlices, flags));
1136*35238bceSAndroid Build Coastguard Worker }
1137*35238bceSAndroid Build Coastguard Worker }
1138*35238bceSAndroid Build Coastguard Worker
1139*35238bceSAndroid Build Coastguard Worker // link status and infolog
1140*35238bceSAndroid Build Coastguard Worker {
1141*35238bceSAndroid Build Coastguard Worker TestCaseGroup *linkStatusGroup =
1142*35238bceSAndroid Build Coastguard Worker new TestCaseGroup(m_context, "program_state", "Program state persistence tests");
1143*35238bceSAndroid Build Coastguard Worker addChild(linkStatusGroup);
1144*35238bceSAndroid Build Coastguard Worker
1145*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateDetachShaderCase>(linkStatusGroup, m_context, "detach_shader", "detach shader");
1146*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateReattachShaderCase>(linkStatusGroup, m_context, "reattach_shader",
1147*35238bceSAndroid Build Coastguard Worker "reattach shader");
1148*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateDeleteShaderCase>(linkStatusGroup, m_context, "delete_shader", "delete shader");
1149*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateReplaceShaderCase>(linkStatusGroup, m_context, "replace_shader",
1150*35238bceSAndroid Build Coastguard Worker "replace shader object");
1151*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateRecompileShaderCase>(linkStatusGroup, m_context, "recompile_shader",
1152*35238bceSAndroid Build Coastguard Worker "recompile shader");
1153*35238bceSAndroid Build Coastguard Worker addProgramStateCase<ProgramStateReplaceSourceCase>(linkStatusGroup, m_context, "replace_source",
1154*35238bceSAndroid Build Coastguard Worker "replace shader source");
1155*35238bceSAndroid Build Coastguard Worker }
1156*35238bceSAndroid Build Coastguard Worker }
1157*35238bceSAndroid Build Coastguard Worker
1158*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1159*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1160*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1161