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