1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES Utilities
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 Wrapper for GL program object.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker #include <cstring>
32*35238bceSAndroid Build Coastguard Worker
33*35238bceSAndroid Build Coastguard Worker using std::string;
34*35238bceSAndroid Build Coastguard Worker
35*35238bceSAndroid Build Coastguard Worker namespace glu
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker
38*35238bceSAndroid Build Coastguard Worker // Shader
39*35238bceSAndroid Build Coastguard Worker
Shader(const RenderContext & renderCtx,ShaderType shaderType)40*35238bceSAndroid Build Coastguard Worker Shader::Shader(const RenderContext &renderCtx, ShaderType shaderType) : m_gl(renderCtx.getFunctions()), m_shader(0)
41*35238bceSAndroid Build Coastguard Worker {
42*35238bceSAndroid Build Coastguard Worker m_info.type = shaderType;
43*35238bceSAndroid Build Coastguard Worker m_shader = m_gl.createShader(getGLShaderType(shaderType));
44*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateShader()");
45*35238bceSAndroid Build Coastguard Worker TCU_CHECK(m_shader);
46*35238bceSAndroid Build Coastguard Worker }
47*35238bceSAndroid Build Coastguard Worker
Shader(const glw::Functions & gl,ShaderType shaderType)48*35238bceSAndroid Build Coastguard Worker Shader::Shader(const glw::Functions &gl, ShaderType shaderType) : m_gl(gl), m_shader(0)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker m_info.type = shaderType;
51*35238bceSAndroid Build Coastguard Worker m_shader = m_gl.createShader(getGLShaderType(shaderType));
52*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateShader()");
53*35238bceSAndroid Build Coastguard Worker TCU_CHECK(m_shader);
54*35238bceSAndroid Build Coastguard Worker }
55*35238bceSAndroid Build Coastguard Worker
~Shader(void)56*35238bceSAndroid Build Coastguard Worker Shader::~Shader(void)
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker m_gl.deleteShader(m_shader);
59*35238bceSAndroid Build Coastguard Worker }
60*35238bceSAndroid Build Coastguard Worker
setSources(int numSourceStrings,const char * const * sourceStrings,const int * lengths)61*35238bceSAndroid Build Coastguard Worker void Shader::setSources(int numSourceStrings, const char *const *sourceStrings, const int *lengths)
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker m_gl.shaderSource(m_shader, numSourceStrings, sourceStrings, lengths);
64*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glShaderSource()");
65*35238bceSAndroid Build Coastguard Worker
66*35238bceSAndroid Build Coastguard Worker m_info.source.clear();
67*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numSourceStrings; ndx++)
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker const size_t length = lengths && lengths[ndx] >= 0 ? lengths[ndx] : strlen(sourceStrings[ndx]);
70*35238bceSAndroid Build Coastguard Worker m_info.source += std::string(sourceStrings[ndx], length);
71*35238bceSAndroid Build Coastguard Worker }
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker
compile(void)74*35238bceSAndroid Build Coastguard Worker void Shader::compile(void)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker m_info.compileOk = false;
77*35238bceSAndroid Build Coastguard Worker m_info.compileTimeUs = 0;
78*35238bceSAndroid Build Coastguard Worker m_info.infoLog.clear();
79*35238bceSAndroid Build Coastguard Worker
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker uint64_t compileStart = deGetMicroseconds();
82*35238bceSAndroid Build Coastguard Worker m_gl.compileShader(m_shader);
83*35238bceSAndroid Build Coastguard Worker m_info.compileTimeUs = deGetMicroseconds() - compileStart;
84*35238bceSAndroid Build Coastguard Worker }
85*35238bceSAndroid Build Coastguard Worker
86*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCompileShader()");
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker // Query status
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker int compileStatus = 0;
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker m_gl.getShaderiv(m_shader, GL_COMPILE_STATUS, &compileStatus);
93*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()");
94*35238bceSAndroid Build Coastguard Worker
95*35238bceSAndroid Build Coastguard Worker m_info.compileOk = compileStatus != GL_FALSE;
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker // Query log
99*35238bceSAndroid Build Coastguard Worker {
100*35238bceSAndroid Build Coastguard Worker int infoLogLen = 0;
101*35238bceSAndroid Build Coastguard Worker int unusedLen;
102*35238bceSAndroid Build Coastguard Worker
103*35238bceSAndroid Build Coastguard Worker m_gl.getShaderiv(m_shader, GL_INFO_LOG_LENGTH, &infoLogLen);
104*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()");
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker if (infoLogLen > 0)
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker // The INFO_LOG_LENGTH query and the buffer query implementations have
109*35238bceSAndroid Build Coastguard Worker // very commonly off-by-one errors. Try to work around these issues.
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker // add tolerance for off-by-one in log length, buffer write, and for terminator
112*35238bceSAndroid Build Coastguard Worker std::vector<char> infoLog(infoLogLen + 3, '\0');
113*35238bceSAndroid Build Coastguard Worker
114*35238bceSAndroid Build Coastguard Worker // claim buf size is one smaller to protect from off-by-one writing over buffer bounds
115*35238bceSAndroid Build Coastguard Worker m_gl.getShaderInfoLog(m_shader, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]);
116*35238bceSAndroid Build Coastguard Worker
117*35238bceSAndroid Build Coastguard Worker if (infoLog[(int)(infoLog.size()) - 1] != '\0')
118*35238bceSAndroid Build Coastguard Worker {
119*35238bceSAndroid Build Coastguard Worker // return whole buffer if null terminator was overwritten
120*35238bceSAndroid Build Coastguard Worker m_info.infoLog = std::string(&infoLog[0], infoLog.size());
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker else
123*35238bceSAndroid Build Coastguard Worker {
124*35238bceSAndroid Build Coastguard Worker // read as C string. infoLog is guaranteed to be 0-terminated
125*35238bceSAndroid Build Coastguard Worker m_info.infoLog = std::string(&infoLog[0]);
126*35238bceSAndroid Build Coastguard Worker }
127*35238bceSAndroid Build Coastguard Worker }
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker
specialize(const char * entryPoint,glw::GLuint numSpecializationConstants,const glw::GLuint * constantIndex,const glw::GLuint * constantValue)131*35238bceSAndroid Build Coastguard Worker void Shader::specialize(const char *entryPoint, glw::GLuint numSpecializationConstants,
132*35238bceSAndroid Build Coastguard Worker const glw::GLuint *constantIndex, const glw::GLuint *constantValue)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker m_info.compileOk = false;
135*35238bceSAndroid Build Coastguard Worker m_info.compileTimeUs = 0;
136*35238bceSAndroid Build Coastguard Worker m_info.infoLog.clear();
137*35238bceSAndroid Build Coastguard Worker
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker uint64_t compileStart = deGetMicroseconds();
140*35238bceSAndroid Build Coastguard Worker m_gl.specializeShader(m_shader, entryPoint, numSpecializationConstants, constantIndex, constantValue);
141*35238bceSAndroid Build Coastguard Worker m_info.compileTimeUs = deGetMicroseconds() - compileStart;
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
144*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glSpecializeShader()");
145*35238bceSAndroid Build Coastguard Worker
146*35238bceSAndroid Build Coastguard Worker // Query status
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker int compileStatus = 0;
149*35238bceSAndroid Build Coastguard Worker
150*35238bceSAndroid Build Coastguard Worker m_gl.getShaderiv(m_shader, GL_COMPILE_STATUS, &compileStatus);
151*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()");
152*35238bceSAndroid Build Coastguard Worker
153*35238bceSAndroid Build Coastguard Worker m_info.compileOk = compileStatus != GL_FALSE;
154*35238bceSAndroid Build Coastguard Worker }
155*35238bceSAndroid Build Coastguard Worker
156*35238bceSAndroid Build Coastguard Worker // Query log
157*35238bceSAndroid Build Coastguard Worker {
158*35238bceSAndroid Build Coastguard Worker int infoLogLen = 0;
159*35238bceSAndroid Build Coastguard Worker int unusedLen;
160*35238bceSAndroid Build Coastguard Worker
161*35238bceSAndroid Build Coastguard Worker m_gl.getShaderiv(m_shader, GL_INFO_LOG_LENGTH, &infoLogLen);
162*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()");
163*35238bceSAndroid Build Coastguard Worker
164*35238bceSAndroid Build Coastguard Worker if (infoLogLen > 0)
165*35238bceSAndroid Build Coastguard Worker {
166*35238bceSAndroid Build Coastguard Worker // The INFO_LOG_LENGTH query and the buffer query implementations have
167*35238bceSAndroid Build Coastguard Worker // very commonly off-by-one errors. Try to work around these issues.
168*35238bceSAndroid Build Coastguard Worker
169*35238bceSAndroid Build Coastguard Worker // add tolerance for off-by-one in log length, buffer write, and for terminator
170*35238bceSAndroid Build Coastguard Worker std::vector<char> infoLog(infoLogLen + 3, '\0');
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker // claim buf size is one smaller to protect from off-by-one writing over buffer bounds
173*35238bceSAndroid Build Coastguard Worker m_gl.getShaderInfoLog(m_shader, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]);
174*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderInfoLog()");
175*35238bceSAndroid Build Coastguard Worker
176*35238bceSAndroid Build Coastguard Worker if (infoLog[(int)(infoLog.size()) - 1] != '\0')
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker // return whole buffer if null terminator was overwritten
179*35238bceSAndroid Build Coastguard Worker m_info.infoLog = std::string(&infoLog[0], infoLog.size());
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker else
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker // read as C string. infoLog is guaranteed to be 0-terminated
184*35238bceSAndroid Build Coastguard Worker m_info.infoLog = std::string(&infoLog[0]);
185*35238bceSAndroid Build Coastguard Worker }
186*35238bceSAndroid Build Coastguard Worker }
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker }
189*35238bceSAndroid Build Coastguard Worker
190*35238bceSAndroid Build Coastguard Worker // Program
191*35238bceSAndroid Build Coastguard Worker
getProgramLinkStatus(const glw::Functions & gl,uint32_t program)192*35238bceSAndroid Build Coastguard Worker static bool getProgramLinkStatus(const glw::Functions &gl, uint32_t program)
193*35238bceSAndroid Build Coastguard Worker {
194*35238bceSAndroid Build Coastguard Worker int linkStatus = 0;
195*35238bceSAndroid Build Coastguard Worker
196*35238bceSAndroid Build Coastguard Worker gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
197*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()");
198*35238bceSAndroid Build Coastguard Worker return (linkStatus != GL_FALSE);
199*35238bceSAndroid Build Coastguard Worker }
200*35238bceSAndroid Build Coastguard Worker
getProgramInfoLog(const glw::Functions & gl,uint32_t program)201*35238bceSAndroid Build Coastguard Worker static std::string getProgramInfoLog(const glw::Functions &gl, uint32_t program)
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker int infoLogLen = 0;
204*35238bceSAndroid Build Coastguard Worker int unusedLen;
205*35238bceSAndroid Build Coastguard Worker
206*35238bceSAndroid Build Coastguard Worker gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
207*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()");
208*35238bceSAndroid Build Coastguard Worker
209*35238bceSAndroid Build Coastguard Worker if (infoLogLen > 0)
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker // The INFO_LOG_LENGTH query and the buffer query implementations have
212*35238bceSAndroid Build Coastguard Worker // very commonly off-by-one errors. Try to work around these issues.
213*35238bceSAndroid Build Coastguard Worker
214*35238bceSAndroid Build Coastguard Worker // add tolerance for off-by-one in log length, buffer write, and for terminator
215*35238bceSAndroid Build Coastguard Worker std::vector<char> infoLog(infoLogLen + 3, '\0');
216*35238bceSAndroid Build Coastguard Worker
217*35238bceSAndroid Build Coastguard Worker // claim buf size is one smaller to protect from off-by-one writing over buffer bounds
218*35238bceSAndroid Build Coastguard Worker gl.getProgramInfoLog(program, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]);
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker // return whole buffer if null terminator was overwritten
221*35238bceSAndroid Build Coastguard Worker if (infoLog[(int)(infoLog.size()) - 1] != '\0')
222*35238bceSAndroid Build Coastguard Worker return std::string(&infoLog[0], infoLog.size());
223*35238bceSAndroid Build Coastguard Worker
224*35238bceSAndroid Build Coastguard Worker // read as C string. infoLog is guaranteed to be 0-terminated
225*35238bceSAndroid Build Coastguard Worker return std::string(&infoLog[0]);
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker return std::string();
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker
Program(const RenderContext & renderCtx)230*35238bceSAndroid Build Coastguard Worker Program::Program(const RenderContext &renderCtx) : m_gl(renderCtx.getFunctions()), m_program(0)
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker m_program = m_gl.createProgram();
233*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateProgram()");
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker
Program(const glw::Functions & gl)236*35238bceSAndroid Build Coastguard Worker Program::Program(const glw::Functions &gl) : m_gl(gl), m_program(0)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker m_program = m_gl.createProgram();
239*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateProgram()");
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker
Program(const RenderContext & renderCtx,uint32_t program)242*35238bceSAndroid Build Coastguard Worker Program::Program(const RenderContext &renderCtx, uint32_t program) : m_gl(renderCtx.getFunctions()), m_program(program)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker m_info.linkOk = getProgramLinkStatus(m_gl, program);
245*35238bceSAndroid Build Coastguard Worker m_info.infoLog = getProgramInfoLog(m_gl, program);
246*35238bceSAndroid Build Coastguard Worker }
247*35238bceSAndroid Build Coastguard Worker
~Program(void)248*35238bceSAndroid Build Coastguard Worker Program::~Program(void)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker m_gl.deleteProgram(m_program);
251*35238bceSAndroid Build Coastguard Worker }
252*35238bceSAndroid Build Coastguard Worker
attachShader(uint32_t shader)253*35238bceSAndroid Build Coastguard Worker void Program::attachShader(uint32_t shader)
254*35238bceSAndroid Build Coastguard Worker {
255*35238bceSAndroid Build Coastguard Worker m_gl.attachShader(m_program, shader);
256*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glAttachShader()");
257*35238bceSAndroid Build Coastguard Worker }
258*35238bceSAndroid Build Coastguard Worker
detachShader(uint32_t shader)259*35238bceSAndroid Build Coastguard Worker void Program::detachShader(uint32_t shader)
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker m_gl.detachShader(m_program, shader);
262*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDetachShader()");
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker
bindAttribLocation(uint32_t location,const char * name)265*35238bceSAndroid Build Coastguard Worker void Program::bindAttribLocation(uint32_t location, const char *name)
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker m_gl.bindAttribLocation(m_program, location, name);
268*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindAttribLocation()");
269*35238bceSAndroid Build Coastguard Worker }
270*35238bceSAndroid Build Coastguard Worker
transformFeedbackVaryings(int count,const char * const * varyings,uint32_t bufferMode)271*35238bceSAndroid Build Coastguard Worker void Program::transformFeedbackVaryings(int count, const char *const *varyings, uint32_t bufferMode)
272*35238bceSAndroid Build Coastguard Worker {
273*35238bceSAndroid Build Coastguard Worker m_gl.transformFeedbackVaryings(m_program, count, varyings, bufferMode);
274*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTransformFeedbackVaryings()");
275*35238bceSAndroid Build Coastguard Worker }
276*35238bceSAndroid Build Coastguard Worker
link(void)277*35238bceSAndroid Build Coastguard Worker void Program::link(void)
278*35238bceSAndroid Build Coastguard Worker {
279*35238bceSAndroid Build Coastguard Worker m_info.linkOk = false;
280*35238bceSAndroid Build Coastguard Worker m_info.linkTimeUs = 0;
281*35238bceSAndroid Build Coastguard Worker m_info.infoLog.clear();
282*35238bceSAndroid Build Coastguard Worker
283*35238bceSAndroid Build Coastguard Worker {
284*35238bceSAndroid Build Coastguard Worker uint64_t linkStart = deGetMicroseconds();
285*35238bceSAndroid Build Coastguard Worker m_gl.linkProgram(m_program);
286*35238bceSAndroid Build Coastguard Worker m_info.linkTimeUs = deGetMicroseconds() - linkStart;
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glLinkProgram()");
289*35238bceSAndroid Build Coastguard Worker
290*35238bceSAndroid Build Coastguard Worker m_info.linkOk = getProgramLinkStatus(m_gl, m_program);
291*35238bceSAndroid Build Coastguard Worker m_info.infoLog = getProgramInfoLog(m_gl, m_program);
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker
isSeparable(void) const294*35238bceSAndroid Build Coastguard Worker bool Program::isSeparable(void) const
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker int separable = GL_FALSE;
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker m_gl.getProgramiv(m_program, GL_PROGRAM_SEPARABLE, &separable);
299*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetProgramiv()");
300*35238bceSAndroid Build Coastguard Worker
301*35238bceSAndroid Build Coastguard Worker return (separable != GL_FALSE);
302*35238bceSAndroid Build Coastguard Worker }
303*35238bceSAndroid Build Coastguard Worker
setSeparable(bool separable)304*35238bceSAndroid Build Coastguard Worker void Program::setSeparable(bool separable)
305*35238bceSAndroid Build Coastguard Worker {
306*35238bceSAndroid Build Coastguard Worker m_gl.programParameteri(m_program, GL_PROGRAM_SEPARABLE, separable);
307*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glProgramParameteri()");
308*35238bceSAndroid Build Coastguard Worker }
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker // ProgramPipeline
311*35238bceSAndroid Build Coastguard Worker
ProgramPipeline(const RenderContext & renderCtx)312*35238bceSAndroid Build Coastguard Worker ProgramPipeline::ProgramPipeline(const RenderContext &renderCtx) : m_gl(renderCtx.getFunctions()), m_pipeline(0)
313*35238bceSAndroid Build Coastguard Worker {
314*35238bceSAndroid Build Coastguard Worker m_gl.genProgramPipelines(1, &m_pipeline);
315*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenProgramPipelines()");
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker
ProgramPipeline(const glw::Functions & gl)318*35238bceSAndroid Build Coastguard Worker ProgramPipeline::ProgramPipeline(const glw::Functions &gl) : m_gl(gl), m_pipeline(0)
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker m_gl.genProgramPipelines(1, &m_pipeline);
321*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenProgramPipelines()");
322*35238bceSAndroid Build Coastguard Worker }
323*35238bceSAndroid Build Coastguard Worker
~ProgramPipeline(void)324*35238bceSAndroid Build Coastguard Worker ProgramPipeline::~ProgramPipeline(void)
325*35238bceSAndroid Build Coastguard Worker {
326*35238bceSAndroid Build Coastguard Worker m_gl.deleteProgramPipelines(1, &m_pipeline);
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker
useProgramStages(uint32_t stages,uint32_t program)329*35238bceSAndroid Build Coastguard Worker void ProgramPipeline::useProgramStages(uint32_t stages, uint32_t program)
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker m_gl.useProgramStages(m_pipeline, stages, program);
332*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgramStages()");
333*35238bceSAndroid Build Coastguard Worker }
334*35238bceSAndroid Build Coastguard Worker
activeShaderProgram(uint32_t program)335*35238bceSAndroid Build Coastguard Worker void ProgramPipeline::activeShaderProgram(uint32_t program)
336*35238bceSAndroid Build Coastguard Worker {
337*35238bceSAndroid Build Coastguard Worker m_gl.activeShaderProgram(m_pipeline, program);
338*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glActiveShaderProgram()");
339*35238bceSAndroid Build Coastguard Worker }
340*35238bceSAndroid Build Coastguard Worker
isValid(void)341*35238bceSAndroid Build Coastguard Worker bool ProgramPipeline::isValid(void)
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker glw::GLint status = GL_FALSE;
344*35238bceSAndroid Build Coastguard Worker m_gl.validateProgramPipeline(m_pipeline);
345*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_gl.getError(), "glValidateProgramPipeline()");
346*35238bceSAndroid Build Coastguard Worker
347*35238bceSAndroid Build Coastguard Worker m_gl.getProgramPipelineiv(m_pipeline, GL_VALIDATE_STATUS, &status);
348*35238bceSAndroid Build Coastguard Worker
349*35238bceSAndroid Build Coastguard Worker return (status != GL_FALSE);
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker
352*35238bceSAndroid Build Coastguard Worker // ShaderProgram
353*35238bceSAndroid Build Coastguard Worker
ShaderProgram(const RenderContext & renderCtx,const ProgramSources & sources)354*35238bceSAndroid Build Coastguard Worker ShaderProgram::ShaderProgram(const RenderContext &renderCtx, const ProgramSources &sources)
355*35238bceSAndroid Build Coastguard Worker : m_program(renderCtx.getFunctions())
356*35238bceSAndroid Build Coastguard Worker {
357*35238bceSAndroid Build Coastguard Worker init(renderCtx.getFunctions(), sources);
358*35238bceSAndroid Build Coastguard Worker }
359*35238bceSAndroid Build Coastguard Worker
ShaderProgram(const RenderContext & renderCtx,const ProgramBinaries & binaries)360*35238bceSAndroid Build Coastguard Worker ShaderProgram::ShaderProgram(const RenderContext &renderCtx, const ProgramBinaries &binaries)
361*35238bceSAndroid Build Coastguard Worker : m_program(renderCtx.getFunctions())
362*35238bceSAndroid Build Coastguard Worker {
363*35238bceSAndroid Build Coastguard Worker init(renderCtx.getFunctions(), binaries);
364*35238bceSAndroid Build Coastguard Worker }
365*35238bceSAndroid Build Coastguard Worker
ShaderProgram(const glw::Functions & gl,const ProgramSources & sources)366*35238bceSAndroid Build Coastguard Worker ShaderProgram::ShaderProgram(const glw::Functions &gl, const ProgramSources &sources) : m_program(gl)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker init(gl, sources);
369*35238bceSAndroid Build Coastguard Worker }
370*35238bceSAndroid Build Coastguard Worker
ShaderProgram(const glw::Functions & gl,const ProgramBinaries & binaries)371*35238bceSAndroid Build Coastguard Worker ShaderProgram::ShaderProgram(const glw::Functions &gl, const ProgramBinaries &binaries) : m_program(gl)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker init(gl, binaries);
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker
init(const glw::Functions & gl,const ProgramSources & sources)376*35238bceSAndroid Build Coastguard Worker void ShaderProgram::init(const glw::Functions &gl, const ProgramSources &sources)
377*35238bceSAndroid Build Coastguard Worker {
378*35238bceSAndroid Build Coastguard Worker try
379*35238bceSAndroid Build Coastguard Worker {
380*35238bceSAndroid Build Coastguard Worker bool shadersOk = true;
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)sources.sources[shaderType].size(); ++shaderNdx)
385*35238bceSAndroid Build Coastguard Worker {
386*35238bceSAndroid Build Coastguard Worker const char *source = sources.sources[shaderType][shaderNdx].c_str();
387*35238bceSAndroid Build Coastguard Worker const int length = (int)sources.sources[shaderType][shaderNdx].size();
388*35238bceSAndroid Build Coastguard Worker
389*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].reserve(m_shaders[shaderType].size() + 1);
390*35238bceSAndroid Build Coastguard Worker
391*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].push_back(new Shader(gl, ShaderType(shaderType)));
392*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].back()->setSources(1, &source, &length);
393*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].back()->compile();
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker shadersOk = shadersOk && m_shaders[shaderType].back()->getCompileStatus();
396*35238bceSAndroid Build Coastguard Worker }
397*35238bceSAndroid Build Coastguard Worker }
398*35238bceSAndroid Build Coastguard Worker
399*35238bceSAndroid Build Coastguard Worker if (shadersOk)
400*35238bceSAndroid Build Coastguard Worker {
401*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
402*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx)
403*35238bceSAndroid Build Coastguard Worker m_program.attachShader(m_shaders[shaderType][shaderNdx]->getShader());
404*35238bceSAndroid Build Coastguard Worker
405*35238bceSAndroid Build Coastguard Worker for (std::vector<AttribLocationBinding>::const_iterator binding = sources.attribLocationBindings.begin();
406*35238bceSAndroid Build Coastguard Worker binding != sources.attribLocationBindings.end(); ++binding)
407*35238bceSAndroid Build Coastguard Worker m_program.bindAttribLocation(binding->location, binding->name.c_str());
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker DE_ASSERT((sources.transformFeedbackBufferMode == GL_NONE) == sources.transformFeedbackVaryings.empty());
410*35238bceSAndroid Build Coastguard Worker if (sources.transformFeedbackBufferMode != GL_NONE)
411*35238bceSAndroid Build Coastguard Worker {
412*35238bceSAndroid Build Coastguard Worker std::vector<const char *> tfVaryings(sources.transformFeedbackVaryings.size());
413*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)tfVaryings.size(); ndx++)
414*35238bceSAndroid Build Coastguard Worker tfVaryings[ndx] = sources.transformFeedbackVaryings[ndx].c_str();
415*35238bceSAndroid Build Coastguard Worker
416*35238bceSAndroid Build Coastguard Worker m_program.transformFeedbackVaryings((int)tfVaryings.size(), &tfVaryings[0],
417*35238bceSAndroid Build Coastguard Worker sources.transformFeedbackBufferMode);
418*35238bceSAndroid Build Coastguard Worker }
419*35238bceSAndroid Build Coastguard Worker
420*35238bceSAndroid Build Coastguard Worker if (sources.separable)
421*35238bceSAndroid Build Coastguard Worker m_program.setSeparable(true);
422*35238bceSAndroid Build Coastguard Worker
423*35238bceSAndroid Build Coastguard Worker m_program.link();
424*35238bceSAndroid Build Coastguard Worker }
425*35238bceSAndroid Build Coastguard Worker }
426*35238bceSAndroid Build Coastguard Worker catch (...)
427*35238bceSAndroid Build Coastguard Worker {
428*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
429*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx)
430*35238bceSAndroid Build Coastguard Worker delete m_shaders[shaderType][shaderNdx];
431*35238bceSAndroid Build Coastguard Worker throw;
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker }
434*35238bceSAndroid Build Coastguard Worker
init(const glw::Functions & gl,const ProgramBinaries & binaries)435*35238bceSAndroid Build Coastguard Worker void ShaderProgram::init(const glw::Functions &gl, const ProgramBinaries &binaries)
436*35238bceSAndroid Build Coastguard Worker {
437*35238bceSAndroid Build Coastguard Worker try
438*35238bceSAndroid Build Coastguard Worker {
439*35238bceSAndroid Build Coastguard Worker bool shadersOk = true;
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker for (uint32_t binaryNdx = 0; binaryNdx < binaries.binaries.size(); ++binaryNdx)
442*35238bceSAndroid Build Coastguard Worker {
443*35238bceSAndroid Build Coastguard Worker ShaderBinary shaderBinary = binaries.binaries[binaryNdx];
444*35238bceSAndroid Build Coastguard Worker if (!shaderBinary.binary.empty())
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker const char *binary = (const char *)shaderBinary.binary.data();
447*35238bceSAndroid Build Coastguard Worker const int length = (int)(shaderBinary.binary.size() * sizeof(uint32_t));
448*35238bceSAndroid Build Coastguard Worker
449*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shaderBinary.shaderEntryPoints.size() == shaderBinary.shaderTypes.size());
450*35238bceSAndroid Build Coastguard Worker
451*35238bceSAndroid Build Coastguard Worker std::vector<Shader *> shaders;
452*35238bceSAndroid Build Coastguard Worker for (uint32_t shaderTypeNdx = 0; shaderTypeNdx < shaderBinary.shaderTypes.size(); ++shaderTypeNdx)
453*35238bceSAndroid Build Coastguard Worker {
454*35238bceSAndroid Build Coastguard Worker ShaderType shaderType = shaderBinary.shaderTypes[shaderTypeNdx];
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker Shader *shader = new Shader(gl, ShaderType(shaderType));
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].reserve(m_shaders[shaderType].size() + 1);
459*35238bceSAndroid Build Coastguard Worker m_shaders[shaderType].push_back(shader);
460*35238bceSAndroid Build Coastguard Worker shaders.push_back(shader);
461*35238bceSAndroid Build Coastguard Worker }
462*35238bceSAndroid Build Coastguard Worker
463*35238bceSAndroid Build Coastguard Worker setBinary(gl, shaders, binaries.binaryFormat, binary, length);
464*35238bceSAndroid Build Coastguard Worker
465*35238bceSAndroid Build Coastguard Worker for (uint32_t shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
466*35238bceSAndroid Build Coastguard Worker {
467*35238bceSAndroid Build Coastguard Worker shaders[shaderNdx]->specialize(shaderBinary.shaderEntryPoints[shaderNdx].c_str(),
468*35238bceSAndroid Build Coastguard Worker (uint32_t)shaderBinary.specializationIndices.size(),
469*35238bceSAndroid Build Coastguard Worker shaderBinary.specializationIndices.data(),
470*35238bceSAndroid Build Coastguard Worker shaderBinary.specializationValues.data());
471*35238bceSAndroid Build Coastguard Worker
472*35238bceSAndroid Build Coastguard Worker shadersOk = shadersOk && shaders[shaderNdx]->getCompileStatus();
473*35238bceSAndroid Build Coastguard Worker }
474*35238bceSAndroid Build Coastguard Worker }
475*35238bceSAndroid Build Coastguard Worker }
476*35238bceSAndroid Build Coastguard Worker
477*35238bceSAndroid Build Coastguard Worker if (shadersOk)
478*35238bceSAndroid Build Coastguard Worker {
479*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
480*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx)
481*35238bceSAndroid Build Coastguard Worker m_program.attachShader(m_shaders[shaderType][shaderNdx]->getShader());
482*35238bceSAndroid Build Coastguard Worker
483*35238bceSAndroid Build Coastguard Worker m_program.link();
484*35238bceSAndroid Build Coastguard Worker }
485*35238bceSAndroid Build Coastguard Worker }
486*35238bceSAndroid Build Coastguard Worker catch (...)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
489*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx)
490*35238bceSAndroid Build Coastguard Worker delete m_shaders[shaderType][shaderNdx];
491*35238bceSAndroid Build Coastguard Worker throw;
492*35238bceSAndroid Build Coastguard Worker }
493*35238bceSAndroid Build Coastguard Worker }
494*35238bceSAndroid Build Coastguard Worker
setBinary(const glw::Functions & gl,std::vector<Shader * > & shaders,glw::GLenum binaryFormat,const void * binaryData,const int length)495*35238bceSAndroid Build Coastguard Worker void ShaderProgram::setBinary(const glw::Functions &gl, std::vector<Shader *> &shaders, glw::GLenum binaryFormat,
496*35238bceSAndroid Build Coastguard Worker const void *binaryData, const int length)
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLuint> shaderVec;
499*35238bceSAndroid Build Coastguard Worker for (uint32_t shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
500*35238bceSAndroid Build Coastguard Worker shaderVec.push_back(shaders[shaderNdx]->getShader());
501*35238bceSAndroid Build Coastguard Worker
502*35238bceSAndroid Build Coastguard Worker gl.shaderBinary((glw::GLsizei)shaderVec.size(), shaderVec.data(), binaryFormat, binaryData, length);
503*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderBinary");
504*35238bceSAndroid Build Coastguard Worker
505*35238bceSAndroid Build Coastguard Worker for (uint32_t shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
506*35238bceSAndroid Build Coastguard Worker {
507*35238bceSAndroid Build Coastguard Worker glw::GLint shaderState;
508*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(shaders[shaderNdx]->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
509*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shaderState == GL_TRUE);
512*35238bceSAndroid Build Coastguard Worker }
513*35238bceSAndroid Build Coastguard Worker }
514*35238bceSAndroid Build Coastguard Worker
~ShaderProgram(void)515*35238bceSAndroid Build Coastguard Worker ShaderProgram::~ShaderProgram(void)
516*35238bceSAndroid Build Coastguard Worker {
517*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
518*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx)
519*35238bceSAndroid Build Coastguard Worker delete m_shaders[shaderType][shaderNdx];
520*35238bceSAndroid Build Coastguard Worker }
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker // Utilities
523*35238bceSAndroid Build Coastguard Worker
getGLShaderType(ShaderType shaderType)524*35238bceSAndroid Build Coastguard Worker uint32_t getGLShaderType(ShaderType shaderType)
525*35238bceSAndroid Build Coastguard Worker {
526*35238bceSAndroid Build Coastguard Worker static const uint32_t s_typeMap[] = {
527*35238bceSAndroid Build Coastguard Worker GL_VERTEX_SHADER,
528*35238bceSAndroid Build Coastguard Worker GL_FRAGMENT_SHADER,
529*35238bceSAndroid Build Coastguard Worker GL_GEOMETRY_SHADER,
530*35238bceSAndroid Build Coastguard Worker GL_TESS_CONTROL_SHADER,
531*35238bceSAndroid Build Coastguard Worker GL_TESS_EVALUATION_SHADER,
532*35238bceSAndroid Build Coastguard Worker GL_COMPUTE_SHADER,
533*35238bceSAndroid Build Coastguard Worker 0,
534*35238bceSAndroid Build Coastguard Worker 0,
535*35238bceSAndroid Build Coastguard Worker 0,
536*35238bceSAndroid Build Coastguard Worker 0,
537*35238bceSAndroid Build Coastguard Worker 0,
538*35238bceSAndroid Build Coastguard Worker 0,
539*35238bceSAndroid Build Coastguard Worker 0,
540*35238bceSAndroid Build Coastguard Worker 0,
541*35238bceSAndroid Build Coastguard Worker };
542*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typeMap) == SHADERTYPE_LAST);
543*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typeMap)));
544*35238bceSAndroid Build Coastguard Worker return s_typeMap[shaderType];
545*35238bceSAndroid Build Coastguard Worker }
546*35238bceSAndroid Build Coastguard Worker
getGLShaderTypeBit(ShaderType shaderType)547*35238bceSAndroid Build Coastguard Worker uint32_t getGLShaderTypeBit(ShaderType shaderType)
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker static const uint32_t s_typebitMap[] = {
550*35238bceSAndroid Build Coastguard Worker GL_VERTEX_SHADER_BIT,
551*35238bceSAndroid Build Coastguard Worker GL_FRAGMENT_SHADER_BIT,
552*35238bceSAndroid Build Coastguard Worker GL_GEOMETRY_SHADER_BIT,
553*35238bceSAndroid Build Coastguard Worker GL_TESS_CONTROL_SHADER_BIT,
554*35238bceSAndroid Build Coastguard Worker GL_TESS_EVALUATION_SHADER_BIT,
555*35238bceSAndroid Build Coastguard Worker GL_COMPUTE_SHADER_BIT,
556*35238bceSAndroid Build Coastguard Worker 0,
557*35238bceSAndroid Build Coastguard Worker 0,
558*35238bceSAndroid Build Coastguard Worker 0,
559*35238bceSAndroid Build Coastguard Worker 0,
560*35238bceSAndroid Build Coastguard Worker 0,
561*35238bceSAndroid Build Coastguard Worker 0,
562*35238bceSAndroid Build Coastguard Worker 0,
563*35238bceSAndroid Build Coastguard Worker 0,
564*35238bceSAndroid Build Coastguard Worker };
565*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typebitMap) == SHADERTYPE_LAST);
566*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typebitMap)));
567*35238bceSAndroid Build Coastguard Worker return s_typebitMap[shaderType];
568*35238bceSAndroid Build Coastguard Worker }
569*35238bceSAndroid Build Coastguard Worker
getLogShaderType(ShaderType shaderType)570*35238bceSAndroid Build Coastguard Worker qpShaderType getLogShaderType(ShaderType shaderType)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker static const qpShaderType s_typeMap[] = {
573*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_VERTEX,
574*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_FRAGMENT,
575*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_GEOMETRY,
576*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_TESS_CONTROL,
577*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_TESS_EVALUATION,
578*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_COMPUTE,
579*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_RAYGEN,
580*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_ANY_HIT,
581*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_CLOSEST_HIT,
582*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_MISS,
583*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_INTERSECTION,
584*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_CALLABLE,
585*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_TASK,
586*35238bceSAndroid Build Coastguard Worker QP_SHADER_TYPE_MESH,
587*35238bceSAndroid Build Coastguard Worker };
588*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typeMap) == SHADERTYPE_LAST);
589*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typeMap)));
590*35238bceSAndroid Build Coastguard Worker return s_typeMap[shaderType];
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker
operator <<(tcu::TestLog & log,const ShaderInfo & shaderInfo)593*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderInfo &shaderInfo)
594*35238bceSAndroid Build Coastguard Worker {
595*35238bceSAndroid Build Coastguard Worker return log << tcu::TestLog::Shader(getLogShaderType(shaderInfo.type), shaderInfo.source, shaderInfo.compileOk,
596*35238bceSAndroid Build Coastguard Worker shaderInfo.infoLog);
597*35238bceSAndroid Build Coastguard Worker }
598*35238bceSAndroid Build Coastguard Worker
operator <<(tcu::TestLog & log,const Shader & shader)599*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const Shader &shader)
600*35238bceSAndroid Build Coastguard Worker {
601*35238bceSAndroid Build Coastguard Worker return log << tcu::TestLog::ShaderProgram(false, "Plain shader") << shader.getInfo()
602*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndShaderProgram;
603*35238bceSAndroid Build Coastguard Worker }
604*35238bceSAndroid Build Coastguard Worker
logShaderProgram(tcu::TestLog & log,const ProgramInfo & programInfo,size_t numShaders,const ShaderInfo * const * shaderInfos)605*35238bceSAndroid Build Coastguard Worker static void logShaderProgram(tcu::TestLog &log, const ProgramInfo &programInfo, size_t numShaders,
606*35238bceSAndroid Build Coastguard Worker const ShaderInfo *const *shaderInfos)
607*35238bceSAndroid Build Coastguard Worker {
608*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::ShaderProgram(programInfo.linkOk, programInfo.infoLog);
609*35238bceSAndroid Build Coastguard Worker try
610*35238bceSAndroid Build Coastguard Worker {
611*35238bceSAndroid Build Coastguard Worker for (size_t shaderNdx = 0; shaderNdx < numShaders; ++shaderNdx)
612*35238bceSAndroid Build Coastguard Worker log << *shaderInfos[shaderNdx];
613*35238bceSAndroid Build Coastguard Worker }
614*35238bceSAndroid Build Coastguard Worker catch (...)
615*35238bceSAndroid Build Coastguard Worker {
616*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::EndShaderProgram;
617*35238bceSAndroid Build Coastguard Worker throw;
618*35238bceSAndroid Build Coastguard Worker }
619*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::EndShaderProgram;
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker // Write statistics.
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker static const struct
624*35238bceSAndroid Build Coastguard Worker {
625*35238bceSAndroid Build Coastguard Worker const char *name;
626*35238bceSAndroid Build Coastguard Worker const char *description;
627*35238bceSAndroid Build Coastguard Worker } s_compileTimeDesc[] = {
628*35238bceSAndroid Build Coastguard Worker {"VertexCompileTime", "Vertex shader compile time"},
629*35238bceSAndroid Build Coastguard Worker {"FragmentCompileTime", "Fragment shader compile time"},
630*35238bceSAndroid Build Coastguard Worker {"GeometryCompileTime", "Geometry shader compile time"},
631*35238bceSAndroid Build Coastguard Worker {"TessControlCompileTime", "Tesselation control shader compile time"},
632*35238bceSAndroid Build Coastguard Worker {"TessEvaluationCompileTime", "Tesselation evaluation shader compile time"},
633*35238bceSAndroid Build Coastguard Worker {"ComputeCompileTime", "Compute shader compile time"},
634*35238bceSAndroid Build Coastguard Worker {"RaygenCompileTime", "Raygen shader compile time"},
635*35238bceSAndroid Build Coastguard Worker {"AnyHitCompileTime", "Any hit shader compile time"},
636*35238bceSAndroid Build Coastguard Worker {"ClosestHitCompileTime", "Closest hit shader compile time"},
637*35238bceSAndroid Build Coastguard Worker {"MissCompileTime", "Miss shader compile time"},
638*35238bceSAndroid Build Coastguard Worker {"IntersectionCompileTime", "Intersection shader compile time"},
639*35238bceSAndroid Build Coastguard Worker {"CallableCompileTime", "Callable shader compile time"},
640*35238bceSAndroid Build Coastguard Worker {"TaskCompileTime", "Task shader compile time"},
641*35238bceSAndroid Build Coastguard Worker {"MeshCompileTime", "Mesh shader compile time"},
642*35238bceSAndroid Build Coastguard Worker };
643*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_compileTimeDesc) == SHADERTYPE_LAST);
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker bool allShadersOk = true;
646*35238bceSAndroid Build Coastguard Worker
647*35238bceSAndroid Build Coastguard Worker for (size_t shaderNdx = 0; shaderNdx < numShaders; ++shaderNdx)
648*35238bceSAndroid Build Coastguard Worker {
649*35238bceSAndroid Build Coastguard Worker const ShaderInfo &shaderInfo = *shaderInfos[shaderNdx];
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Float(s_compileTimeDesc[shaderInfo.type].name,
652*35238bceSAndroid Build Coastguard Worker s_compileTimeDesc[shaderInfo.type].description, "ms", QP_KEY_TAG_TIME,
653*35238bceSAndroid Build Coastguard Worker (float)shaderInfo.compileTimeUs / 1000.0f);
654*35238bceSAndroid Build Coastguard Worker
655*35238bceSAndroid Build Coastguard Worker allShadersOk = allShadersOk && shaderInfo.compileOk;
656*35238bceSAndroid Build Coastguard Worker }
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker if (allShadersOk)
659*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Float("LinkTime", "Link time", "ms", QP_KEY_TAG_TIME,
660*35238bceSAndroid Build Coastguard Worker (float)programInfo.linkTimeUs / 1000.0f);
661*35238bceSAndroid Build Coastguard Worker }
662*35238bceSAndroid Build Coastguard Worker }
663*35238bceSAndroid Build Coastguard Worker
operator <<(tcu::TestLog & log,const ShaderProgramInfo & shaderProgramInfo)664*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderProgramInfo &shaderProgramInfo)
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker std::vector<const ShaderInfo *> shaderPtrs(shaderProgramInfo.shaders.size());
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < shaderPtrs.size(); ndx++)
669*35238bceSAndroid Build Coastguard Worker shaderPtrs[ndx] = &shaderProgramInfo.shaders[ndx];
670*35238bceSAndroid Build Coastguard Worker
671*35238bceSAndroid Build Coastguard Worker logShaderProgram(log, shaderProgramInfo.program, shaderPtrs.size(), shaderPtrs.empty() ? DE_NULL : &shaderPtrs[0]);
672*35238bceSAndroid Build Coastguard Worker
673*35238bceSAndroid Build Coastguard Worker return log;
674*35238bceSAndroid Build Coastguard Worker }
675*35238bceSAndroid Build Coastguard Worker
operator <<(tcu::TestLog & log,const ShaderProgram & shaderProgram)676*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderProgram &shaderProgram)
677*35238bceSAndroid Build Coastguard Worker {
678*35238bceSAndroid Build Coastguard Worker std::vector<const ShaderInfo *> shaderPtrs;
679*35238bceSAndroid Build Coastguard Worker
680*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
681*35238bceSAndroid Build Coastguard Worker {
682*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < shaderProgram.getNumShaders((ShaderType)shaderType); shaderNdx++)
683*35238bceSAndroid Build Coastguard Worker shaderPtrs.push_back(&shaderProgram.getShaderInfo((ShaderType)shaderType, shaderNdx));
684*35238bceSAndroid Build Coastguard Worker }
685*35238bceSAndroid Build Coastguard Worker
686*35238bceSAndroid Build Coastguard Worker logShaderProgram(log, shaderProgram.getProgramInfo(), shaderPtrs.size(),
687*35238bceSAndroid Build Coastguard Worker shaderPtrs.empty() ? DE_NULL : &shaderPtrs[0]);
688*35238bceSAndroid Build Coastguard Worker
689*35238bceSAndroid Build Coastguard Worker return log;
690*35238bceSAndroid Build Coastguard Worker }
691*35238bceSAndroid Build Coastguard Worker
operator <<(tcu::TestLog & log,const ProgramSources & sources)692*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const ProgramSources &sources)
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::ShaderProgram(false, "(Source only)");
695*35238bceSAndroid Build Coastguard Worker
696*35238bceSAndroid Build Coastguard Worker try
697*35238bceSAndroid Build Coastguard Worker {
698*35238bceSAndroid Build Coastguard Worker for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++)
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker for (size_t shaderNdx = 0; shaderNdx < sources.sources[shaderType].size(); shaderNdx++)
701*35238bceSAndroid Build Coastguard Worker {
702*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Shader(getLogShaderType((ShaderType)shaderType),
703*35238bceSAndroid Build Coastguard Worker sources.sources[shaderType][shaderNdx], false, "");
704*35238bceSAndroid Build Coastguard Worker }
705*35238bceSAndroid Build Coastguard Worker }
706*35238bceSAndroid Build Coastguard Worker }
707*35238bceSAndroid Build Coastguard Worker catch (...)
708*35238bceSAndroid Build Coastguard Worker {
709*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::EndShaderProgram;
710*35238bceSAndroid Build Coastguard Worker throw;
711*35238bceSAndroid Build Coastguard Worker }
712*35238bceSAndroid Build Coastguard Worker
713*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::EndShaderProgram;
714*35238bceSAndroid Build Coastguard Worker
715*35238bceSAndroid Build Coastguard Worker return log;
716*35238bceSAndroid Build Coastguard Worker }
717*35238bceSAndroid Build Coastguard Worker
718*35238bceSAndroid Build Coastguard Worker } // namespace glu
719