| <!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, Dave Baldwin and Randi Rost (Version 1.1 Authors)"> | 
 | <title>The OpenGL ES® Shading Language, Version 3.20.5</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>®</sup> Shading Language, Version 3.20.5</h1> | 
 | <div class="details"> | 
 | <span id="author" class="author">Robert J. Simpson, Qualcomm (Editor) ; John Kessenich, Dave Baldwin and Randi Rost (Version 1.1 Authors)</span><br> | 
 | <span id="revnumber">version 3.20.5,</span> | 
 | <span id="revdate">Wed, 12 Dec 2018 23:37:49 +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 OpenGL ES 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="#order-of-qualification">4.11. Order and Repetition of Qualification</a></li> | 
 | <li><a href="#empty-declarations">4.12. 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="#evaluation-of-expressions">5.11. 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> | 
 | </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> | 
 | </ul> | 
 | </div> | 
 | </div> | 
 | <div id="content"> | 
 | <div id="preamble"> | 
 | <div class="sectionbody"> | 
 | <div style="page-break-after: always;"></div> | 
 | <div class="paragraph"> | 
 | <p>Copyright © 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. | 
 | 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 OpenGL ES API. | 
 | See the <a href="#references">OpenGL ES Specification</a> for details on what language versions are | 
 | supported.</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-4">1.1.1. 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.2. 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.3. 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.4. 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.5. 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">OpenGL ES Specification</a> will specify the OpenGL ES 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 OpenGL ES.</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 “<a href="#shading-language-grammar">Shading Language | 
 | Grammar</a>” 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 API, 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 OpenGL ES 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 OpenGL ES 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 OpenGL ES state is not tracked or made available to shaders. | 
 | Typically, user-defined variables will be used for communicating between | 
 | different stages of the OpenGL ES 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 OpenGL ES 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’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 OpenGL ES | 
 | state and the OpenGL ES 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 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><</strong> and <strong>></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>&</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’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 "float foo;"</span> | 
 | <span class="comment">// (assuming '\' is the last character before the new-line and "oo" 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 “<strong>#version 320 es</strong>” 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 | 
 | “<a href="#references">Normative References</a>”).</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 running on an ES | 
 | system.</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 “GL_” (“GL” 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"><< >></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">< > <= >=</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">&</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">&&</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 ('&&') 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’s information log (see section 7.12 “Shader, Program | 
 | and Program Pipeline Queries” of the <a href="#references">OpenGL ES Specification</a> for how to | 
 | access a shader object’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>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>The following are the keywords reserved for future use. | 
 | Using them will result in an error:</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>attribute</strong> <strong>varying</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>noperspective</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>subroutine</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>common</strong> <strong>partition</strong> <strong>active</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>asm</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>class</strong> <strong>union</strong> <strong>enum</strong> <strong>typedef</strong> <strong>template</strong> <strong>this</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>resource</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>goto</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>inline</strong> <strong>noinline</strong> <strong>public</strong> <strong>static</strong> <strong>extern</strong> <strong>external</strong> <strong>interface</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>long</strong> <strong>short</strong> <strong>half</strong> <strong>fixed</strong> <strong>unsigned</strong> <strong>superp</strong> | 
 | <strong>double</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>input</strong> <strong>output</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>hvec2</strong> <strong>hvec3</strong> <strong>hvec4</strong> <strong>fvec2</strong> <strong>fvec3</strong> <strong>fvec4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>dvec2</strong> <strong>dvec3</strong> <strong>dvec4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>dmat2</strong> <strong>dmat3</strong> <strong>dmat4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>dmat2x2</strong> <strong>dmat2x3</strong> <strong>dmat2x4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>dmat3x2</strong> <strong>dmat3x3</strong> <strong>dmat3x4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>dmat4x2</strong> <strong>dmat4x3</strong> <strong>dmat4x4</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>filter</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>sizeof</strong> <strong>cast</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>namespace</strong> <strong>using</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>sampler1D</strong> <strong>sampler1DShadow</strong> <strong>sampler1DArray</strong> <strong>sampler1DArrayShadow</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>isampler1D</strong> <strong>isampler1DArray</strong> <strong>usampler1D</strong> <strong>usampler1DArray</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>sampler2DRect</strong> <strong>sampler2DRectShadow</strong> <strong>isampler2DRect</strong> <strong>usampler2DRect</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>sampler3DRect</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>image1D</strong> <strong>iimage1D</strong> <strong>uimage1D</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>image1DArray</strong> <strong>iimage1DArray</strong> <strong>uimage1DArray</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>image2DRect</strong> <strong>iimage2DRect</strong> <strong>uimage2DRect</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>image2DMS</strong> <strong>iimage2DMS</strong> <strong>uimage2DMS</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><strong>image2DMSArray</strong> <strong>iimage2DMSArray</strong> <strong>uimage2DMSArray</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In addition, all identifiers 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.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="identifiers">3.8. Identifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>Identifiers are used for variable names, function names, structure names, | 
 | and field selectors (field selectors select components of | 
 | <code><a href="#vector-components">vectors</a></code> and <code><a href="#matrix-components">matrices</a></code>, | 
 | similarly to structure members). | 
 | Identifiers have the form:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>identifier</em> : </dt> | 
 | <dd> | 
 | <p><em>nondigit</em><br> | 
 | <em>identifier</em> <em>nondigit</em><br> | 
 | <em>identifier</em> <em>digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>nondigit</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>_</strong> <strong>a b c d e f g h i j k l m n o p q r s t u v w x y z</strong><br> | 
 | <strong>A B C D E F G H I J K L M N O P Q R S T U V W X Y Z</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>digit</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>0 1 2 3 4 5 6 7 8 9</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Identifiers starting with “gl_” are reserved for use by OpenGL ES, and | 
 | in general, may not be declared in a shader; | 
 | this results in an error. | 
 | However, as noted in the specification, there are some cases where | 
 | previously declared variables can be redeclared, and predeclared “gl_” | 
 | names are allowed to be redeclared in a shader only for these specific | 
 | purposes.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Implementations must support identifier lengths of up to 1024 characters. | 
 | It is an error if the length exceeds this value.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="definitions">3.9. Definitions</h3> | 
 | <div class="paragraph"> | 
 | <p>Some language rules described below depend on the following definitions.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="static-use">3.9.1. Static Use</h4> | 
 | <div class="paragraph"> | 
 | <p>A shader contains a <em>static use</em> of a variable <em>x</em> if, after preprocessing, | 
 | the shader contains a statement that would access any part of <em>x</em>, | 
 | whether or not flow of control will cause that statement to be executed. | 
 | Such a variable is referred to as being <em>statically used</em>. If the access is a | 
 | write then <em>x</em> is further said to be <em>statically assigned</em>.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="uniform-and-non-uniform-control-flow">3.9.2. Uniform and Non-Uniform Control Flow</h4> | 
 | <div class="paragraph"> | 
 | <p>When executing statements in a fragment shader, control flow starts as | 
 | <em>uniform control flow</em>; all fragments enter the same control path into | 
 | <em>main()</em>. | 
 | Control flow becomes <em>non-uniform</em> when different fragments take different | 
 | paths through control-flow statements (selection, iteration, and jumps). | 
 | Control flow subsequently returns to being uniform after such divergent | 
 | sub-statements or skipped code completes, until the next time different | 
 | control paths are taken.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">main() | 
 | { | 
 |     <span class="predefined-type">float</span> a = ...; <span class="comment">// this is uniform control flow</span> | 
 |     <span class="keyword">if</span> (a < b) {   <span class="comment">// this expression is true for some fragments, not all</span> | 
 |         ...;       <span class="comment">// non-uniform control flow</span> | 
 |     } <span class="keyword">else</span> { | 
 |         ...;       <span class="comment">// non-uniform control flow</span> | 
 |     } | 
 |     ...;           <span class="comment">// uniform control flow again</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Other examples of non-uniform control flow can occur within switch | 
 | statements and after conditional breaks, continues, early returns, and after | 
 | fragment discards, when the condition is true for some fragments but not | 
 | others. | 
 | Loop iterations that only some fragments execute are also non-uniform | 
 | control flow.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This is similarly defined for other shader stages, based on the per-instance | 
 | data items they process.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="dynamically-uniform-expressions">3.9.3. Dynamically Uniform Expressions</h4> | 
 | <div class="paragraph"> | 
 | <p>A fragment-shader expression is <em>dynamically uniform</em> if all fragments | 
 | evaluating it get the same resulting value. | 
 | When loops are involved, this refers to the expression’s value for the same | 
 | loop iteration. | 
 | When functions are involved, this refers to calls from the same call point.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This is similarly defined for other shader stages, based on the per-instance | 
 | data they process.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that constant expressions are trivially dynamically uniform. | 
 | It follows that typical loop counters based on these are also dynamically | 
 | uniform.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="logical-phases-of-compilation">3.10. Logical Phases of Compilation</h3> | 
 | <div class="paragraph"> | 
 | <p>The compilation units for the shader processors are processed separately | 
 | before optionally being linked together in the final stage of compilation. | 
 | The logical phases of compilation are:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>Source strings are input as byte sequences. | 
 | The value 'zero' is interpreted as a terminator.</p> | 
 | </li> | 
 | <li> | 
 | <p>Source strings are concatenated to form a single input. | 
 | Zero bytes are discarded but all other values are retained.</p> | 
 | </li> | 
 | <li> | 
 | <p>Each string is interpreted according to the UTF-8 standard, with the | 
 | exception that all invalid byte sequences are retained in their original | 
 | form for subsequent processing.</p> | 
 | </li> | 
 | <li> | 
 | <p>Each {carriage-return, line-feed} and {line-feed, carriage return} | 
 | sequence is replaced by a single newline. | 
 | All remaining carriage-return and line-feed characters are then each | 
 | replaced by a newline.</p> | 
 | </li> | 
 | <li> | 
 | <p>Line numbering for each character, which is equal to the number of | 
 | preceding newlines plus one, is noted. | 
 | Note this can only be subsequently changed by the #line directive and is | 
 | not affected by the removal of newlines in phase 6 of compilation.</p> | 
 | </li> | 
 | <li> | 
 | <p>Wherever a backslash ('\') occurs immediately before a newline, both are | 
 | deleted. | 
 | Note that no whitespace is substituted, thereby allowing a single | 
 | preprocessing token to span a newline. | 
 | This operation is not recursive; any new {backslash newline} sequences | 
 | generated are not removed.</p> | 
 | </li> | 
 | <li> | 
 | <p>All comments are replaced with a single space. | 
 | All (non-zero) characters and invalid UTF-8 byte sequences are allowed | 
 | within comments. | 
 | '//' style comments include the initial '//' marker and continue up to, | 
 | but not including, the terminating newline. | 
 | '/<strong>…​</strong>/' comments include both the start and end marker.</p> | 
 | </li> | 
 | <li> | 
 | <p>The source string is converted into a sequence of preprocessing tokens. | 
 | These tokens include preprocessing numbers, identifiers and | 
 | preprocessing operations. | 
 | The line number associated with each token is copied from the line | 
 | number of the first character of the token.</p> | 
 | </li> | 
 | <li> | 
 | <p>The preprocessor is run. | 
 | Directives are executed and macro expansion is performed.</p> | 
 | </li> | 
 | <li> | 
 | <p>White space and newlines are discarded.</p> | 
 | </li> | 
 | <li> | 
 | <p>Preprocessing tokens are converted into tokens.</p> | 
 | </li> | 
 | <li> | 
 | <p>The syntax is analyzed according to the GLSL ES grammar.</p> | 
 | </li> | 
 | <li> | 
 | <p>The result is checked according to the semantic rules of the language.</p> | 
 | </li> | 
 | <li> | 
 | <p>Optionally, the shaders are linked together to form one or more programs | 
 | or separable programs. | 
 | When a pair of shaders from consecutive stages are linked into the same | 
 | program, any outputs and corresponding inputs not used in both shaders | 
 | may be discarded.</p> | 
 | </li> | 
 | <li> | 
 | <p>The binary is generated.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="variables-and-types">4. Variables and Types</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>All variables and functions must be declared before being used. | 
 | Variable and function names are identifiers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There are no default types. | 
 | All variable and function declarations must have a declared type, and | 
 | optionally qualifiers. | 
 | A variable is declared by specifying its type followed by one or more names | 
 | separated by commas. | 
 | In many cases, a variable can be initialized as part of its declaration by | 
 | using the assignment operator (<strong>=</strong>).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>User-defined types may be defined using <strong>struct</strong> to aggregate a list of | 
 | existing types into a single name.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language is type safe. | 
 | There are no implicit conversions between types.</p> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="basic-types">4.1. Basic Types</h3> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">Definition</dt> | 
 | <dd> | 
 | <p>A <em>basic type</em> is a type defined by a keyword in the language.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language supports the following basic data types, grouped as follows.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="_transparent_types">4.1.1. Transparent Types</h4> | 
 | <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">Type</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>void</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">for functions that do not return a value</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>bool</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a conditional type, taking on values of true or false</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>int</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a signed integer</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uint</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">an unsigned integer</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>float</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point scalar</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>vec2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a two-component single-precision floating-point vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>vec3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a three-component single-precision floating-point vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>vec4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a four-component single-precision floating-point vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>bvec2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a two-component Boolean vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>bvec3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a three-component Boolean vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>bvec4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a four-component Boolean vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>ivec2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a two-component signed integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>ivec3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a three-component signed integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>ivec4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a four-component signed integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uvec2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a two-component unsigned integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uvec3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a three-component unsigned integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uvec4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a four-component unsigned integer vector</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a 2 × 2 single-precision floating-point matrix</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a 3 × 3 single-precision floating-point matrix</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a 4 × 4 single-precision floating-point matrix</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat2x2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">same as a <strong>mat2</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat2x3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 2 columns and 3 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat2x4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 2 columns and 4 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat3x2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 3 columns and 2 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat3x3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">same as a <strong>mat3</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat3x4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 3 columns and 4 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat4x2</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 4 columns and 2 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat4x3</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a single-precision floating-point matrix with 4 columns and 3 rows</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mat4x4</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">same as a <strong>mat4</strong></p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Note that where the following tables say “accessing a texture”, the | 
 | <strong>sampler*</strong> opaque types access textures, and the <strong>image*</strong> opaque types | 
 | access images, of a specified type.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="_floating_point_opaque_types">4.1.2. Floating-Point Opaque Types</h4> | 
 | <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">Type</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2D</strong><br> | 
 |   <strong>image2D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2DShadow</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D depth texture with comparison</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2DArray</strong><br> | 
 |   <strong>image2DArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2DArrayShadow</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D array depth texture with comparison</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2DMS</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D multisample texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler2DMSArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 2D multisample array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sampler3D</strong><br> | 
 |   <strong>image3D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a 3D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>samplerCube</strong><br> | 
 |   <strong>imageCube</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a cube mapped texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>samplerCubeShadow</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a cube map depth texture with comparison</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>samplerCubeArray</strong><br> | 
 |   <strong>imageCubeArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a cube map array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>samplerCubeArrayShadow</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a cube map array depth texture with comparison</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>samplerBuffer</strong><br> | 
 |   <strong>imageBuffer</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing a buffer texture</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="_signed_integer_opaque_types">4.1.3. Signed Integer Opaque Types</h4> | 
 | <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">Type</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isampler2D</strong><br> | 
 |   <strong>iimage2D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer 2D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isampler2DArray</strong><br> | 
 |   <strong>iimage2DArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer 2D array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isampler2DMS</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer 2D multisample texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isampler2DMSArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer 2D multisample array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isampler3D</strong><br> | 
 |   <strong>iimage3D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer 3D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isamplerCube</strong><br> | 
 |   <strong>iimageCube</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer cube mapped texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isamplerCubeArray</strong><br> | 
 |   <strong>iimageCubeArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer cube map array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>isamplerBuffer</strong><br> | 
 |   <strong>iimageBuffer</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an integer buffer texture</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="_unsigned_integer_opaque_types">4.1.4. Unsigned Integer Opaque Types</h4> | 
 | <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">Type</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usampler2D</strong><br> | 
 |   <strong>uimage2D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer 2D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usampler2DArray</strong><br> | 
 |   <strong>uimage2DArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer 2D array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usampler2DMS</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer 2D multisample texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usampler2DMSArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer 2D multisample array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usampler3D</strong><br> | 
 |   <strong>uimage3D</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer 3D texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usamplerCube</strong><br> | 
 |   <strong>uimageCube</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer cube mapped texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usamplerCubeArray</strong><br> | 
 |   <strong>uimageCubeArray</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer cube map array texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>usamplerBuffer</strong><br> | 
 |   <strong>uimageBuffer</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer buffer texture</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>atomic_uint</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a handle for accessing an unsigned integer atomic counter</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>In addition, a shader can aggregate these basic types using arrays and | 
 | structures to build more complex types.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There are no pointer types.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="void">4.1.5. Void</h4> | 
 | <div class="paragraph"> | 
 | <p>Functions that do not return a value must be declared as <strong>void</strong>. | 
 | There is no default function return type. | 
 | The keyword <strong>void</strong> cannot be used in any other declarations (except for | 
 | empty formal or actual parameter lists), or an error results.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="booleans">4.1.6. Booleans</h4> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">Definition</dt> | 
 | <dd> | 
 | <p>A <em>boolean type</em> is any boolean scalar or vector type (<strong>bool</strong>, <strong>bvec2</strong>, | 
 | <strong>bvec3</strong>, <strong>bvec4</strong>)</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To make conditional execution of code easier to express, the type <strong>bool</strong> is | 
 | supported. | 
 | There is no expectation that hardware directly supports variables of this | 
 | type. | 
 | It is a genuine Boolean type, holding only one of two values meaning either | 
 | true or false. | 
 | Two keywords <strong>true</strong> and <strong>false</strong> can be used as literal Boolean constants. | 
 | Booleans are declared and optionally initialized as in the follow example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">bool</span> success;      <span class="comment">// declare "success" to be a Boolean</span> | 
 | <span class="predefined-type">bool</span> done = <span class="predefined-constant">false</span>; <span class="comment">// declare and initialize "done"</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Expressions used for conditional jumps (<strong>if</strong>, <strong>for</strong>, <strong>?:</strong>, <strong>while</strong>, | 
 | <strong>do</strong>-<strong>while</strong>) must evaluate to the type <strong>bool</strong>.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="integers">4.1.7. Integers</h4> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">Definitions</dt> | 
 | <dd> | 
 | <p>An <em>integral type</em> is any signed or unsigned, scalar or vector integer type. | 
 | It excludes arrays and structures.</p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>A <em>scalar integral type</em> is a scalar signed or unsigned integer type:</p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>A <em>vector integral type</em> is a vector of signed or unsigned integers:</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Signed and unsigned integer variables are fully supported. | 
 | In this document, the term <em>integer</em> is meant to generally include both | 
 | signed and unsigned integers. | 
 | <strong>highp</strong> unsigned | 
 | integers have exactly 32 bits of precision. | 
 | <strong>highp</strong> signed | 
 | integers use 32 bits, including a sign bit, in two’s complement form.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>mediump</strong> and <strong>lowp</strong> integers have implementation-defined numbers of bits. | 
 | See “<a href="#range-and-precision">Range and Precision</a>” for details. | 
 | For all precisions, | 
 | operations resulting in overflow or | 
 | underflow will not cause any exception, nor will they saturate, rather they | 
 | will “wrap” to yield the low-order | 
 | n bits of the result where n is the size in bits of the integer. | 
 | However, for the case where the minimum representable value is divided by | 
 | -1, it is allowed to return either the minimum representable value or the | 
 | maximum representable value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Integers are declared and optionally initialized with integer expressions, | 
 | as in the following example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> i, j = <span class="integer">42</span>; <span class="comment">// default integer literal type is int</span> | 
 | uint k = <span class="integer">3</span>u;   <span class="comment">// "u" establishes the type as uint</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Literal integer constants can be expressed in decimal (base 10), octal (base | 
 | 8), or hexadecimal (base 16) as follows.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>integer-constant</em> : </dt> | 
 | <dd> | 
 | <p><em>decimal-constant</em> <em>integer-suffix<sub>opt</sub></em><br> | 
 | <em>octal-constant</em> <em>integer-suffix<sub>opt</sub></em><br> | 
 | <em>hexadecimal-constant</em> <em>integer-suffix<sub>opt</sub></em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>integer-suffix</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>u</strong> <strong>U</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>decimal-constant</em> : </dt> | 
 | <dd> | 
 | <p><em>nonzero-digit</em><br> | 
 | <em>decimal-constant</em> <em>digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>octal-constant</em> : </dt> | 
 | <dd> | 
 | <p><strong>0</strong><br> | 
 | <em>octal-constant</em> <em>octal-digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>hexadecimal-constant</em> : </dt> | 
 | <dd> | 
 | <p><strong>0x</strong> <em>hexadecimal-digit</em><br> | 
 | <strong>0X</strong> <em>hexadecimal-digit</em><br> | 
 | <em>hexadecimal-constant</em> <em>hexadecimal-digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>digit</em> : </dt> | 
 | <dd> | 
 | <p><strong>0</strong><br> | 
 | <em>nonzero-digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>nonzero-digit</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>1 2 3 4 5 6 7 8 9</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>octal-digit</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>0 1 2 3 4 5 6 7</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>hexadecimal-digit</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>0 1 2 3 4 5 6 7 8 9<br> | 
 | a b c d e f<br> | 
 | A B C D E F</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>No white space is allowed between the digits of an integer constant, | 
 | including after the leading <strong>0</strong> or after the leading <strong>0x</strong> or <strong>0X</strong> of a | 
 | constant, or before the suffix <strong>u</strong> or <strong>U</strong>. | 
 | When the suffix <strong>u</strong> or <strong>U</strong> is present, the literal has type <strong>uint</strong>, | 
 | otherwise the type is <strong>int</strong>. | 
 | A leading unary minus sign (-) is interpreted as an arithmetic unary | 
 | negation, not as part of the constant. | 
 | Hence, literals themselves are always expressed with non-negative syntax, | 
 | though they could result in a negative value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is an error to provide a literal integer whose bit pattern | 
 | cannot fit in 32 bits. | 
 | The bit pattern of the literal is always used unmodified. | 
 | So a signed literal whose bit pattern includes a set sign bit creates a | 
 | negative value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="integer">1</span>             <span class="comment">// OK. Signed integer, value 1</span> | 
 | <span class="integer">1</span>u            <span class="comment">// OK. Unsigned integer, value 1</span> | 
 | -<span class="integer">1</span>            <span class="comment">// OK. Unary minus applied to signed integer.</span> | 
 |               <span class="comment">// result is a signed integer, value -1</span> | 
 | -<span class="integer">1</span>u           <span class="comment">// OK. Unary minus applies to unsigned integer.</span> | 
 |               <span class="comment">// Result is an unsigned integer, value 0xffffffff</span> | 
 | <span class="hex">0xA0000000</span>    <span class="comment">// OK. 32-bit signed hexadecimal</span> | 
 | <span class="hex">0xABcdEF00</span>u   <span class="comment">// OK. 32-bit unsigned hexadecimal</span> | 
 | <span class="hex">0xffffffff</span>    <span class="comment">// OK. Signed integer, value -1</span> | 
 | <span class="hex">0x80000000</span>    <span class="comment">// OK. Evaluates to -2147483648</span> | 
 | <span class="hex">0xffffffff</span>u   <span class="comment">// OK. Unsigned integer, value 0xffffffff</span> | 
 | <span class="hex">0xfffffffff</span>   <span class="comment">// Error: needs more than 32 bits</span> | 
 | <span class="integer">3000000000</span>    <span class="comment">// OK. A signed decimal literal taking 32 bits.</span> | 
 |               <span class="comment">// It evaluates to -1294967296</span> | 
 | <span class="integer">2147483648</span>    <span class="comment">// OK. Evaluates to -2147483648 (the literal set the sign bit)</span> | 
 | <span class="integer">5000000000</span>    <span class="comment">// Error: needs more than 32 bits</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="floats">4.1.8. Floats</h4> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">Definition</dt> | 
 | <dd> | 
 | <p>A <em>floating-point type</em> is any floating-point scalar, vector or matrix type. | 
 | It excludes arrays and structures.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Floats are available for use in a variety of scalar calculations. | 
 | Floating-point variables are defined as in the following example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> a, b = <span class="float">1</span><span class="float">.5</span>;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As an input value to one of the processing units, a floating-point variable | 
 | is expected to match the IEEE 754 single precision floating-point definition | 
 | for precision and dynamic range. | 
 | <strong>highp</strong> floating-point variables within a shader are encoded according to | 
 | the IEEE 754 specification for single-precision floating-point values | 
 | (logically, not necessarily physically). | 
 | While encodings are logically IEEE 754, operations (addition, | 
 | multiplication, etc.) are not necessarily performed as required by IEEE 754. | 
 | See “<a href="#range-and-precision">Range and Precision</a>” for more details on | 
 | precision and usage of NaNs (Not a Number) and Infs (positive or negative | 
 | infinities).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Floating-point constants are defined as follows.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>floating-constant</em> : </dt> | 
 | <dd> | 
 | <p><em>fractional-constant</em> <em>exponent-part<sub>opt</sub></em> <em>floating-suffix<sub>opt</sub></em><br> | 
 | <em>digit-sequence</em> <em>exponent-part</em> <em>floating-suffix<sub>opt</sub></em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>fractional-constant</em> : </dt> | 
 | <dd> | 
 | <p><em>digit-sequence</em> <strong>.</strong> <em>digit-sequence</em><br> | 
 | <em>digit-sequence</em> <strong>.</strong><br> | 
 | <strong>.</strong> <em>digit-sequence</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>exponent-part</em> : </dt> | 
 | <dd> | 
 | <p><strong>e</strong> <em>sign<sub>opt</sub></em> <em>digit-sequence</em><br> | 
 | <strong>E</strong> <em>sign<sub>opt</sub></em> <em>digit-sequence</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>sign</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>+</strong> <strong>-</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>digit-sequence</em> : </dt> | 
 | <dd> | 
 | <p><em>digit</em><br> | 
 | <em>digit-sequence</em> <em>digit</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>floating-suffix</em> : one of </dt> | 
 | <dd> | 
 | <p><strong>f</strong> <strong>F</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A decimal point (<strong>.</strong>) is not needed if the exponent part is present. | 
 | No white space may appear anywhere within a floating-point constant, | 
 | including before a suffix. | 
 | A leading unary minus sign (<strong>-</strong>) is interpreted as a unary operator and is | 
 | not part of the floating-point constant.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is no limit on the number of digits in any <em>digit-sequence</em>. | 
 | If the value of the floating-point number is too large (small) to be stored | 
 | as a single precision value, it is converted to positive (negative) | 
 | infinity. | 
 | A value with a magnitude too small to be represented as a mantissa and | 
 | exponent is converted to zero. | 
 | Implementations may also convert subnormal (denormalized) numbers to zero.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="vectors">4.1.9. Vectors</h4> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language includes data types for generic 2-, 3-, and 4-component vectors | 
 | of floating-point values, integers, and Booleans. | 
 | Floating-point vector variables can be used to store colors, normals, | 
 | positions, texture coordinates, texture lookup results and the like. | 
 | Boolean vectors can be used for component-wise comparisons of numeric | 
 | vectors. | 
 | Some examples of vector declarations are:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec2 texcoord1, texcoord2; | 
 | vec3 position; | 
 | vec4 myRGBA; | 
 | ivec2 textureLookup; | 
 | bvec3 less;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Initialization of vectors can be done with constructors. | 
 | See “<a href="#vector-and-matrix-constructors">Vector and Matrix Constructors</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="matrices">4.1.10. Matrices</h4> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language has built-in types for 2 × 2, 2 × 3, 2 × 4, 3 | 
 | × 2, 3 × 3, 3 × 4, 4 × 2, 4 × 3, and 4 × | 
 | 4 matrices of floating-point numbers. | 
 | The first number in the type is the number of columns, the second is the | 
 | number of rows. | 
 | If there is only one number, the matrix is square. | 
 | Example matrix declarations:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat2 mat2D; | 
 | mat3 optMatrix; | 
 | mat4 view, projection; | 
 | mat4x4 view; <span class="comment">// an alternate way of declaring a mat4</span> | 
 | mat3x2 m;    <span class="comment">// a matrix with 3 columns and 2 rows</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Initialization of matrix values is done with constructors (described in | 
 | “<a href="#vector-and-matrix-constructors">Vector and Matrix Constructors</a>”) in | 
 | column-major order.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>mat2</strong> is an alias for <strong>mat2x2</strong>, not a distinct type. | 
 | Similarly for <strong>mat3</strong> and <strong>mat4.</strong> The following is legal:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat2 a; | 
 | mat2x2 b = a;</code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="opaque-types">4.1.11. Opaque Types</h4> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">Definition</dt> | 
 | <dd> | 
 | <p>An <em>opaque type</em> is a type where the internal structure of the type is | 
 | hidden from the language.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The opaque types, as listed in the following sections, declare variables | 
 | that are effectively opaque handles to other objects. | 
 | These objects are accessed through built-in functions, not through direct | 
 | reading or writing of the declared variable. | 
 | They can only be declared as function parameters or in <strong>uniform</strong>-qualified | 
 | variables (see “<a href="#uniform-variables">Uniform Variables</a>”). | 
 | The only opaque types that take memory qualifiers are the image types. | 
 | Except for array indexing, structure member selection, and parentheses, | 
 | opaque variables are not allowed to be operands in expressions; such use | 
 | results in a compile-time error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When aggregated into arrays within a shader, opaque types can only be | 
 | indexed with a dynamically uniform integral expression (see “Dynamically | 
 | Uniform Expressions”) unless otherwise noted; otherwise, results are | 
 | undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Opaque variables cannot be treated as l-values; hence cannot be used as | 
 | <strong>out</strong> or <strong>inout</strong> function parameters, nor can they be assigned into. | 
 | Any such use results in a compile-time error. | 
 | However, they can be passed as <strong>in</strong> parameters with matching types and | 
 | memory qualifiers. | 
 | They cannot be declared with an initializer.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Because a single opaque type declaration effectively declares two objects, | 
 | the opaque handle itself and the object it is a handle to, there is room for | 
 | both a storage qualifier and a memory qualifier. | 
 | The storage qualifier will qualify the opaque handle, while the memory | 
 | qualifier will qualify the object it is a handle to.</p> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="samplers">Samplers</h5> | 
 | <div class="paragraph"> | 
 | <p>Sampler types (e.g. <strong>sampler2D</strong>) are opaque types, declared and behaving as | 
 | described above for opaque types.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Sampler variables are handles to | 
 | two-, and three- dimensional textures, cube maps, depth textures (shadowing), | 
 | etc., as enumerated in the basic types tables. | 
 | There are distinct sampler types for each texture target, and for each of | 
 | float, integer, and unsigned integer data types. | 
 | Texture accesses are done through built-in texture functions (described in | 
 | “<a href="#texture-functions">Texture Functions</a>”) and samplers are used to | 
 | specify which texture to access and how it is to be filtered.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="images">Images</h5> | 
 | <div class="paragraph"> | 
 | <p>Image types are opaque types, declared and behaving as described above for | 
 | opaque types. | 
 | They can be further qualified with memory qualifiers. | 
 | When aggregated into arrays within a shader, images can only be indexed with | 
 | a constant integral expression.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Image variables are handles to | 
 | two-, or three-dimensional images | 
 | corresponding to all or a portion of a single level of a texture image bound | 
 | to an image unit. | 
 | There are distinct image variable types for each texture target, and for | 
 | each of float, integer, and unsigned integer data types. | 
 | Image accesses should use an image type that matches the target of the | 
 | texture whose level is bound to the image unit, or for non-layered bindings | 
 | of 3D or array images should use the image type that matches the | 
 | dimensionality of the layer of the image (i.e., a layer of 3D, 2DArray, | 
 | Cube, or CubeArray should use | 
 | <strong>image2D</strong>). | 
 | If the image target type does not match the bound image in this manner, if | 
 | the data type does not match the bound image, or if the format layout | 
 | qualifier does not match the image unit format as described in section | 
 | 8.22 | 
 | “Texture Image Loads and Stores” of the <a href="#references">OpenGL ES Specification</a>, the | 
 | results of image accesses are undefined but cannot include program | 
 | termination.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Image variables are used in the image load, store, and atomic functions | 
 | described in “<a href="#image-functions">Image Functions</a>” to specify an image to | 
 | access.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="atomic-counters">Atomic Counters</h5> | 
 | <div class="paragraph"> | 
 | <p>Atomic counter types (e.g. <strong>atomic_uint</strong>) are opaque handles to counters, | 
 | declared and behaving as described above for opaque types. | 
 | The variables they declare specify which counter to access when using the | 
 | built-in atomic counter functions as described in | 
 | “<a href="#atomic-counter-functions">Atomic Counter Functions</a>”. | 
 | They are bound to buffers as described in | 
 | “<a href="#atomic-counter-layout-qualifiers">Atomic Counter Layout Qualifiers</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Atomic counters aggregated into arrays within a shader can only be indexed | 
 | with dynamically uniform integral expressions, otherwise results are | 
 | undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Members of structures cannot be declared as atomic counter types.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The default precision of all atomic types is <strong>highp</strong>. | 
 | It is an error to declare an atomic type with a different precision or to | 
 | specify the default precision for an atomic type to be <strong>lowp</strong> or <strong>mediump</strong>.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="structures">4.1.12. Structures</h4> | 
 | <div class="paragraph"> | 
 | <p>User-defined types can be created by aggregating other already defined types | 
 | into a structure using the <strong>struct</strong> keyword. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> light { | 
 |     <span class="predefined-type">float</span> intensity; | 
 |     vec3 position; | 
 | } lightVar;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In this example, <em>light</em> becomes the name of the new type, and <em>lightVar</em> | 
 | becomes a variable of type <em>light</em>. | 
 | To declare variables of the new type, use its name (without the keyword | 
 | <strong>struct</strong>).</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">light lightVar2;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>More formally, structures are declared as follows. | 
 | However, the definitive grammar is as given in | 
 | “<a href="#shading-language-grammar">Shading Language Grammar</a>”.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>struct-definition</em> : </dt> | 
 | <dd> | 
 | <p><em>qualifier<sub>opt</sub></em> <strong>struct</strong> name<sub>opt</sub>_ <strong>{</strong> <em>member-list</em> <strong>}</strong> | 
 | <em>declarators<sub>opt</sub></em> <strong>;</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>member-list</em> : </dt> | 
 | <dd> | 
 | <p><em>member-declaration</em> <strong>;</strong><br> | 
 | <em>member-declaration</em> <em>member-list</em> <strong>;</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>member-declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>basic-type</em> <em>declarators</em> <strong>;</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where <em>name</em> becomes the user-defined type, and can be used to declare | 
 | variables to be of this new type. | 
 | The <em>name</em> shares the same name space as other variables, types, and | 
 | functions. | 
 | All previously visible variables, types, constructors, or functions with | 
 | that name are hidden. | 
 | The optional <em>qualifier</em> only applies to any <em>declarators</em>, and is not part | 
 | of the type being defined for <em>name</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structures must have at least one member declaration. | 
 | Member declarators may contain precision qualifiers, but use of any other | 
 | qualifier results in an error. | 
 | Bit fields are not supported. | 
 | Member types must be already defined (there are no forward references). | 
 | Member declarations cannot contain initializers. | 
 | Member declarators can contain arrays. | 
 | Such arrays must have a size specified, and the size must be a constant | 
 | integral expression that’s greater than zero (see | 
 | “<a href="#constant-expressions">Constant Expressions</a>”). | 
 | Each level of structure has its own name space for names given in member | 
 | declarators; such names need only be unique within that name space.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Anonymous structures are not supported. | 
 | Embedded structure definitions are not supported.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> S { <span class="predefined-type">float</span> f; }; <span class="comment">// Allowed: S is defined as a structure.</span> | 
 |  | 
 | <span class="keyword">struct</span> T { | 
 |     S;              <span class="comment">// Error: anonymous structures disallowed</span> | 
 |     <span class="keyword">struct</span> { ... }; <span class="comment">// Error: embedded structures disallowed</span> | 
 |     S s;            <span class="comment">// Allowed: nested structure with a name.</span> | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structures can be initialized at declaration time using constructors, as | 
 | discussed in “<a href="#structure-constructors">Structure Constructors</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any restrictions on the usage of a type or qualifier also apply to any | 
 | structure that contains a member of that type or qualifier. | 
 | This also applies to structure members that are structures, recursively.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structures can contain variables of any type except:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p><strong>atomic_uint</strong> (since there is no mechanism to specify the binding)</p> | 
 | </li> | 
 | <li> | 
 | <p>image types (since there is no mechanism to specify the format | 
 | qualifier)</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="arrays">4.1.13. Arrays</h4> | 
 | <div class="paragraph"> | 
 | <p>Variables of the same type can be aggregated into arrays by declaring a name | 
 | followed by brackets (<strong>[ ]</strong>) enclosing an optional size.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When present, the array size must be a constant integral expression (see | 
 | “<a href="#constant-expressions">Constant Expressions</a>”) greater than zero. | 
 | The type of the size parameter can be a signed or unsigned integer and the | 
 | choice of type does not affect the type of the resulting array. | 
 | Arrays only have a single dimension (a single number within “[ ]”), | 
 | however, arrays of arrays can be declared. | 
 | Any type can be formed into an array.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays are sized either at compile-time or at run-time. | 
 | To size an array at compile-time, either the size must be specified within | 
 | the brackets as above or must be inferred from the type of the initializer.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an array is declared as the last member of a shader storage block and the | 
 | size is not specified at compile-time, it is sized at run-time. | 
 | In all other cases, arrays are sized only at compile-time. | 
 | An array declaration sized at compile-time which leaves the size of the | 
 | array unspecified is an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For compile-time sized arrays, it is illegal to index an array with a | 
 | constant integral expression greater than or equal to the declared size or | 
 | with a negative constant expression. | 
 | Arrays declared as formal parameters in a function declaration must also | 
 | specify a size. | 
 | Undefined behavior results from indexing an array with a non-constant | 
 | expression that’s greater than or equal to the array’s size or less than 0. | 
 | If robust buffer access is enabled (see section 10.3.5 “Robust Buffer | 
 | Access” of the <a href="#references">OpenGL ES Specification</a>), such indexing must not result in | 
 | abnormal program termination. | 
 | The results are still undefined, but implementations are encouraged to | 
 | produce zero values for such accesses.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some examples are:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> frequencies[<span class="integer">3</span>]; | 
 | uniform vec4 lightPosition[<span class="integer">4</span>u]; | 
 | <span class="directive">const</span> <span class="predefined-type">int</span> numLights = <span class="integer">2</span>; | 
 | light lights[numLights]; | 
 | vec4 a[<span class="integer">3</span>][<span class="integer">2</span>]; | 
 | a.length() <span class="comment">// this is 3</span> | 
 | a[x].length() <span class="comment">// this is 2</span> | 
 | <span class="comment">// a shader storage block, introduced in section 4.3.7 "Buffer Variables"</span> | 
 | buffer b { | 
 |     <span class="predefined-type">float</span> u[]; <span class="comment">// an error</span> | 
 |     vec4 v[];  <span class="comment">// okay, v will be sized at run-time</span> | 
 | } name[<span class="integer">3</span>];     <span class="comment">// when the block is arrayed, all u will be the same size,</span> | 
 |                <span class="comment">// but not necessarily all v, if sized dynamically</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When the <strong>length</strong>() method will return a compile-time constant, the | 
 | expression in brackets (x above) will be evaluated and subject to the rules | 
 | required for array indices, but the array will not be dereferenced. | 
 | Thus, behavior is well defined even if the run-time value of the expression | 
 | is out of bounds.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An array type can be formed by specifying a non-array type | 
 | (<a href="#type_specifier_nonarray">[type_specifier_nonarray]</a>) followed by an <a href="#array_specifier">[array_specifier]</a>.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span>[<span class="integer">5</span>]</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that the construct <em>type [size]</em> does not always result in an array of | 
 | length <em>size</em> of type <em>type</em>:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span>[<span class="integer">2</span>][<span class="integer">3</span>] <span class="comment">// an array of size [2] of array of size [3] of float,</span> | 
 |             <span class="comment">// not size [3] of float[2]</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This type can be used anywhere any other type can be used, including as the | 
 | return value from a function</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span>[<span class="integer">5</span>] foo() { }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>as a constructor of an array:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span>[<span class="integer">5</span>](<span class="float">3</span><span class="float">.4</span>, <span class="float">4</span><span class="float">.2</span>, <span class="float">5</span><span class="float">.0</span>, <span class="float">5</span><span class="float">.2</span>, <span class="float">1</span><span class="float">.1</span>)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>as an unnamed parameter:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> foo(<span class="predefined-type">float</span>[<span class="integer">5</span>])</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>and as an alternate way of declaring a variable or function parameter:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span>[<span class="integer">5</span>] a;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An array type can also be formed without specifying a size if the definition | 
 | includes an initializer:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> x[] = <span class="predefined-type">float</span>[<span class="integer">2</span>] (<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>); <span class="comment">// declares an array of size 2</span> | 
 | <span class="predefined-type">float</span> y[] = <span class="predefined-type">float</span>[] (<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>, <span class="float">3</span><span class="float">.0</span>); <span class="comment">// declares an array of size 3</span> | 
 | <span class="predefined-type">float</span> a[<span class="integer">5</span>]; | 
 | <span class="predefined-type">float</span> b[] = a;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that the initializer itself does not need to be a constant expression | 
 | but the length of the initializer will be a constant expression.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays can have initializers formed from array constructors:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> a[<span class="integer">5</span>] = <span class="predefined-type">float</span>[<span class="integer">5</span>](<span class="float">3</span><span class="float">.4</span>, <span class="float">4</span><span class="float">.2</span>, <span class="float">5</span><span class="float">.0</span>, <span class="float">5</span><span class="float">.2</span>, <span class="float">1</span><span class="float">.1</span>); | 
 | <span class="predefined-type">float</span> a[<span class="integer">5</span>] = <span class="predefined-type">float</span>[](<span class="float">3</span><span class="float">.4</span>, <span class="float">4</span><span class="float">.2</span>, <span class="float">5</span><span class="float">.0</span>, <span class="float">5</span><span class="float">.2</span>, <span class="float">1</span><span class="float">.1</span>);  <span class="comment">// same thing</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An array of arrays can be declared as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 a[<span class="integer">3</span>][<span class="integer">2</span>]; <span class="comment">// size-3 array of size-2 array of vec4</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>which declares a one-dimensional array of size 3 of one-dimensional arrays | 
 | of size 2 of <strong>vec4</strong>. | 
 | The following declarations do the same thing:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4[<span class="integer">2</span>] a[<span class="integer">3</span>]; <span class="comment">// size-3 array of size-2 array of vec4</span> | 
 | vec4[<span class="integer">3</span>][<span class="integer">2</span>] a; <span class="comment">// size-3 array of size-2 array of vec4</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When in transparent memory (like in a uniform block), the layout is that the | 
 | inner-most (right-most in declaration) dimensions iterate faster than the | 
 | outer dimensions. | 
 | That is, for the above, the order in memory would be:</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>Low address : a[0][0] : a[0][1] : a[1][0] : a[1][1] : a[2][0] : a[2][1] | 
 | : High address</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The last member of a shader storage block (see “<a href="#buffer-variables">Buffer | 
 | Variables</a>”), may be declared without specifying a size. | 
 | For such arrays, the effective array size is inferred at run-time from the | 
 | size of the data store backing the shader storage block. | 
 | Such runtime-sized arrays may be indexed with general integer expressions, | 
 | but may not be passed as an argument to a function or indexed with a | 
 | negative constant expression.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> S { <span class="predefined-type">float</span> f; }; | 
 | buffer ShaderStorageBlock1 | 
 | { | 
 |     vec4 a[]; <span class="comment">// illegal</span> | 
 |     vec4 b[]; <span class="comment">// legal, runtime-sized arrays are last member</span> | 
 | }; | 
 | buffer ShaderStorageBlock2 | 
 | { | 
 |     vec4 a[<span class="integer">4</span>]; <span class="comment">// legal, size declared</span> | 
 |     S b[]; <span class="comment">// legal, runtime-sized arrays are allowed,</span> | 
 |     <span class="comment">// including arrays of structures</span> | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>However, it is a compile-time error to assign to a runtime-sized array. | 
 | Assignments to individual elements of the array is allowed.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays have a fixed number of elements. | 
 | This can be obtained by using the <strong>length</strong>() method:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> a[<span class="integer">5</span>]; | 
 | a.length(); <span class="comment">// returns 5</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The return value is a signed integral expression. | 
 | For compile-time sized arrays, the value returned by the length method is a | 
 | constant expression. | 
 | For run-time sized arrays , the value returned will not be constant | 
 | expression and will be determined at run time based on the size of the | 
 | buffer object providing storage for the block.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision is determined using the same rules as for other cases where | 
 | there is no intrinsic precision. | 
 | See “<a href="#precision-qualifiers">Precision Qualifiers</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any restrictions on the usage of a type also apply to arrays of that type. | 
 | This applies recursively.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="scoping">4.2. Scoping</h3> | 
 | <div class="paragraph"> | 
 | <p>The scope of a declaration determines where the declaration is visible. | 
 | GLSL ES uses a system of statically nested scopes. | 
 | This allows names to be redefined within a shader.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="definition-of-terms">4.2.1. Definition of Terms</h4> | 
 | <div class="paragraph"> | 
 | <p>The term <em>scope</em> refers to a specified region of the program where names are | 
 | guaranteed to be visible. | 
 | For example, a <em>compound_statement_with_scope</em> ('{' <em>statement</em> <em>statement</em> | 
 | …​ | 
 | '}') defines a scope.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <em>nested scope</em> is a scope defined within an outer scope.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The terms '<em>same scope'</em> and '<em>current scope</em>' are equivalent to the term | 
 | '<em>scope</em>' but used to emphasize that nested scopes are excluded.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <em>scope of a declaration</em> is the region or regions of the program where | 
 | that declaration is visible.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <em>name space</em> defines where names may be defined. | 
 | Within a single name space, a name has at most one entry, specifying it to | 
 | be one of: structure, variable, or function.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In general, each scope has an associated name space. | 
 | However, in certain cases e.g. for uniforms, multiple scopes share the same | 
 | name space. | 
 | In these cases, conflicting declarations are an error, even though the name | 
 | is only visible in the scopes where it is declared.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="types-of-scope">4.2.2. Types of Scope</h4> | 
 | <div class="paragraph"> | 
 | <p>The scope of a variable is determined by where it is declared. | 
 | If it is declared outside all function definitions, it has global scope, | 
 | which starts from where it is declared and persists to the end of the shader | 
 | it is declared in. | 
 | If it is declared in a <strong>while</strong> test or a <strong>for</strong> statement, then it is scoped | 
 | to the end of the following sub-statement (specified as | 
 | <em>statement-no-new-scope</em> in the grammar). | 
 | Otherwise, if it is declared as a statement within a compound statement, it | 
 | is scoped to the end of that compound statement. | 
 | If it is declared as a parameter in a function definition, it is scoped | 
 | until the end of that function definition. | 
 | A function’s parameter declarations and body together form a single scope.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> f( <span class="comment">/* nested scope begins here */</span> <span class="predefined-type">int</span> k) | 
 | { | 
 |     <span class="predefined-type">int</span> k = k + <span class="integer">3</span>; <span class="comment">// redeclaration error of the name k</span> | 
 |     ... | 
 | } | 
 | <span class="predefined-type">int</span> f(<span class="predefined-type">int</span> k) | 
 | { | 
 |     { | 
 |        <span class="predefined-type">int</span> k = k + <span class="integer">3</span>; <span class="comment">// 2nd k is parameter, initializing nested first k</span> | 
 |        <span class="predefined-type">int</span> m = k <span class="comment">// use of new k, which is hiding the parameter</span> | 
 |     } | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For both for and while loops, the sub-statement itself does not introduce a | 
 | new scope for variable names, so the following has a redeclaration | 
 | compile-time error:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">for</span> ( <span class="comment">/* nested scope begins here */</span> <span class="predefined-type">int</span> i = <span class="integer">0</span>; i < <span class="integer">10</span>; i++) | 
 | { | 
 |     <span class="predefined-type">int</span> i; <span class="comment">// redeclaration error</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The body of a <strong>do</strong>-<strong>while</strong> loop introduces a new scope lasting only between | 
 | the do and while (not including the while test expression), whether or not | 
 | the body is simple or compound:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> _i_ = <span class="integer">17</span>; | 
 | <span class="keyword">do</span> | 
 |     <span class="predefined-type">int</span> i = <span class="integer">4</span>; <span class="comment">// okay, in nested scope</span> | 
 | <span class="keyword">while</span> (i == <span class="integer">0</span>); <span class="comment">// i is 17, scoped outside the do-while body</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The statement following a <strong>switch</strong> (…​) forms a nested scope.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Representing the if construct as:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>if</strong> if-expression <strong>then</strong> if-statement <strong>else</strong> else-statement,</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>a variable declared in the if-statement is scoped to the end of the | 
 | if-statement. | 
 | A variable declared in the else-statement is scoped to the end of the | 
 | else-statement. | 
 | This applies both when these statements are simple statements and when they | 
 | are compound statements. | 
 | The if-expression does not allow new variables to be declared, hence does | 
 | not form a new scope.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within a declaration, the scope of a name starts immediately after the | 
 | initializer if present or immediately after the name being declared if not. | 
 | Several examples:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> x = <span class="integer">1</span>; | 
 | { | 
 |     <span class="predefined-type">int</span> x = <span class="integer">2</span>,<span class="comment">/* 2nd x visible here */</span> y = x; <span class="comment">// y is initialized to 2</span> | 
 |     <span class="predefined-type">int</span> z = z; <span class="comment">// error if z not previously defined.</span> | 
 | } | 
 | { | 
 | <span class="predefined-type">int</span> x = x; <span class="comment">// x is initialized to '1'</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A structure name declaration is visible at the end of the <em>struct_specifier</em> | 
 | in which it was declared:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> S | 
 | { | 
 |     <span class="predefined-type">int</span> x; | 
 | }; | 
 | { | 
 |     S S = S(<span class="integer">0</span>); <span class="comment">// 'S' is only visible as a struct and constructor</span> | 
 |     S; <span class="comment">// 'S' is now visible as a variable</span> | 
 | } | 
 | <span class="predefined-type">int</span> x = x; <span class="comment">// Error if x has not been previously defined.</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="redeclaring-names">4.2.3. Redeclaring Names</h4> | 
 | <div class="paragraph"> | 
 | <p>All variable names, structure type names, and function names in a given | 
 | scope share the same name space. | 
 | Function names can be redeclared in the same scope, with the same or | 
 | different parameters, without error. | 
 | Otherwise, within a shader, a declared name cannot be redeclared in the same | 
 | scope; doing so results in a redeclaration error. | 
 | If a nested scope redeclares a name used in an outer scope, it hides all | 
 | existing uses of that name. | 
 | There is no way to access the hidden name or make it unhidden, without | 
 | exiting the scope that hid it.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Names of built-in functions cannot be redeclared as functions. | 
 | Therefore overloading or redefining built-in functions is an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <em>declaration</em> is considered to be a statement that adds a name or | 
 | signature to the symbol table. | 
 | A <em>definition</em> is a statement that fully defines that name or signature. | 
 | E.g.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> f();<span class="comment">// declaration;</span> | 
 | <span class="predefined-type">int</span> f() {<span class="keyword">return</span> <span class="integer">0</span>;}<span class="comment">// declaration and definition</span> | 
 | <span class="predefined-type">int</span> x; <span class="comment">// declaration and definition</span> | 
 | <span class="predefined-type">int</span> a[<span class="integer">4</span>];<span class="comment">// array declaration and definition</span> | 
 | <span class="keyword">struct</span> S {<span class="predefined-type">int</span> x;};<span class="comment">// structure declaration and definition</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The determination of equivalence of two declarations depends on the type of | 
 | declaration. | 
 | For functions, the whole function signature must be considered (see | 
 | “Function Definitions”). | 
 | For variables (including arrays) and structures only the names must match.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within each scope, a name may be declared either as a variable declaration | 
 | <em>or</em> as function declarations <em>or</em> as a structure.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Examples of combinations that are allowed:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>1.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> f(<span class="predefined-type">int</span>) {...} | 
 | <span class="directive">void</span> f(<span class="predefined-type">float</span>) {...}<span class="comment">// function overloading allowed</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>2.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> f(<span class="predefined-type">int</span>);<span class="comment">// 1^st^ declaration (allowed)</span> | 
 | <span class="directive">void</span> f(<span class="predefined-type">int</span>);<span class="comment">// repeated declaration (allowed)</span> | 
 | <span class="directive">void</span> f(<span class="predefined-type">int</span>) {...}<span class="comment">// single definition (allowed)</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Examples of combinations that are disallowed:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>1.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> f(<span class="predefined-type">int</span>) {...} | 
 | <span class="directive">void</span> f(<span class="predefined-type">int</span>) {...}<span class="comment">// Error: repeated definition</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>2.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> f(<span class="predefined-type">int</span>); | 
 | <span class="keyword">struct</span> f {<span class="predefined-type">int</span> x;};<span class="comment">// Error: type 'f' conflicts with function 'f'</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>3.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> f {<span class="predefined-type">int</span> x;}; | 
 | <span class="predefined-type">int</span> f;<span class="comment">// Error: conflicts with the type 'f'</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>4.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> a[<span class="integer">3</span>]; | 
 | <span class="predefined-type">int</span> a[<span class="integer">3</span>];<span class="comment">// Error: repeated array definition</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>5.</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> x; | 
 | <span class="predefined-type">int</span> x;<span class="comment">// Error: repeated variable definition</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="global-scope">4.2.4. Global Scope</h4> | 
 | <div class="paragraph"> | 
 | <p>The built-in functions are scoped in the global scope users declare global | 
 | variables in. | 
 | That is, a shader’s global scope, available for user-defined functions and | 
 | global variables, is the same as the scope containing the built-in | 
 | functions. | 
 | Function declarations (prototypes) cannot occur inside of functions; they | 
 | must be at global scope. | 
 | Hence it is not possible to hide a name with a function.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="shared-globals">4.2.5. Shared Globals</h4> | 
 | <div class="paragraph"> | 
 | <p>Shared globals are variables that can be accessed by multiple compilation | 
 | units. | 
 | In GLSL ES the only shared globals are uniforms. | 
 | Vertex shader outputs are not considered to be shared globals since they | 
 | must pass through the rasterization stage before they are used as input by | 
 | the fragment shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Shared globals share the same name space, and must be declared with the same | 
 | type and precision. | 
 | They will share the same storage. | 
 | Shared global arrays must have the same base type and the same explicit | 
 | size. | 
 | Scalars must have exactly the same precision, type name and type definition. | 
 | Structures must have the same name, sequence of type names, and type | 
 | definitions, and member names to be considered the same type. | 
 | This rule applies recursively for nested or embedded types.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="storage-qualifiers">4.3. Storage Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>Variable declarations may have at most one storage qualifier specified in | 
 | front of the type. | 
 | These are summarized as</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">Storage Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><none: default></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">local read/write memory, or an input parameter to a | 
 |                       function</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>const</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">a compile-time constant</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>in</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">linkage into a shader from a previous stage, variable | 
 |                       is copied in</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>out</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">linkage out of a shader to a subsequent stage, | 
 |                       variable is copied out</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uniform</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">value does not change across the primitive being | 
 |                       processed, uniforms form the linkage between a shader, | 
 |                       OpenGL ES, and the application</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>buffer</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">value is stored in a buffer object, and can be read or | 
 |                       written both by shader invocations and the OpenGL ES | 
 |                       API</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>shared</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">compute shader only; variable storage is shared across | 
 |                       all work items in a workgroup</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Some input and output qualified variables can be qualified with at most one | 
 | additional auxiliary storage qualifier:</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">Auxiliary Storage Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>centroid</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">centroid-based interpolation</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sample</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">per-sample interpolation</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>patch</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">per-tessellation-patch attributes</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Local variables can only use the <strong>const</strong> storage qualifier (or use no | 
 | storage qualifier).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that function parameters can use <strong>const</strong>, <strong>in</strong>, and <strong>out</strong> qualifiers, | 
 | but as <em>parameter qualifiers</em>. | 
 | Parameter qualifiers are discussed in | 
 | “<a href="#function-calling-conventions">Function Calling Conventions</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Function return types and structure members do not use storage qualifiers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Data types for communication from one run of a shader executable to its next | 
 | run (to communicate between fragments or between vertices) do not exist. | 
 | This would prevent parallel execution of the same shader executable on | 
 | multiple vertices or fragments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In declarations of global variables with no storage qualifier or with a | 
 | const qualifier, any initializer must be a constant expression. | 
 | Declarations of global variables with other storage qualifiers may not | 
 | contain initializers. | 
 | Global variables without storage qualifiers that are not initialized in | 
 | their declaration or by the application will not be initialized by | 
 | OpenGL ES, but rather will enter <em>main()</em> with undefined values.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="default-storage-qualifier">4.3.1. Default Storage Qualifier</h4> | 
 | <div class="paragraph"> | 
 | <p>If no qualifier is present on a global variable, then the variable has no | 
 | linkage to the application or shaders running on other pipeline stages. | 
 | For either global or local unqualified variables, the declaration will | 
 | appear to allocate memory associated with the processor it targets. | 
 | This variable will provide read/write access to this allocated memory.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="constant-qualifier">4.3.2. Constant Qualifier</h4> | 
 | <div class="paragraph"> | 
 | <p>Named compile-time constants | 
 | can be declared using | 
 | the <strong>const</strong> qualifier. | 
 | Any variables qualified as constant are read-only variables for that shader. | 
 | Declaring variables as constant allows more descriptive shaders than using | 
 | hard-wired numerical constants. | 
 | The <strong>const</strong> qualifier can be used with any of the non-void transparent basic | 
 | data types, as well as with structures and arrays of these. | 
 | It is an error to write to a <strong>const</strong> variable outside of its | 
 | declaration, so they must be initialized when declared. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">const</span> vec3 zAxis = vec3 (<span class="float">0</span><span class="float">.0</span>, <span class="float">0</span><span class="float">.0</span>, <span class="float">1</span><span class="float">.0</span>);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structure members may not be qualified with <strong>const</strong>. | 
 | Structure variables can be declared as <strong>const</strong>, and initialized with a | 
 | structure | 
 | constructor.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Initializers for <strong>const</strong> declarations | 
 | must be constant expressions, as defined in | 
 | “<a href="#constant-expressions">Constant Expressions</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="constant-expressions">4.3.3. Constant Expressions</h4> | 
 | <div class="paragraph"> | 
 | <p>A <em>constant expression</em> is one of</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A literal value (e.g. <strong>5</strong> or <strong>true</strong>).</p> | 
 | </li> | 
 | <li> | 
 | <p>A global or local variable qualified as <strong>const</strong> (i.e., not including | 
 | function parameters).</p> | 
 | </li> | 
 | <li> | 
 | <p>An expression formed by an operator on operands that are all constant | 
 | expressions, including getting an element of a constant array, or a | 
 | member of a constant structure, or components of a constant vector. | 
 | However, the lowest precedence operators of the sequence operator (<strong>,</strong>) | 
 | and the assignment operators (<strong>=</strong>, <strong>+=</strong>, <strong>…​</strong>) are not included in the | 
 | operators that can create a constant expression.</p> | 
 | </li> | 
 | <li> | 
 | <p>The <strong>length</strong>() method on a compile-time sized array, whether or not the | 
 | object itself is constant.</p> | 
 | </li> | 
 | <li> | 
 | <p>A constructor whose arguments are all constant expressions.</p> | 
 | </li> | 
 | <li> | 
 | <p>A built-in function call whose arguments are all constant expressions, | 
 | with the exception of the texture lookup functions. | 
 | This rule excludes functions with a <strong>void</strong> return or functions that have | 
 | an <strong>out</strong> parameter. | 
 | The built-in functions <strong>dFdx</strong>, <strong>dFdy</strong>, and <strong>fwidth</strong> must return 0 when | 
 | evaluated inside an initializer with an argument that is a constant | 
 | expression.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Function calls to user-defined functions (non-built-in functions) cannot be | 
 | used to form constant expressions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Scalar, vector, matrix, array and structure variables are constant | 
 | expressions if qualified as <strong>const</strong>. | 
 | Opaque types cannot be constant expressions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <em>constant integral expression</em> is a constant expression that evaluates to | 
 | a scalar signed or unsigned integer.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Constant expressions will be evaluated in an invariant way so as to create | 
 | the same value in multiple shaders when the same constant expressions appear | 
 | in those shaders. | 
 | See “<a href="#the-invariant-qualifier">The Invariant Qualifier</a>” for more details | 
 | on how to create invariant expressions and | 
 | “<a href="#precision-qualifiers">Precision Qualifiers</a>” for detail on how | 
 | expressions are evaluated.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Constant expressions respect the <strong>precise</strong> and <strong>invariant</strong> qualifiers but | 
 | will be always be evaluated in an invariant way, independent of the use of | 
 | such qualification, so as to create the same value in multiple shaders when | 
 | the same constant expressions appear in those shaders. | 
 | See “<a href="#the-invariant-qualifier">The Invariant Qualifier</a>” and | 
 | “<a href="#the-precise-qualifier">The Precise Qualifier</a>” for more details on how | 
 | to create invariant expressions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Constant | 
 | expressions may be evaluated by the compiler’s | 
 | host platform, and are therefore not required to compute the same value that | 
 | the same expression would evaluate to on the shader execution target. | 
 | However, the host must use the same or greater precision than the target | 
 | would use. | 
 | When the precision qualification cannot be determined, the expression is | 
 | evaluated at <strong>highp</strong>. | 
 | See “<a href="#default-precision-qualifiers">Default Precision Qualifiers</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="input-variables">4.3.4. Input Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>Shader input variables are declared with the <strong>in</strong> storage qualifier. | 
 | They form the input interface between previous stages of the OpenGL ES | 
 | pipeline and the declaring shader. | 
 | Input variables must be declared at global scope. | 
 | Values from the previous pipeline stage are copied into input variables at | 
 | the beginning of shader execution. | 
 | It is an error to write to a variable declared as an input.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Only the input variables that are | 
 | actually | 
 | read need to be written by the | 
 | previous stage; it is allowed to have superfluous declarations of input | 
 | variables.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>See “<a href="#built-in-variables">Built-In Variables</a>” for a list of the built-in | 
 | input names.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Vertex shader input variables (or attributes) receive per-vertex data. | 
 | It is an error to use auxiliary storage or interpolation qualifiers | 
 | on a vertex shader input. | 
 | The values copied in are established by the OpenGL ES API or through the use | 
 | of the layout identifier <strong>location</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error to declare a vertex shader input with, or that | 
 | contains, any of the following types:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A <a href="#booleans">boolean type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An <a href="#opaque-types">opaque type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An array</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example declarations in a vertex shader:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in vec4 position; | 
 | in vec3 normal; | 
 | in vec2 texCoord[<span class="integer">4</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is expected that graphics hardware will have a small number of fixed | 
 | vector locations for passing vertex inputs. | 
 | Therefore, the OpenGL ES Shading Language defines each non-matrix input variable as taking up | 
 | one such vector location. | 
 | There is an implementation-dependent limit on the number of locations that | 
 | can be used, and if this is exceeded it will cause a link-time error. | 
 | (Declared input variables that are not statically used do not count against | 
 | this limit.) A scalar input counts the same amount against this limit as a | 
 | <strong>vec4</strong>, so applications may want to consider packing groups of four | 
 | unrelated float inputs together into a vector to better utilize the | 
 | capabilities of the underlying hardware. | 
 | A matrix input will use up multiple locations. | 
 | The number of locations used will equal the number of columns in the matrix.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Tessellation control, evaluation, and geometry shader input variables get | 
 | the per-vertex values written out by output variables of the same names in | 
 | the previous active shader stage. | 
 | For these inputs, <strong>centroid</strong> and interpolation qualifiers are allowed, but | 
 | have no effect. | 
 | Since tessellation control, tessellation evaluation, and geometry shaders | 
 | operate on a set of vertices, each input variable (or input block, see | 
 | interface blocks below) needs to be declared as an array. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in <span class="predefined-type">float</span> foo[]; <span class="comment">// geometry shader input for vertex "out float foo"</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Each element of such an array corresponds to one vertex of the primitive | 
 | being processed. | 
 | Each array can optionally have a size declared. | 
 | For geometry shaders, the array size will be set by, (or if provided must be | 
 | consistent with) the input <strong>layout</strong> declaration(s) establishing the type of | 
 | input primitive, as described later in “<a href="#input-layout-qualifiers">Input | 
 | Layout Qualifiers</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some inputs and outputs are <em>arrayed</em>, meaning that for an interface between | 
 | two shader stages either the input or output declaration requires an extra | 
 | level of array indexing for the declarations to match. | 
 | For example, with the interface between a vertex shader and a geometry | 
 | shader, vertex shader output variables and geometry shader input variables | 
 | of the same name must have matching types, except that the geometry shader | 
 | will have one more array dimension than the vertex shader, to allow for | 
 | vertex indexing. | 
 | If such an arrayed interface variable is not declared with the necessary | 
 | additional input or output array dimension, a link-time error will result. | 
 | Geometry shader inputs, tessellation control shader inputs and outputs, and | 
 | tessellation evaluation inputs all have an additional level of arrayness | 
 | relative to other shader inputs and outputs. | 
 | These inputs and outputs are known as <em>per-vertex-arrayed</em> inputs and | 
 | outputs. | 
 | Component limits for arrayed interfaces (e.g. | 
 | <em>gl_MaxTessControlInputComponents</em>) are limits per vertex, not limits for | 
 | the entire interface.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For non-arrayed interfaces (meaning array dimensionally stays the same | 
 | between stages), it is a link-time error if the input variable is not | 
 | declared with the same type, including array dimensionality, as the matching | 
 | output variable.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The link-time type-matching rules apply to all declared input and output | 
 | variables, whether or not they are used.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Additionally, tessellation evaluation shaders support per-patch input | 
 | variables declared with the <strong>patch</strong> and <strong>in</strong> qualifiers. | 
 | Per-patch input variables are filled with the values of per-patch output | 
 | variables written by the tessellation control shader. | 
 | Per-patch inputs may be declared as one-dimensional arrays, but are not | 
 | indexed by vertex number. | 
 | Applying the <strong>patch</strong> qualifier to inputs can only be done in tessellation | 
 | evaluation shaders. | 
 | As with other input variables, per-patch inputs must be declared using the | 
 | same type and qualification as per-patch outputs from the previous | 
 | (tessellation control) shader stage. | 
 | It is a compile-time error to use <strong>patch</strong> with inputs in any other stage.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error to declare a tessellation control, tessellation | 
 | evaluation or geometry shader input with, or that contains, any of the | 
 | following types:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A <a href="#booleans">boolean type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An <a href="#opaque-types">opaque type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing an array</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing a structure</p> | 
 | </li> | 
 | <li> | 
 | <p>For per-vertex-arrayed variables:</p> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Per-vertex-arrayed arrays of arrays</p> | 
 | </li> | 
 | <li> | 
 | <p>Per-vertex-arrayed arrays of structures</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </li> | 
 | <li> | 
 | <p>For non-per-vertex-arrayed variables:</p> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>An array of arrays</p> | 
 | </li> | 
 | <li> | 
 | <p>An array of structures</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shader inputs get per-fragment values, typically interpolated from | 
 | a previous stage’s outputs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error to declare a fragment shader input with, or that | 
 | contains, any of the following types:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A <a href="#booleans">boolean type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An <a href="#opaque-types">opaque type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An array of arrays</p> | 
 | </li> | 
 | <li> | 
 | <p>An array of structures</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing an array</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing a structure</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shader inputs that are, or contain, integral | 
 | types must be | 
 | qualified with the interpolation qualifier <strong>flat</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment inputs are declared as in the following examples:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in vec3 normal; | 
 | centroid in vec2 TexCoord; | 
 | flat in vec3 myColor;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The fragment shader inputs form an interface with the last active shader in | 
 | the vertex processing pipeline. | 
 | For this interface, the last active shader stage output variables and | 
 | fragment shader input variables of the same name must match in type and | 
 | qualification, with a few exceptions: The storage qualifiers must, of | 
 | course, differ (one is <strong>in</strong> and one is <strong>out</strong>). | 
 | Also, | 
 | auxiliary qualification (e.g. <strong>centroid</strong>) may differ. | 
 | When | 
 | auxiliary qualifiers do not match, those provided in | 
 | the fragment shader supersede those provided in previous stages. | 
 | If any such qualifiers are completely missing in the fragment shaders, then | 
 | the default is used, rather than any qualifiers that may have been declared | 
 | in previous stages. | 
 | That is, what matters is what is declared in the fragment shaders, not what | 
 | is declared in shaders in previous stages.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When an interface between shader stages is formed using shaders from two | 
 | separate program objects, it is not possible to detect mismatches between | 
 | inputs and outputs when the programs are linked. | 
 | When there are mismatches between inputs and outputs on such interfaces, | 
 | attempting to use the two programs in the same program pipeline will result | 
 | in program pipeline validation failures, as described in section 7.4.1 | 
 | “Shader Interface Matching” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Shaders can ensure matches across such interfaces either by using input and | 
 | output layout qualifiers (sections “<a href="#input-layout-qualifiers">Input Layout | 
 | Qualifiers</a>” and “<a href="#output-layout-qualifiers">Output Layout | 
 | Qualifiers</a>”) or by using identical input and output declarations of | 
 | blocks or variables. | 
 | Complete rules for interface matching are found in section 7.4.1 “Shader | 
 | Interface Matching” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Compute shaders do not permit user-defined input variables and do not form a | 
 | formal interface with any other shader stage. | 
 | See “<a href="#compute-shader-special-variables">Compute Shader Special | 
 | Variables</a>” for a description of built-in compute shader input variables. | 
 | All other input to a compute shader is retrieved explicitly through image | 
 | loads, texture fetches, loads from uniforms or uniform buffers, or other | 
 | user supplied code.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="uniform-variables">4.3.5. Uniform Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>The <strong>uniform</strong> qualifier is used to declare global variables whose values are | 
 | the same across the entire primitive being processed. | 
 | All <strong>uniform</strong> variables are read-only. | 
 | Except for variables declared within a uniform block, all uniform variables | 
 | are initialized to 0 at link time and may be updated through the API.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example declarations are:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">uniform vec4 lightPosition;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>uniform</strong> qualifier can be used with any of the basic data types, or | 
 | when declaring a variable whose type is a structure, or an array of any of | 
 | these.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is an implementation-dependent limit on the amount of storage for | 
 | uniforms that can be used for each type of shader and if this is exceeded it | 
 | will cause a compile-time or link-time error. | 
 | Uniform variables that are declared but not | 
 | statically | 
 | used do not count against this limit. | 
 | The number of user-defined uniform variables and the number of built-in | 
 | uniform variables that are used within a shader are added together to | 
 | determine whether available uniform storage has been exceeded.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Uniforms in shaders all share a single global name space when linked into a | 
 | program or separable program. | 
 | Hence, the types, | 
 | precisions, | 
 | and any location specifiers of all statically used uniform variables with the | 
 | same name must match across all shaders that are linked into a single program. | 
 | However it is not required to repeat the | 
 | location specifier in all the linked shaders. | 
 | While this single uniform name space is cross stage, a uniform variable | 
 | name’s scope is per stage: If a uniform variable name is declared in one | 
 | stage (e.g. a vertex shader) but not in another (e.g. a fragment shader), | 
 | then that name is still available in the other stage for a different use.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A compile or link-time error is generated if any of the explicitly given or | 
 | compiler generated uniform locations is greater than the | 
 | implementation-defined maximum number of uniform locations minus one.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Unlike locations for inputs and outputs, uniform locations are logical | 
 | values, not register locations, and there is no concept of overlap. | 
 | For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">2</span>) uniform mat4 x; | 
 | layout(location = <span class="integer">3</span>) uniform mat4 y; <span class="comment">// No overlap with x</span> | 
 | layout(location = <span class="integer">2</span>) in mat4 x; | 
 | layout(location = <span class="integer">3</span>) in mat4 y; <span class="comment">// Error, locations conflict with x</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="output-variables">4.3.6. Output Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>Shader output variables are declared with the <strong>out</strong> storage qualifier. | 
 | They form the output interface between the declaring shader and the | 
 | subsequent stages of the OpenGL ES pipeline. | 
 | Output variables must be declared at global scope. | 
 | During shader execution they will behave as normal unqualified global | 
 | variables. | 
 | Their values are copied out to the subsequent pipeline stage on shader exit. | 
 | Only output variables that are read by the subsequent pipeline stage need to | 
 | be written; it is allowed to have superfluous declarations of output | 
 | variables.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is <em>not</em> an <strong>inout</strong> storage qualifier for declaring a single variable | 
 | name as both input and output to a shader. | 
 | Also, a variable cannot be declared with both the <strong>in</strong> and the <strong>out</strong> | 
 | qualifiers, this will result in a compile-time or link-time error. | 
 | Output variables must be declared with different names than input variables. | 
 | However, nesting an input or output inside an interface block with an | 
 | instance name allows the same names with one referenced through a block | 
 | instance name.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Vertex, tessellation evaluation, and geometry output variables output | 
 | per-vertex data and are declared using the <strong>out</strong> storage qualifier. | 
 | Applying <strong>patch</strong> to an output can only be done in a tessellation control | 
 | shader. | 
 | It is a compile-time error to use <strong>patch</strong> on outputs in any other stage.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error to declare a vertex, tessellation evaluation, | 
 | tessellation control, or geometry shader output with, or that contains, any | 
 | of the following types:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A <a href="#booleans">boolean type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An <a href="#opaque-types">opaque type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing an array</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure containing a structure</p> | 
 | </li> | 
 | <li> | 
 | <p>For per-vertex-arrayed variables (applies to tessellation control, | 
 | tessellation evaluation and geometry shaders):</p> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Per-vertex-arrayed arrays of arrays</p> | 
 | </li> | 
 | <li> | 
 | <p>Per-vertex-arrayed arrays of structures</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </li> | 
 | <li> | 
 | <p>For non-per-vertex-arrayed variables:</p> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>An array of arrays</p> | 
 | </li> | 
 | <li> | 
 | <p>An array of structures</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Vertex shader outputs may be qualified with the interpolation qualifier | 
 | <strong>flat</strong><sup>1</sup>.</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">1</dt> | 
 | <dd> | 
 | <p>Unlike previous versions of the OpenGL ES Shading Language, there is no requirement for | 
 | outputs containing integers to be qualified as <strong>flat</strong>, since the vertex | 
 | shader may interface with the tessellation control shader. | 
 | However, in all cases, the qualifier must match across interfaces.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Individual outputs are declared as in the following examples:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out vec3 normal; | 
 | centroid out vec2 TexCoord; | 
 | invariant centroid out vec4 Color; | 
 | flat out vec3 myColor; | 
 | sample out vec4 perSampleColor;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These can also appear in interface blocks, as described in | 
 | “<a href="#interface-blocks">Interface Blocks</a>”. | 
 | Interface blocks allow simpler addition of arrays to the interface from | 
 | vertex to geometry shader. | 
 | They also allow a fragment shader to have the same input interface as a | 
 | geometry shader for a given vertex shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Tessellation control shader output variables are used to output | 
 | per-vertex and per-patch data. | 
 | Per-vertex output variables are arrayed (see <em>arrayed</em> under | 
 | “<a href="#input-variables">Input Variables</a>”) and declared using the <strong>out</strong> | 
 | qualifier without the <strong>patch</strong> qualifier. | 
 | Per-patch output variables are declared using the <strong>patch</strong> and <strong>out</strong> | 
 | qualifiers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Since tessellation control shaders produce an arrayed primitive comprising | 
 | multiple vertices, each per-vertex output variable (or output block, see | 
 | interface blocks below) needs to be declared as an array. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out <span class="predefined-type">float</span> foo[]; <span class="comment">// feeds next stage input "in float foo[]"</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Each element of such an array corresponds to one vertex of the primitive | 
 | being produced. | 
 | Each array can optionally have a size declared. | 
 | The array size will be set by (or if provided must be consistent with) the | 
 | output layout declaration(s) establishing the number of vertices in the | 
 | output patch, as described later in | 
 | “<a href="#tessellation-control-outputs">Tessellation Control Outputs</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Each tessellation control shader invocation has a corresponding output patch | 
 | vertex, and may assign values to per-vertex outputs only if they belong to | 
 | that corresponding vertex. | 
 | If a per-vertex output variable is used as an l-value, it is a compile-time | 
 | or link-time error if the expression indicating the vertex index is not the | 
 | identifier <em>gl_InvocationID</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The order of execution of a tessellation control shader invocation relative | 
 | to the other invocations for the same input patch is undefined unless the | 
 | built-in function <strong>barrier</strong>() is used. | 
 | This provides some control over relative execution order. | 
 | When a shader invocation calls <strong>barrier</strong>(), its execution pauses until all | 
 | other invocations have reached the same point of execution. | 
 | Output variable assignments performed by any invocation executed prior to | 
 | calling <strong>barrier</strong>() will be visible to any other invocation after the call | 
 | to <strong>barrier</strong>() returns.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Because tessellation control shader invocations execute in undefined order | 
 | between barriers, the values of per-vertex or per-patch output variables | 
 | will sometimes be undefined. | 
 | Consider the beginning and end of shader execution and each call to | 
 | <strong>barrier</strong>() as synchronization points. | 
 | The value of an output variable will be undefined in any of the three | 
 | following cases:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>At the beginning of execution.</p> | 
 | </li> | 
 | <li> | 
 | <p>At each synchronization point, unless</p> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>the value was well-defined after the previous synchronization point and | 
 | was not written by any invocation since, or</p> | 
 | </li> | 
 | <li> | 
 | <p>the value was written by exactly one shader invocation since the previous | 
 | synchronization point, or</p> | 
 | </li> | 
 | <li> | 
 | <p>the value was written by multiple shader invocations since the previous | 
 | synchronization point, and the last write performed by all such | 
 | invocations wrote the same value.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </li> | 
 | <li> | 
 | <p>When read by a shader invocation, if</p> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>the value was undefined at the previous synchronization point and has not | 
 | been written by the same shader invocation since, or</p> | 
 | </li> | 
 | <li> | 
 | <p>the output variable is written to by any other shader invocation between | 
 | the previous and next synchronization points, even if that assignment | 
 | occurs in code following the read.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment outputs output per-fragment data and are declared using the <strong>out</strong> | 
 | storage qualifier. | 
 | It is an error to use auxiliary storage qualifiers or | 
 | interpolation qualifiers in a fragment shader output declaration. | 
 | It is a compile-time error to declare a fragment shader output with, or that | 
 | contains, any of the following types:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>A <a href="#booleans">boolean type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>An <a href="#opaque-types">opaque type</a></p> | 
 | </li> | 
 | <li> | 
 | <p>A matrix type</p> | 
 | </li> | 
 | <li> | 
 | <p>A structure</p> | 
 | </li> | 
 | <li> | 
 | <p>An array of arrays</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shader outputs declared as arrays may only be indexed by a constant | 
 | integral expression.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment outputs are declared as in the following examples:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out vec4 FragmentColor; | 
 | out uint Luminosity;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Compute shaders have no built-in output variables, do not support | 
 | user-defined output variables and do not form a formal interface with any | 
 | other shader stage. | 
 | All outputs from a compute shader take the form of the side effects such as | 
 | image stores and operations on atomic counters.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="buffer-variables">4.3.7. Buffer Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>The <strong>buffer</strong> qualifier is used to declare global variables whose values are | 
 | stored in the data store of a buffer object bound through the OpenGL ES API. | 
 | Buffer variables can be read and written, with the underlying storage shared | 
 | among all active shader invocations. | 
 | Buffer variable memory reads and writes within a single shader invocation | 
 | are processed in order. | 
 | However, the order of reads and writes performed in one invocation relative | 
 | to those performed by another invocation is largely undefined. | 
 | Buffer variables may be qualified with memory qualifiers affecting how the | 
 | underlying memory is accessed, as described in “<a href="#memory-qualifiers">Memory | 
 | Qualifiers</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>buffer</strong> qualifier can be used to declare interface blocks (see | 
 | “<a href="#interface-blocks">Interface Blocks</a>”), which are then referred to as | 
 | shader storage blocks. | 
 | It is a compile-time error to declare buffer variables outside a block. | 
 | Buffer variables cannot have initializers.</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>The terms <em>shader storage buffer (object)</em>, and <em>shader storage block</em> are | 
 | often used interchangeably. | 
 | The former generally refers to the underlying storage whereas the latter | 
 | refers only to the interface definition in the shader. | 
 | Similarly for <em>uniform buffer objects</em> and _uniform blocks.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// use buffer to create a buffer block (shader storage block)</span> | 
 | buffer BufferName { <span class="comment">// externally visible name of buffer</span> | 
 |     <span class="predefined-type">int</span> count;      <span class="comment">// typed, shared memory...</span> | 
 |     ...             <span class="comment">// ...</span> | 
 |     vec4 v[];       <span class="comment">// last member may be an array that is not sized</span> | 
 |                     <span class="comment">// until after link time (dynamically sized)</span> | 
 | } Name;             <span class="comment">// name of block within the shader</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There are implementation-dependent limits on the number of shader storage | 
 | blocks used for each type of shader, the combined number of shader storage | 
 | blocks used for a program, and the amount of storage required by each | 
 | individual shader storage block. | 
 | If any of these limits are exceeded, it will cause a compile-time or | 
 | link-time error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If multiple shaders are linked together, then they will share a single | 
 | global buffer variable name space. | 
 | Hence, the types of all declared buffer variables with the same name must | 
 | match across all shaders that are linked into a single program.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Precision qualifiers for such variables need not match.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="shared-variables">4.3.8. Shared Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>The <strong>shared</strong> qualifier is used to declare global variables that have storage | 
 | shared between all work items in a compute shader workgroup. | 
 | Variables declared as <strong>shared</strong> may only be used in compute shaders (see | 
 | “<a href="#compute-processor">Compute Processor</a>”). | 
 | Any other declaration of a <strong>shared</strong> variable is an error. | 
 | Shared variables are implicitly coherent (see | 
 | “<a href="#memory-qualifiers">Memory Qualifiers</a>”).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Variables declared as <strong>shared</strong> may not have initializers and their contents | 
 | are undefined at the beginning of shader execution. | 
 | Any data written to <strong>shared</strong> variables will be visible to other work items | 
 | (executing the same shader) within the same workgroup.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In the absence of synchronization, the order of reads and writes to the same | 
 | <strong>shared</strong> variable by different invocations of a shader is not defined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In order to achieve ordering with respect to reads and writes to <strong>shared</strong> | 
 | variables, control flow barriers must be employed using the <strong>barrier</strong>() function | 
 | (see “<a href="#shader-invocation-control-functions">Shader Invocation Control | 
 | Functions</a>”).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is a limit to the total size of all variables declared as <strong>shared</strong> in a | 
 | single program. | 
 | This limit, expressed in units of basic machine units may be determined by | 
 | using the OpenGL ES API to query the value of | 
 | MAX_COMPUTE_SHARED_MEMORY_SIZE.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="interface-blocks">4.3.9. Interface Blocks</h4> | 
 | <div class="paragraph"> | 
 | <p>Input, output, uniform, and buffer variable declarations can be grouped into | 
 | named interface blocks to provide coarser granularity backing than is | 
 | achievable with individual declarations. | 
 | They can have an optional instance name, used in the shader to reference | 
 | their members. | 
 | An output block of one programmable stage is backed by a corresponding input | 
 | block in the subsequent programmable stage. | 
 | A <em>uniform block</em> is backed by the application with a buffer object. | 
 | A block of buffer variables, called a <em>shader storage block</em>, is also backed | 
 | by the application with a buffer object. | 
 | It is a compile-time error to have an input block in a vertex shader or an | 
 | output block in a fragment shader. | 
 | These uses are reserved for future use.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An interface block is started by an <strong>in</strong>, <strong>out</strong>, <strong>uniform</strong>, or <strong>buffer</strong> | 
 | keyword, followed by a block name, followed by an open curly brace (<strong>{</strong>) as | 
 | follows:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>interface-block</em> : </dt> | 
 | <dd> | 
 | <p><em>layout-qualifier<sub>opt</sub></em> <em>interface-qualifier</em> <em>block-name</em> <strong>{</strong> | 
 | <em>member-list</em> <strong>}</strong> <em>instance-name<sub>opt</sub></em> <strong>;</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>interface-qualifier</em> : </dt> | 
 | <dd> | 
 | <p><strong>in</strong><br> | 
 | <strong>out</strong><br> | 
 | <strong>patch</strong> <strong>in</strong> // Note: Qualifiers can be in any order.<br> | 
 | <strong>patch</strong> <strong>out</strong><br> | 
 | <strong>uniform</strong><br> | 
 | <strong>buffer</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>member-list</em> : </dt> | 
 | <dd> | 
 | <p><em>member-declaration</em><br> | 
 | <em>member-declaration</em> <em>member-list</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>member-declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>layout-qualifier<sub>opt</sub></em> <em>qualifiers<sub>opt</sub></em> <em>type</em> <em>declarators</em> <strong>;</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>instance-name</em> : </dt> | 
 | <dd> | 
 | <p><em>identifier</em><br> | 
 | <em>identifier</em> <strong>[</strong> <strong>]</strong><br> | 
 | <em>identifier</em> <strong>[</strong> <em>constant-integral-expression</em> <strong>]</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Each of the above elements is discussed below, with the exception of layout | 
 | qualifiers (<em>layout-qualifier</em>), which are defined in the next section.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>First, an example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">uniform Transform { | 
 |     mat4 ModelViewMatrix; | 
 |     mat4 ModelViewProjectionMatrix; | 
 |     uniform mat3 NormalMatrix;      <span class="comment">// allowed restatement of qualifier</span> | 
 |     <span class="predefined-type">float</span> Deformation; | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The above establishes a uniform block named “Transform” with four uniforms | 
 | grouped inside it.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Types and declarators are the same as for other input, output, uniform, and | 
 | buffer variable declarations outside blocks, with these exceptions:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Opaque types are not allowed</p> | 
 | </li> | 
 | <li> | 
 | <p>Structure definitions cannot be nested inside a block</p> | 
 | </li> | 
 | <li> | 
 | <p>Arrays of arrays of blocks are not allowed, except for the case in the | 
 | tessellation pipe where the declaration is a per-vertex-array of arrays | 
 | of blocks.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If no optional qualifier is used in a member-declaration, the qualification | 
 | of the member includes all <strong>in</strong>, <strong>out</strong>, <strong>patch</strong>, <strong>uniform</strong>, or <strong>buffer</strong> as | 
 | determined by <em>interface-qualifier</em>. | 
 | If optional qualifiers are used, they can include interpolation qualifiers, | 
 | auxiliary storage qualifiers, | 
 | precision qualifiers, | 
 | and storage qualifiers and they must declare | 
 | an input, output, or uniform member consistent with the interface qualifier | 
 | of the block: Input variables, output variables, uniform variables, and | 
 | <strong>buffer</strong> members can only be in <strong>in</strong> blocks, <strong>out</strong> blocks, <strong>uniform</strong> blocks, | 
 | and shader storage blocks, respectively.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Repeating the <strong>in</strong>, <strong>out</strong>, <strong>patch</strong>, <strong>uniform</strong>, or <strong>buffer</strong> interface | 
 | qualifier for a member’s storage qualifier is optional. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in Material { | 
 |     smooth in vec4 Color1; <span class="comment">// legal, input inside in block</span> | 
 |     smooth vec4 Color2;    <span class="comment">// legal, 'in' inherited from 'in Material'</span> | 
 |     vec2 TexCoord;         <span class="comment">// legal, TexCoord is an input</span> | 
 |     uniform <span class="predefined-type">float</span> Atten;   <span class="comment">// illegal, mismatched storage qualifier</span> | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <em>shader interface</em> is defined to be one of these:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>All the uniform variables and uniform blocks declared in a program. | 
 | This spans all compilation units linked together within one program.</p> | 
 | </li> | 
 | <li> | 
 | <p>All the <strong>buffer</strong> blocks declared in a program.</p> | 
 | </li> | 
 | <li> | 
 | <p>The boundary between adjacent programmable pipeline stages: This spans | 
 | all the outputs declared in all compilation units of the first stage and | 
 | all the inputs declared in all compilation units of the second stage. | 
 | Note that for the purposes of this definition, the fragment shader and | 
 | the preceding shader are considered to have a shared boundary even | 
 | though in practice, all values passed to the fragment shader first pass | 
 | through the rasterizer and interpolator.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The block name (<em>block-name</em>) is used to match within shader interfaces: an | 
 | output block of one pipeline stage will be matched to an input block with | 
 | the same name in the subsequent pipeline stage. | 
 | For uniform or shader storage blocks, the application uses the block name to | 
 | identify the block. | 
 | Block names have no other use within a shader beyond interface matching; it | 
 | is an error | 
 | to use a block name at global scope for anything other than as a | 
 | block name (e.g. use of a block name for a global variable name or function | 
 | name is currently reserved). | 
 | It is a compile-time error to use the same block name for more than one | 
 | block declaration in the same shader interface (as defined above) within one | 
 | shader, even if the block contents are identical.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Matched block names within a shader interface (as defined above) must match | 
 | in terms of having the same number of declarations with the same sequence of | 
 | types and the same sequence of member names, as well as having matching | 
 | member-wise layout qualification | 
 | as defined in “<a href="#matching-of-qualifiers">Matching of Qualifiers</a>”. | 
 | Matched uniform or shader storage block names (but not input or output block | 
 | names) must also either all be lacking an instance name or all having an | 
 | instance name, putting their members at the same scoping level. | 
 | When instance names are present on matched block names, it is allowed for | 
 | the instance names to differ; they need not match for the blocks to match. | 
 | Furthermore, if a matching block is declared as an array, then the array | 
 | sizes must also match (or follow array matching rules for the shader | 
 | interface between consecutive shader stages). | 
 | Any mismatch will generate a link-time error. | 
 | A block name is allowed to have different definitions in different shader | 
 | interfaces within the same shader, allowing, for example, an input block and | 
 | output block to have the same name.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an instance name (<em>instance-name</em>) is not used, the names declared inside | 
 | the block are scoped at the global level and accessed as if they were | 
 | declared outside the block. | 
 | If an instance name (<em>instance-name</em>) is used, then it puts all the members | 
 | inside a scope within its own name space, accessed with the field selector | 
 | (<strong>.</strong>) operator (analogously to structures). | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in Light { | 
 |     vec4 LightPos; | 
 |     vec3 LightColor; | 
 | }; | 
 | in ColoredTexture { | 
 |     vec4 Color; | 
 |     vec2 TexCoord; | 
 | } Material;           <span class="comment">// instance name</span> | 
 | vec3 Color;           <span class="comment">// different Color than Material.Color</span> | 
 | vec4 LightPos;        <span class="comment">// illegal, already defined</span> | 
 | ... | 
 | ... = LightPos;       <span class="comment">// accessing LightPos</span> | 
 | ... = Material.Color; <span class="comment">// accessing Color in ColoredTexture block</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Outside the shading language (i.e., in the API), members are similarly | 
 | identified except the block name is always used in place of the instance | 
 | name (API accesses are to shader interfaces, not to shaders). | 
 | If there is no instance name, then the API does not use the block name to | 
 | access a member, just the member name.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within a shader interface, all declarations of the same global name must be | 
 | for the same object and must match in type and in whether they declare a | 
 | variable or member of a block with no instance name. | 
 | The API also needs this name to uniquely identify an object in the shader | 
 | interface. | 
 | It is a link-time error if any particular shader interface contains</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>two different blocks, each having no instance name, and each having a | 
 | member of the same name, or</p> | 
 | </li> | 
 | <li> | 
 | <p>a variable outside a block, and a block with no instance name, where the | 
 | variable has the same name as a member in the block.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out Vertex { | 
 |     vec4 Position;  <span class="comment">// API transform/feedback will use "Vertex.Position"</span> | 
 |     vec2 Texture; | 
 | } Coords;           <span class="comment">// shader will use "Coords.Position"</span> | 
 | out Vertex2 { | 
 |     vec4 Color;     <span class="comment">// API will use "Color"</span> | 
 |     <span class="predefined-type">float</span> Color2; | 
 | }; | 
 |  | 
 | <span class="comment">// in same program as Vertex2 above:</span> | 
 | out Vertex3 { | 
 |     <span class="predefined-type">float</span> Intensity; | 
 |     vec4 Color;     <span class="comment">// ERROR, name collision with Color in Vertex2</span> | 
 | }; | 
 | <span class="predefined-type">float</span> Color2;       <span class="comment">// ERROR, collides with Color2 in Vertex2</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For blocks declared as arrays, the array index must also be included when | 
 | accessing members, as in this example</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">uniform Transform { <span class="comment">// API uses "Transform[2]" to refer to instance 2</span> | 
 |     mat4 ModelViewMatrix; | 
 |     mat4 ModelViewProjectionMatrix; | 
 |     <span class="predefined-type">float</span> Deformation; | 
 | } transforms[<span class="integer">4</span>]; | 
 | ... | 
 | ... = transforms[<span class="integer">2</span>].ModelViewMatrix; <span class="comment">// shader access of instance 2</span> | 
 | <span class="comment">// API uses "Transform.ModelViewMatrix" to query an offset or other query</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For uniform or shader storage blocks declared as an array, each individual | 
 | array element corresponds to a separate buffer object bind range, backing | 
 | one instance of the block. | 
 | As the array size indicates the number of buffer objects needed, uniform and | 
 | shader storage block array declarations must specify an array size. | 
 | All indices used to index a shader storage block array must be constant | 
 | integral expressions. | 
 | A uniform block array can only be indexed with a dynamically uniform | 
 | integral expression, otherwise results are undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When using OpenGL ES API entry points to identify the name of an individual | 
 | block in an array of blocks, the name string may include an array index | 
 | (e.g. <em>Transform[2]</em>). | 
 | When using OpenGL ES API entry points to refer to offsets or other | 
 | characteristics of a block member, an array index must not be specified | 
 | (e.g. <em>Transform.ModelViewMatrix</em>). | 
 | See section 7.3.1 “Program Interfaces” of the <a href="#references">OpenGL ES Specification</a> for | 
 | details.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Tessellation control, tessellation evaluation and geometry shader input | 
 | blocks must be declared as arrays and follow the array declaration and | 
 | linking rules for all shader inputs for the respective stages. | 
 | All other input and output block arrays must specify an array size.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There are implementation-dependent limits on the number of uniform blocks | 
 | and the number of shader storage blocks that can be used per stage. | 
 | If either limit is exceeded, it will cause a link-time error.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="layout-qualifiers">4.4. Layout Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifiers can appear in several forms of declaration. | 
 | They can appear as part of an interface block definition or block member, as | 
 | shown in the grammar in the previous section. | 
 | They can also appear with just an <em>interface-qualifier</em> to establish layouts | 
 | of other declarations made with that qualifier:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="paragraph"> | 
 | <p><em>layout-qualifier</em> <em>interface-qualifier</em> <strong>;</strong></p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Or, they can appear with an individual variable declared with an interface | 
 | qualifier:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="paragraph"> | 
 | <p><em>layout-qualifier</em> <em>interface-qualifier</em> <em>declaration</em> <strong>;</strong></p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Declarations of layouts can only be made at global scope or block members, | 
 | and only where indicated in the following subsections; their details are | 
 | specific to what the interface qualifier is, and are discussed individually.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <em>layout-qualifier</em> expands to:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier</em> : </dt> | 
 | <dd> | 
 | <p><strong>layout</strong> <strong>(</strong> <em>layout-qualifier-id-list</em> <strong>)</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>layout-qualifier-id-list</em> : </dt> | 
 | <dd> | 
 | <p><em>layout-qualifier-id</em><br> | 
 | <em>layout-qualifier-id</em> <strong>,</strong> <em>layout-qualifier-id-list</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><em>layout-qualifier-name</em><br> | 
 | <em>layout-qualifier-name</em> <strong>=</strong> <em>layout-qualifier-value</em><br> | 
 | <strong>shared</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-value</em> : </dt> | 
 | <dd> | 
 | <p><em>integer-constant</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The tokens used for <em>layout-qualifier-name</em> are identifiers, not keywords, | 
 | however, the <strong>shared</strong> keyword is allowed as a <em>layout-qualifier-id</em>. | 
 | Generally, they can be listed in any order. | 
 | Order-dependent meanings exist only if explicitly called out below. | 
 | As for other identifiers, they are case sensitive.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The set of allowed layout qualifiers depends on the shader, the interface | 
 | and the variable type as specified in the following sections. | 
 | For example, a sampler in the default uniform block in a fragment shader can | 
 | have <strong>location</strong> and <strong>binding</strong> layout qualifiers but no others. | 
 | Invalid use of layout qualifiers is an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following table summarizes the use of layout qualifiers. | 
 | It shows for each one what kinds of declarations it may be applied to. | 
 | These are all discussed in detail in the following sections.</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.667%;"> | 
 | </colgroup> | 
 | <thead> | 
 | <tr> | 
 | <th class="tableblock halign-left valign-top">Layout Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Qualifier Only</th> | 
 | <th class="tableblock halign-left valign-top">Individual Variable</th> | 
 | <th class="tableblock halign-left valign-top">Block</th> | 
 | <th class="tableblock halign-left valign-top">Block Member</th> | 
 | <th class="tableblock halign-left valign-top">Allowed Interfaces</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>shared</strong><br> | 
 |   <strong>packed</strong><br> | 
 |   <strong>std140</strong><br> | 
 |   <strong>std430</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top" rowspan="4"><p class="tableblock"><strong>uniform</strong> / <strong>buffer</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>row_major</strong><br> | 
 |   <strong>column_major</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>binding</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">opaque types only</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>offset</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">atomic counters only</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>location</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uniform</strong> / <strong>buffer</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>location</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X<sup>1</sup></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">all <strong>in</strong> / <strong>out</strong>, except for compute</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>triangles</strong><br> | 
 |   <strong>quads</strong><br> | 
 |   <strong>isolines</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">tessellation evaluation <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>equal_spacing</strong><br> | 
 |   <strong>fractional_even_spacing</strong><br> | 
 |   <strong>fractional_odd_spacing</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">tessellation evaluation <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>cw</strong><br> | 
 |   <strong>ccw</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">tessellation evaluation <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>point_mode</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">tessellation evaluation <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>points</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">geometry <strong>in</strong>/<strong>out</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">[ <strong>points</strong> ]<br> | 
 |   <strong>lines</strong><br> | 
 |   <strong>lines_adjacency</strong><br> | 
 |   <strong>triangles</strong><br> | 
 |   <strong>triangles_adjacency</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">geometry <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>invocations</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">geometry <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>early_fragment_tests</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">fragment <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>local_size_x</strong> =<br> | 
 |   <strong>local_size_y</strong> =<br> | 
 |   <strong>local_size_z</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">compute <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>vertices</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">tessellation control <strong>out</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">[ <strong>points</strong> ]<br> | 
 |   <strong>line_strip</strong><br> | 
 |   <strong>triangle_strip</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">geometry <strong>out</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>max_vertices</strong> =</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">geometry <strong>out</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>rgba32f</strong><br> | 
 |   <strong>rgba16f</strong><br> | 
 |   <strong>r32f</strong><br> | 
 |   <strong>rgba8</strong><br> | 
 |   <strong>rgba8_snorm</strong><br> | 
 |   <strong>rgba32i</strong><br> | 
 |   <strong>rgba16i</strong><br> | 
 |   <strong>rgba8i</strong><br> | 
 |   <strong>r32i</strong><br> | 
 |   <strong>rgba32ui</strong><br> | 
 |   <strong>rgba16ui</strong><br> | 
 |   <strong>rgba8ui</strong><br> | 
 |   <strong>r32ui</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">image types only</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>uniform</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_multiply</strong><br> | 
 |   <strong>blend_support_screen</strong><br> | 
 |   <strong>blend_support_overlay</strong><br> | 
 |   <strong>blend_support_darken</strong><br> | 
 |   <strong>blend_support_lighten</strong><br> | 
 |   <strong>blend_support_colordodge blend_support_colorburn</strong><br> | 
 |   <strong>blend_support_hardlight</strong><br> | 
 |   <strong>blend_support_softlight</strong><br> | 
 |   <strong>blend_support_difference</strong><br> | 
 |   <strong>blend_support_exclusion</strong><br> | 
 |   <strong>blend_support_hsl_hue</strong><br> | 
 |   <strong>blend_support_hsl_saturation</strong><br> | 
 |   <strong>blend_support_hsl_color blend_support_hsl_luminosity</strong><br> | 
 |   <strong>blend_support_all_equations</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">X</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">fragment <strong>out</strong></p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">1</dt> | 
 | <dd> | 
 | <p>Location qualifiers are not allowed for members of an arrayed block, | 
 | except for per-vertex-arrays (see “<a href="#interface-blocks">Interface | 
 | Blocks</a>”).</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="input-layout-qualifiers">4.4.1. Input Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifiers specific to a particular shader language are discussed in | 
 | separate sections below.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All shaders except compute shaders allow <strong>location</strong> layout qualifiers on | 
 | input variable declarations, input block declarations, and input block | 
 | member declarations.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>location</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">3</span>) in vec4 normal;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that the shader input <em>normal</em> is assigned to vector location | 
 | number | 
 | 3. | 
 | For vertex shader inputs, the location specifies the number of the | 
 | vertex attribute from which input values are taken. | 
 | For inputs of all other shader types, the location specifies a vector number | 
 | that can be used to match against outputs from a previous shader stage, even | 
 | if that shader is in a different program object.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following language describes how many locations are consumed by a given | 
 | type. | 
 | However, geometry shader inputs, tessellation control shader inputs and | 
 | outputs, and tessellation evaluation inputs all have an additional level of | 
 | arrayness relative to other shader inputs and outputs. | 
 | This outer array level is removed from the type before considering how many | 
 | locations the type consumes.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a shader input is any scalar or vector type, it will consume a single | 
 | location.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared input (after potentially removing an outer array level as | 
 | just described above) is an array of size <em>n</em> and each of the elements takes | 
 | <em>m</em> locations, it will be assigned <em>m</em> * <em>n</em> consecutive locations starting | 
 | with the location specified. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">6</span>) in vec4 colors[<span class="integer">3</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that the shader input <em>colors</em> is assigned to vector location | 
 | numbers 6, 7, and 8.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared input is an <em>n</em> × <em>m</em> | 
 | matrix, it will be assigned multiple locations starting with the location | 
 | specified. | 
 | The number of locations assigned for each matrix will be the same as for an | 
 | <em>n</em>-element array of <em>m</em>-component vectors. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">9</span>) in mat4 transforms[<span class="integer">2</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that shader input <em>transforms</em> is assigned to vector | 
 | locations 9-16, with <em>transforms[0]</em> being assigned to locations 9-12, and | 
 | <em>transforms[1]</em> being assigned to locations 13-16.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared input is a structure or block, its members will be assigned | 
 | consecutive locations in their order of declaration, with the first member | 
 | assigned the location provided in the layout qualifier. | 
 | For a structure, this process applies to the entire structure. | 
 | It is a compile-time error to use a <strong>location</strong> qualifier on a member of a | 
 | structure. | 
 | For a block, this process applies to the entire block, or until the first | 
 | member is reached that has a <strong>location</strong> layout qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When a block member is declared with a <strong>location</strong> qualifier, its location | 
 | comes from that qualifier; the member’s <strong>location</strong> qualifier overrides the | 
 | block-level declaration. | 
 | Subsequent members are again assigned consecutive locations, based on the | 
 | newest location, until the next member declared with a <strong>location</strong> qualifier. | 
 | The values used for locations do not have to be declared in increasing | 
 | order.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a block has no block-level <strong>location</strong> layout qualifier, it is required | 
 | that either all or none of its members have a <strong>location</strong> layout qualifier, | 
 | or a compile-time error results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an input is declared as an array of blocks, excluding per-vertex-arrays | 
 | as required for tessellation, it is an error to declare a member of the | 
 | block with a <strong>location</strong> qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The locations consumed by block and structure members are determined by | 
 | applying the rules above recursively as though the structure member were | 
 | declared as an input variable of the same type. | 
 | For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">3</span>) in <span class="keyword">struct</span> S | 
 | { | 
 |     vec3 a;                      <span class="comment">// gets location 3</span> | 
 |     mat2 b;                      <span class="comment">// gets locations 4 and 5</span> | 
 |     vec4 c[<span class="integer">2</span>];                   <span class="comment">// gets locations 6 and 7</span> | 
 |     layout(location = <span class="integer">8</span>) vec2 A; <span class="comment">// ERROR, can't use on struct member</span> | 
 | } s; | 
 | layout(location = <span class="integer">4</span>) in block | 
 | { | 
 |     vec4 d;                      <span class="comment">// gets location 4</span> | 
 |     vec4 e;                      <span class="comment">// gets location 5</span> | 
 |     layout(location = <span class="integer">7</span>) vec4 f; <span class="comment">// gets location 7</span> | 
 |     vec4 g;                      <span class="comment">// gets location 8</span> | 
 |     layout(location = <span class="integer">1</span>) vec4 h; <span class="comment">// gets location 1</span> | 
 |     vec4 i;                      <span class="comment">// gets location 2</span> | 
 |     vec4 j;                      <span class="comment">// gets location 3</span> | 
 |     vec4 k;                      <span class="comment">// ERROR, location 4 already used</span> | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The number of input locations available to a shader is limited. | 
 | For vertex shaders, the limit is the advertised number of vertex attributes. | 
 | For all other shaders, the limit is implementation-dependent and must be no | 
 | less than one fourth of the advertised maximum input component count.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A program will fail to link if any attached shader uses a location greater | 
 | than or equal to the number of supported locations, unless device-dependent | 
 | optimizations are able to make the program fit within available hardware | 
 | resources.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A program will fail to link if explicit location assignments leave the | 
 | linker unable to find space for other variables without explicit | 
 | assignments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For the purposes of determining if a non-vertex input matches an output from | 
 | a previous shader stage, the <strong>location</strong> layout qualifier (if any) must | 
 | match.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a vertex shader input variable with no location assigned in the shader | 
 | text has a location specified through the OpenGL ES API, the API-assigned | 
 | location will be used. | 
 | Otherwise, such variables will be assigned a location by the linker. | 
 | See section 11.1.1 “Vertex Attributes” of the <a href="#references">OpenGL ES Specification</a> for | 
 | more details.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is an error if more than one input or element of a matrix input is bound | 
 | to the same location.</p> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-evaluation-inputs">Tessellation Evaluation Inputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Additional input layout qualifier identifiers allowed for tessellation | 
 | evaluation shaders are described below.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><em>primitive_mode</em><br> | 
 | <em>vertex_spacing</em><br> | 
 | <em>ordering</em><br> | 
 | <em>point_mode</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>primitive-mode</strong> is used to specify a tessellation primitive mode to be | 
 | used by the tessellation primitive generator.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>primitive-mode</em>: </dt> | 
 | <dd> | 
 | <p><strong>triangles</strong><br> | 
 | <strong>quads</strong><br> | 
 | <strong>isolines</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If present, the <em>primitive-mode</em> specifies that the tessellation primitive | 
 | generator should subdivide a triangle into smaller triangles, a quad into | 
 | triangles, or a quad into a collection of lines, respectively.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A second group of layout identifiers, <em>vertex spacing</em>, is used to specify | 
 | the spacing used by the tessellation primitive generator when subdividing an | 
 | edge.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>vertex-spacing</em>: </dt> | 
 | <dd> | 
 | <p><strong>equal_spacing</strong><br> | 
 | <strong>fractional_even_spacing</strong><br> | 
 | <strong>fractional_odd_spacing</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>equal_spacing</strong> specifies that edges should be divided into a collection of | 
 | equal-sized segments;</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>fractional_even_spacing</strong> specifies that edges should be divided into an | 
 | even number of equal-length segments plus two additional shorter | 
 | “fractional” segments; or</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>fractional_odd_spacing</strong> specifies that edges should be divided into an odd | 
 | number of equal-length segments plus two additional shorter “fractional” | 
 | segments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A third group of layout identifiers, <em>ordering</em>, specifies whether the | 
 | tessellation primitive generator produces triangles in clockwise or | 
 | counter-clockwise order, according to the coordinate system depicted in the | 
 | <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>ordering</em>: </dt> | 
 | <dd> | 
 | <p><strong>cw</strong><br> | 
 | <strong>ccw</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The identifiers <strong>cw</strong> and <strong>ccw</strong> indicate clockwise and counter-clockwise | 
 | triangles, respectively. | 
 | If the tessellation primitive generator does not produce triangles, the | 
 | order is ignored.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Finally, <em>point mode</em> indicates that the tessellation primitive generator | 
 | should produce one point for each distinct vertex in the subdivided | 
 | primitive, rather than generating lines or triangles.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>point-mode</em>: </dt> | 
 | <dd> | 
 | <p><strong>point_mode</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any or all of these identifiers may be specified one or more times in a | 
 | single input layout declaration.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The tessellation evaluation shader object in a program must declare a | 
 | primitive mode in its input layout. | 
 | Declaring vertex spacing, ordering, or point mode identifiers is optional. | 
 | If spacing or vertex ordering declarations are omitted, the tessellation | 
 | primitive generator will use equal spacing or counter-clockwise vertex | 
 | ordering, respectively. | 
 | If a point mode declaration is omitted, the tessellation primitive generator | 
 | will produce lines or triangles according to the primitive mode.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="geometry-shader-inputs">Geometry Shader Inputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Additional layout qualifier identifiers for geometry shader inputs include | 
 | <em>primitive</em> identifiers and an <em>invocation count</em> identifier:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>points</strong><br> | 
 | <strong>lines</strong><br> | 
 | <strong>lines_adjacency</strong><br> | 
 | <strong>triangles</strong><br> | 
 | <strong>triangles_adjacency</strong><br> | 
 | <strong>invocations</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The identifiers <strong>points</strong>, <strong>lines</strong>, <strong>lines_adjacency</strong>, <strong>triangles</strong>, and | 
 | <strong>triangles_adjacency</strong> are used to specify the type of input primitive | 
 | accepted by the geometry shader, and only one of these is accepted. | 
 | The geometry shader must declare this input primitive layout.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The identifier <strong>invocations</strong> is used to specify the number of times the | 
 | geometry shader executable is invoked for each input primitive received. | 
 | Invocation count declarations are optional. | 
 | If no invocation count is declared in the geometry shader, it will be run | 
 | once for each input primitive. | 
 | If an invocation count is declared, all such declarations must specify the | 
 | same count. | 
 | If a shader specifies an invocation count greater than the | 
 | implementation-dependent maximum, or less than or equal to zero, | 
 | a compile-time error results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(triangles, invocations = <span class="integer">6</span>) in;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that all inputs to the geometry shader are triangles and that | 
 | the geometry shader executable is run six times for each triangle processed.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All geometry shader input unsized array declarations will be sized by an | 
 | earlier input primitive layout qualifier, when present, as per the following | 
 | table.</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">Layout</th> | 
 | <th class="tableblock halign-left valign-top">Size of Input Arrays</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>points</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lines</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lines_adjacency</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>triangles</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>triangles_adjacency</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The intrinsically declared input array <em>gl_in[]</em> will also be sized by any | 
 | input primitive-layout declaration. | 
 | Hence, the expression</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">gl_in.length()</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will return the value from the table above.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An input can be declared without an array size if there is a previous layout | 
 | which specifies the size. | 
 | For built-in inputs (e.g. <em>gl_in[]</em>), a layout must be declared before any | 
 | use.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error if a layout declaration’s array size (from the | 
 | table above) does not match all the explicit array sizes specified in | 
 | declarations of an input variables in the same shader. | 
 | The following includes examples of compile-time errors:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// code sequence within one shader...</span> | 
 | in vec4 Color2[<span class="integer">2</span>];    <span class="comment">// legal, size is 2</span> | 
 | in vec4 Color3[<span class="integer">3</span>];    <span class="comment">// illegal, input sizes are inconsistent</span> | 
 | layout(lines) in;     <span class="comment">// legal for Color2, input size is 2, matching Color2</span> | 
 | in vec4 Color4[<span class="integer">3</span>];    <span class="comment">// illegal, contradicts layout of lines</span> | 
 | layout(lines) in;     <span class="comment">// legal, matches other layout() declaration</span> | 
 | layout(triangles) in; <span class="comment">// illegal, does not match earlier layout() declaration</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a link-time error if not all provided sizes (sized input arrays and | 
 | layout size) match in the geometry shader of a program.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="fragment-shader-inputs">Fragment Shader Inputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Fragment shaders allow the following layout qualifier on <strong>in</strong> only (not with | 
 | variable declarations):</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>early_fragment_tests</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>to request that fragment tests be performed before fragment shader | 
 | execution, as described in section 13.8.4 “Early Fragment Tests” of the | 
 | <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(early_fragment_tests) in;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Specifying this will make per-fragment tests be performed before fragment | 
 | shader execution. | 
 | In addition it is an error to statically write to <em>gl_FragDepth</em> in the | 
 | fragment shader. | 
 | If this is not declared, per-fragment tests will be performed after fragment | 
 | shader execution.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="compute-shader-inputs">Compute Shader Inputs</h5> | 
 | <div class="paragraph"> | 
 | <p>There are no layout location qualifiers for compute shader inputs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifier identifiers for compute shader inputs are the workgroup | 
 | size qualifiers:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>local_size_x</strong> <strong>=</strong> <em>layout-qualifier-value</em><br> | 
 | <strong>local_size_y</strong> <strong>=</strong> <em>layout-qualifier-value</em><br> | 
 | <strong>local_size_z</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>local_size_x</strong>, <strong>local_size_y</strong>, and <strong>local_size_z</strong> qualifiers are used | 
 | to declare a fixed workgroup size by the compute shader in the first, | 
 | second, and third dimension, respectively. | 
 | If a shader does not specify a size for one of the dimensions, that | 
 | dimension will have a size of 1.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example, the following declaration in a compute shader</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(local_size_x = <span class="integer">32</span>, local_size_y = <span class="integer">32</span>) in;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is used to declare a two-dimensional compute shader with a workgroup size of 32 | 
 | X 32 elements, which is equivalent to a three-dimensional compute shader | 
 | where the third dimension has size one.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As another example, the declaration</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(local_size_x = <span class="integer">8</span>) in;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>effectively specifies that a one-dimensional compute shader is being | 
 | compiled, and its size is 8 elements.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the fixed workgroup size of the shader in any dimension is less than | 
 | or equal to zero or greater than the maximum size supported by the | 
 | implementation for that dimension, a compile-time error results. | 
 | Also, if such a layout qualifier is declared more than once in the same | 
 | shader, all those declarations must set the same set of workgroup | 
 | sizes and set them to the same values; otherwise a compile-time error | 
 | results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Furthermore, if a program object contains a compute shader, that shader must | 
 | contain an input layout qualifier specifying a fixed workgroup size for | 
 | the program, or a link-time error will occur.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="output-layout-qualifiers">4.4.2. Output Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Some output layout qualifiers apply to all shader stages and some apply only | 
 | to specific stages. | 
 | The latter are discussed in separate sections below.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As with input layout qualifiers, all shaders except compute shaders allow | 
 | <strong>location</strong> layout qualifiers on output variable declarations, output block | 
 | declarations, and output block member declarations.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>location</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The usage and rules for applying the <strong>location</strong> qualifier | 
 | to blocks and structures are exactly as described in | 
 | “<a href="#input-layout-qualifiers">Input Layout Qualifiers</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The qualifier may appear at most once within a declaration. | 
 | For example, in a fragment shader,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">3</span>) out vec4 color;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that the fragment shader output <em>color</em> is assigned to</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>fragment color 3.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For fragment shader outputs, the location | 
 | specifies | 
 | the color output number | 
 | receiving the values of the output. | 
 | For outputs of all other shader stages, the location specifies a vector | 
 | number that can be used to match against inputs in a subsequent shader | 
 | stage, even if that shader is in a different program object.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Declared outputs of scalar or vector type consume a single location.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared output is an array, it will be assigned consecutive | 
 | locations starting with the location specified. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(location = <span class="integer">2</span>) out vec4 colors[<span class="integer">3</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that <em>colors</em> is assigned to vector location numbers 2, 3, | 
 | and 4.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared output is an <em>n</em> × <em>m</em> | 
 | matrix, it will be assigned multiple locations starting with the location | 
 | specified. | 
 | The number of locations assigned will be the same as for an <em>n</em>-element | 
 | array of <em>m</em>-component vectors.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the declared output is a structure, its members will be assigned | 
 | consecutive locations in the order of declaration, with the first member | 
 | assigned the location specified for the structure. | 
 | The number of locations consumed by a structure member is determined by | 
 | applying the rules above recursively as though the structure member were | 
 | declared as an output variable of the same type.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>location</strong> layout qualifiers may be used on output variables declared as | 
 | structures. | 
 | However, it is a compile-time error to use a <strong>location</strong> qualifier on a | 
 | structure member. | 
 | Location layout qualifiers may be used on output blocks and output block | 
 | members.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an output is declared as an array of blocks, excluding per-vertex-arrays | 
 | as required for tessellation, it is an error to declare a member of the | 
 | block with a <strong>location</strong> qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The number of output locations available to a shader is limited. | 
 | For fragment shaders, the limit is the advertised number of draw buffers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For all other shaders, the limit is implementation-dependent and must be no | 
 | less than one fourth of the advertised maximum output component count | 
 | (compute shaders have no outputs). | 
 | A program will fail to link if any attached shader uses a location greater | 
 | than or equal to the number of supported locations, unless device-dependent | 
 | optimizations are able to make the program fit within available hardware | 
 | resources.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Compile-time errors may also be given if at compile time it is known the | 
 | link will fail. | 
 | A negative output location will result in an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time or link-time error if any of the following occur:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>any two fragment shader output variables are assigned to the same | 
 | location.</p> | 
 | </li> | 
 | <li> | 
 | <p>if any two output variables from the same vertex, tessellation or | 
 | geometry shader stage are assigned to the same location.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For all shader types, a program will fail to link if explicit location | 
 | assignments leave the linker unable to find space for other variables | 
 | without explicit assignments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an output variable has no location assigned in the shader text, it will | 
 | be assigned a location by the linker. | 
 | See section 11.1.3 “Shader Execution” of the <a href="#references">OpenGL ES Specification</a> for | 
 | more details.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If there is only a single output, the location does not need to be | 
 | specified, in which case it defaults to zero. | 
 | This applies for all output types, including arrays. | 
 | If there is more than one fragment output, the location must be specified | 
 | for all outputs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For the purposes of determining if a non-fragment output matches an input | 
 | from a subsequent shader stage, the <strong>location</strong> layout qualifier (if any) | 
 | must match.</p> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-control-outputs">Tessellation Control Outputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Tessellation control shaders allow output layout qualifiers only on the | 
 | interface | 
 | qualifier <strong>out</strong>, not on an output block, block member, or variable | 
 | declaration. | 
 | The output layout qualifier identifiers allowed for tessellation control | 
 | shaders are:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>vertices</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The identifier <strong>vertices</strong> specifies the number of vertices in the output | 
 | patch produced by the tessellation control shader, which also specifies the | 
 | number of times the tessellation control shader is invoked. | 
 | It is a compile- or link-time error for the output vertex count to be less | 
 | than or equal to zero, or greater than the implementation-dependent maximum | 
 | patch size.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The intrinsically declared tessellation control output array <em>gl_out[]</em> will | 
 | also be sized by any output layout declaration. | 
 | Hence, the expression</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">gl_out.length()</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will return the output patch vertex count specified in a previous output | 
 | layout qualifier. | 
 | For outputs declared without an array size, including intrinsically declared | 
 | outputs (i.e., <em>gl_out</em>), a layout must be declared before any use of the | 
 | method <strong>length</strong>() or other array use that requires its size to be known.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error if the output patch vertex count specified in an | 
 | output layout qualifier does not match the array size specified in any | 
 | output variable declaration in the same shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All tessellation control shader layout declarations in a program must | 
 | specify the same output patch vertex count. | 
 | There must be at least one layout qualifier specifying an output patch | 
 | vertex count in any program containing a tessellation control shader.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="geometry-outputs">Geometry Outputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Geometry shaders can have two additional types of output layout identifiers: | 
 | an output primitive type and a maximum output vertex count. | 
 | The primitive type and vertex count identifiers are allowed only on the | 
 | interface qualifier <strong>out</strong>, not on an output block, block member, or variable | 
 | declaration.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The layout qualifier identifiers for geometry shader outputs are</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>points</strong><br> | 
 | <strong>line_strip</strong><br> | 
 | <strong>triangle_strip</strong><br> | 
 | <strong>max_vertices</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The primitive type identifiers <strong>points</strong>, <strong>line_strip</strong>, and <strong>triangle_strip</strong> | 
 | are used to specify the type of output primitive produced by the geometry | 
 | shader, and only one of these is accepted. | 
 | The geometry shader object in a program must declare an output primitive | 
 | type, and all geometry shader output primitive type declarations in a | 
 | program must declare the same primitive type.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The vertex count identifier <strong>max_vertices</strong> is used to specify the maximum | 
 | number of vertices the shader will ever emit in a single invocation. | 
 | The geometry shader object in a program must declare a maximum output vertex | 
 | count, and all geometry shader output vertex count declarations in a program | 
 | must declare the same count.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In this example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(triangle_strip, max_vertices = <span class="integer">60</span>) out; <span class="comment">// order does not matter</span> | 
 | layout(max_vertices = <span class="integer">60</span>) out;  <span class="comment">// redeclaration okay</span> | 
 | layout(triangle_strip) out;     <span class="comment">// redeclaration okay</span> | 
 | layout(points) out;             <span class="comment">// error, contradicts triangle_strip</span> | 
 | layout(max_vertices = <span class="integer">30</span>) out;  <span class="comment">// error, contradicts 60</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>all outputs from the geometry shader are triangles and at most 60 vertices | 
 | will be emitted by the shader. | 
 | It is an error for the maximum number of vertices to be greater than | 
 | <em>gl_MaxGeometryOutputVertices</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All geometry shader output layout declarations in a program must declare the | 
 | same layout and same value for <strong>max_vertices</strong>. | 
 | If geometry shaders are in a program, there must be at least one geometry | 
 | output layout declaration somewhere in that | 
 | program.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="fragment-outputs">Fragment Outputs</h5> | 
 | <div class="paragraph"> | 
 | <p>Fragment shaders can have an output layout for redeclaring the built-in | 
 | variable <em>gl_FragDepth</em>:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// redeclaration that changes nothing is allowed +</span> | 
 | out <span class="predefined-type">float</span> gl_FragDepth;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in <em>gl_FragDepth</em> is only predeclared in fragment shaders, so | 
 | redeclaring it in any other shader language results in an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shaders additionally support layout qualifiers specifying a set of | 
 | advanced blend equations supported when the fragment shader is used. | 
 | These layout qualifiers are only permitted on the interface qualifier <strong>out</strong>, | 
 | and use the identifiers specified in the “Layout Qualifier” column of the | 
 | table below.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a layout qualifier in the table below is specified in the fragment | 
 | shader, the fragment shader may be used with the corresponding advanced | 
 | blend equation in the “Blend Equation(s) Supported” column. | 
 | Additionally, the special qualifier <strong>blend_support_all_equations</strong> indicates | 
 | that the shader may be used with any advanced blending equation supported by | 
 | the <a href="#references">OpenGL ES Specification</a>. | 
 | It is not an error to specify more than one of these identifiers in any | 
 | fragment shader. | 
 | Specifying more than one qualifier or <strong>blend_support_all_equations</strong> means | 
 | that the fragment shader may be used with multiple advanced blend equations. | 
 | Additionally, it is not an error to specify any single one of these layout | 
 | qualifiers more than once.</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 50%;"> | 
 | <col style="width: 50%;"> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Layout Qualifier</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Blend Equations(s) Supported</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_multiply</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">MULTIPLY</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_screen</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">SCREEN</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_overlay</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">OVERLAY</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_darken</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">DARKEN</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_lighten</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">LIGHTEN</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_colordodge</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">COLORDODGE</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_colorburn</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">COLORBURN</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_hardlight</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">HARDLIGHT</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_softlight</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">SOFTLIGHT</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_difference</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">DIFFERENCE</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_exclusion</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">EXCLUSION</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_hsl_hue</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">HSL_HUE</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_hsl_saturation</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">HSL_SATURATION</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_hsl_color</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">HSL_COLOR</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_hsl_luminosity</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">HSL_LUMINOSITY</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>blend_support_all_equations</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">all blend equations</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="uniform-variable-layout-qualifiers">4.4.3. Uniform Variable Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>The following layout qualifier can be used for all default-block uniform | 
 | variables but not for variables in uniform or shader storage blocks. | 
 | The layout qualifier identifier for uniform variables is:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>location</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The location specifies the location by which the OpenGL ES API can reference | 
 | the uniform and update its value. | 
 | Individual elements of a uniform array are assigned consecutive locations | 
 | with the first element taking location <strong>location</strong>. | 
 | No two default-block uniform variables in the program can have the same | 
 | location, even if they are unused, otherwise a compile-time or link-time | 
 | error will be generated. | 
 | Valid locations for default-block uniform variable locations are in the | 
 | range of 0 to the implementation-defined maximum number of uniform locations | 
 | minus one.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Locations can be assigned to default-block uniform arrays and structures. | 
 | The first inner-most scalar, vector or matrix member or element takes the | 
 | specified <strong>location</strong> and the compiler assigns the next inner-most member or | 
 | element the next incremental location value. | 
 | Each subsequent inner-most member or element gets incremental locations for | 
 | the entire structure or array. | 
 | This rule applies to nested structures and arrays and gives each inner-most | 
 | scalar, vector, or matrix member a unique location. | 
 | When the linker generates locations for uniforms without an explicit | 
 | location, it assumes for all uniforms with an explicit location all their | 
 | array elements and structure members are used and the linker will not | 
 | generate a conflicting location, even if that element or member is deemed | 
 | unused.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="uniform-and-shader-storage-block-layout-qualifiers">4.4.4. Uniform and Shader Storage Block Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifiers can be used for uniform and shader storage blocks, but not | 
 | for non-block uniform declarations. | 
 | The layout qualifier identifiers (and <strong>shared</strong> keyword) for uniform and | 
 | shader storage blocks are:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>shared</strong><br> | 
 | <strong>packed</strong><br> | 
 | <strong>std140</strong><br> | 
 | <strong>std430</strong><br> | 
 | <strong>row_major</strong><br> | 
 | <strong>column_major</strong><br> | 
 | <strong>binding</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>None of these have any semantic effect at all on the usage of the variables | 
 | being declared; they only describe how data is laid out in memory. | 
 | For example, matrix semantics are always column-based, as described in the | 
 | rest of this specification, no matter what layout qualifiers are being used.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Uniform and shader storage block layout qualifiers can be declared for | 
 | global scope, on a single uniform or shader storage block, or on a single | 
 | block member declaration.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Default layouts are established at global scope for uniform blocks as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(layout-qualifier-id-list) uniform;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>and for shader storage blocks as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(layout-qualifier-id-list) buffer;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When this is done, the previous default qualification is first inherited and | 
 | then overridden as per the override rules listed below for each qualifier | 
 | listed in the declaration. | 
 | The result becomes the new default qualification scoped to subsequent | 
 | uniform or shader storage block definitions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The initial state of compilation | 
 | is as if the following were declared:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(shared, column_major) uniform; | 
 | layout(shared, column_major) buffer;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Uniform and shader storage blocks can be declared with optional layout | 
 | qualifiers, and so can their individual member declarations. | 
 | Such block layout qualification is scoped only to the content of the block. | 
 | As with global layout declarations, block layout qualification first | 
 | inherits from the current default qualification and then overrides it. | 
 | Similarly, individual member layout qualification is scoped just to the | 
 | member declaration, and inherits from and overrides the block’s | 
 | qualification.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>shared</strong> qualifier overrides only the <strong>std140</strong>, <strong>std430</strong>, and <strong>packed</strong> | 
 | qualifiers; other qualifiers are inherited. | 
 | The compiler/linker will ensure that multiple programs and programmable | 
 | stages containing this definition will share the same memory layout for this | 
 | block, as long as they also matched in their <strong>row_major</strong> and/or | 
 | <strong>column_major</strong> qualifications. | 
 | This allows use of the same buffer to back the same block definition across | 
 | different programs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>packed</strong> qualifier overrides only <strong>std140</strong>, <strong>std430</strong>, and <strong>shared</strong>; | 
 | other qualifiers are inherited. | 
 | When <strong>packed</strong> is used, no shareable layout is guaranteed. | 
 | The compiler and linker can optimize memory use based on what variables | 
 | actively get used and on other criteria. | 
 | Offsets must be queried, as there is no other way of guaranteeing where (and | 
 | which) variables reside within the block.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a link-time error to access the same packed uniform or shader storage | 
 | block in multiple stages within a program. | 
 | Attempts to access the same packed uniform or shader storage block across | 
 | programs can result in conflicting member offsets and in undefined values | 
 | being read. | 
 | However, implementations may aid application management of packed blocks by | 
 | using canonical layouts for packed blocks.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>std140</strong> and <strong>std430</strong> qualifiers override only the <strong>packed</strong>, <strong>shared</strong>, | 
 | <strong>std140</strong>, and <strong>std430</strong> qualifiers; other qualifiers are inherited. | 
 | The <strong>std430</strong> qualifier is supported only for shader storage blocks; a shader | 
 | using the <strong>std430</strong> qualifier on a uniform block will fail to compile.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The layout is explicitly determined by this, as described in section 7.6.2.2 | 
 | “Standard Uniform Block Layout” of the <a href="#references">OpenGL ES Specification</a>. | 
 | Hence, as in <strong>shared</strong> above, the resulting layout is shareable across | 
 | programs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifiers on member declarations cannot use the <strong>shared</strong>, <strong>packed</strong>, | 
 | <strong>std140</strong>, or <strong>std430</strong> qualifiers. | 
 | These can only be used at global scope (without an object) or on a block | 
 | declaration, or an error results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>row_major</strong> and <strong>column_major</strong> qualifiers only affect the layout of | 
 | matrices, including all matrices contained in structures and arrays they are | 
 | applied to, to all depths of nesting. | 
 | These qualifiers can be applied to other types, but will have no effect.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>row_major</strong> qualifier overrides only the <strong>column_major</strong> qualifier; other | 
 | qualifiers are inherited. | 
 | Elements within a matrix row will be contiguous in memory.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>column_major</strong> qualifier overrides only the <strong>row_major</strong> qualifier; other | 
 | qualifiers are inherited. | 
 | Elements within a matrix column will be contiguous in memory.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>binding</strong> qualifier specifies the uniform buffer binding point | 
 | corresponding to the uniform or shader storage block, which will be used to | 
 | obtain the values of the member variables of the block. | 
 | It is a compile-time error to specify the <strong>binding</strong> qualifier for the global | 
 | scope or for block member declarations. | 
 | Any uniform or shader storage block declared without a <strong>binding</strong> qualifier | 
 | is initially assigned to block binding point zero. | 
 | After a program is linked, the binding points used for uniform | 
 | (but not shader storage) blocks | 
 | declared with or without a <strong>binding</strong> qualifier can be updated | 
 | by the OpenGL ES API.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the <strong>binding</strong> qualifier is used with a uniform block or shader storage | 
 | block instanced as an array, the first element of the array takes the | 
 | specified block binding and each subsequent element takes the next | 
 | consecutive binding point. | 
 | For an array of arrays, each element (e.g. 6 elements for a[2][3]) gets a | 
 | binding point, and they are ordered per the array of array ordering | 
 | described in “<a href="#arrays.">Arrays.</a>”</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the binding point for any uniform or shader storage block instance is | 
 | less than zero, or greater than or equal to the corresponding | 
 | implementation-dependent maximum number of buffer bindings, a compile-time | 
 | error will occur. | 
 | When the <strong>binding</strong> qualifier is used with a uniform or shader storage block | 
 | instanced as an array of size <em>N</em>, all elements of the array from <strong>binding</strong> | 
 | through <em>binding + N - 1</em> must be within this range.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When multiple arguments are listed in a <strong>layout</strong> declaration, the effect | 
 | will be the same as if they were declared one at a time, in order from left | 
 | to right, each in turn inheriting from and overriding the result from the | 
 | previous qualification.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(row_major, column_major)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>results in the qualification being <strong>column_major</strong>. | 
 | Other examples:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(shared, row_major) uniform; <span class="comment">// default is now shared and row_major</span> | 
 |  | 
 | layout(std140) uniform Transform { <span class="comment">// layout of this block is std140</span> | 
 |     mat4 M1;                       <span class="comment">// row major</span> | 
 |     layout(column_major) mat4 M2;  <span class="comment">// column major</span> | 
 |     mat3 N1;                       <span class="comment">// row major</span> | 
 | }; | 
 |  | 
 | uniform T2 {                       <span class="comment">// layout of this block is shared</span> | 
 |     ... | 
 | }; | 
 |  | 
 | layout(column_major) uniform T3 {  <span class="comment">// shared and column major</span> | 
 |     mat4 M3;                       <span class="comment">// column major</span> | 
 |     layout(row_major) mat4 m4;     <span class="comment">// row major</span> | 
 |     mat3 N2;                       <span class="comment">// column major</span> | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="opaque-uniform-layout-qualifiers">4.4.5. Opaque Uniform Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Uniform layout qualifiers can be used to bind opaque uniform variables to | 
 | specific buffers or units. | 
 | Samplers can be bound to texture image units, images can be bound to image | 
 | units, and atomic counters can be bound to buffers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Sampler, image and atomic counter types take the uniform layout qualifier | 
 | identifier for binding:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>binding</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The identifier <strong>binding</strong> specifies which unit will be bound. | 
 | Any uniform sampler, image or atomic counter | 
 | variable declared without a binding qualifier | 
 | is initially bound to unit zero. | 
 | After a program is linked, the unit referenced by a sampler | 
 | uniform variable declared with or without a <strong>binding</strong> qualifier can be | 
 | updated by the OpenGL ES API.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the <strong>binding</strong> qualifier is used with an array, the first element of the | 
 | array takes the specified unit and each subsequent element takes the next | 
 | consecutive unit. | 
 | For an array of arrays, each element (e.g. 6 elements for a[2][3]) gets a | 
 | binding point, and they are ordered per the array of array ordering | 
 | described in “<a href="#arrays.">Arrays.</a>”</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the <strong>binding</strong> is less than zero, or greater than or equal to the | 
 | implementation-dependent maximum supported number of units, a compile-time | 
 | error will occur. | 
 | When the <strong>binding</strong> qualifier is used with an array of size <em>N</em>, all elements | 
 | of the array from <strong>binding</strong> through <em>binding + N - 1</em> must be within this | 
 | range.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A link-time error will result if two shaders in a program specify different | 
 | <em>layout-qualifier-value</em> bindings for the same opaque-uniform name. | 
 | However, it is not an error to specify a binding on some but not all | 
 | declarations for the same name, as shown in the examples below.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// in one shader...</span> | 
 | layout(binding=<span class="integer">3</span>) uniform sampler2D s; <span class="comment">// s bound to unit 3</span> | 
 |  | 
 | <span class="comment">// in another shader...</span> | 
 | uniform sampler2D s;                   <span class="comment">// okay, s still bound at 3</span> | 
 |  | 
 | <span class="comment">// in another shader...</span> | 
 | layout(binding=<span class="integer">4</span>) uniform sampler2D s; <span class="comment">// ERROR: contradictory bindings</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="atomic-counter-layout-qualifiers">4.4.6. Atomic Counter Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Atomic counter layout qualifiers can be used on atomic counter declarations. | 
 | The atomic counter qualifiers are:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><strong>binding</strong> <strong>=</strong> <em>layout-qualifier-value</em><br> | 
 | <strong>offset</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(binding = <span class="integer">2</span>, offset = <span class="integer">4</span>) uniform atomic_uint a;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that the opaque handle to the atomic counter <em>a</em> will be | 
 | bound to atomic counter buffer binding point 2 at an offset of 4 basic | 
 | machine units into that buffer. | 
 | The default <em>offset</em> for binding point 2 will be post incremented by 4 (the | 
 | size of an atomic counter).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A subsequent atomic counter declaration will inherit the previous (post | 
 | incremented) offset. | 
 | For example, a subsequent declaration of</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(binding = <span class="integer">2</span>) uniform atomic_uint bar;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will establish that the atomic counter <em>bar</em> has a binding to buffer binding | 
 | point 2 at an offset of 8 basic machine units into that buffer. | 
 | The offset for binding point 2 will again be post-incremented by 4 (the size | 
 | of an atomic counter).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When multiple variables are listed in a layout declaration, the effect will | 
 | be the same as if they were declared one at a time, in order from left to | 
 | right.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Binding points are not inherited, only offsets. | 
 | Each binding point tracks its own current default <em>offset</em> for inheritance | 
 | of subsequent variables using the same <strong>binding</strong>. | 
 | The initial state of compilation is that all <strong>binding</strong> points have an | 
 | <em>offset</em> of 0. | 
 | The <em>offset</em> can be set per binding point at global scope (without declaring | 
 | a variable). | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(binding = <span class="integer">2</span>, offset = <span class="integer">4</span>) uniform atomic_uint;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Establishes that the next <strong>atomic_uint</strong> declaration for binding point 2 will | 
 | inherit <em>offset</em> 4 (but does not establish a default <strong>binding</strong>):</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(binding = <span class="integer">2</span>) uniform atomic_uint bar; <span class="comment">// offset is 4</span> | 
 | layout(offset = <span class="integer">8</span>) uniform atomic_uint bar;  <span class="comment">// error, no default binding</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Atomic counters may share the same binding point, but if a binding is | 
 | shared, their offsets must be either explicitly or implicitly (from | 
 | inheritance) unique and non overlapping.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example valid uniform declarations, assuming top of shader:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(binding=<span class="integer">3</span>, offset=<span class="integer">4</span>) uniform atomic_uint a; <span class="comment">// offset = 4</span> | 
 | layout(binding=<span class="integer">2</span>) uniform atomic_uint b;           <span class="comment">// offset = 0</span> | 
 | layout(binding=<span class="integer">3</span>) uniform atomic_uint c;           <span class="comment">// offset = 8</span> | 
 | layout(binding=<span class="integer">2</span>) uniform atomic_uint d;           <span class="comment">// offset = 4</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example of an invalid uniform declaration:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">layout(offset=<span class="integer">4</span>) ...               <span class="comment">// error, must include binding</span> | 
 | layout(binding=<span class="integer">1</span>, offset=<span class="integer">0</span>) ... a; <span class="comment">// okay</span> | 
 | layout(binding=<span class="integer">2</span>, offset=<span class="integer">0</span>) ... b; <span class="comment">// okay</span> | 
 | layout(binding=<span class="integer">1</span>, offset=<span class="integer">0</span>) ... c; <span class="comment">// error, offsets must not be shared</span> | 
 |                                    <span class="comment">// between a and c</span> | 
 | layout(binding=<span class="integer">1</span>, offset=<span class="integer">2</span>) ... d; <span class="comment">// error, overlaps offset 0 of a</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time error to bind an atomic counter with a binding value | 
 | greater than or equal to <em>gl_MaxAtomicCounterBindings</em>.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="format-layout-qualifiers">4.4.7. Format Layout Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Format layout qualifiers can be used on image variable declarations (those | 
 | declared with a basic type having “<strong>image</strong>” in its keyword). | 
 | The format layout qualifier identifiers for image variable declarations are:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>layout-qualifier-id</em> : </dt> | 
 | <dd> | 
 | <p><em>float-image-format-qualifier</em><br> | 
 | <em>int-image-format-qualifier</em><br> | 
 | <em>uint-image-format-qualifier</em><br> | 
 | <strong>binding</strong> <strong>=</strong> <em>layout-qualifier-value</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>float-image-format-qualifier</em> : </dt> | 
 | <dd> | 
 | <p><strong>rgba32f</strong><br> | 
 | <strong>rgba16f</strong><br> | 
 | <strong>r32f</strong><br> | 
 | <strong>rgba8</strong><br> | 
 | <strong>rgba8_snorm</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>int-image-format-qualifier</em> : </dt> | 
 | <dd> | 
 | <p><strong>rgba32i</strong><br> | 
 | <strong>rgba16i</strong><br> | 
 | <strong>rgba8i</strong><br> | 
 | <strong>r32i</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>uint-image-format-qualifier</em> : </dt> | 
 | <dd> | 
 | <p><strong>rgba32ui</strong><br> | 
 | <strong>rgba16ui</strong><br> | 
 | <strong>rgba8ui</strong><br> | 
 | <strong>r32ui</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A format layout qualifier specifies the image format associated with a | 
 | declared image variable. | 
 | Only one format qualifier may be specified for any image variable | 
 | declaration. | 
 | For image variables with floating-point component types (keywords starting | 
 | with “<strong>image</strong>”), signed integer component types (keywords starting with | 
 | “<strong>iimage</strong>”), or unsigned integer component types (keywords starting with | 
 | “<strong>uimage</strong>”), the format qualifier used must match the | 
 | <em>float-image-format-qualifier</em>, <em>int-image-format-qualifier</em>, or | 
 | <em>uint-image-format-qualifier</em> grammar rules, respectively. | 
 | It is an error to declare an image variable where the format | 
 | qualifier does not match the image variable type.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any image variable must specify a format layout qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>binding</strong> qualifier was described in | 
 | “<a href="#opaque-uniform-layout-qualifiers">Opaque Uniform Layout Qualifiers</a>”.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="interpolation-qualifiers">4.5. Interpolation Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>Inputs and outputs that could be interpolated can be further qualified by at | 
 | most one of the following interpolation qualifiers:</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">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>smooth</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">perspective correct interpolation</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>flat</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">no interpolation</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The presence of and type of interpolation is controlled by the above | 
 | interpolation qualifiers as well as the auxiliary storage qualifiers | 
 | <strong>centroid</strong> and <strong>sample</strong>. | 
 | When no interpolation qualifier is present, smooth interpolation is used. | 
 | It is a compile-time error to use more than one interpolation qualifier. | 
 | The auxiliary storage qualifier <strong>patch</strong> is not used for interpolation; it is | 
 | a compile-time error to use interpolation qualifiers with <strong>patch</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A variable qualified as <strong>flat</strong> will not be interpolated. | 
 | Instead, it will have the same value for every fragment within a primitive. | 
 | This value will come from a single provoking vertex, as described by the | 
 | <a href="#references">OpenGL ES Specification</a>. | 
 | A variable qualified as <strong>flat</strong> may also be qualified as <strong>centroid</strong> or | 
 | <strong>sample</strong>, which will mean the same thing as qualifying it only as <strong>flat</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A variable qualified as <strong>smooth</strong> will be interpolated in a | 
 | perspective-correct manner over the primitive being rendered.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Interpolation in a perspective correct manner is specified in equations 13.4 | 
 | of the <a href="#references">OpenGL ES Specification</a>, section 13.4.1 “Line Segments” and | 
 | equation 13.7, section 13.5.1 “Polygon Interpolation”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When multisample rasterization is disabled, or for fragment shader input | 
 | variables qualified with neither <strong>centroid</strong> nor <strong>sample</strong>, the value of the | 
 | assigned variable may be interpolated anywhere within the pixel and a single | 
 | value may be assigned to each sample within the pixel, to the extent | 
 | permitted by the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When multisample rasterization is enabled, <strong>centroid</strong> and <strong>sample</strong> may be | 
 | used to control the location and frequency of the sampling of the qualified | 
 | fragment shader input. | 
 | If a fragment shader input is qualified with <strong>centroid</strong>, a single value may | 
 | be assigned to that variable for all samples in the pixel, but that value | 
 | must be interpolated at a location that lies in both the pixel and in the | 
 | primitive being rendered, including any of the pixel’s samples covered by | 
 | the primitive. | 
 | Because the location at which the variable is interpolated may be different | 
 | in neighboring pixels, and derivatives may be computed by computing | 
 | differences between neighboring pixels, derivatives of centroid-sampled | 
 | inputs may be less accurate than those for non-centroid interpolated | 
 | variables. | 
 | If a fragment shader input is qualified with <strong>sample</strong>, a separate value must | 
 | be assigned to that variable for each covered sample in the pixel, and that | 
 | value must be sampled at the location of the individual sample.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="parameter-qualifiers">4.6. Parameter Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>In addition to precision qualifiers and memory qualifiers, parameters can | 
 | have these parameter qualifiers.</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">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><none: default></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">same as <strong>in</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>in</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">for function parameters passed into a function</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>out</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">for function parameters passed back out of a function, | 
 |                    but not initialized for use when passed in</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>inout</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">for function parameters passed both into and out of a | 
 |                    function</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Parameter qualifiers are discussed in more detail in | 
 | “<a href="#function-calling-conventions">Function Calling Conventions</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="precision-and-precision-qualifiers">4.7. Precision and Precision Qualifiers</h3> | 
 | <div class="sect3"> | 
 | <h4 id="range-and-precision">4.7.1. Range and Precision</h4> | 
 | <div class="paragraph"> | 
 | <p>The precision of <strong>highp</strong> floating-point variables is defined by the IEEE 754 | 
 | standard for 32-bit floating-point numbers. | 
 | This includes support for NaNs (Not a Number) and Infs (positive or negative | 
 | infinities) and positive and negative zeros.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following rules apply to | 
 | <strong>highp</strong> | 
 | operations: | 
 | Signed infinities and zeros are generated as dictated by IEEE, but subject | 
 | to the precisions allowed in the following table. | 
 | Any subnormal (denormalized) value input into a shader or potentially | 
 | generated by any operation in a shader can be flushed to 0. | 
 | The rounding mode cannot be set and is undefined but must not affect the | 
 | result by more than 1 ULP. | 
 | NaNs are not required to be generated. | 
 | Support for signaling NaNs is not required and exceptions are never raised. | 
 | Operations including built-in functions that operate on a NaN are not | 
 | required to return a NaN as the result. | 
 | However if NaNs are generated, <strong>isnan</strong>() must return the correct value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Precisions are expressed in terms of maximum relative error in units of ULP | 
 | (units in the last place), unless otherwise noted.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For single precision operations, precisions are required as follows:</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">Operation</th> | 
 | <th class="tableblock halign-left valign-top">Precision</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>a</em> + <em>b</em>, <em>a</em> - <em>b</em>, <em>a</em> * <em>b</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><, <=, ==, >, >=</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Correct result.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>a</em> / <em>b</em>, 1.0 / <em>b</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">2.5 ULP for <span class="eq">|b|</span> in the range <span class="eq">[2<sup>-126</sup>, 2<sup>126</sup>]</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>a</em> * <em>b</em> + <em>c</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded single operation or | 
 |                                     sequence of two correctly rounded operations.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>fma</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Inherited from <em>a</em> * <em>b</em> + <em>c</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>pow</strong>(<em>x</em>, <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Inherited from <strong>exp2</strong>(<em>y</em> * <strong>log2</strong>(<em>x</em>)).</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>exp</strong>(<em>x</em>), <strong>exp2</strong>(<em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">(3 + 2 · |x|)</span> ULP.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>log</strong>(), <strong>log2</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">3 ULP outside the range <span class="eq">[0.5,2.0]</span>.<br> | 
 |                                     Absolute error < 2<sup>-21</sup> inside the range | 
 |                                     <span class="eq">[0.5,2.0]</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>sqrt</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Inherited from 1.0 / <strong>inversesqrt</strong>().</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>inversesqrt</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">2 ULP.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">implicit and explicit | 
 |   conversions between types</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Built-in functions defined in the specification with an equation built from | 
 | the above operations inherit the above errors. | 
 | These include, for example, the geometric functions, the common functions, | 
 | and many of the matrix functions. | 
 | Built-in functions not listed above and not defined as equations of the | 
 | above have undefined precision. | 
 | These include, for example, the trigonometric functions and determinant.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Storage requirements are declared through use of <em>precision qualifiers</em>. | 
 | The precision of operations must preserve the storage precisions of the | 
 | variables involved.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><strong>highp</strong> floating-point values are stored in IEEE 754 single precision | 
 | floating-point format. | 
 | <strong>mediump</strong> and <strong>lowp</strong> floating-point values have minimum range and precision | 
 | requirements as detailed below and have maximum range and precision as | 
 | defined by IEEE 754.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All integral types are assumed to be implemented as integers and so may not | 
 | be emulated by floating-point values. | 
 | <strong>highp</strong> signed integers are represented as twos-complement 32-bit signed | 
 | integers. | 
 | <strong>highp</strong> unsigned integers are represented as unsigned 32-bit integers. | 
 | <strong>mediump</strong> integers (signed and unsigned) must be represented as an integer | 
 | with between 16 and 32 bits inclusive. | 
 | <strong>lowp</strong> integers (signed and unsigned) must be represented as an integer with | 
 | between 9 and 32 bits inclusive.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The required ranges and precisions for precision qualifiers are:</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.667%;"> | 
 | </colgroup> | 
 | <thead> | 
 | <tr> | 
 | <th class="tableblock halign-left valign-top">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Floating-Point Range</th> | 
 | <th class="tableblock halign-left valign-top">Floating-Point Magnitude Range</th> | 
 | <th class="tableblock halign-left valign-top">Floating-Point Precision</th> | 
 | <th class="tableblock halign-left valign-top">Signed Integer Range</th> | 
 | <th class="tableblock halign-left valign-top">Unsigned Integer Range</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>highp</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Subset of IEEE-754<br> | 
 |       <span class="eq">(-2<sup>128</sup>,2<sup>128</sup>)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Subset of IEEE-754<br> | 
 |       0.0, <span class="eq">[2<sup>-126</sup>,2<sup>128</sup>)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Subset of IEEE-754 relative:<br> | 
 |       <span class="eq">2<sup>-24</sup></span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[-2<sup>31</sup>,2<sup>31</sup>-1]</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[0,2<sup>32</sup>-1]</span></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mediump</strong> (minimum requirements)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">(-2<sup>14</sup>,2<sup>14</sup>)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">(2<sup>14</sup>,2<sup>14</sup>)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Relative:<br> | 
 |       <span class="eq">2<sup>-10</sup></span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[-2<sup>15</sup>,2<sup>15</sup>-1]</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[0,2<sup>16</sup>-1]</span></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lowp</strong> (minimum requirements)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">(-2,2)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">(2<sup>-8</sup>,2)</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Absolute:<br> | 
 |       <span class="eq">2<sup>-8</sup></span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[-2<sup>8</sup>,2<sup>8</sup>-1]</span></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="eq">[0,2<sup>9</sup>-1]</span></p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p><em>Relative precision</em> is defined as the worst case (i.e. largest) ratio of | 
 | the smallest step in relation to the value for all non-zero values:</p> | 
 | </div> | 
 | <div class="stemblock"> | 
 | <div class="content"> | 
 | \[\begin{aligned} | 
 |     \mathit{Precision}_{relative} = { | 
 |         \left| { | 
 |             { \left| v_1 - v_2 \right| }_{min} } \over { v_1 } | 
 |         \right| | 
 |     }_{max}, & | 
 |     v_1,v_2 \neq 0, v_1 \neq v_2 | 
 | \end{aligned}\] | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is therefore twice the maximum rounding error when converting from a real | 
 | number.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In addition, the range and precision of a <strong>mediump</strong> floating-point value | 
 | must be the same as or greater than the range and precision of a <strong>lowp</strong> | 
 | floating-point value. | 
 | The range and precision of a <strong>highp</strong> floating-point value must be the same | 
 | as or greater than the range and precision of a <strong>mediump</strong> floating-point | 
 | value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The range of a <strong>mediump</strong> integer value must be the same as or greater than | 
 | the range of a <strong>lowp</strong> integer value. | 
 | The range of a <strong>highp</strong> integer value must be the same as or greater than the | 
 | range of a <strong>mediump</strong> integer value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within the above specification, an implementation is allowed to vary the | 
 | representation of numeric values, both within a shader and between different | 
 | shaders. | 
 | If necessary, this variance can be controlled using the invariance | 
 | qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The actual ranges and precisions provided by an implementation can be | 
 | queried through the API. | 
 | See the <a href="#references">OpenGL ES Specification</a> specification for details on how to do | 
 | this.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="conversion-between-precisions">4.7.2. Conversion between precisions</h4> | 
 | <div class="paragraph"> | 
 | <p>Within the same type, conversion from a lower to a higher precision must be | 
 | exact. | 
 | When converting from a higher precision to a lower precision, if the value | 
 | is representable by the implementation of the target precision, the | 
 | conversion must also be exact. | 
 | If the value is not representable, the behavior is dependent on the type:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>For signed and unsigned integers, the value is truncated; bits in | 
 | positions not present in the target precision are set to zero. | 
 | (Positions start at zero and the least significant bit is considered to | 
 | be position zero for this purpose.)</p> | 
 | </li> | 
 | <li> | 
 | <p>For floating-point values, the value should either clamp to +Inf or | 
 | -Inf, or to the maximum or minimum value that the implementation | 
 | supports. | 
 | While this behavior is implementation-dependent, it should be consistent | 
 | for a given implementation.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="precision-qualifiers">4.7.3. Precision Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>Any | 
 | floating-point, integer, or opaque-type declaration can have the type | 
 | preceded by one of these precision qualifiers:</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 50%;"> | 
 | <col style="width: 50%;"> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Qualifier</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Meaning</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>highp</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The variable satisfies the minimum requirements for <strong>highp</strong> | 
 |               described above. <strong>highp</strong> variables have the maximum range and | 
 |               precision available but may cause operations to run more | 
 |               slowly on some implementations.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>mediump</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The variable satisfies the minimum requirements for <strong>mediump</strong> | 
 |               described above. <strong>mediump</strong> variables may typically be used to | 
 |               store high dynamic range colors and low precision geometry.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lowp</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The variable satisfies the minimum requirements for <strong>lowp</strong> | 
 |               described above. <strong>lowp</strong> variables may typically be used to | 
 |               store 8-bit color values.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">lowp <span class="predefined-type">float</span> color; | 
 | out mediump vec2 P; | 
 | lowp ivec2 foo(lowp mat3); | 
 | highp mat4 m;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Literal constants do not have precision qualifiers. | 
 | Neither do Boolean variables. | 
 | Neither do constructors.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For this paragraph, “operation” includes operators, built-in functions, | 
 | and constructors, and “operand” includes function arguments and | 
 | constructor arguments. | 
 | The precision used to internally evaluate an operation, and the precision | 
 | qualification subsequently associated with any resulting intermediate | 
 | values, must be at least as high as the highest precision qualification of | 
 | the operands consumed by the operation.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In cases where operands do not have a precision qualifier, the precision | 
 | qualification will come from the other operands. | 
 | If no operands have a precision qualifier, then the precision qualifications | 
 | of the operands of the next consuming operation in the expression will be | 
 | used. | 
 | This rule can be applied recursively until a precision qualified operand is | 
 | found. | 
 | If necessary, it will also include the precision qualification of l-values | 
 | for assignments, of the declared variable for initializers, of formal | 
 | parameters for function call arguments, or of function return types for | 
 | function return values. | 
 | If the precision cannot be determined by this method e.g. if an entire | 
 | expression is composed only of operands with no precision qualifier, and the | 
 | result is not assigned or passed as an argument, then it is evaluated at the | 
 | default precision of the type or greater. | 
 | When this occurs in the fragment shader, the default precision must be | 
 | defined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example, consider the statements:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">uniform highp <span class="predefined-type">float</span> h1; | 
 | highp <span class="predefined-type">float</span> h2 = <span class="float">2</span><span class="float">.3</span> * <span class="float">4</span><span class="float">.7</span>; <span class="comment">// operation and result are highp</span> | 
 | precision | 
 | mediump <span class="predefined-type">float</span> m; | 
 | m = <span class="float">3</span><span class="float">.7</span> * h1 * h2; <span class="comment">// all operations are highp precision</span> | 
 | h2 = m * h1; <span class="comment">// operation is highp precision</span> | 
 | m = h2 - h1; <span class="comment">// operation is highp precision</span> | 
 | h2 = m + m; <span class="comment">// addition and result at mediump precision</span> | 
 | <span class="directive">void</span> f(highp <span class="predefined-type">float</span> p); | 
 | f(<span class="float">3</span><span class="float">.3</span>); <span class="comment">// 3.3 will be passed in at highp precision</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Precision qualifiers, as with other qualifiers, do not affect the basic type | 
 | of the variable. | 
 | In particular, there are no constructors for precision conversions; | 
 | constructors only convert types. | 
 | Similarly, precision qualifiers, as with other qualifiers, do not contribute | 
 | to function overloading based on parameter types. | 
 | As discussed in “<a href="#function-calling-conventions">Function Calling | 
 | Conventions</a>”, function input and output is done through copies, and | 
 | therefore qualifiers do not have to match.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Precision qualifiers for outputs in one shader matched to inputs in another | 
 | shader need not match when both shaders are linked into the same program. | 
 | When both shaders are in separate programs, mismatched precision qualifiers | 
 | will result in a program interface mismatch that will result in program | 
 | pipeline validation failures, as described in section 7.4.1 “Shader | 
 | Interface Matching” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision of a variable is determined when the variable is declared and | 
 | cannot be subsequently changed.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Where the precision of a constant integral or constant floating-point | 
 | expression is not specified, evaluation is performed at <strong>highp</strong>. | 
 | This rule does not affect the precision qualification of the expression.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The evaluation of constant expressions must be invariant and will usually be | 
 | performed at compile time.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="default-precision-qualifiers">4.7.4. Default Precision Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>The precision statement</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">precision precision-qualifier type;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>can be used to establish a default precision qualifier. | 
 | The <em>type</em> field can be either <strong>int</strong>, <strong>float</strong>, or any of the opaque types, | 
 | and the <em>precision-qualifier</em> can be <strong>lowp</strong>, <strong>mediump</strong>, or <strong>highp</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any other types or qualifiers will result in an error. | 
 | If <em>type</em> is <strong>float</strong>, the directive applies to non-precision-qualified | 
 | floating-point type (scalar, vector, and matrix) declarations. | 
 | If <em>type</em> is <strong>int</strong>, the directive applies to all non-precision-qualified | 
 | integer type (scalar, vector, signed, and unsigned) declarations. | 
 | This includes global variable declarations, function return declarations, | 
 | function parameter declarations, and local variable declarations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Non-precision qualified declarations will use the precision qualifier | 
 | specified in the most recent <strong>precision</strong> statement that is still in scope. | 
 | The <strong>precision</strong> statement has the same scoping rules as variable | 
 | declarations. | 
 | If it is declared inside a compound statement, its effect stops at the end | 
 | of the inner-most statement it was declared in. | 
 | Precision statements in nested scopes override precision statements in outer | 
 | scopes. | 
 | Multiple precision statements for the same basic type can appear inside the | 
 | same scope, with later statements overriding earlier statements within that | 
 | scope.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All languages except for the fragment language have the following | 
 | predeclared globally scoped default precision statements:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">precision highp <span class="predefined-type">float</span>; | 
 | precision highp <span class="predefined-type">int</span>; | 
 | precision lowp sampler2D; | 
 | precision lowp samplerCube; | 
 | precision highp atomic_uint;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The fragment language has the following predeclared globally scoped default | 
 | precision statements:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">precision mediump <span class="predefined-type">int</span>; | 
 | precision lowp sampler2D; | 
 | precision lowp samplerCube; | 
 | precision highp atomic_uint;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The fragment language has no default precision qualifier for floating-point | 
 | types. | 
 | Hence for <strong>float</strong>, floating-point vector and matrix variable declarations, | 
 | either the declaration must include a precision qualifier or the default | 
 | float precision must have been previously declared. | 
 | Similarly, there is no default precision qualifier in any of the languages | 
 | for any type not listed above.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="available-precision-qualifiers">4.7.5. Available Precision Qualifiers</h4> | 
 | <div class="paragraph"> | 
 | <p>The built-in macro GL_FRAGMENT_PRECISION_HIGH is defined to one:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> GL_FRAGMENT_PRECISION_HIGH <span class="integer">1</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This macro is available in all languages except compute.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="variance-and-the-invariant-qualifier">4.8. Variance and the Invariant Qualifier</h3> | 
 | <div class="paragraph"> | 
 | <p>In this section, <em>variance</em> refers to the possibility of getting different | 
 | values from the same expression in different programs. | 
 | For example, consider the situation where two vertex shaders, in different | 
 | programs, each set <em>gl_Position</em> with the same expression, and the input | 
 | values into that expression are the same when both shaders run. | 
 | It is possible, due to independent compilation of the two shaders, that the | 
 | values assigned to <em>gl_Position</em> are not exactly the same when the two | 
 | shaders run. | 
 | In this example, this can cause problems with alignment of geometry in a | 
 | multi-pass algorithm.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In general, such variance between shaders is allowed. | 
 | When such variance does not exist for a particular output variable, that | 
 | variable is said to be <em>invariant</em>.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="the-invariant-qualifier">4.8.1. The Invariant Qualifier</h4> | 
 | <div class="paragraph"> | 
 | <p>To ensure that a particular output variable is invariant, it is necessary to | 
 | use the <strong>invariant</strong> qualifier. | 
 | It can either be used to qualify a previously declared variable as being | 
 | invariant:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">invariant gl_Position; <span class="comment">// make existing gl_Position be invariant</span> | 
 | out vec3 Color; | 
 | invariant Color;       <span class="comment">// make existing Color be invariant</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>or as part of a declaration when a variable is declared:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">invariant centroid out vec3 Color;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Only variables output from a shader can be candidates for invariance. | 
 | This includes user-defined output variables and the built-in output | 
 | variables. | 
 | As only outputs can be declared as invariant, an output from one shader | 
 | stage will still match an input of a subsequent stage without the input | 
 | being declared as invariant.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>invariant</strong> keyword can be followed by a comma separated list of | 
 | previously declared identifiers. | 
 | All uses of <strong>invariant</strong> must be at global scope or on block | 
 | members, and before any use of the variables being declared as invariant.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To guarantee invariance of a particular output variable across two programs, | 
 | the following must also be true:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>The output variable is declared as invariant in both programs.</p> | 
 | </li> | 
 | <li> | 
 | <p>The same values must be input to all shader input variables consumed by | 
 | expressions and control flow contributing to the value assigned to the | 
 | output variable.</p> | 
 | </li> | 
 | <li> | 
 | <p>The texture formats, texel values, and texture filtering are set the | 
 | same way for any texture function calls contributing to the value of the | 
 | output variable.</p> | 
 | </li> | 
 | <li> | 
 | <p>All input values are all operated on in the same way. | 
 |     All operations in the consuming expressions and any intermediate | 
 |     expressions must be the same, with the same order of operands and same | 
 |     associativity, to give the same order of evaluation. | 
 |     Intermediate variables and functions must be declared as the same type | 
 |     with the same explicit or implicit precision | 
 | qualifiers and the same constant qualifiers. | 
 |     Any control flow affecting the output value must be the same, and any | 
 |     expressions consumed to determine this control flow must also follow | 
 |     these invariance rules.</p> | 
 | </li> | 
 | <li> | 
 | <p>All the data flow and control flow leading to setting the invariant | 
 | output variable reside in a single compilation unit.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Essentially, all the data flow and control flow leading to an invariant | 
 | output must match.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Initially, by default, all output variables are allowed to be variant. | 
 | To force all output variables to be invariant, use the pragma</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> STDGL invariant(all)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>before all declarations in a shader. | 
 | If this pragma is used after the declaration of any variables or functions, | 
 | then the set of outputs that behave as invariant is undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Generally, invariance is ensured at the cost of flexibility in optimization, | 
 | so performance can be degraded by use of invariance. | 
 | Hence, use of this pragma is intended as a debug aid, to avoid individually | 
 | declaring all output variables as invariant.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="invariance-within-a-shader">4.8.2. Invariance Within a Shader</h4> | 
 | <div class="paragraph"> | 
 | <p>When a value is stored in a variable, it is usually assumed it will remain | 
 | constant unless explicitly changed. | 
 | However, during the process of optimization, it is possible that the | 
 | compiler may choose to recompute a value rather than store it in a register. | 
 | Since the precision of operations is not completely specified (e.g. a low | 
 | precision operation may be done at medium or high precision), it would be | 
 | possible for the recomputed value to be different from the original value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Values are allowed to be variant within a shader. | 
 | To prevent this, the invariant qualifier or invariant pragma must be used.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within a shader, there is no invariance for values generated by different | 
 | non-constant expressions, even if those expressions are identical.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example 1:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">precision mediump; | 
 | vec4 col; | 
 | vec2 a = ... | 
 | ... | 
 | col = texture(tex, a);<span class="comment">// a has a value _a1 _</span> | 
 | ... | 
 | col = texture(tex, a); <span class="comment">// a has a value a2 where possibly a1 != a2</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To enforce invariance in this example use:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> STDGL invariant(all)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example 2:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec2 m = ...; | 
 | vec2 n = ...; | 
 | vec2 a = m + n; | 
 | vec2 b = m + n; <span class="comment">// a and b are not guaranteed to be exactly equal</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is no mechanism to enforce invariance between a and b.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="invariance-of-constant-expressions">4.8.3. Invariance of Constant Expressions</h4> | 
 | <div class="paragraph"> | 
 | <p>Invariance must be guaranteed for constant expressions. | 
 | A particular constant expression must evaluate to the same result if it | 
 | appears again in the same shader or a different shader. | 
 | This includes the same expression appearing in two shaders of the same | 
 | language or shaders of two different languages.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Constant expressions must evaluate to the same result when operated on as | 
 | already described above for invariant variables. | 
 | Constant expressions are not invariant with respect to equivalent | 
 | non-constant expressions, even when the <strong>invariant</strong> qualifier or pragma is | 
 | used.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="invariance-of-undefined-values">4.8.4. Invariance of Undefined Values</h4> | 
 | <div class="paragraph"> | 
 | <p>Undefined values are not invariant nor can they be made invariant by use of | 
 | the invariant qualifier or pragma. | 
 | In some implementations, undefined values may cause unexpected behavior if | 
 | they are used in control-flow expressions e.g. in the following case, one, | 
 | both or neither functions may be executed and this may not be consistent | 
 | over multiple invocations of the shader:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span> x; <span class="comment">// undefined value</span> | 
 | <span class="keyword">if</span> (x == <span class="integer">1</span>) | 
 | { | 
 |     f(); <span class="comment">// Undefined whether f() is executed</span> | 
 | } | 
 | <span class="keyword">if</span> (x == <span class="integer">2</span>) | 
 | { | 
 |     g(); <span class="comment">// Undefined whether g() is executed.</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that an undefined value is a value that has not been specified. | 
 | A value that has been specified but has a potentially large error due to, | 
 | for example, lack of precision in an expression, is not undefined and so can | 
 | be made invariant.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="the-precise-qualifier">4.9. The Precise Qualifier</h3> | 
 | <div class="paragraph"> | 
 | <p>Some algorithms require floating-point computations to exactly follow the | 
 | order of operations specified in the source code and to treat all operations | 
 | consistently, even if the implementation supports optimizations that could | 
 | produce nearly equivalent results with higher performance. | 
 | For example, many GL implementations support a “multiply-add” instruction | 
 | that can compute a floating-point expression such as</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">result = (a * b) + (c * d);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>in two operations instead of three operations; one multiply and one | 
 | multiply-add instead of two multiplies and one add. | 
 | The result of a floating-point multiply-add might not always be identical to | 
 | first doing a multiply yielding a floating-point result and then doing a | 
 | floating-point add. | 
 | Hence, in this example, the two multiply operations would not be treated | 
 | consistently; the two multiplies could effectively appear to have differing | 
 | precisions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The key computation that needs to be made consistent appears when | 
 | tessellating, where intermediate points for subdivision are synthesized in | 
 | different directions, yet need to yield the same result, as shown in the | 
 | diagram below.</p> | 
 | </div> | 
 | <div id="img-precise" class="imageblock"> | 
 | <div class="content"> | 
 | <img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KCjxzdmcgdmVyc2lvbj0iMS4yIiBiYXNlUHJvZmlsZT0idGlueSIgd2lkdGg9IjIxMG1tIiBoZWlnaHQ9IjI5N21tIiB2aWV3Qm94PSIwIDAgMjEwMDAgMjk3MDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcGF0aD0idXJsKCNwcmVzZW50YXRpb25fY2xpcF9wYXRoKSIgc3Ryb2tlLXdpZHRoPSIyOC4yMjIiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6b29vPSJodHRwOi8veG1sLm9wZW5vZmZpY2Uub3JnL3N2Zy9leHBvcnQiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIj4KIDxkZWZzIGNsYXNzPSJDbGlwUGF0aEdyb3VwIj4KICA8Y2xpcFBhdGggaWQ9InByZXNlbnRhdGlvbl9jbGlwX3BhdGgiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KICAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIxMDAwIiBoZWlnaHQ9IjI5NzAwIi8+CiAgPC9jbGlwUGF0aD4KIDwvZGVmcz4KIDxkZWZzPgogIDxmb250IGlkPSJFbWJlZGRlZEZvbnRfMSIgaG9yaXotYWR2LXg9IjIwNDgiPgogICA8Zm9udC1mYWNlIGZvbnQtZmFtaWx5PSJMaWJlcmF0aW9uIFNhbnMgZW1iZWRkZWQiIHVuaXRzLXBlci1lbT0iMjA0OCIgZm9udC13ZWlnaHQ9Im5vcm1hbCIgZm9udC1zdHlsZT0ibm9ybWFsIiBhc2NlbnQ9IjE4NTIiIGRlc2NlbnQ9IjQyMyIvPgogICA8bWlzc2luZy1nbHlwaCBob3Jpei1hZHYteD0iMjA0OCIgZD0iTSAwLDAgTCAyMDQ3LDAgMjA0NywyMDQ3IDAsMjA0NyAwLDAgWiIvPgogICA8Z2x5cGggdW5pY29kZT0idyIgaG9yaXotYWR2LXg9IjE1MDkiIGQ9Ik0gMTE3NCwwIEwgOTY1LDAgNzkyLDY5OCBDIDc4Nyw3MTYgNzgxLDczOCA3NzYsNzY1IDc3MCw3OTIgNzY0LDgxOCA3NTksODQzIDc1Miw4NzIgNzQ2LDkwMyA3NDAsOTM0IDczNCw5MDQgNzI4LDg3NCA3MjEsODQ1IDcxNiw4MjAgNzEwLDc5MyA3MDQsNzY2IDY5Nyw3MzkgNjkxLDcxNSA2ODYsNjk0IEwgNTA4LDAgMzAwLDAgLTMsMTA4MiAxNzUsMTA4MiAzNTgsMzQ3IEMgMzYzLDMzMiAzNjcsMzEzIDM3MiwyOTEgMzc3LDI2OCAzODEsMjQ2IDM4NiwyMjUgMzkxLDIwMCAzOTYsMTc1IDQwMSwxNDkgNDA2LDE3NCA0MTIsMTk5IDQxOCwyMjMgNDIzLDI0NCA0MjksMjY1IDQzNCwyODYgNDM5LDMwNyA0NDQsMzI1IDQ0OCwzMzkgTCA2NDQsMTA4MiA4MzcsMTA4MiAxMDI2LDMzOSBDIDEwMzEsMzIyIDEwMzYsMzAyIDEwNDEsMjgwIDEwNDYsMjU4IDEwNTEsMjM3IDEwNTYsMjE4IDEwNjEsMTk1IDEwNjcsMTcyIDEwNzIsMTQ5IDEwNzcsMTc0IDEwODMsMTk5IDEwODgsMjIzIDEwOTMsMjQ0IDEwOTgsMjY1IDExMDMsMjg4IDExMDgsMzEwIDExMTIsMzMwIDExMTcsMzQ3IEwgMTMwOCwxMDgyIDE0ODQsMTA4MiAxMTc0LDAgWiIvPgogICA8Z2x5cGggdW5pY29kZT0idiIgaG9yaXotYWR2LXg9IjEwMzMiIGQ9Ik0gNjEzLDAgTCA0MDAsMCA3LDEwODIgMTk5LDEwODIgNDM3LDM3OCBDIDQ0MiwzNjMgNDQ3LDM0NiA0NTQsMzI1IDQ2MCwzMDQgNDY2LDI4MiA0NzMsMjU5IDQ4MCwyMzYgNDg2LDIxNSA0OTIsMTk0IDQ5NywxNzMgNTAyLDE1NSA1MDYsMTQxIDUxMCwxNTUgNTE1LDE3MyA1MjIsMTk0IDUyOCwyMTUgNTM0LDIzNiA1NDEsMjU4IDU0OCwyODAgNTU1LDMwMiA1NjIsMzIzIDU2OSwzNDQgNTc1LDM2MSA1ODAsMzc2IEwgODI2LDEwODIgMTAxNywxMDgyIDYxMywwIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9InUiIGhvcml6LWFkdi14PSI4NzQiIGQ9Ik0gMzE0LDEwODIgTCAzMTQsMzk2IEMgMzE0LDM0MyAzMTgsMjk5IDMyNiwyNjQgMzMzLDIyOSAzNDYsMjAwIDM2MywxNzkgMzgwLDE1NyA0MDMsMTQyIDQzMiwxMzMgNDYwLDEyNCA0OTUsMTE5IDUzNywxMTkgNTgwLDExOSA2MTgsMTI3IDY1MywxNDIgNjg3LDE1NyA3MTYsMTc4IDc0MSwyMDcgNzY1LDIzNSA3ODQsMjcwIDc5NywzMTIgODEwLDM1MyA4MTcsNDAxIDgxNyw0NTUgTCA4MTcsMTA4MiA5OTcsMTA4MiA5OTcsMjMxIEMgOTk3LDIwOCA5OTcsMTg1IDk5OCwxNjAgOTk4LDEzNSA5OTgsMTExIDk5OSw4OSAxMDAwLDY2IDEwMDAsNDcgMTAwMSwzMSAxMDAyLDE1IDEwMDIsNSAxMDAzLDAgTCA4MzMsMCBDIDgzMiwzIDgzMiwxMiA4MzEsMjcgODMwLDQyIDgzMCw1OSA4MjksNzggODI4LDk3IDgyNywxMTYgODI2LDEzNiA4MjUsMTU1IDgyNSwxNzIgODI1LDE4NSBMIDgyMiwxODUgQyA4MDUsMTU0IDc4NiwxMjUgNzY1LDEwMCA3NDQsNzUgNzIwLDUzIDY5MywzNiA2NjYsMTggNjM0LDQgNTk5LC02IDU2NCwtMTUgNTIzLC0yMCA0NzYsLTIwIDQxNiwtMjAgMzY0LC0xMyAzMjEsMiAyNzgsMTcgMjQyLDM5IDIxNCw3MCAxODYsMTAxIDE2NiwxNDAgMTUzLDE4OCAxNDAsMjM2IDEzMywyOTQgMTMzLDM2MSBMIDEzMywxMDgyIDMxNCwxMDgyIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9InQiIGhvcml6LWFkdi14PSI1MzEiIGQ9Ik0gNTU0LDggQyA1MjcsMSA0OTksLTUgNDcxLC0xMCA0NDIsLTE0IDQwOSwtMTYgMzcyLC0xNiAyMjgsLTE2IDE1Niw2NiAxNTYsMjI5IEwgMTU2LDk1MSAzMSw5NTEgMzEsMTA4MiAxNjMsMTA4MiAyMTYsMTMyNCAzMzYsMTMyNCAzMzYsMTA4MiA1MzYsMTA4MiA1MzYsOTUxIDMzNiw5NTEgMzM2LDI2OCBDIDMzNiwyMTYgMzQ1LDE4MCAzNjIsMTU5IDM3OSwxMzggNDA4LDEyNyA0NTAsMTI3IDQ2NywxMjcgNDg0LDEyOCA1MDEsMTMxIDUxNywxMzQgNTM1LDEzNyA1NTQsMTQxIEwgNTU0LDggWiIvPgogICA8Z2x5cGggdW5pY29kZT0icyIgaG9yaXotYWR2LXg9IjkwMSIgZD0iTSA5NTAsMjk5IEMgOTUwLDI0OCA5NDAsMjAzIDkyMSwxNjQgOTAxLDEyNCA4NzIsOTEgODM1LDY0IDc5OCwzNyA3NTIsMTYgNjk4LDIgNjQzLC0xMyA1ODEsLTIwIDUxMSwtMjAgNDQ4LC0yMCAzOTIsLTE1IDM0MiwtNiAyOTEsNCAyNDcsMjAgMjA5LDQxIDE3MSw2MiAxMzksOTEgMTE0LDEyNiA4OCwxNjEgNjksMjAzIDU3LDI1NCBMIDIxNiwyODUgQyAyMzEsMjI3IDI2MywxODUgMzExLDE1OCAzNTksMTMxIDQyNiwxMTcgNTExLDExNyA1NTAsMTE3IDU4NSwxMjAgNjE4LDEyNSA2NTAsMTMwIDY3OCwxNDAgNzAxLDE1MyA3MjQsMTY2IDc0MywxODMgNzU2LDIwNSA3NjksMjI2IDc3NSwyNTMgNzc1LDI4NSA3NzUsMzE4IDc2NywzNDUgNzUyLDM2NiA3MzcsMzg3IDcxNSw0MDQgNjg4LDQxOCA2NjEsNDMyIDYyOCw0NDQgNTg5LDQ1NSA1NTAsNDY1IDUwNyw0NzYgNDYwLDQ4OSA0MTcsNTAwIDM3NCw1MTMgMzMxLDUyNyAyODgsNTQxIDI1MCw1NjAgMjE2LDU4MyAxODEsNjA2IDE1Myw2MzQgMTMyLDY2OCAxMTEsNzAyIDEwMCw3NDUgMTAwLDc5NiAxMDAsODk1IDEzNSw5NzAgMjA2LDEwMjIgMjc2LDEwNzMgMzc4LDEwOTkgNTEzLDEwOTkgNjMyLDEwOTkgNzI3LDEwNzggNzk4LDEwMzYgODY4LDk5NCA5MTIsOTI3IDkzMSw4MzQgTCA3NjksODE0IEMgNzYzLDg0MiA3NTIsODY2IDczNiw4ODUgNzIwLDkwNCA3MDEsOTE5IDY3OCw5MzEgNjU1LDk0MiA2MzAsOTUxIDYwMiw5NTYgNTczLDk2MSA1NDQsOTYzIDUxMyw5NjMgNDMyLDk2MyAzNzIsOTUxIDMzMyw5MjYgMjk0LDkwMSAyNzUsODY0IDI3NSw4MTQgMjc1LDc4NSAyODIsNzYxIDI5Nyw3NDIgMzExLDcyMyAzMzEsNzA3IDM1Nyw2OTQgMzgyLDY4MSA0MTMsNjY5IDQ0OSw2NjAgNDg1LDY1MCA1MjUsNjQwIDU2OCw2MjkgNTk3LDYyMiA2MjYsNjE0IDY1Niw2MDYgNjg2LDU5NyA3MTUsNTg3IDc0NCw1NzYgNzcyLDU2NCA3OTksNTUwIDgyNCw1MzUgODQ5LDUxOSA4NzAsNTAwIDg4OSw0NzggOTA4LDQ1NiA5MjMsNDMwIDkzNCw0MDEgOTQ1LDM3MiA5NTAsMzM4IDk1MCwyOTkgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iciIgaG9yaXotYWR2LXg9IjUzMCIgZD0iTSAxNDIsMCBMIDE0Miw4MzAgQyAxNDIsODUzIDE0Miw4NzYgMTQyLDkwMCAxNDEsOTIzIDE0MSw5NDYgMTQwLDk2OCAxMzksOTkwIDEzOSwxMDExIDEzOCwxMDMwIDEzNywxMDQ5IDEzNywxMDY3IDEzNiwxMDgyIEwgMzA2LDEwODIgQyAzMDcsMTA2NyAzMDgsMTA0OSAzMDksMTAzMCAzMTAsMTAxMCAzMTEsOTkwIDMxMiw5NjkgMzEzLDk0OCAzMTMsOTI5IDMxNCw5MTAgMzE0LDg5MSAzMTQsODc0IDMxNCw4NjEgTCAzMTgsODYxIEMgMzMxLDkwMiAzNDQsOTM4IDM1OSw5NjkgMzczLDk5OSAzOTAsMTAyNCA0MDksMTA0NCA0MjgsMTA2MyA0NTEsMTA3OCA0NzgsMTA4OCA1MDUsMTA5NyA1MzcsMTEwMiA1NzUsMTEwMiA1OTAsMTEwMiA2MDQsMTEwMSA2MTcsMTA5OSA2MzAsMTA5NiA2NDEsMTA5NCA2NDgsMTA5MiBMIDY0OCw5MjcgQyA2MzYsOTMwIDYyMiw5MzMgNjA2LDkzNSA1OTAsOTM2IDU3Miw5MzcgNTUyLDkzNyA1MTEsOTM3IDQ3Niw5MjggNDQ3LDkwOSA0MTgsODkwIDM5NCw4NjUgMzc2LDgzMiAzNTcsNzk5IDM0NCw3NTkgMzM1LDcxNCAzMjYsNjY4IDMyMiw2MTggMzIyLDU2NCBMIDMyMiwwIDE0MiwwIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9InAiIGhvcml6LWFkdi14PSI5NTMiIGQ9Ik0gMTA1Myw1NDYgQyAxMDUzLDQ2NCAxMDQ2LDM4OCAxMDMzLDMxOSAxMDIwLDI1MCA5OTgsMTkwIDk2NywxNDAgOTM2LDkwIDg5NSw1MSA4NDQsMjMgNzkzLC02IDczMCwtMjAgNjU1LC0yMCA1NzgsLTIwIDUxMCwtNSA0NTIsMjQgMzk0LDUzIDM1MCwxMDEgMzE5LDE2OCBMIDMxNCwxNjggQyAzMTUsMTY3IDMxNSwxNjEgMzE2LDE1MCAzMTYsMTM5IDMxNiwxMjYgMzE3LDExMCAzMTcsOTQgMzE3LDc2IDMxOCw1NyAzMTgsMzcgMzE4LDE3IDMxOCwtMiBMIDMxOCwtNDI1IDEzOCwtNDI1IDEzOCw4NjEgQyAxMzgsODg3IDEzOCw5MTIgMTM4LDkzNiAxMzcsOTYwIDEzNyw5ODIgMTM2LDEwMDIgMTM1LDEwMjEgMTM1LDEwMzggMTM0LDEwNTIgMTMzLDEwNjYgMTMzLDEwNzYgMTMyLDEwODIgTCAzMDYsMTA4MiBDIDMwNywxMDgwIDMwOCwxMDczIDMwOSwxMDYxIDMxMCwxMDQ5IDMxMSwxMDM1IDMxMiwxMDE4IDMxMywxMDAxIDMxNCw5ODIgMzE1LDk2MyAzMTYsOTQ0IDMxNiw5MjUgMzE2LDkwOCBMIDMyMCw5MDggQyAzMzcsOTQzIDM1Niw5NzIgMzc3LDk5NyAzOTgsMTAyMSA0MjMsMTA0MSA0NTAsMTA1NyA0NzcsMTA3MiA1MDgsMTA4NCA1NDIsMTA5MSA1NzUsMTA5OCA2MTMsMTEwMSA2NTUsMTEwMSA3MzAsMTEwMSA3OTMsMTA4OCA4NDQsMTA2MSA4OTUsMTAzNCA5MzYsOTk3IDk2Nyw5NDkgOTk4LDkwMCAxMDIwLDg0MiAxMDMzLDc3NCAxMDQ2LDcwNSAxMDUzLDYyOSAxMDUzLDU0NiBaIE0gODY0LDU0MiBDIDg2NCw2MDkgODYwLDY2OCA4NTIsNzIwIDg0NCw3NzIgODMwLDgxNiA4MTEsODUyIDc5MSw4ODggNzY1LDkxNSA3MzIsOTM0IDY5OSw5NTMgNjU4LDk2MiA2MDksOTYyIDU2OSw5NjIgNTMxLDk1NiA0OTYsOTQ1IDQ2MSw5MzQgNDMwLDkxMiA0MDQsODgwIDM3Nyw4NDggMzU2LDgwNCAzNDEsNzQ4IDMyNiw2OTEgMzE4LDYxOCAzMTgsNTI4IDMxOCw0NTEgMzI0LDM4NyAzMzcsMzM0IDM1MCwyODEgMzY4LDIzOCAzOTMsMjA1IDQxNywxNzIgNDQ3LDE0OSA0ODMsMTM1IDUxOSwxMjAgNTYwLDExMyA2MDcsMTEzIDY1NywxMTMgNjk5LDEyMyA3MzIsMTQyIDc2NSwxNjEgNzkxLDE4OSA4MTEsMjI2IDgzMCwyNjMgODQ0LDMwOCA4NTIsMzYxIDg2MCw0MTQgODY0LDQ3NCA4NjQsNTQyIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9Im8iIGhvcml6LWFkdi14PSI5ODAiIGQ9Ik0gMTA1Myw1NDIgQyAxMDUzLDM1MyAxMDExLDIxMiA5MjgsMTE5IDg0NSwyNiA3MjQsLTIwIDU2NSwtMjAgNDkwLC0yMCA0MjIsLTkgMzYzLDE0IDMwNCwzNyAyNTQsNzEgMjEzLDExOCAxNzIsMTY1IDE0MCwyMjMgMTE5LDI5NCA5NywzNjQgODYsNDQ3IDg2LDU0MiA4Niw5MTUgMjQ4LDExMDIgNTcxLDExMDIgNjU1LDExMDIgNzI4LDEwOTAgNzg5LDEwNjcgODUwLDEwNDQgOTAwLDEwMDkgOTM5LDk2MiA5NzgsOTE1IDEwMDYsODU3IDEwMjUsNzg3IDEwNDQsNzE3IDEwNTMsNjM1IDEwNTMsNTQyIFogTSA4NjQsNTQyIEMgODY0LDYyNiA4NTgsNjk1IDg0NSw3NTAgODMyLDgwNSA4MTMsODQ4IDc4OCw4ODEgNzYzLDkxNCA3MzIsOTM3IDY5Niw5NTAgNjYwLDk2MyA2MTksOTY5IDU3NCw5NjkgNTI4LDk2OSA0ODcsOTYyIDQ1MCw5NDkgNDEzLDkzNSAzODEsOTEyIDM1NSw4NzkgMzI5LDg0NiAzMDksODAyIDI5Niw3NDcgMjgyLDY5MiAyNzUsNjI0IDI3NSw1NDIgMjc1LDQ1OCAyODIsMzg5IDI5NywzMzQgMzEyLDI3OSAzMzIsMjM1IDM1OCwyMDIgMzgzLDE2OSA0MTQsMTQ2IDQ0OSwxMzMgNDg0LDEyMCA1MjIsMTEzIDU2MywxMTMgNjA5LDExMyA2NTEsMTIwIDY4OCwxMzMgNzI1LDE0NiA3NTcsMTY4IDc4MywyMDEgODA5LDIzNCA4MjksMjc4IDg0MywzMzMgODU3LDM4OCA4NjQsNDU4IDg2NCw1NDIgWiIvPgogICA8Z2x5cGggdW5pY29kZT0ibiIgaG9yaXotYWR2LXg9Ijg3NCIgZD0iTSA4MjUsMCBMIDgyNSw2ODYgQyA4MjUsNzM5IDgyMSw3ODMgODE0LDgxOCA4MDYsODUzIDc5Myw4ODIgNzc2LDkwNCA3NTksOTI1IDczNiw5NDEgNzA4LDk1MCA2NzksOTU5IDY0NCw5NjMgNjAyLDk2MyA1NTksOTYzIDUyMSw5NTYgNDg3LDk0MSA0NTIsOTI2IDQyMyw5MDQgMzk5LDg3NiAzNzQsODQ3IDM1NSw4MTIgMzQyLDc3MSAzMjksNzI5IDMyMiw2ODEgMzIyLDYyNyBMIDMyMiwwIDE0MiwwIDE0Miw4NTEgQyAxNDIsODc0IDE0Miw4OTggMTQyLDkyMyAxNDEsOTQ4IDE0MSw5NzEgMTQwLDk5NCAxMzksMTAxNiAxMzksMTAzNSAxMzgsMTA1MSAxMzcsMTA2NyAxMzcsMTA3NyAxMzYsMTA4MiBMIDMwNiwxMDgyIEMgMzA3LDEwNzkgMzA3LDEwNzAgMzA4LDEwNTUgMzA5LDEwNDAgMzEwLDEwMjQgMzExLDEwMDUgMzEyLDk4NiAzMTIsOTY2IDMxMyw5NDcgMzE0LDkyNyAzMTQsOTEwIDMxNCw4OTcgTCAzMTcsODk3IEMgMzM0LDkyOCAzNTMsOTU3IDM3NCw5ODIgMzk1LDEwMDcgNDE5LDEwMjkgNDQ2LDEwNDcgNDczLDEwNjQgNTA1LDEwNzggNTQwLDEwODggNTc1LDEwOTcgNjE2LDExMDIgNjYzLDExMDIgNzIzLDExMDIgNzc1LDEwOTUgODE4LDEwODAgODYxLDEwNjUgODk3LDEwNDMgOTI1LDEwMTIgOTUzLDk4MSA5NzQsOTQyIDk4Nyw4OTQgMTAwMCw4NDUgMTAwNiw3ODggMTAwNiw3MjEgTCAxMDA2LDAgODI1LDAgWiIvPgogICA8Z2x5cGggdW5pY29kZT0ibSIgaG9yaXotYWR2LXg9IjE0NTciIGQ9Ik0gNzY4LDAgTCA3NjgsNjg2IEMgNzY4LDczOSA3NjUsNzgzIDc1OCw4MTggNzUxLDg1MyA3NDAsODgyIDcyNSw5MDQgNzA5LDkyNSA2ODgsOTQxIDY2Myw5NTAgNjM4LDk1OSA2MDcsOTYzIDU3MCw5NjMgNTMyLDk2MyA0OTgsOTU2IDQ2Nyw5NDEgNDM2LDkyNiA0MTAsOTA0IDM4OSw4NzYgMzY3LDg0NyAzNTAsODEyIDMzOSw3NzEgMzI3LDcyOSAzMjEsNjgxIDMyMSw2MjcgTCAzMjEsMCAxNDIsMCAxNDIsODUxIEMgMTQyLDg3NCAxNDIsODk4IDE0Miw5MjMgMTQxLDk0OCAxNDEsOTcxIDE0MCw5OTQgMTM5LDEwMTYgMTM5LDEwMzUgMTM4LDEwNTEgMTM3LDEwNjcgMTM3LDEwNzcgMTM2LDEwODIgTCAzMDYsMTA4MiBDIDMwNywxMDc5IDMwNywxMDcwIDMwOCwxMDU1IDMwOSwxMDQwIDMxMCwxMDI0IDMxMSwxMDA1IDMxMiw5ODYgMzEyLDk2NiAzMTMsOTQ3IDMxNCw5MjcgMzE0LDkxMCAzMTQsODk3IEwgMzE3LDg5NyBDIDMzMyw5MjggMzUwLDk1NyAzNjksOTgyIDM4OCwxMDA3IDQxMCwxMDI5IDQzNSwxMDQ3IDQ2MCwxMDY0IDQ4OCwxMDc4IDUyMSwxMDg4IDU1MywxMDk3IDU5MCwxMTAyIDYzMywxMTAyIDcxNSwxMTAyIDc4MCwxMDg2IDgyOCwxMDUzIDg3NSwxMDIwIDkwOCw5NjggOTI3LDg5NyBMIDkzMCw4OTcgQyA5NDYsOTI4IDk2NCw5NTcgOTg0LDk4MiAxMDA0LDEwMDcgMTAyNywxMDI5IDEwNTQsMTA0NyAxMDgxLDEwNjQgMTExMSwxMDc4IDExNDQsMTA4OCAxMTc3LDEwOTcgMTIxNSwxMTAyIDEyNTgsMTEwMiAxMzEzLDExMDIgMTM2MCwxMDk1IDE0MDAsMTA4MCAxNDM5LDEwNjUgMTQ3MiwxMDQzIDE0OTcsMTAxMiAxNTIyLDk4MSAxNTQxLDk0MiAxNTUzLDg5NCAxNTY1LDg0NSAxNTcxLDc4OCAxNTcxLDcyMSBMIDE1NzEsMCAxMzkzLDAgMTM5Myw2ODYgQyAxMzkzLDczOSAxMzkwLDc4MyAxMzgzLDgxOCAxMzc2LDg1MyAxMzY1LDg4MiAxMzUwLDkwNCAxMzM0LDkyNSAxMzEzLDk0MSAxMjg4LDk1MCAxMjYzLDk1OSAxMjMyLDk2MyAxMTk1LDk2MyAxMTU3LDk2MyAxMTIzLDk1NiAxMDkyLDk0MiAxMDYxLDkyNyAxMDM1LDkwNiAxMDE0LDg3OCA5OTIsODUwIDk3NSw4MTUgOTY0LDc3MyA5NTIsNzMxIDk0Niw2ODIgOTQ2LDYyNyBMIDk0NiwwIDc2OCwwIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9ImwiIGhvcml6LWFkdi14PSIxODciIGQ9Ik0gMTM4LDAgTCAxMzgsMTQ4NCAzMTgsMTQ4NCAzMTgsMCAxMzgsMCBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSJrIiBob3Jpei1hZHYteD0iOTAxIiBkPSJNIDgxNiwwIEwgNDUwLDQ5NCAzMTgsMzg1IDMxOCwwIDEzOCwwIDEzOCwxNDg0IDMxOCwxNDg0IDMxOCw1NTcgNzkzLDEwODIgMTAwNCwxMDgyIDU2NSw2MTcgMTAyNywwIDgxNiwwIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9ImkiIGhvcml6LWFkdi14PSIxODciIGQ9Ik0gMTM3LDEzMTIgTCAxMzcsMTQ4NCAzMTcsMTQ4NCAzMTcsMTMxMiAxMzcsMTMxMiBaIE0gMTM3LDAgTCAxMzcsMTA4MiAzMTcsMTA4MiAzMTcsMCAxMzcsMCBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSJoIiBob3Jpei1hZHYteD0iODc0IiBkPSJNIDMxNyw4OTcgQyAzMzcsOTM0IDM1OSw5NjUgMzgyLDk5MSA0MDUsMTAxNiA0MzEsMTAzNyA0NTksMTA1NCA0ODcsMTA3MSA1MTgsMTA4MyA1NTEsMTA5MSA1ODQsMTA5OCA2MjIsMTEwMiA2NjMsMTEwMiA3MzIsMTEwMiA3ODksMTA5MyA4MzQsMTA3NCA4NzgsMTA1NSA5MTMsMTAyOSA5MzksOTk2IDk2NCw5NjIgOTgyLDkyMiA5OTIsODc1IDEwMDEsODI4IDEwMDYsNzc3IDEwMDYsNzIxIEwgMTAwNiwwIDgyNSwwIDgyNSw2ODYgQyA4MjUsNzMyIDgyMiw3NzIgODE3LDgwNyA4MTEsODQyIDgwMCw4NzEgNzg0LDg5NCA3NjgsOTE3IDc0NSw5MzQgNzE2LDk0NiA2ODcsOTU3IDY0OSw5NjMgNjAyLDk2MyA1NTksOTYzIDUyMSw5NTUgNDg3LDk0MCA0NTIsOTI1IDQyMyw5MDMgMzk5LDg3NSAzNzQsODQ3IDM1NSw4MTMgMzQyLDc3MyAzMjksNzMzIDMyMiw2ODggMzIyLDYzOCBMIDMyMiwwIDE0MiwwIDE0MiwxNDg0IDMyMiwxNDg0IDMyMiwxMDk4IEMgMzIyLDEwNzYgMzIyLDEwNTQgMzIxLDEwMzIgMzIwLDEwMTAgMzIwLDk5MCAzMTksOTcxIDMxOCw5NTIgMzE3LDkzNyAzMTYsOTI0IDMxNSw5MTEgMzE1LDkwMiAzMTQsODk3IEwgMzE3LDg5NyBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSJnIiBob3Jpei1hZHYteD0iOTI3IiBkPSJNIDU0OCwtNDI1IEMgNDg2LC00MjUgNDMxLC00MTkgMzgzLC00MDYgMzM1LC0zOTMgMjk0LC0zNzUgMjYwLC0zNTIgMjI2LC0zMjggMTk4LC0zMDAgMTc3LC0yNjcgMTU2LC0yMzQgMTQwLC0xOTggMTMxLC0xNTggTCAzMTIsLTEzMiBDIDMyNCwtMTgyIDM1MSwtMjIwIDM5MiwtMjQ4IDQzMywtMjc0IDQ4NiwtMjg4IDU1MywtMjg4IDU5NCwtMjg4IDYzMSwtMjgyIDY2NCwtMjcxIDY5NywtMjYwIDcyNiwtMjQxIDc0OSwtMjE3IDc3MiwtMTkxIDc5MCwtMTU5IDgwMywtMTE5IDgxNiwtNzkgODIyLC0zMCA4MjIsMjcgTCA4MjIsMjAxIDgyMCwyMDEgQyA4MDcsMTc0IDc5MCwxNDggNzcxLDEyMyA3NTEsOTggNzI3LDc1IDY5OSw1NiA2NzAsMzcgNjM3LDIxIDYwMCwxMCA1NjMsLTIgNTIwLC04IDQ3MiwtOCA0MDMsLTggMzQ1LDQgMjk2LDI3IDI0Nyw1MCAyMDcsODQgMTc2LDEzMCAxNDUsMTc2IDEyMiwyMzMgMTA4LDMwMiA5MywzNzAgODYsNDQ5IDg2LDUzOSA4Niw2MjYgOTMsNzA0IDEwOCw3NzMgMTIyLDg0MiAxNDUsOTAxIDE3OCw5NTAgMjEwLDk5OCAyNTIsMTAzNSAzMDQsMTA2MSAzNTUsMTA4NiA0MTgsMTA5OSA0OTIsMTA5OSA1NjksMTA5OSA2MzUsMTA4MiA2OTIsMTA0NyA3NDgsMTAxMiA3OTEsOTYyIDgyMiw4OTcgTCA4MjQsODk3IEMgODI0LDkxNCA4MjUsOTMyIDgyNiw5NTMgODI3LDk3NCA4MjgsOTkzIDgyOSwxMDEyIDgzMCwxMDMwIDgzMSwxMDQ2IDgzMiwxMDU5IDgzMywxMDcyIDgzNSwxMDgwIDgzNiwxMDgyIEwgMTAwNywxMDgyIEMgMTAwNiwxMDc2IDEwMDYsMTA2NiAxMDA1LDEwNTIgMTAwNCwxMDM3IDEwMDQsMTAyMCAxMDAzLDEwMDAgMTAwMiw5ODAgMTAwMiw5NTggMTAwMiw5MzQgMTAwMSw5MDkgMTAwMSw4ODQgMTAwMSw4NTggTCAxMDAxLDMxIEMgMTAwMSwtMTIwIDk2NCwtMjM0IDg5MCwtMzExIDgxNSwtMzg3IDcwMSwtNDI1IDU0OCwtNDI1IFogTSA4MjIsNTQxIEMgODIyLDYxNiA4MTQsNjgxIDc5OCw3MzUgNzgxLDc4OCA3NjAsODMyIDczMyw4NjYgNzA2LDkwMCA2NzYsOTI1IDY0Miw5NDEgNjA3LDk1NyA1NzIsOTY1IDUzNiw5NjUgNDkwLDk2NSA0NTEsOTU3IDQxOCw5NDEgMzg1LDkyNSAzNTcsOTAwIDMzNiw4NjYgMzE0LDgzMSAyOTgsNzg3IDI4OCw3MzQgMjc3LDY4MCAyNzIsNjE2IDI3Miw1NDEgMjcyLDQ2MyAyNzcsMzk4IDI4OCwzNDUgMjk4LDI5MiAzMTQsMjQ5IDMzNSwyMTYgMzU2LDE4MyAzODMsMTYwIDQxNiwxNDYgNDQ5LDEzMiA0ODgsMTI1IDUzMywxMjUgNTY5LDEyNSA2MDQsMTMzIDYzOSwxNDggNjczLDE2MyA3MDQsMTg4IDczMSwyMjEgNzU4LDI1NCA3ODAsMjk3IDc5NywzNTAgODE0LDQwMyA4MjIsNDY2IDgyMiw1NDEgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iZiIgaG9yaXotYWR2LXg9IjU1NyIgZD0iTSAzNjEsOTUxIEwgMzYxLDAgMTgxLDAgMTgxLDk1MSAyOSw5NTEgMjksMTA4MiAxODEsMTA4MiAxODEsMTIwNCBDIDE4MSwxMjQzIDE4NSwxMjgwIDE5MiwxMzE0IDE5OSwxMzQ3IDIxMywxMzc3IDIzMywxNDAyIDI1MiwxNDI3IDI3OSwxNDQ2IDMxMywxNDYxIDM0NywxNDc1IDM5MSwxNDgyIDQ0NSwxNDgyIDQ2NiwxNDgyIDQ4OSwxNDgxIDUxMiwxNDc5IDUzNSwxNDc3IDU1NSwxNDc0IDU3MiwxNDcwIEwgNTcyLDEzMzMgQyA1NjEsMTMzNSA1NDgsMTMzNyA1MzMsMTMzOSA1MTgsMTM0MCA1MDQsMTM0MSA0OTIsMTM0MSA0NjUsMTM0MSA0NDQsMTMzNyA0MjcsMTMzMCA0MTAsMTMyMyAzOTYsMTMxMiAzODcsMTI5OSAzNzcsMTI4NSAzNzAsMTI2OCAzNjcsMTI0OCAzNjMsMTIyOCAzNjEsMTIwNSAzNjEsMTE3OSBMIDM2MSwxMDgyIDU3MiwxMDgyIDU3Miw5NTEgMzYxLDk1MSBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSJlIiBob3Jpei1hZHYteD0iOTgwIiBkPSJNIDI3Niw1MDMgQyAyNzYsNDQ2IDI4MiwzOTQgMjk0LDM0NyAzMDUsMjk5IDMyMywyNTggMzQ4LDIyNCAzNzIsMTg5IDQwMywxNjMgNDQxLDE0NCA0NzksMTI1IDUyNSwxMTUgNTc4LDExNSA2NTYsMTE1IDcxOSwxMzEgNzY2LDE2MiA4MTMsMTkzIDg0NCwyMzMgODYxLDI4MSBMIDEwMTksMjM2IEMgMTAwOCwyMDYgOTkyLDE3NiA5NzIsMTQ2IDk1MSwxMTUgOTI0LDg4IDg5MCw2NCA4NTYsMzkgODE0LDE5IDc2Myw0IDcxMiwtMTIgNjUwLC0yMCA1NzgsLTIwIDQxOCwtMjAgMjk2LDI4IDIxMywxMjMgMTI5LDIxOCA4NywzNjAgODcsNTQ4IDg3LDY0OSAxMDAsNzM1IDEyNSw4MDYgMTUwLDg3NiAxODUsOTMzIDIyOSw5NzcgMjczLDEwMjEgMzI0LDEwNTMgMzgzLDEwNzMgNDQyLDEwOTIgNTA0LDExMDIgNTcxLDExMDIgNjYyLDExMDIgNzM4LDEwODcgNzk5LDEwNTggODYwLDEwMjkgOTA5LDk4OCA5NDYsOTM3IDk4Myw4ODUgMTAwOSw4MjQgMTAyNSw3NTQgMTA0MCw2ODQgMTA0OCw2MDggMTA0OCw1MjcgTCAxMDQ4LDUwMyAyNzYsNTAzIFogTSA4NjIsNjQxIEMgODUyLDc1NSA4MjMsODM4IDc3NSw4OTEgNzI3LDk0MyA2NTgsOTY5IDU2OCw5NjkgNTM4LDk2OSA1MDcsOTY0IDQ3NCw5NTUgNDQxLDk0NSA0MTAsOTI4IDM4Miw5MDMgMzU0LDg3OCAzMzAsODQ1IDMxMSw4MDMgMjkyLDc2MCAyODEsNzA2IDI3OCw2NDEgTCA4NjIsNjQxIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9ImQiIGhvcml6LWFkdi14PSI5MjciIGQ9Ik0gODIxLDE3NCBDIDc4OCwxMDUgNzQ0LDU1IDY4OSwyNSA2MzQsLTUgNTY1LC0yMCA0ODQsLTIwIDM0NywtMjAgMjQ3LDI2IDE4MywxMTggMTE4LDIxMCA4NiwzNDkgODYsNTM2IDg2LDkxMyAyMTksMTEwMiA0ODQsMTEwMiA1NjYsMTEwMiA2MzQsMTA4NyA2ODksMTA1NyA3NDQsMTAyNyA3ODgsOTc5IDgyMSw5MTQgTCA4MjMsOTE0IEMgODIzLDkyMSA4MjMsOTMxIDgyMyw5NDYgODIyLDk2MCA4MjIsOTc1IDgyMiw5OTEgODIxLDEwMDYgODIxLDEwMjEgODIxLDEwMzUgODIxLDEwNDkgODIxLDEwNTkgODIxLDEwNjUgTCA4MjEsMTQ4NCAxMDAxLDE0ODQgMTAwMSwyMjMgQyAxMDAxLDE5NyAxMDAxLDE3MiAxMDAyLDE0OCAxMDAyLDEyNCAxMDAyLDEwMiAxMDAzLDgyIDEwMDQsNjIgMTAwNCw0NSAxMDA1LDMxIDEwMDYsMTYgMTAwNiw2IDEwMDcsMCBMIDgzNSwwIEMgODM0LDcgODMzLDE2IDgzMiwyOSA4MzEsNDEgODMwLDU1IDgyOSw3MSA4MjgsODcgODI3LDEwNCA4MjYsMTIyIDgyNSwxMzkgODI1LDE1NyA4MjUsMTc0IEwgODIxLDE3NCBaIE0gMjc1LDU0MiBDIDI3NSw0NjcgMjgwLDQwMyAyODksMzUwIDI5OCwyOTcgMzEzLDI1MyAzMzQsMjE5IDM1NSwxODQgMzgxLDE1OSA0MTMsMTQzIDQ0NSwxMjcgNDg0LDExOSA1MzAsMTE5IDU3NywxMTkgNjE5LDEyNyA2NTYsMTQyIDY5MiwxNTcgNzIyLDE4MiA3NDcsMjE3IDc3MSwyNTEgNzg5LDI5NiA4MDIsMzUxIDgxNSw0MDYgODIxLDQ3NCA4MjEsNTU0IDgyMSw2MzEgODE1LDY5NiA4MDIsNzQ5IDc4OSw4MDIgNzcxLDg0NCA3NDYsODc3IDcyMSw5MTAgNjkxLDkzMyA2NTYsOTQ4IDYyMCw5NjIgNTc5LDk2OSA1MzIsOTY5IDQ4OCw5NjkgNDUwLDk2MSA0MTgsOTQ2IDM4Niw5MzEgMzU5LDkwNiAzMzgsODcyIDMxNyw4MzggMzAxLDc5NCAyOTEsNzQwIDI4MCw2ODUgMjc1LDYxOSAyNzUsNTQyIFoiLz4KICAgPGdseXBoIHVuaWNvZGU9ImMiIGhvcml6LWFkdi14PSI5MDEiIGQ9Ik0gMjc1LDU0NiBDIDI3NSw0ODQgMjgwLDQyNyAyODksMzc1IDI5OCwzMjMgMzEzLDI3OCAzMzQsMjQxIDM1NSwyMDMgMzg0LDE3NCA0MTksMTUzIDQ1NCwxMzIgNDk3LDEyMiA1NDgsMTIyIDYxMiwxMjIgNjY2LDEzOSA3MDksMTczIDc1MiwyMDYgNzc4LDI1OCA3ODgsMzI4IEwgOTcwLDMyOCBDIDk2NCwyODMgOTUxLDIzOSA5MzEsMTk3IDkxMSwxNTUgODg0LDExOCA4NTAsODYgODE1LDU0IDc3MywyOCA3MjQsOSA2NzUsLTEwIDYxOCwtMjAgNTUzLC0yMCA0NjgsLTIwIDM5NiwtNiAzMzcsMjMgMjc4LDUyIDIzMCw5MSAxOTMsMTQyIDE1NiwxOTIgMTI5LDI1MSAxMTIsMzIwIDk1LDM4OCA4Nyw0NjIgODcsNTQyIDg3LDYxNSA5Myw2NzkgMTA1LDczNSAxMTcsNzkwIDEzNCw4MzkgMTU2LDg4MSAxNzcsOTIyIDIwMyw5NTcgMjMyLDk4NiAyNjEsMTAxNCAyOTMsMTAzNyAzMjgsMTA1NCAzNjIsMTA3MSAzOTgsMTA4MyA0MzYsMTA5MSA0NzQsMTA5OCA1MTIsMTEwMiA1NTEsMTEwMiA2MTIsMTEwMiA2NjYsMTA5NCA3MTMsMTA3NyA3NjAsMTA2MCA4MDEsMTAzOCA4MzYsMTAwOSA4NzAsOTgwIDg5OCw5NDUgOTE5LDkwNiA5NDAsODY3IDk1NSw4MjQgOTY0LDc3OSBMIDc3OSw3NjUgQyA3NzAsODI1IDc0Niw4NzMgNzA4LDkwOCA2NzAsOTQzIDYxNiw5NjEgNTQ2LDk2MSA0OTUsOTYxIDQ1Miw5NTMgNDE4LDkzNiAzODMsOTE5IDM1NSw4OTMgMzM0LDg1OSAzMTMsODI0IDI5OCw3ODEgMjg5LDcyOSAyODAsNjc3IDI3NSw2MTYgMjc1LDU0NiBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSJiIiBob3Jpei1hZHYteD0iOTUzIiBkPSJNIDEwNTMsNTQ2IEMgMTA1MywxNjkgOTIwLC0yMCA2NTUsLTIwIDU3MywtMjAgNTA1LC01IDQ1MSwyNSAzOTYsNTQgMzUyLDEwMiAzMTgsMTY4IEwgMzE2LDE2OCBDIDMxNiwxNTEgMzE2LDEzMyAzMTUsMTE0IDMxNCw5NSAzMTMsNzggMzEyLDYyIDMxMSw0NiAzMTAsMzIgMzA5LDIxIDMwOCwxMCAzMDcsMyAzMDYsMCBMIDEzMiwwIEMgMTMzLDYgMTMzLDE2IDEzNCwzMSAxMzUsNDUgMTM1LDYyIDEzNiw4MiAxMzcsMTAyIDEzNywxMjQgMTM4LDE0OCAxMzgsMTcyIDEzOCwxOTcgMTM4LDIyMyBMIDEzOCwxNDg0IDMxOCwxNDg0IDMxOCwxMDYxIEMgMzE4LDEwNDEgMzE4LDEwMjIgMzE4LDEwMDQgMzE3LDk4NSAzMTcsOTY5IDMxNiw5NTUgMzE1LDkzOCAzMTUsOTIzIDMxNCw5MDggTCAzMTgsOTA4IEMgMzUxLDk3NyAzOTYsMTAyNyA0NTEsMTA1NyA1MDYsMTA4NyA1NzQsMTEwMiA2NTUsMTEwMiA3OTIsMTEwMiA4OTIsMTA1NiA5NTcsOTY0IDEwMjEsODcyIDEwNTMsNzMzIDEwNTMsNTQ2IFogTSA4NjQsNTQwIEMgODY0LDYxNSA4NTksNjc5IDg1MCw3MzIgODQxLDc4NSA4MjYsODI5IDgwNSw4NjQgNzg0LDg5OCA3NTgsOTIzIDcyNiw5MzkgNjk0LDk1NSA2NTUsOTYzIDYwOSw5NjMgNTYyLDk2MyA1MjAsOTU1IDQ4NCw5NDAgNDQ3LDkyNSA0MTcsOTAwIDM5Myw4NjYgMzY4LDgzMiAzNTAsNzg3IDMzNyw3MzIgMzI0LDY3NyAzMTgsNjA5IDMxOCw1MjkgMzE4LDQ1MiAzMjQsMzg3IDMzNywzMzQgMzUwLDI4MSAzNjgsMjM5IDM5MywyMDYgNDE3LDE3MyA0NDcsMTQ5IDQ4MywxMzUgNTE5LDEyMCA1NjAsMTEzIDYwNywxMTMgNjUxLDExMyA2ODksMTIxIDcyMSwxMzYgNzUzLDE1MSA3ODAsMTc2IDgwMSwyMTAgODIyLDI0NCA4MzgsMjg4IDg0OSwzNDMgODU5LDM5NyA4NjQsNDYzIDg2NCw1NDAgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iYSIgaG9yaXotYWR2LXg9IjEwNjAiIGQ9Ik0gNDE0LC0yMCBDIDMwNSwtMjAgMjI0LDkgMTY5LDY2IDExNCwxMjQgODcsMjAzIDg3LDMwMyA4NywzNzUgMTAxLDQzNCAxMjgsNDgwIDE1NSw1MjYgMTkwLDU2MiAyMzQsNTg4IDI3Nyw2MTQgMzI3LDYzMiAzODMsNjQyIDQzOSw2NTIgNDk2LDY1NyA1NTQsNjU3IEwgNzk3LDY1NyA3OTcsNzE3IEMgNzk3LDc2MiA3OTIsODAwIDc4Myw4MzIgNzc0LDg2MyA3NTksODg5IDc0MCw5MDggNzIxLDkyOCA2OTcsOTQyIDY2OCw5NTEgNjM5LDk2MCA2MDQsOTY1IDU2NSw5NjUgNTMwLDk2NSA0OTksOTYzIDQ3MSw5NTggNDQzLDk1MyA0MTksOTQ0IDM5OCw5MzEgMzc3LDkxOCAzNjEsOTAwIDM0OCw4NzggMzM1LDg1NSAzMjcsODI3IDMyMyw3OTMgTCAxMzUsODEwIEMgMTQyLDg1MyAxNTQsODkyIDE3Myw5MjggMTkyLDk2MyAyMTgsOTk0IDI1MywxMDIwIDI4NywxMDQ2IDMzMCwxMDY2IDM4MiwxMDgxIDQzMywxMDk1IDQ5NiwxMTAyIDU2OSwxMTAyIDcwNSwxMTAyIDgwNywxMDcxIDg3NiwxMDA5IDk0NSw5NDYgOTc5LDg1NiA5NzksNzM4IEwgOTc5LDI3MiBDIDk3OSwyMTkgOTg2LDE3OSAxMDAwLDE1MiAxMDE0LDEyNSAxMDQxLDExMSAxMDgwLDExMSAxMDkwLDExMSAxMTAwLDExMiAxMTEwLDExMyAxMTIwLDExNCAxMTMwLDExNiAxMTM5LDExOCBMIDExMzksNiBDIDExMTYsMSAxMDk0LC0zIDEwNzIsLTYgMTA0OSwtOSAxMDI1LC0xMCAxMDAwLC0xMCA5NjYsLTEwIDkzNywtNSA5MTMsNCA4ODgsMTMgODY4LDI2IDg1Myw0NSA4MzgsNjMgODI2LDg2IDgxOCwxMTMgODEwLDE0MCA4MDUsMTcxIDgwMywyMDcgTCA3OTcsMjA3IEMgNzc4LDE3MiA3NTcsMTQxIDczNCwxMTMgNzExLDg1IDY4NCw2MSA2NTMsNDIgNjIyLDIyIDU4OCw3IDU0OSwtNCA1MTAsLTE1IDQ2NSwtMjAgNDE0LC0yMCBaIE0gNDU1LDExNSBDIDUxMiwxMTUgNTYzLDEyNSA2MDYsMTQ2IDY0OSwxNjcgNjg0LDE5NCA3MTMsMjI2IDc0MSwyNTkgNzYyLDI5NCA3NzYsMzMyIDc5MCwzNzEgNzk3LDQwOCA3OTcsNDQzIEwgNzk3LDUzMSA2MDAsNTMxIEMgNTU2LDUzMSA1MTQsNTI4IDQ3NSw1MjIgNDM1LDUxNyA0MDAsNTA2IDM3MCw0ODkgMzQwLDQ3MiAzMTYsNDQ5IDI5OSw0MTggMjgxLDM4OCAyNzIsMzQ5IDI3MiwzMDAgMjcyLDI0MSAyODgsMTk1IDMyMCwxNjMgMzUxLDEzMSAzOTYsMTE1IDQ1NSwxMTUgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iUyIgaG9yaXotYWR2LXg9IjExOTIiIGQ9Ik0gMTI3MiwzODkgQyAxMjcyLDMzMCAxMjYxLDI3NSAxMjM4LDIyNSAxMjE1LDE3NSAxMTc5LDEzMiAxMTMxLDk2IDEwODMsNTkgMTAyMywzMSA5NTAsMTEgODc3LC0xMCA3OTAsLTIwIDY5MCwtMjAgNTE1LC0yMCAzNzgsMTEgMjgwLDcyIDE4MiwxMzMgMTIwLDIyMiA5MywzMzggTCAyNzgsMzc1IEMgMjg3LDMzOCAzMDIsMzA1IDMyMSwyNzUgMzQwLDI0NSAzNjcsMjE5IDQwMCwxOTggNDMzLDE3NiA0NzMsMTU5IDUyMiwxNDcgNTcxLDEzNSA2MjksMTI5IDY5NywxMjkgNzU0LDEyOSA4MDYsMTM0IDg1MywxNDQgOTAwLDE1MyA5NDEsMTY4IDk3NSwxODggMTAwOSwyMDggMTAzNiwyMzQgMTA1NSwyNjYgMTA3NCwyOTcgMTA4MywzMzUgMTA4MywzNzkgMTA4Myw0MjUgMTA3Myw0NjIgMTA1Miw0OTEgMTAzMSw1MjAgMTAwMSw1NDMgOTYzLDU2MiA5MjUsNTgxIDg4MCw1OTYgODI3LDYwOSA3NzQsNjIyIDcxNiw2MzUgNjUyLDY1MCA2MTMsNjU5IDU3Myw2NjggNTM0LDY3OSA0OTQsNjg5IDQ1Niw3MDEgNDIwLDcxNiAzODMsNzMwIDM0OSw3NDcgMzE3LDc2NiAyODUsNzg1IDI1Nyw4MDkgMjM0LDgzNiAyMTEsODYzIDE5Miw4OTQgMTc5LDkzMCAxNjYsOTY1IDE1OSwxMDA2IDE1OSwxMDUzIDE1OSwxMTIwIDE3MywxMTc3IDIwMCwxMjI1IDIyNywxMjcyIDI2NCwxMzExIDMxMiwxMzQyIDM2MCwxMzczIDQxNywxMzk1IDQ4MiwxNDA5IDU0NywxNDIzIDYxOCwxNDMwIDY5NCwxNDMwIDc4MSwxNDMwIDg1NiwxNDIzIDkxOCwxNDEwIDk4MCwxMzk2IDEwMzIsMTM3NSAxMDc1LDEzNDggMTExOCwxMzIxIDExNTIsMTI4NyAxMTc4LDEyNDcgMTIwMywxMjA2IDEyMjQsMTE1OSAxMjM5LDExMDYgTCAxMDUxLDEwNzMgQyAxMDQyLDExMDcgMTAyOCwxMTM3IDEwMTEsMTE2NCA5OTMsMTE5MSA5NzAsMTIxMyA5NDEsMTIzMSA5MTIsMTI0OSA4NzgsMTI2MyA4MzcsMTI3MiA3OTYsMTI4MSA3NDcsMTI4NiA2OTIsMTI4NiA2MjcsMTI4NiA1NzIsMTI4MCA1MjgsMTI2OSA0ODMsMTI1NyA0NDgsMTI0MSA0MjEsMTIyMSAzOTQsMTIwMSAzNzQsMTE3OCAzNjMsMTE1MSAzNTEsMTEyNCAzNDUsMTA5NCAzNDUsMTA2MyAzNDUsMTAyMSAzNTYsOTg3IDM3Nyw5NjAgMzk4LDkzMyA0MjYsOTEwIDQ2Miw4OTIgNDk4LDg3NCA1NDAsODU5IDU4Nyw4NDcgNjM0LDgzNSA2ODUsODIzIDczOCw4MTEgNzgxLDgwMSA4MjUsNzkxIDg2OCw3ODEgOTExLDc3MCA5NTIsNzU4IDk5MSw3NDQgMTAzMCw3MjkgMTA2Nyw3MTIgMTEwMiw2OTMgMTEzNiw2NzQgMTE2Niw2NTAgMTE5MSw2MjIgMTIxNiw1OTQgMTIzNiw1NjEgMTI1MSw1MjMgMTI2NSw0ODUgMTI3Miw0NDAgMTI3MiwzODkgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iTyIgaG9yaXotYWR2LXg9IjE0MzAiIGQ9Ik0gMTQ5NSw3MTEgQyAxNDk1LDYwMSAxNDc5LDUwMSAxNDQ4LDQxMSAxNDE2LDMyMSAxMzcwLDI0NCAxMzEwLDE4MCAxMjUwLDExNiAxMTc3LDY3IDEwOTAsMzIgMTAwMywtMyA5MDUsLTIwIDc5NSwtMjAgNjc5LC0yMCA1NzcsLTIgNDkwLDM1IDQwMyw3MSAzMzAsMTIyIDI3MiwxODcgMjE0LDI1MiAxNzAsMzI5IDE0MSw0MTggMTEyLDUwNyA5Nyw2MDUgOTcsNzExIDk3LDgyMSAxMTIsOTIwIDE0MywxMDA5IDE3NCwxMDk4IDIxOSwxMTczIDI3OCwxMjM2IDMzNywxMjk4IDQxMSwxMzQ2IDQ5OCwxMzgwIDU4NSwxNDEzIDY4NCwxNDMwIDc5NywxNDMwIDkwOSwxNDMwIDEwMDksMTQxMyAxMDk2LDEzNzkgMTE4MywxMzQ1IDEyNTYsMTI5NyAxMzE1LDEyMzQgMTM3NCwxMTcxIDE0MTgsMTA5NiAxNDQ5LDEwMDcgMTQ4MCw5MTggMTQ5NSw4MjAgMTQ5NSw3MTEgWiBNIDEzMDAsNzExIEMgMTMwMCw3OTYgMTI4OSw4NzMgMTI2OCw5NDIgMTI0NiwxMDExIDEyMTQsMTA3MSAxMTcyLDExMjAgMTEyOSwxMTY5IDEwNzcsMTIwNyAxMDE0LDEyMzQgOTUxLDEyNjEgODc5LDEyNzQgNzk3LDEyNzQgNzEzLDEyNzQgNjM5LDEyNjEgNTc2LDEyMzQgNTEzLDEyMDcgNDYwLDExNjkgNDE4LDExMjAgMzc1LDEwNzEgMzQ0LDEwMTEgMzIzLDk0MiAzMDIsODczIDI5MSw3OTYgMjkxLDcxMSAyOTEsNjI2IDMwMiw1NDkgMzI0LDQ3OSAzNDUsNDA4IDM3NywzNDggNDIwLDI5NyA0NjIsMjQ2IDUxNSwyMDYgNTc4LDE3OCA2NDEsMTQ5IDcxMywxMzUgNzk1LDEzNSA4ODMsMTM1IDk1OSwxNDkgMTAyMywxNzggMTA4NiwyMDcgMTEzOSwyNDcgMTE4MCwyOTggMTIyMSwzNDkgMTI1MSw0MDkgMTI3MSw0ODAgMTI5MCw1NTEgMTMwMCw2MjggMTMwMCw3MTEgWiIvPgogICA8Z2x5cGggdW5pY29kZT0iQyIgaG9yaXotYWR2LXg9IjEzMjQiIGQ9Ik0gNzkyLDEyNzQgQyA3MTIsMTI3NCA2NDEsMTI2MSA1ODAsMTIzNCA1MTgsMTIwNyA0NjYsMTE2OSA0MjUsMTEyMCAzODMsMTA3MSAzNTEsMTAxMSAzMzAsOTQyIDMwOSw4NzMgMjk4LDc5NiAyOTgsNzExIDI5OCw2MjYgMzEwLDU0OSAzMzMsNDc5IDM1Niw0MDggMzg5LDM0OCA0MzIsMjk3IDQ3NSwyNDYgNTI3LDIwNyA1OTAsMTc5IDY1MiwxNTEgNzIyLDEzNyA4MDAsMTM3IDg1NSwxMzcgOTA1LDE0NCA5NTAsMTU5IDk5NSwxNzMgMTAzNSwxOTMgMTA3MiwyMTkgMTEwOCwyNDUgMTE0MCwyNzYgMTE2OSwzMTIgMTE5OCwzNDcgMTIyMywzODcgMTI0NSw0MzAgTCAxNDAxLDM1MiBDIDEzNzYsMjk5IDEzNDQsMjUwIDEzMDcsMjA1IDEyNzAsMTYwIDEyMjYsMTIwIDExNzYsODcgMTEyNSw1NCAxMDY4LDI4IDEwMDUsOSA5NDEsLTEwIDg3MCwtMjAgNzkxLC0yMCA2NzcsLTIwIDU3NywtMiA0OTIsMzUgNDA2LDcxIDMzNCwxMjIgMjc3LDE4NyAyMTksMjUyIDE3NiwzMjkgMTQ3LDQxOCAxMTgsNTA3IDEwNCw2MDUgMTA0LDcxMSAxMDQsODIxIDExOSw5MjAgMTUwLDEwMDkgMTgwLDEwOTggMjI0LDExNzMgMjgzLDEyMzYgMzQxLDEyOTggNDEzLDEzNDYgNDk4LDEzODAgNTgzLDE0MTMgNjgxLDE0MzAgNzkwLDE0MzAgOTQwLDE0MzAgMTA2NSwxNDAxIDExNjYsMTM0MiAxMjY3LDEyODMgMTM0MSwxMTk2IDEzODgsMTA4MSBMIDEyMDcsMTAyMSBDIDExOTQsMTA1NCAxMTc2LDEwODYgMTE1MywxMTE3IDExMzAsMTE0NyAxMTAyLDExNzQgMTA2OCwxMTk3IDEwMzQsMTIyMCA5OTQsMTIzOSA5NDksMTI1MyA5MDMsMTI2NyA4NTEsMTI3NCA3OTIsMTI3NCBaIi8+CiAgIDxnbHlwaCB1bmljb2RlPSIgIiBob3Jpei1hZHYteD0iNTU2Ii8+CiAgPC9mb250PgogPC9kZWZzPgogPGRlZnMgY2xhc3M9IlRleHRTaGFwZUluZGV4Ij4KICA8ZyBvb286c2xpZGU9ImlkMSIgb29vOmlkLWxpc3Q9ImlkMyBpZDQgaWQ1IGlkNiBpZDcgaWQ4IGlkOSBpZDEwIGlkMTEgaWQxMiBpZDEzIGlkMTQgaWQxNSBpZDE2IGlkMTcgaWQxOCBpZDE5Ii8+CiA8L2RlZnM+CiA8ZGVmcyBjbGFzcz0iRW1iZWRkZWRCdWxsZXRDaGFycyI+CiAgPGcgaWQ9ImJ1bGxldC1jaGFyLXRlbXBsYXRlKDU3MzU2KSIgdHJhbnNmb3JtPSJzY2FsZSgwLjAwMDQ4ODI4MTI1LC0wLjAwMDQ4ODI4MTI1KSI+CiAgIDxwYXRoIGQ9Ik0gNTgwLDExNDEgTCAxMTYzLDU3MSA1ODAsMCAtNCw1NzEgNTgwLDExNDEgWiIvPgogIDwvZz4KICA8ZyBpZD0iYnVsbGV0LWNoYXItdGVtcGxhdGUoNTczNTQpIiB0cmFuc2Zvcm09InNjYWxlKDAuMDAwNDg4MjgxMjUsLTAuMDAwNDg4MjgxMjUpIj4KICAgPHBhdGggZD0iTSA4LDExMjggTCAxMTM3LDExMjggMTEzNywwIDgsMCA4LDExMjggWiIvPgogIDwvZz4KICA8ZyBpZD0iYnVsbGV0LWNoYXItdGVtcGxhdGUoMTAxNDYpIiB0cmFuc2Zvcm09InNjYWxlKDAuMDAwNDg4MjgxMjUsLTAuMDAwNDg4MjgxMjUpIj4KICAgPHBhdGggZD0iTSAxNzQsMCBMIDYwMiw3MzkgMTc0LDE0ODEgMTQ1Niw3MzkgMTc0LDAgWiBNIDEzNTgsNzM5IEwgMzA5LDEzNDYgNjU5LDczOSAxMzU4LDczOSBaIi8+CiAgPC9nPgogIDxnIGlkPSJidWxsZXQtY2hhci10ZW1wbGF0ZSgxMDEzMikiIHRyYW5zZm9ybT0ic2NhbGUoMC4wMDA0ODgyODEyNSwtMC4wMDA0ODgyODEyNSkiPgogICA8cGF0aCBkPSJNIDIwMTUsNzM5IEwgMTI3NiwwIDcxNywwIDEyNjAsNTQzIDE3NCw1NDMgMTc0LDkzNiAxMjYwLDkzNiA3MTcsMTQ4MSAxMjc0LDE0ODEgMjAxNSw3MzkgWiIvPgogIDwvZz4KICA8ZyBpZD0iYnVsbGV0LWNoYXItdGVtcGxhdGUoMTAwMDcpIiB0cmFuc2Zvcm09InNjYWxlKDAuMDAwNDg4MjgxMjUsLTAuMDAwNDg4MjgxMjUpIj4KICAgPHBhdGggZD0iTSAwLC0yIEMgLTcsMTQgLTE2LDI3IC0yNSwzNyBMIDM1Niw1NjcgQyAyNjIsODIzIDIxNSw5NTIgMjE1LDk1NCAyMTUsOTc5IDIyOCw5OTIgMjU1LDk5MiAyNjQsOTkyIDI3Niw5OTAgMjg5LDk4NyAzMTAsOTkxIDMzMSw5OTkgMzU0LDEwMTIgTCAzODEsOTk5IDQ5Miw3NDggNzcyLDEwNDkgODM2LDEwMjQgODYwLDEwNDkgQyA4ODEsMTAzOSA5MDEsMTAyNSA5MjIsMTAwNiA4ODYsOTM3IDgzNSw4NjMgNzcwLDc4NCA3NjksNzgzIDcxMCw3MTYgNTk0LDU4NCBMIDc3NCwyMjMgQyA3NzQsMTk2IDc1MywxNjggNzExLDEzOSBMIDcyNywxMTkgQyA3MTcsOTAgNjk5LDc2IDY3Miw3NiA2NDEsNzYgNTcwLDE3OCA0NTcsMzgxIEwgMTY0LC03NiBDIDE0MiwtMTEwIDExMSwtMTI3IDcyLC0xMjcgMzAsLTEyNyA5LC0xMTAgOCwtNzYgMSwtNjcgLTIsLTUyIC0yLC0zMiAtMiwtMjMgLTEsLTEzIDAsLTIgWiIvPgogIDwvZz4KICA8ZyBpZD0iYnVsbGV0LWNoYXItdGVtcGxhdGUoMTAwMDQpIiB0cmFuc2Zvcm09InNjYWxlKDAuMDAwNDg4MjgxMjUsLTAuMDAwNDg4MjgxMjUpIj4KICAgPHBhdGggZD0iTSAyODUsLTMzIEMgMTgyLC0zMyAxMTEsMzAgNzQsMTU2IDUyLDIyOCA0MSwzMzMgNDEsNDcxIDQxLDU0OSA1NSw2MTYgODIsNjcyIDExNiw3NDMgMTY5LDc3OCAyNDAsNzc4IDI5Myw3NzggMzI4LDc0NyAzNDYsNjg0IEwgMzY5LDUwOCBDIDM3Nyw0NDQgMzk3LDQxMSA0MjgsNDEwIEwgMTE2MywxMTE2IEMgMTE3NCwxMTI3IDExOTYsMTEzMyAxMjI5LDExMzMgMTI3MSwxMTMzIDEyOTIsMTExOCAxMjkyLDEwODcgTCAxMjkyLDk2NSBDIDEyOTIsOTI5IDEyODIsOTAxIDEyNjIsODgxIEwgNDQyLDQ3IEMgMzkwLC02IDMzOCwtMzMgMjg1LC0zMyBaIi8+CiAgPC9nPgogIDxnIGlkPSJidWxsZXQtY2hhci10ZW1wbGF0ZSg5Njc5KSIgdHJhbnNmb3JtPSJzY2FsZSgwLjAwMDQ4ODI4MTI1LC0wLjAwMDQ4ODI4MTI1KSI+CiAgIDxwYXRoIGQ9Ik0gODEzLDAgQyA2MzIsMCA0ODksNTQgMzgzLDE2MSAyNzYsMjY4IDIyMyw0MTEgMjIzLDU5MiAyMjMsNzczIDI3Niw5MTYgMzgzLDEwMjMgNDg5LDExMzAgNjMyLDExODQgODEzLDExODQgOTkyLDExODQgMTEzNiwxMTMwIDEyNDUsMTAyMyAxMzUzLDkxNiAxNDA3LDc3MiAxNDA3LDU5MiAxNDA3LDQxMiAxMzUzLDI2OCAxMjQ1LDE2MSAxMTM2LDU0IDk5MiwwIDgxMywwIFoiLz4KICA8L2c+CiAgPGcgaWQ9ImJ1bGxldC1jaGFyLXRlbXBsYXRlKDgyMjYpIiB0cmFuc2Zvcm09InNjYWxlKDAuMDAwNDg4MjgxMjUsLTAuMDAwNDg4MjgxMjUpIj4KICAgPHBhdGggZD0iTSAzNDYsNDU3IEMgMjczLDQ1NyAyMDksNDgzIDE1NSw1MzUgMTAxLDU4NiA3NCw2NDkgNzQsNzIzIDc0LDc5NiAxMDEsODU5IDE1NSw5MTEgMjA5LDk2MyAyNzMsOTg5IDM0Niw5ODkgNDE5LDk4OSA0ODAsOTYzIDUzMSw5MTAgNTgyLDg1OSA2MDgsNzk2IDYwOCw3MjMgNjA4LDY0OCA1ODMsNTg2IDUzMiw1MzUgNDgyLDQ4MyA0MjAsNDU3IDM0Niw0NTcgWiIvPgogIDwvZz4KICA8ZyBpZD0iYnVsbGV0LWNoYXItdGVtcGxhdGUoODIxMSkiIHRyYW5zZm9ybT0ic2NhbGUoMC4wMDA0ODgyODEyNSwtMC4wMDA0ODgyODEyNSkiPgogICA8cGF0aCBkPSJNIC00LDQ1OSBMIDExMzUsNDU5IDExMzUsNjA2IC00LDYwNiAtNCw0NTkgWiIvPgogIDwvZz4KIDwvZGVmcz4KIDxkZWZzIGNsYXNzPSJUZXh0RW1iZWRkZWRCaXRtYXBzIi8+CiA8Zz4KICA8ZyBpZD0iaWQyIiBjbGFzcz0iTWFzdGVyX1NsaWRlIj4KICAgPGcgaWQ9ImJnLWlkMiIgY2xhc3M9IkJhY2tncm91bmQiLz4KICAgPGcgaWQ9ImJvLWlkMiIgY2xhc3M9IkJhY2tncm91bmRPYmplY3RzIi8+CiAgPC9nPgogPC9nPgogPGcgY2xhc3M9IlNsaWRlR3JvdXAiPgogIDxnPgogICA8ZyBpZD0iaWQxIiBjbGFzcz0iU2xpZGUiIGNsaXAtcGF0aD0idXJsKCNwcmVzZW50YXRpb25fY2xpcF9wYXRoKSI+CiAgICA8ZyBjbGFzcz0iUGFnZSI+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLlJlY3RhbmdsZVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMyI+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODQ1MCw3MDAwIEwgNzAwMCw3MDAwIDcwMDAsMzAwMCA5OTAwLDMwMDAgOTkwMCw3MDAwIDg0NTAsNzAwMCBaIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLlJlY3RhbmdsZVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkNCI+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTIwNTAsNzAwMCBMIDEwMTAwLDcwMDAgMTAxMDAsMzAwMCAxNDAwMCwzMDAwIDE0MDAwLDcwMDAgMTIwNTAsNzAwMCBaIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkVsbGlwc2VTaGFwZSI+CiAgICAgIDxnIGlkPSJpZDUiPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDg5OTksMzMwMCBDIDkxMDUsMzMxMiA5MTk1LDMzODMgOTI4OCwzNTMxIDkzODcsMzY5MCA5NDU5LDM4ODkgOTUxNiw0MTY1IDk1NzQsNDQ0MSA5NjAwLDQ3MTIgOTYwMCw1MDMxIDk2MDAsNTM1MCA5NTc0LDU2MjEgOTUxNiw1ODk3IDk0NTksNjE3MyA5NDAyLDYzMjggOTMxOSw2NDc4Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiIGQ9Ik0gOTE0MSw2NzAxIEwgOTQwNSw2NTI2IDkyNDgsNjQwMyA5MTQxLDY3MDEgWiIvPgogICAgICA8L2c+CiAgICAgPC9nPgogICAgIDxnIGNsYXNzPSJjb20uc3VuLnN0YXIuZHJhd2luZy5FbGxpcHNlU2hhcGUiPgogICAgICA8ZyBpZD0iaWQ2Ij4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDc5NCw2NzEwIEMgMTA3NDgsNjY2OSAxMDcxMCw2NjE4IDEwNjY4LDY1NDAgMTA1ODMsNjM4MCAxMDUyMSw2MTgxIDEwNDcyLDU5MDUgMTA0MjIsNTYyOCAxMDQwMCw1MzU2IDEwNDAwLDUwMzYgMTA0MDAsNDcxNiAxMDQyMiw0NDQ0IDEwNDcyLDQxNjggMTA1MjEsMzg5MSAxMDU4MywzNjkyIDEwNjY4LDM1MzIgMTA3NDgsMzM4MyAxMDY5MCwzNDkyIDEwNzAxLDM0NzQiLz4KICAgICAgIDxwYXRoIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSIgZD0iTSAxMDkxNiwzMzAwIEwgMTA2MjIsMzQxNiAxMDc1MCwzNTY5IDEwOTE2LDMzMDAgWiIvPgogICAgICA8L2c+CiAgICAgPC9nPgogICAgIDxnIGNsYXNzPSJjb20uc3VuLnN0YXIuZHJhd2luZy5DdXN0b21TaGFwZSI+CiAgICAgIDxnIGlkPSJpZDciPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDk4OTksNjkwMCBDIDk5NTUsNjkwMCA5OTk5LDY5NDMgOTk5OSw2OTk5IDk5OTksNzA1NSA5OTU1LDcwOTkgOTg5OSw3MDk5IDk4NDMsNzA5OSA5ODAwLDcwNTUgOTgwMCw2OTk5IDk4MDAsNjk0MyA5ODQzLDY5MDAgOTg5OSw2OTAwIFoiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSA5ODAwLDY5MDAgTCA5ODAwLDY5MDAgWiIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMDAxLDcxMDEgTCAxMDAwMSw3MTAxIFoiLz4KICAgICAgPC9nPgogICAgIDwvZz4KICAgICA8ZyBjbGFzcz0iY29tLnN1bi5zdGFyLmRyYXdpbmcuQ3VzdG9tU2hhcGUiPgogICAgICA8ZyBpZD0iaWQ4Ij4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDA5OSwyOTAwIEMgMTAxNTUsMjkwMCAxMDE5OSwyOTQzIDEwMTk5LDI5OTkgMTAxOTksMzA1NSAxMDE1NSwzMDk5IDEwMDk5LDMwOTkgMTAwNDMsMzA5OSAxMDAwMCwzMDU1IDEwMDAwLDI5OTkgMTAwMDAsMjk0MyAxMDA0MywyOTAwIDEwMDk5LDI5MDAgWiIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMDAwLDI5MDAgTCAxMDAwMCwyOTAwIFoiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDIwMSwzMTAxIEwgMTAyMDEsMzEwMSBaIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkN1c3RvbVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkOSI+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTg5OSwyOTAwIEMgOTk1NSwyOTAwIDk5OTksMjk0MyA5OTk5LDI5OTkgOTk5OSwzMDU1IDk5NTUsMzA5OSA5ODk5LDMwOTkgOTg0MywzMDk5IDk4MDAsMzA1NSA5ODAwLDI5OTkgOTgwMCwyOTQzIDk4NDMsMjkwMCA5ODk5LDI5MDAgWiIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDk4MDAsMjkwMCBMIDk4MDAsMjkwMCBaIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAwMDEsMzEwMSBMIDEwMDAxLDMxMDEgWiIvPgogICAgICA8L2c+CiAgICAgPC9nPgogICAgIDxnIGNsYXNzPSJjb20uc3VuLnN0YXIuZHJhd2luZy5DdXN0b21TaGFwZSI+CiAgICAgIDxnIGlkPSJpZDEwIj4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSA5ODk5LDQ5MDAgQyA5OTU1LDQ5MDAgOTk5OSw0OTQzIDk5OTksNDk5OSA5OTk5LDUwNTUgOTk1NSw1MDk5IDk4OTksNTA5OSA5ODQzLDUwOTkgOTgwMCw1MDU1IDk4MDAsNDk5OSA5ODAwLDQ5NDMgOTg0Myw0OTAwIDk4OTksNDkwMCBaIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTgwMCw0OTAwIEwgOTgwMCw0OTAwIFoiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDAwMSw1MTAxIEwgMTAwMDEsNTEwMSBaIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkN1c3RvbVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMTEiPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMDk5LDQ5MDAgQyAxMDE1NSw0OTAwIDEwMTk5LDQ5NDMgMTAxOTksNDk5OSAxMDE5OSw1MDU1IDEwMTU1LDUwOTkgMTAwOTksNTA5OSAxMDA0Myw1MDk5IDEwMDAwLDUwNTUgMTAwMDAsNDk5OSAxMDAwMCw0OTQzIDEwMDQzLDQ5MDAgMTAwOTksNDkwMCBaIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAwMDAsNDkwMCBMIDEwMDAwLDQ5MDAgWiIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMjAxLDUxMDEgTCAxMDIwMSw1MTAxIFoiLz4KICAgICAgPC9nPgogICAgIDwvZz4KICAgICA8ZyBjbGFzcz0iY29tLnN1bi5zdGFyLmRyYXdpbmcuQ3VzdG9tU2hhcGUiPgogICAgICA8ZyBpZD0iaWQxMiI+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAwOTksNjkwMCBDIDEwMTU1LDY5MDAgMTAxOTksNjk0MyAxMDE5OSw2OTk5IDEwMTk5LDcwNTUgMTAxNTUsNzA5OSAxMDA5OSw3MDk5IDEwMDQzLDcwOTkgMTAwMDAsNzA1NSAxMDAwMCw2OTk5IDEwMDAwLDY5NDMgMTAwNDMsNjkwMCAxMDA5OSw2OTAwIFoiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDAwMCw2OTAwIEwgMTAwMDAsNjkwMCBaIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAyMDEsNzEwMSBMIDEwMjAxLDcxMDEgWiIvPgogICAgICA8L2c+CiAgICAgPC9nPgogICAgIDxnIGNsYXNzPSJjb20uc3VuLnN0YXIuZHJhd2luZy5DdXN0b21TaGFwZSI+CiAgICAgIDxnIGlkPSJpZDEzIj4KICAgICAgIDxwYXRoIGZpbGw9InJnYigyNTUsMjU1LDI1NSkiIHN0cm9rZT0ibm9uZSIgZD0iTSA1MTAwLDUyMDAgTCAzNTAwLDUyMDAgMzUwMCwzMDAwIDY3MDAsMzAwMCA2NzAwLDUyMDAgNTEwMCw1MjAwIFoiLz4KICAgICAgIDx0ZXh0IGNsYXNzPSJUZXh0U2hhcGUiPjx0c3BhbiBjbGFzcz0iVGV4dFBhcmFncmFwaCIgZm9udC1mYW1pbHk9IkxpYmVyYXRpb24gU2Fucywgc2Fucy1zZXJpZiIgZm9udC1zaXplPSIzNTNweCIgZm9udC13ZWlnaHQ9IjQwMCI+PHRzcGFuIGNsYXNzPSJUZXh0UG9zaXRpb24iIHg9IjM3NTAiIHk9IjM0MzMiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPlN1YmRpdmlzaW9uIDwvdHNwYW4+PC90c3Bhbj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMzc1MCIgeT0iMzgyNyI+PHRzcGFuIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSI+cG9pbnRzIG5lZWQgdG8gPC90c3Bhbj48L3RzcGFuPjx0c3BhbiBjbGFzcz0iVGV4dFBvc2l0aW9uIiB4PSIzNzUwIiB5PSI0MjIxIj48dHNwYW4gZmlsbD0icmdiKDAsMCwwKSIgc3Ryb2tlPSJub25lIj5sYW5kIG9uIHRoZSBzYW1lIDwvdHNwYW4+PC90c3Bhbj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMzc1MCIgeT0iNDYxNSI+PHRzcGFuIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSI+bG9jYXRpb24gdG8gPC90c3Bhbj48L3RzcGFuPjx0c3BhbiBjbGFzcz0iVGV4dFBvc2l0aW9uIiB4PSIzNzUwIiB5PSI1MDA5Ij48dHNwYW4gZmlsbD0icmdiKDAsMCwwKSIgc3Ryb2tlPSJub25lIj5wcmV2ZW50IGNyYWNraW5nPC90c3Bhbj48L3RzcGFuPjwvdHNwYW4+PC90ZXh0PgogICAgICA8L2c+CiAgICAgPC9nPgogICAgIDxnIGNsYXNzPSJjb20uc3VuLnN0YXIuZHJhd2luZy5MaW5lU2hhcGUiPgogICAgICA8ZyBpZD0iaWQxNCI+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNjYwMCw0MjAwIEwgNjY1MSw0MjEzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNjcwMyw0MjI3IEwgNjc1NCw0MjQwIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNjgwNiw0MjUzIEwgNjg1Nyw0MjY2Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNjkwOCw0MjgwIEwgNjk2MCw0MjkzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzAxMSw0MzA2IEwgNzA2Myw0MzE5Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzExNCw0MzMzIEwgNzE2NSw0MzQ2Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzIxNyw0MzU5IEwgNzI2OCw0MzcyIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzMyMCw0Mzg2IEwgNzM3MSw0Mzk5Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzQyMyw0NDEyIEwgNzQ3NCw0NDI2Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzUyNSw0NDM5IEwgNzU3Nyw0NDUyIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzYyOCw0NDY1IEwgNzY4MCw0NDc5Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzczMSw0NDkyIEwgNzc4Miw0NTA1Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzgzNCw0NTE4IEwgNzg4NSw0NTMyIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gNzkzNyw0NTQ1IEwgNzk4OCw0NTU4Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODAzOSw0NTcxIEwgODA5MSw0NTg1Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODE0Miw0NTk4IEwgODE5NCw0NjExIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODI0NSw0NjI1IEwgODI5Niw0NjM4Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODM0OCw0NjUxIEwgODM5OSw0NjY0Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODQ1MSw0Njc4IEwgODUwMiw0NjkxIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODU1Myw0NzA0IEwgODYwNSw0NzE3Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODY1Niw0NzMxIEwgODcwOCw0NzQ0Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODc1OSw0NzU3IEwgODgxMSw0NzcwIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODg2Miw0Nzg0IEwgODkxMyw0Nzk3Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gODk2NSw0ODEwIEwgOTAxNiw0ODI0Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTA2OCw0ODM3IEwgOTExOSw0ODUwIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTE3MCw0ODYzIEwgOTIyMiw0ODc3Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTI3Myw0ODkwIEwgOTMyNSw0OTAzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTM3Niw0OTE2IEwgOTQyNyw0OTMwIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTQ3OSw0OTQzIEwgOTUzMCw0OTU2Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTU4Miw0OTY5IEwgOTYzMyw0OTgzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gOTY4NCw0OTk2IEwgOTcwMCw1MDAwIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkN1c3RvbVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMTUiPgogICAgICAgPHBhdGggZmlsbD0icmdiKDI1NSwyNTUsMjU1KSIgc3Ryb2tlPSJub25lIiBkPSJNIDEyNjUwLDI3MDAgTCAxMDcwMCwyNzAwIDEwNzAwLDE1MDAgMTQ2MDAsMTUwMCAxNDYwMCwyNzAwIDEyNjUwLDI3MDAgWiIvPgogICAgICAgPHRleHQgY2xhc3M9IlRleHRTaGFwZSI+PHRzcGFuIGNsYXNzPSJUZXh0UGFyYWdyYXBoIiBmb250LWZhbWlseT0iTGliZXJhdGlvbiBTYW5zLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjM1M3B4IiBmb250LXdlaWdodD0iNDAwIj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMTA5NTAiIHk9IjIwMjQiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPkNvcm5lciBwb2ludHMgc3RhcnQgPC90c3Bhbj48L3RzcGFuPjx0c3BhbiBjbGFzcz0iVGV4dFBvc2l0aW9uIiB4PSIxMDk1MCIgeT0iMjQxOCI+PHRzcGFuIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSI+d2l0aCB0aGUgc2FtZSB2YWx1ZXM8L3RzcGFuPjwvdHNwYW4+PC90c3Bhbj48L3RleHQ+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkN1c3RvbVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMTYiPgogICAgICAgPHBhdGggZmlsbD0icmdiKDI1NSwyNTUsMjU1KSIgc3Ryb2tlPSJub25lIiBkPSJNIDEyODUwLDg1MDAgTCAxMDkwMCw4NTAwIDEwOTAwLDczMDAgMTQ4MDAsNzMwMCAxNDgwMCw4NTAwIDEyODUwLDg1MDAgWiIvPgogICAgICAgPHRleHQgY2xhc3M9IlRleHRTaGFwZSI+PHRzcGFuIGNsYXNzPSJUZXh0UGFyYWdyYXBoIiBmb250LWZhbWlseT0iTGliZXJhdGlvbiBTYW5zLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjM1M3B4IiBmb250LXdlaWdodD0iNDAwIj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMTExNTAiIHk9Ijc4MjQiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPkNvcm5lciBwb2ludHMgc3RhcnQgPC90c3Bhbj48L3RzcGFuPjx0c3BhbiBjbGFzcz0iVGV4dFBvc2l0aW9uIiB4PSIxMTE1MCIgeT0iODIxOCI+PHRzcGFuIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSI+d2l0aCB0aGUgc2FtZSB2YWx1ZXM8L3RzcGFuPjwvdHNwYW4+PC90c3Bhbj48L3RleHQ+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkN1c3RvbVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMTciPgogICAgICAgPHBhdGggZmlsbD0icmdiKDI1NSwyNTUsMjU1KSIgc3Ryb2tlPSJub25lIiBkPSJNIDEyNDAwLDUyMDAgTCAxMDkwMCw1MjAwIDEwOTAwLDMzMDAgMTM5MDAsMzMwMCAxMzkwMCw1MjAwIDEyNDAwLDUyMDAgWiIvPgogICAgICAgPHRleHQgY2xhc3M9IlRleHRTaGFwZSI+PHRzcGFuIGNsYXNzPSJUZXh0UGFyYWdyYXBoIiBmb250LWZhbWlseT0iTGliZXJhdGlvbiBTYW5zLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjM1M3B4IiBmb250LXdlaWdodD0iNDAwIj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMTExNTAiIHk9IjM3ODAiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPk9wcG9zaW5nIDwvdHNwYW4+PC90c3Bhbj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMTExNTAiIHk9IjQxNzQiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPmRpcmVjdGlvbnMgb2YgPC90c3Bhbj48L3RzcGFuPjx0c3BhbiBjbGFzcz0iVGV4dFBvc2l0aW9uIiB4PSIxMTE1MCIgeT0iNDU2OCI+PHRzcGFuIGZpbGw9InJnYigwLDAsMCkiIHN0cm9rZT0ibm9uZSI+ZWRnZSB3YWxraW5nIDwvdHNwYW4+PC90c3Bhbj48dHNwYW4gY2xhc3M9IlRleHRQb3NpdGlvbiIgeD0iMTExNTAiIHk9IjQ5NjIiPjx0c3BhbiBmaWxsPSJyZ2IoMCwwLDApIiBzdHJva2U9Im5vbmUiPmZvciBzdWJkaXZpc2lvbjwvdHNwYW4+PC90c3Bhbj48L3RzcGFuPjwvdGV4dD4KICAgICAgPC9nPgogICAgIDwvZz4KICAgICA8ZyBjbGFzcz0iY29tLnN1bi5zdGFyLmRyYXdpbmcuTGluZVNoYXBlIj4KICAgICAgPGcgaWQ9ImlkMTgiPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMzAwLDI5MDAgTCAxMDM0MSwyODY3Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAzODMsMjgzNCBMIDEwNDI0LDI4MDEiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDQ2NiwyNzY3IEwgMTA1MDcsMjczNCIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwNTQ5LDI3MDEgTCAxMDU5MCwyNjY4Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTA2MzIsMjYzNSBMIDEwNjczLDI2MDIiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDcxNSwyNTY4IEwgMTA3NTYsMjUzNSIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwNzk3LDI1MDIgTCAxMDgwMCwyNTAwIi8+CiAgICAgIDwvZz4KICAgICA8L2c+CiAgICAgPGcgY2xhc3M9ImNvbS5zdW4uc3Rhci5kcmF3aW5nLkxpbmVTaGFwZSI+CiAgICAgIDxnIGlkPSJpZDE5Ij4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDIwMCw3MTAwIEwgMTAyNDMsNzEzMSIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwMjg2LDcxNjIgTCAxMDMzMCw3MTkzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTAzNzMsNzIyMyBMIDEwNDE2LDcyNTQiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDQ1OSw3Mjg1IEwgMTA1MDIsNzMxNiIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwNTQ2LDczNDcgTCAxMDU4OSw3Mzc4Ii8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTA2MzIsNzQwOSBMIDEwNjc1LDc0MzkiLz4KICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsMCwwKSIgZD0iTSAxMDcxOCw3NDcwIEwgMTA3NjIsNzUwMSIvPgogICAgICAgPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwwLDApIiBkPSJNIDEwODA1LDc1MzIgTCAxMDg0OCw3NTYzIi8+CiAgICAgICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLDAsMCkiIGQ9Ik0gMTA4OTEsNzU5NCBMIDEwOTAwLDc2MDAiLz4KICAgICAgPC9nPgogICAgIDwvZz4KICAgIDwvZz4KICAgPC9nPgogIDwvZz4KIDwvZz4KPC9zdmc+" alt="precise"> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As stated in “<a href="#evaluation-of-expressions">Evaluation of Expressions</a>”, | 
 | the compiler may transform expressions even if this changes the resulting | 
 | value. | 
 | Without any qualifiers, implementations are permitted to perform | 
 | optimizations that effectively modify the order or number of operations used | 
 | to evaluate an expression, even if those optimizations may produce slightly | 
 | different results relative to unoptimized code.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>precise</strong> qualifier ensures that operations contributing to a | 
 | variable’s value are done in their stated order and with operator consistency. | 
 | The order is determined by operator precedence and parenthesis, as described in | 
 | “<a href="#operators">Operators</a>”. | 
 | Operator consistency means for each particular operator, for example the | 
 | multiply operator (<strong>*</strong>), its operation is always computed with the same | 
 | precision. | 
 | Specifically, values computed by compiler-generated code must adhere to the | 
 | following identities:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>a + b = b + a</p> | 
 | </li> | 
 | <li> | 
 | <p>a * b = b * a</p> | 
 | </li> | 
 | <li> | 
 | <p>a * b + c * d = b * a + c* d = d * c + b * a = <any other mathematically | 
 | valid combination></p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>While the following are prevented:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>a + (b + c) is not allowed to become (a + b) + c</p> | 
 | </li> | 
 | <li> | 
 | <p>a * (b * c) is not allowed to become (a * b) * c</p> | 
 | </li> | 
 | <li> | 
 | <p>a * b + c is not allowed to become a single operation <strong>fma</strong>(a, b, c)</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Where <em>a</em>, <em>b</em>, <em>c</em>, and <em>d</em>, are scalars or vectors, not matrices. | 
 | (Matrix multiplication generally does not commute.) It is the shader | 
 | writer’s responsibility to express the computation in terms of these rules | 
 | and the compiler’s responsibility to follow these rules. | 
 | See the description of <em>gl_TessCoord</em> for the rules the tessellation stages | 
 | are responsible for following, which in conjunction with the above allow | 
 | avoiding cracking when subdividing.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">precise out vec4 position;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>declares that operations used to produce the value of <em>position</em> must be | 
 | performed in exactly the order specified in the source code and with all | 
 | operators being treated consistently. | 
 | As with the <strong>invariant</strong> qualifier (see “<a href="#the-invariant-qualifier">The | 
 | Invariant Qualifier</a>”), the <strong>precise</strong> qualifier may be used to qualify a | 
 | built-in or previously declared user-defined variable as being precise:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out vec3 Color; | 
 | precise Color; <span class="comment">// make existing Color be precise</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When applied to a block, a structure type, or a variable of structure type, | 
 | <strong>precise</strong> applies to each contained member, recursively.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This qualifier will affect the evaluation of an r-value in a particular | 
 | function if and only if the result is eventually consumed in the same | 
 | function by an l-value qualified as <strong>precise</strong>. | 
 | Any other expressions within a function are not affected, including return | 
 | values and output parameters not declared as <strong>precise</strong> but that are | 
 | eventually consumed outside the function by a variable qualified as | 
 | <strong>precise</strong>. Unaffected expressions also include the controlling expressions | 
 | in selection and iteration statements and the condition in ternary | 
 | operators (<strong>?:</strong>).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some examples of the use of <strong>precise</strong>:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in vec4 a, b, c, d; | 
 | precise out vec4 v; | 
 |  | 
 | <span class="predefined-type">float</span> func(<span class="predefined-type">float</span> e, <span class="predefined-type">float</span> f, <span class="predefined-type">float</span> g, <span class="predefined-type">float</span> h) | 
 | { | 
 |     <span class="keyword">return</span> (e*f) + (g*h); <span class="comment">// no constraint on order or operator consistency</span> | 
 | } | 
 |  | 
 | <span class="predefined-type">float</span> func2(<span class="predefined-type">float</span> e, <span class="predefined-type">float</span> f, <span class="predefined-type">float</span> g, <span class="predefined-type">float</span> h) | 
 | { | 
 |     precise <span class="predefined-type">float</span> result = (e*f) + (g*h); <span class="comment">// ensures same precision for the two multiplies</span> | 
 |     <span class="keyword">return</span> result; | 
 | } | 
 |  | 
 | <span class="predefined-type">float</span> func3(<span class="predefined-type">float</span> i, <span class="predefined-type">float</span> j, precise out <span class="predefined-type">float</span> k) | 
 | { | 
 |     k = i * i + j;        <span class="comment">// precise, due to <k> declaration</span> | 
 | } | 
 |  | 
 | <span class="directive">void</span> main() | 
 | { | 
 |     vec3 r = vec3(a * b);             <span class="comment">// precise, used to compute v.xyz</span> | 
 |     vec3 s = vec3(c * d);             <span class="comment">// precise, used to compute v.xyz</span> | 
 |     v.xyz = r + s;                    <span class="comment">// precise</span> | 
 |     v.w = (a.w * b.w) + (c.w * d.w);  <span class="comment">// precise</span> | 
 |     v.x = func(a.x, b.x, c.x, d.x);   <span class="comment">// values computed in func() are NOT precise</span> | 
 |     v.x = func2(a.x, b.x, c.x, d.x);  <span class="comment">// precise!</span> | 
 |     func3(a.x * b.x, c.x * d.x, v.x); <span class="comment">// precise!</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For the purposes of determining if an output from one shader stage matches | 
 | an input of the next stage, the <strong>precise</strong> qualifier need not match between | 
 | the input and the output.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All constant expressions are evaluated as if <strong>precise</strong> was present, whether | 
 | or not it is present. | 
 | However, as described in “<a href="#constant-expressions">Constant Expressions</a>”, | 
 | there is no requirement that a compile-time constant expression evaluates to | 
 | the same value as a corresponding non-constant expression.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="memory-qualifiers">4.10. Memory Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>Shader storage blocks, variables declared within shader storage blocks and | 
 | variables declared as image types (the basic opaque types with “<strong>image</strong>” | 
 | in their keyword), can be further qualified with one or more of the | 
 | following memory qualifiers:</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">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top">Meaning</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>coherent</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">memory variable where reads and writes are coherent with | 
 |                 reads and writes from other shader invocations</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>volatile</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">memory variable whose underlying value may be changed at any | 
 |                 point during shader execution by some source other than the | 
 |                 current shader invocation</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>restrict</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">memory variable where use of that variable is the only way | 
 |                 to read and write the underlying memory in the relevant | 
 |                 shader stage</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>readonly</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">memory variable that can be used to read the underlying | 
 |                 memory, but cannot be used to write the underlying memory</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>writeonly</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">memory variable that can be used to write the underlying | 
 |                 memory, but cannot be used to read the underlying memory</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Memory accesses to image variables declared using the <strong>coherent</strong> qualifier | 
 | are performed coherently with accesses to the same location from other | 
 | shader invocations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As described in section | 
 | 7.11 | 
 | “Shader Memory Access” of the | 
 | <a href="#references">OpenGL ES Specification</a>, shader memory reads and writes complete in a | 
 | largely undefined order. | 
 | The built-in function <strong>memoryBarrier</strong>() can be used if needed to guarantee | 
 | the completion and relative ordering of memory accesses performed by a | 
 | single shader invocation.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When accessing memory using variables not declared as <strong>coherent</strong>, the memory | 
 | accessed by a shader may be cached by the implementation to service future | 
 | accesses to the same address. | 
 | Memory stores may be cached in such a way that the values written may not be | 
 | visible to other shader invocations accessing the same memory. | 
 | The implementation may cache the values fetched by memory reads and return | 
 | the same values to any shader invocation accessing the same memory, even if | 
 | the underlying memory has been modified since the first memory read. | 
 | While variables not declared as <strong>coherent</strong> may not be useful for | 
 | communicating between shader invocations, using non-coherent accesses may | 
 | result in higher performance.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Memory accesses to image variables declared using the <strong>volatile</strong> qualifier | 
 | must treat the underlying memory as though it could be read or written at | 
 | any point during shader execution by some source other than the executing | 
 | shader invocation. | 
 | When a volatile variable is read, its value must be re-fetched from the | 
 | underlying memory, even if the shader invocation performing the read had | 
 | previously fetched its value from the same memory. | 
 | When a volatile variable is written, its value must be written to the | 
 | underlying memory, even if the compiler can conclusively determine that its | 
 | value will be overwritten by a subsequent write. | 
 | Since the external source reading or writing a <strong>volatile</strong> variable may be | 
 | another shader invocation, variables declared as <strong>volatile</strong> are | 
 | automatically treated as coherent.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Memory accesses to image variables declared using the <strong>restrict</strong> qualifier | 
 | may be compiled assuming that the variable used to perform the memory access | 
 | is the only way to access the underlying memory using the shader stage in | 
 | question. | 
 | This allows the compiler to coalesce or reorder loads and stores using | 
 | <strong>restrict</strong>-qualified image variables in ways that wouldn’t be permitted | 
 | for image variables not so qualified, because the compiler can assume that | 
 | the underlying image won’t be read or written by other code. | 
 | Applications are responsible for ensuring that image memory referenced by | 
 | variables qualified with <strong>restrict</strong> will not be referenced using other | 
 | variables in the same scope; otherwise, accesses to <strong>restrict</strong>-qualified | 
 | variables will have undefined results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Memory accesses to image variables declared using the <strong>readonly</strong> qualifier | 
 | may only read the underlying memory, which is treated as read-only memory | 
 | and cannot be written to. | 
 | It is an error to pass an image variable qualified with | 
 | <strong>readonly</strong> to <strong>imageStore</strong>() or other built-in functions that modify image | 
 | memory.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Memory accesses to image variables declared using the <strong>writeonly</strong> qualifier | 
 | may only write the underlying memory; the underlying memory cannot be read. | 
 | It is an error to pass an image variable qualified with | 
 | <strong>writeonly</strong> to <strong>imageLoad</strong>() or other built-in functions that read image | 
 | memory.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A variable could be qualified as both <strong>readonly</strong> and <strong>writeonly</strong>, disallowing | 
 | both read and write. Such variables can still be used with some queries, for | 
 | example <strong>imageSize</strong>() and <strong>.length</strong>().</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Except for image variables qualified with the format qualifiers <strong>r32f</strong>, | 
 | <strong>r32i</strong>, and <strong>r32ui</strong>, image variables must specify a memory qualifier | 
 | (<strong>readonly</strong>, <strong>writeonly</strong>, or both).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The memory qualifiers <strong>coherent</strong>, <strong>volatile</strong>, <strong>restrict</strong>, <strong>readonly</strong>, and | 
 | <strong>writeonly</strong> may be used in the declaration of buffer variables (i.e., | 
 | members of shader storage blocks). | 
 | When a buffer variable is declared with a memory qualifier, the behavior | 
 | specified for memory accesses involving image variables described above | 
 | applies identically to memory accesses involving that buffer variable. | 
 | It is a compile-time error to assign to a buffer variable qualified with | 
 | <strong>readonly</strong> or to read from a buffer variable qualified with <strong>writeonly</strong>. | 
 | The combination <strong>readonly</strong> <strong>writeonly</strong> is allowed.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Additionally, memory qualifiers may be used at the block-level declaration | 
 | of a shader storage block, including the combination <strong>readonly</strong> <strong>writeonly</strong>. | 
 | When a block declaration is qualified with a memory qualifier, it is as if | 
 | all of its members were declared with the same memory qualifier. | 
 | For example, the block declaration</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">coherent buffer Block { | 
 |     readonly vec4 member1; | 
 |     vec4 member2; | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">buffer Block { | 
 |     coherent readonly vec4 member1; | 
 |     coherent vec4 member2; | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Memory qualifiers are only supported in the declarations of image variables, | 
 | buffer variables, and shader storage blocks; it is an error to use such | 
 | qualifiers in any other declarations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When calling user-defined functions, variables qualified with <strong>coherent</strong>, | 
 | <strong>volatile</strong>, <strong>readonly</strong>, or <strong>writeonly</strong> may not be passed to functions whose | 
 | formal parameters lack such qualifiers. | 
 | (See “<a href="#function-definitions">Function Definitions</a>” for more detail on | 
 | function calling.) It is legal to have any additional memory qualifiers on a | 
 | formal parameter, but only <strong>restrict</strong> can be taken away from a calling | 
 | argument, by a formal parameter that lacks the <strong>restrict</strong> qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When a built-in function is called, the code generated is to be based on the | 
 | actual qualification of the calling argument, not on the list of memory | 
 | qualifiers specified on the formal parameter in the prototype.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 funcA(restrict image2D a) { ... } | 
 | vec4 funcB(image2D a) { ... } | 
 | layout(rgba32f) uniform image2D img1; | 
 | layout(rgba32f) coherent uniform image2D img2; | 
 |  | 
 | funcA(img1);        <span class="comment">// OK, adding "restrict" is allowed</span> | 
 | funcB(img2);        <span class="comment">// illegal, stripping "coherent" is not</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Layout qualifiers cannot be used on formal function parameters, and layout | 
 | qualification is not included in parameter matching.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that the use of <strong>const</strong> in an image variable declaration is qualifying | 
 | the const-ness of the variable being declared, not the image it refers to. | 
 | The qualifier <strong>readonly</strong> qualifies the image memory (as accessed through | 
 | that variable) while <strong>const</strong> qualifies the variable itself.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="order-of-qualification">4.11. Order and Repetition of Qualification</h3> | 
 | <div class="paragraph"> | 
 | <p>When multiple qualifiers are present in a declaration, they may appear in | 
 | any order, but they must all appear before the type. | 
 | The <strong>layout</strong> qualifier is the only qualifier that can appear more than once. | 
 | Further, a declaration can have at most one storage qualifier, at most one | 
 | auxiliary storage qualifier, and at most one interpolation qualifier. | 
 | Multiple memory qualifiers can be used. | 
 | Any violation of these rules will cause a compile-time error.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="empty-declarations">4.12. Empty Declarations</h3> | 
 | <div class="paragraph"> | 
 | <p><em>Empty declarations</em> are declarations without a variable name, meaning no | 
 | object is instantiated by the declaration. | 
 | Generally, empty declarations are allowed. | 
 | Some are useful when declaring structures, while many others have no effect. | 
 | For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span>;               <span class="comment">// No effect</span> | 
 | <span class="keyword">struct</span> S {<span class="predefined-type">int</span> x;}; <span class="comment">// Defines a struct S</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The combinations of qualifiers that cause compile-time or link-time errors | 
 | are the same whether or not the declaration is empty, for example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">invariant in <span class="predefined-type">float</span> x; <span class="comment">// Error. An input cannot be invariant.</span> | 
 | invariant in <span class="predefined-type">float</span>;   <span class="comment">// Error even though no variable is declared.</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="operators-and-expressions">5. Operators and Expressions</h2> | 
 | <div class="sectionbody"> | 
 | <div class="sect2"> | 
 | <h3 id="operators">5.1. Operators</h3> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language has 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">array subscript<br> | 
 |                  function call and constructor structure<br> | 
 |                  field or method selector, swizzle<br> | 
 |                  post fix increment and decrement</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">[ ]<br> | 
 |                                                   ( )<br> | 
 |                                                   .<br> | 
 |                                                   ++ --</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">3</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">prefix increment and decrement<br> | 
 |                  unary</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">++ --<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">4</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">5</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">6</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"><< >></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">relational</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">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">9</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">&</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 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">11</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">12</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">&&</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">13</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">logical 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">14</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> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">selection</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">? :</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">16</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Assignment<br> | 
 |                  arithmetic assignments</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">=<br> | 
 |                                                   += -=<br> | 
 |                                                   *= /=<br> | 
 |                                                   %= <<= >>=<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">17 (lowest)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">sequence</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>There is no address-of operator nor a dereference operator. | 
 | There is no typecast operator; constructors are used instead.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="array-operations">5.2. Array Operations</h3> | 
 | <div class="paragraph"> | 
 | <p>These are now described in “<a href="#structure-and-array-operations">Structure and | 
 | Array Operations</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="function-calls">5.3. Function Calls</h3> | 
 | <div class="paragraph"> | 
 | <p>If a function returns a value, then a call to that function may be used as | 
 | an expression, whose type will be the type that was used to declare or | 
 | define the function.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Function definitions and calling conventions are discussed in | 
 | “<a href="#function-definitions">Function Definitions</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="constructors">5.4. Constructors</h3> | 
 | <div class="paragraph"> | 
 | <p>Constructors use the function call syntax, where the function name is a | 
 | type, and the call makes an object of that type. | 
 | Constructors are used the same way in both initializers and expressions. | 
 | (See “<a href="#shading-language-grammar">Shading Language Grammar</a>” for details.) | 
 | The parameters are used to initialize the constructed value. | 
 | Constructors can be used to request a data type conversion to change from | 
 | one scalar type to another scalar type, or to build larger types out of | 
 | smaller types, or to reduce a larger type to a smaller type.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In general, constructors are not built-in functions with predetermined | 
 | prototypes. | 
 | For arrays and structures, there must be exactly one argument in the | 
 | constructor for each element or member. | 
 | For the other types, the arguments must provide a sufficient number of | 
 | components to perform the initialization, and it is an error to | 
 | include so many arguments that they cannot all be used. | 
 | Detailed rules follow. | 
 | The prototypes actually listed below are merely a subset of examples.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="conversion-and-scalar-constructors">5.4.1. Conversion and Scalar Constructors</h4> | 
 | <div class="paragraph"> | 
 | <p>Converting between scalar types is done as the following prototypes | 
 | indicate:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">int</span>(uint)     <span class="comment">// converts an unsigned integer to a signed integer</span> | 
 | <span class="predefined-type">int</span>(<span class="predefined-type">bool</span>)     <span class="comment">// converts a Boolean value to an int</span> | 
 | <span class="predefined-type">int</span>(<span class="predefined-type">float</span>)    <span class="comment">// converts a float value to an int</span> | 
 | uint(<span class="predefined-type">int</span>)     <span class="comment">// converts a signed integer value to an unsigned integer</span> | 
 | uint(<span class="predefined-type">bool</span>)    <span class="comment">// converts a Boolean value to an unsigned integer</span> | 
 | uint(<span class="predefined-type">float</span>)   <span class="comment">// converts a float value to an unsigned integer</span> | 
 | <span class="predefined-type">bool</span>(<span class="predefined-type">int</span>)     <span class="comment">// converts a signed integer value to a Boolean</span> | 
 | <span class="predefined-type">bool</span>(uint)    <span class="comment">// converts an unsigned integer value to a Boolean value</span> | 
 | <span class="predefined-type">bool</span>(<span class="predefined-type">float</span>)   <span class="comment">// converts a float value to a Boolean</span> | 
 | <span class="predefined-type">float</span>(<span class="predefined-type">int</span>)    <span class="comment">// converts a signed integer value to a float</span> | 
 | <span class="predefined-type">float</span>(uint)   <span class="comment">// converts an unsigned integer value to a float value</span> | 
 | <span class="predefined-type">float</span>(<span class="predefined-type">bool</span>)   <span class="comment">// converts a Boolean value to a float</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When constructors are used to convert a floating-point type to an integer | 
 | type, the fractional part of the floating-point value is dropped. | 
 | It is undefined to convert a negative floating-point value to an <strong>uint</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Integer values having more bits of precision than a single-precision | 
 | floating-point mantissa will lose precision when converted to <strong>float</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When a constructor is used to convert any integer or floating-point type to | 
 | a <strong>bool</strong>, 0 and 0.0 are converted to <strong>false</strong>, and non-zero values are | 
 | converted to <strong>true</strong>. | 
 | When a constructor is used to convert a <strong>bool</strong> to any integer or | 
 | floating-point type, <strong>false</strong> is converted to 0 or 0.0, and <strong>true</strong> is | 
 | converted to 1 or 1.0.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The constructor <strong>int</strong>(<strong>uint</strong>) preserves the bit pattern in the argument, | 
 | which will change the argument’s value if its sign bit is set. | 
 | The constructor <strong>uint</strong>(<strong>int</strong>) preserves the bit pattern in the argument, | 
 | which will change its value if it is negative.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Identity constructors, like <strong>float</strong>(<strong>float</strong>) are also legal, but of little | 
 | use.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Scalar constructors with non-scalar parameters can be used to take the first | 
 | element from a non-scalar. | 
 | For example, the constructor <strong>float</strong>(<strong>vec3</strong>) will select the first component | 
 | of the <strong>vec3</strong> parameter.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="vector-and-matrix-constructors">5.4.2. Vector and Matrix Constructors</h4> | 
 | <div class="paragraph"> | 
 | <p>Constructors can be used to create vectors or matrices from a set of | 
 | scalars, vectors, or matrices. | 
 | This includes the ability to shorten vectors.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If there is a single scalar parameter to a vector constructor, it is used to | 
 | initialize all components of the constructed vector to that scalar’s value. | 
 | If there is a single scalar parameter to a matrix constructor, it is used to | 
 | initialize all the components on the matrix’s diagonal, with the remaining | 
 | components initialized to 0.0.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a vector is constructed from multiple scalars, one or more vectors, or | 
 | one or more matrices, or a mixture of these, the vector’s components will be | 
 | constructed in order from the components of the arguments. | 
 | The arguments will be consumed left to right, and each argument will have | 
 | all its components consumed, in order, before any components from the next | 
 | argument are consumed. | 
 | Similarly for constructing a matrix from multiple scalars or vectors, or a | 
 | mixture of these. | 
 | Matrix components will be constructed and consumed in column major order. | 
 | In these cases, there must be enough components provided in the arguments to | 
 | provide an initializer for every component in the constructed value. | 
 | It is an error to provide extra arguments beyond this last used | 
 | argument.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a matrix is constructed from a matrix, then each component (column <em>i</em>, | 
 | row <em>j</em>) in the result that has a corresponding component (column <em>i</em>, row | 
 | <em>j</em>) in the argument will be initialized from there. | 
 | All other components will be initialized to the identity matrix. | 
 | If a matrix argument is given to a matrix constructor, it is | 
 | an error to have any other arguments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the basic type (<strong>bool</strong>, <strong>int</strong>, | 
 | or <strong>float</strong>) | 
 | of a parameter to a | 
 | constructor does not match the basic type of the object being constructed, | 
 | the scalar construction rules (above) are used to convert the parameters.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some useful vector constructors are as follows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec3(<span class="predefined-type">float</span>)          <span class="comment">// initializes each component of the vec3 with the float</span> | 
 | vec4(ivec4)          <span class="comment">// makes a vec4 with component-wise conversion</span> | 
 | vec4(mat2)           <span class="comment">// the vec4 is column 0 followed by column 1</span> | 
 | vec2(<span class="predefined-type">float</span>, <span class="predefined-type">float</span>)   <span class="comment">// initializes a vec2 with 2 floats</span> | 
 | ivec3(<span class="predefined-type">int</span>, <span class="predefined-type">int</span>, <span class="predefined-type">int</span>) <span class="comment">// initializes an ivec3 with 3 ints</span> | 
 | bvec4(<span class="predefined-type">int</span>, <span class="predefined-type">int</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>) <span class="comment">// uses 4 Boolean conversions</span> | 
 | vec2(vec3)           <span class="comment">// drops the third component of a vec3</span> | 
 | vec3(vec4)           <span class="comment">// drops the fourth component of a vec4</span> | 
 | vec3(vec2, <span class="predefined-type">float</span>)    <span class="comment">// vec3.x = vec2.x, vec3.y = vec2.y, vec3.z = float</span> | 
 | vec3(<span class="predefined-type">float</span>, vec2)    <span class="comment">// vec3.x = float, vec3.y = vec2.x, vec3.z = vec2.y</span> | 
 | vec4(vec3, <span class="predefined-type">float</span>) | 
 | vec4(<span class="predefined-type">float</span>, vec3) | 
 | vec4(vec2, vec2)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some examples of these are:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 color = vec4(<span class="float">0</span><span class="float">.0</span>, <span class="float">1</span><span class="float">.0</span>, <span class="float">0</span><span class="float">.0</span>, <span class="float">1</span><span class="float">.0</span>); | 
 | vec4 rgba = vec4(<span class="float">1</span><span class="float">.0</span>);      <span class="comment">// sets each component to 1.0</span> | 
 | vec3 rgb = vec3(color);     <span class="comment">// drop the 4th component</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To initialize the diagonal of a matrix with all other elements set to zero:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat2(<span class="predefined-type">float</span>) | 
 | mat3(<span class="predefined-type">float</span>) | 
 | mat4(<span class="predefined-type">float</span>)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>That is, <em>result[i][j]</em> is set to the <em>float</em> argument for all \(i | 
 | = j\) and set to 0 for all \(i \neq j\).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To initialize a matrix by specifying vectors or scalars, the components are | 
 | assigned to the matrix elements in column-major order.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat2(vec2, vec2);                 <span class="comment">// one column per argument</span> | 
 | mat3(vec3, vec3, vec3);           <span class="comment">// one column per argument</span> | 
 | mat4(vec4, vec4, vec4, vec4);     <span class="comment">// one column per argument</span> | 
 | mat3x2(vec2, vec2, vec2);         <span class="comment">// one column per argument</span> | 
 | mat2(<span class="predefined-type">float</span>, <span class="predefined-type">float</span>,                <span class="comment">// first column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>);               <span class="comment">// second column</span> | 
 | mat3(<span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>,         <span class="comment">// first column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>,         <span class="comment">// second column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>);        <span class="comment">// third column</span> | 
 | mat4(<span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>,  <span class="comment">// first column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>,  <span class="comment">// second column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>,  <span class="comment">// third column</span> | 
 |      <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>, <span class="predefined-type">float</span>); <span class="comment">// fourth column</span> | 
 | mat2x3(vec2, <span class="predefined-type">float</span>,               <span class="comment">// first column</span> | 
 |        vec2, <span class="predefined-type">float</span>);              <span class="comment">// second column</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A wide range of other possibilities exist, to construct a matrix from | 
 | vectors and scalars, as long as enough components are present to initialize | 
 | the matrix. | 
 | To construct a matrix from a matrix:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat3x3(mat4x4); <span class="comment">// takes the upper-left 3x3 of the mat4x4</span> | 
 | mat2x3(mat4x2); <span class="comment">// takes the upper-left 2x2 of the mat4x4, last row is 0,0</span> | 
 | mat4x4(mat3x3); <span class="comment">// puts the mat3x3 in the upper-left, sets the lower right</span> | 
 |                 <span class="comment">// component to 1, and the rest to 0</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="structure-constructors">5.4.3. Structure Constructors</h4> | 
 | <div class="paragraph"> | 
 | <p>Once a structure is defined, and its type is given a name, a constructor is | 
 | available with the same name to construct instances of that structure. | 
 | For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">struct</span> light { | 
 |     <span class="predefined-type">float</span> intensity; | 
 |     vec3 position; | 
 | }; | 
 |  | 
 | light lightVar = light(<span class="float">3</span><span class="float">.0</span>, vec3(<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>, <span class="float">3</span><span class="float">.0</span>));</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The arguments to the constructor will be used to set the structure’s | 
 | members, in order, using one argument per member. | 
 | Each argument must be the same type as the member it | 
 | sets.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structure constructors can be used as initializers or in expressions.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="array-constructors">5.4.4. Array Constructors</h4> | 
 | <div class="paragraph"> | 
 | <p>Array types can also be used as constructor names, which can then be used in | 
 | expressions or initializers. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">const</span> <span class="predefined-type">float</span> c[<span class="integer">3</span>] = <span class="predefined-type">float</span>[<span class="integer">3</span>](<span class="float">5</span><span class="float">.0</span>, <span class="float">7</span><span class="float">.2</span>, <span class="float">1</span><span class="float">.1</span>); | 
 | <span class="directive">const</span> <span class="predefined-type">float</span> d[<span class="integer">3</span>] = <span class="predefined-type">float</span>[](<span class="float">5</span><span class="float">.0</span>, <span class="float">7</span><span class="float">.2</span>, <span class="float">1</span><span class="float">.1</span>); | 
 |  | 
 | <span class="predefined-type">float</span> g; | 
 | ... | 
 | <span class="predefined-type">float</span> a[<span class="integer">5</span>] = <span class="predefined-type">float</span>[<span class="integer">5</span>](g, <span class="integer">1</span>, g, <span class="float">2</span><span class="float">.3</span>, g); | 
 | <span class="predefined-type">float</span> b[<span class="integer">3</span>]; | 
 |  | 
 | b = <span class="predefined-type">float</span>[<span class="integer">3</span>](g, g + <span class="float">1</span><span class="float">.0</span>, g + <span class="float">2</span><span class="float">.0</span>);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There must be exactly the same number of arguments as the size of the array | 
 | being constructed. | 
 | If no size is present in the constructor, then the array is explicitly sized | 
 | to the number of arguments provided. | 
 | The arguments are assigned in order, starting at element 0, to the elements | 
 | of the constructed array. | 
 | Each argument must be the same type as the element type of the | 
 | array.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays of arrays are similarly constructed, and the size for any dimension | 
 | is <strong class="purple">optional</strong></p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 b[<span class="integer">2</span>] = ...; | 
 | vec4[<span class="integer">3</span>][<span class="integer">2</span>](b, b, b);    <span class="comment">// constructor</span> | 
 | vec4[][<span class="integer">2</span>](b, b, b);     <span class="comment">// constructor, valid, size deduced</span> | 
 | vec4[<span class="integer">3</span>][](b, b, b);     <span class="comment">// constructor, valid, size deduced</span> | 
 | vec4[][](b, b, b);      <span class="comment">// constructor, valid, both sizes deduced</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="vector-components">5.5. Vector Components</h3> | 
 | <div class="paragraph"> | 
 | <p>The names of the components of a vector | 
 | are denoted by a single letter. | 
 | As a notational convenience, several letters are associated with each | 
 | component based on common usage of position, color or texture coordinate | 
 | vectors. | 
 | The individual components can be selected by following the variable name | 
 | with period (<strong>.</strong>) and then the component name.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The component names supported are:</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all fit-content"> | 
 | <colgroup> | 
 | <col> | 
 | <col> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>{ x, y, z, w }</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Useful when accessing vectors that represent points or normals</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>{ r, g, b, a }</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Useful when accessing vectors that represent colors</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><em>{ s, t, p, q }</em></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Useful when accessing vectors that represent texture coordinates</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The component names <em>x</em>, <em>r</em>, and <em>s</em> are, for example, synonyms for the | 
 | same (first) component in a vector.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that the third component of the texture coordinate set, <em>r</em> in | 
 | OpenGL ES, has been renamed <em>p</em> so as to avoid the confusion with <em>r</em> (for | 
 | red) in a color.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Accessing components beyond those declared for the type is | 
 | an error so, for example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec2 pos; | 
 | pos.x       <span class="comment">// is legal</span> | 
 | pos.z       <span class="comment">// is illegal</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The component selection syntax allows multiple components to be selected by | 
 | appending their names (from the same name set) after the period (<strong>.</strong>).</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 v4; | 
 | v4.rgba;    <span class="comment">// is a vec4 and the same as just using v4,</span> | 
 | v4.rgb;     <span class="comment">// is a vec3,</span> | 
 | v4.b;       <span class="comment">// is a float,</span> | 
 | v4.xy;      <span class="comment">// is a vec2,</span> | 
 | v4.xgba;    <span class="comment">// is illegal - the component names do not come from the same set</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>No more than 4 components can be selected.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 v4; | 
 | v4.xyzwxy;      <span class="comment">// is illegal since it has 6 components</span> | 
 | (v4.xyzwxy).xy; <span class="comment">// is illegal since the intermediate value has 6</span> | 
 | components</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The order of the components can be different to swizzle them, or replicated:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 pos = vec4(<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>, <span class="float">3</span><span class="float">.0</span>, <span class="float">4</span><span class="float">.0</span>); | 
 | vec4 swiz = pos.wzyx;   <span class="comment">// swiz = (4.0, 3.0, 2.0, 1.0)</span> | 
 | vec4 dup = pos.xxyy;    <span class="comment">// dup = (1.0, 1.0, 2.0, 2.0)</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This notation is more concise than the constructor syntax. | 
 | To form an r-value, it can be applied to any expression that results in a | 
 | vector r-value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The component group notation can occur on the left hand side of an | 
 | expression.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 pos = vec4(<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>, <span class="float">3</span><span class="float">.0</span>, <span class="float">4</span><span class="float">.0</span>); | 
 | pos.xw = vec2(<span class="float">5</span><span class="float">.0</span>, <span class="float">6</span><span class="float">.0</span>);        <span class="comment">// pos = (5.0, 2.0, 3.0, 6.0)</span> | 
 | pos.wx = vec2(<span class="float">7</span><span class="float">.0</span>, <span class="float">8</span><span class="float">.0</span>);        <span class="comment">// pos = (8.0, 2.0, 3.0, 7.0)</span> | 
 | pos.xx = vec2(<span class="float">3</span><span class="float">.0</span>, <span class="float">4</span><span class="float">.0</span>);        <span class="comment">// illegal - 'x' used twice</span> | 
 | pos.xy = vec3(<span class="float">1</span><span class="float">.0</span>, <span class="float">2</span><span class="float">.0</span>, <span class="float">3</span><span class="float">.0</span>);   <span class="comment">// illegal - mismatch between vec2 and vec3</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>To form an l-value, swizzling must further be applied to an l-value and | 
 | contain no duplicate components. It results in an l-value of scalar or | 
 | vector type, depending on number of components specified.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Array subscripting syntax can also be applied to vectors (but not to | 
 | scalars) to provide numeric indexing. | 
 | So in</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 pos;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>pos[2]</em> refers to the third element of <em>pos</em> and is equivalent to <em>pos.z</em>. | 
 | This allows variable indexing into a vector, as well as a generic way of | 
 | accessing components. | 
 | Any integer expression can be used as the subscript. | 
 | The first component is at index zero. | 
 | Reading from or writing to a vector using a constant integral expression | 
 | with a value that is negative or greater than or equal to the size of the | 
 | vector results in an error. | 
 | When indexing with non-constant expressions, behavior is undefined if the | 
 | index is negative, or greater than or equal to the size of the vector.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note that scalars are not considered to be single-component vectors and | 
 | therefore the use of component selection operators on scalars is illegal.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="matrix-components">5.6. Matrix Components</h3> | 
 | <div class="paragraph"> | 
 | <p>The components of a matrix can be accessed using array subscripting syntax. | 
 | Applying a single subscript to a matrix treats the matrix as an array of | 
 | column vectors, and selects a single column, whose type is a vector of the | 
 | same size as the (column size of the) matrix. | 
 | The leftmost column is column 0. | 
 | A second subscript would then operate on the resulting vector, as defined | 
 | earlier for vectors. | 
 | Hence, two subscripts select a column and then a row.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat4 m; | 
 | m[<span class="integer">1</span>] = vec4(<span class="float">2</span><span class="float">.0</span>);   <span class="comment">// sets the second column to all 2.0</span> | 
 | m[<span class="integer">0</span>][<span class="integer">0</span>] = <span class="float">1</span><span class="float">.0</span>;      <span class="comment">// sets the upper left element to 1.0</span> | 
 | m[<span class="integer">2</span>][<span class="integer">3</span>] = <span class="float">2</span><span class="float">.0</span>;      <span class="comment">// sets the 4th element of the third column to 2.0</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Behavior is undefined when accessing a component outside the bounds of a | 
 | matrix with a non-constant expression. | 
 | It is an error to access a matrix with a constant expression | 
 | that is outside the bounds of the matrix.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="structure-and-array-operations">5.7. Structure and Array Operations</h3> | 
 | <div class="paragraph"> | 
 | <p>The members of a structure and the <strong>length</strong>() method of an array are | 
 | selected using the period (<strong>.</strong>).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In total, only the following operators are allowed to operate on arrays and | 
 | structures as whole entities:</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all fit-content"> | 
 | <colgroup> | 
 | <col> | 
 | <col> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">field selector</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>.</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">equality</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>==</strong> <strong>!=</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">assignment</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>=</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Ternary operator</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>?:</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Sequence operator</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>,</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">indexing (arrays only)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>[</strong> <strong>]</strong></p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The equality operators and assignment operator are only allowed if the two | 
 | operands are same size and type. | 
 | The operands cannot contain any opaque types. | 
 | Structure types must be of the same declared structure. | 
 | Both array operands must be | 
 | compile-time | 
 | sized. | 
 | When using the equality operators, two structures are equal if and only if | 
 | all the members are component-wise equal, and two arrays are equal if and | 
 | only if all the elements are element-wise equal.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Array elements are accessed using the array subscript operator (<strong>[ ]</strong>). | 
 | An example of accessing an array element is</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">diffuseColor += lightIntensity[<span class="integer">3</span>] * NdotL;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Array indices start at zero. | 
 | Array elements are accessed using an expression whose type is <strong>int</strong> or | 
 | <strong>uint</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Behavior is undefined if a shader subscripts an array with an index less | 
 | than 0 or greater than or equal to the size the array was declared with.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays can also be accessed with the method operator (<strong>.</strong>) and the <strong>length</strong> | 
 | method to query the size of the array:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">lightIntensity.length() <span class="comment">// return the size of the array</span></code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="assignments">5.8. Assignments</h3> | 
 | <div class="paragraph"> | 
 | <p>Assignments of values to variable names are done with the assignment | 
 | operator (<strong>=</strong>):</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><em>lvalue-expression</em> = <em>rvalue-expression</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <em>lvalue-expression</em> evaluates to an l-value. | 
 | The assignment operator stores the value of <em>rvalue-expression</em> into the | 
 | l-value and returns an r-value with the type and precision of | 
 | <em>lvalue-expression</em>. | 
 | The <em>lvalue-expression</em> and <em>rvalue-expression</em> must have the same | 
 | type. | 
 | Any type-conversions must be specified explicitly via constructors. | 
 | It is an error if the l-value is not writable. | 
 | Variables that are built-in types, entire structures or arrays, structure | 
 | members, l-values with the field selector (<strong>.</strong>) applied to select components | 
 | or swizzles without repeated fields, l-values within parentheses, and | 
 | l-values dereferenced with the array subscript operator (<strong>[ ]</strong>) are all | 
 | l-values. | 
 | Other binary or unary expressions, function names, swizzles with repeated | 
 | fields, and constants cannot be l-values. | 
 | The ternary operator (<strong>?:</strong>) is also not allowed as an l-value. | 
 | Using an incorrect expression as an l-value results in an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Expressions on the left of an assignment are evaluated before expressions on | 
 | the right of the assignment.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The other assignment operators are</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>add into (<strong>+=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>subtract from (<strong>-=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>multiply into (<strong>*=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>divide into (<strong>/=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>modulus into (<strong>%=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>left shift by (<strong><<=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>right shift by (<strong>>>=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>and into (<strong>&=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>inclusive-or into (<strong>|=</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>exclusive-or into (<strong>^=</strong>)</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where the general expression</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><em>lvalue</em> <em>op</em>= <em>expression</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is equivalent to</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><em>lvalue</em> = <em>lvalue</em> <em>op</em> <em>expression</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where <em>lvalue</em> is the value returned by <em>lvalue-expression</em>, <em>op</em> is as | 
 | described below, and the <em>lvalue-expression</em> and <em>expression</em> must satisfy | 
 | the semantic requirements of both <em>op</em> and equals (<strong>=</strong>).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Reading a variable before writing (or initializing) it is legal, however the | 
 | value is undefined.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="expressions">5.9. Expressions</h3> | 
 | <div class="paragraph"> | 
 | <p>Expressions in the shading language are built from the following:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Constants of type <strong>bool</strong>, all integral types, all floating-point types, | 
 | all vector types, and all matrix types.</p> | 
 | </li> | 
 | <li> | 
 | <p>Constructors of all types.</p> | 
 | </li> | 
 | <li> | 
 | <p>Variable names of all types.</p> | 
 | </li> | 
 | <li> | 
 | <p>Arrays with the length method applied.</p> | 
 | </li> | 
 | <li> | 
 | <p>Subscripted arrays.</p> | 
 | </li> | 
 | <li> | 
 | <p>Function calls that return values. | 
 | In some cases, function calls returning <strong>void</strong> are also allowed in | 
 | expressions as specified below.</p> | 
 | </li> | 
 | <li> | 
 | <p>Component field selectors and array subscript results.</p> | 
 | </li> | 
 | <li> | 
 | <p>Parenthesized expressions. | 
 | Any expression, including expressions with void type can be | 
 | parenthesized. | 
 | Parentheses can be used to group operations. | 
 | Operations within parentheses are done before operations across | 
 | parentheses.</p> | 
 | </li> | 
 | <li> | 
 | <p>The arithmetic binary operators add (<strong>+</strong>), subtract (<strong>-</strong>), multiply | 
 | (<strong>*</strong>), and divide (<strong>/</strong>) operate on integer and floating-point scalars, | 
 | vectors, and matrices. | 
 | If the operands are integral types, they must both be signed or both be | 
 | unsigned. | 
 | All arithmetic binary operators result in the same fundamental type | 
 | (signed integer, unsigned integer, or floating-point) as the operands | 
 | they operate on. | 
 | The following cases are valid</p> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>The two operands are scalars. | 
 | In this case the operation is applied, resulting in a scalar.</p> | 
 | </li> | 
 | <li> | 
 | <p>One operand is a scalar, and the other is a vector or matrix. | 
 | In this case, the scalar operation is applied independently to each | 
 | component of the vector or matrix, resulting in the same size vector or | 
 | matrix.</p> | 
 | </li> | 
 | <li> | 
 | <p>The two operands are vectors of the same size. | 
 | In this case, the operation is done component-wise resulting in the | 
 | same size vector.</p> | 
 | </li> | 
 | <li> | 
 | <p>The operator is add (<strong>+</strong>), subtract (<strong>-</strong>), or divide (<strong>/</strong>), and the | 
 | operands are matrices with the same number of rows and the same number | 
 | of columns. | 
 | In this case, the operation is done component-wise resulting in the | 
 | same size matrix.</p> | 
 | </li> | 
 | <li> | 
 | <p>The operator is multiply (<strong>*</strong>), where both operands are matrices or one | 
 | operand is a vector and the other a matrix. | 
 | A right vector operand is treated as a column vector and a left vector | 
 | operand as a row vector. | 
 | In all these cases, it is required that the number of columns of the | 
 | left operand is equal to the number of rows of the right operand. | 
 | Then, the multiply (<strong>*</strong>) operation does a linear algebraic multiply, | 
 | yielding an object that has the same number of rows as the left operand | 
 | and the same number of columns as the right operand. | 
 | “<a href="#vector-and-matrix-operations">Vector and Matrix Operations</a>” | 
 | explains in more detail how vectors and matrices are operated on.</p> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="paragraph"> | 
 | <p>All other cases result in an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Use the built-in functions <strong>dot</strong>, <strong>cross</strong>, <strong>matrixCompMult</strong>, and | 
 | <strong>outerProduct</strong>, to get, respectively, vector dot product, vector cross | 
 | product, matrix component-wise multiplication, and the matrix product of a | 
 | column vector times a row vector.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | </li> | 
 | <li> | 
 | <p>The operator modulus (<strong>%</strong>) operates on signed or unsigned integers or | 
 | integer vectors. | 
 | The operand types must both be signed or both be unsigned. | 
 | The operands cannot be vectors of differing size; this is | 
 | an error. | 
 | If one operand is a scalar and the other vector, then the scalar is | 
 | applied component-wise to the vector, resulting in the same type as the | 
 | vector. | 
 | If both are vectors of the same size, the result is computed | 
 | component-wise. | 
 | The resulting value is undefined for any component computed with a | 
 | second operand that is zero, while results for other components with | 
 | non-zero second operands remain defined. | 
 | If both operands are non-negative, then the remainder is non-negative. | 
 | Results are undefined if one or both operands are negative. | 
 | The operator modulus (<strong>%</strong>) is not defined for any other data types | 
 | (non-integer types).</p> | 
 | </li> | 
 | <li> | 
 | <p>The arithmetic unary operators negate (<strong>-</strong>), post- and pre-increment and | 
 | decrement (<strong>--</strong> and <strong>++</strong>) operate on integer or floating-point values | 
 | (including vectors and matrices). | 
 | All unary operators work component-wise on their operands. | 
 | These result with the same type they operated on. | 
 | For post- and pre-increment and decrement, the expression must be a writable | 
 | l-value. | 
 | Pre-increment and pre-decrement add or subtract 1 or 1.0 to the contents | 
 | of the expression they operate on, and the value of the pre-increment or | 
 | pre-decrement expression is the resulting value of that modification. | 
 | Post-increment and post-decrement expressions add or subtract 1 or 1.0 | 
 | to the contents of the expression they operate on, but the resulting | 
 | expression has the expression’s value before the post-increment or | 
 | post-decrement was executed.</p> | 
 | </li> | 
 | <li> | 
 | <p>The relational operators greater than (<strong>></strong>), less than (<strong><</strong>), greater | 
 | than or equal (<strong>>=</strong>), and less than or equal (<strong><=</strong>) operate only on | 
 | scalar integer and scalar floating-point expressions. | 
 | The result is scalar Boolean. | 
 | The types of the operands must match. | 
 | To do component-wise relational comparisons on vectors, use the built-in | 
 | functions <strong>lessThan</strong>, <strong>lessThanEqual</strong>, <strong>greaterThan</strong>, and | 
 | <strong>greaterThanEqual.</strong></p> | 
 | </li> | 
 | <li> | 
 | <p>The equality operators <strong>equal</strong> (<strong>==</strong>), and not equal (<strong>!=</strong>) operate on | 
 | all types except opaque types. | 
 | They result in a scalar Boolean. | 
 | The types of the operands must match. | 
 | For vectors, matrices, structures, and arrays, all components, members, | 
 | or elements of one operand must equal the corresponding components, | 
 | members, or elements in the other operand for the operands to be | 
 | considered equal. | 
 | To get a vector of component-wise equality results for vectors, use the | 
 | built-in functions <strong>equal</strong> and <strong>notEqual</strong>.</p> | 
 | </li> | 
 | <li> | 
 | <p>The logical binary operators and (<strong>&&</strong>), or (<strong>||</strong>), and exclusive or | 
 | (<strong>^^</strong>) operate only on two Boolean expressions and result in a Boolean | 
 | expression. | 
 | And (<strong>&&</strong>) will only evaluate the right hand operand if the left hand | 
 | operand evaluated to <strong>true</strong>. | 
 | Or (<strong>||</strong>) will only evaluate the right hand operand if the left hand | 
 | operand evaluated to <strong>false</strong>. | 
 | Exclusive or (<strong>^^</strong>) will always evaluate both operands.</p> | 
 | </li> | 
 | <li> | 
 | <p>The logical unary operator not (<strong>!</strong>). | 
 | It operates only on a Boolean expression and results in a Boolean | 
 | expression. | 
 | To operate on a vector, use the built-in function <strong>not</strong>.</p> | 
 | </li> | 
 | <li> | 
 | <p>The sequence (<strong>,</strong>) operator that operates on expressions by returning | 
 | the type and value of the right-most expression in a comma separated | 
 | list of expressions. | 
 | All expressions are evaluated, in order, from left to right. | 
 | The operands to the sequence operator may have <strong>void</strong> type.</p> | 
 | </li> | 
 | <li> | 
 | <p>The ternary selection operator (<strong>?:</strong>). | 
 | It operates on three expressions (<em>exp1</em> <strong>?</strong> <em>exp2</em> <strong>:</strong> <em>exp3</em>). | 
 | This operator evaluates the first expression, which must result in a | 
 | scalar Boolean. | 
 | If the result is true, it selects to evaluate the second expression, | 
 | otherwise it selects to evaluate the third expression. | 
 | Only one of the second and third expressions is evaluated. | 
 | The second and third expressions can be any type, including <strong>void</strong>, as | 
 | long their types match. | 
 | This resulting matching type is the type of the entire expression.</p> | 
 | </li> | 
 | <li> | 
 | <p>The one’s complement operator (<strong>~</strong>). | 
 | The operand must be of type signed or unsigned integer or integer | 
 | vector, and the result is the one’s complement of its operand; each bit | 
 | of each component is complemented, including any sign bits.</p> | 
 | </li> | 
 | <li> | 
 | <p>The shift operators (<strong><<</strong>) and (<strong>>></strong>). | 
 | For both operators, the operands must be signed or unsigned integers or | 
 | integer vectors. | 
 | One operand can be signed while the other is unsigned. | 
 | In all cases, the resulting type will be the same type as the left | 
 | operand. | 
 | If the first operand is a scalar, the second operand has to be a scalar | 
 | as well. | 
 | If the first operand is a vector, the second operand must be a scalar or | 
 | a vector with the same size as the first operand, and the result is | 
 | computed component-wise. | 
 | The result is undefined if the right operand is negative, or greater | 
 | than or equal to the number of bits in the left expression’s base type. | 
 | The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted | 
 | by E2 bits. | 
 | The value of E1 >> E2 is E1 right-shifted by E2 bit positions. | 
 | If E1 is a signed integer, the right-shift will extend the sign bit. | 
 | If E1 is an unsigned integer, the right-shift will zero-extend.</p> | 
 | </li> | 
 | <li> | 
 | <p>The bitwise operators and (<strong>&</strong>), exclusive-or (<strong>^</strong>), and inclusive-or | 
 | (<strong>|</strong>). | 
 | The operands must be of type signed or unsigned integers or integer | 
 | vectors. | 
 | The operands cannot be vectors of differing size; this is an error. | 
 | If one operand is a scalar and the other a vector, the scalar is applied | 
 | component-wise to the vector, resulting in the same type as the vector. | 
 | The fundamental types of the operands (signed or unsigned) must match, | 
 | and will be the resulting fundamental type. | 
 | For and (<strong>&</strong>), the result is the bitwise-and function of the operands. | 
 | For exclusive-or (<strong>^</strong>), the result is the bitwise exclusive-or function | 
 | of the operands. | 
 | For inclusive-or (<strong>|</strong>), the result is the bitwise inclusive-or function | 
 | of the operands.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For a complete specification of the syntax of expressions, see | 
 | “<a href="#shading-language-grammar">Shading Language Grammar</a>”.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="vector-and-matrix-operations">5.10. Vector and Matrix Operations</h3> | 
 | <div class="paragraph"> | 
 | <p>With a few exceptions, operations are component-wise. | 
 | Usually, when an operator operates on a vector or matrix, it is operating | 
 | independently on each component of the vector or matrix, in a component-wise | 
 | fashion. | 
 | For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec3 v, u; | 
 | <span class="predefined-type">float</span> f; | 
 | v = u + f;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will be equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">v.x = u.x + f; | 
 | v.y = u.y + f; | 
 | v.z = u.z + f;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>And</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec3 v, u, w; | 
 | w = v + u;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>will be equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">w.x = v.x + u.x; | 
 | w.y = v.y + u.y; | 
 | w.z = v.z + u.z;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>and likewise for most operators and all integer and floating-point vector | 
 | and matrix types. | 
 | The exceptions are matrix multiplied by vector, vector multiplied by matrix, | 
 | and matrix multiplied by matrix. | 
 | These do not operate component-wise, but rather perform the correct linear | 
 | algebraic multiply.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec3 v, u; | 
 | mat3 m; | 
 | u = v * m;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">u.x = dot(v, m[<span class="integer">0</span>]); <span class="comment">// m[0] is the left column of m</span> | 
 | u.y = dot(v, m[<span class="integer">1</span>]); <span class="comment">// dot(a,b) is the inner (dot) product of a and b</span> | 
 | u.z = dot(v, m[<span class="integer">2</span>]);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>And</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">u = m * v;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">u.x = m[<span class="integer">0</span>].x * v.x + m[<span class="integer">1</span>].x * v.y + m[<span class="integer">2</span>].x * v.z; | 
 | u.y = m[<span class="integer">0</span>].y * v.x + m[<span class="integer">1</span>].y * v.y + m[<span class="integer">2</span>].y * v.z; | 
 | u.z = m[<span class="integer">0</span>].z * v.x + m[<span class="integer">1</span>].z * v.y + m[<span class="integer">2</span>].z * v.z;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>And</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">mat3 m, n, r; | 
 | r = m * n;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>is equivalent to</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">r[<span class="integer">0</span>].x = m[<span class="integer">0</span>].x * n[<span class="integer">0</span>].x + m[<span class="integer">1</span>].x * n[<span class="integer">0</span>].y + m[<span class="integer">2</span>].x * n[<span class="integer">0</span>].z; | 
 | r[<span class="integer">1</span>].x = m[<span class="integer">0</span>].x * n[<span class="integer">1</span>].x + m[<span class="integer">1</span>].x * n[<span class="integer">1</span>].y + m[<span class="integer">2</span>].x * n[<span class="integer">1</span>].z; | 
 | r[<span class="integer">2</span>].x = m[<span class="integer">0</span>].x * n[<span class="integer">2</span>].x + m[<span class="integer">1</span>].x * n[<span class="integer">2</span>].y + m[<span class="integer">2</span>].x * n[<span class="integer">2</span>].z; | 
 | r[<span class="integer">0</span>].y = m[<span class="integer">0</span>].y * n[<span class="integer">0</span>].x + m[<span class="integer">1</span>].y * n[<span class="integer">0</span>].y + m[<span class="integer">2</span>].y * n[<span class="integer">0</span>].z; | 
 | r[<span class="integer">1</span>].y = m[<span class="integer">0</span>].y * n[<span class="integer">1</span>].x + m[<span class="integer">1</span>].y * n[<span class="integer">1</span>].y + m[<span class="integer">2</span>].y * n[<span class="integer">1</span>].z; | 
 | r[<span class="integer">2</span>].y = m[<span class="integer">0</span>].y * n[<span class="integer">2</span>].x + m[<span class="integer">1</span>].y * n[<span class="integer">2</span>].y + m[<span class="integer">2</span>].y * n[<span class="integer">2</span>].z; | 
 | r[<span class="integer">0</span>].z = m[<span class="integer">0</span>].z * n[<span class="integer">0</span>].x + m[<span class="integer">1</span>].z * n[<span class="integer">0</span>].y + m[<span class="integer">2</span>].z * n[<span class="integer">0</span>].z; | 
 | r[<span class="integer">1</span>].z = m[<span class="integer">0</span>].z * n[<span class="integer">1</span>].x + m[<span class="integer">1</span>].z * n[<span class="integer">1</span>].y + m[<span class="integer">2</span>].z * n[<span class="integer">1</span>].z; | 
 | r[<span class="integer">2</span>].z = m[<span class="integer">0</span>].z * n[<span class="integer">2</span>].x + m[<span class="integer">1</span>].z * n[<span class="integer">2</span>].y + m[<span class="integer">2</span>].z * n[<span class="integer">2</span>].z;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>and similarly for other sizes of vectors and matrices.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="evaluation-of-expressions">5.11. Evaluation of Expressions</h3> | 
 | <div class="paragraph"> | 
 | <p>In general expressions must be evaluated in the order specified by the | 
 | precedence of operations and may only be regrouped if the result is the same or | 
 | where the result is undefined. | 
 | No other transforms may be applied that affect the result of an operation. | 
 | GLSL ES relaxes these requirements for scalar operations in the following | 
 | ways:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Addition and multiplication are assumed to be associative.</p> | 
 | </li> | 
 | <li> | 
 | <p>Multiplication is assumed to be distributive over addition. | 
 | Therefore expressions may be expanded and re-factored.</p> | 
 | </li> | 
 | <li> | 
 | <p>Floating-point division may be replaced by reciprocal and | 
 | multiplication.</p> | 
 | </li> | 
 | <li> | 
 | <p>Multiplication may be replaced by repeated addition.</p> | 
 | </li> | 
 | <li> | 
 | <p>Within the constraints of invariance (where applicable), the precision | 
 | used may vary.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These rules also apply to the built-in functions.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="statements-and-structure">6. Statements and Structure</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>The fundamental building blocks of the OpenGL ES Shading Language are:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>statements and declarations</p> | 
 | </li> | 
 | <li> | 
 | <p>function definitions</p> | 
 | </li> | 
 | <li> | 
 | <p>selection (<strong>if</strong>-<strong>else</strong> and <strong>switch</strong>-<strong>case</strong>-<strong>default</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>iteration (<strong>for</strong>, <strong>while</strong>, and <strong>do</strong>-<strong>while</strong>)</p> | 
 | </li> | 
 | <li> | 
 | <p>jumps (<strong>discard</strong>, <strong>return</strong>, <strong>break</strong>, and <strong>continue</strong>)</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The overall structure of a shader is as follows</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>translation-unit</em> : </dt> | 
 | <dd> | 
 | <p><em>global-declaration</em><br> | 
 | <em>translation-unit</em> <em>global-declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>global-declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>function-definition</em><br> | 
 | <em>declaration</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>That is, a shader is a sequence of declarations and function bodies. | 
 | Function bodies are defined as</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>function-definition</em> : </dt> | 
 | <dd> | 
 | <p><em>function-prototype</em> <strong>{</strong> <em>statement-list</em> <strong>}</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>statement-list</em> : </dt> | 
 | <dd> | 
 | <p><em>statement</em><br> | 
 | <em>statement-list</em> <em>statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>statement</em> : </dt> | 
 | <dd> | 
 | <p><em>compound-statement</em><br> | 
 | <em>simple-statement</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Curly braces are used to group sequences of statements into compound | 
 | statements.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>compound-statement</em> : </dt> | 
 | <dd> | 
 | <p><strong>{</strong> <em>statement-list</em> <strong>}</strong></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>simple-statement</em> : </dt> | 
 | <dd> | 
 | <p><em>declaration-statement</em><br> | 
 | <em>expression-statement</em><br> | 
 | <em>selection-statement</em><br> | 
 | <em>iteration-statement</em><br> | 
 | <em>jump-statement</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Simple declaration, expression, and jump statements end in a semi-colon.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This above is slightly simplified, and the complete grammar specified in | 
 | “<a href="#shading-language-grammar">Shading Language Grammar</a>” should be used as | 
 | the definitive specification.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Declarations and expressions have already been discussed.</p> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="function-definitions">6.1. Function Definitions</h3> | 
 | <div class="paragraph"> | 
 | <p>As indicated by the grammar above, a valid shader is a sequence of global | 
 | declarations and function definitions. | 
 | A function is declared as the following example shows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// prototype</span> | 
 | returnType functionName (type0 arg0, type1 arg1, ..., typen argn);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>and a function is defined like</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// definition</span> | 
 | returnType functionName (type0 arg0, type1 arg1, ..., typen argn) | 
 | { | 
 |     <span class="comment">// do some computation</span> | 
 |     <span class="keyword">return</span> returnValue; | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where <em>returnType</em> must be present and cannot be void, or:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> functionName (type0 arg0, type1 arg1, ..., typen argn) | 
 | { | 
 |     <span class="comment">// do some computation</span> | 
 |     <span class="keyword">return</span>; <span class="comment">// optional</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Each of the <em>typeN</em> must include a type and can optionally include a | 
 | parameter qualifier and/or <strong>const</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A function is called by using its name followed by a list of arguments in | 
 | parentheses.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Arrays are allowed as arguments and as the return type. | 
 | In both cases, the array must be | 
 | compile-time | 
 | sized. | 
 | An array is passed or returned by using just its name, without brackets, and | 
 | the size of the array must match the size specified in the function’s | 
 | declaration.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Structures are also allowed as argument types. | 
 | The return type can also be a structure.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>See “<a href="#shading-language-grammar">Shading Language Grammar</a>” for the | 
 | definitive reference on the syntax to declare and define functions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All functions must be either declared with a prototype or defined with a | 
 | body before they are called. | 
 | For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> myfunc (<span class="predefined-type">float</span> f,      <span class="comment">// f is an input parameter</span> | 
 |               out <span class="predefined-type">float</span> g); <span class="comment">// g is an output parameter</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Functions that return no value must be declared as <strong>void</strong>. | 
 | A <strong>void</strong> function can only use <strong>return</strong> without a return argument, even if | 
 | the return argument has <strong>void</strong> type. | 
 | Return statements only accept values:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> func1() { } | 
 | <span class="directive">void</span> func2() { <span class="keyword">return</span> func1(); } <span class="comment">// illegal return statement</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Only a precision qualifier is allowed on the return type of a function. | 
 | Formal parameters can have parameter, precision, and memory qualifiers, but | 
 | no other qualifiers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Functions that accept no input arguments need not use <strong>void</strong> in the argument | 
 | list because prototypes (or definitions) are required and therefore there is | 
 | no ambiguity when an empty argument list “( )” is declared. | 
 | The idiom “(<strong>void</strong>)” as a parameter list is provided for convenience.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Function names can be overloaded. | 
 | The same function name can be used for multiple functions, as long as the | 
 | parameter types differ. | 
 | If a function name is declared twice with the same parameter types, then the | 
 | return types and all qualifiers must also match, and it is the same function | 
 | being declared. | 
 | When function calls are resolved, an exact type match for all the arguments | 
 | is required.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example,</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4 f(in vec4 x, out vec4 y); | 
 | vec4 f(in vec4 x, out uvec4 y);      <span class="comment">// allowed, different argument type</span> | 
 | <span class="predefined-type">int</span> f(in vec4 x, out vec4 y);        <span class="comment">// error, only return type differs</span> | 
 | vec4 f(in vec4 x, in vec4 y);        <span class="comment">// error, only qualifier differs</span> | 
 | vec4 f(<span class="directive">const</span> in vec4 x, out vec4 y); <span class="comment">// error, only qualifier differs</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Calling the first two functions above with the following argument types | 
 | yields</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">f(vec4, vec4)   <span class="comment">// exact match of vec4 f(in vec4 x, out vec4 y)</span> | 
 | f(vec4, uvec4)  <span class="comment">// exact match of vec4 f(in vec4 x, out uvec4 y)</span> | 
 | f(ivec4, vec4)  <span class="comment">// error, no exact match.</span> | 
 | f(ivec4, uvec4) <span class="comment">// error, no exact match.</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>User-defined functions can have multiple declarations, but only one | 
 | definition.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A shader cannot redefine or overload built-in functions.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The function <em>main</em> is used as the entry point to a shader executable. | 
 | All shaders must define a function named <em>main</em>. | 
 | This function takes no arguments, returns no value, and must be declared as | 
 | type <strong>void</strong>:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> main() | 
 | { | 
 |     ... | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The function <em>main</em> can contain uses of <strong>return</strong>. | 
 | See “<a href="#jumps">Jumps</a>” for more details.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>It is a compile-time or link-time error to declare or define a function | 
 | <strong>main</strong> with any other parameters or return type.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="function-calling-conventions">6.1.1. Function Calling Conventions</h4> | 
 | <div class="paragraph"> | 
 | <p>Functions are called by value-return. | 
 | This means input arguments are copied into the function at call time, and | 
 | output arguments are copied back to the caller before function exit. | 
 | Because the function works with local copies of parameters, there are no | 
 | issues regarding aliasing of variables within a function. | 
 | To control what parameters are copied in and/or out through a function | 
 | definition or declaration:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>The keyword <strong>in</strong> is used as a qualifier to denote a parameter is to be | 
 | copied in, but not copied out.</p> | 
 | </li> | 
 | <li> | 
 | <p>The keyword <strong>out</strong> is used as a qualifier to denote a parameter is to be | 
 | copied out, but not copied in. | 
 | This should be used whenever possible to avoid unnecessarily copying | 
 | parameters in.</p> | 
 | </li> | 
 | <li> | 
 | <p>The keyword <strong>inout</strong> is used as a qualifier to denote the parameter is to | 
 | be both copied in and copied out. | 
 | It means the same thing as specifying both <strong>in</strong> and <strong>out</strong>.</p> | 
 | </li> | 
 | <li> | 
 | <p>A function parameter declared with no such qualifier means the same | 
 | thing as specifying <strong>in</strong>.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All arguments are evaluated at call time, exactly once, in order, from left | 
 | to right. | 
 | Evaluation of an <strong>in</strong> parameter results in a value that is copied to the | 
 | formal parameter. | 
 | Evaluation of an <strong>out</strong> parameter results in an l-value that is used to copy | 
 | out a value when the function returns. | 
 | Evaluation of an <strong>inout</strong> parameter results in both a value and an l-value; | 
 | the value is copied to the formal parameter at call time and the l-value is | 
 | used to copy out a value when the function returns.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The order in which output parameters are copied back to the caller is | 
 | undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In a function, writing to an input-only parameter is allowed. | 
 | Only the function’s copy is modified. | 
 | This can be prevented by declaring a parameter with the <strong>const</strong> qualifier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When calling a function, expressions that do not evaluate to l-values cannot | 
 | be passed to parameters declared as <strong>out</strong> or <strong>inout</strong>, or an error | 
 | results.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Only precision qualifiers are allowed on the return type of a function.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The syntax for function prototypes can be informally expressed as:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>function_prototype</em> : </dt> | 
 | <dd> | 
 | <p>[ <em>type_qualifier</em> ] <em>type_specifier</em> <em>IDENTIFIER</em> <em>LEFT_PAREN</em> | 
 | <em>parameter_declaration</em> , <em>parameter_declaration</em> , …​ | 
 | , <em>RIGHT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>parameter_declaration</em> : </dt> | 
 | <dd> | 
 | <p>[ <em>type_qualifier</em> ] <em>type_specifier</em> [ <em>IDENTIFIER</em> [ <em>array_specifier</em> | 
 | ] ]</p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>type_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>single_type_qualifier</em> , <em>single_type_qualifier</em> , …​</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The qualifiers allowed on formal parameters are:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p><em>empty</em><br> | 
 | <strong>const</strong><br> | 
 | <strong>in</strong><br> | 
 | <strong>out</strong><br> | 
 | <strong>inout</strong><br> | 
 | <strong>precise</strong><br> | 
 | <em>memory-qualifier</em><br> | 
 | <em>precision-qualifier</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>const</strong> qualifier cannot be used with <strong>out</strong> or <strong>inout</strong>, or | 
 | an error results. | 
 | The above is used both for function declarations (i.e., prototypes) and for | 
 | function definitions. | 
 | Hence, function definitions can have unnamed arguments.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Static, and hence dynamic recursion, are not allowed. | 
 | Static recursion is present if the static function-call graph of a program | 
 | contains cycles. | 
 | Dynamic recursion occurs if at any time control flow has entered but not | 
 | exited a single function more than once.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="selection">6.2. Selection</h3> | 
 | <div class="paragraph"> | 
 | <p>Conditional control flow in the shading language is done by either <strong>if</strong>, | 
 | <strong>if</strong>-<strong>else</strong>, or <strong>switch</strong> statements:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>selection-statement</em> : </dt> | 
 | <dd> | 
 | <p><strong>if</strong> <strong>(</strong> <em>bool-expression</em> <strong>)</strong> <em>statement</em><br> | 
 | <strong>if</strong> <strong>(</strong> <em>bool-expression</em> <strong>)</strong> <em>statement</em> <strong>else</strong> <em>statement</em><br> | 
 | <strong>switch</strong> <strong>(</strong> <em>init-expression</em> <strong>)</strong> <strong>{</strong> <em>switch-statement-list<sub>opt</sub></em> <strong>}</strong></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Where <em>switch-statement-list</em> is a nested scope containing a list of zero or | 
 | more <em>switch-statement</em> and other statements defined by the language, where | 
 | <em>switch-statement</em> adds some forms of labels. | 
 | That is</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>switch-statement-list</em> : </dt> | 
 | <dd> | 
 | <p><em>switch-statement</em><br> | 
 | <em>switch-statement-list</em> <em>switch-statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>switch-statement</em> : </dt> | 
 | <dd> | 
 | <p><strong>case</strong> <em>constant-expression</em> <strong>:</strong><br> | 
 | <strong>default</strong> <strong>:</strong> <em>statement</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Note the above grammar’s purpose is to aid discussion in this section; the | 
 | normative grammar is in “<a href="#shading-language-grammar">Shading Language | 
 | Grammar</a>”.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If an <strong>if</strong>-expression evaluates to <strong>true</strong>, then the first <em>statement</em> is | 
 | executed. | 
 | If it evaluates to <strong>false</strong> and there is an <strong>else</strong> part then the second | 
 | <em>statement</em> is executed.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Any expression whose type evaluates to a Boolean can be used as the | 
 | conditional expression <em>bool-expression</em>. | 
 | Vector types are not accepted as the expression to <strong>if</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Conditionals can be nested.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The type of <em>init-expression</em> in a <strong>switch</strong> statement must be a scalar | 
 | integer. | 
 | The type of <em>init-expression</em> must match the type of the <strong>case</strong> labels | 
 | within each <strong>switch</strong> statement. | 
 | Either signed integers or unsigned integers are allowed but there is no | 
 | implicit type conversion between the two. | 
 | If a <strong>case</strong> label has a <em>constant-expression</em> of equal value to | 
 | <em>init-expression</em>, execution will continue after that label. | 
 | Otherwise, if there is a <strong>default</strong> label, execution will continue after that | 
 | label. | 
 | Otherwise, execution skips the rest of the switch statement. | 
 | It is an error to have more than one <strong>default</strong> or a replicated | 
 | <em>constant-expression</em>. | 
 | A <strong>break</strong> statement not nested in a loop or other switch statement (either | 
 | not nested or nested only in <strong>if</strong> or <strong>if</strong>-<strong>else</strong> statements) will also skip | 
 | the rest of the switch statement. | 
 | Fall through labels are allowed, but it is an error to have no | 
 | statement between a label and the end of the switch statement. | 
 | No statements are allowed in a switch statement before the first <strong>case</strong> | 
 | statement.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>case</strong> and <strong>default</strong> labels can only appear within a <strong>switch</strong> statement. | 
 | No <strong>case</strong> or <strong>default</strong> labels can be nested inside other statements or | 
 | compound statements within their corresponding <strong>switch</strong>.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="iteration">6.3. Iteration</h3> | 
 | <div class="paragraph"> | 
 | <p>For, while, and do loops are allowed as follows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">for</span> (init-expression; condition-expression; loop-expression) | 
 |     sub-statement | 
 | <span class="keyword">while</span> (condition-expression) | 
 |     sub-statement | 
 | <span class="keyword">do</span> | 
 |     statement | 
 | <span class="keyword">while</span> (condition-expression)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>See “<a href="#shading-language-grammar">Shading Language Grammar</a>” for the | 
 | definitive specification of loops.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>for</strong> loop first evaluates the <em>init-expression</em>, then the | 
 | <em>condition-expression</em>. | 
 | If the <em>condition-expression</em> evaluates to <strong>true</strong>, then the body of the loop | 
 | is executed. | 
 | After the body is executed, a <strong>for</strong> loop will then evaluate the | 
 | <em>loop-expression</em>, and then loop back to evaluate the | 
 | <em>condition-expression</em>, repeating until the <em>condition-expression</em> evaluates | 
 | to <strong>false</strong>. | 
 | The loop is then exited, skipping its body and skipping its | 
 | <em>loop-expression</em>. | 
 | Variables modified by the <em>loop-expression</em> maintain their value after the | 
 | loop is exited, provided they are still in scope. | 
 | Variables declared in <em>init-expression</em> or <em>condition-expression</em> are only | 
 | in scope until the end of the sub-statement of the <strong>for</strong> loop.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>while</strong> loop first evaluates the <em>condition-expression</em>. | 
 | If <strong>true</strong>, then the body is executed. | 
 | This is then repeated, until the <em>condition-expression</em> evaluates to | 
 | <strong>false</strong>, exiting the loop and skipping its body. | 
 | Variables declared in the <em>condition-expression</em> are only in scope until the | 
 | end of the sub-statement of the <strong>while</strong> loop.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For both <strong>for</strong> and <strong>while</strong> loops, the sub-statement does not introduce a new | 
 | scope for variable names, so the following has a redeclaration error:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">for</span> (<span class="predefined-type">int</span> i = <span class="integer">0</span>; i < <span class="integer">10</span>; i++) + | 
 | { | 
 |     <span class="predefined-type">int</span> i; <span class="comment">// redeclaration error +</span> | 
 | }</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>do</strong>-<strong>while</strong> loop first executes the body, then executes the | 
 | <em>condition-expression</em>. | 
 | This is repeated until <em>condition-expression</em> evaluates to <strong>false</strong>, and then | 
 | the loop is exited.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Expressions for <em>condition-expression</em> must evaluate to a Boolean.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Both the <em>condition-expression</em> and the <em>init-expression</em> can declare and | 
 | initialize a variable, except in the <strong>do</strong>-<strong>while</strong> loop, which cannot declare | 
 | a variable in its <em>condition-expression</em>. | 
 | The variable’s scope lasts only until the end of the sub-statement that | 
 | forms the body of the loop.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Loops can be nested.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Non-terminating loops are allowed. | 
 | The consequences of very long or non-terminating loops are platform | 
 | dependent.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="jumps">6.4. Jumps</h3> | 
 | <div class="paragraph"> | 
 | <p>These are the jumps:</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>jump_statement</em> : </dt> | 
 | <dd> | 
 | <p><strong>continue</strong> <strong>;</strong><br> | 
 | <strong>break</strong> <strong>;</strong><br> | 
 | <strong>return</strong> <strong>;</strong><br> | 
 | <strong>return</strong> <em>expression</em> <strong>;</strong><br> | 
 | <strong>discard</strong> <strong>;</strong> // in the fragment shader language only</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>There is no “goto” or other non-structured flow of control.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>continue</strong> jump is used only in loops. | 
 | It skips the remainder of the body of the inner-most loop of which it is | 
 | inside. | 
 | For <strong>while</strong> and <strong>do</strong>-<strong>while</strong> loops, this jump is to the next evaluation of | 
 | the loop <em>condition-expression</em> from which the loop continues as previously | 
 | defined. | 
 | For <strong>for</strong> loops, the jump is to the <em>loop-expression</em>, followed by the | 
 | <em>condition-expression</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>break</strong> jump can also be used only in loops and <strong>switch</strong> statements. | 
 | It is simply an immediate exit of the inner-most loop or <strong>switch</strong> statements | 
 | containing the <strong>break</strong>. | 
 | No further execution of <em>condition-expression</em>, <em>loop-expression</em>, or | 
 | <em>switch-statement</em> is done.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>discard</strong> keyword is only allowed within fragment shaders. | 
 | It can be used within a fragment shader to abandon the operation on the | 
 | current fragment. | 
 | This keyword causes the fragment to be discarded and no updates to any | 
 | buffers will occur. | 
 | Any prior writes to other buffers such as shader storage buffers are | 
 | unaffected. | 
 | Control flow exits the shader, and subsequent implicit or explicit | 
 | derivatives are undefined when this control flow is non-uniform (meaning | 
 | different fragments within the primitive take different control paths). | 
 | It would typically be used within a conditional statement, for example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">if</span> (intensity < <span class="float">0</span><span class="float">.0</span>) | 
 |     discard;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A fragment shader may test a fragment’s alpha value and discard the fragment | 
 | based on that test. | 
 | However, it should be noted that coverage testing occurs after the fragment | 
 | shader runs, and the coverage test can change the alpha value.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>return</strong> jump causes immediate exit of the current function. | 
 | If it has <em>expression</em> then that is the return value for the function.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The function <em>main</em> can use <strong>return</strong>. | 
 | This simply causes <em>main</em> to exit in the same way as when the end of the | 
 | function had been reached. | 
 | It does not imply a use of <strong>discard</strong> in a fragment shader. | 
 | Using <strong>return</strong> in <em>main</em> before defining outputs will have the same behavior | 
 | as reaching the end of <em>main</em> before defining outputs.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="built-in-variables">7. Built-In Variables</h2> | 
 | <div class="sectionbody"> | 
 | <div class="sect2"> | 
 | <h3 id="built-in-language-variables">7.1. Built-In Language Variables</h3> | 
 | <div class="paragraph"> | 
 | <p>Some OpenGL ES operations occur in fixed functionality and need to provide | 
 | values to or receive values from shader executables. | 
 | Shaders communicate with fixed-function OpenGL ES pipeline stages, and | 
 | optionally with other shader executables, through the use of built-in input | 
 | and output variables.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="vertex-shader-special-variables">7.1.1. Vertex Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>The built-in vertex shader variables are intrinsically declared as follows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in highp <span class="predefined-type">int</span> gl_VertexID; | 
 | in highp <span class="predefined-type">int</span> gl_InstanceID; | 
 |  | 
 | out gl_PerVertex { | 
 |     out highp vec4 gl_Position; | 
 |     out highp <span class="predefined-type">float</span> gl_PointSize; | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The variable <em>gl_Position</em> is intended for writing the homogeneous vertex | 
 | position. | 
 | It can be written at any time during shader execution. | 
 | This value will be used by primitive assembly, clipping, culling, and other | 
 | fixed functionality operations, if present, that operate on primitives after | 
 | vertex processing has occurred. | 
 | Its value is undefined after the vertex processing stage if the vertex | 
 | shader executable does not write <em>gl_Position</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The variable <em>gl_PointSize</em> is intended for a shader to write the size of | 
 | the point to be rasterized. | 
 | It is measured in pixels. | 
 | If <em>gl_PointSize</em> is not written to, its value is undefined in subsequent | 
 | pipe stages.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The variable <em>gl_VertexID</em> is a vertex shader input variable that holds an | 
 | integer index for the vertex, as defined under “Shader Inputs” in section | 
 | 11.1.3.9 “Shader Inputs” of the <a href="#references">OpenGL ES Specification</a>. | 
 | While the variable <em>gl_VertexID</em> is always present, its value is not always | 
 | defined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The variable <em>gl_InstanceID</em> is a vertex shader input variable that holds | 
 | the instance number of the current primitive in an instanced draw call (see | 
 | “Shader Inputs” in section 11.1.3.9 “Shader Inputs” of the | 
 | <a href="#references">OpenGL ES Specification</a>). | 
 | If the current primitive does not come from an instanced draw call, the | 
 | value of <em>gl_InstanceID</em> is zero.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="tessellation-control-shader-special-variables">7.1.2. Tessellation Control Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>In the tessellation control shader, built-in variables are intrinsically | 
 | declared as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | } gl_in[gl_MaxPatchVertices]; | 
 |  | 
 | in highp <span class="predefined-type">int</span> gl_PatchVerticesIn; | 
 | in highp <span class="predefined-type">int</span> gl_PrimitiveID; | 
 | in highp <span class="predefined-type">int</span> gl_InvocationID; | 
 |  | 
 | out gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | } gl_out[]; | 
 |  | 
 | patch out highp <span class="predefined-type">float</span> gl_TessLevelOuter[<span class="integer">4</span>]; | 
 | patch out highp <span class="predefined-type">float</span> gl_TessLevelInner[<span class="integer">2</span>]; | 
 | patch out highp vec4 gl_BoundingBox[<span class="integer">2</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-control-input-variables">Tessellation Control Input Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> contains the output written in the previous shader stage to | 
 | <em>gl_Position</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_PatchVerticesIn</em> contains the number of vertices in the input patch | 
 | being processed by the shader. | 
 | A single shader can read patches of differing sizes, so the value of | 
 | <em>gl_PatchVerticesIn</em> may differ between patches.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_PrimitiveID</em> contains the number of primitives processed by the shader | 
 | since the current set of rendering primitives was started.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_InvocationID</em> contains the number of the output patch vertex assigned to | 
 | the tessellation control shader invocation. | 
 | It is assigned integer values in the range [0, N-1], where N is the number | 
 | of output patch vertices per primitive.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-control-output-variables">Tessellation Control Output Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> is used in the same fashion as the corresponding output | 
 | variable in the vertex shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The values written to <em>gl_TessLevelOuter</em> and <em>gl_TessLevelInner</em> are | 
 | assigned to the corresponding outer and inner tessellation levels of the | 
 | output patch. | 
 | They are used by the tessellation primitive generator to control primitive | 
 | tessellation and may be read by tessellation evaluation shaders.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The values written to <em>gl_BoundingBox</em> specify the minimum and maximum | 
 | clip-space extents of a bounding box containing all primitives generated | 
 | from the patch by the primitive generator, geometry shader, and clipping. | 
 | Fragments may or may not be generated for portions of these primitives | 
 | that extend outside the window-coordinate projection of this bounding | 
 | box.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="tessellation-evaluation-shader-special-variables">7.1.3. Tessellation Evaluation Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>In the tessellation evaluation shader, built-in variables are intrinsically | 
 | declared as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | } gl_in[gl_MaxPatchVertices]; | 
 |  | 
 | in highp <span class="predefined-type">int</span> gl_PatchVerticesIn; | 
 | in highp <span class="predefined-type">int</span> gl_PrimitiveID; | 
 | in highp vec3 gl_TessCoord; | 
 | patch in highp <span class="predefined-type">float</span> gl_TessLevelOuter[<span class="integer">4</span>]; | 
 | patch in highp <span class="predefined-type">float</span> gl_TessLevelInner[<span class="integer">2</span>]; | 
 |  | 
 | out gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | };</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-evaluation-input-variables">Tessellation Evaluation Input Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> contains the output written in the previous shader stage to | 
 | <em>gl_Position</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_PatchVerticesIn</em> and <em>gl_PrimitiveID</em> are defined in the same fashion as | 
 | the corresponding input variables in the tessellation control shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_TessCoord</em> specifies a three-component <em>(u,v,w)</em> vector identifying the | 
 | position of the vertex being processed by the shader relative to the | 
 | primitive being tessellated. | 
 | Its values will obey the properties</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">gl_TessCoord.x == <span class="float">1</span><span class="float">.0</span> - (<span class="float">1</span><span class="float">.0</span> - gl_TessCoord.x) <span class="comment">// two operations performed</span> | 
 | gl_TessCoord.y == <span class="float">1</span><span class="float">.0</span> - (<span class="float">1</span><span class="float">.0</span> - gl_TessCoord.y) <span class="comment">// two operations performed</span> | 
 | gl_TessCoord.z == <span class="float">1</span><span class="float">.0</span> - (<span class="float">1</span><span class="float">.0</span> - gl_TessCoord.z) <span class="comment">// two operations performed</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>to aid in replicating subdivision computations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_TessLevelOuter</em> and <em>gl_TessLevelInner</em> are filled with the | 
 | corresponding outputs written by the active tessellation control shader.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="tessellation-evaluation-output-variables">Tessellation Evaluation Output Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> is used in the same fashion as the corresponding output | 
 | variable in the vertex shader.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="geometry-shader-special-variables">7.1.4. Geometry Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>In the geometry shader, built-in variables are intrinsically declared as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | } gl_in[]; | 
 |  | 
 | in highp <span class="predefined-type">int</span> gl_PrimitiveIDIn; | 
 | in highp <span class="predefined-type">int</span> gl_InvocationID; | 
 |  | 
 | out gl_PerVertex { | 
 |     highp vec4 gl_Position; | 
 | }; | 
 |  | 
 | out highp <span class="predefined-type">int</span> gl_PrimitiveID; | 
 | out highp <span class="predefined-type">int</span> gl_Layer;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="geometry-shader-input-variables">Geometry Shader Input Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> contains the output written in the previous shader stage to | 
 | <em>gl_Position</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_PrimitiveIDIn</em> contains the number of primitives processed by the shader | 
 | since the current set of rendering primitives was started.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_InvocationID</em> contains the invocation number assigned to the geometry | 
 | shader invocation. | 
 | It is assigned integer values in the range [0, N-1], where N is the number | 
 | of geometry shader invocations per primitive.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect4"> | 
 | <h5 id="geometry-shader-output-variables">Geometry Shader Output Variables</h5> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Position</em> is used in the same fashion as the corresponding output | 
 | variable in the vertex shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_PrimitiveID</em> is filled with a single integer that serves as a primitive | 
 | identifier to the fragment shader. | 
 | This is then available to fragment shaders, which will select the written | 
 | primitive ID from the provoking vertex of the primitive being shaded. | 
 | If a fragment shader using <em>gl_PrimitiveID</em> is active and a geometry shader | 
 | is also active, the geometry shader must write to <em>gl_PrimitiveID</em> or the | 
 | fragment shader input <em>gl_PrimitiveID</em> is undefined. | 
 | See section 11.3.4.4 “Geometry Shader Outputs” of the | 
 | <a href="#references">OpenGL ES Specification</a> for more information.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p><em>gl_Layer</em> is used to select a specific layer (or face and layer of a cube | 
 | map) of a multi-layer framebuffer attachment. | 
 | The actual layer used will come from one of the vertices in the primitive | 
 | being shaded. | 
 | Which vertex the layer comes from is determined as discussed in section | 
 | 11.3.4.4 of the <a href="#references">OpenGL ES Specification</a> | 
 | but may be undefined, so it is best to write the same layer value for all | 
 | vertices of a primitive. | 
 | If a shader statically assigns a value to <em>gl_Layer</em>, layered rendering mode | 
 | is enabled. | 
 | See section 11.3.4.4 “Geometry Shader Outputs” and section 9.8 “Layered | 
 | Framebuffers” of the <a href="#references">OpenGL ES Specification</a> for more information. | 
 | If a shader statically assigns a value to <em>gl_Layer</em>, and there is an | 
 | execution path through the shader that does not set <em>gl_Layer</em>, then the | 
 | value of <em>gl_Layer</em> is undefined for executions of the shader that take that | 
 | path.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The output variable <em>gl_Layer</em> takes on a special value when used with an | 
 | array of cube map textures. | 
 | Instead of only referring to the layer, it is used to select a cube map face | 
 | and a layer. | 
 | Setting <em>gl_Layer</em> to the value <em>layer*6+face</em> will render to face <em>face</em> of | 
 | the cube defined in layer <em>layer</em>. | 
 | The face values are defined in table 8.25 of the <a href="#references">OpenGL ES Specification</a>, | 
 | but repeated below for clarity.</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">Face Value</th> | 
 | <th class="tableblock halign-left valign-top">Resulting Target</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">TEXTURE_CUBE_MAP_POSITIVE_X</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">TEXTURE_CUBE_MAP_NEGATIVE_X</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">TEXTURE_CUBE_MAP_POSITIVE_Y</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">TEXTURE_CUBE_MAP_NEGATIVE_Y</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">TEXTURE_CUBE_MAP_POSITIVE_Z</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">TEXTURE_CUBE_MAP_NEGATIVE_Z</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>For example, to render to the positive <em>y</em> cube map face located in the 5th | 
 | layer of the cube map array, <em>gl_Layer</em> should be set to <em>5 * 6 + 2</em>.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="fragment-shader-special-variables">7.1.5. Fragment Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>The built-in special variables that are accessible from a fragment shader | 
 | are intrinsically declared as follows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">in highp vec4 gl_FragCoord; | 
 | in <span class="predefined-type">bool</span> gl_FrontFacing; | 
 | out highp <span class="predefined-type">float</span> gl_FragDepth; | 
 | in mediump vec2 gl_PointCoord; | 
 | in <span class="predefined-type">bool</span> gl_HelperInvocation; | 
 | in highp <span class="predefined-type">int</span> gl_PrimitiveID; | 
 | in highp <span class="predefined-type">int</span> gl_Layer; | 
 | in lowp <span class="predefined-type">int</span> gl_SampleID; | 
 | in mediump vec2 gl_SamplePosition; | 
 | in highp <span class="predefined-type">int</span> gl_SampleMaskIn[(gl_MaxSamples+<span class="integer">31</span>)/<span class="integer">32</span>]; | 
 | out highp <span class="predefined-type">int</span> gl_SampleMask[(gl_MaxSamples+<span class="integer">31</span>)/<span class="integer">32</span>];</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The output of the fragment shader executable is processed by the fixed | 
 | function operations at the back end of the OpenGL ES pipeline.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The fixed functionality computed depth for a fragment may be obtained by | 
 | reading <em>gl_FragCoord.z</em>, described below.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Writing to <em>gl_FragDepth</em> will establish the depth value for the fragment | 
 | being processed. | 
 | If depth buffering is enabled, and no shader writes <em>gl_FragDepth</em>, then the | 
 | fixed function value for depth will be used as the fragment’s depth value. | 
 | If a shader statically assigns a value to <em>gl_FragDepth</em>, and there is an | 
 | execution path through the shader that does not set <em>gl_FragDepth</em>, then the | 
 | value of the fragment’s depth may be undefined for executions of the shader | 
 | that take that path. | 
 | That is, if the set of linked fragment shaders statically contain a write to | 
 | <em>gl_FragDepth</em>, then it is responsible for always writing it.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a shader executes the <strong>discard</strong> keyword, the fragment is discarded, and | 
 | the values of any user-defined fragment outputs, <em>gl_FragDepth</em>, and | 
 | <em>gl_SampleMask</em> become irrelevant.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The variable <em>gl_FragCoord</em> is available as an input variable from within | 
 | fragment shaders and it holds the window relative coordinates (<em>x</em>, <em>y</em>, | 
 | <em>z</em>, <em>1/w</em>) values for the fragment. | 
 | If multi-sampling, this value can be for any location within the pixel, or | 
 | one of the fragment samples. | 
 | The use of <strong>centroid</strong> does not further restrict this value to be inside the | 
 | current primitive. | 
 | This value is the result of the fixed functionality that interpolates | 
 | primitives after vertex processing to generate fragments. | 
 | The <em>z</em> component is the depth value that would be used for the fragment’s | 
 | depth if no shader contained any writes to <em>gl_FragDepth</em>. | 
 | This is useful for invariance if a shader conditionally computes | 
 | <em>gl_FragDepth</em> but otherwise wants the fixed functionality fragment depth.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shaders have access to the input built-in variable | 
 | <em>gl_FrontFacing</em>, whose value is <strong>true</strong> if the fragment belongs to a | 
 | front-facing primitive. | 
 | One use of this is to emulate two-sided lighting by selecting one of two | 
 | colors calculated by a vertex or geometry shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The values in <em>gl_PointCoord</em> are two-dimensional coordinates indicating | 
 | where within a point primitive the current fragment is located, when point | 
 | sprites are enabled. | 
 | They range from 0.0 to 1.0 across the point. | 
 | If the current primitive is not a point, or if point sprites are not | 
 | enabled, then the values read from <em>gl_PointCoord</em> are undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For both the input array <em>gl_SampleMaskIn[]</em> and the output array | 
 | <em>gl_SampleMask[]</em>, bit <em>B</em> of mask <em>M</em> (<em>gl_SampleMaskIn[M]</em> or | 
 | <em>gl_SampleMask[M]</em>) corresponds to sample <em>32*M+B</em>. | 
 | These arrays have <strong>ceil</strong>(<em>s</em>/32) elements, where <em>s</em> is the maximum number | 
 | of color samples supported by the implementation.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The input variable <em>gl_SampleMaskIn</em> indicates the set of samples covered by | 
 | the primitive generating the fragment during multisample rasterization. | 
 | It has a sample bit set if and only if the sample is considered covered for | 
 | this fragment shader invocation.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The output array <em>gl_SampleMask[]</em> sets the sample mask for the fragment | 
 | being processed. | 
 | Coverage for the current fragment will become the logical AND of the | 
 | coverage mask and the output <em>gl_SampleMask</em>. | 
 | This array must be sized in the fragment shader either implicitly or | 
 | explicitly, to be no larger than the implementation-dependent maximum | 
 | sample-mask (as an array of 32bit elements), determined by the maximum | 
 | number of samples.. | 
 | If the fragment shader statically assigns a value to <em>gl_SampleMask</em>, the | 
 | sample mask will be undefined for any array elements of any fragment shader | 
 | invocations that fail to assign a value. | 
 | If a shader does not statically assign a value to <em>gl_SampleMask</em>, the | 
 | sample mask has no effect on the processing of a fragment.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The input variable <em>gl_SampleID</em> is filled with the sample number of the | 
 | sample currently being processed. | 
 | This variable is in the range <em>0</em> to <em>gl_NumSamples-1</em>, where | 
 | <em>gl_NumSamples</em> is the total number of samples in the framebuffer, or 1 if | 
 | rendering to a non-multisample framebuffer. | 
 | Any static use of this variable in a fragment shader causes the entire | 
 | shader to be evaluated per-sample.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The input variable <em>gl_SamplePosition</em> contains the position of the current | 
 | sample within the multisample draw buffer. | 
 | The <em>x</em> and <em>y</em> components of <em>gl_SamplePosition</em> contain the sub-pixel | 
 | coordinate of the current sample and will have values in the range 0.0 to | 
 | 1.0. | 
 | Any static use of this variable in a fragment shader causes the entire | 
 | shader to be evaluated per sample.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The value <em>gl_HelperInvocation</em> is <strong>true</strong> if the fragment shader invocation | 
 | is considered a <em>helper invocation</em> and is <strong>false</strong> otherwise. | 
 | A helper invocation is a fragment shader invocation that is created solely | 
 | for the purposes of evaluating derivatives for use in non-helper fragment | 
 | shader invocations. | 
 | Such derivatives are computed implicitly in the built-in function | 
 | <strong>texture</strong>() (see “<a href="#texture-functions">Texture Functions</a>”), and | 
 | explicitly in the derivative functions in | 
 | “<a href="#derivative-functions">Derivative Functions</a>”, for example <strong>dFdx</strong>() and | 
 | <strong>dFdy</strong>().</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Fragment shader helper invocations execute the same shader code as | 
 | non-helper invocations, but will not have side effects that modify the | 
 | framebuffer or other shader-accessible memory. | 
 | In particular:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>Fragments corresponding to helper invocations are discarded when shader | 
 | execution is complete, without updating the framebuffer.</p> | 
 | </li> | 
 | <li> | 
 | <p>Stores to image and buffer variables performed by helper invocations | 
 | have no effect on the underlying image or buffer memory.</p> | 
 | </li> | 
 | <li> | 
 | <p>Atomic operations to image, buffer, or atomic counter variables | 
 | performed by helper invocations have no effect on the underlying image | 
 | or buffer memory. | 
 | The values returned by such atomic operations are undefined.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Helper invocations may be generated for pixels not covered by a primitive | 
 | being rendered. | 
 | While fragment shader inputs qualified with <strong>centroid</strong> are normally required | 
 | to be sampled in the intersection of the pixel and the primitive, the | 
 | requirement is ignored for such pixels since there is no intersection | 
 | between the pixel and primitive.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Helper invocations may also be generated for fragments that are covered by a | 
 | primitive being rendered when the fragment is killed by early fragment tests | 
 | (using the <strong>early_fragment_tests</strong> qualifier) or where the implementation is | 
 | able to determine that executing the fragment shader would have no effect | 
 | other than assisting in computing derivatives for other fragment shader | 
 | invocations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The set of helper invocations generated when processing any set of | 
 | primitives is implementation-dependent.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The input variable <em>gl_PrimitiveID</em> is filled with the value written to the | 
 | <em>gl_PrimitiveID</em> geometry shader output, if a geometry shader is present. | 
 | Otherwise, it is filled with the number of primitives processed by the | 
 | shader since the current set of rendering primitives was started.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The input variable <em>gl_Layer</em> is filled with the value written to the | 
 | <em>gl_Layer</em> geometry shader output, if a geometry shader is present. | 
 | If the geometry stage does not dynamically assign a value to <em>gl_Layer</em>, the | 
 | value of <em>gl_Layer</em> in the fragment stage will be undefined. | 
 | If the geometry stage makes no static assignment to <em>gl_Layer</em>, the input | 
 | value in the fragment stage will be zero. | 
 | Otherwise, the fragment stage will read the same value written by the | 
 | geometry stage, even if that value is out of range. | 
 | If a fragment shader contains a static access to <em>gl_Layer</em>, it will count | 
 | against the implementation defined limit for the maximum number of inputs to | 
 | the fragment stage.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="compute-shader-special-variables">7.1.6. Compute Shader Special Variables</h4> | 
 | <div class="paragraph"> | 
 | <p>In the compute shader, built-in variables are declared as follows:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// workgroup dimensions</span> | 
 | in uvec3 gl_NumWorkGroups; | 
 | <span class="directive">const</span> uvec3 gl_WorkGroupSize; | 
 |  | 
 | <span class="comment">// workgroup and invocation IDs</span> | 
 | in uvec3 gl_WorkGroupID; | 
 | in uvec3 gl_LocalInvocationID; | 
 |  | 
 | <span class="comment">// derived variables</span> | 
 | in uvec3 gl_GlobalInvocationID; | 
 | in uint gl_LocalInvocationIndex;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in variable <em>gl_NumWorkGroups</em> is a compute-shader input variable | 
 | containing the number of workgroups in each dimension of the dispatch that | 
 | will execute the compute shader. | 
 | Its content is equal to the values specified in the <em>num_groups_x</em>, | 
 | <em>num_groups_y</em>, and <em>num_groups_z</em> parameters passed to the | 
 | <em>DispatchCompute</em> API entry point.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in constant <em>gl_WorkGroupSize</em> is a compute-shader constant | 
 | containing the workgroup size of the shader. | 
 | The size of the workgroup in the <em>X</em>, <em>Y</em>, and <em>Z</em> dimensions is stored in | 
 | the <em>x</em>, <em>y</em>, and <em>z</em> components. | 
 | The constants values in <em>gl_WorkGroupSize</em> will match those specified in the | 
 | required <strong>local_size_x</strong>, <strong>local_size_y</strong>, and <strong>local_size_z</strong> layout | 
 | qualifiers for the current shader. | 
 | This is a constant so that it can be used to size arrays of memory that can | 
 | be shared within the workgroup. | 
 | It is a compile-time error to use <em>gl_WorkGroupSize</em> in a shader that does | 
 | not declare a fixed workgroup size, or before that shader has declared a | 
 | fixed workgroup size, using <strong>local_size_x</strong>, <strong>local_size_y</strong>, and | 
 | <strong>local_size_z</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in variable <em>gl_WorkGroupID</em> is a compute-shader input variable | 
 | containing the three-dimensional index of the workgroup that the | 
 | current invocation is executing in. | 
 | The possible values range across the parameters passed into | 
 | <em>DispatchCompute</em>, i.e., from (0, 0, 0) to (<em>gl_NumWorkGroups.x</em> - 1, | 
 | <em>gl_NumWorkGroups.y</em> - 1, <em>gl_NumWorkGroups.z</em> -1).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in variable <em>gl_LocalInvocationID</em> is a compute-shader input | 
 | variable containing the three-dimensional index of the current work item | 
 | within the workgroup. | 
 | The possible values for this variable range across the workgroup | 
 | size, i.e., (0,0,0) to (<em>gl_WorkGroupSize.x</em> - 1, <em>gl_WorkGroupSize.y</em> - 1, | 
 | <em>gl_WorkGroupSize.z</em> - 1).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in variable <em>gl_GlobalInvocationID</em> is a compute shader input | 
 | variable containing the global index of the current work item. | 
 | This value uniquely identifies this invocation from all other invocations | 
 | across all workgroups initiated by the current <em>DispatchCompute</em> call. | 
 | This is computed as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">gl_GlobalInvocationID = | 
 |     gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in variable <em>gl_LocalInvocationIndex</em> is a compute shader input | 
 | variable that contains the one-dimensional representation of the | 
 | <em>gl_LocalInvocationID</em>. | 
 | This is computed as:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">gl_LocalInvocationIndex = | 
 |     gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y + | 
 |     gl_LocalInvocationID.y * gl_WorkGroupSize.x + | 
 |     gl_LocalInvocationID.x;</code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="built-in-constants">7.2. Built-In Constants</h3> | 
 | <div class="paragraph"> | 
 | <p>The following built-in constants are provided to all shaders. | 
 | The actual values used are implementation-dependent, but must be at least | 
 | the value shown.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">//</span> | 
 | <span class="comment">// Implementation-dependent constants. The example values below</span> | 
 | <span class="comment">// are the minimum values allowed for these maximums.</span> | 
 | <span class="comment">//</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexAttribs = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexUniformVectors = <span class="integer">256</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexOutputVectors = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexImageUniforms = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexAtomicCounters = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxVertexAtomicCounterBuffers = <span class="integer">0</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlInputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlOutputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlUniformComponents = <span class="integer">1024</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlTotalOutputComponents = <span class="integer">2048</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlImageUniforms = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlAtomicCounters = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessControlAtomicCounterBuffers = <span class="integer">0</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessPatchComponents = <span class="integer">120</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxPatchVertices = <span class="integer">32</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessGenLevel = <span class="integer">64</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationInputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationOutputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationUniformComponents = <span class="integer">1024</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationImageUniforms = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationAtomicCounters = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTessEvaluationAtomicCounterBuffers = <span class="integer">0</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryInputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryOutputComponents = <span class="integer">64</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryImageUniforms = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryOutputVertices = <span class="integer">256</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryTotalOutputComponents = <span class="integer">1024</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryUniformComponents = <span class="integer">1024</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryAtomicCounters = <span class="integer">0</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxGeometryAtomicCounterBuffers = <span class="integer">0</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxFragmentInputVectors = <span class="integer">15</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxFragmentImageUniforms = <span class="integer">4</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxFragmentUniformVectors = <span class="integer">256</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxFragmentAtomicCounters = <span class="integer">8</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxFragmentAtomicCounterBuffers = <span class="integer">1</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxDrawBuffers = <span class="integer">4</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MinProgramTexelOffset = -<span class="integer">8</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxProgramTexelOffset = <span class="integer">7</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxImageUnits = <span class="integer">4</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxSamples = <span class="integer">4</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxComputeImageUniforms = <span class="integer">4</span>; | 
 | <span class="directive">const</span> highp ivec3 gl_MaxComputeWorkGroupCount = ivec3(<span class="integer">65535</span>, <span class="integer">65535</span>, <span class="integer">65535</span>); | 
 | <span class="directive">const</span> highp ivec3 gl_MaxComputeWorkGroupSize = ivec3(<span class="integer">128</span>, <span class="integer">128</span>, <span class="integer">64</span>); | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxComputeUniformComponents = <span class="integer">1024</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxComputeTextureImageUnits = <span class="integer">16</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxComputeAtomicCounters = <span class="integer">8</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxComputeAtomicCounterBuffers = <span class="integer">1</span>; | 
 |  | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxCombinedTextureImageUnits = <span class="integer">96</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxCombinedImageUniforms = <span class="integer">4</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxCombinedShaderOutputResources = <span class="integer">4</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxCombinedAtomicCounters = <span class="integer">8</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxCombinedAtomicCounterBuffers = <span class="integer">1</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxAtomicCounterBindings = <span class="integer">1</span>; | 
 | <span class="directive">const</span> mediump <span class="predefined-type">int</span> gl_MaxAtomicCounterBufferSize = <span class="integer">32</span>;</code></pre> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="built-in-uniform-state">7.3. Built-In Uniform State</h3> | 
 | <div class="paragraph"> | 
 | <p>As an aid to accessing OpenGL ES processing state, the following uniform | 
 | variables are built into the OpenGL ES Shading Language.</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">//</span> | 
 | <span class="comment">// Depth range in window coordinates,</span> | 
 | <span class="comment">// section 12.5.1 "Controlling the Viewport" in the</span> | 
 | <span class="comment">// OpenGL ES Specification.</span> | 
 | <span class="comment">//</span> | 
 | <span class="keyword">struct</span> gl_DepthRangeParameters { | 
 |     highp <span class="predefined-type">float</span> near; <span class="comment">// n</span> | 
 |     highp <span class="predefined-type">float</span> far;  <span class="comment">// f</span> | 
 |     highp <span class="predefined-type">float</span> diff; <span class="comment">// f - n</span> | 
 | }; | 
 | uniform gl_DepthRangeParameters gl_DepthRange; | 
 | uniform lowp <span class="predefined-type">int</span> gl_NumSamples;</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These variables are only guaranteed to be available in the fragment stage. | 
 | In other stages, their presence and function is implementation-defined.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="redeclaring-built-in-blocks">7.4. Redeclaring Built-In Blocks</h3> | 
 | <div class="paragraph"> | 
 | <p>The <em>gl_PerVertex</em> block can be redeclared in a shader to explicitly | 
 | indicate what subset of the fixed pipeline interface will be used. | 
 | This is necessary to establish the interface between multiple programs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the <em>gl_PerVertex</em> block is not redefined in a given program, the | 
 | intrinsically declared definition of that block is used for the program | 
 | interface.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For example:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out gl_PerVertex { | 
 |     highp vec4 gl_Position; <span class="comment">// will use gl_Position</span> | 
 |     highp vec4 t;           <span class="comment">// error, only gl_PerVertex members allowed</span> | 
 | }; <span class="comment">// no other members of gl_PerVertex will be used</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>This establishes the output interface the shader will use with the | 
 | subsequent pipeline stage. | 
 | It must be a subset of the built-in members of <em>gl_PerVertex</em>. | 
 | Such a redeclaration can also add the <strong>invariant</strong> qualifier and | 
 | interpolation qualifiers.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Other layout qualifiers, like <strong>location</strong>, cannot be added to such a | 
 | redeclaration, unless specifically stated.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If a built-in interface block is redeclared, it must appear in the shader | 
 | before any use of any member included in the built-in declaration, or a | 
 | compile-time error will result. | 
 | It is also a compile-time error to redeclare the block more than once or to | 
 | redeclare a built-in block and then use a member from that built-in block | 
 | that was not included in the redeclaration. | 
 | Also, if a built-in interface block is redeclared, no member of the built-in | 
 | declaration can be redeclared outside the block redeclaration. | 
 | If multiple shaders using members of a built-in block belonging to the same | 
 | interface are linked together in the same program, they must all redeclare | 
 | the built-in block in the same way, as described in | 
 | “<a href="#interface-blocks">Interface Blocks</a>” for interface block matching, or a | 
 | link-time error will result. | 
 | It will also be a link-time error if some shaders in a program redeclare a | 
 | specific built-in interface block while another shader in that program does | 
 | not redeclare that interface block yet still uses a member of that interface | 
 | block. | 
 | If a built-in block interface is formed across shaders in different | 
 | programs, the shaders must all redeclare the built-in block in the same way | 
 | (as described for a single program), or the values passed along the | 
 | interface are undefined.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="built-in-functions">8. Built-In Functions</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>The OpenGL ES Shading Language defines an assortment of built-in convenience functions for | 
 | scalar and vector operations. | 
 | Many of these built-in functions can be used in more than one type of | 
 | shader, but some are intended to provide a direct mapping to hardware and so | 
 | are available only for a specific type of shader.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The built-in functions basically fall into three categories:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>They expose some necessary hardware functionality in a convenient way | 
 | such as accessing a texture map. | 
 | There is no way in the language for these functions to be emulated by a | 
 | shader.</p> | 
 | </li> | 
 | <li> | 
 | <p>They represent a trivial operation (clamp, mix, etc.) that is very | 
 | simple for the user to write, but they are very common and may have | 
 | direct hardware support. | 
 | It is a very hard problem for the compiler to map expressions to complex | 
 | assembler instructions.</p> | 
 | </li> | 
 | <li> | 
 | <p>They represent an operation graphics hardware is likely to accelerate at | 
 | some point. | 
 | The trigonometry functions fall into this category.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Many of the functions are similar to the same named ones in common C | 
 | libraries, but they support vector input as well as the more traditional | 
 | scalar input.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Applications should be encouraged to use the built-in functions rather than | 
 | do the equivalent computations in their own shader code since the built-in | 
 | functions are assumed to be optimal (e.g. perhaps supported directly in | 
 | hardware).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When the built-in functions are specified below, where the input arguments | 
 | (and corresponding output) can be <strong>float</strong>, <strong>vec2</strong>, <strong>vec3</strong>, or <strong>vec4</strong>, | 
 | <em>genFType</em> is used as the argument. | 
 | Where the input arguments (and corresponding output) can be <strong>int</strong>, <strong>ivec2</strong>, | 
 | <strong>ivec3</strong>, or <strong>ivec4</strong>, <em>genIType</em> is used as the argument. | 
 | Where the input arguments (and corresponding output) can be <strong>uint</strong>, <strong>uvec2</strong>, | 
 | <strong>uvec3</strong>, or <strong>uvec4</strong>, <em>genUType</em> is used as the argument. | 
 | Where the input arguments (or corresponding output) can be <strong>bool</strong>, <strong>bvec2</strong>, | 
 | <strong>bvec3</strong>, or <strong>bvec4</strong>, <em>genBType</em> is used as the argument. | 
 | For any specific use of a function, the actual types substituted for | 
 | <em>genFType</em>, <em>genIType</em>, <em>genUType</em>, or <em>genBType</em> have to have the same | 
 | number of components for all arguments and for the return type. | 
 | Similarly, <em>mat</em> is used for any matrix basic | 
 | type.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Built-in functions have an effective precision qualification. | 
 | This qualification cannot be set explicitly and may be different from the | 
 | precision qualification of the result.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision qualification of the operation of a built-in function is based | 
 | on the precision qualification of its formal parameters and actual | 
 | parameters (input arguments): When a formal parameter specifies a precision | 
 | qualifier, that is used, otherwise, the precision qualification of the | 
 | actual (calling) argument is used. | 
 | The highest precision of these will be the precision of the operation of the | 
 | built-in function. | 
 | Generally, this is applied across all arguments to a built-in function, with | 
 | the exceptions being:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p><strong>bitfieldExtract</strong> and <strong>bitfieldInsert</strong> ignore the <em>offset</em> and <em>bits</em> | 
 | arguments.</p> | 
 | </li> | 
 | <li> | 
 | <p><strong>interpolateAt</strong> functions only look at the <em>interpolant</em> argument.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision qualification of the result of a built-in function is | 
 | determined in one of the following ways:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For the texture sampling, image load and image store functions, the | 
 | precision of the return type matches the precision of the sampler type:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">uniform lowp sampler2D sampler; | 
 | highp vec2 coord; | 
 | ... | 
 | lowp vec4 col = texture (sampler, coord); <span class="comment">// texture() returns lowp</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Otherwise:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>For prototypes that do not specify a resulting precision qualifier, the | 
 | precision will be the same as the precision of the operation (as defined | 
 | earlier).</p> | 
 | </li> | 
 | <li> | 
 | <p>For prototypes that do specify a resulting precision qualifier, the | 
 | specified precision qualifier is the precision qualification of the | 
 | result.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Where the built-in functions in the following sections specify an equation, | 
 | the entire equation will be evaluated at the operation’s precision. | 
 | This may lead to underflow or overflow in the result, even when the correct | 
 | result could be represented in the operation precision.</p> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="angle-and-trigonometry-functions">8.1. Angle and Trigonometry Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Function parameters specified as <em>angle</em> are assumed to be in units of | 
 | radians. | 
 | In no case will any of these functions result in a divide by zero error. | 
 | If the divisor of a ratio is 0, then results will be undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These all operate component-wise. | 
 | The description is per component.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>radians</strong>(genFType <em>degrees</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Converts <em>degrees</em> to radians, i.e., | 
 |       <span class="eq">(π / 180) · degrees</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>degrees</strong>(genFType <em>radians</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Converts <em>radians</em> to degrees, i.e., | 
 |       <span class="eq">(180 / π) · radians</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>sin</strong>(genFType <em>angle</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The standard trigonometric sine function.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>cos</strong>(genFType <em>angle</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The standard trigonometric cosine function.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>tan</strong>(genFType <em>angle</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">The standard trigonometric tangent.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>asin</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc sine. | 
 |       Returns an angle whose sine is <em>x</em>. | 
 |       The range of values returned by this function is | 
 |       <span class="eq">[-π / 2, π / 2]</span>. | 
 |       Results are undefined if <span class="eq">|x| > 1</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>acos</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc cosine. | 
 |       Returns an angle whose cosine is <em>x</em>. | 
 |       The range of values returned by this function is <span class="eq">[0,π]</span>. | 
 |       Results are undefined if <span class="eq">|x| > 1</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>atan</strong>(genFType <em>y</em>, genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc tangent. | 
 |       Returns an angle whose tangent is <span class="eq">y / x</span>. | 
 |       The signs of <em>x</em> and <em>y</em> are used to determine what quadrant the angle | 
 |       is in. | 
 |       The range of values returned by this function is <span class="eq">[-π, π</span>. | 
 |       Results are undefined if <em>x</em> and <em>y</em> are both 0.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>atan</strong>(genFType <em>y_over_x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc tangent. | 
 |       Returns an angle whose tangent is <em>y_over_x</em>. | 
 |       The range of values returned by this function is | 
 |       <span class="eq">[-π / 2, π / 2]</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>sinh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the hyperbolic sine function <span class="eq">(e<sup>x</sup> - e<sup>-x</sup>) / 2</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>cosh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the hyperbolic cosine function <span class="eq">(e<sup>x</sup> + e<sup>-x</sup>) / 2</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>tanh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the hyperbolic tangent function <span class="eq">sinh(x) / cosh(x)</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>asinh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc hyperbolic sine; returns the inverse of <strong>sinh</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>acosh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc hyperbolic cosine; returns the non-negative inverse of <strong>cosh</strong>. | 
 |       Results are undefined if <span class="eq">x < 1</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>atanh</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Arc hyperbolic tangent; returns the inverse of <strong>tanh</strong>. | 
 |       Results are undefined if <span class="eq">x ≥ 1</span>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="exponential-functions">8.2. Exponential Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These all operate component-wise. | 
 | The description is per component.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>pow</strong>(genFType <em>x</em>, genFType <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <em>x</em> raised to the <em>y</em> power, i.e., <span class="eq">x<sup>y</sup></span>. | 
 |       Results are undefined if <span class="eq">x < 0</span>. | 
 |       Results are undefined if <span class="eq">x = 0</span> and <span class="eq">y ≤ 0</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>exp</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the natural exponentiation of <em>x</em>, i.e., <span class="eq">e<sup>x</sup></span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>log</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the natural logarithm of <em>x</em>, i.e., returns the value <em>y</em> | 
 |       which satisfies the equation <span class="eq">x = e<sup>y</sup></span>. | 
 |       Results are undefined if <span class="eq">x ≤ 0</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>exp2</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns 2 raised to the <em>x</em> power, i.e., <span class="eq">2<sup>x</sup></span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>log2</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the base 2 logarithm of <em>x</em>, i.e., returns the value <em>y</em> which | 
 |       satisfies the equation <span class="eq">x = 2<sup>y</sup></span>. | 
 |       Results are undefined if <span class="eq">x ≤ 0</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>sqrt</strong>(genFType <em>x</em>)<br> | 
 |   genDType <strong>sqrt</strong>(genDType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <span class="eq">sqrt(x)</span>. | 
 |       Results are undefined if <span class="eq">x < 0</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>inversesqrt</strong>(genFType <em>x</em>)<br> | 
 |   genDType <strong>inversesqrt</strong>(genDType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <span class="eq">1 / sqrt(x)</span>. | 
 |       Results are undefined if <span class="eq">x ≤ 0</span>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="common-functions">8.3. Common Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These all operate component-wise. | 
 | The description is per component.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>abs</strong>(genFType <em>x</em>)<br> | 
 |   genIType <strong>abs</strong>(genIType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <em>x</em> if <span class="eq">x ≥ 0</span>; otherwise it returns -<em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>sign</strong>(genFType <em>x</em>)<br> | 
 |   genIType <strong>sign</strong>(genIType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns 1.0 if <em>x</em> > 0, 0.0 if <em>x</em> = 0, or -1.0 if <em>x</em> < 0.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>floor</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a value equal to the nearest integer that is less than or | 
 |       equal to <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>trunc</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a value equal to the nearest integer to <em>x</em> whose absolute | 
 |       value is not larger than the absolute value of <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>round</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a value equal to the nearest integer to <em>x</em>. | 
 |       The fraction 0.5 will round in a direction chosen by the | 
 |       implementation, presumably the direction that is fastest. | 
 |       This includes the possibility that <strong>round</strong>(<em>x</em>) returns the same value | 
 |       as <strong>roundEven</strong>(<em>x</em>) for all values of <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>roundEven</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a value equal to the nearest integer to <em>x</em>. | 
 |       A fractional part of 0.5 will round toward the nearest even integer. | 
 |       (Both 3.5 and 4.5 for x will return 4.0.)</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>ceil</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a value equal to the nearest integer that is greater than or | 
 |       equal to <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>fract</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <em>x</em> - <strong>floor</strong>(<em>x</em>).</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>mod</strong>(genFType <em>x</em>, float <em>y</em>)<br> | 
 |   genFType <strong>mod</strong>(genFType <em>x</em>, genFType <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Modulus. | 
 |       Returns <span class="eq">x - y · <strong>floor</strong>(x / y)</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>modf</strong>(genFType <em>x</em>, out genFType <em>i</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the fractional part of <em>x</em> and sets <em>i</em> to the integer part (as | 
 |       a whole number floating-point value). | 
 |       Both the return value and the output parameter will have the same sign | 
 |       as <em>x</em>. | 
 |       If <em>x</em> has the value +/- Inf, the return value should be NaN and must | 
 |       be either NaN or 0.0. | 
 |       For <strong>highp</strong> non-constant expressions, the value returned must be | 
 |       consistent.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>min</strong>(genFType <em>x</em>, genFType <em>y</em>)<br> | 
 |   genFType <strong>min</strong>(genFType <em>x</em>, float <em>y</em>)<br> | 
 |   genIType <strong>min</strong>(genIType <em>x</em>, genIType <em>y</em>)<br> | 
 |   genIType <strong>min</strong>(genIType <em>x</em>, int <em>y</em>)<br> | 
 |   genUType <strong>min</strong>(genUType <em>x</em>, genUType <em>y</em>)<br> | 
 |   genUType <strong>min</strong>(genUType <em>x</em>, uint <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <em>y</em> if <em>y</em> < <em>x;</em> otherwise it returns <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>max</strong>(genFType <em>x</em>, genFType <em>y</em>)<br> | 
 |   genFType <strong>max</strong>(genFType <em>x</em>, float <em>y</em>)<br> | 
 |   genIType <strong>max</strong>(genIType <em>x</em>, genIType <em>y</em>)<br> | 
 |   genIType <strong>max</strong>(genIType <em>x</em>, int <em>y</em>)<br> | 
 |   genUType <strong>max</strong>(genUType <em>x</em>, genUType <em>y</em>)<br> | 
 |   genUType <strong>max</strong>(genUType <em>x</em>, uint <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <em>y</em> if <em>x</em> < <em>y;</em> otherwise it returns <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>clamp</strong>(genFType <em>x</em>, genFType <em>minVal</em>, genFType <em>maxVal</em>)<br> | 
 |   genFType <strong>clamp</strong>(genFType <em>x</em>, float <em>minVal</em>, float <em>maxVal</em>)<br> | 
 |   genIType <strong>clamp</strong>(genIType <em>x</em>, genIType <em>minVal</em>, genIType <em>maxVal</em>)<br> | 
 |   genIType <strong>clamp</strong>(genIType <em>x</em>, int <em>minVal</em>, int <em>maxVal</em>)<br> | 
 |   genUType <strong>clamp</strong>(genUType <em>x</em>, genUType <em>minVal</em>, genUType <em>maxVal</em>)<br> | 
 |   genUType <strong>clamp</strong>(genUType <em>x</em>, uint <em>minVal</em>, uint <em>maxVal</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <strong>min</strong>(<strong>max</strong>(<em>x</em>, <em>minVal</em>), <em>maxVal</em>). | 
 |       Results are undefined if <em>minVal</em> > <em>maxVal</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>mix</strong>(genFType <em>x</em>, genFType <em>y</em>, genFType <em>a</em>)<br> | 
 |   genFType <strong>mix</strong>(genFType <em>x</em>, genFType <em>y</em>, float <em>a</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the linear blend of <em>x</em> and <em>y</em>, i.e., | 
 |       <span class="eq">x · (1 - a) + y · a</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>mix</strong>(genFType <em>x</em>, genFType <em>y</em>,  genBType <em>a</em>)<br> | 
 |   genIType <strong>mix</strong>(genIType <em>x</em>, genIType <em>y</em>, genBType <em>a</em>)<br> | 
 |   genUType <strong>mix</strong>(genUType <em>x</em>, genUType <em>y</em>, genBType <em>a</em>)<br> | 
 |   genBType <strong>mix</strong>(genBType <em>x</em>, genBType <em>y</em>, genBType <em>a</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Selects which vector each returned component comes from. | 
 |       For a component of <em>a</em> that is <strong>false</strong>, the corresponding component of | 
 |       <em>x</em> is returned. | 
 |       For a component of <em>a</em> that is <strong>true</strong>, the corresponding component of | 
 |       <em>y</em> is returned. | 
 |       Components of <em>x</em> and <em>y</em> that are not selected are allowed to be | 
 |       invalid floating-point values and will have no effect on the results. | 
 |       Thus, this provides different functionality than, for example,<br> | 
 |       genFType <strong>mix</strong>(genFType <em>x</em>, genFType <em>y</em>, genFType(<em>a</em>))<br> | 
 |       where <em>a</em> is a Boolean vector.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>step</strong>(genFType <em>edge</em>, genFType <em>x</em>)<br> | 
 |   genFType <strong>step</strong>(float <em>edge</em>, genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns 0.0 if <em>x</em> < <em>edge;</em> otherwise it returns 1.0.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>smoothstep</strong>(genFType <em>edge0</em>, genFType <em>edge1</em>, genFType <em>x</em>)<br> | 
 |   genFType <strong>smoothstep</strong>(float <em>edge0</em>, float <em>edge1</em>, genFType <em>x</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Returns 0.0 if <span class="eq">x ≤ edge0</span> and 1.0 if <span class="eq">x ≥ edge1</span>, and | 
 |       performs smooth Hermite interpolation between 0 and 1 when <span class="eq">edge0 | 
 |       < x < edge1</span>. | 
 |       This is useful in cases where you would want a threshold function with | 
 |       a smooth transition. | 
 |       This is equivalent to:</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">genFType t; | 
 | t = clamp ((x - edge0) / (edge1 - edge0), <span class="integer">0</span>, <span class="integer">1</span>); | 
 | <span class="keyword">return</span> t * t * (<span class="integer">3</span> - <span class="integer">2</span> * t);</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>(And similarly for doubles.) Results are undefined if <span class="eq">edge0 ≥ | 
 | edge1</span>.</p> | 
 | </div> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genBType <strong>isnan</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <strong>true</strong> if <em>x</em> holds a NaN. | 
 |       Returns <strong>false</strong> otherwise. | 
 |       Always returns <strong>false</strong> if NaNs are not implemented.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genBType <strong>isinf</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <strong>true</strong> if <em>x</em> holds a positive infinity or negative infinity. | 
 |       Returns <strong>false</strong> otherwise.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genIType <strong>floatBitsToInt</strong>(highp genFType <em>value</em>)<br> | 
 |   genUType <strong>floatBitsToUint</strong>(highp genFType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a signed or unsigned integer value representing the encoding | 
 |       of a floating-point value. | 
 |       The <strong>float</strong> value’s bit-level representation is preserved.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>intBitsToFloat</strong>(highp genIType <em>value</em>)<br> | 
 |   genFType <strong>uintBitsToFloat</strong>(highp genUType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a floating-point value corresponding to a signed or unsigned | 
 |       integer encoding of a floating-point value. | 
 |       If an Inf or NaN is passed in, it will not signal, and the resulting | 
 |       floating-point value is unspecified. | 
 |       Otherwise, the bit-level representation is preserved.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>fma</strong>(genFType <em>a</em>, genFType <em>b</em>, genFType <em>c</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Computes and returns <span class="eq">a * b + c</span>. | 
 |       In uses where the return value is eventually consumed by a variable | 
 |       declared as <strong>precise</strong>:</p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p><strong>fma</strong>() is considered a single operation, whereas the expression “a * b | 
 | + c” consumed by a variable declared <strong>precise</strong> is considered two | 
 | operations.</p> | 
 | </li> | 
 | <li> | 
 | <p>The precision of <strong>fma</strong>() can differ from the precision of the expression | 
 | “a * b + c”.</p> | 
 | </li> | 
 | <li> | 
 | <p><strong>fma</strong>() will be computed with the same precision as any other <strong>fma</strong>() | 
 | consumed by a precise variable, giving invariant results for the same | 
 | input values of <em>a</em>, <em>b</em>, and <em>c</em>.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Otherwise, in the absence of <strong>precise</strong> consumption, there are no special | 
 | constraints on the number of operations or difference in precision between | 
 | <strong>fma</strong>() and the expression “_a_ * <em>b</em> + <em>c</em>”.</p> | 
 | </div> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>frexp</strong>(highp genFType <em>x</em>, out highp genIType <em>exp</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Splits <em>x</em> into a floating-point significand in the range | 
 |       <span class="eq">[0.5,1.0]</span>, and an integral exponent of two, such that</p> | 
 | <p class="tableblock">      <span class="eq">x = significant · 2<sup>exponent</sup></span></p> | 
 | <p class="tableblock">      The significand is returned by the function and the exponent is | 
 |       returned in the parameter <em>exp</em>. | 
 |       For a floating-point value of zero, the significand and exponent are | 
 |       both zero.</p> | 
 | <p class="tableblock">      If an implementation supports signed zero, an input value of minus | 
 |       zero should return a significand of minus zero. | 
 |       For a floating-point value that is an infinity or is not a number, the | 
 |       results are undefined.</p> | 
 | <p class="tableblock">      If the input <em>x</em> is a vector, this operation is performed in a | 
 |       component-wise manner; the value returned by the function and the | 
 |       value written to <em>exp</em> are vectors with the same number of components | 
 |       as <em>x</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>ldexp</strong>(highp genFType <em>x</em>, highp genIType <em>exp</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Builds a floating-point number from <em>x</em> and the corresponding integral | 
 |       exponent of two in <em>exp</em>, returning:</p> | 
 | <p class="tableblock">      <span class="eq">significand · 2<sup>exponent</sup></span></p> | 
 | <p class="tableblock">      If this product is too large to be represented in the floating-point | 
 |       type, the result is undefined.</p> | 
 | <p class="tableblock">      If <em>exp</em> is greater than +128, the value returned is undefined. | 
 |       If <em>exp</em> is less than -126, the value returned may be flushed to zero. | 
 |       Additionally, splitting the value into a significand and exponent | 
 |       using <strong>frexp</strong>() and then reconstructing a floating-point value using | 
 |       <strong>ldexp</strong>() should yield the original input for zero and all finite | 
 |       non-denormalized values.<br> | 
 |       If the input <em>x</em> is a vector, this operation is performed in a | 
 |       component-wise manner; the value passed in <em>exp</em> and returned by the | 
 |       function are vectors with the same number of components as <em>x</em>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="floating-point-pack-and-unpack-functions">8.4. Floating-Point Pack and Unpack Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These functions do not operate component-wise, rather, as described in each | 
 | case.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>packUnorm2x16</strong>(vec2 <em>v</em>)<br> | 
 |   highp uint <strong>packSnorm2x16</strong>(vec2 <em>v</em>)<br> | 
 |   highp uint <strong>packUnorm4x8</strong>(vec4 <em>v</em>)<br> | 
 |   highp uint <strong>packSnorm4x8</strong>(vec4 <em>v</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">First, converts each component of the normalized floating-point value | 
 |       <em>v</em> into 16-bit (<strong>2x16</strong>) or 8-bit (<strong>4x8</strong>) integer values. | 
 |       Then, the results are packed into the returned 32-bit unsigned | 
 |       integer.</p> | 
 | <p class="tableblock">      The conversion for component <em>c</em> of <em>v</em> to fixed point is done as | 
 |       follows:</p> | 
 | <p class="tableblock">      <strong>packUnorm2x16</strong>: <strong>round</strong>(<strong>clamp</strong>(<em>c</em>, 0, +1) * 65535.0)<br> | 
 |       <strong>packSnorm2x16:</strong> <strong>round</strong>(<strong>clamp</strong>(<em>c</em>, -1, +1) * 32767.0)<br> | 
 |       <strong>packUnorm4x8</strong>: <strong>round</strong>(<strong>clamp</strong>(<em>c</em>, 0, +1) * 255.0)<br> | 
 |       <strong>packSnorm4x8</strong>: <strong>round</strong>(<strong>clamp</strong>(<em>c</em>, -1, +1) * 127.0)</p> | 
 | <p class="tableblock">      The first component of the vector will be written to the least | 
 |       significant bits of the output; the last component will be written to | 
 |       the most significant bits.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp vec2 <strong>unpackUnorm2x16</strong>(highp uint <em>p</em>)<br> | 
 |   highp vec2 <strong>unpackSnorm2x16</strong>(highp uint <em>p</em>)<br> | 
 |   mediump vec4 <strong>unpackUnorm4x8</strong>(highp uint <em>p</em>)<br> | 
 |   mediump vec4 <strong>unpackSnorm4x8</strong>(highp uint <em>p</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">First, unpacks a single 32-bit unsigned integer <em>p</em> into a pair of | 
 |       16-bit unsigned integers, a pair of 16-bit signed integers, four 8-bit | 
 |       unsigned integers, or four 8-bit signed integers, respectively. | 
 |       Then, each component is converted to a normalized floating-point value | 
 |       to generate the returned two- or four-component vector.</p> | 
 | <p class="tableblock">      The conversion for unpacked fixed-point value <em>f</em> to floating-point is | 
 |       done as follows:</p> | 
 | <p class="tableblock">      <strong>unpackUnorm2x16</strong>: <em>f</em> / 65535.0<br> | 
 |       <strong>unpackSnorm2x16</strong>: <strong>clamp</strong>(<em>f</em> / 32767.0, -1, +1)<br> | 
 |       <strong>unpackUnorm4x8</strong>: <em>f</em> / 255.0<br> | 
 |       <strong>unpackSnorm4x8</strong>: <strong>clamp</strong>(<em>f</em> / 127.0, -1, +1)</p> | 
 | <p class="tableblock">      The first component of the returned vector will be extracted from the | 
 |       least significant bits of the input; the last component will be | 
 |       extracted from the most significant bits.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>packHalf2x16</strong>(vec2 <em>v</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns an unsigned integer obtained by converting the components of a | 
 |       two-component floating-point vector to the 16-bit floating-point | 
 |       representation found in the <a href="#references">OpenGL ES Specification</a>, and | 
 |       then packing these two 16-bit integers into a 32-bit unsigned integer.</p> | 
 | <p class="tableblock">      The first vector component specifies the 16 least-significant bits of | 
 |       the result; the second component specifies the 16 most-significant | 
 |       bits.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">mediump vec2 <strong>unpackHalf2x16</strong>(highp uint <em>v</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a two-component floating-point vector with components obtained | 
 |       by unpacking a 32-bit unsigned integer into a pair of 16-bit values, | 
 |       interpreting those values as 16-bit floating-point numbers according | 
 |       to the <a href="#references">OpenGL ES Specification</a>, and converting them to | 
 |       32-bit floating-point values.</p> | 
 | <p class="tableblock">      The first component of the vector is obtained from the 16 | 
 |       least-significant bits of <em>v</em>; the second component is obtained from | 
 |       the 16 most-significant bits of <em>v</em>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="geometric-functions">8.5. Geometric Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These operate on vectors as vectors, not component-wise.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>length</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Returns the length of vector <em>x</em>, i.e., | 
 |       <span class="eq">sqrt( x<sub>0</sub><sup>2</sup> + x<sub>1</sub><sup>2</sup> + …​ )</span>.</p> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>distance</strong>(genFType <em>p0</em>, genFType <em>p1</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the distance between <em>p0</em> and <em>p1</em>, i.e., | 
 |       <strong>length</strong>(<em>p0</em> - <em>p1</em>)</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>dot</strong>(genFType <em>x</em>, genFType <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the dot product of <em>x</em> and <em>y</em>, i.e., | 
 |       <span class="eq">x<sub>0</sub> · y<sub>0</sub> + x<sub>1</sub> · y<sub>1</sub> + …​</span></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">vec3 <strong>cross</strong>(vec3 <em>x</em>, vec3 <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Returns the cross product of <em>x</em> and <em>y</em>, i.e., | 
 |       <span class="eq">(x<sub>1</sub> · y<sub>2</sub> - y<sub>1</sub> · x<sub>2</sub>, | 
 |             x<sub>2</sub> · y<sub>0</sub> - y<sub>2</sub> · x<sub>0</sub>, | 
 |             x<sub>0</sub> · y<sub>1</sub> - y<sub>0</sub> · x<sub>1</sub>)</span>.</p> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>normalize</strong>(genFType <em>x</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a vector in the same direction as <em>x</em> but with a length of 1, | 
 |       i.e. <em>x</em> / <strong>length</strong>(x).</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>faceforward</strong>(genFType <em>N</em>, genFType <em>I</em>, genFType <em>Nref</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">If <strong>dot</strong>(<em>Nref</em>, <em>I</em>) < 0 return <em>N</em>, otherwise return -<em>N</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>reflect</strong>(genFType <em>I</em>, genFType <em>N</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">For the incident vector <em>I</em> and surface orientation <em>N</em>, returns the | 
 |       reflection direction: <span class="eq">I - 2 · <strong>dot</strong>(N, I) · N</span>. | 
 |       <em>N</em> must already be normalized in order to achieve the desired result.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>refract</strong>(genFType <em>I</em>, genFType <em>N</em>, float <em>eta</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>For the incident vector <em>I</em> and surface normal <em>N</em>, and the ratio of | 
 |       indices of refraction <em>eta</em>, return the refraction vector. | 
 |       The result is computed by the <a href="#refraction-equation">refraction | 
 |       equation</a> shown below.</p> | 
 | </div> | 
 | <div class="literalblock"> | 
 | <div class="content"> | 
 | <pre>The input parameters for the incident vector _I_ and the surface | 
 | normal _N_ must already be normalized to get the desired results.</pre> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="sect3"> | 
 | <h4 id="refraction-equation">8.5.1. Refraction Equation</h4> | 
 | <div class="stemblock"> | 
 | <div class="content"> | 
 | \[k = 1.0 - eta * eta * (1.0 - \textbf{dot}(N,I) \cdot \textbf{dot}(N,I))\] | 
 | </div> | 
 | </div> | 
 | <div class="stemblock"> | 
 | <div class="content"> | 
 | \[\begin{aligned} | 
 | result &= | 
 |   \begin{cases} | 
 |     genFType(0.0), & k < 0.0 \\ | 
 |     eta * I - (eta * \textbf{dot}(N,I) + \sqrt { k }) * N, & \textbf{otherwise} | 
 |   \end{cases} | 
 | \end{aligned}\] | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="matrix-functions">8.6. Matrix Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>For each of the following built-in matrix functions, there is both a | 
 | single-precision floating-point version, where all arguments and return | 
 | values are single precision, and a double-precision floating-point version, | 
 | where all arguments and return values are double precision. | 
 | Only the single-precision floating-point version is shown.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">mat <strong>matrixCompMult</strong>(mat <em>x</em>, mat <em>y</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Multiply matrix <em>x</em> by matrix <em>y</em> component-wise, i.e., result[i][j] | 
 |       is the scalar product of <em>x</em>[i][j] and <em>y</em>[i][j].<br></p> | 
 | <p class="tableblock">      Note: to get linear algebraic matrix multiplication, use the multiply | 
 |       operator (<strong>*</strong>).</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">mat2 <strong>outerProduct</strong>(vec2 <em>c</em>, vec2 <em>r</em>)<br> | 
 |   mat3 <strong>outerProduct</strong>(vec3 <em>c</em>, vec3 <em>r</em>)<br> | 
 |   mat4 <strong>outerProduct</strong>(vec4 <em>c</em>, vec4 <em>r</em>)<br> | 
 |   mat2x3 <strong>outerProduct</strong>(vec3 <em>c</em>, vec2 <em>r</em>)<br> | 
 |   mat3x2 <strong>outerProduct</strong>(vec2 <em>c</em>, vec3 <em>r</em>)<br> | 
 |   mat2x4 <strong>outerProduct</strong>(vec4 <em>c</em>, vec2 <em>r</em>)<br> | 
 |   mat4x2 <strong>outerProduct</strong>(vec2 <em>c</em>, vec4 <em>r</em>)<br> | 
 |   mat3x4 <strong>outerProduct</strong>(vec4 <em>c</em>, vec3 <em>r</em>)<br> | 
 |   mat4x3 <strong>outerProduct</strong>(vec3 <em>c</em>, vec4 <em>r</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Treats the first parameter <em>c</em> as a column vector (matrix with one | 
 |       column) and the second parameter <em>r</em> as a row vector (matrix with one | 
 |       row) and does a linear algebraic matrix multiply <em>c</em> * <em>r</em>, yielding a | 
 |       matrix whose number of rows is the number of components in <em>c</em> and | 
 |       whose number of columns is the number of components in <em>r</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">mat2 <strong>transpose</strong>(mat2 <em>m</em>)<br> | 
 |   mat3 <strong>transpose</strong>(mat3 <em>m</em>)<br> | 
 |   mat4 <strong>transpose</strong>(mat4 <em>m</em>)<br> | 
 |   mat2x3 <strong>transpose</strong>(mat3x2 <em>m</em>)<br> | 
 |   mat3x2 <strong>transpose</strong>(mat2x3 <em>m</em>)<br> | 
 |   mat2x4 <strong>transpose</strong>(mat4x2 <em>m</em>)<br> | 
 |   mat4x2 <strong>transpose</strong>(mat2x4 <em>m</em>)<br> | 
 |   mat3x4 <strong>transpose</strong>(mat4x3 <em>m</em>)<br> | 
 |   mat4x3 <strong>transpose</strong>(mat3x4 <em>m</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a matrix that is the transpose of <em>m</em>. | 
 |       The input matrix <em>m</em> is not modified.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>determinant</strong>(mat2 <em>m</em>)<br> | 
 |   float <strong>determinant</strong>(mat3 <em>m</em>)<br> | 
 |   float <strong>determinant</strong>(mat4 <em>m</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the determinant of <em>m</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">mat2 <strong>inverse</strong>(mat2 <em>m</em>)<br> | 
 |   mat3 <strong>inverse</strong>(mat3 <em>m</em>)<br> | 
 |   mat4 <strong>inverse</strong>(mat4 <em>m</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns a matrix that is the inverse of <em>m</em>. | 
 |       The input matrix <em>m</em> is not modified. | 
 |       The values in the returned matrix are undefined if <em>m</em> is singular or | 
 |       poorly-conditioned (nearly singular).</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="vector-relational-functions">8.7. Vector Relational Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Relational and equality operators (<strong><</strong>, <strong><=</strong>, <strong>></strong>, <strong>>=</strong>, <strong>==</strong>, <strong>!=</strong>) are | 
 | defined to operate on scalars and produce scalar Boolean results. | 
 | For vector results, use the following built-in functions. | 
 | Below, the following placeholders are used for the listed specific types:</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">Placeholder</th> | 
 | <th class="tableblock halign-left valign-top">Specific Types Allowed</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec2, bvec3, bvec4</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">ivec</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">ivec2, ivec3, ivec4</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uvec</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uvec2, uvec3, uvec4</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">vec</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">vec2, vec3, vec4</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>In all cases, the sizes of all the input and return vectors for any | 
 | particular call must match.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>lessThan</strong>(vec x, vec y)<br> | 
 |   bvec <strong>lessThan</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>lessThan</strong>(uvec x, uvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x < y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>lessThanEqual</strong>(vec x, vec y)<br> | 
 |   bvec <strong>lessThanEqual</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>lessThanEqual</strong>(uvec x, uvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x ≤ y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>greaterThan</strong>(vec x, vec y)<br> | 
 |   bvec <strong>greaterThan</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>greaterThan</strong>(uvec x, uvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x > y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>greaterThanEqual</strong>(vec x, vec y)<br> | 
 |   bvec <strong>greaterThanEqual</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>greaterThanEqual</strong>(uvec x, uvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x ≥ y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>equal</strong>(vec x, vec y)<br> | 
 |   bvec <strong>equal</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>equal</strong>(uvec x, uvec y)<br> | 
 |   bvec <strong>equal</strong>(bvec x, bvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x == y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>notEqual</strong>(vec x, vec y)<br> | 
 |   bvec <strong>notEqual</strong>(ivec x, ivec y)<br> | 
 |   bvec <strong>notEqual</strong>(uvec x, uvec y)<br> | 
 |   bvec <strong>notEqual</strong>(bvec x, bvec y)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise compare of <span class="eq">x ≠ y</span>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bool <strong>any</strong>(bvec x)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <strong>true</strong> if any component of <em>x</em> is <strong>true</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bool <strong>all</strong>(bvec x)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns <strong>true</strong> only if all components of <em>x</em> are <strong>true</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">bvec <strong>not</strong>(bvec x)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the component-wise logical complement of <em>x</em>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="integer-functions">8.8. Integer Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These all operate component-wise. | 
 | The description is per component. | 
 | The notation [<em>a</em>, <em>b</em>] means the set of bits from bit-number <em>a</em> through | 
 | bit-number <em>b</em>, inclusive. | 
 | The lowest-order bit is bit 0. | 
 | “Bit number” will always refer to counting up from the lowest-order bit as | 
 | bit 0.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genUType <strong>uaddCarry</strong>(highp genUType <em>x</em>, highp genUType <em>y</em>, out lowp genUType <em>carry</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Adds 32-bit unsigned integers <em>x</em> and <em>y</em>, returning the sum modulo | 
 |       2<sup>32</sup>. | 
 |       The value <em>carry</em> is set to zero if the sum was less than 2<sup>32</sup>, or | 
 |       one otherwise.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genUType <strong>usubBorrow</strong>(highp genUType <em>x</em>, highp genUType <em>y</em>, out lowp genUType <em>borrow</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Subtracts the 32-bit unsigned integer <em>y</em> from <em>x</em>, returning the | 
 |       difference if non-negative, or 2<sup>32</sup> plus the difference otherwise. | 
 |       The value <em>borrow</em> is set to zero if <span class="eq">x ≥ y</span>, or one | 
 |       otherwise.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>umulExtended</strong>(highp genUType <em>x</em>, highp genUType <em>y</em>, out highp genUType <em>msb</em>, out highp genUType <em>lsb</em>)<br> | 
 |   void <strong>imulExtended</strong>(highp genIType <em>x</em>, highp genIType <em>y</em>, out highp genIType <em>msb</em>, out highp genIType <em>lsb</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Multiplies 32-bit unsigned or signed integers <em>x</em> and <em>y</em>, producing a | 
 |       64-bit result. | 
 |       The 32 least-significant bits are returned in <em>lsb</em>. | 
 |       The 32 most-significant bits are returned in <em>msb</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genIType <strong>bitfieldExtract</strong>(genIType <em>value</em>, int <em>offset</em>, int <em>bits</em>)<br> | 
 |   genUType <strong>bitfieldExtract</strong>(genUType <em>value</em>, int <em>offset</em>, int <em>bits</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Extracts bits <span class="eq">[offset, offset + bits - 1]</span> from <em>value</em>, | 
 |       returning them in the least significant bits of the result.<br></p> | 
 | <p class="tableblock">      For unsigned data types, the most significant bits of the result will | 
 |       be set to zero. | 
 |       For signed data types, the most significant bits will be set to the | 
 |       value of bit <span class="eq">offset + bits - 1</span>.<br></p> | 
 | <p class="tableblock">      If <em>bits</em> is zero, the result will be zero. | 
 |       The result will be undefined if <em>offset</em> or <em>bits</em> is negative, or if | 
 |       the sum of <em>offset</em> and <em>bits</em> is greater than the number of bits used | 
 |       to store the operand. | 
 |       Note that for vector versions of <strong>bitfieldExtract</strong>(), a single pair of | 
 |       <em>offset</em> and <em>bits</em> values is shared for all components.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genIType <strong>bitfieldInsert</strong>(genIType <em>base</em>, genIType <em>insert</em>, int <em>offset</em>, int <em>bits</em>)<br> | 
 |   genUType <strong>bitfieldInsert</strong>(genUType <em>base</em>, genUType <em>insert</em>, int <em>offset</em>, int <em>bits</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Inserts the <em>bits</em> least significant bits of <em>insert</em> into <em>base</em>.</p> | 
 | <p class="tableblock">      The result will have bits <span class="eq">[offset, offset + bits - 1]</span> taken from | 
 |       bits <span class="eq">[0, bits - 1]</span> of <em>insert</em>, and all other bits taken | 
 |       directly from the corresponding bits of <em>base</em>. | 
 |       If <em>bits</em> is zero, the result will simply be <em>base</em>. | 
 |       The result will be undefined if <em>offset</em> or <em>bits</em> is negative, or if | 
 |       the sum of <em>offset</em> and <em>bits</em> is greater than the number of bits used | 
 |       to store the operand.<br> | 
 |       Note that for vector versions of <strong>bitfieldInsert</strong>(), a single pair of | 
 |       <em>offset</em> and <em>bits</em> values is shared for all components.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genIType <strong>bitfieldReverse</strong>(highp genIType <em>value</em>)<br> | 
 |   genUType <strong>bitfieldReverse</strong>(highp genUType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Reverses the bits of <em>value</em>. | 
 |       The bit numbered <em>n</em> of the result will be taken from bit <span class="eq">(bits - | 
 |       1) - n</span> of <em>value</em>, where <em>bits</em> is the total number of bits used to | 
 |       represent <em>value</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">lowp genIType <strong>bitCount</strong>(genIType <em>value</em>)<br> | 
 |   lowp genIType <strong>bitCount</strong>(genUType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the number of one bits in the binary representation of | 
 |       <em>value</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">lowp genIType <strong>findLSB</strong>(genIType <em>value</em>)<br> | 
 |   lowp genIType <strong>findLSB</strong>(genUType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the bit number of the least significant one bit in the binary | 
 |       representation of <em>value</em>. | 
 |       If <em>value</em> is zero, -1 will be returned.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">lowp genIType <strong>findMSB</strong>(highp genIType <em>value</em>)<br> | 
 |   lowp genIType <strong>findMSB</strong>(highp genUType <em>value</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the bit number of the most significant bit in the binary | 
 |       representation of <em>value</em>.</p> | 
 | <p class="tableblock">      For positive integers, the result will be the bit number of the most | 
 |       significant one bit. | 
 |       For negative integers, the result will be the bit number of the most | 
 |       significant zero bit. | 
 |       For a <em>value</em> of zero or negative one, -1 will be returned.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="texture-functions">8.9. Texture Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Texture lookup functions are available in all shading stages. | 
 | However, level-of-detail is implicitly computed only for fragment shaders. | 
 | Other shaders operate as though the base level-of-detail were computed as | 
 | zero. | 
 | The functions in the table below provide access to textures through | 
 | samplers, as set up through the OpenGL ES API. | 
 | Texture properties such as size, pixel format, number of dimensions, | 
 | filtering method, number of mipmap levels, depth comparison, and so on are | 
 | also defined by OpenGL ES API calls. | 
 | Such properties are taken into account as the texture is accessed via the | 
 | built-in functions defined below.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Texture data can be stored by the GL as single-precision floating-point, | 
 | unsigned normalized integer, unsigned integer or signed integer data. | 
 | This is determined by the type of the internal format of the texture.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Texture lookup functions are provided that can return their result as | 
 | floating-point, unsigned integer or signed integer, depending on the sampler | 
 | type passed to the lookup function. | 
 | Care must be taken to use the right sampler type for texture access. | 
 | The following table lists the supported combinations of sampler types and | 
 | texture internal formats. | 
 | Blank entries are unsupported. | 
 | Doing a texture lookup will return undefined values for unsupported | 
 | combinations.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For depth/stencil textures, the internal texture format is determined by the | 
 | component being accessed as set through the OpenGL ES API. | 
 | When the depth/stencil texture mode is set to DEPTH_COMPONENT, the internal | 
 | format of the depth component should be used. | 
 | When the depth/stencil texture mode is set to STENCIL_INDEX, the internal format | 
 | of the stencil component should be used.</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">Internal Texture Format</th> | 
 | <th class="tableblock halign-left valign-top">Floating-Point Sampler Types</th> | 
 | <th class="tableblock halign-left valign-top">Signed Integer Sampler Types</th> | 
 | <th class="tableblock halign-left valign-top">Unsigned Integer Sampler Types</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Floating-point</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Supported</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Normalized Integer</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Supported</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Signed Integer</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Supported</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Unsigned Integer</p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Supported</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>If an integer sampler type is used, the result of a texture lookup is an | 
 | <strong>ivec4</strong>. | 
 | If an unsigned integer sampler type is used, the result of a texture lookup | 
 | is a <strong>uvec4</strong>. | 
 | If a floating-point sampler type is used, the result of a texture lookup is | 
 | a <strong>vec4</strong>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In the prototypes below, the “_g_” in the return type “_gvec4_” is used | 
 | as a placeholder for nothing, “_i_”, or “_u_” making a return type of | 
 | <strong>vec4</strong>, <strong>ivec4</strong>, or <strong>uvec4</strong>. | 
 | In these cases, the sampler argument type also starts with “_g_”, | 
 | indicating the same substitution done on the return type; it is either a | 
 | floating-point, signed integer, or unsigned integer sampler, matching the | 
 | basic type of the return type, as described above.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For shadow forms (the sampler parameter is a shadow-type), a depth | 
 | comparison lookup on the depth texture bound to <em>sampler</em> is done as | 
 | described in section | 
 | 8.20 | 
 | “Texture Comparison Modes” of the | 
 | <a href="#references">OpenGL ES Specification</a>. | 
 | See the table below for which component specifies <em>D<sub>ref</sub></em>. | 
 | The texture bound to <em>sampler</em> must be a depth texture, or results are | 
 | undefined. | 
 | If a non-shadow texture call is made to a sampler that represents a depth | 
 | texture with depth comparisons turned on, then results are undefined. | 
 | If a shadow texture call is made to a sampler that represents a depth | 
 | texture with depth comparisons turned off, then results are undefined. | 
 | If a shadow texture call is made to a sampler that does not represent a | 
 | depth texture, then results are undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In all functions below, the <em>bias</em> parameter is optional for fragment | 
 | shaders. | 
 | The <em>bias</em> parameter is not accepted in any other shader stage. | 
 | For a fragment shader, if <em>bias</em> is present, it is added to the implicit | 
 | level-of-detail prior to performing the texture access operation. | 
 | No <em>bias</em> or <em>lod</em> parameters for | 
 | multisample textures, or texture buffers | 
 | are supported because mipmaps are not allowed for these types of textures.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The implicit level-of-detail is selected as follows: For a texture that is | 
 | not mipmapped, the texture is used directly. | 
 | If it is mipmapped and running in a fragment shader, the level-of-detail | 
 | computed by the implementation is used to do the texture lookup. | 
 | If it is mipmapped and running in a non-fragment shader, then the base | 
 | texture is used.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Some texture functions (non-“<strong>Lod</strong>” and non-“<strong>Grad</strong>” versions) may | 
 | require implicit derivatives. | 
 | Implicit derivatives are undefined within non-uniform control flow and for | 
 | non-fragment shader texture fetches.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For <strong>Cube</strong> forms, the direction of <em>P</em> is used to select which face to do a | 
 | 2-dimensional texture lookup in, as described in section 8.13 “Cube Map | 
 | Texture Selection” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For <strong>Array</strong> forms, the array layer used will be</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(\max(0,\min(d-1,\left\lfloor layer + 0.5\right\rfloor))\)</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where <em>d</em> is the depth of the texture array and <em>layer</em> comes from the | 
 | component indicated in the tables below.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="texture-query-functions">8.9.1. Texture Query Functions</h4> | 
 | <div class="paragraph"> | 
 | <p>The <strong>textureSize</strong> functions query the dimensions of a specific texture level | 
 | for a sampler.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp ivec2 <strong>textureSize</strong>(gsampler2D <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec3 <strong>textureSize</strong>(gsampler3D <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec2 <strong>textureSize</strong>(gsamplerCube <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec2 <strong>textureSize</strong>(sampler2DShadow <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec2 <strong>textureSize</strong>(samplerCubeShadow <em>sampler</em>, int <em>lod</em>) | 
 |   highp ivec3 <strong>textureSize</strong>(gsamplerCubeArray <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec3 <strong>textureSize</strong>(samplerCubeArrayShadow <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec3 <strong>textureSize</strong>(gsampler2DArray <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp ivec3 <strong>textureSize</strong>(sampler2DArrayShadow <em>sampler</em>, int <em>lod</em>)<br> | 
 |   highp int <strong>textureSize</strong>(gsamplerBuffer <em>sampler</em>)<br> | 
 |   highp ivec2 <strong>textureSize</strong>(gsampler2DMS <em>sampler</em>)<br> | 
 |   highp ivec3 <strong>textureSize</strong>(gsampler2DMSArray <em>sampler</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the dimensions of level <em>lod</em> (if present) for the texture | 
 |       bound to <em>sampler</em>, as described in section | 
 |       8.11 “Texture Queries” of the <a href="#references">OpenGL ES Specification</a>.<br> | 
 |       The components in the return value are filled in, in order, with the | 
 |       width, height, and depth of the texture.</p> | 
 | <p class="tableblock">      For the array forms, the last component of the return value is the | 
 |       number of layers in the texture array, or the number of cubes in the | 
 |       texture cube map array.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="texel-lookup-functions">8.9.2. Texel Lookup Functions</h4> | 
 | <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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>texture</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>texture</strong>(gsampler3D <em>sampler</em>, vec3 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>texture</strong>(gsamplerCube <em>sampler</em>, vec3 <em>P</em>[, float <em>bias</em>] )<br> | 
 |   float <strong>texture</strong>(sampler2DShadow <em>sampler</em>, <em>vec3 _P</em> [, float <em>bias</em>])<br> | 
 |   float <strong>texture</strong>(samplerCubeShadow <em>sampler</em>, <em>vec4 _P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>texture</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>texture</strong>(gsamplerCubeArray <em>sampler</em>, vec4 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   float <strong>texture</strong>(sampler2DArrayShadow <em>sampler</em>, vec4 <em>P</em>)<br> | 
 |   float <strong>texture</strong>(samplerCubeArrayShadow <em>sampler</em>, vec4 <em>P</em>, float <em>compare</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Use the texture coordinate <em>P</em> to do a texture lookup in the texture | 
 |       currently bound to <em>sampler</em>.</p> | 
 | <p class="tableblock">      For shadow forms: When <em>compare</em> is present, it is used as <em>D<sub>ref</sub></em> | 
 |       and the array layer comes from the last component of <em>P</em>. | 
 |       When <em>compare</em> is not present, the last component of <em>P</em> is used as | 
 |       <em>D<sub>ref</sub></em> and the array layer comes from the second to last component | 
 |       of <em>P</em>.</p> | 
 | <p class="tableblock">      For non-shadow forms: the array layer comes from the last component of | 
 |       <em>P</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProj</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureProj</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureProj</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em> [, float <em>bias</em>] )<br> | 
 |   float <strong>textureProj</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em> [, float <em>bias</em>] )<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a texture lookup with projection. | 
 |       The texture coordinates consumed from <em>P</em>, not including the last | 
 |       component of <em>P</em>, are divided by the last component of <em>P</em> to | 
 |       form projected coordinates <em>P'</em>. | 
 |       The resulting third component of <em>P</em> in the shadow forms is used as | 
 |       <em>D<sub>ref</sub></em>. | 
 |       The third component of <em>P</em> is ignored when <em>sampler</em> has type | 
 |       <strong>gsampler2D</strong> and <em>P</em> has type <strong>vec4</strong>. | 
 |       After these values are computed, texture lookup proceeds as in | 
 |       <strong>texture</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureLod</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureLod</strong>(gsampler3D <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureLod</strong>(gsamplerCube <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>)<br> | 
 |   float <strong>textureLod</strong>(sampler2DShadow <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureLod</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureLod</strong>(gsamplerCubeArray <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Do a texture lookup as in <strong>texture</strong> but with explicit level-of-detail; | 
 |       <em>lod</em> specifies <span class="eq">λ<sub>base</sub>]</span> and sets the partial derivatives | 
 |       as follows:<br> | 
 |       (See section 8.14 “Texture Minification” and equations 8.4-8.6 of | 
 |       the <a href="#references">OpenGL ES Specification</a>.)<br> | 
 |      <br> | 
 |       <span class="eq">∂u / ∂x = | 
 |            ∂v / ∂x = | 
 |            ∂w / ∂x = 0</span> | 
 |      <br> | 
 |       <span class="eq">∂u / ∂y = | 
 |            ∂v / ∂y = | 
 |            ∂w / ∂y = 0</span></p> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureOffset</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureOffset</strong>(gsampler3D <em>sampler</em>, vec3 <em>P</em>, ivec3 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   float <strong>textureOffset</strong>(sampler2DShadow <em>sampler</em>, vec3 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureOffset</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a texture lookup as in <strong>texture</strong> but with <em>offset</em> added to the | 
 |       <span class="eq">(u,v,w)</span> texel coordinates before looking up each texel. | 
 |       The offset value must be a constant expression. | 
 |       A limited range of offset values are supported; the minimum and | 
 |       maximum offset values are implementation-dependent and given by | 
 |       <em>gl_MinProgramTexelOffset</em> and <em>gl_MaxProgramTexelOffset</em>, | 
 |       respectively.</p> | 
 | <p class="tableblock">      Note that <em>offset</em> does not apply to the layer coordinate for texture | 
 |       arrays. | 
 |       This is explained in detail in section 8.14.2 “Coordinate Wrapping | 
 |       and Texel Selection” of the <a href="#references">OpenGL ES Specification</a>, where <em>offset</em> | 
 |       is <span class="eq">(δ<sub>u</sub>, δ<sub>v</sub>, δ<sub>w</sub>)</span>.<br> | 
 |       Note that texel offsets are also not supported for cube maps.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>texelFetch</strong>(gsampler2D <em>sampler</em>, ivec2 <em>P</em>, int <em>lod</em>)<br> | 
 |   gvec4 <strong>texelFetch</strong>(gsampler3D <em>sampler</em>, ivec3 <em>P</em>, int <em>lod</em>) | 
 |   gvec4 <strong>texelFetch</strong>(gsampler2DArray <em>sampler</em>, ivec3 <em>P</em>, int <em>lod</em>)<br> | 
 |   gvec4 <strong>texelFetch</strong>(gsamplerBuffer <em>sampler</em>, int <em>P</em>)<br> | 
 |   gvec4 <strong>texelFetch</strong>(gsampler2DMS <em>sampler</em>, ivec2 <em>P</em>, int <em>sample</em>)<br> | 
 |   gvec4 <strong>texelFetch</strong>(gsampler2DMSArray <em>sampler</em>, ivec3 <em>P</em>, int <em>sample</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Use integer texture coordinate <em>P</em> to lookup a single texel from | 
 |       <em>sampler</em>. | 
 |       The array layer comes from the last component of <em>P</em> for the array | 
 |       forms. | 
 |       The level-of-detail <em>lod</em> (if present) is as described in sections | 
 |       11.1.3.2 “Texel Fetches” and 8.14.1 “Scale Factor and Level of | 
 |       Detail” of the <a href="#references">OpenGL ES Specification</a>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>texelFetchOffset</strong>(gsampler2D <em>sampler</em>, ivec2 <em>P</em>, int <em>lod</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>texelFetchOffset</strong>(gsampler3D <em>sampler</em>, ivec3 <em>P</em>, int <em>lod</em>, ivec3 <em>offset</em>)<br> | 
 |   gvec4 <strong>texelFetchOffset</strong>(gsampler2DArray <em>sampler</em>, ivec3 <em>P</em>, int <em>lod</em>, ivec2 <em>offset</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Fetch a single texel as in <strong>texelFetch</strong>, offset by <em>offset</em> as | 
 |       described in <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProjOffset</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureProjOffset</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   gvec4 <strong>textureProjOffset</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em>, ivec3 <em>offset</em> [, float <em>bias</em>] )<br> | 
 |   float <strong>textureProjOffset</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em>, ivec2 <em>offset</em> [, float <em>bias</em>] )</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a projective texture lookup as described in <strong>textureProj</strong>, offset | 
 |       by <em>offset</em> as described in <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureLodOffset</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureLodOffset</strong>(gsampler3D <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>, ivec3 <em>offset</em>)<br> | 
 |   float <strong>textureLodOffset</strong>(sampler2DShadow <em>sampler</em>,  <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureLodOffset</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do an offset texture lookup with explicit level-of-detail. | 
 |       See <strong>textureLod</strong> and <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProjLod</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureProjLod</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>)<br> | 
 |   gvec4 <strong>textureProjLod</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>)<br> | 
 |   float <strong>textureProjLod</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a projective texture lookup with explicit level-of-detail. | 
 |       See <strong>textureProj</strong> and <strong>textureLod</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProjLodOffset</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureProjLodOffset</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureProjLodOffset</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>, ivec3 <em>offset</em>)<br> | 
 |   float <strong>textureProjLodOffset</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em>, float <em>lod</em>, ivec2 <em>offset</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do an offset projective texture lookup with explicit level-of-detail. | 
 |       See <strong>textureProj</strong>, <strong>textureLod</strong>, and <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureGrad</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)<br> | 
 |   gvec4 <strong>textureGrad</strong>(gsampler3D <em>sampler</em>,  <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>)<br> | 
 |   gvec4 <strong>textureGrad</strong>(gsamplerCube <em>sampler</em>, vec3 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>)<br> | 
 |   float <strong>textureGrad</strong>(sampler2DShadow <em>sampler</em>, vec3 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)<br> | 
 |   float <strong>textureGrad</strong>(samplerCubeShadow <em>sampler</em>, vec4 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>)<br> | 
 |   float <strong>textureGrad</strong>(sampler2DArrayShadow <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)<br> | 
 |   gvec4 <strong>textureGrad</strong>(gsamplerCubeArray <em>sampler</em>, vec4 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Do a texture lookup as in <strong>texture</strong> but with <a href="#explicit-gradients">explicit gradients</a> as shown below. | 
 |       The partial derivatives of <em>P</em> are with respect to window <em>x</em> and | 
 |       window <em>y</em>. | 
 |       For the cube version, the partial derivatives of <em>P</em> are assumed to be | 
 |       in the coordinate system used before texture coordinates are projected | 
 |       onto the appropriate cube face.</p> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureGradOffset</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureGradOffset</strong>(gsampler3D <em>sampler</em>, vec3 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>, ivec3 <em>offset</em>)<br> | 
 |   float <strong>textureGradOffset</strong>(sampler2DShadow <em>sampler</em>, vec3 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureGradOffset</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br> | 
 |   float <strong>textureGradOffset</strong>(sampler2DArrayShadow <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a texture lookup with both explicit gradient and offset, as | 
 |       described in <strong>textureGrad</strong> and <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProjGrad</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)<br> | 
 |   gvec4 <strong>textureProjGrad</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)<br> | 
 |   gvec4 <strong>textureProjGrad</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>)<br> | 
 |   float <strong>textureProjGrad</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a texture lookup both projectively, as described in <strong>textureProj</strong>, | 
 |       and with explicit gradient as described in <strong>textureGrad</strong>. | 
 |       The partial derivatives <em>dPdx</em> and <em>dPdy</em> are assumed to be already | 
 |       projected.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureProjGradOffset</strong>(gsampler2D <em>sampler</em>, vec3 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureProjGradOffset</strong>(gsampler2D <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)<br> | 
 |   gvec4 <strong>textureProjGradOffset</strong>(gsampler3D <em>sampler</em>, vec4 <em>P</em>, vec3 <em>dPdx</em>, vec3 <em>dPdy</em>, ivec3 <em>offset</em>)<br> | 
 |   float <strong>textureProjGradOffset</strong>(sampler2DShadow <em>sampler</em>, vec4 <em>P</em>, vec2 <em>dPdx</em>, vec2 <em>dPdy</em>, ivec2 <em>offset</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Do a texture lookup projectively and with explicit gradient as | 
 |       described in <strong>textureProjGrad</strong>, as well as with offset, as described in | 
 |       <strong>textureOffset</strong>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="explicit-gradients">8.9.3. Explicit Gradients</h4> | 
 | <div class="paragraph"> | 
 | <p>In the <strong>textureGrad</strong> functions described above, explicit gradients control | 
 | texture lookups as follows:</p> | 
 | </div> | 
 | <div class="stemblock"> | 
 | <div class="content"> | 
 | \[\begin{aligned} | 
 |   \frac{\partial{s}}{\partial{x}} & = \frac{\partial{P.s}}{\partial{x}} \\[0.8em] | 
 |   \frac{\partial{s}}{\partial{y}} & = \frac{\partial{P.s}}{\partial{y}} \\[0.8em] | 
 |   \frac{\partial{t}}{\partial{x}} & = \frac{\partial{P.t}}{\partial{x}} \\[0.8em] | 
 |   \frac{\partial{t}}{\partial{y}} & = \frac{\partial{P.t}}{\partial{y}} \\[0.8em] | 
 |   \frac{\partial{r}}{\partial{x}} & = | 
 |     \begin{cases} | 
 |       0.0,                               & \text{for 2D} \\[0.8em] | 
 |       \frac{\partial{P.p}}{\partial{x}}, & \text{cube, other} | 
 |     \end{cases} \\[2.5em] | 
 |   \frac{\partial{r}}{\partial{y}} & = | 
 |     \begin{cases} | 
 |       0.0,                               & \text{for 2D} \\[0.8em] | 
 |       \frac{\partial{P.p}}{\partial{y}}, & \text{cube, other} | 
 |     \end{cases} | 
 | \end{aligned}\] | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="texture-gather-functions">8.9.4. Texture Gather Functions</h4> | 
 | <div class="paragraph"> | 
 | <p>The texture gather functions take components of a single floating-point | 
 | vector operand as a texture coordinate, determine a set of four texels to | 
 | sample from the base level-of-detail of the specified texture image, and | 
 | return one component from each texel in a four-component result vector.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When performing a texture gather operation, the minification and | 
 | magnification filters are ignored, and the rules for LINEAR filtering in the | 
 | <a href="#references">OpenGL ES Specification</a> are applied to the base level of the texture image | 
 | to identify the four texels <em>i<sub>0</sub> j<sub>1</sub></em>, <em>i<sub>1</sub> j<sub>1</sub></em>, <em>i<sub>1</sub> j<sub>0</sub></em>, and <em>i<sub>0</sub> | 
 | j<sub>0</sub></em>. | 
 | The texels are then converted to texture base colors (<em>R<sub>s</sub></em>, <em>G<sub>s</sub></em>, | 
 | <em>B<sub>s</sub></em>, <em>A<sub>s</sub></em>) according to table 15.1, followed by application of the | 
 | texture swizzle as described in section 15.2.1 “Texture Access” of the | 
 | <a href="#references">OpenGL ES Specification</a>. | 
 | A four-component vector is assembled by taking the selected component from | 
 | each of the post-swizzled texture source colors in the order (<em>i<sub>0</sub> j<sub>1</sub></em>, | 
 | <em>i<sub>1</sub> j<sub>1</sub></em>, <em>i<sub>1</sub> j<sub>0</sub></em>, <em>i<sub>0</sub> j<sub>0</sub></em>).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The selected component is identified by the optional <em>comp</em> argument, where | 
 | the values zero, one, two, and three identify the <em>R<sub>s</sub></em>, <em>G<sub>s</sub></em>, <em>B<sub>s</sub></em>, or | 
 | <em>A<sub>s</sub></em> component, respectively. | 
 | If <em>comp</em> is omitted, it is treated as identifying the <em>R<sub>s</sub></em> component.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Incomplete textures (see section 8.16 “Texture Completeness” of the | 
 | <a href="#references">OpenGL ES Specification</a>) return a texture source color of (0,0,0,1) for all | 
 | four source texels.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For texture gather functions using a shadow sampler type, each of the four | 
 | texel lookups perform a depth comparison against the depth reference value | 
 | passed in (<em>refZ</em>), and returns the result of that comparison in the | 
 | appropriate component of the result vector.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>As with other texture lookup functions, the results of a texture gather are | 
 | undefined for shadow samplers if the texture referenced is not a depth | 
 | texture or has depth comparisons disabled; or for non-shadow samplers if the | 
 | texture referenced is a depth texture with depth comparisons enabled.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <strong>textureGatherOffset</strong> built-in functions from the OpenGL ES Shading Language return a vector | 
 | derived from sampling four texels in the image array of level <em>level<sub>base</sub></em>. | 
 | For each of the four texel offsets specified by the <em>offsets</em> argument, the | 
 | rules for the LINEAR minification filter are applied to identify a 2 × | 
 | 2 texel footprint, from which the single texel T<sub>i0j0</sub> is selected. | 
 | A four-component vector is then assembled by taking a single component from | 
 | each of the four T<sub>i0j0</sub> texels in the same manner as for the | 
 | <strong>textureGather</strong> function.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureGather</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em> [, int <em>comp</em>])<br> | 
 |   gvec4 <strong>textureGather</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em> [, int <em>comp</em>])<br> | 
 |   gvec4 <strong>textureGather</strong>(gsamplerCube <em>sampler</em>, vec3 <em>P</em> [, int <em>comp</em>])<br> | 
 |   gvec4 <strong>textureGather</strong>(gsamplerCubeArray <em>sampler</em>, vec4 <em>P</em>[, int <em>comp</em>])<br> | 
 |   vec4 <strong>textureGather</strong>(sampler2DShadow <em>sampler</em>, vec2 <em>P</em>, float <em>refZ</em>)<br> | 
 |   vec4 <strong>textureGather</strong>(sampler2DArrayShadow <em>sampler</em>, vec3 <em>P</em>, float <em>refZ</em>)<br> | 
 |   vec4 <strong>textureGather</strong>(samplerCubeShadow <em>sampler</em>, vec3 <em>P</em>, float <em>refZ</em>)<br> | 
 |   vec4 <strong>textureGather</strong>(samplerCubeArrayShadow <em>sampler</em>, vec4 <em>P</em>, float <em>refZ</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Returns the value<br></p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">vec4(Sample_i0_j1(P, base).comp, | 
 |      Sample_i1_j1(P, base).comp, | 
 |      Sample_i1_j0(P, base).comp, | 
 |      Sample_i0_j0(P, base).comp)</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If specified, the value of <em>comp</em> must be a constant integer expression with | 
 | a value of 0, 1, 2, or 3, identifying the <em>x</em>, <em>y</em>, <em>z</em>, or <em>w</em> | 
 | post-swizzled component of the four-component vector lookup result for each | 
 | texel, respectively. | 
 | If <em>comp</em> is not specified, it is treated as 0, selecting the <em>x</em> component | 
 | of each texel to generate the result.</p> | 
 | </div> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureGatherOffset</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, ivec2 <em>offset</em>, [ int <em>comp</em>])<br> | 
 |   gvec4 <strong>textureGatherOffset</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, ivec2 <em>offset</em> [ int <em>comp</em>])<br> | 
 |   vec4 <strong>textureGatherOffset</strong>(sampler2DShadow <em>sampler</em>, vec2 <em>P</em>, float <em>refZ</em>, ivec2 <em>offset</em>)<br> | 
 |   vec4 <strong>textureGatherOffset</strong>(sampler2DArrayShadow <em>sampler</em>, vec3 <em>P</em>, float <em>refZ</em>, ivec2 <em>offset</em>)<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Perform a texture gather operation as in <strong>textureGather</strong> by <em>offset</em> | 
 |       as described in <strong>textureOffset</strong> except that the <em>offset</em> can be | 
 |       variable (non constant) and the implementation-dependent minimum and | 
 |       maximum offset values are given by MIN_PROGRAM_TEXTURE_GATHER_OFFSET | 
 |       and MAX_PROGRAM_TEXTURE_GATHER_OFFSET, respectively.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">gvec4 <strong>textureGatherOffsets</strong>(gsampler2D <em>sampler</em>, vec2 <em>P</em>, ivec2 <em>offsets</em>[4] [, int <em>comp</em>])<br> | 
 |   gvec4 <strong>textureGatherOffsets</strong>(gsampler2DArray <em>sampler</em>, vec3 <em>P</em>, ivec2 <em>offsets</em>[4]   [, int <em>comp</em>])<br> | 
 |   vec4 <strong>textureGatherOffsets</strong>(sampler2DShadow <em>sampler</em>, vec2 <em>P</em>, float <em>refZ</em>, ivec2 <em>offsets</em>[4])<br> | 
 |   vec4 <strong>textureGatherOffsets</strong>(sampler2DArrayShadow <em>sampler</em>, vec3 <em>P</em>, float <em>refZ</em>, ivec2 <em>offsets</em>[4])<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Operate identically to <strong>textureGatherOffset</strong> except that <em>offsets</em> is | 
 |       used to determine the location of the four texels to sample. | 
 |       Each of the four texels is obtained by applying the corresponding | 
 |       offset in <em>offsets</em> as a (<em>u</em>, <em>v</em>) coordinate offset to <em>P</em>, | 
 |       identifying the four-texel LINEAR footprint, and then selecting the | 
 |       texel <em>i<sub>0</sub> j<sub>0</sub></em> of that footprint. | 
 |       The specified values in <em>offsets</em> must be constant integral | 
 |       expressions.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="atomic-counter-functions">8.10. Atomic Counter Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>The atomic-counter operations in this section operate atomically with | 
 | respect to each other. | 
 | They are atomic for any single counter, meaning any of these operations on a | 
 | specific counter in one shader instantiation will be indivisible by any of | 
 | these operations on the same counter from another shader instantiation. | 
 | There is no guarantee that these operations are atomic with respect to other | 
 | forms of access to the counter or that they are serialized when applied to | 
 | separate counters. | 
 | Such cases would require additional use of fences, barriers, or other forms | 
 | of synchronization, if atomicity or serialization is desired.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The underlying counter is a 32-bit unsigned integer. | 
 | The result of operations will wrap to [0, 2<sup>32</sup>-1].</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicCounterIncrement</strong>(atomic_uint <em>c</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Atomically<br></p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>increments the counter for <em>c</em>, and</p> | 
 | </li> | 
 | <li> | 
 | <p>returns its value prior to the increment operation.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These two steps are done atomically with respect to the atomic counter | 
 | functions in this table.</p> | 
 | </div> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicCounterDecrement</strong>(atomic_uint <em>c</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> | 
 | <p>Atomically<br></p> | 
 | </div> | 
 | <div class="openblock"> | 
 | <div class="content"> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>decrements the counter for <em>c</em>, and</p> | 
 | </li> | 
 | <li> | 
 | <p>returns the value resulting from the decrement operation.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>These two steps are done atomically with respect to the atomic counter | 
 | functions in this table.</p> | 
 | </div> | 
 | </div> | 
 | </div></div></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicCounter</strong>(atomic_uint <em>c</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the counter value for <em>c</em>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="atomic-memory-functions">8.11. Atomic Memory Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Atomic memory functions perform atomic operations on an individual signed or | 
 | unsigned integer stored in buffer object or shared variable storage. | 
 | All of the atomic memory operations read a value from memory, compute a new | 
 | value using one of the operations described below, write the new value to | 
 | memory, and return the original value read. | 
 | The contents of the memory being updated by the atomic operation are | 
 | guaranteed not to be modified by any other assignment or atomic memory | 
 | function in any shader invocation between the time the original value is | 
 | read and the time the new value is written.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Atomic memory functions are supported only for a limited set of variables. | 
 | A shader will fail to compile if the value passed to the <em>mem</em> argument of | 
 | an atomic memory function does not correspond to a buffer or shared | 
 | variable. | 
 | It is acceptable to pass an element of an array or a single component of a | 
 | vector to the <em>mem</em> argument of an atomic memory function, as long as the | 
 | underlying array or vector is a buffer or shared variable.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All the built-in functions in this section accept arguments with | 
 | combinations of <strong>restrict</strong>, <strong>coherent</strong>, and <strong>volatile</strong> memory qualification, | 
 | despite not having them listed in the prototypes. | 
 | The atomic operation will operate as required by the calling argument’s | 
 | memory qualification, not by the built-in function’s formal parameter memory | 
 | qualification.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicAdd</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicAdd</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by adding the value of <em>data</em> to the contents | 
 |       <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicMin</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicMin</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by taking the minimum of the value of <em>data</em> and | 
 |       the contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicMax</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicMax</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by taking the maximum of the value of <em>data</em> and | 
 |       the contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicAnd</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicAnd</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise AND of the value of | 
 |       <em>data</em> and the contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicOr</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicOr</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise OR of the value of | 
 |       <em>data</em> and the contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicXor</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicXor</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise EXCLUSIVE OR of the | 
 |       value of <em>data</em> and the contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicExchange</strong>(inout uint <em>mem</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicExchange</strong>(inout int <em>mem</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by simply copying the value of <em>data</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">uint <strong>atomicCompSwap</strong>(inout uint <em>mem</em>, uint <em>compare</em>, uint <em>data</em>)<br> | 
 |   int <strong>atomicCompSwap</strong>(inout int <em>mem</em>, int <em>compare</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Compares the value of <em>compare</em> and the contents of <em>mem</em>. | 
 |       If the values are equal, the new value is given by <em>data</em>; otherwise, | 
 |       it is taken from the original contents of <em>mem</em>.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="image-functions">8.12. Image Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Variables using one of the image basic types may be used by the built-in | 
 | shader image memory functions defined in this section to read and write | 
 | individual texels of a texture. | 
 | Each image variable references an image unit, which has a texture image | 
 | attached.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When image memory functions below access memory, an individual texel in the | 
 | image is identified using an (<em>i</em>), (<em>i, j</em>), or (<em>i, j, k</em>) coordinate | 
 | corresponding to the values of <em>P</em>. | 
 | The coordinates | 
 | are used to select an individual texel in the manner described in section | 
 | 8.22 | 
 | “Texture Image Loads and Stores” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Loads and stores support float, integer, and unsigned integer types. | 
 | The data types below starting “_gimage_” serve as placeholders meaning | 
 | types starting either “<strong>image</strong>”, “<strong>iimage</strong>”, or “<strong>uimage</strong>” in the same | 
 | way as <em>gvec</em> or <em>gsampler</em> in earlier sections.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The <em>IMAGE_PARAMS</em> in the prototypes below is a placeholder representing | 
 | 18 | 
 | separate functions, each for a different type of image variable. | 
 | The <em>IMAGE_PARAMS</em> placeholder is replaced by one of the following parameter | 
 | lists:</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimage2D <em>image</em>, ivec2 <em>P</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimage3D <em>image</em>, ivec3 <em>P</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimageCube <em>image</em>, ivec3 <em>P</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimageBuffer <em>image</em>, int <em>P</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimage2DArray <em>image</em>, ivec3 <em>P</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"></dt> | 
 | <dd> | 
 | <p>gimageCubeArray <em>image</em>, ivec3 <em>P</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>where each of the lines represents one of three different image variable | 
 | types, and <em>image</em>, | 
 | <em>P</em> | 
 | specify the individual texel to operate on. | 
 | The method for identifying the individual texel operated on from <em>image</em>, | 
 | <em>P</em>, | 
 | and the method for reading and writing the texel are specified in section | 
 | 8.22 | 
 | “Texture Image Loads and Stores” of the <a href="#references">OpenGL ES Specification</a>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The atomic functions perform operations on individual texels or samples of | 
 | an image variable. | 
 | Atomic memory operations read a value from the selected texel, compute a new | 
 | value using one of the operations described below, write the new value to | 
 | the selected texel, and return the original value read. | 
 | The contents of the texel being updated by the atomic operation are | 
 | guaranteed not to be modified by any other image store or atomic function | 
 | between the time the original value is read and the time the new value is | 
 | written.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Atomic memory operations are supported on only a subset of all image | 
 | variable types; <em>image</em> must be either:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>a signed integer image variable (type starts “<strong>iimage</strong>”) and a format | 
 | qualifier of <strong>r32i</strong>, used with a <em>data</em> argument of type <strong>int</strong>, or</p> | 
 | </li> | 
 | <li> | 
 | <p>an unsigned integer image variable (type starts “<strong>uimage</strong>”) and a | 
 | format qualifier of <strong>r32ui</strong>, used with a <em>data</em> argument of type <strong>uint</strong>, | 
 | or</p> | 
 | </li> | 
 | <li> | 
 | <p>a float image variable (type starts “<strong>image</strong>”) and a format qualifier | 
 | of <strong>r32f</strong>, used with a <em>data</em> argument of type <strong>float</strong> | 
 | (<strong>imageAtomicExchange</strong> only).</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>All the built-in functions in this section accept arguments with | 
 | combinations of <strong>restrict</strong>, <strong>coherent</strong>, and <strong>volatile</strong> memory qualification, | 
 | despite not having them listed in the prototypes. | 
 | The image operation will operate as required by the calling argument’s | 
 | memory qualification, not by the built-in function’s formal parameter memory | 
 | qualification.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp ivec2 <strong>imageSize</strong>(readonly writeonly gimage2D <em>image</em>)<br> | 
 |   highp ivec3 <strong>imageSize</strong>(readonly writeonly gimage3D <em>image</em>)<br> | 
 |   highp ivec2 <strong>imageSize</strong>(readonly writeonly gimageCube <em>image</em>)<br> | 
 |   highp ivec3 <strong>imageSize</strong>(readonly writeonly gimageCubeArray <em>image</em>)<br> | 
 |   highp ivec3 <strong>imageSize</strong>(readonly writeonly gimage2DArray <em>image</em>)<br> | 
 |   highp   int <strong>imageSize</strong>(readonly writeonly gimageBuffer <em>image</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the dimensions of the image or images bound to <em>image</em>. | 
 |       For arrayed images, the last component of the return value will hold | 
 |       the size of the array. | 
 |       Cube images only return the dimensions of one face, and the number of | 
 |       cubes in the cube map array, if arrayed.<br> | 
 |       Note: The qualification <strong>readonly writeonly</strong> accepts a variable | 
 |       qualified with <strong>readonly</strong>, <strong>writeonly</strong>, both, or neither. | 
 |       It means the formal argument will be used for neither reading nor | 
 |       writing to the underlying memory.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp gvec4 <strong>imageLoad</strong>(readonly <em>IMAGE_PARAMS</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Loads the texel at the coordinate <em>P</em> from the image unit <em>image</em> (in | 
 |       <em>IMAGE_PARAMS</em>). | 
 |       When <em>image</em> and <em>P</em> | 
 |       identify a valid texel, the bits used to represent the selected texel in | 
 |       memory are converted to a <strong>vec4</strong>, <strong>ivec4</strong>, or <strong>uvec4</strong> in the manner | 
 |       described in section | 
 | 8.23 | 
 |       “Texture Image Loads and Stores” of the | 
 |       <a href="#references">OpenGL ES Specification</a> and returned.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>imageStore</strong>(writeonly <em>IMAGE_PARAMS</em>, gvec4 <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Stores <em>data</em> into the texel at the coordinate <em>P</em> from the image | 
 |       specified by <em>image</em>. | 
 |       When <em>image</em> and <em>P</em> | 
 |       identify a valid texel, the bits used to represent <em>data</em> are converted | 
 |       to the format of the image unit in the manner described in section | 
 | 8.23 | 
 |       “Texture Image Loads and Stores” of the <a href="#references">OpenGL ES Specification</a> | 
 |       and stored to the specified texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicAdd</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicAdd</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by adding the value of <em>data</em> to the contents of | 
 |       the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicMin</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicMin</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by taking the minimum of the value of <em>data</em> and | 
 |       the contents of the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicMax</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicMax</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by taking the maximum of the value <em>data</em> and the | 
 |       contents of the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicAnd</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicAnd</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise AND of the value of | 
 |       <em>data</em> and the contents of the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicOr</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicOr</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise OR of the value of | 
 |       <em>data</em> and the contents of the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicXor</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicXor</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by performing a bit-wise EXCLUSIVE OR of the | 
 |       value of <em>data</em> and the contents of the selected texel.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicExchange</strong>(<em>IMAGE_PARAMS</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicExchange</strong>(<em>IMAGE_PARAMS</em>, int <em>data</em>)<br> | 
 |   highp float <strong>imageAtomicExchange</strong>(<em>IMAGE_PARAMS</em>, float <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Computes a new value by simply copying the value of <em>data</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">highp uint <strong>imageAtomicCompSwap</strong>(<em>IMAGE_PARAMS</em>, uint <em>compare</em>, uint <em>data</em>)<br> | 
 |   highp int <strong>imageAtomicCompSwap</strong>(<em>IMAGE_PARAMS</em>, int <em>compare</em>, int <em>data</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Compares the value of <em>compare</em> and the contents of the selected | 
 |       texel. | 
 |       If the values are equal, the new value is given by <em>data</em>; otherwise, | 
 |       it is taken from the original value loaded from the texel.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="geometry-shader-functions">8.13. Geometry Shader Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>These functions are only available in geometry shaders. | 
 | They are described in more depth following the table.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>EmitVertex</strong>()<br></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Emits the current values of output variables to the current output | 
 |       primitive. | 
 |       On return from this call, the values of output variables are | 
 |       undefined.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>EndPrimitive</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Completes the current output primitive and starts a new one. | 
 |       No vertex is emitted.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The function <strong>EmitVertex</strong>() specifies that a vertex is completed. | 
 | A vertex is added to the current output primitive using the current values | 
 | of all built-in and user-defined output variables. | 
 | The values of all output variables are undefined after a call to | 
 | <strong>EmitVertex</strong>(). | 
 | If a geometry shader invocation has emitted more vertices than permitted by | 
 | the output layout qualifier <strong>max_vertices</strong>, the results of calling | 
 | <strong>EmitVertex</strong>() are undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The function <strong>EndPrimitive</strong>() specifies that the current output primitive is | 
 | completed and a new output primitive (of the same type) will be started by | 
 | any subsequent <strong>EmitVertex</strong>(). | 
 | This function does not emit a vertex. | 
 | If the output layout is declared to be <strong>points</strong>, calling <strong>EndPrimitive</strong>() is | 
 | optional.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A geometry shader starts with an output primitive containing no vertices. | 
 | When a geometry shader terminates, the current output primitive is | 
 | automatically completed. | 
 | It is not necessary to call <strong>EndPrimitive</strong>() if the geometry shader writes | 
 | only a single primitive.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="fragment-processing-functions">8.14. Fragment Processing Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Fragment processing functions are only available in fragment shaders.</p> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="derivative-functions">8.14.1. Derivative Functions</h4> | 
 | <div class="paragraph"> | 
 | <p>Derivatives may be computationally expensive and/or numerically unstable. | 
 | Therefore, an OpenGL ES implementation may approximate the true derivatives | 
 | by using a fast but not entirely accurate derivative computation. | 
 | Derivatives are undefined within non-uniform control flow.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The expected behavior of a derivative is specified using forward/backward | 
 | differencing.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Forward differencing:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(F(x+dx) - F(x) \sim dFdx(x) \cdot dx (1a)\)</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(dFdx(x) \sim \frac{F(x+dx) - F(x)}{dx} (1b)\)</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Backward differencing:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(F(x-dx) - F(x) \sim -dFdx(x) \cdot dx (2a)\)</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(dFdx(x) \sim \frac{F(x) - F(x-dx)}{dx} (2b)\)</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>With single-sample rasterization, \(dx \leq 1.0\) in equations 1b | 
 | and 2b. | 
 | For multisample rasterization, \(dx < 2.0\) in equations 1b and 2b.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>\(dFdy\) is approximated similarly, with <em>y</em> replacing <em>x</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>An OpenGL ES implementation may use the above or other methods to perform | 
 | the calculation, subject to the following conditions:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>The method may use piecewise linear approximations. | 
 | Such linear approximations imply that higher order derivatives, | 
 | <strong>dFdx</strong>(<strong>dFdx</strong>(<em>x</em>)) and above, are undefined.</p> | 
 | </li> | 
 | <li> | 
 | <p>The method may assume that the function evaluated is continuous. | 
 | Therefore derivatives within the body of a non-uniform conditional are | 
 | undefined.</p> | 
 | </li> | 
 | <li> | 
 | <p>The method may differ per fragment, subject to the constraint that the | 
 | method may vary by window coordinates, not screen coordinates. | 
 | The invariance requirement described in section 13.2 “Invariance” of | 
 | the <a href="#references">OpenGL ES Specification</a>, is relaxed for derivative calculations, | 
 | because the method may be a function of fragment location.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Other properties that are desirable, but not required, are:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>Functions should be evaluated within the interior of a primitive | 
 | (interpolated, not extrapolated).</p> | 
 | </li> | 
 | <li> | 
 | <p>Functions for <strong>dFdx</strong> should be evaluated while holding <em>y</em> constant. | 
 | Functions for <strong>dFdy</strong> should be evaluated while holding <em>x</em> constant. | 
 | However, mixed higher order derivatives, like <strong>dFdx</strong>(<strong>dFdy</strong>(<em>y</em>)) and | 
 | <strong>dFdy</strong>(<strong>dFdx</strong>(<em>x</em>)) are undefined.</p> | 
 | </li> | 
 | <li> | 
 | <p>Derivatives of constant arguments should be 0.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In some implementations, varying degrees of derivative accuracy may be | 
 | obtained by providing GL hints (see section 19.1 “Hints” of the | 
 | <a href="#references">OpenGL ES Specification</a>), allowing a user to make an image quality versus | 
 | speed trade off.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>dFdx</strong>(genFType <em>p</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the derivative in x using local differencing for the input | 
 |       argument <em>p</em>.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>dFdy</strong>(genFType <em>p</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the derivative in y using local differencing for the input | 
 |       argument <em>p</em>.<br> | 
 |       <br> | 
 |       These two functions are commonly used to estimate the filter width used | 
 |       to anti-alias procedural textures. We are assuming that the expression | 
 |       is being evaluated in parallel on a SIMD array so that at any given | 
 |       point in time the value of the function is known at the grid points | 
 |       represented by the SIMD array. Local differencing between SIMD array | 
 |       elements can therefore be used to derive <strong>dFdx</strong>, <strong>dFdy</strong>, etc.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">genFType <strong>fwidth</strong>(genFType <em>p</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the sum of the absolute derivative in x and y using local | 
 |       differencing for the input argument <em>p</em>, i.e., <strong>abs</strong>(<strong>dFdx</strong>(<em>p</em>)) | 
 |       + <strong>abs</strong>(<strong>dFdy</strong>(<em>p</em>));</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="interpolation-functions">8.14.2. Interpolation Functions</h4> | 
 | <div class="paragraph"> | 
 | <p>Built-in interpolation functions are available to compute an interpolated | 
 | value of a fragment shader input variable at a shader-specified (<em>x</em>, <em>y</em>) | 
 | location. | 
 | A separate (<em>x</em>, <em>y</em>) location may be used for each invocation of the | 
 | built-in function, and those locations may differ from the default (<em>x</em>, | 
 | <em>y</em>) location used to produce the default value of the input. | 
 | For the <strong>interpolateAt*</strong> functions, the call will return a precision | 
 | qualification matching the precision of the <em>interpolant</em> argument to the | 
 | function call.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For all of the interpolation functions, <em>interpolant</em> must be an l-value | 
 | from an <strong>in</strong> declaration; | 
 | this can be either a variable, or an array element. | 
 | Component selection operators (e.g. <strong>.xy</strong>) may not be used when specifying <em>interpolant</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If <em>interpolant</em> is declared with the <strong>flat</strong> qualifier, the interpolated | 
 | value will have the same value everywhere for a single primitive, so the | 
 | location used for interpolation has no effect and the functions just return | 
 | that same value. | 
 | If <em>interpolant</em> is declared with the <strong>centroid</strong> qualifier, the value | 
 | returned by <strong>interpolateAtSample</strong>() and <strong>interpolateAtOffset</strong>() will be | 
 | evaluated at the specified location, ignoring the location normally used | 
 | with the <strong>centroid</strong> qualifier.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>interpolateAtCentroid</strong>(float <em>interpolant</em>)<br> | 
 |   vec2 <strong>interpolateAtCentroid</strong>(vec2 <em>interpolant</em>)<br> | 
 |   vec3 <strong>interpolateAtCentroid</strong>(vec3 <em>interpolant</em>)<br> | 
 |   vec4 <strong>interpolateAtCentroid</strong>(vec4 <em>interpolant</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the value of the input <em>interpolant</em> sampled at a location | 
 |       inside both the pixel and the primitive being processed. | 
 |       The value obtained would be the same value assigned to the input | 
 |       variable if declared with the <strong>centroid</strong> qualifier.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>interpolateAtSample</strong>(float <em>interpolant</em>, int <em>sample</em>)<br> | 
 |   vec2 <strong>interpolateAtSample</strong>(vec2 <em>interpolant</em>, int <em>sample</em>)<br> | 
 |   vec3 <strong>interpolateAtSample</strong>(vec3 <em>interpolant</em>, int <em>sample</em>)<br> | 
 |   vec4 <strong>interpolateAtSample</strong>(vec4 <em>interpolant</em>, int <em>sample</em>)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the value of the input <em>interpolant</em> variable at the location | 
 |       of sample number <em>sample</em>. | 
 |       If multisample buffers are not available, the input variable will be | 
 |       evaluated at the center of the pixel. | 
 |       If sample <em>sample</em> does not exist, the position used to interpolate | 
 |       the input variable is undefined.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">float <strong>interpolateAtOffset</strong>(float <em>interpolant</em>, vec2 offset)<br> | 
 |   vec2 <strong>interpolateAtOffset</strong>(vec2 <em>interpolant</em>, vec2 offset)<br> | 
 |   vec3 <strong>interpolateAtOffset</strong>(vec3 <em>interpolant</em>, vec2 offset)<br> | 
 |   vec4 <strong>interpolateAtOffset</strong>(vec4 <em>interpolant</em>, vec2 offset)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Returns the value of the input <em>interpolant</em> variable sampled at an | 
 |       offset from the center of the pixel specified by <em>offset</em>. | 
 |       The two floating-point components of <em>offset</em>, give the offset in | 
 |       pixels in the <em>x</em> and <em>y</em> directions, respectively.<br> | 
 |       An offset of (0, 0) identifies the center of the pixel. | 
 |       The range and granularity of offsets supported by this function is | 
 |       implementation-dependent.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="shader-invocation-control-functions">8.15. Shader Invocation Control Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>The shader invocation control function is only available in tessellation | 
 | control and compute shaders. | 
 | It is used to control the relative execution order of multiple shader | 
 | invocations used to process a patch (in the case of tessellation control | 
 | shaders) or a workgroup (in the case of compute shaders), which are | 
 | otherwise executed with an undefined relative order.</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>barrier</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">For any given static instance of <strong>barrier</strong>(), all tessellation control | 
 |       shader invocations for a single input patch must enter it before any | 
 |       will be allowed to continue beyond it, or all compute shader | 
 |       invocations for a single workgroup must enter it before any will | 
 |       continue beyond it.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The function <strong>barrier</strong>() provides a partially defined order of execution | 
 | between shader invocations. | 
 | The ensures that, for some types of memory accesses, values written by one | 
 | invocation prior to a given static instance of <strong>barrier</strong>() can be safely read | 
 | by other invocations after their call to the same static instance <strong>barrier</strong>(). | 
 | Because invocations may execute in an undefined order between these barrier | 
 | calls, the values of a per-vertex or per-patch output variable for tessellation | 
 | control shaders, or the values of <strong>shared</strong> variables for compute shaders will be | 
 | undefined in a number of cases enumerated in | 
 | “<a href="#output-variables">Output Variables</a>” (for tessellation control shaders) | 
 | and “<a href="#shared-variables">Shared Variables</a>” (for compute shaders).</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For tessellation control shaders, the <strong>barrier</strong>() function may only be | 
 | placed inside the function <strong>main</strong>() of the shader and may not be called | 
 | within any control flow. | 
 | Barriers are also disallowed after a return statement in the function | 
 | <strong>main</strong>(). | 
 | Any such misplaced barriers result in a compile-time error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>A <strong>barrier</strong>() affects control flow but only synchronizes memory accesses | 
 | to <strong>shared</strong> variables and tessellation control output variables. | 
 | For other memory accesses, it does not ensure that values written by one invocation | 
 | prior to a given static instance of <strong>barrier</strong>() can be safely read by other | 
 | invocations after their call to the same static instance of <strong>barrier</strong>(). | 
 | To achieve this requires the use of both <strong>barrier</strong>() and a memory barrier.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For compute shaders, the <strong>barrier</strong>() function may be placed within control | 
 | flow, but that control flow must be uniform control flow. | 
 | That is, all the controlling expressions that lead to execution of the | 
 | barrier must be dynamically uniform expressions. | 
 | This ensures that if any shader invocation enters a conditional statement, | 
 | then all invocations will enter it. | 
 | While compilers are encouraged to give warnings if they can detect this | 
 | might not happen, compilers cannot completely determine this. | 
 | Hence, it is the author’s responsibility to ensure <strong>barrier</strong>() only exists | 
 | inside uniform control flow. | 
 | Otherwise, some shader invocations will stall indefinitely, waiting for a | 
 | barrier that is never reached by other invocations.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="shader-memory-control-functions">8.16. Shader Memory Control Functions</h3> | 
 | <div class="paragraph"> | 
 | <p>Within a single shader invocation, the visibility and order of writes made | 
 | by that invocation are well-defined. | 
 | However, the relative order of reads and writes to a single shared memory | 
 | address from multiple separate shader invocations is largely undefined. | 
 | Additionally, the order of accesses to multiple memory addresses performed | 
 | by a single shader invocation, as observed by other shader invocations, is | 
 | also undefined.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following built-in functions can be used to control the ordering of | 
 | reads and writes:</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">Syntax</th> | 
 | <th class="tableblock halign-left valign-top">Description</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>memoryBarrier</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of memory transactions issued by a single shader | 
 |       invocation.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>memoryBarrierAtomicCounter</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of accesses to atomic-counter variables issued by | 
 |       a single shader invocation.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>memoryBarrierBuffer</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of memory transactions to buffer variables issued | 
 |       within a single shader invocation.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>memoryBarrierShared</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of memory transactions to shared variables issued | 
 |       within a single shader invocation, as viewed by other invocations in | 
 |       the same workgroup.<br> | 
 |       Only available in compute shaders.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>memoryBarrierImage</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of memory transactions to images issued within a | 
 |       single shader invocation.</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">void <strong>groupMemoryBarrier</strong>()</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Control the ordering of all memory transactions issued within a single | 
 |       shader invocation, as viewed by other invocations in the same workgroup.<br> | 
 |       Only available in compute shaders.</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>The memory barrier built-in functions can be used to order reads and writes | 
 | to variables stored in memory accessible to other shader invocations. | 
 | When called, these functions will wait for the completion of all reads and | 
 | writes previously performed by the caller that access selected variable | 
 | types, and then return with no other effect. | 
 | The built-in functions <strong>memoryBarrierAtomicCounter</strong>(), | 
 | <strong>memoryBarrierBuffer</strong>(), <strong>memoryBarrierImage</strong>(), and <strong>memoryBarrierShared</strong>() | 
 | wait for the completion of accesses to atomic counter, buffer, image, and | 
 | shared variables, respectively. | 
 | The built-in functions <strong>memoryBarrier</strong>() and <strong>groupMemoryBarrier</strong>() wait for | 
 | the completion of accesses to all of the above variable types. | 
 | The functions <strong>memoryBarrierShared</strong>() and <strong>groupMemoryBarrier</strong>() are | 
 | available only in compute shaders; the other functions are available in all | 
 | shader types.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>When these functions return, the effects of any memory stores performed | 
 | using coherent variables prior to the call will be visible to any | 
 | future<sup>1</sup> coherent access to the same memory performed by any other shader | 
 | invocation. | 
 | In particular, the values written this way in one shader stage are | 
 | guaranteed to be visible to coherent memory accesses performed by shader | 
 | invocations in subsequent stages when those invocations were triggered by | 
 | the execution of the original shader invocation (e.g. fragment shader | 
 | invocations for a primitive resulting from a particular geometry | 
 | shader invocation).</p> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">1</dt> | 
 | <dd> | 
 | <p>An access is only a <em>future</em> access if a <em>happens-before</em> relation can | 
 | be established between the store and the load.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Additionally, memory barrier functions order stores performed by the calling | 
 | invocation, as observed by other shader invocations. | 
 | Without memory barriers, if one shader invocation performs two stores to | 
 | coherent variables, a second shader invocation might see the values written | 
 | by the second store prior to seeing those written by the first. | 
 | However, if the first shader invocation calls a memory barrier function | 
 | between the two stores, selected other shader invocations will never see the | 
 | results of the second store before seeing those of the first. | 
 | When using the functions <strong>groupMemoryBarrier</strong>() or <strong>memoryBarrierShared</strong>(), | 
 | this ordering guarantee applies only to other shader invocations in the same | 
 | compute shader workgroup; all other memory barrier functions provide the | 
 | guarantee to all other shader invocations. | 
 | No memory barrier is required to guarantee the order of memory stores as | 
 | observed by the invocation performing the stores; an invocation reading from | 
 | a variable that it previously wrote will always see the most recently | 
 | written value unless another shader invocation also wrote to the same | 
 | memory.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="shader-interface-matching">9. Shader Interface Matching</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>As described in chapter 7 of the <a href="#references">OpenGL ES Specification</a>, shaders may be | 
 | linked together to form a <em>program object</em> before being bound to the | 
 | pipeline or may be linked and bound individually as <em>separable program | 
 | objects</em>.</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>These were previously known as separate shader objects (SSOs) but the | 
 | mechanism has been extended to support future versions of the specification | 
 | that have more than two shader stages. | 
 | It allows a subset of the shaders to be linked together.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Within a <em>program object</em> or a <em>separable program object</em>, qualifiers for | 
 | matching variables must themselves match according to the rules specified in | 
 | this section. | 
 | There are also matching rules for qualifiers of matching variables between | 
 | separable program objects but only for variables across an input/output | 
 | boundary between shader stages. | 
 | For other shader interface variables such as uniforms, each program object | 
 | or separable program object has its own name space and so the same name can | 
 | refer to multiple independent variables. | 
 | Consequently, there are no matching rules for qualifiers in these cases.</p> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="input-output-matching-by-name-in-linked-programs">9.1. Input Output Matching by Name in Linked Programs</h3> | 
 | <div class="paragraph"> | 
 | <p>When linking shaders, the type of declared vertex outputs and fragment | 
 | inputs with the same name must match, otherwise the link command will fail. | 
 | Only those fragment inputs statically used (i.e. read) in the fragment | 
 | shader must be declared as outputs in the vertex shader; declaring | 
 | superfluous vertex shader outputs is permissible.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following table summarizes the rules for matching shader outputs to | 
 | shader inputs in consecutive stages when shaders are linked together.</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all fit-content"> | 
 | <colgroup> | 
 | <col> | 
 | <col> | 
 | <col> | 
 | <col> | 
 | <col> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" colspan="2" rowspan="2"><p class="tableblock">Treatment of Mismatched Input Variables</p></td> | 
 | <td class="tableblock halign-left valign-top" colspan="3"><p class="tableblock">Consuming Shader (input variables)</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No Declaration</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Declared but no Static Use</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Declared and Static Use</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" rowspan="3"><p class="tableblock">Generating Shader (output variables)</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No Declaration</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">error</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Declares; no static Use</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed (values are undefined)</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Declares and static Use</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Allowed (values are potentially undefined)</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>See “<a href="#static-use">Static Use</a>” for the definition of <em>static use</em>.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision of a vertex output does not need to match the precision of the | 
 | corresponding fragment input. | 
 | The minimum precision at which vertex outputs are interpolated is the | 
 | minimum of the vertex output precision and the fragment input precision, | 
 | with the exception that for <strong>highp</strong>, implementations do not have to support | 
 | full IEEE 754 precision.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The precision of values exported to a transform feedback buffer is the | 
 | precision of the outputs of the vertex shader. | 
 | However, they are converted to <strong>highp</strong> format before being written.</p> | 
 | </div> | 
 | </div> | 
 | <div class="sect2"> | 
 | <h3 id="matching-of-qualifiers">9.2. Matching of Qualifiers</h3> | 
 | <div class="paragraph"> | 
 | <p>The following tables summarize the requirements for matching of qualifiers. | 
 | It applies whenever there are two or more matching variables in a shader | 
 | interface.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Notes:</p> | 
 | </div> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p><em>Yes</em> means the qualifiers must match.</p> | 
 | </li> | 
 | <li> | 
 | <p><em>No</em> means the qualifiers do not need to match.</p> | 
 | </li> | 
 | <li> | 
 | <p><em>Consistent</em> means qualifiers may be missing from a subset of | 
 | declarations but they cannot conflict</p> | 
 | </li> | 
 | <li> | 
 | <p>If there are conflicting qualifiers, only the last of these is | 
 | significant.</p> | 
 | </li> | 
 | <li> | 
 | <p>Matching is based only on the resulting qualification, not on the | 
 | presence or otherwise of qualifiers.</p> | 
 | </li> | 
 | <li> | 
 | <p>The rules apply to all declared variables, irrespective of whether they | 
 | are statically used, with the exception of inputs and outputs when | 
 | shaders are linked (see | 
 | “<a href="#input-output-matching-by-name-in-linked-programs">Input Output | 
 | Matching by Name in Linked Programs</a>”).</p> | 
 | </li> | 
 | <li> | 
 | <p>Errors are generated for any conflicts.</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="linked-shaders">9.2.1. Linked Shaders</h4> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.6666%;"> | 
 | <col style="width: 16.667%;"> | 
 | </colgroup> | 
 | <thead> | 
 | <tr> | 
 | <th class="tableblock halign-left valign-top">Qualifier Class</th> | 
 | <th class="tableblock halign-left valign-top">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top"><strong>in</strong>/<strong>out</strong></th> | 
 | <th class="tableblock halign-left valign-top">Default Uniforms</th> | 
 | <th class="tableblock halign-left valign-top"><strong>uniform</strong> Block</th> | 
 | <th class="tableblock halign-left valign-top"><strong>buffer</strong> Block</th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Storage<sup>1</sup></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>in</strong><br> | 
 |                     <strong>out</strong><br> | 
 |                     <strong>uniform</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" rowspan="2"><p class="tableblock">Auxiliary</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>centroid</strong><br> | 
 |                     <strong>sample</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>patch</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" rowspan="5"><p class="tableblock">Layout</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>location</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes<sup>2</sup></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Consistent</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Block layout<sup>3,4</sup></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>binding</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Consistent</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>offset</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">format</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Interpolation</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>smooth</strong><br> | 
 |                     <strong>flat</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Precision</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lowp</strong><br> | 
 |                     <strong>mediump</strong><br> | 
 |                     <strong>highp</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Variance</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>invariant</strong><br> | 
 |                     <strong>precise</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Memory</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">all</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1">1</dt> | 
 | <dd> | 
 | <p>Storage qualifiers determine <em>when</em> variables match rather than being | 
 | <em>required</em> to match for matching variables. | 
 | Note also that each shader interface has a separate name space so for | 
 | example, it is possible to use the same name for a vertex output and | 
 | fragment uniform.</p> | 
 | </dd> | 
 | <dt class="hdlist1">2</dt> | 
 | <dd> | 
 | <p>If present, the <strong>location</strong> qualifier determines the matching of inputs | 
 | and outputs. | 
 | See section 7.4.1 “Shader interface Matching” of the | 
 | <a href="#references">OpenGL ES Specification</a> for details.]</p> | 
 | </dd> | 
 | <dt class="hdlist1">3</dt> | 
 | <dd> | 
 | <p>The <strong>row_major</strong> and <strong>column_major</strong> layout qualifiers do not need to | 
 | match when applied to non-matrix types.</p> | 
 | </dd> | 
 | <dt class="hdlist1">4</dt> | 
 | <dd> | 
 | <p>In cases where a layout qualifier overrides a previous layout qualifier | 
 | or a default, only the resulting qualification must match.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | <div class="sect3"> | 
 | <h4 id="separable-programs">9.2.2. Separable Programs</h4> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 33.3333%;"> | 
 | <col style="width: 33.3333%;"> | 
 | <col style="width: 33.3334%;"> | 
 | </colgroup> | 
 | <thead> | 
 | <tr> | 
 | <th class="tableblock halign-left valign-top">Qualifier Class</th> | 
 | <th class="tableblock halign-left valign-top">Qualifier</th> | 
 | <th class="tableblock halign-left valign-top"><strong>in</strong>/<strong>out</strong></th> | 
 | </tr> | 
 | </thead> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Storage</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>in</strong><br> | 
 |                     <strong>out</strong><br> | 
 |                     <strong>uniform</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" rowspan="2"><p class="tableblock">Auxiliary</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>centroid</strong><br> | 
 |                     <strong>sample</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>patch</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top" rowspan="5"><p class="tableblock">Layout</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>location</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Block layout</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>binding</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>offset</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">format</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Interpolation</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>smooth</strong><br> | 
 |                     <strong>flat</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Precision</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>lowp</strong><br> | 
 |                     <strong>mediump</strong><br> | 
 |                     <strong>highp</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Variance</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>invariant</strong><br> | 
 |                     <strong>precise</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">Memory</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">all</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="shading-language-grammar">10. Shading Language Grammar</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>The grammar is fed from the output of lexical analysis. | 
 | The tokens returned from lexical analysis are</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">CONST BOOL FLOAT INT UINT | 
 |  | 
 | BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 | 
 |  | 
 | MAT2 MAT3 MAT4 CENTROID IN OUT INOUT | 
 |  | 
 | UNIFORM PATCH SAMPLE BUFFER SHARED | 
 |  | 
 | COHERENT VOLATILE RESTRICT READONLY WRITEONLY | 
 |  | 
 | FLAT SMOOTH LAYOUT | 
 |  | 
 | MAT2X2 MAT2X3 MAT2X4 | 
 |  | 
 | MAT3X2 MAT3X3 MAT3X4 | 
 |  | 
 | MAT4X2 MAT4X3 MAT4X4 | 
 |  | 
 |  | 
 |  | 
 |  | 
 |  | 
 | ATOMIC_UINT | 
 |  | 
 | SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER2DSHADOW | 
 |  | 
 | SAMPLERCUBESHADOW SAMPLER2DARRAY SAMPLER2DARRAYSHADOW | 
 |  | 
 | ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY | 
 |  | 
 | USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY | 
 |  | 
 |  | 
 |  | 
 |  | 
 |  | 
 |  | 
 | SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER | 
 |  | 
 | SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW | 
 |  | 
 | ISAMPLERCUBEARRAY USAMPLERCUBEARRAY | 
 |  | 
 | SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS | 
 |  | 
 | SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY | 
 |  | 
 | IMAGE2D IIMAGE2D UIMAGE2D | 
 |  | 
 | IMAGE3D IIMAGE3D UIMAGE3D | 
 |  | 
 | IMAGECUBE IIMAGECUBE UIMAGECUBE | 
 |  | 
 | IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER | 
 |  | 
 | IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY | 
 |  | 
 | IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY | 
 |  | 
 |  | 
 |  | 
 |  | 
 |  | 
 |  | 
 | STRUCT VOID | 
 |  | 
 | WHILE BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT | 
 |  | 
 | IDENTIFIER TYPE_NAME | 
 |  | 
 | FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT | 
 |  | 
 | FIELD_SELECTION | 
 |  | 
 | LEFT_OP RIGHT_OP | 
 |  | 
 | INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP | 
 |  | 
 | AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN | 
 |  | 
 | MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN | 
 |  | 
 | SUB_ASSIGN | 
 |  | 
 | LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT | 
 |  | 
 | COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT | 
 |  | 
 | LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION | 
 |  | 
 | INVARIANT PRECISE | 
 |  | 
 | HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION</code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The following describes the grammar for the OpenGL ES Shading Language in terms of the above | 
 | tokens. | 
 | The starting rule is <em>translation_unit</em>.</p> | 
 | </div> | 
 | <div class="openblock bnf"> | 
 | <div class="content"> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>variable_identifier</em> : </dt> | 
 | <dd> | 
 | <p><em>IDENTIFIER</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>primary_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>variable_identifier</em><br> | 
 | <em>INTCONSTANT</em><br> | 
 | <em>UINTCONSTANT</em><br> | 
 | <em>FLOATCONSTANT</em><br> | 
 | <em>BOOLCONSTANT</em><br> | 
 | <em>LEFT_PAREN</em> <em>expression</em> <em>RIGHT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>postfix_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>primary_expression</em><br> | 
 | <em>postfix_expression</em> <em>LEFT_BRACKET</em> <em>integer_expression</em> <em>RIGHT_BRACKET</em><br> | 
 | <em>function_call</em><br> | 
 | <em>postfix_expression</em> <em>DOT</em> <em>FIELD_SELECTION</em><br> | 
 | <em>postfix_expression</em> <em>INC_OP</em><br> | 
 | <em>postfix_expression</em> <em>DEC_OP</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>FIELD_SELECTION includes members in structures, component selection for | 
 | vectors and the 'length' identifier for the length() method</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>integer_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call</em> : </dt> | 
 | <dd> | 
 | <p><em>function_call_or_method</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call_or_method</em> : </dt> | 
 | <dd> | 
 | <p><em>function_call_generic</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call_generic</em> : </dt> | 
 | <dd> | 
 | <p><em>function_call_header_with_parameters</em> <em>RIGHT_PAREN</em><br> | 
 | <em>function_call_header_no_parameters</em> <em>RIGHT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call_header_no_parameters</em> : </dt> | 
 | <dd> | 
 | <p><em>function_call_header</em> <em>VOID</em><br> | 
 | <em>function_call_header</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call_header_with_parameters</em> : </dt> | 
 | <dd> | 
 | <p><em>function_call_header</em> <em>assignment_expression</em><br> | 
 | <em>function_call_header_with_parameters</em> <em>COMMA</em> <em>assignment_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_call_header</em> : </dt> | 
 | <dd> | 
 | <p><em>function_identifier</em> <em>LEFT_PAREN</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: Constructors look like functions, but lexical analysis | 
 | recognized most of them as keywords. | 
 | They are now recognized through <em>type_specifier</em>.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Methods (<strong>.length</strong>) and identifiers are recognized through | 
 | <em>postfix_expression</em>.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>function_identifier</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier</em><br> | 
 | <em>postfix_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>unary_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>postfix_expression</em><br> | 
 | <em>INC_OP</em> <em>unary_expression</em><br> | 
 | <em>DEC_OP</em> <em>unary_expression</em><br> | 
 | <em>unary_operator</em> <em>unary_expression</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: No traditional style type casts.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>unary_operator</em> : </dt> | 
 | <dd> | 
 | <p><em>PLUS</em><br> | 
 | <em>DASH</em><br> | 
 | <em>BANG</em><br> | 
 | <em>TILDE</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: No '*' or '&' unary ops. | 
 | Pointers are not supported.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>multiplicative_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>unary_expression</em><br> | 
 | <em>multiplicative_expression</em> <em>STAR</em> <em>unary_expression</em><br> | 
 | <em>multiplicative_expression</em> <em>SLASH</em> <em>unary_expression</em><br> | 
 | <em>multiplicative_expression</em> <em>PERCENT</em> <em>unary_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>additive_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>multiplicative_expression</em><br> | 
 | <em>additive_expression</em> <em>PLUS</em> <em>multiplicative_expression</em><br> | 
 | <em>additive_expression</em> <em>DASH</em> <em>multiplicative_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>shift_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>additive_expression</em><br> | 
 | <em>shift_expression</em> <em>LEFT_OP</em> <em>additive_expression</em><br> | 
 | <em>shift_expression</em> <em>RIGHT_OP</em> <em>additive_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>relational_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>shift_expression</em><br> | 
 | <em>relational_expression</em> <em>LEFT_ANGLE</em> <em>shift_expression</em><br> | 
 | <em>relational_expression</em> <em>RIGHT_ANGLE</em> <em>shift_expression</em><br> | 
 | <em>relational_expression</em> <em>LE_OP</em> <em>shift_expression</em><br> | 
 | <em>relational_expression</em> <em>GE_OP</em> <em>shift_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>equality_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>relational_expression</em><br> | 
 | <em>equality_expression</em> <em>EQ_OP</em> <em>relational_expression</em><br> | 
 | <em>equality_expression</em> <em>NE_OP</em> <em>relational_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>and_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>equality_expression</em><br> | 
 | <em>and_expression</em> <em>AMPERSAND</em> <em>equality_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>exclusive_or_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>and_expression</em><br> | 
 | <em>exclusive_or_expression</em> <em>CARET</em> <em>and_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>inclusive_or_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>exclusive_or_expression</em><br> | 
 | <em>inclusive_or_expression</em> <em>VERTICAL_BAR</em> <em>exclusive_or_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>logical_and_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>inclusive_or_expression</em><br> | 
 | <em>logical_and_expression</em> <em>AND_OP</em> <em>inclusive_or_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>logical_xor_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>logical_and_expression</em><br> | 
 | <em>logical_xor_expression</em> <em>XOR_OP</em> <em>logical_and_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>logical_or_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>logical_xor_expression</em><br> | 
 | <em>logical_or_expression</em> <em>OR_OP</em> <em>logical_xor_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>conditional_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>logical_or_expression</em><br> | 
 | <em>logical_or_expression</em> <em>QUESTION</em> <em>expression</em> <em>COLON</em> | 
 | <em>assignment_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>assignment_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>conditional_expression</em><br> | 
 | <em>unary_expression</em> <em>assignment_operator</em> <em>assignment_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>assignment_operator</em> : </dt> | 
 | <dd> | 
 | <p><em>EQUAL</em><br> | 
 | <em>MUL_ASSIGN</em><br> | 
 | <em>DIV_ASSIGN</em><br> | 
 | <em>MOD_ASSIGN</em><br> | 
 | <em>ADD_ASSIGN</em><br> | 
 | <em>SUB_ASSIGN</em><br> | 
 | <em>LEFT_ASSIGN</em><br> | 
 | <em>RIGHT_ASSIGN</em><br> | 
 | <em>AND_ASSIGN</em><br> | 
 | <em>XOR_ASSIGN</em><br> | 
 | <em>OR_ASSIGN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>expression</em> : </dt> | 
 | <dd> | 
 | <p><em>assignment_expression</em><br> | 
 | <em>expression</em> <em>COMMA</em> <em>assignment_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>constant_expression</em> : </dt> | 
 | <dd> | 
 | <p><em>conditional_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>function_prototype</em> <em>SEMICOLON</em><br> | 
 | <em>init_declarator_list</em> <em>SEMICOLON</em><br> | 
 | <em>PRECISION</em> <em>precision_qualifier</em> <em>type_specifier</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>IDENTIFIER</em> <em>LEFT_BRACE</em> <em>struct_declaration_list</em> | 
 | <em>RIGHT_BRACE</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>IDENTIFIER</em> <em>LEFT_BRACE</em> <em>struct_declaration_list</em> | 
 | <em>RIGHT_BRACE</em> <em>IDENTIFIER</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>IDENTIFIER</em> <em>LEFT_BRACE</em> <em>struct_declaration_list</em> | 
 | <em>RIGHT_BRACE</em> <em>IDENTIFIER</em> <em>array_specifier</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>IDENTIFIER</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>IDENTIFIER</em> <em>identifier_list</em> <em>SEMICOLON</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>identifier_list</em> : </dt> | 
 | <dd> | 
 | <p><em>COMMA</em> <em>IDENTIFIER</em><br> | 
 | <em>identifier_list</em> <em>COMMA</em> <em>IDENTIFIER</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_prototype</em> : </dt> | 
 | <dd> | 
 | <p><em>function_declarator</em> <em>RIGHT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_declarator</em> : </dt> | 
 | <dd> | 
 | <p><em>function_header</em><br> | 
 | <em>function_header_with_parameters</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_header_with_parameters</em> : </dt> | 
 | <dd> | 
 | <p><em>function_header</em> <em>parameter_declaration</em><br> | 
 | <em>function_header_with_parameters</em> <em>COMMA</em> <em>parameter_declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_header</em> : </dt> | 
 | <dd> | 
 | <p><em>fully_specified_type</em> <em>IDENTIFIER</em> <em>LEFT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>parameter_declarator</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier</em> <em>IDENTIFIER</em><br> | 
 | <em>type_specifier</em> <em>IDENTIFIER</em> <em>array_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>parameter_declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>type_qualifier</em> <em>parameter_declarator</em><br> | 
 | <em>parameter_declarator</em><br> | 
 | <em>type_qualifier</em> <em>parameter_type_specifier</em><br> | 
 | <em>parameter_type_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>parameter_type_specifier</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>init_declarator_list</em> : </dt> | 
 | <dd> | 
 | <p><em>single_declaration</em><br> | 
 | <em>init_declarator_list</em> <em>COMMA</em> <em>IDENTIFIER</em><br> | 
 | <em>init_declarator_list</em> <em>COMMA</em> <em>IDENTIFIER</em> <em>array_specifier</em><br> | 
 | <em>init_declarator_list</em> <em>COMMA</em> <em>IDENTIFIER</em> <em>array_specifier</em> <em>EQUAL</em> | 
 | <em>initializer</em><br> | 
 | <em>init_declarator_list</em> <em>COMMA</em> <em>IDENTIFIER</em> <em>EQUAL</em> <em>initializer</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>single_declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>fully_specified_type</em><br> | 
 | <em>fully_specified_type</em> <em>IDENTIFIER</em><br> | 
 | <em>fully_specified_type</em> <em>IDENTIFIER</em> <em>array_specifier</em><br> | 
 | <em>fully_specified_type</em> <em>IDENTIFIER</em> <em>array_specifier</em> <em>EQUAL</em> | 
 | <em>initializer</em><br> | 
 | <em>fully_specified_type</em> <em>IDENTIFIER</em> <em>EQUAL</em> <em>initializer</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: No 'enum', or 'typedef'.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>fully_specified_type</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier</em><br> | 
 | <em>type_qualifier</em> <em>type_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>invariant_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>INVARIANT</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>interpolation_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>SMOOTH</em><br> | 
 | <em>FLAT</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>layout_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>LAYOUT</em> <em>LEFT_PAREN</em> <em>layout_qualifier_id_list</em> <em>RIGHT_PAREN</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>layout_qualifier_id_list</em> : </dt> | 
 | <dd> | 
 | <p><em>layout_qualifier_id</em><br> | 
 | <em>layout_qualifier_id_list</em> <em>COMMA</em> <em>layout_qualifier_id</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>layout_qualifier_id</em> : </dt> | 
 | <dd> | 
 | <p><em>IDENTIFIER</em><br> | 
 | <em>IDENTIFIER</em> <em>EQUAL</em> <em>INTCONSTANT</em><br> | 
 | <em>IDENTIFIER</em> <em>EQUAL</em> <em>UINTCONSTANT</em><br> | 
 | <em>SHARED</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>precise_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>PRECISE</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>type_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>single_type_qualifier</em><br> | 
 | <em>type_qualifier</em> <em>single_type_qualifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>single_type_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>storage_qualifier</em><br> | 
 | <em>layout_qualifier</em><br> | 
 | <em>precision_qualifier</em><br> | 
 | <em>interpolation_qualifier</em><br> | 
 | <em>invariant_qualifier</em><br> | 
 | <em>precise_qualifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>storage_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>CONST</em><br> | 
 | <em>IN</em><br> | 
 | <em>OUT</em><br> | 
 | <em>INOUT</em><br> | 
 | <em>CENTROID</em><br> | 
 | <em>PATCH</em><br> | 
 | <em>SAMPLE</em><br> | 
 | <em>UNIFORM</em><br> | 
 | <em>BUFFER</em><br> | 
 | <em>SHARED</em><br> | 
 | <em>COHERENT</em><br> | 
 | <em>VOLATILE</em><br> | 
 | <em>RESTRICT</em><br> | 
 | <em>READONLY</em><br> | 
 | <em>WRITEONLY</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>type_specifier</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier_nonarray</em><br> | 
 | <em>type_specifier_nonarray</em> <em>array_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>array_specifier</em> : </dt> | 
 | <dd> | 
 | <p><em>LEFT_BRACKET</em> <em>RIGHT_BRACKET</em><br> | 
 | <em>LEFT_BRACKET</em> <em>constant_expression</em> <em>RIGHT_BRACKET</em><br> | 
 | <em>array_specifier</em> <em>LEFT_BRACKET</em> <em>RIGHT_BRACKET</em><br> | 
 | <em>array_specifier</em> <em>LEFT_BRACKET</em> <em>constant_expression</em> <em>RIGHT_BRACKET</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>type_specifier_nonarray</em> : </dt> | 
 | <dd> | 
 | <p><em>VOID</em><br> | 
 | <em>FLOAT</em><br> | 
 | <em>INT</em><br> | 
 | <em>UINT</em><br> | 
 | <em>BOOL</em><br> | 
 | <em>VEC2</em><br> | 
 | <em>VEC3</em><br> | 
 | <em>VEC4</em><br> | 
 | <em>BVEC2</em><br> | 
 | <em>BVEC3</em><br> | 
 | <em>BVEC4</em><br> | 
 | <em>IVEC2</em><br> | 
 | <em>IVEC3</em><br> | 
 | <em>IVEC4</em><br> | 
 | <em>UVEC2</em><br> | 
 | <em>UVEC3</em><br> | 
 | <em>UVEC4</em><br> | 
 | <em>MAT2</em><br> | 
 | <em>MAT3</em><br> | 
 | <em>MAT4</em><br> | 
 | <em>MAT2X2</em><br> | 
 | <em>MAT2X3</em><br> | 
 | <em>MAT2X4</em><br> | 
 | <em>MAT3X2</em><br> | 
 | <em>MAT3X3</em><br> | 
 | <em>MAT3X4</em><br> | 
 | <em>MAT4X2</em><br> | 
 | <em>MAT4X3</em><br> | 
 | <em>MAT4X4</em><br> | 
 | <em>ATOMIC_UINT</em><br> | 
 | <em>SAMPLER2D</em><br> | 
 | <em>SAMPLER3D</em><br> | 
 | <em>SAMPLERCUBE</em><br> | 
 | <em>SAMPLER2DSHADOW</em><br> | 
 | <em>SAMPLERCUBESHADOW</em><br> | 
 | <em>SAMPLER2DARRAY</em><br> | 
 | <em>SAMPLER2DARRAYSHADOW</em><br> | 
 | <em>SAMPLERCUBEARRAY</em><br> | 
 | <em>SAMPLERCUBEARRAYSHADOW</em><br> | 
 | <em>ISAMPLER2D</em><br> | 
 | <em>ISAMPLER3D</em><br> | 
 | <em>ISAMPLERCUBE</em><br> | 
 | <em>ISAMPLER2DARRAY</em><br> | 
 | <em>ISAMPLERCUBEARRAY</em><br> | 
 | <em>USAMPLER2D</em><br> | 
 | <em>USAMPLER3D</em><br> | 
 | <em>USAMPLERCUBE</em><br> | 
 | <em>USAMPLER2DARRAY</em><br> | 
 | <em>USAMPLERCUBEARRAY</em><br> | 
 | <em>SAMPLERBUFFER</em><br> | 
 | <em>ISAMPLERBUFFER</em><br> | 
 | <em>USAMPLERBUFFER</em><br> | 
 | <em>SAMPLER2DMS</em><br> | 
 | <em>ISAMPLER2DMS</em><br> | 
 | <em>USAMPLER2DMS</em><br> | 
 | <em>SAMPLER2DMSARRAY</em><br> | 
 | <em>ISAMPLER2DMSARRAY</em><br> | 
 | <em>USAMPLER2DMSARRAY</em><br> | 
 | <em>IMAGE2D</em><br> | 
 | <em>IIMAGE2D</em><br> | 
 | <em>UIMAGE2D</em><br> | 
 | <em>IMAGE3D</em><br> | 
 | <em>IIMAGE3D</em><br> | 
 | <em>UIMAGE3D</em><br> | 
 | <em>IMAGECUBE</em><br> | 
 | <em>IIMAGECUBE</em><br> | 
 | <em>UIMAGECUBE</em><br> | 
 | <em>IMAGEBUFFER</em><br> | 
 | <em>IIMAGEBUFFER</em><br> | 
 | <em>UIMAGEBUFFER</em><br> | 
 | <em>IMAGE2DARRAY</em><br> | 
 | <em>IIMAGE2DARRAY</em><br> | 
 | <em>UIMAGE2DARRAY</em><br> | 
 | <em>IMAGECUBEARRAY</em><br> | 
 | <em>IIMAGECUBEARRAY</em><br> | 
 | <em>UIMAGECUBEARRAY</em><br> | 
 | <em>struct_specifier</em><br> | 
 | <em>TYPE_NAME</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>precision_qualifier</em> : </dt> | 
 | <dd> | 
 | <p><em>HIGH_PRECISION</em><br> | 
 | <em>MEDIUM_PRECISION</em><br> | 
 | <em>LOW_PRECISION</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>struct_specifier</em> : </dt> | 
 | <dd> | 
 | <p><em>STRUCT</em> <em>IDENTIFIER</em> <em>LEFT_BRACE</em> <em>struct_declaration_list</em> | 
 | <em>RIGHT_BRACE</em><br> | 
 | <em>STRUCT</em> <em>LEFT_BRACE</em> <em>struct_declaration_list</em> <em>RIGHT_BRACE</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>struct_declaration_list</em> : </dt> | 
 | <dd> | 
 | <p><em>struct_declaration</em><br> | 
 | <em>struct_declaration_list</em> <em>struct_declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>struct_declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>type_specifier</em> <em>struct_declarator_list</em> <em>SEMICOLON</em><br> | 
 | <em>type_qualifier</em> <em>type_specifier</em> <em>struct_declarator_list</em> <em>SEMICOLON</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>struct_declarator_list</em> : </dt> | 
 | <dd> | 
 | <p><em>struct_declarator</em><br> | 
 | <em>struct_declarator_list</em> <em>COMMA</em> <em>struct_declarator</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>struct_declarator</em> : </dt> | 
 | <dd> | 
 | <p><em>IDENTIFIER</em><br> | 
 | <em>IDENTIFIER</em> <em>array_specifier</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>initializer</em> : </dt> | 
 | <dd> | 
 | <p><em>assignment_expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>declaration_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>statement</em> : </dt> | 
 | <dd> | 
 | <p><em>compound_statement</em><br> | 
 | <em>simple_statement</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: labeled statements for SWITCH only; 'goto' is not supported.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>simple_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>declaration_statement</em><br> | 
 | <em>expression_statement</em><br> | 
 | <em>selection_statement</em><br> | 
 | <em>switch_statement</em><br> | 
 | <em>case_label</em><br> | 
 | <em>iteration_statement</em><br> | 
 | <em>jump_statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>compound_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>LEFT_BRACE</em> <em>RIGHT_BRACE</em><br> | 
 | <em>LEFT_BRACE</em> <em>statement_list</em> <em>RIGHT_BRACE</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>statement_no_new_scope</em> : </dt> | 
 | <dd> | 
 | <p><em>compound_statement_no_new_scope</em><br> | 
 | <em>simple_statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>compound_statement_no_new_scope</em> : </dt> | 
 | <dd> | 
 | <p><em>LEFT_BRACE</em> <em>RIGHT_BRACE</em><br> | 
 | <em>LEFT_BRACE</em> <em>statement_list</em> <em>RIGHT_BRACE</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>statement_list</em> : </dt> | 
 | <dd> | 
 | <p><em>statement</em><br> | 
 | <em>statement_list</em> <em>statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>expression_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>SEMICOLON</em><br> | 
 | <em>expression</em> <em>SEMICOLON</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>selection_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>IF</em> <em>LEFT_PAREN</em> <em>expression</em> <em>RIGHT_PAREN</em> <em>selection_rest_statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>selection_rest_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>statement</em> <em>ELSE</em> <em>statement</em><br> | 
 | <em>statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>condition</em> : </dt> | 
 | <dd> | 
 | <p><em>expression</em><br> | 
 | <em>fully_specified_type</em> <em>IDENTIFIER</em> <em>EQUAL</em> <em>initializer</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>switch_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>SWITCH</em> <em>LEFT_PAREN</em> <em>expression</em> <em>RIGHT_PAREN</em> <em>LEFT_BRACE</em> | 
 | <em>switch_statement_list</em><br> | 
 | <em>RIGHT_BRACE</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>switch_statement_list</em> : </dt> | 
 | <dd> | 
 | <p>/* <em>nothing</em> */<br> | 
 | <em>statement_list</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>case_label</em> : </dt> | 
 | <dd> | 
 | <p><em>CASE</em> <em>expression</em> <em>COLON</em><br> | 
 | <em>DEFAULT</em> <em>COLON</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>iteration_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>WHILE</em> <em>LEFT_PAREN</em> <em>condition</em> <em>RIGHT_PAREN</em> <em>statement_no_new_scope</em><br> | 
 | <em>DO</em> <em>statement</em> <em>WHILE</em> <em>LEFT_PAREN</em> <em>expression</em> <em>RIGHT_PAREN</em> | 
 | <em>SEMICOLON</em><br> | 
 | <em>FOR</em> <em>LEFT_PAREN</em> <em>for_init_statement</em> <em>for_rest_statement</em> | 
 | <em>RIGHT_PAREN</em> <em>statement_no_new_scope</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>for_init_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>expression_statement</em><br> | 
 | <em>declaration_statement</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>conditionopt</em> : </dt> | 
 | <dd> | 
 | <p><em>condition</em><br> | 
 | /* <em>empty</em> */</p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>for_rest_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>conditionopt</em> <em>SEMICOLON</em><br> | 
 | <em>conditionopt</em> <em>SEMICOLON</em> <em>expression</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>jump_statement</em> : </dt> | 
 | <dd> | 
 | <p><em>CONTINUE</em> <em>SEMICOLON</em><br> | 
 | <em>BREAK</em> <em>SEMICOLON</em><br> | 
 | <em>RETURN</em> <em>SEMICOLON</em><br> | 
 | <em>RETURN</em> <em>expression</em> <em>SEMICOLON</em><br> | 
 | <em>DISCARD</em> <em>SEMICOLON</em> // Fragment shader only.</p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | <div class="admonitionblock note"> | 
 | <table> | 
 | <tr> | 
 | <td class="icon"> | 
 | <i class="fa icon-note" title="Note"></i> | 
 | </td> | 
 | <td class="content"> | 
 | <div class="paragraph"> | 
 | <p>Grammar Note: No 'goto'. | 
 | Gotos are not supported.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="dlist"> | 
 | <dl> | 
 | <dt class="hdlist1"><em>translation_unit</em> : </dt> | 
 | <dd> | 
 | <p><em>external_declaration</em><br> | 
 | <em>translation_unit</em> <em>external_declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>external_declaration</em> : </dt> | 
 | <dd> | 
 | <p><em>function_definition</em><br> | 
 | <em>declaration</em></p> | 
 | </dd> | 
 | <dt class="hdlist1"><em>function_definition</em> : </dt> | 
 | <dd> | 
 | <p><em>function_prototype</em> <em>compound_statement_no_new_scope</em></p> | 
 | </dd> | 
 | </dl> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In general the above grammar describes a super set of the OpenGL ES Shading Language. | 
 | Certain constructs that are valid purely in terms of the grammar are | 
 | disallowed by statements elsewhere in this specification.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="counting-of-inputs-and-outputs">11. Counting of Inputs and Outputs</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>This section applies to outputs from the last active vertex processing stage | 
 | and inputs to the fragment stage. | 
 | GLSL ES 3.20 specifies the storage available for such variables in terms of | 
 | an array of 4-vectors. | 
 | The assumption is that variables will be packed into these arrays without | 
 | wasting space. | 
 | This places significant burden on implementations since optimal packing is | 
 | computationally intensive. | 
 | Implementations may have more internal resources than exposed to the | 
 | application and so avoid the need to perform packing but this is also | 
 | considered an expensive solution.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>GLSL ES 3.20 therefore relaxes the requirements for packing by | 
 | specifying a simpler algorithm that may be used. | 
 | This algorithm specifies a minimum requirement for when a set of variables | 
 | must be supported by an implementation. | 
 | The implementation is allowed to support more than the minimum and so may | 
 | use a more efficient algorithm and/or may support more registers than the | 
 | virtual target machine.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Outputs from the last active vertex stage and inputs to the fragment stage are | 
 | counted separately. | 
 | If statically used in the fragment shader, the built-in special variables | 
 | (<em>gl_FragCoord</em>, <em>gl_FrontFacing</em> and <em>gl_PointCoord</em>) are included when | 
 | calculating the storage requirements of fragment inputs.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>If the last active vertex-pipeline shader and fragment shader are linked | 
 | together, inputs and outputs are only counted if they are statically used | 
 | within the shader. | 
 | If the shaders are each compiled into a separable program, all declared inputs | 
 | and outputs are counted.</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>GLSL ES 3.20 does not require the implementation to remove | 
 | outputs which are not statically used in the fragment shader.</p> | 
 | </div> | 
 | </td> | 
 | </tr> | 
 | </table> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>For the algorithm used, failing resource allocation for a variable must | 
 | result in an error.</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>The resource allocation of variables must succeed for all cases where the | 
 | following packing algorithm succeeds:</p> | 
 | </div> | 
 | <div class="ulist"> | 
 | <ul> | 
 | <li> | 
 | <p>The target architecture consists of a grid of registers, 16 rows by 4 | 
 | columns. | 
 | Each register can contain a scalar value, i.e. a float, int or uint.</p> | 
 | </li> | 
 | <li> | 
 | <p>Variables with an explicit location are allocated first. | 
 | When attempting to allocate a location for other variables, if there is | 
 | a conflict, the search moves to the next available free location.</p> | 
 | </li> | 
 | <li> | 
 | <p>Structures are assumed to be flattened. | 
 | Each data member is treated as if it were at global scope.</p> | 
 | </li> | 
 | <li> | 
 | <p>Variables are packed into the registers one at a time so that they each | 
 | occupy a contiguous sub-rectangle. | 
 | No splitting of variables is permitted.</p> | 
 | </li> | 
 | <li> | 
 | <p>The orientation of variables is fixed. | 
 | Vectors always occupy registers in a single row. | 
 | Elements of an array must be in different rows. | 
 | E.g. <strong>vec4</strong> will always occupy one row; float[16] will occupy one | 
 | column. | 
 | Since it is not permitted to split a variable, large arrays e.g. | 
 | float[32] will always fail with this algorithm.</p> | 
 | </li> | 
 | <li> | 
 | <p>Non-square matrices of type <strong>matCxR</strong> consume the same space as a square | 
 | matrix of type <strong>matN</strong> where N is the greater of C and R. | 
 | Variables of type <strong>mat2</strong> occupies 2 complete rows. | 
 | These rules allow implementations more flexibility in how variables are | 
 | stored. | 
 | + Other variables consume only the minimum space required.</p> | 
 | </li> | 
 | <li> | 
 | <p>Arrays of size N are assumed to take N times the size of the base type.</p> | 
 | </li> | 
 | <li> | 
 | <p>Variables are packed in the following order:</p> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p><strong>mat4</strong> and arrays of <strong>mat4</strong>.</p> | 
 | </li> | 
 | <li> | 
 | <p><strong>mat2</strong> and arrays of <strong>mat2</strong> (since they occupy full rows)</p> | 
 | </li> | 
 | <li> | 
 | <p><strong>vec4</strong> and arrays of <strong>vec4</strong></p> | 
 | </li> | 
 | <li> | 
 | <p><strong>mat3</strong> and arrays of <strong>mat3</strong></p> | 
 | </li> | 
 | <li> | 
 | <p><strong>vec3</strong> and arrays of <strong>vec3</strong></p> | 
 | </li> | 
 | <li> | 
 | <p><strong>vec2</strong> and arrays of <strong>vec2</strong></p> | 
 | </li> | 
 | <li> | 
 | <p>Scalar types and arrays of scalar types</p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | </li> | 
 | <li> | 
 | <p>For each of the above types, the arrays are processed in order of size, | 
 | largest first. | 
 | Arrays of size 1 and the base type are considered equivalent. | 
 | The first type to be packed will be mat4[4], mat4[3], mat[2] followed by | 
 | mat4, mat2[4]…​mat2[2], mat2, vec4[8], vec4[7],…​vec4[1], vec4, | 
 | mat3[2], mat3 and so on. | 
 | The last variables to be packed will be float (and float[1]).</p> | 
 | </li> | 
 | <li> | 
 | <p>For 2,3 and 4 component variables packing is started using the 1<sup>st</sup> | 
 | column of the 1<sup>st</sup> row. | 
 | Variables are then allocated to successive rows, aligning them to the | 
 | 1<sup>st</sup> column.</p> | 
 | </li> | 
 | <li> | 
 | <p>For 2 component variables, when there are no spare rows, the strategy is | 
 | switched to using the highest numbered row and the lowest numbered | 
 | column where the variable will fit. | 
 | (In practice, this means they will be aligned to the x or z component.) | 
 | Packing of any further 3 or 4 component variables will fail at this | 
 | point.</p> | 
 | </li> | 
 | <li> | 
 | <p>1 component variables (e.g. floats and arrays of floats) have their own | 
 | packing rule. | 
 | They are packed in order of size, largest first. | 
 | Each variable is placed in the column that leaves the least amount of | 
 | space in the column and aligned to the lowest available rows within that | 
 | column. | 
 | During this phase of packing, space will be available in up to 4 | 
 | columns. | 
 | The space within each column is always contiguous in the case where no | 
 | variables have explicit locations.</p> | 
 | </li> | 
 | <li> | 
 | <p>For each type, variables with the 'smooth' property are packed first, | 
 | followed by variables with the 'flat' property.</p> | 
 | </li> | 
 | <li> | 
 | <p>Each row can contain either values with the 'smooth' property or the | 
 | 'flat' property but not both. | 
 | If this situation is encountered during allocation, the algorithm skips | 
 | the component location and continues with the next available location. | 
 | These skipped locations may be used for other values later in the | 
 | allocation process.</p> | 
 | </li> | 
 | <li> | 
 | <p>There is no backtracking. | 
 | Once a value is assigned a location, it cannot be changed, even if such | 
 | a change is required for a successful allocation.</p> | 
 | </li> | 
 | </ul> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Example: pack the following types:</p> | 
 | </div> | 
 | <div class="listingblock"> | 
 | <div class="content"> | 
 | <pre class="CodeRay highlight"><code data-lang="c++">out vec4 a;     <span class="comment">// top left</span> | 
 | out mat3 b;     <span class="comment">// align to left, lowest numbered rows</span> | 
 | out mat2x3 c;   <span class="comment">// same size as mat3, align to left</span> | 
 | out vec2 d[<span class="integer">6</span>];  <span class="comment">// align to left, lowest numbered rows</span> | 
 | out vec2 e[<span class="integer">4</span>];  <span class="comment">// Cannot align to left so align to z column, highest</span> | 
 |                 <span class="comment">// numbered rows</span> | 
 | out vec2 f;     <span class="comment">// Align to left, lowest numbered rows.</span> | 
 | out <span class="predefined-type">float</span> g[<span class="integer">3</span>]  <span class="comment">// Column with minimum space</span> | 
 | out <span class="predefined-type">float</span> h[<span class="integer">2</span>]; <span class="comment">// Column with minimum space (choice of 3, any</span> | 
 |                 <span class="comment">// can be used)</span> | 
 | out <span class="predefined-type">float</span> i;    <span class="comment">// Column with minimum space</span></code></pre> | 
 | </div> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>In this example, the variables happen to be listed in the order in which | 
 | they are packed. | 
 | Packing is independent of the order of declaration.</p> | 
 | </div> | 
 | <table class="tableblock frame-all grid-all stretch"> | 
 | <colgroup> | 
 | <col style="width: 20%;"> | 
 | <col style="width: 20%;"> | 
 | <col style="width: 20%;"> | 
 | <col style="width: 20%;"> | 
 | <col style="width: 20%;"> | 
 | </colgroup> | 
 | <tbody> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>x</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>y</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>z</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>w</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>a</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>a</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>a</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>a</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>b</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>c</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>g</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>g</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>g</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></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"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">12</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>d</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">13</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>f</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>f</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">14</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>h</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>i</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | </tr> | 
 | <tr> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>h</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>e</strong></p></td> | 
 | </tr> | 
 | </tbody> | 
 | </table> | 
 | <div class="paragraph"> | 
 | <p>Some types e.g. mat4[8] will be too large to fit. | 
 | These always fail with this algorithm.</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="acknowledgments">12. Acknowledgments</h2> | 
 | <div class="sectionbody"> | 
 | <div class="paragraph"> | 
 | <p>This specification is based on the work of those who contributed to past | 
 | versions of the Open GL and Open GL ES Language Specifications and the | 
 | following contributors to this version:</p> | 
 | </div> | 
 | <div class="paragraph"> | 
 | <p>Acorn Pooley, NVIDIA<br> | 
 | Alberto Moreira, Qualcomm<br> | 
 | Aleksandra Krstic, Qualcomm<br> | 
 | Alon Or-bach, Nokia & Samsung<br> | 
 | Andrzej Kacprowski, Intel<br> | 
 | Arzhange Safdarzadeh, Intel<br> | 
 | Aske Simon Christensen, ARM<br> | 
 | Avi Shapira, Graphic Remedy<br> | 
 | Barthold Lichtenbelt, NVIDIA<br> | 
 | Ben Bowman, Imagination Technologies<br> | 
 | Ben Brierton, Broadcom<br> | 
 | Benj Lipchak, Apple<br> | 
 | Benson Tao, Vivante<br> | 
 | Bill Licea-Kane, Qualcomm<br> | 
 | Brent Insko, Intel<br> | 
 | Brian Murray, Freescale<br> | 
 | Bruce Merry, ARM<br> | 
 | Carlos Santa, TI<br> | 
 | Cass Everitt, Epic Games & NVIDIA<br> | 
 | Cemil Azizoglu, TI<br> | 
 | Chang-Hyo Yu, Samsung<br> | 
 | Chris Dodd, NVIDIA<br> | 
 | Chris Knox, NVIDIA<br> | 
 | Chris Tserng, TI<br> | 
 | Clay Montgomery, TI<br> | 
 | Daniel Kartch, NVIDIA<br> | 
 | Daniel Koch, Transgaming& NVIDIA<br> | 
 | Daoxiang Gong, Imagination Technologies<br> | 
 | Dave Shreiner, ARM<br> | 
 | David Garcia, AMD<br> | 
 | David Jarmon, Vivante<br> | 
 | Derek Cornish, Epic Games<br> | 
 | Dominick Witczak, Mobica<br> | 
 | Eben Upton, Broadcom<br> | 
 | Ed Plowman, ARM<br> | 
 | Eisaku Ohbuchi, DMP<br> | 
 | Elan Lennard, ARM<br> | 
 | Erik Faye-Lund, ARM<br> | 
 | Graham Connor, Imagination Technologies<br> | 
 | Graham Sellers, AMD<br> | 
 | Greg Roth, NVIDIA<br> | 
 | Guillaume Portier, Hi Corporation<br> | 
 | Guofang Jiao, Qualcomm<br> | 
 | Hans-Martin Will, Vincent<br> | 
 | Hwanyong Lee, Huone<br> | 
 | I-Gene Leong, NVIDIA<br> | 
 | Ian Romanick, Intel<br> | 
 | Ian South-Dickinson, NVIDIA<br> | 
 | Ilan Aelion-Exch, Samsung<br> | 
 | Inkyun Lee, Huone<br> | 
 | Jacob Strm, Ericsson<br> | 
 | James Adams, Broadcom<br> | 
 | James Jones, Imagination Technologies<br> | 
 | James McCombe, Imagination Technologies<br> | 
 | Jamie Gennis, Google<br> | 
 | Jan-Harald Fredriksen, ARM<br> | 
 | Jani Vaisanen, Nokia<br> | 
 | Jarkko Kemppainen, Symbio<br> | 
 | Jeff Bolz, NVIDIA<br> | 
 | Jeff Leger, Qualcomm<br> | 
 | Jeff Vigil, Qualcomm<br> | 
 | Jeremy Sandmel, Apple<br> | 
 | Jeremy Thorne, Broadcom<br> | 
 | Jim Hauxwell, Broadcom<br> | 
 | Jinsung Kim, Huone<br> | 
 | Jiyoung Yoon, Huone<br> | 
 | John Kessenich, Google<br> | 
 | Jon Kennedy, 3DLabs<br> | 
 | Jon Leech, Khronos<br> | 
 | Jonathan Putsman, Imagination Technologies<br> | 
 | Joohoon Lee, Samsung<br> | 
 | JoukoKylmäoja, Symbio<br> | 
 | Jrn Nystad, ARM<br> | 
 | Jussi Rasanen, NVIDIA<br> | 
 | Kalle Raita, drawElements<br> | 
 | Kari Pulli, Nokia<br> | 
 | Keith Whitwell, VMware<br> | 
 | Kent Miller, Netlogic Microsystems<br> | 
 | Kimmo Nikkanen, Nokia<br> | 
 | Konsta Karsisto, Nokia<br> | 
 | Krzysztof Kaminski, Intel<br> | 
 | Larry Seiler, Intel<br> | 
 | Lars Remes, Symbio<br> | 
 | Lee Thomason, Adobe<br> | 
 | Lefan Zhong, Vivante<br> | 
 | Marcus Lorentzon, Ericsson<br> | 
 | Mark Butler, Imagination Technologies<br> | 
 | Mark Callow, Hi Corporation<br> | 
 | Mark Cresswell, Broadcom<br> | 
 | Mark Snyder, Alt Software<br> | 
 | Mark Young, AMD<br> | 
 | Mathieu Robart, STM<br> | 
 | Matt Netsch, Qualcomm<br> | 
 | Matt Russo, Matrox<br> | 
 | Maurice Ribble, Qualcomm<br> | 
 | Max Kazakov, DMP<br> | 
 | Mika Pesonen, Nokia<br> | 
 | Mike Cai, Vivante<br> | 
 | Mike Weiblen, Zebra Imaging & Qualcomm<br> | 
 | Mila Smith, AMD<br> | 
 | Nakhoon Baek, Kyungpook Univeristy<br> | 
 | Nate Huang, NVIDIA<br> | 
 | Neil Trevett, NVIDIA<br> | 
 | Nelson Kidd, Intel<br> | 
 | Nick Haemel, NVIDIA<br> | 
 | Nick Penwarden, Epic Games<br> | 
 | Niklas Smedberg, Epic Games<br> | 
 | Nizar Romdan, ARM<br> | 
 | Oliver Wohlmuth , Fujitsu<br> | 
 | Pat Brown, NVIDIA<br> | 
 | Paul Ruggieri, Qualcomm<br> | 
 | Per Wennersten, Ericsson<br> | 
 | Petri Talala, Symbio<br> | 
 | Phil Huxley, ZiiLabs<br> | 
 | Philip Hatcher, Freescale & Intel<br> | 
 | Piers Daniell, NVIDIA<br> | 
 | Pyry Haulos, drawElements<br> | 
 | Piotr Tomaszewski, Ericsson<br> | 
 | Piotr Uminski, Intel<br> | 
 | Rami Mayer, Samsung<br> | 
 | Rauli Laatikainen, RightWare<br> | 
 | Rob Barris, NVIDIA<br> | 
 | Rob Simpson, Qualcomm<br> | 
 | Roj Langhi, Vivante<br> | 
 | Rune Holm, ARM<br> | 
 | Sami Kyostila, Nokia<br> | 
 | Sean Ellis, ARM<br> | 
 | Shereef Shehata, TI<br> | 
 | Sila Kayo, Nokia<br> | 
 | Slawomir Cygan, Intel<br> | 
 | Slawomir Grajewski, Intel<br> | 
 | Steve Hill, STM & Broadcom<br> | 
 | Steven Olney, DMP<br> | 
 | Suman Sharma, Intel<br> | 
 | Tapani Palli, Nokia<br> | 
 | Teemu Laakso, Symbio<br> | 
 | Tero Karras, NVIDIA<br> | 
 | Timo Suoranta, Imagination Technologies & Broadcom<br> | 
 | Tom Cooksey, ARM<br> | 
 | Tom McReynolds, NVIDIA<br> | 
 | Tom Olson, TI & ARM<br> | 
 | Tomi Aarnio, Nokia<br> | 
 | Tommy Asano, Takumi<br> | 
 | Wes Bang, Nokia<br> | 
 | Yanjun Zhang, Vivante</p> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div class="sect1"> | 
 | <h2 id="references">13. Normative References</h2> | 
 | <div class="sectionbody"> | 
 | <div class="olist arabic"> | 
 | <ol class="arabic"> | 
 | <li> | 
 | <p>International Standard ISO/IEC 14882:1998(E). | 
 | Programming Languages - C++. Referenced for preprocessor only</p> | 
 | </li> | 
 | <li> | 
 | <p>“OpenGL<sup>R</sup> ES, Version 3.2”, | 
 | <a href="https://www.khronos.org/registry/OpenGL/index_es.php" class="bare">https://www.khronos.org/registry/OpenGL/index_es.php</a>, November 3, 2016.</p> | 
 | </li> | 
 | <li> | 
 | <p>“The OpenGL<sup>R</sup> Graphics System: A Specification, Version 4.6 (Core | 
 | Profile)”, <a href="https://www.khronos.org/registry/OpenGL/index_gl.php" class="bare">https://www.khronos.org/registry/OpenGL/index_gl.php</a>, June | 
 | 1, 2016.</p> | 
 | </li> | 
 | <li> | 
 | <p>International Standard ISO/IEC 646:1991. | 
 | Information technology - ISO 7-bit coded character set for information | 
 | interchange</p> | 
 | </li> | 
 | <li> | 
 | <p>The Unicode Standard Version 6.0 - Core Specification.</p> | 
 | </li> | 
 | <li> | 
 | <p>IEEE 754-2008. | 
 | <em>IEEE Standard for Floating-Point Arithmetic</em></p> | 
 | </li> | 
 | </ol> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | </div> | 
 | <div id="footer"> | 
 | <div id="footer-text"> | 
 | Version 3.20.5<br> | 
 | Last updated 2018-12-12 16:37:44 MST | 
 | </div> | 
 | </div> | 
 |  | 
 | <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script> | 
 | </body> | 
 | </html> |