Fix missing dependency on sparse binds
[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) : type(SHADERTYPE_LAST), 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 RaygenSource : public ShaderSource
311 {
312         RaygenSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_RAYGEN, source_) {}
313 };
314
315 struct AnyHitSource : public ShaderSource
316 {
317         AnyHitSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_ANY_HIT, source_) {}
318 };
319
320 struct ClosestHitSource : public ShaderSource
321 {
322         ClosestHitSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_CLOSEST_HIT, source_) {}
323 };
324
325 struct MissSource : public ShaderSource
326 {
327         MissSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_MISS, source_) {}
328 };
329
330 struct IntersectionSource : public ShaderSource
331 {
332         IntersectionSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_INTERSECTION, source_) {}
333 };
334
335 struct CallableSource : public ShaderSource
336 {
337         CallableSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_CALLABLE, source_) {}
338 };
339
340 struct TaskSource : public ShaderSource
341 {
342         TaskSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_TASK, source_) {}
343 };
344
345 struct MeshSource : public ShaderSource
346 {
347         MeshSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_MESH, source_) {}
348 };
349
350 struct ProgramSources
351 {
352         std::vector<std::string>                        sources[SHADERTYPE_LAST];
353         std::vector<AttribLocationBinding>      attribLocationBindings;
354
355         deUint32                                                        transformFeedbackBufferMode;            //!< TF buffer mode, or GL_NONE.
356         std::vector<std::string>                        transformFeedbackVaryings;
357         bool                                                            separable;
358
359         ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
360
361         ProgramSources&                                         operator<<                      (const AttribLocationBinding& binding)          { attribLocationBindings.push_back(binding);                                            return *this;   }
362         ProgramSources&                                         operator<<                      (const TransformFeedbackMode& mode)                     { transformFeedbackBufferMode = mode.mode;                                                      return *this;   }
363         ProgramSources&                                         operator<<                      (const TransformFeedbackVarying& varying)       { transformFeedbackVaryings.push_back(varying.name);                            return *this;   }
364         ProgramSources&                                         operator<<                      (const ShaderSource& shaderSource)                      { sources[shaderSource.shaderType].push_back(shaderSource.source);      return *this;   }
365         ProgramSources&                                         operator<<                      (const ProgramSeparable& progSeparable)         { separable = progSeparable.separable;                                                          return *this;   }
366
367         template<typename Iterator>
368         ProgramSources&                                         operator<<                      (const TransformFeedbackVaryings<Iterator>& varyings);
369 };
370
371 struct SpecializationData
372 {
373         deUint32 index;
374         deUint32 value;
375
376         SpecializationData (void) : index(0), value(0) {}
377         SpecializationData (const deUint32 index_, const deUint32 value_) : index(index_), value(value_) {}
378 };
379
380 struct ShaderBinary
381 {
382         ShaderBinaryDataType            binary;
383         std::vector<ShaderType>         shaderTypes;
384         std::vector<std::string>        shaderEntryPoints;
385         std::vector<deUint32>           specializationIndices;
386         std::vector<deUint32>           specializationValues;
387
388         ShaderBinary (void) {}
389         ShaderBinary (const ShaderBinaryDataType binary_) : binary(binary_)
390         {
391                 DE_ASSERT(!binary_.empty());
392         }
393         ShaderBinary (const ShaderBinaryDataType binary_, glu::ShaderType shaderType_) : binary(binary_)
394         {
395                 DE_ASSERT(!binary_.empty());
396                 shaderTypes.push_back(shaderType_);
397                 shaderEntryPoints.push_back("main");
398         }
399
400         ShaderBinary& operator<< (const ShaderType& shaderType)
401         {
402                 shaderTypes.push_back(shaderType);
403                 return *this;
404         }
405
406         ShaderBinary& operator<< (const std::string& entryPoint)
407         {
408                 shaderEntryPoints.push_back(entryPoint);
409                 return *this;
410         }
411
412         ShaderBinary& operator<< (const SpecializationData& specData)
413         {
414                 specializationIndices.push_back(specData.index);
415                 specializationValues.push_back(specData.value);
416                 return *this;
417         }
418 };
419
420 struct VertexBinary : public ShaderBinary
421 {
422         VertexBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_VERTEX) {}
423 };
424
425 struct FragmentBinary : public ShaderBinary
426 {
427         FragmentBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_FRAGMENT) {}
428 };
429
430 struct GeometryBinary : public ShaderBinary
431 {
432         GeometryBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_GEOMETRY) {}
433 };
434
435 struct ComputeBinary : public ShaderBinary
436 {
437         ComputeBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_COMPUTE) {}
438 };
439
440 struct TessellationControlBinary : public ShaderBinary
441 {
442         TessellationControlBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_CONTROL) {}
443 };
444
445 struct TessellationEvaluationBinary : public ShaderBinary
446 {
447         TessellationEvaluationBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_EVALUATION) {}
448 };
449
450 struct ProgramBinaries
451 {
452         std::vector<ShaderBinary>       binaries;
453
454         glw::GLenum                                     binaryFormat;
455
456         ProgramBinaries (void) : binaryFormat(GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) {}
457         ProgramBinaries (glw::GLenum binaryFormat_) : binaryFormat(binaryFormat_) {}
458
459         ProgramBinaries& operator<< (const ShaderBinary& shaderBinary)  { binaries.push_back(shaderBinary);     return *this;   }
460 };
461
462 template<typename Iterator>
463 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
464 {
465         for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
466                 transformFeedbackVaryings.push_back(*cur);
467         return *this;
468 }
469
470 //! Helper for constructing vertex-fragment source pair.
471 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
472 {
473         ProgramSources sources;
474         sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
475         sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
476         return sources;
477 }
478
479 } // glu
480
481 #endif // _GLUSHADERPROGRAM_HPP