xref: /aosp_15_r20/external/deqp/framework/opengl/gluShaderProgram.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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<uint32_t> 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     uint64_t compileTimeUs; //!< Compile time in microseconds (us).
56 
ShaderInfoglu::ShaderInfo57     ShaderInfo(void) : type(SHADERTYPE_LAST), compileOk(false), compileTimeUs(0)
58     {
59     }
60 };
61 
62 /*--------------------------------------------------------------------*//*!
63  * \brief Program information (link status, log).
64  *//*--------------------------------------------------------------------*/
65 struct ProgramInfo
66 {
67     std::string infoLog; //!< Link info log.
68     bool linkOk;         //!< Did link succeed?
69     uint64_t linkTimeUs; //!< Link time in microseconds (us).
70 
ProgramInfoglu::ProgramInfo71     ProgramInfo(void) : linkOk(false), linkTimeUs(0)
72     {
73     }
74 };
75 
76 /*--------------------------------------------------------------------*//*!
77  * \brief Combined shader compilation and program linking info.
78  *//*--------------------------------------------------------------------*/
79 struct ShaderProgramInfo
80 {
81     glu::ProgramInfo program;
82     std::vector<glu::ShaderInfo> shaders;
83 };
84 
85 /*--------------------------------------------------------------------*//*!
86  * \brief Shader object.
87  *//*--------------------------------------------------------------------*/
88 class Shader
89 {
90 public:
91     Shader(const glw::Functions &gl, ShaderType shaderType);
92     Shader(const RenderContext &renderCtx, ShaderType shaderType);
93     ~Shader(void);
94 
95     void setSources(int numSourceStrings, const char *const *sourceStrings, const int *lengths);
96     void compile(void);
97     void specialize(const char *entryPoint, glw::GLuint numSpecializationConstants, const glw::GLuint *constantIndex,
98                     const glw::GLuint *constantValue);
99 
getShader(void) const100     uint32_t getShader(void) const
101     {
102         return m_shader;
103     }
getInfo(void) const104     const ShaderInfo &getInfo(void) const
105     {
106         return m_info;
107     }
108 
getType(void) const109     glu::ShaderType getType(void) const
110     {
111         return getInfo().type;
112     }
getCompileStatus(void) const113     bool getCompileStatus(void) const
114     {
115         return getInfo().compileOk;
116     }
getSource(void) const117     const std::string &getSource(void) const
118     {
119         return getInfo().source;
120     }
getInfoLog(void) const121     const std::string &getInfoLog(void) const
122     {
123         return getInfo().infoLog;
124     }
125 
operator *(void) const126     uint32_t operator*(void) const
127     {
128         return getShader();
129     }
130 
131 private:
132     Shader(const Shader &other);
133     Shader &operator=(const Shader &other);
134 
135     const glw::Functions &m_gl;
136     uint32_t m_shader; //!< Shader handle.
137     ShaderInfo m_info; //!< Client-side clone of state for debug / perf reasons.
138 };
139 
140 /*--------------------------------------------------------------------*//*!
141  * \brief Program object.
142  *//*--------------------------------------------------------------------*/
143 class Program
144 {
145 public:
146     Program(const glw::Functions &gl);
147     Program(const RenderContext &renderCtx);
148     Program(const RenderContext &renderCtx, uint32_t program);
149     ~Program(void);
150 
151     void attachShader(uint32_t shader);
152     void detachShader(uint32_t shader);
153 
154     void bindAttribLocation(uint32_t location, const char *name);
155     void transformFeedbackVaryings(int count, const char *const *varyings, uint32_t bufferMode);
156 
157     void link(void);
158 
getProgram(void) const159     uint32_t getProgram(void) const
160     {
161         return m_program;
162     }
getInfo(void) const163     const ProgramInfo &getInfo(void) const
164     {
165         return m_info;
166     }
167 
getLinkStatus(void) const168     bool getLinkStatus(void) const
169     {
170         return getInfo().linkOk;
171     }
getInfoLog(void) const172     const std::string &getInfoLog(void) const
173     {
174         return getInfo().infoLog;
175     }
176 
177     bool isSeparable(void) const;
178     void setSeparable(bool separable);
179 
180     int getUniformLocation(const std::string &name);
181 
operator *(void) const182     uint32_t operator*(void) const
183     {
184         return getProgram();
185     }
186 
187 private:
188     Program(const Program &other);
189     Program &operator=(const Program &other);
190 
191     const glw::Functions &m_gl;
192     uint32_t m_program;
193     ProgramInfo m_info;
194 };
195 
196 /*--------------------------------------------------------------------*//*!
197  * \brief Program pipeline object.
198  *//*--------------------------------------------------------------------*/
199 class ProgramPipeline
200 {
201 public:
202     ProgramPipeline(const RenderContext &renderCtx);
203     ProgramPipeline(const glw::Functions &gl);
204     ~ProgramPipeline(void);
205 
getPipeline(void) const206     uint32_t getPipeline(void) const
207     {
208         return m_pipeline;
209     }
210     void useProgramStages(uint32_t stages, uint32_t program);
211     void activeShaderProgram(uint32_t program);
212     bool isValid(void);
213 
214 private:
215     ProgramPipeline(const ProgramPipeline &other);
216     ProgramPipeline &operator=(const ProgramPipeline &other);
217 
218     const glw::Functions &m_gl;
219     uint32_t m_pipeline;
220 };
221 
222 struct ProgramSources;
223 struct ProgramBinaries;
224 
225 /*--------------------------------------------------------------------*//*!
226  * \brief Shader program manager.
227  *
228  * ShaderProgram manages both Shader and Program objects, and provides
229  * convenient API for constructing such programs.
230  *//*--------------------------------------------------------------------*/
231 class ShaderProgram
232 {
233 public:
234     ShaderProgram(const glw::Functions &gl, const ProgramSources &sources);
235     ShaderProgram(const glw::Functions &gl, const ProgramBinaries &binaries);
236     ShaderProgram(const RenderContext &renderCtx, const ProgramSources &sources);
237     ShaderProgram(const RenderContext &renderCtx, const ProgramBinaries &binaries);
238     ~ShaderProgram(void);
239 
isOk(void) const240     bool isOk(void) const
241     {
242         return m_program.getLinkStatus();
243     }
getProgram(void) const244     uint32_t getProgram(void) const
245     {
246         return m_program.getProgram();
247     }
248 
hasShader(glu::ShaderType shaderType) const249     bool hasShader(glu::ShaderType shaderType) const
250     {
251         return !m_shaders[shaderType].empty();
252     }
getShader(glu::ShaderType shaderType,int shaderNdx=0) const253     Shader *getShader(glu::ShaderType shaderType, int shaderNdx = 0) const
254     {
255         return m_shaders[shaderType][shaderNdx];
256     }
getNumShaders(glu::ShaderType shaderType) const257     int getNumShaders(glu::ShaderType shaderType) const
258     {
259         return (int)m_shaders[shaderType].size();
260     }
getShaderInfo(glu::ShaderType shaderType,int shaderNdx=0) const261     const ShaderInfo &getShaderInfo(glu::ShaderType shaderType, int shaderNdx = 0) const
262     {
263         return m_shaders[shaderType][shaderNdx]->getInfo();
264     }
getProgramInfo(void) const265     const ProgramInfo &getProgramInfo(void) const
266     {
267         return m_program.getInfo();
268     }
269 
270 private:
271     ShaderProgram(const ShaderProgram &other);
272     ShaderProgram &operator=(const ShaderProgram &other);
273     void init(const glw::Functions &gl, const ProgramSources &sources);
274     void init(const glw::Functions &gl, const ProgramBinaries &binaries);
275     void setBinary(const glw::Functions &gl, std::vector<Shader *> &shaders, glw::GLenum binaryFormat,
276                    const void *binaryData, const int length);
277 
278     std::vector<Shader *> m_shaders[SHADERTYPE_LAST];
279     Program m_program;
280 };
281 
282 // Utilities.
283 
284 uint32_t getGLShaderType(ShaderType shaderType);
285 uint32_t getGLShaderTypeBit(ShaderType shaderType);
286 qpShaderType getLogShaderType(ShaderType shaderType);
287 
288 tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderInfo &shaderInfo);
289 tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderProgramInfo &shaderProgramInfo);
290 tcu::TestLog &operator<<(tcu::TestLog &log, const ProgramSources &sources);
291 tcu::TestLog &operator<<(tcu::TestLog &log, const Shader &shader);
292 tcu::TestLog &operator<<(tcu::TestLog &log, const ShaderProgram &program);
293 
294 // ProgramSources utilities and implementation.
295 
296 struct AttribLocationBinding
297 {
298     std::string name;
299     uint32_t location;
300 
AttribLocationBindingglu::AttribLocationBinding301     AttribLocationBinding(void) : location(0)
302     {
303     }
AttribLocationBindingglu::AttribLocationBinding304     AttribLocationBinding(const std::string &name_, uint32_t location_) : name(name_), location(location_)
305     {
306     }
307 };
308 
309 struct TransformFeedbackMode
310 {
311     uint32_t mode;
312 
TransformFeedbackModeglu::TransformFeedbackMode313     TransformFeedbackMode(void) : mode(0)
314     {
315     }
TransformFeedbackModeglu::TransformFeedbackMode316     TransformFeedbackMode(uint32_t mode_) : mode(mode_)
317     {
318     }
319 };
320 
321 struct TransformFeedbackVarying
322 {
323     std::string name;
324 
TransformFeedbackVaryingglu::TransformFeedbackVarying325     explicit TransformFeedbackVarying(const std::string &name_) : name(name_)
326     {
327     }
328 };
329 
330 struct ProgramSeparable
331 {
332     bool separable;
ProgramSeparableglu::ProgramSeparable333     explicit ProgramSeparable(bool separable_) : separable(separable_)
334     {
335     }
336 };
337 
338 template <typename Iterator>
339 struct TransformFeedbackVaryings
340 {
341     Iterator begin;
342     Iterator end;
343 
TransformFeedbackVaryingsglu::TransformFeedbackVaryings344     TransformFeedbackVaryings(Iterator begin_, Iterator end_) : begin(begin_), end(end_)
345     {
346     }
347 };
348 
349 struct ShaderSource
350 {
351     ShaderType shaderType;
352     std::string source;
353 
ShaderSourceglu::ShaderSource354     ShaderSource(void) : shaderType(SHADERTYPE_LAST)
355     {
356     }
ShaderSourceglu::ShaderSource357     ShaderSource(glu::ShaderType shaderType_, const std::string &source_) : shaderType(shaderType_), source(source_)
358     {
359         DE_ASSERT(!source_.empty());
360     }
361 };
362 
363 struct VertexSource : public ShaderSource
364 {
VertexSourceglu::VertexSource365     VertexSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_)
366     {
367     }
368 };
369 
370 struct FragmentSource : public ShaderSource
371 {
FragmentSourceglu::FragmentSource372     FragmentSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_)
373     {
374     }
375 };
376 
377 struct GeometrySource : public ShaderSource
378 {
GeometrySourceglu::GeometrySource379     GeometrySource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_)
380     {
381     }
382 };
383 
384 struct ComputeSource : public ShaderSource
385 {
ComputeSourceglu::ComputeSource386     ComputeSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_)
387     {
388     }
389 };
390 
391 struct TessellationControlSource : public ShaderSource
392 {
TessellationControlSourceglu::TessellationControlSource393     TessellationControlSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_)
394     {
395     }
396 };
397 
398 struct TessellationEvaluationSource : public ShaderSource
399 {
TessellationEvaluationSourceglu::TessellationEvaluationSource400     TessellationEvaluationSource(const std::string &source_)
401         : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_)
402     {
403     }
404 };
405 
406 struct RaygenSource : public ShaderSource
407 {
RaygenSourceglu::RaygenSource408     RaygenSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_RAYGEN, source_)
409     {
410     }
411 };
412 
413 struct AnyHitSource : public ShaderSource
414 {
AnyHitSourceglu::AnyHitSource415     AnyHitSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_ANY_HIT, source_)
416     {
417     }
418 };
419 
420 struct ClosestHitSource : public ShaderSource
421 {
ClosestHitSourceglu::ClosestHitSource422     ClosestHitSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_CLOSEST_HIT, source_)
423     {
424     }
425 };
426 
427 struct MissSource : public ShaderSource
428 {
MissSourceglu::MissSource429     MissSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_MISS, source_)
430     {
431     }
432 };
433 
434 struct IntersectionSource : public ShaderSource
435 {
IntersectionSourceglu::IntersectionSource436     IntersectionSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_INTERSECTION, source_)
437     {
438     }
439 };
440 
441 struct CallableSource : public ShaderSource
442 {
CallableSourceglu::CallableSource443     CallableSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_CALLABLE, source_)
444     {
445     }
446 };
447 
448 struct TaskSource : public ShaderSource
449 {
TaskSourceglu::TaskSource450     TaskSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_TASK, source_)
451     {
452     }
453 };
454 
455 struct MeshSource : public ShaderSource
456 {
MeshSourceglu::MeshSource457     MeshSource(const std::string &source_) : ShaderSource(glu::SHADERTYPE_MESH, source_)
458     {
459     }
460 };
461 
462 struct ProgramSources
463 {
464     std::vector<std::string> sources[SHADERTYPE_LAST];
465     std::vector<AttribLocationBinding> attribLocationBindings;
466 
467     uint32_t transformFeedbackBufferMode; //!< TF buffer mode, or GL_NONE.
468     std::vector<std::string> transformFeedbackVaryings;
469     bool separable;
470 
ProgramSourcesglu::ProgramSources471     ProgramSources(void) : transformFeedbackBufferMode(0), separable(false)
472     {
473     }
474 
operator <<glu::ProgramSources475     ProgramSources &operator<<(const AttribLocationBinding &binding)
476     {
477         attribLocationBindings.push_back(binding);
478         return *this;
479     }
operator <<glu::ProgramSources480     ProgramSources &operator<<(const TransformFeedbackMode &mode)
481     {
482         transformFeedbackBufferMode = mode.mode;
483         return *this;
484     }
operator <<glu::ProgramSources485     ProgramSources &operator<<(const TransformFeedbackVarying &varying)
486     {
487         transformFeedbackVaryings.push_back(varying.name);
488         return *this;
489     }
operator <<glu::ProgramSources490     ProgramSources &operator<<(const ShaderSource &shaderSource)
491     {
492         sources[shaderSource.shaderType].push_back(shaderSource.source);
493         return *this;
494     }
operator <<glu::ProgramSources495     ProgramSources &operator<<(const ProgramSeparable &progSeparable)
496     {
497         separable = progSeparable.separable;
498         return *this;
499     }
500 
501     template <typename Iterator>
502     ProgramSources &operator<<(const TransformFeedbackVaryings<Iterator> &varyings);
503 };
504 
505 struct SpecializationData
506 {
507     uint32_t index;
508     uint32_t value;
509 
SpecializationDataglu::SpecializationData510     SpecializationData(void) : index(0), value(0)
511     {
512     }
SpecializationDataglu::SpecializationData513     SpecializationData(const uint32_t index_, const uint32_t value_) : index(index_), value(value_)
514     {
515     }
516 };
517 
518 struct ShaderBinary
519 {
520     ShaderBinaryDataType binary;
521     std::vector<ShaderType> shaderTypes;
522     std::vector<std::string> shaderEntryPoints;
523     std::vector<uint32_t> specializationIndices;
524     std::vector<uint32_t> specializationValues;
525 
ShaderBinaryglu::ShaderBinary526     ShaderBinary(void)
527     {
528     }
ShaderBinaryglu::ShaderBinary529     ShaderBinary(const ShaderBinaryDataType binary_) : binary(binary_)
530     {
531         DE_ASSERT(!binary_.empty());
532     }
ShaderBinaryglu::ShaderBinary533     ShaderBinary(const ShaderBinaryDataType binary_, glu::ShaderType shaderType_) : binary(binary_)
534     {
535         DE_ASSERT(!binary_.empty());
536         shaderTypes.push_back(shaderType_);
537         shaderEntryPoints.push_back("main");
538     }
539 
operator <<glu::ShaderBinary540     ShaderBinary &operator<<(const ShaderType &shaderType)
541     {
542         shaderTypes.push_back(shaderType);
543         return *this;
544     }
545 
operator <<glu::ShaderBinary546     ShaderBinary &operator<<(const std::string &entryPoint)
547     {
548         shaderEntryPoints.push_back(entryPoint);
549         return *this;
550     }
551 
operator <<glu::ShaderBinary552     ShaderBinary &operator<<(const SpecializationData &specData)
553     {
554         specializationIndices.push_back(specData.index);
555         specializationValues.push_back(specData.value);
556         return *this;
557     }
558 };
559 
560 struct VertexBinary : public ShaderBinary
561 {
VertexBinaryglu::VertexBinary562     VertexBinary(const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_VERTEX)
563     {
564     }
565 };
566 
567 struct FragmentBinary : public ShaderBinary
568 {
FragmentBinaryglu::FragmentBinary569     FragmentBinary(const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_FRAGMENT)
570     {
571     }
572 };
573 
574 struct GeometryBinary : public ShaderBinary
575 {
GeometryBinaryglu::GeometryBinary576     GeometryBinary(const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_GEOMETRY)
577     {
578     }
579 };
580 
581 struct ComputeBinary : public ShaderBinary
582 {
ComputeBinaryglu::ComputeBinary583     ComputeBinary(const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_COMPUTE)
584     {
585     }
586 };
587 
588 struct TessellationControlBinary : public ShaderBinary
589 {
TessellationControlBinaryglu::TessellationControlBinary590     TessellationControlBinary(const ShaderBinaryDataType binary_)
591         : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_CONTROL)
592     {
593     }
594 };
595 
596 struct TessellationEvaluationBinary : public ShaderBinary
597 {
TessellationEvaluationBinaryglu::TessellationEvaluationBinary598     TessellationEvaluationBinary(const ShaderBinaryDataType binary_)
599         : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_EVALUATION)
600     {
601     }
602 };
603 
604 struct ProgramBinaries
605 {
606     std::vector<ShaderBinary> binaries;
607 
608     glw::GLenum binaryFormat;
609 
ProgramBinariesglu::ProgramBinaries610     ProgramBinaries(void) : binaryFormat(GL_SHADER_BINARY_FORMAT_SPIR_V_ARB)
611     {
612     }
ProgramBinariesglu::ProgramBinaries613     ProgramBinaries(glw::GLenum binaryFormat_) : binaryFormat(binaryFormat_)
614     {
615     }
616 
operator <<glu::ProgramBinaries617     ProgramBinaries &operator<<(const ShaderBinary &shaderBinary)
618     {
619         binaries.push_back(shaderBinary);
620         return *this;
621     }
622 };
623 
624 template <typename Iterator>
operator <<(const TransformFeedbackVaryings<Iterator> & varyings)625 inline ProgramSources &ProgramSources::operator<<(const TransformFeedbackVaryings<Iterator> &varyings)
626 {
627     for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
628         transformFeedbackVaryings.push_back(*cur);
629     return *this;
630 }
631 
632 //! Helper for constructing vertex-fragment source pair.
makeVtxFragSources(const std::string & vertexSrc,const std::string & fragmentSrc)633 inline ProgramSources makeVtxFragSources(const std::string &vertexSrc, const std::string &fragmentSrc)
634 {
635     ProgramSources sources;
636     sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
637     sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
638     return sources;
639 }
640 
641 } // namespace glu
642 
643 #endif // _GLUSHADERPROGRAM_HPP
644