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