xref: /aosp_15_r20/external/angle/util/shader_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "util/shader_utils.h"
8 
9 #include <cstring>
10 #include <fstream>
11 #include <iostream>
12 #include <vector>
13 
14 #include "common/utilities.h"
15 #include "util/test_utils.h"
16 
17 namespace
18 {
CompileProgramInternal(const char * vsSource,const char * tcsSource,const char * tesSource,const char * gsSource,const char * fsSource,const std::function<void (GLuint)> & preLinkCallback)19 GLuint CompileProgramInternal(const char *vsSource,
20                               const char *tcsSource,
21                               const char *tesSource,
22                               const char *gsSource,
23                               const char *fsSource,
24                               const std::function<void(GLuint)> &preLinkCallback)
25 {
26     GLuint program = glCreateProgram();
27 
28     GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
29     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
30 
31     if (vs == 0 || fs == 0)
32     {
33         glDeleteShader(fs);
34         glDeleteShader(vs);
35         glDeleteProgram(program);
36         return 0;
37     }
38 
39     glAttachShader(program, vs);
40     glDeleteShader(vs);
41 
42     glAttachShader(program, fs);
43     glDeleteShader(fs);
44 
45     GLuint tcs = 0;
46     GLuint tes = 0;
47     GLuint gs  = 0;
48 
49     if (strlen(tcsSource) > 0)
50     {
51         tcs = CompileShader(GL_TESS_CONTROL_SHADER_EXT, tcsSource);
52         if (tcs == 0)
53         {
54             glDeleteShader(vs);
55             glDeleteShader(fs);
56             glDeleteProgram(program);
57             return 0;
58         }
59 
60         glAttachShader(program, tcs);
61         glDeleteShader(tcs);
62     }
63 
64     if (strlen(tesSource) > 0)
65     {
66         tes = CompileShader(GL_TESS_EVALUATION_SHADER_EXT, tesSource);
67         if (tes == 0)
68         {
69             glDeleteShader(vs);
70             glDeleteShader(fs);
71             glDeleteShader(tcs);
72             glDeleteProgram(program);
73             return 0;
74         }
75 
76         glAttachShader(program, tes);
77         glDeleteShader(tes);
78     }
79 
80     if (strlen(gsSource) > 0)
81     {
82         gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource);
83         if (gs == 0)
84         {
85             glDeleteShader(vs);
86             glDeleteShader(fs);
87             glDeleteShader(tcs);
88             glDeleteShader(tes);
89             glDeleteProgram(program);
90             return 0;
91         }
92 
93         glAttachShader(program, gs);
94         glDeleteShader(gs);
95     }
96 
97     if (preLinkCallback)
98     {
99         preLinkCallback(program);
100     }
101 
102     glLinkProgram(program);
103 
104     return CheckLinkStatusAndReturnProgram(program, true);
105 }
106 
107 const void *gCallbackChainUserParam;
108 
DebugMessageCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)109 void KHRONOS_APIENTRY DebugMessageCallback(GLenum source,
110                                            GLenum type,
111                                            GLuint id,
112                                            GLenum severity,
113                                            GLsizei length,
114                                            const GLchar *message,
115                                            const void *userParam)
116 {
117     std::string sourceText   = gl::GetDebugMessageSourceString(source);
118     std::string typeText     = gl::GetDebugMessageTypeString(type);
119     std::string severityText = gl::GetDebugMessageSeverityString(severity);
120     std::cerr << sourceText << ", " << typeText << ", " << severityText << ": " << message << "\n";
121 
122     GLDEBUGPROC callbackChain = reinterpret_cast<GLDEBUGPROC>(const_cast<void *>(userParam));
123     if (callbackChain)
124     {
125         callbackChain(source, type, id, severity, length, message, gCallbackChainUserParam);
126     }
127 }
128 
GetPerfCounterValue(const CounterNameToIndexMap & counterIndexMap,std::vector<angle::PerfMonitorTriplet> & triplets,const char * name,GLuint64 * counterOut)129 void GetPerfCounterValue(const CounterNameToIndexMap &counterIndexMap,
130                          std::vector<angle::PerfMonitorTriplet> &triplets,
131                          const char *name,
132                          GLuint64 *counterOut)
133 {
134     auto iter = counterIndexMap.find(name);
135     ASSERT(iter != counterIndexMap.end());
136     GLuint counterIndex = iter->second;
137 
138     for (const angle::PerfMonitorTriplet &triplet : triplets)
139     {
140         ASSERT(triplet.group == 0);
141         if (triplet.counter == counterIndex)
142         {
143             *counterOut = triplet.value;
144             return;
145         }
146     }
147 
148     // Additional logs for b/382094011
149     std::cerr << "GetPerfCounterValue missing counter: " << name << "; index: " << counterIndex
150               << "; triplets: " << std::endl;
151     for (const angle::PerfMonitorTriplet &triplet : triplets)
152     {
153         std::cerr << triplet.counter << " " << triplet.value << std::endl;
154     }
155 
156     UNREACHABLE();
157 }
158 }  // namespace
159 
CompileShader(GLenum type,const char * source)160 GLuint CompileShader(GLenum type, const char *source)
161 {
162     GLuint shader = glCreateShader(type);
163 
164     const char *sourceArray[1] = {source};
165     glShaderSource(shader, 1, sourceArray, nullptr);
166     glCompileShader(shader);
167 
168     GLint compileResult;
169     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
170 
171     if (compileResult == 0)
172     {
173         GLint infoLogLength;
174         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
175 
176         // Info log length includes the null terminator, so 1 means that the info log is an empty
177         // string.
178         if (infoLogLength > 1)
179         {
180             std::vector<GLchar> infoLog(infoLogLength);
181             glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), nullptr, &infoLog[0]);
182             std::cerr << "shader compilation failed: " << &infoLog[0];
183         }
184         else
185         {
186             std::cerr << "shader compilation failed. <Empty log message>";
187         }
188 
189         std::cerr << std::endl;
190 
191         glDeleteShader(shader);
192         shader = 0;
193     }
194 
195     return shader;
196 }
197 
CompileShaderFromFile(GLenum type,const std::string & sourcePath)198 GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
199 {
200     std::string source;
201     if (!angle::ReadEntireFileToString(sourcePath.c_str(), &source))
202     {
203         std::cerr << "Error reading shader file: " << sourcePath << "\n";
204         return 0;
205     }
206 
207     return CompileShader(type, source.c_str());
208 }
209 
CheckLinkStatusAndReturnProgram(GLuint program,bool outputErrorMessages)210 GLuint CheckLinkStatusAndReturnProgram(GLuint program, bool outputErrorMessages)
211 {
212     if (glGetError() != GL_NO_ERROR)
213         return 0;
214 
215     GLint linkStatus;
216     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
217     if (linkStatus == 0)
218     {
219         if (outputErrorMessages)
220         {
221             GLint infoLogLength;
222             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
223 
224             // Info log length includes the null terminator, so 1 means that the info log is an
225             // empty string.
226             if (infoLogLength > 1)
227             {
228                 std::vector<GLchar> infoLog(infoLogLength);
229                 glGetProgramInfoLog(program, static_cast<GLsizei>(infoLog.size()), nullptr,
230                                     &infoLog[0]);
231 
232                 std::cerr << "program link failed: " << &infoLog[0];
233             }
234             else
235             {
236                 std::cerr << "program link failed. <Empty log message>";
237             }
238         }
239 
240         glDeleteProgram(program);
241         return 0;
242     }
243 
244     return program;
245 }
246 
GetProgramShader(GLuint program,GLint requestedType)247 GLuint GetProgramShader(GLuint program, GLint requestedType)
248 {
249     static constexpr GLsizei kMaxShaderCount = 16;
250     GLuint attachedShaders[kMaxShaderCount]  = {0u};
251     GLsizei count                            = 0;
252     glGetAttachedShaders(program, kMaxShaderCount, &count, attachedShaders);
253     for (int i = 0; i < count; ++i)
254     {
255         GLint type = 0;
256         glGetShaderiv(attachedShaders[i], GL_SHADER_TYPE, &type);
257         if (type == requestedType)
258         {
259             return attachedShaders[i];
260         }
261     }
262 
263     return 0;
264 }
265 
CompileProgramWithTransformFeedback(const char * vsSource,const char * fsSource,const std::vector<std::string> & transformFeedbackVaryings,GLenum bufferMode)266 GLuint CompileProgramWithTransformFeedback(
267     const char *vsSource,
268     const char *fsSource,
269     const std::vector<std::string> &transformFeedbackVaryings,
270     GLenum bufferMode)
271 {
272     auto preLink = [&](GLuint program) {
273         if (transformFeedbackVaryings.size() > 0)
274         {
275             std::vector<const char *> constCharTFVaryings;
276 
277             for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
278             {
279                 constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
280             }
281 
282             glTransformFeedbackVaryings(program,
283                                         static_cast<GLsizei>(transformFeedbackVaryings.size()),
284                                         &constCharTFVaryings[0], bufferMode);
285         }
286     };
287 
288     return CompileProgramInternal(vsSource, "", "", "", fsSource, preLink);
289 }
290 
CompileProgram(const char * vsSource,const char * fsSource)291 GLuint CompileProgram(const char *vsSource, const char *fsSource)
292 {
293     return CompileProgramInternal(vsSource, "", "", "", fsSource, nullptr);
294 }
295 
CompileProgram(const char * vsSource,const char * fsSource,const std::function<void (GLuint)> & preLinkCallback)296 GLuint CompileProgram(const char *vsSource,
297                       const char *fsSource,
298                       const std::function<void(GLuint)> &preLinkCallback)
299 {
300     return CompileProgramInternal(vsSource, "", "", "", fsSource, preLinkCallback);
301 }
302 
CompileProgramWithGS(const char * vsSource,const char * gsSource,const char * fsSource)303 GLuint CompileProgramWithGS(const char *vsSource, const char *gsSource, const char *fsSource)
304 {
305     return CompileProgramInternal(vsSource, "", "", gsSource, fsSource, nullptr);
306 }
307 
CompileProgramWithTESS(const char * vsSource,const char * tcsSource,const char * tesSource,const char * fsSource)308 GLuint CompileProgramWithTESS(const char *vsSource,
309                               const char *tcsSource,
310                               const char *tesSource,
311                               const char *fsSource)
312 {
313     return CompileProgramInternal(vsSource, tcsSource, tesSource, "", fsSource, nullptr);
314 }
315 
CompileProgramFromFiles(const std::string & vsPath,const std::string & fsPath)316 GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
317 {
318     std::string vsSource;
319     if (!angle::ReadEntireFileToString(vsPath.c_str(), &vsSource))
320     {
321         std::cerr << "Error reading shader: " << vsPath << "\n";
322         return 0;
323     }
324 
325     std::string fsSource;
326     if (!angle::ReadEntireFileToString(fsPath.c_str(), &fsSource))
327     {
328         std::cerr << "Error reading shader: " << fsPath << "\n";
329         return 0;
330     }
331 
332     return CompileProgram(vsSource.c_str(), fsSource.c_str());
333 }
334 
CompileComputeProgram(const char * csSource,bool outputErrorMessages)335 GLuint CompileComputeProgram(const char *csSource, bool outputErrorMessages)
336 {
337     GLuint program = glCreateProgram();
338 
339     GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
340     if (cs == 0)
341     {
342         glDeleteProgram(program);
343         return 0;
344     }
345 
346     glAttachShader(program, cs);
347 
348     glLinkProgram(program);
349 
350     return CheckLinkStatusAndReturnProgram(program, outputErrorMessages);
351 }
352 
LoadBinaryProgramOES(const std::vector<uint8_t> & binary,GLenum binaryFormat)353 GLuint LoadBinaryProgramOES(const std::vector<uint8_t> &binary, GLenum binaryFormat)
354 {
355     GLuint program = glCreateProgram();
356     glProgramBinaryOES(program, binaryFormat, binary.data(), static_cast<GLint>(binary.size()));
357     return CheckLinkStatusAndReturnProgram(program, true);
358 }
359 
LoadBinaryProgramES3(const std::vector<uint8_t> & binary,GLenum binaryFormat)360 GLuint LoadBinaryProgramES3(const std::vector<uint8_t> &binary, GLenum binaryFormat)
361 {
362     GLuint program = glCreateProgram();
363     glProgramBinary(program, binaryFormat, binary.data(), static_cast<GLint>(binary.size()));
364     return CheckLinkStatusAndReturnProgram(program, true);
365 }
366 
LinkAttachedProgram(GLuint program)367 bool LinkAttachedProgram(GLuint program)
368 {
369     glLinkProgram(program);
370     return (CheckLinkStatusAndReturnProgram(program, true) != 0);
371 }
372 
EnableDebugCallback(GLDEBUGPROC callbackChain,const void * userParam)373 void EnableDebugCallback(GLDEBUGPROC callbackChain, const void *userParam)
374 {
375     gCallbackChainUserParam = userParam;
376 
377     glEnable(GL_DEBUG_OUTPUT);
378     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
379     // Enable medium and high priority messages.
380     glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr,
381                              GL_TRUE);
382     glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr,
383                              GL_TRUE);
384     // Disable low and notification priority messages.
385     glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr,
386                              GL_FALSE);
387     glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr,
388                              GL_FALSE);
389     // Disable performance messages to reduce spam.
390     glDebugMessageControlKHR(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE, 0, nullptr,
391                              GL_FALSE);
392     glDebugMessageCallbackKHR(DebugMessageCallback, reinterpret_cast<const void *>(callbackChain));
393 }
394 
BuildCounterNameToIndexMap()395 CounterNameToIndexMap BuildCounterNameToIndexMap()
396 {
397     GLint numCounters = 0;
398     glGetPerfMonitorCountersAMD(0, &numCounters, nullptr, 0, nullptr);
399     if (glGetError() != GL_NO_ERROR)
400     {
401         std::cerr << "glGetPerfMonitorCountersAMD failed (count)" << std::endl;
402         return {};
403     }
404 
405     std::vector<GLuint> counterIndexes(numCounters, 0);
406     glGetPerfMonitorCountersAMD(0, nullptr, nullptr, numCounters, counterIndexes.data());
407     if (glGetError() != GL_NO_ERROR)
408     {
409         std::cerr << "glGetPerfMonitorCountersAMD failed (data)" << std::endl;
410         return {};
411     }
412 
413     CounterNameToIndexMap indexMap;
414 
415     for (GLuint counterIndex : counterIndexes)
416     {
417         static constexpr size_t kBufSize = 1000;
418         char buffer[kBufSize]            = {};
419         glGetPerfMonitorCounterStringAMD(0, counterIndex, kBufSize, nullptr, buffer);
420         if (glGetError() != GL_NO_ERROR)
421         {
422             std::cerr << "glGetPerfMonitorCounterStringAMD failed" << std::endl;
423             return {};
424         }
425 
426         indexMap[buffer] = counterIndex;
427     }
428 
429     return indexMap;
430 }
431 
GetPerfMonitorTriplets()432 std::vector<angle::PerfMonitorTriplet> GetPerfMonitorTriplets()
433 {
434     GLuint resultSize = 0;
435     glGetPerfMonitorCounterDataAMD(0, GL_PERFMON_RESULT_SIZE_AMD, sizeof(GLuint), &resultSize,
436                                    nullptr);
437     if (glGetError() != GL_NO_ERROR || resultSize == 0)
438     {
439         std::cerr << "glGetPerfMonitorCounterDataAMD failed (count)" << std::endl;
440         return {};
441     }
442 
443     std::vector<angle::PerfMonitorTriplet> perfResults(resultSize /
444                                                        sizeof(angle::PerfMonitorTriplet));
445     GLint bytesWritten = 0;
446     glGetPerfMonitorCounterDataAMD(
447         0, GL_PERFMON_RESULT_AMD, static_cast<GLsizei>(perfResults.size() * sizeof(perfResults[0])),
448         &perfResults.data()->group, &bytesWritten);
449 
450     if (glGetError() != GL_NO_ERROR)
451     {
452         std::cerr << "glGetPerfMonitorCounterDataAMD failed (data)" << std::endl;
453         return {};
454     }
455     ASSERT(static_cast<GLuint>(bytesWritten) == resultSize);
456 
457     return perfResults;
458 }
459 
GetPerfCounters(const CounterNameToIndexMap & indexMap)460 angle::VulkanPerfCounters GetPerfCounters(const CounterNameToIndexMap &indexMap)
461 {
462     std::vector<angle::PerfMonitorTriplet> perfResults = GetPerfMonitorTriplets();
463 
464     angle::VulkanPerfCounters counters;
465 
466 #define ANGLE_UNPACK_PERF_COUNTER(COUNTER) \
467     GetPerfCounterValue(indexMap, perfResults, #COUNTER, &counters.COUNTER);
468 
469     ANGLE_VK_PERF_COUNTERS_X(ANGLE_UNPACK_PERF_COUNTER)
470 
471 #undef ANGLE_UNPACK_PERF_COUNTER
472 
473     return counters;
474 }
475 
BuildCounterNameToValueMap()476 CounterNameToValueMap BuildCounterNameToValueMap()
477 {
478     CounterNameToIndexMap indexMap                     = BuildCounterNameToIndexMap();
479     std::vector<angle::PerfMonitorTriplet> perfResults = GetPerfMonitorTriplets();
480 
481     CounterNameToValueMap valueMap;
482 
483     for (const auto &iter : indexMap)
484     {
485         const std::string &name = iter.first;
486         GLuint index            = iter.second;
487 
488         valueMap[name] = perfResults[index].value;
489     }
490 
491     return valueMap;
492 }
493 
494 namespace angle
495 {
496 
497 namespace essl1_shaders
498 {
499 
PositionAttrib()500 const char *PositionAttrib()
501 {
502     return "a_position";
503 }
ColorUniform()504 const char *ColorUniform()
505 {
506     return "u_color";
507 }
508 
Texture2DUniform()509 const char *Texture2DUniform()
510 {
511     return "u_tex2D";
512 }
513 
514 namespace vs
515 {
516 
517 // A shader that sets gl_Position to zero.
Zero()518 const char *Zero()
519 {
520     return R"(void main()
521 {
522     gl_Position = vec4(0);
523 })";
524 }
525 
526 // A shader that sets gl_Position to attribute a_position.
Simple()527 const char *Simple()
528 {
529     return R"(precision highp float;
530 attribute vec4 a_position;
531 
532 void main()
533 {
534     gl_Position = a_position;
535 })";
536 }
537 
538 // A shader that sets gl_Position to attribute a_position, and sets gl_PointSize to 1.
SimpleForPoints()539 const char *SimpleForPoints()
540 {
541     return R"(precision highp float;
542 attribute vec4 a_position;
543 
544 void main()
545 {
546     gl_Position = a_position;
547     gl_PointSize = 1.0;
548 })";
549 }
550 
551 // A shader that simply passes through attribute a_position, setting it to gl_Position and varying
552 // v_position.
Passthrough()553 const char *Passthrough()
554 {
555     return R"(precision highp float;
556 attribute vec4 a_position;
557 varying vec4 v_position;
558 
559 void main()
560 {
561     gl_Position = a_position;
562     v_position = a_position;
563 })";
564 }
565 
566 // A shader that simply passes through attribute a_position, setting it to gl_Position and varying
567 // texcoord.
Texture2D()568 const char *Texture2D()
569 {
570     return R"(precision highp float;
571 attribute vec4 a_position;
572 varying vec2 v_texCoord;
573 
574 void main()
575 {
576     gl_Position = a_position;
577     v_texCoord = a_position.xy * 0.5 + vec2(0.5);
578 })";
579 }
580 
Texture2DArray()581 const char *Texture2DArray()
582 {
583     return R"(#version 300 es
584 out vec2 v_texCoord;
585 in vec4 a_position;
586 void main()
587 {
588     gl_Position = vec4(a_position.xy, 0.0, 1.0);
589     v_texCoord = (a_position.xy * 0.5) + 0.5;
590 })";
591 }
592 
593 }  // namespace vs
594 
595 namespace fs
596 {
597 
598 // A shader that renders a simple checker pattern of red and green. X axis and y axis separate the
599 // different colors. Needs varying v_position.
Checkered()600 const char *Checkered()
601 {
602     return R"(precision highp float;
603 varying vec4 v_position;
604 
605 void main()
606 {
607     bool isLeft = v_position.x < 0.0;
608     bool isTop = v_position.y < 0.0;
609     if (isLeft)
610     {
611         if (isTop)
612         {
613             gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
614         }
615         else
616         {
617             gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
618         }
619     }
620     else
621     {
622         if (isTop)
623         {
624             gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
625         }
626         else
627         {
628             gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
629         }
630     }
631 })";
632 }
633 
634 // A shader that fills with color taken from uniform named "color".
UniformColor()635 const char *UniformColor()
636 {
637     return R"(uniform mediump vec4 u_color;
638 void main(void)
639 {
640     gl_FragColor = u_color;
641 })";
642 }
643 
644 // A shader that fills with 100% opaque red.
Red()645 const char *Red()
646 {
647     return R"(precision mediump float;
648 
649 void main()
650 {
651     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
652 })";
653 }
654 
655 // A shader that fills with 100% opaque green.
Green()656 const char *Green()
657 {
658     return R"(precision mediump float;
659 
660 void main()
661 {
662     gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
663 })";
664 }
665 
666 // A shader that fills with 100% opaque blue.
Blue()667 const char *Blue()
668 {
669     return R"(precision mediump float;
670 
671 void main()
672 {
673     gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
674 })";
675 }
676 
677 // A shader that samples the texture.
Texture2D()678 const char *Texture2D()
679 {
680     return R"(precision mediump float;
681 uniform sampler2D u_tex2D;
682 varying vec2 v_texCoord;
683 
684 void main()
685 {
686     gl_FragColor = texture2D(u_tex2D, v_texCoord);
687 })";
688 }
689 
Texture2DArray()690 const char *Texture2DArray()
691 {
692     return R"(#version 300 es
693 precision highp float;
694 uniform highp sampler2DArray tex2DArray;
695 uniform int slice;
696 in vec2 v_texCoord;
697 out vec4 fragColor;
698 void main()
699 {
700     fragColor = texture(tex2DArray, vec3(v_texCoord, float(slice)));
701 })";
702 }
703 
704 }  // namespace fs
705 }  // namespace essl1_shaders
706 
707 namespace essl3_shaders
708 {
709 
PositionAttrib()710 const char *PositionAttrib()
711 {
712     return "a_position";
713 }
Texture2DUniform()714 const char *Texture2DUniform()
715 {
716     return "u_tex2D";
717 }
LodUniform()718 const char *LodUniform()
719 {
720     return "u_lod";
721 }
722 
723 namespace vs
724 {
725 
726 // A shader that sets gl_Position to zero.
Zero()727 const char *Zero()
728 {
729     return R"(#version 300 es
730 void main()
731 {
732     gl_Position = vec4(0);
733 })";
734 }
735 
736 // A shader that sets gl_Position to attribute a_position.
Simple()737 const char *Simple()
738 {
739     return R"(#version 300 es
740 in vec4 a_position;
741 void main()
742 {
743     gl_Position = a_position;
744 })";
745 }
746 
747 // A shader that sets gl_Position to attribute a_position, and sets gl_PointSize to 1.
SimpleForPoints()748 const char *SimpleForPoints()
749 {
750     return R"(#version 300 es
751 in vec4 a_position;
752 void main()
753 {
754     gl_Position = a_position;
755     gl_PointSize = 1.0;
756 })";
757 }
758 
759 // A shader that simply passes through attribute a_position, setting it to gl_Position and varying
760 // v_position.
Passthrough()761 const char *Passthrough()
762 {
763     return R"(#version 300 es
764 in vec4 a_position;
765 out vec4 v_position;
766 void main()
767 {
768     gl_Position = a_position;
769     v_position = a_position;
770 })";
771 }
772 
773 // A shader that simply passes through attribute a_position, setting it to gl_Position and varying
774 // texcoord.
Texture2DLod()775 const char *Texture2DLod()
776 {
777     return R"(#version 300 es
778 in vec4 a_position;
779 out vec2 v_texCoord;
780 
781 void main()
782 {
783     gl_Position = vec4(a_position.xy, 0.0, 1.0);
784     v_texCoord = a_position.xy * 0.5 + vec2(0.5);
785 })";
786 }
787 
788 }  // namespace vs
789 
790 namespace fs
791 {
792 
793 // A shader that fills with 100% opaque red.
Red()794 const char *Red()
795 {
796     return R"(#version 300 es
797 precision highp float;
798 out vec4 my_FragColor;
799 void main()
800 {
801     my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
802 })";
803 }
804 
805 // A shader that fills with 100% opaque green.
Green()806 const char *Green()
807 {
808     return R"(#version 300 es
809 precision highp float;
810 out vec4 my_FragColor;
811 void main()
812 {
813     my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
814 })";
815 }
816 
817 // A shader that fills with 100% opaque blue.
Blue()818 const char *Blue()
819 {
820     return R"(#version 300 es
821 precision highp float;
822 out vec4 my_FragColor;
823 void main()
824 {
825     my_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
826 })";
827 }
828 
829 // A shader that samples the texture at a given lod.
Texture2DLod()830 const char *Texture2DLod()
831 {
832     return R"(#version 300 es
833 precision mediump float;
834 uniform sampler2D u_tex2D;
835 uniform float u_lod;
836 in vec2 v_texCoord;
837 out vec4 my_FragColor;
838 
839 void main()
840 {
841     my_FragColor = textureLod(u_tex2D, v_texCoord, u_lod);
842 })";
843 }
844 
845 }  // namespace fs
846 }  // namespace essl3_shaders
847 
848 namespace essl31_shaders
849 {
850 
PositionAttrib()851 const char *PositionAttrib()
852 {
853     return "a_position";
854 }
855 
856 namespace vs
857 {
858 
859 // A shader that sets gl_Position to zero.
Zero()860 const char *Zero()
861 {
862     return R"(#version 310 es
863 void main()
864 {
865     gl_Position = vec4(0);
866 })";
867 }
868 
869 // A shader that sets gl_Position to attribute a_position.
Simple()870 const char *Simple()
871 {
872     return R"(#version 310 es
873 in vec4 a_position;
874 void main()
875 {
876     gl_Position = a_position;
877 })";
878 }
879 
880 // A shader that simply passes through attribute a_position, setting it to gl_Position and varying
881 // v_position.
Passthrough()882 const char *Passthrough()
883 {
884     return R"(#version 310 es
885 in vec4 a_position;
886 out vec4 v_position;
887 void main()
888 {
889     gl_Position = a_position;
890     v_position = a_position;
891 })";
892 }
893 
894 }  // namespace vs
895 
896 namespace fs
897 {
898 
899 // A shader that fills with 100% opaque red.
Red()900 const char *Red()
901 {
902     return R"(#version 310 es
903 precision highp float;
904 out vec4 my_FragColor;
905 void main()
906 {
907     my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
908 })";
909 }
910 
911 // A shader that fills with 100% opaque green.
Green()912 const char *Green()
913 {
914     return R"(#version 310 es
915 precision highp float;
916 out vec4 my_FragColor;
917 void main()
918 {
919     my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
920 })";
921 }
922 
923 // A shader that renders a simple gradient of red to green. Needs varying v_position.
RedGreenGradient()924 const char *RedGreenGradient()
925 {
926     return R"(#version 310 es
927 precision highp float;
928 in vec4 v_position;
929 out vec4 my_FragColor;
930 
931 void main()
932 {
933     my_FragColor = vec4(v_position.xy * 0.5 + vec2(0.5), 0.0, 1.0);
934 })";
935 }
936 
937 }  // namespace fs
938 }  // namespace essl31_shaders
939 }  // namespace angle
940