blob: 98653c01f16de0b4a8bdda3df46aa7450bf29291 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.7.1">
<meta name="author" content="Robert J. Simpson, Qualcomm (Editor), John Kessenich, Google (Editor), Dave Baldwin and Randi Rost (Version 1.1 Authors)">
<title>The OpenGL ES&#174; Shading Language, Version 3.20.6</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Uncomment @import statement below to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
*:not(pre)>code.nobreak{word-wrap:normal}
*:not(pre)>code.nowrap{white-space:nowrap}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote::before{display:none}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{word-spacing:0;line-height:1.6}
.quoteblock.abstract blockquote::before,.quoteblock.abstract p::before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot,table.frame-ends{border-width:1px 0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
/*pre.CodeRay {background-color:#f7f7f8;}*/
.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
table.CodeRay td{vertical-align: top;line-height:1.45}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
table.CodeRay td.code{padding:0 0 0 .5em}
table.CodeRay td.code>pre{padding:0}
.CodeRay .debug{color:#fff !important;background:#000080 !important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:#000080}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:#008080}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:#008080}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:#008080}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
<link rel="stylesheet" href="../katex/katex.min.css">
<script src="../katex/katex.min.js"></script>
<script src="../katex/contrib/auto-render.min.js"></script>
<!-- Use KaTeX to render math once document is loaded, see
https://github.com/Khan/KaTeX/tree/master/contrib/auto-render -->
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(
document.body,
{
delimiters: [
{ left: "$$", right: "$$", display: true},
{ left: "\\[", right: "\\]", display: true},
{ left: "$", right: "$", display: false},
{ left: "\\(", right: "\\)", display: false}
]
}
);
});
</script></head>
<body class="book toc2 toc-left" style="max-width: 100;">
<div id="header">
<h1>The OpenGL ES<sup>&#174;</sup> Shading Language, Version 3.20.6</h1>
<div class="details">
<span id="author" class="author">Robert J. Simpson, Qualcomm (Editor), John Kessenich, Google (Editor), Dave Baldwin and Randi Rost (Version 1.1 Authors)</span><br>
<span id="revnumber">version 3.20.6,</span>
<span id="revdate">Wed, 10 Jul 2019 20:42:56 +0000</span>
<br><span id="revremark">Git branch information not available</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#introduction">1. Introduction</a>
<ul class="sectlevel2">
<li><a href="#changes">1.1. Changes</a></li>
<li><a href="#overview">1.2. Overview</a></li>
<li><a href="#error-handling">1.3. Error Handling</a></li>
<li><a href="#typographical-conventions">1.4. Typographical Conventions</a></li>
<li><a href="#compatibility">1.5. Compatibility</a></li>
</ul>
</li>
<li><a href="#overview-of-opengl-shading">2. Overview of Shading</a>
<ul class="sectlevel2">
<li><a href="#vertex-processor">2.1. Vertex Processor</a></li>
<li><a href="#tessellation-control-processor">2.2. Tessellation Control Processor</a></li>
<li><a href="#tessellation-evaluation-processor">2.3. Tessellation Evaluation Processor</a></li>
<li><a href="#geometry-processor">2.4. Geometry Processor</a></li>
<li><a href="#fragment-processor">2.5. Fragment Processor</a></li>
<li><a href="#compute-processor">2.6. Compute Processor</a></li>
</ul>
</li>
<li><a href="#basics">3. Basics</a>
<ul class="sectlevel2">
<li><a href="#character-set">3.1. Character Set</a></li>
<li><a href="#source-strings">3.2. Source Strings</a></li>
<li><a href="#version-declaration">3.3. Version Declaration</a></li>
<li><a href="#preprocessor">3.4. Preprocessor</a></li>
<li><a href="#comments">3.5. Comments</a></li>
<li><a href="#tokens">3.6. Tokens</a></li>
<li><a href="#keywords">3.7. Keywords</a></li>
<li><a href="#identifiers">3.8. Identifiers</a></li>
<li><a href="#definitions">3.9. Definitions</a></li>
<li><a href="#logical-phases-of-compilation">3.10. Logical Phases of Compilation</a></li>
</ul>
</li>
<li><a href="#variables-and-types">4. Variables and Types</a>
<ul class="sectlevel2">
<li><a href="#basic-types">4.1. Basic Types</a></li>
<li><a href="#scoping">4.2. Scoping</a></li>
<li><a href="#storage-qualifiers">4.3. Storage Qualifiers</a></li>
<li><a href="#layout-qualifiers">4.4. Layout Qualifiers</a></li>
<li><a href="#interpolation-qualifiers">4.5. Interpolation Qualifiers</a></li>
<li><a href="#parameter-qualifiers">4.6. Parameter Qualifiers</a></li>
<li><a href="#precision-and-precision-qualifiers">4.7. Precision and Precision Qualifiers</a></li>
<li><a href="#variance-and-the-invariant-qualifier">4.8. Variance and the Invariant Qualifier</a></li>
<li><a href="#the-precise-qualifier">4.9. The Precise Qualifier</a></li>
<li><a href="#memory-qualifiers">4.10. Memory Qualifiers</a></li>
<li><a href="#specialization-constant-qualifier">4.11. Specialization-Constant Qualifier</a></li>
<li><a href="#order-of-qualification">4.12. Order and Repetition of Qualification</a></li>
<li><a href="#empty-declarations">4.13. Empty Declarations</a></li>
</ul>
</li>
<li><a href="#operators-and-expressions">5. Operators and Expressions</a>
<ul class="sectlevel2">
<li><a href="#operators">5.1. Operators</a></li>
<li><a href="#array-operations">5.2. Array Operations</a></li>
<li><a href="#function-calls">5.3. Function Calls</a></li>
<li><a href="#constructors">5.4. Constructors</a></li>
<li><a href="#vector-components">5.5. Vector Components</a></li>
<li><a href="#matrix-components">5.6. Matrix Components</a></li>
<li><a href="#structure-and-array-operations">5.7. Structure and Array Operations</a></li>
<li><a href="#assignments">5.8. Assignments</a></li>
<li><a href="#expressions">5.9. Expressions</a></li>
<li><a href="#vector-and-matrix-operations">5.10. Vector and Matrix Operations</a></li>
<li><a href="#specialization-constant-operations">5.11. Specialization-Constant Operations</a></li>
<li><a href="#evaluation-of-expressions">5.12. Evaluation of Expressions</a></li>
</ul>
</li>
<li><a href="#statements-and-structure">6. Statements and Structure</a>
<ul class="sectlevel2">
<li><a href="#function-definitions">6.1. Function Definitions</a></li>
<li><a href="#selection">6.2. Selection</a></li>
<li><a href="#iteration">6.3. Iteration</a></li>
<li><a href="#jumps">6.4. Jumps</a></li>
</ul>
</li>
<li><a href="#built-in-variables">7. Built-In Variables</a>
<ul class="sectlevel2">
<li><a href="#built-in-language-variables">7.1. Built-In Language Variables</a></li>
<li><a href="#built-in-constants">7.2. Built-In Constants</a></li>
<li><a href="#built-in-uniform-state">7.3. Built-In Uniform State</a></li>
<li><a href="#redeclaring-built-in-blocks">7.4. Redeclaring Built-In Blocks</a></li>
</ul>
</li>
<li><a href="#built-in-functions">8. Built-In Functions</a>
<ul class="sectlevel2">
<li><a href="#angle-and-trigonometry-functions">8.1. Angle and Trigonometry Functions</a></li>
<li><a href="#exponential-functions">8.2. Exponential Functions</a></li>
<li><a href="#common-functions">8.3. Common Functions</a></li>
<li><a href="#floating-point-pack-and-unpack-functions">8.4. Floating-Point Pack and Unpack Functions</a></li>
<li><a href="#geometric-functions">8.5. Geometric Functions</a></li>
<li><a href="#matrix-functions">8.6. Matrix Functions</a></li>
<li><a href="#vector-relational-functions">8.7. Vector Relational Functions</a></li>
<li><a href="#integer-functions">8.8. Integer Functions</a></li>
<li><a href="#texture-functions">8.9. Texture Functions</a></li>
<li><a href="#atomic-counter-functions">8.10. Atomic Counter Functions</a></li>
<li><a href="#atomic-memory-functions">8.11. Atomic Memory Functions</a></li>
<li><a href="#image-functions">8.12. Image Functions</a></li>
<li><a href="#geometry-shader-functions">8.13. Geometry Shader Functions</a></li>
<li><a href="#fragment-processing-functions">8.14. Fragment Processing Functions</a></li>
<li><a href="#shader-invocation-control-functions">8.15. Shader Invocation Control Functions</a></li>
<li><a href="#shader-memory-control-functions">8.16. Shader Memory Control Functions</a></li>
<li><a href="#_subpass_input_functions">8.17. Subpass-Input Functions</a></li>
</ul>
</li>
<li><a href="#shader-interface-matching">9. Shader Interface Matching</a>
<ul class="sectlevel2">
<li><a href="#input-output-matching-by-name-in-linked-programs">9.1. Input Output Matching by Name in Linked Programs</a></li>
<li><a href="#matching-of-qualifiers">9.2. Matching of Qualifiers</a></li>
</ul>
</li>
<li><a href="#shading-language-grammar">10. Shading Language Grammar</a></li>
<li><a href="#counting-of-inputs-and-outputs">11. Counting of Inputs and Outputs</a></li>
<li><a href="#acknowledgments">12. Acknowledgments</a></li>
<li><a href="#references">13. Normative References</a></li>
<li><a href="#_non_normative_spir_v_mappings">14. Non-Normative SPIR-V Mappings</a>
<ul class="sectlevel2">
<li><a href="#_feature_comparisons">14.1. Feature Comparisons</a></li>
<li><a href="#_mapping_from_glsl_to_spir_v">14.2. Mapping from GLSL to SPIR-V</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div style="page-break-after: always;"></div>
<div class="paragraph">
<p>Copyright &#169; 2008-2018 The Khronos Group Inc. All Rights Reserved.</p>
</div>
<div class="paragraph">
<p>This specification is protected by copyright laws and contains material
proprietary to the Khronos Group, Inc. It or any components may not be
reproduced, republished, distributed, transmitted, displayed, broadcast,
or otherwise exploited in any manner without the express prior written
permission of Khronos Group. You may use this specification for
implementing the functionality therein, without altering or removing any
trademark, copyright or other notice from the specification, but the
receipt or possession of this specification does not convey any rights
to reproduce, disclose, or distribute its contents, or to manufacture,
use, or sell anything that it may describe, in whole or in part.</p>
</div>
<div class="paragraph">
<p>Khronos Group grants express permission to any current Promoter,
Contributor or Adopter member of Khronos to copy and redistribute
UNMODIFIED versions of this specification in any fashion, provided that
NO CHARGE is made for the specification and the latest available update
of the specification for any version of the API is used whenever
possible. Such distributed specification may be reformatted AS LONG AS
the contents of the specification are not changed in any way. The
specification may be incorporated into a product that is sold as long as
such product includes significant independent work developed by the
seller. A link to the current version of this specification on the
Khronos Group website should be included whenever possible with
specification distributions.</p>
</div>
<div class="paragraph">
<p>Khronos Group makes no, and expressly disclaims any, representations or
warranties, express or implied, regarding this specification, including,
without limitation, any implied warranties of merchantability or fitness
for a particular purpose or noninfringement of any intellectual
property. Khronos Group makes no, and expressly disclaims any,
warranties, express or implied, regarding the correctness, accuracy,
completeness, timeliness, and reliability of the specification. Under no
circumstances will the Khronos Group, or any of its Promoters,
Contributors or Members or their respective partners, officers,
directors, employees, agents, or representatives be liable for any
damages, whether direct, indirect, special or consequential damages for
lost revenues, lost profits, or otherwise, arising from or in connection
with these materials.</p>
</div>
<div class="paragraph">
<p>Khronos, Vulkan, SYCL, SPIR, WebGL, EGL, COLLADA, StreamInput, OpenVX,
OpenKCam, glTF, OpenKODE, OpenVG, OpenWF, OpenSL ES, OpenMAX, OpenMAX
AL, OpenMAX IL and OpenMAX DL are trademarks and WebCL is a
certification mark of the Khronos Group Inc. OpenCL is a trademark of
Apple Inc. and OpenGL and OpenML are registered trademarks and the
OpenGL ES and OpenGL SC logos are trademarks of Silicon Graphics
International used under license by Khronos. All other product names,
trademarks, and/or company names are used solely for identification and
belong to their respective owners.</p>
</div>
<div style="page-break-after: always;"></div>
<!-- toc disabled -->
</div>
</div>
<div class="sect1">
<h2 id="introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This document specifies only version 3.20 of the OpenGL ES Shading Language (GLSL ES).
It requires __VERSION__ to substitute 320, and requires
<strong>#version</strong> to accept only
<code>320 es</code>.
If <strong>#version</strong> is declared with a smaller number, the language accepted is a
previous version of the shading language, which will be supported depending
on the version and type of context in the API.
See the <a href="#references">normative references</a> for details on what language
versions are supported.</p>
</div>
<div class="paragraph">
<p>Throughout, when generating SPIR-V for consumption by the Vulkan API
(see <a href="#references">normative references</a>), this will be said to be
<em>targeting Vulkan</em>.</p>
</div>
<div class="paragraph">
<p>While this specification and the OpenGL ES Specification are normative for OpenGL ES Shading Language, for
SPIR-V generation it is still the SPIR-V specification and the SPIR-V client
API specification that are normative for the generated SPIR-V.
See the <a href="#references">normative references</a> for further detail.</p>
</div>
<div class="paragraph">
<p>For SPIR-V generation, the SPIR-V client API specifies the commands used to
manipulate SPIR-V shaders.</p>
</div>
<div class="paragraph">
<p>Independent offline tool chains will compile GLSL ES down to the SPIR-V
intermediate language.
SPIR-V generation is not enabled with a <strong>#extension</strong>, <strong>#version</strong>, or a
profile.
Instead, use of GLSL ES for SPIR-V is determined by offline tool-chain use.
See the documentation of such tools to see how to request generation of
SPIR-V for its client API.</p>
</div>
<div class="paragraph">
<p>GLSL ES &#8594; SPIR-V compilers must be directed as to what SPIR-V <strong>Capabilities</strong>
are legal at run-time and give errors for GLSL ES feature use outside those
capabilities.
This is also true for implementation-dependent limits that can be error
checked by the front-end against built-in constants present in the GLSL ES
source: the front-end can be informed of such limits, and report errors when
they are exceeded.</p>
</div>
<div class="paragraph">
<p>All references in this specification to the <a href="#references">OpenGL ES Specification</a> are to
version 3.2.</p>
</div>
<div class="sect2">
<h3 id="changes">1.1. Changes</h3>
<div class="sect3">
<h4 id="_changes_from_glsl_es_3_2_revision_5">1.1.1. Changes from GLSL ES 3.2 revision 5</h4>
<div class="ulist">
<ul>
<li>
<p>Incorporated the GL_KHR_vulkan_glsl specification.</p>
</li>
<li>
<p>Clarify it is same location that triggers default-uniform block matching
rules.
See <a href="#uniform-variable-layout-qualifiers">Uniform Variable Layout Qualifiers</a>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-from-glsl-es-3.2-revision-4">1.1.2. Changes from GLSL ES 3.2 revision 4</h4>
<div class="ulist">
<ul>
<li>
<p>Clarified that this specification completely defines the OpenGL ES Shading Language.
Normatively reference C++ only for the preprocessor.</p>
</li>
<li>
<p>Private GLSL issues 7, 38: Corrected the values of some builtin constants.
The values were given correctly in the OpenGL ES Specification.</p>
</li>
<li>
<p>Private GLSL issue 30: Clarify that output packing rules apply to the last
vertex pipeline stage, not necessarily the vertex stage.</p>
</li>
<li>
<p>Private GLSL issue 15: Clarify the ordering of bindings for arrays of arrays.</p>
</li>
<li>
<p>Private GLSL issue 14: Uniform variables need only match at link time if they
are statically used.</p>
</li>
<li>
<p>For <strong>precise</strong> computations, the controlling expressions for
control flow and ternary operators (<strong>?:</strong>) are not included.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-from-glsl-es-3.2-revision-3">1.1.3. Changes from GLSL ES 3.2 revision 3</h4>
<div class="ulist">
<ul>
<li>
<p>Matching of default uniforms when shaders are linked.</p>
</li>
<li>
<p><em>gl_DepthRange</em> is only guaranteed to be available in the fragment
stage.</p>
</li>
<li>
<p>Clarification of definition of static use.</p>
</li>
<li>
<p>Sampling behavior in the absence of <strong>sample</strong> and <strong>centroid</strong>.</p>
</li>
<li>
<p>Clarified the requirements when the specification uses the terms
<em>should</em>/<em>should not</em> and <em>undefined behavior</em>.</p>
</li>
<li>
<p>Arrayed blocks cannot have layout location qualifiers on members</p>
</li>
<li>
<p><strong>barrier</strong>() defines a partial order which includes tessellation control
shader outputs.</p>
</li>
<li>
<p>Vertex shader integer output qualification.</p>
</li>
<li>
<p>Incorrect use of predefined pragmas.</p>
</li>
<li>
<p>Clarified use of <strong>readonly</strong> and <strong>writeonly</strong> qualifiers.</p>
</li>
<li>
<p>USAMPLERBUFFER added to grammar.</p>
</li>
<li>
<p>Clarified precision qualifiers can be used in interface blocks.</p>
</li>
<li>
<p>Clarified <strong>memoryBarrierShared</strong> only applies to the current workgroup.</p>
</li>
<li>
<p>The layout qualifier <em>invocations</em> must not be zero.</p>
</li>
<li>
<p>The layout qualifier <em>local_size</em> must not be zero.</p>
</li>
<li>
<p>Clarified the definition of static assignment.</p>
</li>
<li>
<p>Removed list of types with no default precision.</p>
</li>
<li>
<p>Removed scoping rules from the grammar. Refer instead to the <a href="#scoping">scoping</a> section.</p>
</li>
<li>
<p>Require a statement after the final label of a switch.</p>
</li>
<li>
<p>Define <strong>gl_BoundingBox</strong>.</p>
</li>
<li>
<p><strong>length</strong>() expressions returning a constant-value may not include side effects.</p>
</li>
<li>
<p>Clarified that variables may be declared <strong>readonly writeonly</strong>.</p>
</li>
<li>
<p>Use of constant expressions within <strong>#line</strong> directives is undefined.</p>
</li>
<li>
<p><strong>gl_in</strong> can be redeclared using unsized-array syntax.</p>
</li>
<li>
<p>Clarified which sampler types may be used for depth and stencil textures.</p>
</li>
<li>
<p>Added order-of-operation and other explanations to the
<a href="#the-precise-qualifier">Precise Qualifier</a> section.</p>
</li>
<li>
<p>The <strong>precise</strong> qualifier applied to a block/struct applies recursively to the members.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-from-glsl-es-3.2-revision-2">1.1.4. Changes from GLSL ES 3.2 revision 2</h4>
<div class="ulist">
<ul>
<li>
<p>Updated value for <em>gl_MaxTessControlTotalOutputComponents</em></p>
</li>
<li>
<p>Clarified the allowed character set for pre-processing</p>
</li>
<li>
<p>Integer division wrapping behavior</p>
</li>
<li>
<p>Clarified pre-processor expressions (<em>pp-constant-expression</em>)</p>
</li>
<li>
<p>UBO and SSBO precisions do not need to match for linked shaders
(consistent with GLSL ES 3.1)</p>
</li>
<li>
<p><strong>modf</strong> function</p>
</li>
<li>
<p>Sequence and ternary operators with <strong>void</strong> type</p>
</li>
<li>
<p>Sequence and ternary operators with array types</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-from-glsl-es-3.2-revision-1">1.1.5. Changes from GLSL ES 3.2 revision 1</h4>
<div class="ulist">
<ul>
<li>
<p>Signed zeros must be supported</p>
</li>
<li>
<p>Layout qualifier table</p>
</li>
<li>
<p>Allowed optimizations when evaluating expressions</p>
</li>
<li>
<p>Updated value for <em>gl_MaxTessControlInputComponents</em></p>
</li>
<li>
<p>Updated value for <em>gl_MaxTessControlOutputComponents</em></p>
</li>
<li>
<p>Updated value for <em>gl_MaxTessEvaluationInputComponents</em></p>
</li>
<li>
<p>Updated value for <em>gl_MaxTessEvaluationOutputComponents</em></p>
</li>
<li>
<p>Updated value for <em>gl_MaxGeometryOutputComponents</em></p>
</li>
<li>
<p>Require precisions in blocks to match when linking</p>
</li>
<li>
<p>Updated conclusions in issues section</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-from-glsl-es-3.1-revision-4">1.1.6. Changes from GLSL ES 3.1 revision 4</h4>
<div class="ulist">
<ul>
<li>
<p>Added the following extensions:</p>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.opengl.org/registry/specs/KHR/blend_equation_advanced.txt">KHR_blend_equation_advanced</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_sample_variables.txt">OES_sample_variables</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_shader_image_atomic.txt">OES_shader_image_atomic</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_shader_multisample_interpolation.txt">OES_shader_multisample_interpolation</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_texture_storage_multisample_2d_array.txt">OES_texture_storage_multisample_2d_array</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_geometry_shader.txt">OES_geometry_shader</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_gpu_shader5.txt">OES_gpu_shader5</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_primitive_bounding_box.txt">OES_primitive_bounding_box</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_shader_io_blocks.txt">OES_shader_io_blocks</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_tessellation_shader.txt">OES_tessellation_shader</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_texture_buffer.txt">OES_texture_buffer</a></p>
</li>
<li>
<p><a href="https://www.khronos.org/registry/gles/extensions/OES/OES_texture_cube_map_array.txt">OES_texture_cube_map_array</a></p>
</li>
<li>
<p><a href="https://www.opengl.org/registry/specs/KHR/robustness.txt">KHR_robustness</a></p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="overview">1.2. Overview</h3>
<div class="paragraph">
<p>This document describes <em>The OpenGL ES Shading Language, version 3.20</em>.</p>
</div>
<div class="paragraph">
<p>Independent compilation units written in this language are called <em>shaders</em>.
A <em>program</em> is a set of shaders that are compiled and linked
together.
The aim of this document is to thoroughly specify the programming language.
The <a href="#references">normative references</a> will specify the API entry points
used to manipulate and communicate with programs and shaders.</p>
</div>
</div>
<div class="sect2">
<h3 id="error-handling">1.3. Error Handling</h3>
<div class="paragraph">
<p>Compilers, in general, accept programs that are ill-formed, due to the
impossibility of detecting all ill-formed programs.
Portability is only ensured for well-formed programs, which this
specification describes.
Compilers are encouraged to detect ill-formed programs and issue diagnostic
messages, but are not required to do so for all cases.</p>
</div>
<div class="paragraph">
<p>The compilation process is implementation-dependent but is generally split
into a number of stages, each of which occurs at one of the following times:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A call to <em>glCompileShader</em></p>
</li>
<li>
<p>A call to <em>glLinkProgram</em></p>
</li>
<li>
<p>A draw call or a call to <em>glValidateProgram</em></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The implementation should report errors as early a possible but in any case
must satisfy the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>All lexical, grammatical and semantic errors must have been detected
following a call to <em>glLinkProgram</em></p>
</li>
<li>
<p>Errors due to mismatch between the shaders (link-time errors) must have
been detected following a call to <em>glLinkProgram</em></p>
</li>
<li>
<p>Errors due to exceeding resource limits must have been detected
following any draw call or a call to <em>glValidateProgram</em></p>
</li>
<li>
<p>A call to <em>glValidateProgram</em> must report all errors associated with a
program object given the current GL state.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Where the specification uses the terms <em>required</em>, <em>must</em>/<em>must</em> <em>not</em>,
<em>does</em>/<em>does</em> <em>not</em>, <em>disallowed</em>, or <em>not</em> <em>supported</em>, the compiler or
linker is required to detect and report any violations.
Similarly when a condition or situation is an <strong>error</strong>, it must be reported.
Use of any feature marked as <em>reserved</em> is an error.
Where the specification uses the terms <em>should</em>/<em>should</em> <em>not</em>, <em>undefined</em>
<em>behavior</em>, <em>undefined</em> <em>value</em> or <em>undefined</em> <em>*results*</em>, implementations
will not produce a compile-time error but are encouraged to issue a warning
for violations.
The run-time behavior of the program in these cases is not constrained (and
so may include termination or system instability).
It is expected that systems will be designed to handle these cases
gracefully but specification of this is outside the scope of this
specification.</p>
</div>
<div class="paragraph">
<p>Implementations may not in general support functionality beyond the mandated
parts of the specification without use of the relevant extension.
The only exceptions are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If a feature is marked as optional.</p>
</li>
<li>
<p>Where a maximum value is stated (e.g. the maximum number of vertex
outputs), the implementation may support a higher value than that
specified.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Where the implementation supports more than the mandated specification,
off-target compilers are encouraged to issue warnings if these features are
used.</p>
</div>
<div class="paragraph">
<p>The compilation process is split between the compiler and linker.
The allocation of tasks between the compiler and linker is implementation
dependent.
Consequently there are many errors which may be detected either at compile
or link time, depending on the implementation.</p>
</div>
</div>
<div class="sect2">
<h3 id="typographical-conventions">1.4. Typographical Conventions</h3>
<div class="paragraph">
<p>Italic, bold, and font choices have been used in this specification
primarily to improve readability.
Code fragments use a fixed width font.
Identifiers embedded in text are italicized.
Keywords embedded in text are bold.
Operators are called by their name, followed by their symbol in bold in
parentheses.
The clarifying grammar fragments in the text use bold for literals and
italics for non-terminals.
The official grammar in &#8220;<a href="#shading-language-grammar">Shading Language
Grammar</a>&#8221; uses all capitals for terminals and lower case for
non-terminals.</p>
</div>
</div>
<div class="sect2">
<h3 id="compatibility">1.5. Compatibility</h3>
<div class="paragraph">
<p>The OpenGL ES 3.2 API is designed to work with GLSL ES v1.00,
GLSL ES 3.00, GLSL ES 3.10 and GLSL ES 3.20.
In general a shader written for versions prior to OpenGL ES 3.2
should work without modification in OpenGL ES 3.2.</p>
</div>
<div class="paragraph">
<p>When porting applications from an earlier to later version of the GLSL ES,
the following points should be noted:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Not all language constructs present in earlier versions of the language
are available in later versions e.g. attribute and varying qualifiers
are present in v1.00 but not v3.00.
However, the functionality of GLSL ES 3.20 is a super-set of
GLSL ES 3.10.</p>
</li>
<li>
<p>Some features of later versions of the API require language features
that are not present in earlier version of the language.</p>
</li>
<li>
<p>It is an error to link shaders if they are written in different versions
of the language.</p>
</li>
<li>
<p>The OpenGL ES 2.0 and 3.0 APIs do not support shaders written in GLSL ES
3.20.</p>
</li>
<li>
<p>Using GLSL ES 1.00 shaders within OpenGL ES 3.x may extend the resources
available beyond the minima specified in GLSL ES 1.0.
Shaders which make use of this will not necessarily run on an OpenGL ES
2.0 implementation: Similarly for GLSL ES 3.00 shaders running within
OpenGL ES 3.2.</p>
</li>
<li>
<p>Support of line continuation and support of UTF-8 characters within
comments is optional in GLSL ES 1.00 when used with the OpenGL ES 2.0
API.
However, support is mandated for both of these when a GLSL ES 1.00
shader is used with the OpenGL ES 3.x APIs.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="overview-of-opengl-shading">2. Overview of Shading</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The OpenGL ES Shading Language is actually several closely related languages.
These languages are used to create shaders for each of the programmable
processors contained in the API&#8217;s processing pipeline.
Currently, these processors are the vertex, tessellation control,
tessellation evaluation, geometry, fragment, and compute processors.</p>
</div>
<div class="paragraph">
<p>Compilation units for these processors are referred to as <em>shaders</em> and the
processors themselves are also referred to as <em>shader stages</em>.
Only one shader can be run on a processor at any one time; there is no
support for linking multiple compilation units together for a single shader
stage.
One or more shaders are linked together to form a single program and each
program contains shader <em>executables</em> for one or more consecutive shader
stages.</p>
</div>
<div class="paragraph">
<p>Unless otherwise noted in this paper, a language feature applies to all
languages, and common usage will refer to these languages as a single
language.
The specific languages will be referred to by the name of the processor they
target: vertex, tessellation control, tessellation evaluation, geometry,
fragment, or compute.</p>
</div>
<div class="paragraph">
<p>Most API state is not tracked or made available to shaders.
Typically, user-defined variables will be used for communicating between
different stages of the API pipeline.
However, a small amount of state is still tracked and automatically made
available to shaders, and there are a few built-in variables for interfaces
between different stages of the API pipeline.</p>
</div>
<div class="sect2">
<h3 id="vertex-processor">2.1. Vertex Processor</h3>
<div class="paragraph">
<p>The <em>vertex processor</em> is a programmable unit that operates on incoming
vertices and their associated data.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
<em>vertex shaders</em>.</p>
</div>
<div class="paragraph">
<p>The vertex processor operates on one vertex at a time.
It does not replace graphics operations that require knowledge of several
vertices at a time.</p>
</div>
</div>
<div class="sect2">
<h3 id="tessellation-control-processor">2.2. Tessellation Control Processor</h3>
<div class="paragraph">
<p>The <em>tessellation control processor</em> is a programmable unit that operates on
a patch of incoming vertices and their associated data, emitting a new
output patch.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
tessellation control shaders.</p>
</div>
<div class="paragraph">
<p>The tessellation control shader is invoked for each vertex of the output
patch.
Each invocation can read the attributes of any vertex in the input or output
patches, but can only write per-vertex attributes for the corresponding
output patch vertex.
The shader invocations collectively produce a set of per-patch attributes
for the output patch.</p>
</div>
<div class="paragraph">
<p>After all tessellation control shader invocations have completed, the output
vertices and per-patch attributes are assembled to form a patch to be used
by subsequent pipeline stages.</p>
</div>
<div class="paragraph">
<p>Tessellation control shader invocations run mostly independently, with
undefined relative execution order.
However, the built-in function <strong>barrier</strong>() can be used to control execution
order by synchronizing invocations, effectively dividing tessellation
control shader execution into a set of phases.
Tessellation control shaders will get undefined results if one invocation
reads from a per-vertex or per-patch attribute written by another invocation
at any point during the same phase, or if two invocations attempt to write
different values to the same per-patch output
in a single phase.</p>
</div>
</div>
<div class="sect2">
<h3 id="tessellation-evaluation-processor">2.3. Tessellation Evaluation Processor</h3>
<div class="paragraph">
<p>The <em>tessellation evaluation processor</em> is a programmable unit that
evaluates the position and other attributes of a vertex generated by the
tessellation primitive generator, using a patch of incoming vertices and
their associated data.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
tessellation evaluation shaders.</p>
</div>
<div class="paragraph">
<p>Each invocation of the tessellation evaluation executable computes the
position and attributes of a single vertex generated by the tessellation
primitive generator.
The executable can read the attributes of any vertex in the input patch,
plus the tessellation coordinate, which is the relative location of the
vertex in the primitive being tessellated.
The executable writes the position and other attributes of the vertex.</p>
</div>
</div>
<div class="sect2">
<h3 id="geometry-processor">2.4. Geometry Processor</h3>
<div class="paragraph">
<p>The <em>geometry processor</em> is a programmable unit that operates on data for
incoming vertices for a primitive assembled after vertex processing and
outputs a sequence of vertices forming output primitives.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
<em>geometry shaders</em>.</p>
</div>
<div class="paragraph">
<p>A single invocation of the geometry shader executable on the geometry
processor will operate on a declared input primitive with a fixed number of
vertices.
This single invocation can emit a variable number of vertices that are
assembled into primitives of a declared output primitive type and passed to
subsequent pipeline stages.</p>
</div>
</div>
<div class="sect2">
<h3 id="fragment-processor">2.5. Fragment Processor</h3>
<div class="paragraph">
<p>The <em>fragment processor</em> is a programmable unit that operates on fragment
values and their associated data.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
<em>fragment shaders</em>.</p>
</div>
<div class="paragraph">
<p>A fragment shader cannot change a fragment&#8217;s (<em>x</em>, <em>y</em>) position.
Access to neighboring fragments is not allowed.
The values computed by the fragment shader are ultimately used to update
framebuffer memory or texture memory, depending on the current API
state and the API command that caused the fragments to be generated.</p>
</div>
</div>
<div class="sect2">
<h3 id="compute-processor">2.6. Compute Processor</h3>
<div class="paragraph">
<p>The <em>compute processor</em> is a programmable unit that operates independently
from the other shader processors.
Compilation units written in the OpenGL ES Shading Language to run on this processor are called
<em>compute shaders</em>.</p>
</div>
<div class="paragraph">
<p>A compute shader has access to many of the same resources as fragment and
other shader processors, such as textures, buffers, image variables, and
atomic counters.
It does not have fixed-function outputs.
It is not part of the graphics pipeline and its visible side effects are
through changes to images, storage buffers, and atomic counters.</p>
</div>
<div class="paragraph">
<p>A compute shader operates on a group of work items called a <em>workgroup</em>.
A workgroup is a collection of shader invocations that execute the same
code, potentially in parallel.
An invocation within a workgroup may share data with other members of the
same workgroup through shared variables and issue memory and control flow
barriers to synchronize with other members of the same workgroup.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="basics">3. Basics</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="character-set">3.1. Character Set</h3>
<div class="paragraph">
<p>The source character set used for the OpenGL ES Shading Language is Unicode in the UTF-8
encoding scheme.
Invalid UTF-8 characters are ignored.
During pre-processing, the following applies:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A byte with the value zero is always interpreted as the end of the
string</p>
</li>
<li>
<p>Backslash ('\'), is used to indicate line continuation when immediately
preceding a new-line.</p>
</li>
<li>
<p>White space consists of one or more of the following characters: the
space character, horizontal tab, vertical tab, form feed,
carriage-return, line-feed.</p>
</li>
<li>
<p>The number sign (<strong>#</strong>) is used for preprocessor directives</p>
</li>
<li>
<p>Macro names are restricted to:</p>
<div class="ulist">
<ul>
<li>
<p>The letters <strong>a-z</strong>, <strong>A-Z</strong>, and the underscore (<strong>_</strong>).</p>
</li>
<li>
<p>The numbers <strong>0-9</strong>, except for the first character of a macro name.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>After preprocessing, only the following characters are allowed in the
resulting stream of GLSL ES tokens:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The letters <strong>a-z</strong>, <strong>A-Z</strong>, and the underscore (<strong>_</strong>).</p>
</li>
<li>
<p>The numbers <strong>0-9</strong>.</p>
</li>
<li>
<p>The symbols period (<strong>.</strong>), plus (<strong>+</strong>), dash (<strong>-</strong>), slash (<strong>/</strong>), asterisk
(<strong>*</strong>), percent (<strong>%</strong>), angled brackets (<strong>&lt;</strong> and <strong>&gt;</strong>), square brackets
(<strong>[</strong> and <strong>]</strong>), parentheses (<strong>(</strong> and <strong>)</strong>), braces (<strong>{</strong> and <strong>}</strong>), caret
(<strong>^</strong>), vertical bar (<strong>|</strong>), ampersand (<strong>&amp;</strong>), tilde (<strong>~</strong>), equals (<strong>=</strong>),
exclamation point (<strong>!</strong>), colon (<strong>:</strong>), semicolon (<strong>;</strong>), comma (<strong>,</strong>), and
question mark (<strong>?</strong>).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>There are no digraphs or trigraphs.
There are no escape sequences or other uses of the backslash beyond use as
the line-continuation character.</p>
</div>
<div class="paragraph">
<p>Lines are relevant for compiler diagnostic messages and the preprocessor.
They are terminated by carriage-return or line-feed.
If both are used together, it will count as only a single line termination.
For the remainder of this document, any of these combinations is simply
referred to as a new-line.
Lines may be of arbitrary length.</p>
</div>
<div class="paragraph">
<p>In general, the language&#8217;s use of this character set is case sensitive.</p>
</div>
<div class="paragraph">
<p>There are no character or string data types, so no quoting characters are
included.</p>
</div>
<div class="paragraph">
<p>There is no end-of-file character.</p>
</div>
</div>
<div class="sect2">
<h3 id="source-strings">3.2. Source Strings</h3>
<div class="paragraph">
<p>The source for a single shader is an array of strings of characters from the
character set.
A single shader is made from the concatenation of these strings.
Each string can contain multiple lines, separated by new-lines.
No new-lines need be present in a string; a single line can be formed from
multiple strings.
No new-lines or other characters are inserted by the implementation when it
concatenates the strings to form a single shader.</p>
</div>
<div class="paragraph">
<p>Diagnostic messages returned from compiling a shader must identify both the
line number within a string and which source string the message applies to.
Source strings are counted sequentially with the first string being string
0.
Line numbers are one more than the number of new-lines that have been
processed, including counting the new-lines that will be removed by the
line-continuation character (<strong>\</strong>).</p>
</div>
<div class="paragraph">
<p>Lines separated by the line-continuation character preceding a new-line are
concatenated together before either comment processing or preprocessing.
This means that no white space is substituted for the line-continuation
character.
That is, a single token could be formed by the concatenation by taking the
characters at the end of one line concatenating them with the characters at
the beginning of the next line.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> f\
oo;
<span class="comment">// forms a single line equivalent to &quot;float foo;&quot;</span>
<span class="comment">// (assuming '\' is the last character before the new-line and &quot;oo&quot; are</span>
<span class="comment">// the first two characters of the next line)</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="version-declaration">3.3. Version Declaration</h3>
<div class="paragraph">
<p>Shaders must declare the version of the language they are written to.
The version is specified in the first line of a shader by a character
string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#version</span> number es</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <em>number</em> must be a version of the language, following the same
convention as __VERSION__ above.
The directive &#8220;<strong>#version 320 es</strong>&#8221; is required in any shader that
uses version 3.20 of the language.
Any <em>number</em> representing a version of the language a compiler does not
support will cause an error to be generated.
Version 1.00 of the language does not require shaders to include this
directive, and shaders that do not include a <strong>#version</strong> directive will be
treated as targeting version 1.00.</p>
</div>
<div class="paragraph">
<p>Shaders declaring version 3.20 of the shading language cannot be
linked with shaders declaring a previous version.</p>
</div>
<div class="paragraph">
<p>The <strong>#version</strong> directive must be present in the first line of a shader and
must be followed by a newline.
It may contain optional white-space as specified below but no other
characters are allowed.
The directive is only permitted in the first line of a shader.</p>
</div>
<div class="paragraph">
<p>Processing of the #version directive occurs before all other preprocessing,
including line concatenation and comment processing.</p>
</div>
<div class="openblock bnf">
<div class="content">
<div class="dlist">
<dl>
<dt class="hdlist1"><em>version-declaration</em> : </dt>
<dd>
<p><em>whitespace<sub>opt</sub></em> POUND <em>whitespace<sub>opt</sub></em> VERSION <em>whitespace</em> <em>number</em>
<em>whitespace</em> ES <em>whitespace<sub>opt</sub></em></p>
</dd>
</dl>
</div>
</div>
</div>
<div class="paragraph">
<p>Tokens:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>POUND <strong>#</strong><br>
VERSION <strong>version</strong><br>
ES <strong>es</strong></p>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="preprocessor">3.4. Preprocessor</h3>
<div class="paragraph">
<p>There is a preprocessor that processes the source strings as part of the
compilation process.
Except as noted below, it behaves as the C++ standard preprocessor (see
&#8220;<a href="#references">Normative References</a>&#8221;).</p>
</div>
<div class="paragraph">
<p>The complete list of preprocessor directives is as follows.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>#<br>
#define<br>
#undef<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#if<br>
#ifdef<br>
#ifndef<br>
#else<br>
#elif<br>
#endif<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#error<br>
#pragma<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#extension<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#line</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The following
operator is
also available:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>defined<br></p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Note that the version directive is not considered to be a preprocessor
directive and so is not listed here.</p>
</div>
<div class="paragraph">
<p>Each number sign (<strong>#</strong>) can be preceded in its line only by spaces or
horizontal tabs.
It may also be followed by spaces and horizontal tabs, preceding the
directive.
Each directive is terminated by a new-line.
Preprocessing does not change the number or relative location of new-lines
in a source string.</p>
</div>
<div class="paragraph">
<p>The number sign (<strong>#</strong>) on a line by itself is ignored.
Any directive not listed above will cause an error.</p>
</div>
<div class="paragraph">
<p><strong>#define</strong> and <strong>#undef</strong> functionality are defined as is standard for C++
preprocessors for macro definitions both with and without macro parameters.</p>
</div>
<div class="paragraph">
<p>The following predefined macros are available:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>__LINE__<br>
__FILE__<br>
__VERSION__<br>
GL_ES</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>__LINE__ will substitute a decimal integer constant that is one more than
the number of preceding new-lines in the current source string.</p>
</div>
<div class="paragraph">
<p>__FILE__ will substitute a decimal integer constant that says which source
string number is currently being processed.</p>
</div>
<div class="paragraph">
<p>__VERSION__ will substitute a decimal integer reflecting the version
number of the OpenGL ES Shading Language.
The version of the shading language described in this document will have
__VERSION__ substitute the decimal integer 320.</p>
</div>
<div class="paragraph">
<p>GL_ES will be defined and set to 1.
This is not true for the non-ES OpenGL Shading Language, so it can be used
to do a compile time test to determine if a shader is compiling as an
GLSL ES shader.</p>
</div>
<div class="paragraph">
<p>By convention, all macro names containing two consecutive underscores (__)
are reserved for use by underlying software layers.
Defining
such a name in a shader does not itself result in an error, but may
result in unintended behaviors that stem from having multiple definitions of
the same name.
All macro names prefixed with &#8220;GL_&#8221; (&#8220;GL&#8221; followed by a single
underscore) are also reserved, and defining
such a name results in a compile-time error.</p>
</div>
<div class="paragraph">
<p>It is an error to undefine or to redefine a built-in (pre-defined) macro
name.</p>
</div>
<div class="paragraph">
<p>Implementations must support macro-name lengths of up to 1024 characters.
It is an error to declare a name with a length greater than this.</p>
</div>
<div class="paragraph">
<p><strong>#if</strong>, <strong>#ifdef</strong>, <strong>#ifndef</strong>, <strong>#else</strong>, <strong>#elif</strong>, and <strong>#endif</strong> are defined to
operate as is standard for C++ preprocessors except for the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Expressions following <strong>#if</strong> and <strong>#elif</strong> are
restricted to <em>pp-constant-expressions</em> as defined below.</p>
</li>
<li>
<p>Undefined identifiers not consumed by the <strong>defined</strong> operator do not
default to '0'.
Use of such identifiers causes an error.</p>
</li>
<li>
<p>Character constants are not supported.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As in C++, a macro name defined with an empty replacement list does not
default to '0' when used in a preprocessor expression.</p>
</div>
<div class="paragraph">
<p>A <em>pp-constant-expression</em> is an integral expression, evaluated at
compile-time during preprocessing and formed from literal integer constants
and the following operators:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Precedence</th>
<th class="tableblock halign-left valign-top">Operator class</th>
<th class="tableblock halign-left valign-top">Operators</th>
<th class="tableblock halign-left valign-top">Associativity</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1 (highest)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">parenthetical grouping</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">( )</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NA</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">unary</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">defined<br>
+ - ~ !</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Right to Left</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">multiplicative</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">* / %</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">additive</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">+ -</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise shift</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;&lt; &gt;&gt;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">relational</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; &gt; &lt;= &gt;=</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">equality</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">== !=</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise and</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&amp;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise exclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">^</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise inclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">|</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">logical and</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&amp;&amp;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">12 (lowest)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">logical inclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">||</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The <strong>defined</strong> operator can be used in either of the following ways:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++">defined identifier
defined ( identifier )</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are no number sign based operators (e.g. no <strong><mark></strong> or <strong></mark>@</strong>), no <strong>##</strong>
operator, nor is there a <strong>sizeof</strong> operator.</p>
</div>
<div class="paragraph">
<p>The semantics of applying operators in the preprocessor match those standard
in the C++ preprocessor with the following exceptions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The 2<sup>nd</sup> operand in a logical and ('&amp;&amp;') operation is evaluated if and
only if the 1<sup>st</sup> operand evaluates to non-zero.</p>
</li>
<li>
<p>The 2<sup>nd</sup> operand in a logical or ('||') operation is evaluated if and
only if the 1<sup>st</sup> operand evaluates to zero.</p>
</li>
<li>
<p>There is no boolean type and no boolean literals.
A <em>true</em> or <em>false</em> result is returned as integer <em>one</em> or <em>zero</em>
respectively.
Wherever a boolean operand is expected, any non-zero integer is
interpreted as <em>true</em> and a zero integer as <em>false</em>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If an operand is not evaluated, the presence of undefined identifiers in the
operand will not cause an error.</p>
</div>
<div class="paragraph">
<p><strong>#error</strong> will cause the implementation to put a compile-time diagnostic message
into the shader object&#8217;s information log (see section 7.12 &#8220;Shader, Program
and Program Pipeline Queries&#8221; of the <a href="#references">OpenGL ES Specification</a> for how to
access a shader object&#8217;s information log).
The message will be the tokens following the <strong>#error</strong> directive, up to the
first new-line.
The implementation must treat the presence of a <strong>#error</strong> directive as a
compile-time error.</p>
</div>
<div class="paragraph">
<p><strong>#pragma</strong> allows implementation-dependent compiler control.
Tokens following <strong>#pragma</strong> are not subject to preprocessor macro expansion.
If an implementation does not recognize the tokens following <strong>#pragma</strong>, then
it will ignore that pragma.
The following pragmas are defined as part of the language.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> STDGL</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <strong>STDGL</strong> pragma is used to reserve pragmas for use by future revisions of
this language.
No implementation may use a pragma whose first token is <strong>STDGL</strong>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> optimize(on)
<span class="preprocessor">#pragma</span> optimize(off)</code></pre>
</div>
</div>
<div class="paragraph">
<p>can be used to turn off optimizations as an aid in developing and debugging
shaders.
It can only be used outside function definitions.
By default, optimization is turned on for all shaders.
The debug pragma</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> debug(on)
<span class="preprocessor">#pragma</span> debug(off)</code></pre>
</div>
</div>
<div class="paragraph">
<p>can be used to enable compiling and annotating a shader with debug
information, so that it can be used with a debugger.
It can only be used outside function definitions.
By default, debug is turned off.</p>
</div>
<div class="paragraph">
<p>The scope as well as the effect of the optimize and debug pragmas is
implementation-dependent except that their use must not generate an error.
Incorrect use of predefined pragmas does not cause an error.</p>
</div>
<div class="paragraph">
<p>By default, compilers of this language must issue compile-time
syntactic, semantic,
and
grammatical errors for shaders that do not conform to this specification.
Any extended behavior must first be enabled.
Directives to control the behavior of the compiler with respect to
extensions are declared with the <strong>#extension</strong> directive</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#extension</span> extension_name : behavior
<span class="preprocessor">#extension</span> all : behavior</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <em>extension_name</em> is the name of an extension.
Extension names are not documented in this specification.
The token <strong>all</strong> means the behavior applies to all extensions supported by
the compiler.
The <em>behavior</em> can be one of the following:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Behavior</th>
<th class="tableblock halign-left valign-top">Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>require</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Behave as specified by the extension <em>extension_name</em>.<br>
Give a compile-time error on the <strong>#extension</strong> if the extension
<em>extension_name</em> is not supported, or if <strong>all</strong> is specified.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>enable</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Behave as specified by the extension <em>extension_name</em>.<br>
Warn on the <strong>#extension</strong> if the extension <em>extension_name</em> is
not supported.<br>
Give an error on the <strong>#extension</strong> if <strong>all</strong> is
specified.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>warn</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Behave as specified by the extension <em>extension_name</em>,
except issue warnings on any detectable use of that extension,
unless such use is supported by other enabled or required
extensions.<br>
If <strong>all</strong> is specified, then warn on all detectable uses of any
extension used.<br>
Warn on the <strong>#extension</strong> if the extension <em>extension_name</em> is
not supported.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>disable</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Behave (including issuing errors and warnings) as if the
extension <em>extension_name</em> is not part of the language
definition.<br>
If <strong>all</strong> is specified, then behavior must revert back to that
of the non-extended core version of the language being
compiled to.<br>
Warn on the <strong>#extension</strong> if the extension <em>extension_name</em> is
not supported.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The <strong>extension</strong> directive is a simple, low-level mechanism to set the
behavior for each extension.
It does not define policies such as which combinations are appropriate,
those must be defined elsewhere.
Order of directives matters in setting the behavior for each extension:
Directives that occur later override those seen earlier.
The <strong>all</strong> variant sets the behavior for all extensions, overriding all
previously issued <strong>extension</strong> directives, but only for the <em>behaviors</em>
<strong>warn</strong> and <strong>disable</strong>.</p>
</div>
<div class="paragraph">
<p>The initial state of the compiler is as if the directive</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#extension</span> all : disable</code></pre>
</div>
</div>
<div class="paragraph">
<p>was issued, telling the compiler that all error and warning reporting must
be done according to this specification, ignoring any extensions.</p>
</div>
<div class="paragraph">
<p>Each extension can define its allowed granularity of scope.
If nothing is said, the granularity is a shader (that is, a single
compilation unit), and the extension directives must occur before any
non-preprocessor tokens.
If necessary, the linker can enforce granularities larger than a single
compilation unit, in which case each involved shader will have to contain
the necessary extension directive.</p>
</div>
<div class="paragraph">
<p>Macro expansion is not done on lines containing <strong>#extension</strong> and <strong>#version</strong>
directives.</p>
</div>
<div class="paragraph">
<p>For each extension there is an associated macro.
The macro is always defined in an implementation that supports the
extension.
This allows the following construct to be used:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#ifdef</span> OES_extension_name
<span class="preprocessor">#extension</span> OES_extension_name : enable
<span class="comment">// code that requires the extension</span>
<span class="preprocessor">#else</span>
<span class="comment">// alternative code</span>
<span class="preprocessor">#endif</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>#line</strong> must have, after macro substitution, one of the following forms:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#line</span> line
<span class="preprocessor">#line</span> line source-<span class="predefined-type">string</span>-number</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <em>line</em> and <em>source-string-number</em> are
<em>pp-constant-expressions</em>.
If these constant expressions are not integer literals then behavior is undefined.
After processing this directive (including its new-line), the implementation
will behave as if it is compiling at line number <em>line</em> and source string
number <em>source-string-number</em>.
Subsequent source strings will be numbered sequentially, until another
<strong>#line</strong> directive overrides that numbering.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="title">Note</div>
<div class="paragraph">
<p>Some implementations have allowed constant expressions in #line directives and
some have not. Even where expressions are supported the grammar is ambiguous and so
results are implementation dependent. For example,
+ #line +2 +2 // Line number set to 4, or file to 2 and line to 2</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>When targeting Vulkan, the following predefined macro is available:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> VULKAN <span class="integer">100</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>If during macro expansion a preprocessor directive is encountered, the
results are undefined; the compiler may or may not report an error in such
cases.</p>
</div>
</div>
<div class="sect2">
<h3 id="comments">3.5. Comments</h3>
<div class="paragraph">
<p>Comments are delimited by <strong>/*</strong> and <strong>*/</strong>, or by <strong>//</strong> and a new-line.
// style comments include the initial // marker and continue up to, but
not including, the terminating newline.
/*...*/ comments include both the start and end marker.
The begin comment delimiters (/* or //) are not recognized as comment
delimiters inside of a comment, hence comments cannot be nested.
Comments are treated syntactically as a single space.</p>
</div>
</div>
<div class="sect2">
<h3 id="tokens">3.6. Tokens</h3>
<div class="paragraph">
<p>The language, after preprocessing, is a sequence of tokens.
A token can be</p>
</div>
<div class="openblock bnf">
<div class="content">
<div class="dlist">
<dl>
<dt class="hdlist1"><em>token</em> : </dt>
<dd>
<p><em>keyword</em><br>
<em>identifier</em><br>
<em>integer-constant</em><br>
<em>floating-constant</em><br>
<em>operator</em><br>
<strong>;</strong> <strong>{</strong> <strong>}</strong></p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="keywords">3.7. Keywords</h3>
<div class="paragraph">
<p>The following are the keywords in the language and (after
preprocessing) can only be used as described in this specification,
or an error results:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p><strong>const</strong> <strong>uniform</strong> <strong>buffer</strong> <strong>shared</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>coherent</strong> <strong>volatile</strong> <strong>restrict</strong> <strong>readonly</strong> <strong>writeonly</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>atomic_uint</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>layout</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>centroid</strong> <strong>flat</strong> <strong>smooth</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>patch</strong> <strong>sample</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>invariant</strong> <strong>precise</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>break</strong> <strong>continue</strong> <strong>do</strong> <strong>for</strong> <strong>while</strong> <strong>switch</strong> <strong>case</strong> <strong>default</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>if</strong> <strong>else</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>in</strong> <strong>out</strong> <strong>inout</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>int</strong> <strong>void</strong> <strong>bool</strong> <strong>true</strong> <strong>false</strong> <strong>float</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>discard</strong> <strong>return</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>vec2</strong> <strong>vec3</strong> <strong>vec4</strong> <strong>ivec2</strong> <strong>ivec3</strong> <strong>ivec4</strong> <strong>bvec2</strong> <strong>bvec3</strong> <strong>bvec4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>uint</strong> <strong>uvec2</strong> <strong>uvec3</strong> <strong>uvec4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>mat2</strong> <strong>mat3</strong> <strong>mat4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>mat2x2</strong> <strong>mat2x3</strong> <strong>mat2x4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>mat3x2</strong> <strong>mat3x3</strong> <strong>mat3x4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>mat4x2</strong> <strong>mat4x3</strong> <strong>mat4x4</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>lowp</strong> <strong>mediump</strong> <strong>highp</strong> <strong>precision</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>sampler2D</strong> <strong>sampler2DShadow</strong> <strong>sampler2DArray</strong> <strong>sampler2DArrayShadow</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>isampler2D</strong> <strong>isampler2DArray</strong> <strong>usampler2D</strong> <strong>usampler2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>sampler2DMS</strong> <strong>isampler2DMS</strong> <strong>usampler2DMS</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>sampler2DMSArray</strong> <strong>isampler2DMSArray</strong> <strong>usampler2DMSArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>sampler3D</strong> <strong>isampler3D</strong> <strong>usampler3D</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>samplerCube</strong> <strong>samplerCubeShadow</strong> <strong>isamplerCube</strong> <strong>usamplerCube</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>samplerCubeArray</strong> <strong>samplerCubeArrayShadow</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>isamplerCubeArray</strong> <strong>usamplerCubeArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>samplerBuffer</strong> <strong>isamplerBuffer</strong> <strong>usamplerBuffer</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>image2D</strong> <strong>iimage2D</strong> <strong>uimage2D</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>image2DArray</strong> <strong>iimage2DArray</strong> <strong>uimage2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>image3D</strong> <strong>iimage3D</strong> <strong>uimage3D</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageCube</strong> <strong>iimageCube</strong> <strong>uimageCube</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageCubeArray</strong> <strong>iimageCubeArray</strong> <strong>uimageCubeArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageBuffer</strong> <strong>iimageBuffer</strong> <strong>uimageBuffer</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>struct</strong></p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>In addition, when targeting Vulkan, the following keywords also exist:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2D</strong> <strong>texture2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>itexture2D</strong> <strong>itexture2DArray</strong> <strong>utexture2D</strong> <strong>utexture2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2DMS</strong> <strong>itexture2DMS</strong> <strong>utexture2DMS</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2DMSArray</strong> <strong>itexture2DMSArray</strong> <strong>utexture2DMSArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture3D</strong> <strong>itexture3D</strong> <strong>utexture3D</strong></p>
</dd>
<dt class="hdlist1"></dt>