Vulkan: Add wide-color tests
[platform/upstream/VK-GL-CTS.git] / framework / opengl / gluShaderProgram.hpp
1 #ifndef _GLUSHADERPROGRAM_HPP
2 #define _GLUSHADERPROGRAM_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL ES Utilities
5  * ------------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Shader and Program helpers.
24  *//*--------------------------------------------------------------------*/
25
26 #include "gluDefs.hpp"
27 #include "gluShaderUtil.hpp"
28 #include "glwEnums.hpp"
29 #include "qpTestLog.h"
30
31 #include <string>
32 #include <vector>
33
34 namespace tcu
35 {
36 class TestLog;
37 }
38
39 namespace glu
40 {
41
42 class RenderContext;
43
44 typedef std::vector<deUint32> ShaderBinaryDataType;
45
46 /*--------------------------------------------------------------------*//*!
47  * \brief Shader information (compile status, log, etc.).
48  *//*--------------------------------------------------------------------*/
49 struct ShaderInfo
50 {
51         ShaderType                              type;                   //!< Shader type.
52         std::string                             source;                 //!< Shader source.
53         std::string                             infoLog;                //!< Compile info log.
54         bool                                    compileOk;              //!< Did compilation succeed?
55         deUint64                                compileTimeUs;  //!< Compile time in microseconds (us).
56
57         ShaderInfo (void) : compileOk(false), compileTimeUs(0) {}
58 };
59
60 /*--------------------------------------------------------------------*//*!
61  * \brief Program information (link status, log).
62  *//*--------------------------------------------------------------------*/
63 struct ProgramInfo
64 {
65         std::string                             infoLog;                //!< Link info log.
66         bool                                    linkOk;                 //!< Did link succeed?
67         deUint64                                linkTimeUs;             //!< Link time in microseconds (us).
68
69         ProgramInfo (void) : linkOk(false), linkTimeUs(0) {}
70 };
71
72 /*--------------------------------------------------------------------*//*!
73  * \brief Combined shader compilation and program linking info.
74  *//*--------------------------------------------------------------------*/
75 struct ShaderProgramInfo
76 {
77         glu::ProgramInfo                                program;
78         std::vector<glu::ShaderInfo>    shaders;
79 };
80
81 /*--------------------------------------------------------------------*//*!
82  * \brief Shader object.
83  *//*--------------------------------------------------------------------*/
84 class Shader
85 {
86 public:
87                                                         Shader                          (const glw::Functions& gl, ShaderType shaderType);
88                                                         Shader                          (const RenderContext& renderCtx, ShaderType shaderType);
89                                                         ~Shader                         (void);
90
91         void                                    setSources                      (int numSourceStrings, const char* const* sourceStrings, const int* lengths);
92         void                                    compile                         (void);
93         void                                    specialize                      (const char* entryPoint, glw::GLuint numSpecializationConstants,
94                                                                                                  const glw::GLuint* constantIndex, const glw::GLuint* constantValue);
95
96         deUint32                                getShader                       (void) const { return m_shader;                         }
97         const ShaderInfo&               getInfo                         (void) const { return m_info;                           }
98
99         glu::ShaderType                 getType                         (void) const { return getInfo().type;           }
100         bool                                    getCompileStatus        (void) const { return getInfo().compileOk;      }
101         const std::string&              getSource                       (void) const { return getInfo().source;         }
102         const std::string&              getInfoLog                      (void) const { return getInfo().infoLog;        }
103
104         deUint32                                operator*                       (void) const { return getShader();                      }
105
106 private:
107                                                         Shader                          (const Shader& other);
108         Shader&                                 operator=                       (const Shader& other);
109
110         const glw::Functions&   m_gl;
111         deUint32                                m_shader;       //!< Shader handle.
112         ShaderInfo                              m_info;         //!< Client-side clone of state for debug / perf reasons.
113 };
114
115 /*--------------------------------------------------------------------*//*!
116  * \brief Program object.
117  *//*--------------------------------------------------------------------*/
118 class Program
119 {
120 public:
121                                                         Program                                         (const glw::Functions& gl);
122                                                         Program                                         (const RenderContext& renderCtx);
123                                                         Program                                         (const RenderContext& renderCtx, deUint32 program);
124                                                         ~Program                                        (void);
125
126         void                                    attachShader                            (deUint32 shader);
127         void                                    detachShader                            (deUint32 shader);
128
129         void                                    bindAttribLocation                      (deUint32 location, const char* name);
130         void                                    transformFeedbackVaryings       (int count, const char* const* varyings, deUint32 bufferMode);
131
132         void                                    link                                            (void);
133
134         deUint32                                getProgram                                      (void) const { return m_program;                        }
135         const ProgramInfo&              getInfo                                         (void) const { return m_info;                           }
136
137         bool                                    getLinkStatus                           (void) const { return getInfo().linkOk;         }
138         const std::string&              getInfoLog                                      (void) const { return getInfo().infoLog;        }
139
140         bool                                    isSeparable                                     (void) const;
141         void                                    setSeparable                            (bool separable);
142
143         int                                             getUniformLocation                      (const std::string& name);
144
145         deUint32                                operator*                                       (void) const { return getProgram();                     }
146
147 private:
148                                                         Program                                         (const Program& other);
149         Program&                                operator=                                       (const Program& other);
150
151         const glw::Functions&   m_gl;
152         deUint32                                m_program;
153         ProgramInfo                             m_info;
154 };
155
156
157 /*--------------------------------------------------------------------*//*!
158  * \brief Program pipeline object.
159  *//*--------------------------------------------------------------------*/
160 class ProgramPipeline
161 {
162 public:
163                                                         ProgramPipeline                         (const RenderContext& renderCtx);
164                                                         ProgramPipeline                         (const glw::Functions& gl);
165                                                         ~ProgramPipeline                        (void);
166
167         deUint32                                getPipeline                                     (void) const { return m_pipeline; }
168         void                                    useProgramStages                        (deUint32 stages, deUint32 program);
169         void                                    activeShaderProgram                     (deUint32 program);
170         bool                                    isValid                                         (void);
171
172 private:
173                                                         ProgramPipeline                         (const ProgramPipeline& other);
174         ProgramPipeline&                operator=                                       (const ProgramPipeline& other);
175
176         const glw::Functions&   m_gl;
177         deUint32                                m_pipeline;
178 };
179
180 struct ProgramSources;
181 struct ProgramBinaries;
182
183 /*--------------------------------------------------------------------*//*!
184  * \brief Shader program manager.
185  *
186  * ShaderProgram manages both Shader and Program objects, and provides
187  * convenient API for constructing such programs.
188  *//*--------------------------------------------------------------------*/
189 class ShaderProgram
190 {
191 public:
192                                                         ShaderProgram                           (const glw::Functions& gl, const ProgramSources& sources);
193                                                         ShaderProgram                           (const glw::Functions& gl, const ProgramBinaries& binaries);
194                                                         ShaderProgram                           (const RenderContext& renderCtx, const ProgramSources& sources);
195                                                         ShaderProgram                           (const RenderContext& renderCtx, const ProgramBinaries& binaries);
196                                                         ~ShaderProgram                          (void);
197
198         bool                                    isOk                                            (void) const                                                                                    { return m_program.getLinkStatus();                                             }
199         deUint32                                getProgram                                      (void) const                                                                                    { return m_program.getProgram();                                                }
200
201         bool                                    hasShader                                       (glu::ShaderType shaderType) const                                              { return !m_shaders[shaderType].empty();                                }
202         Shader*                                 getShader                                       (glu::ShaderType shaderType, int shaderNdx = 0) const   { return m_shaders[shaderType][shaderNdx];      }
203         int                                             getNumShaders                           (glu::ShaderType shaderType) const                                              { return (int)m_shaders[shaderType].size();                             }
204         const ShaderInfo&               getShaderInfo                           (glu::ShaderType shaderType, int shaderNdx = 0) const   { return m_shaders[shaderType][shaderNdx]->getInfo();   }
205         const ProgramInfo&              getProgramInfo                          (void) const                                                                                    { return m_program.getInfo();                                                   }
206
207 private:
208                                                         ShaderProgram                           (const ShaderProgram& other);
209         ShaderProgram&                  operator=                                       (const ShaderProgram& other);
210         void                                    init                                            (const glw::Functions& gl, const ProgramSources& sources);
211         void                                    init                                            (const glw::Functions& gl, const ProgramBinaries& binaries);
212         void                                    setBinary                                       (const glw::Functions& gl, std::vector<Shader*>& shaders, glw::GLenum binaryFormat, const void* binaryData, const int length);
213
214         std::vector<Shader*>    m_shaders[SHADERTYPE_LAST];
215         Program                                 m_program;
216 };
217
218 // Utilities.
219
220 deUint32                getGLShaderType         (ShaderType shaderType);
221 deUint32                getGLShaderTypeBit      (ShaderType shaderType);
222 qpShaderType    getLogShaderType        (ShaderType shaderType);
223
224 tcu::TestLog&   operator<<                      (tcu::TestLog& log, const ShaderInfo& shaderInfo);
225 tcu::TestLog&   operator<<                      (tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo);
226 tcu::TestLog&   operator<<                      (tcu::TestLog& log, const ProgramSources& sources);
227 tcu::TestLog&   operator<<                      (tcu::TestLog& log, const Shader& shader);
228 tcu::TestLog&   operator<<                      (tcu::TestLog& log, const ShaderProgram& program);
229
230 // ProgramSources utilities and implementation.
231
232 struct AttribLocationBinding
233 {
234         std::string                     name;
235         deUint32                        location;
236
237         AttribLocationBinding (void) : location(0) {}
238         AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
239 };
240
241 struct TransformFeedbackMode
242 {
243         deUint32                        mode;
244
245         TransformFeedbackMode (void) : mode(0) {}
246         TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
247 };
248
249 struct TransformFeedbackVarying
250 {
251         std::string                     name;
252
253         explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
254 };
255
256 struct ProgramSeparable
257 {
258         bool                            separable;
259         explicit ProgramSeparable (bool separable_) : separable(separable_) {}
260 };
261
262 template<typename Iterator>
263 struct TransformFeedbackVaryings
264 {
265         Iterator                        begin;
266         Iterator                        end;
267
268         TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
269 };
270
271 struct ShaderSource
272 {
273         ShaderType                      shaderType;
274         std::string                     source;
275
276         ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
277         ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
278 };
279
280 struct VertexSource : public ShaderSource
281 {
282         VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
283 };
284
285 struct FragmentSource : public ShaderSource
286 {
287         FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
288 };
289
290 struct GeometrySource : public ShaderSource
291 {
292         GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
293 };
294
295 struct ComputeSource : public ShaderSource
296 {
297         ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
298 };
299
300 struct TessellationControlSource : public ShaderSource
301 {
302         TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
303 };
304
305 struct TessellationEvaluationSource : public ShaderSource
306 {
307         TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
308 };
309
310 struct ProgramSources
311 {
312         std::vector<std::string>                        sources[SHADERTYPE_LAST];
313         std::vector<AttribLocationBinding>      attribLocationBindings;
314
315         deUint32                                                        transformFeedbackBufferMode;            //!< TF buffer mode, or GL_NONE.
316         std::vector<std::string>                        transformFeedbackVaryings;
317         bool                                                            separable;
318
319         ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
320
321         ProgramSources&                                         operator<<                      (const AttribLocationBinding& binding)          { attribLocationBindings.push_back(binding);                                            return *this;   }
322         ProgramSources&                                         operator<<                      (const TransformFeedbackMode& mode)                     { transformFeedbackBufferMode = mode.mode;                                                      return *this;   }
323         ProgramSources&                                         operator<<                      (const TransformFeedbackVarying& varying)       { transformFeedbackVaryings.push_back(varying.name);                            return *this;   }
324         ProgramSources&                                         operator<<                      (const ShaderSource& shaderSource)                      { sources[shaderSource.shaderType].push_back(shaderSource.source);      return *this;   }
325         ProgramSources&                                         operator<<                      (const ProgramSeparable& progSeparable)         { separable = progSeparable.separable;                                                          return *this;   }
326
327         template<typename Iterator>
328         ProgramSources&                                         operator<<                      (const TransformFeedbackVaryings<Iterator>& varyings);
329 };
330
331 struct SpecializationData
332 {
333         deUint32 index;
334         deUint32 value;
335
336         SpecializationData (void) : index(0), value(0) {}
337         SpecializationData (const deUint32 index_, const deUint32 value_) : index(index_), value(value_) {}
338 };
339
340 struct ShaderBinary
341 {
342         ShaderBinaryDataType            binary;
343         std::vector<ShaderType>         shaderTypes;
344         std::vector<std::string>        shaderEntryPoints;
345         std::vector<deUint32>           specializationIndices;
346         std::vector<deUint32>           specializationValues;
347
348         ShaderBinary (void) {}
349         ShaderBinary (const ShaderBinaryDataType binary_) : binary(binary_)
350         {
351                 DE_ASSERT(!binary_.empty());
352         }
353         ShaderBinary (const ShaderBinaryDataType binary_, glu::ShaderType shaderType_) : binary(binary_)
354         {
355                 DE_ASSERT(!binary_.empty());
356                 shaderTypes.push_back(shaderType_);
357                 shaderEntryPoints.push_back("main");
358         }
359
360         ShaderBinary& operator<< (const ShaderType& shaderType)
361         {
362                 shaderTypes.push_back(shaderType);
363                 return *this;
364         }
365
366         ShaderBinary& operator<< (const std::string& entryPoint)
367         {
368                 shaderEntryPoints.push_back(entryPoint);
369                 return *this;
370         }
371
372         ShaderBinary& operator<< (const SpecializationData& specData)
373         {
374                 specializationIndices.push_back(specData.index);
375                 specializationValues.push_back(specData.value);
376                 return *this;
377         }
378 };
379
380 struct VertexBinary : public ShaderBinary
381 {
382         VertexBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_VERTEX) {}
383 };
384
385 struct FragmentBinary : public ShaderBinary
386 {
387         FragmentBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_FRAGMENT) {}
388 };
389
390 struct GeometryBinary : public ShaderBinary
391 {
392         GeometryBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_GEOMETRY) {}
393 };
394
395 struct ComputeBinary : public ShaderBinary
396 {
397         ComputeBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_COMPUTE) {}
398 };
399
400 struct TessellationControlBinary : public ShaderBinary
401 {
402         TessellationControlBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_CONTROL) {}
403 };
404
405 struct TessellationEvaluationBinary : public ShaderBinary
406 {
407         TessellationEvaluationBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_EVALUATION) {}
408 };
409
410 struct ProgramBinaries
411 {
412         std::vector<ShaderBinary>       binaries;
413
414         glw::GLenum                                     binaryFormat;
415
416         ProgramBinaries (void) : binaryFormat(GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) {}
417         ProgramBinaries (glw::GLenum binaryFormat_) : binaryFormat(binaryFormat_) {}
418
419         ProgramBinaries& operator<< (const ShaderBinary& shaderBinary)  { binaries.push_back(shaderBinary);     return *this;   }
420 };
421
422 template<typename Iterator>
423 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
424 {
425         for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
426                 transformFeedbackVaryings.push_back(*cur);
427         return *this;
428 }
429
430 //! Helper for constructing vertex-fragment source pair.
431 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
432 {
433         ProgramSources sources;
434         sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
435         sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
436         return sources;
437 }
438
439 } // glu
440
441 #endif // _GLUSHADERPROGRAM_HPP