blob: 236d893577cfa1f33f90c23bfc37b74930b3cdf7 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.7.1">
<meta name="author" content="John Kessenich, Google (Editor and Author) ; Dave Baldwin and Randi Rost (Version 1.1 Authors)">
<title>The OpenGL&#174; Shading Language, Version 4.60.7</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<sup>&#174;</sup> Shading Language, Version 4.60.7</h1>
<div class="details">
<span id="author" class="author">John Kessenich, Google (Editor and Author) ; Dave Baldwin and Randi Rost (Version 1.1 Authors)</span><br>
<span id="revnumber">version 4.60.7,</span>
<span id="revdate">Wed, 10 Jul 2019 20:42:58 +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="#deprecation">1.5. Deprecation</a></li>
</ul>
</li>
<li><a href="#overview-of-opengl-shading">2. Overview of Shading</a>
<ul class="sectlevel2">
<li><a href="#vertex-processor">2.1. Vertex Processor</a></li>
<li><a href="#tessellation-control-processor">2.2. Tessellation Control Processor</a></li>
<li><a href="#tessellation-evaluation-processor">2.3. Tessellation Evaluation Processor</a></li>
<li><a href="#geometry-processor">2.4. Geometry Processor</a></li>
<li><a href="#fragment-processor">2.5. Fragment Processor</a></li>
<li><a href="#compute-processor">2.6. Compute Processor</a></li>
</ul>
</li>
<li><a href="#basics">3. Basics</a>
<ul class="sectlevel2">
<li><a href="#character-set">3.1. Character Set and Phases of Compilation</a></li>
<li><a href="#source-strings">3.2. Source Strings</a></li>
<li><a href="#preprocessor">3.3. Preprocessor</a></li>
<li><a href="#comments">3.4. Comments</a></li>
<li><a href="#tokens">3.5. Tokens</a></li>
<li><a href="#keywords">3.6. Keywords</a></li>
<li><a href="#identifiers">3.7. Identifiers</a></li>
<li><a href="#definitions">3.8. Definitions</a></li>
</ul>
</li>
<li><a href="#variables-and-types">4. Variables and Types</a>
<ul class="sectlevel2">
<li><a href="#basic-types">4.1. Basic Types</a></li>
<li><a href="#scoping">4.2. Scoping</a></li>
<li><a href="#storage-qualifiers">4.3. Storage Qualifiers</a></li>
<li><a href="#layout-qualifiers">4.4. Layout Qualifiers</a></li>
<li><a href="#interpolation-qualifiers">4.5. Interpolation Qualifiers</a></li>
<li><a href="#parameter-qualifiers">4.6. Parameter Qualifiers</a></li>
<li><a href="#precision-and-precision-qualifiers">4.7. Precision and Precision Qualifiers</a></li>
<li><a href="#variance-and-the-invariant-qualifier">4.8. Variance and the Invariant Qualifier</a></li>
<li><a href="#the-precise-qualifier">4.9. The Precise Qualifier</a></li>
<li><a href="#memory-qualifiers">4.10. Memory Qualifiers</a></li>
<li><a href="#specialization-constant-qualifier">4.11. Specialization-Constant Qualifier</a></li>
<li><a href="#order-of-qualification">4.12. Order and Repetition of Qualification</a></li>
<li><a href="#empty-declarations">4.13. Empty Declarations</a></li>
</ul>
</li>
<li><a href="#operators-and-expressions">5. Operators and Expressions</a>
<ul class="sectlevel2">
<li><a href="#operators">5.1. Operators</a></li>
<li><a href="#array-operations">5.2. Array Operations</a></li>
<li><a href="#function-calls">5.3. Function Calls</a></li>
<li><a href="#constructors">5.4. Constructors</a></li>
<li><a href="#vector-components">5.5. Vector and Scalar Components and Length</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="#out-of-bounds-accesses">5.11. Out-of-Bounds Accesses</a></li>
<li><a href="#specialization-constant-operations">5.12. Specialization-Constant Operations</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="#compatibility-profile-vertex-shader-built-in-inputs">7.2. Compatibility Profile Vertex Shader Built-In Inputs</a></li>
<li><a href="#built-in-constants">7.3. Built-In Constants</a></li>
<li><a href="#built-in-uniform-state">7.4. Built-In Uniform State</a></li>
<li><a href="#redeclaring-built-in-blocks">7.5. 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="#noise-functions">8.15. Noise Functions</a></li>
<li><a href="#shader-invocation-control-functions">8.16. Shader Invocation Control Functions</a></li>
<li><a href="#shader-memory-control-functions">8.17. Shader Memory Control Functions</a></li>
<li><a href="#_subpass_input_functions">8.18. Subpass-Input Functions</a></li>
<li><a href="#shader-invocation-group-functions">8.19. Shader Invocation Group Functions</a></li>
</ul>
</li>
<li><a href="#shading-language-grammar">9. Shading Language Grammar</a></li>
<li><a href="#acknowledgments">10. Acknowledgments</a></li>
<li><a href="#references">11. Normative References</a></li>
<li><a href="#_non_normative_spir_v_mappings">12. Non-Normative SPIR-V Mappings</a>
<ul class="sectlevel2">
<li><a href="#_feature_comparisons">12.1. Feature Comparisons</a></li>
<li><a href="#_mapping_from_glsl_to_spir_v">12.2. Mapping from GLSL to SPIR-V</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div style="page-break-after: always;"></div>
<div class="paragraph">
<p>Copyright &#169; 2008-2018 The Khronos Group Inc. All Rights Reserved.</p>
</div>
<div class="paragraph">
<p>This specification is protected by copyright laws and contains material
proprietary to the Khronos Group, Inc. It or any components may not be
reproduced, republished, distributed, transmitted, displayed, broadcast,
or otherwise exploited in any manner without the express prior written
permission of Khronos Group. You may use this specification for
implementing the functionality therein, without altering or removing any
trademark, copyright or other notice from the specification, but the
receipt or possession of this specification does not convey any rights
to reproduce, disclose, or distribute its contents, or to manufacture,
use, or sell anything that it may describe, in whole or in part.</p>
</div>
<div class="paragraph">
<p>Khronos Group grants express permission to any current Promoter,
Contributor or Adopter member of Khronos to copy and redistribute
UNMODIFIED versions of this specification in any fashion, provided that
NO CHARGE is made for the specification and the latest available update
of the specification for any version of the API is used whenever
possible. Such distributed specification may be reformatted AS LONG AS
the contents of the specification are not changed in any way. The
specification may be incorporated into a product that is sold as long as
such product includes significant independent work developed by the
seller. A link to the current version of this specification on the
Khronos Group website should be included whenever possible with
specification distributions.</p>
</div>
<div class="paragraph">
<p>Khronos Group makes no, and expressly disclaims any, representations or
warranties, express or implied, regarding this specification, including,
without limitation, any implied warranties of merchantability or fitness
for a particular purpose or noninfringement of any intellectual
property. Khronos Group makes no, and expressly disclaims any,
warranties, express or implied, regarding the correctness, accuracy,
completeness, timeliness, and reliability of the specification. Under no
circumstances will the Khronos Group, or any of its Promoters,
Contributors or Members or their respective partners, officers,
directors, employees, agents, or representatives be liable for any
damages, whether direct, indirect, special or consequential damages for
lost revenues, lost profits, or otherwise, arising from or in connection
with these materials.</p>
</div>
<div class="paragraph">
<p>Khronos, Vulkan, SYCL, SPIR, WebGL, EGL, COLLADA, StreamInput, OpenVX,
OpenKCam, glTF, OpenKODE, OpenVG, OpenWF, OpenSL ES, OpenMAX, OpenMAX
AL, OpenMAX IL and OpenMAX DL are trademarks and WebCL is a
certification mark of the Khronos Group Inc. OpenCL is a trademark of
Apple Inc. and OpenGL and OpenML are registered trademarks and the
OpenGL ES and OpenGL SC logos are trademarks of Silicon Graphics
International used under license by Khronos. All other product names,
trademarks, and/or company names are used solely for identification and
belong to their respective owners.</p>
</div>
<div style="page-break-after: always;"></div>
<!-- toc disabled -->
</div>
</div>
<div class="sect1">
<h2 id="introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This document specifies only version 4.60 of the OpenGL Shading Language (GLSL).
It requires __VERSION__ to substitute 460, and requires
<strong>#version</strong> to accept only
<code>460</code>.
If <strong>#version</strong> is declared with a smaller number, the language accepted is a
previous version of the shading language, which will be supported depending
on the version and type of context in the API.
See the <a href="#references">normative references</a> for details on what language
versions are supported.</p>
</div>
<div class="paragraph">
<p>Previous versions of the OpenGL Shading Language, as well as the OpenGL ES Shading Language,
are not strict subsets of the version specified here, particularly with
respect to precision, name-hiding rules, and treatment of interface
variables.
See the specification corresponding to a particular language version for
details specific to that version of the language.</p>
</div>
<div class="paragraph">
<p>Throughout, when generating SPIR-V for consumption by the Vulkan API
(see <a href="#references">normative references</a>), this will be said to be
<em>targeting Vulkan</em>.</p>
</div>
<div class="paragraph">
<p>While this specification and the OpenGL Specification are normative for OpenGL Shading Language, for
SPIR-V generation it is still the SPIR-V specification and the SPIR-V client
API specification that are normative for the generated SPIR-V.
See the <a href="#references">normative references</a> for further detail.</p>
</div>
<div class="paragraph">
<p>For SPIR-V generation, the SPIR-V client API specifies the commands used to
manipulate SPIR-V shaders.</p>
</div>
<div class="paragraph">
<p>Independent offline tool chains will compile GLSL down to the SPIR-V
intermediate language.
SPIR-V generation is not enabled with a <strong>#extension</strong>, <strong>#version</strong>, or a
profile.
Instead, use of GLSL for SPIR-V is determined by offline tool-chain use.
See the documentation of such tools to see how to request generation of
SPIR-V for its client API.</p>
</div>
<div class="paragraph">
<p>GLSL &#8594; SPIR-V compilers must be directed as to what SPIR-V <strong>Capabilities</strong>
are legal at run-time and give errors for GLSL feature use outside those
capabilities.
This is also true for implementation-dependent limits that can be error
checked by the front-end against built-in constants present in the GLSL
source: the front-end can be informed of such limits, and report errors when
they are exceeded.</p>
</div>
<div class="paragraph">
<p>SPIR-V features that are not controlled by a SPIR-V capability, but do have an
equivalent GLSL counterpart (stages, built-in functions, types, limits, etc.)
are only expected to work on OpenGL drivers that support the GLSL counterpart.</p>
</div>
<div class="paragraph">
<p>All references in this specification to the <a href="#references">OpenGL Specification</a> are to
the Core profile of version 4.6, unless a different profile is
specified.</p>
</div>
<div class="sect2">
<h3 id="changes">1.1. Changes</h3>
<div class="sect3">
<h4 id="_changes_from_revision_6_of_glsl_4_6">1.1.1. Changes from Revision 6 of GLSL 4.6</h4>
<div class="ulist">
<ul>
<li>
<p>Incorporated the GL_KHR_vulkan_glsl specification.</p>
</li>
<li>
<p>Add note in the introduction about presence in drivers of SPIR-V features,
as they relate to GLSL features.</p>
</li>
<li>
<p>Clarify it is same location that triggers default-uniform block matching
rules.
See <a href="#uniform-variable-layout-qualifiers">Uniform Variable Layout Qualifiers</a>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_changes_from_revision_5_of_glsl_4_6">1.1.2. Changes from Revision 5 of GLSL 4.6</h4>
<div class="ulist">
<ul>
<li>
<p>Private GLSL issue #34: Clarify/consolidate implicit conversion rules from int &#8594; uint
to be the same as explicit construction.</p>
</li>
<li>
<p>Private GLSL issue #24: Clarify that <strong>barrier</strong>() by itself is enough to synchronize
both control flow and memory accesses to <strong>shared</strong> variables and tessellation
control output variables. For other memory accesses an additional memory
barrier is still required.</p>
</li>
<li>
<p>Normatively reference IEEE-754 for definitions of floating-point formats.</p>
</li>
<li>
<p>Private GLSL issue 36: <strong>refract</strong> function on <strong>double</strong> types requires eta
argument to have type <strong>double</strong>.</p>
</li>
<li>
<p>Clarify restrictions on input variables in tessellation and geometry stages.</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_revision_4_of_glsl_4_6">1.1.3. Changes from Revision 4 of GLSL 4.6</h4>
<div class="ulist">
<ul>
<li>
<p>Private bug 13012: Clarified that builtin uniform variables might only
be available in the fragment stage.</p>
</li>
<li>
<p>Private bug 13837: Ternary and sequence operators may operate on <strong>void</strong> types.</p>
</li>
<li>
<p>Clarified that errors arising from preprocessing must be returned at compile time.</p>
</li>
<li>
<p>Clarified that access to any part of a variable constitutes a static use.</p>
</li>
<li>
<p>Private GLSL issue 19: A statement is required following any label at the end of a <strong>switch</strong>.</p>
</li>
<li>
<p>Private GLSL issue 26: <strong>noise</strong> is not valid when compiling for SPIR-V.</p>
</li>
<li>
<p>Private GLSL issue 20: <strong>length</strong>() expressions returning a constant value may not
contain side effects.</p>
</li>
<li>
<p>Public OpenGL-API issue 7: Variables can be declared as both <strong>readonly</strong>
and <strong>writeonly</strong>.</p>
</li>
<li>
<p>Private GLSL issue 16: Use of constant expressions within <strong>#line</strong> directives is undefined.</p>
</li>
<li>
<p>Corrected return type of <strong>imageAtomicExchange</strong> on <strong>float</strong> images.</p>
</li>
<li>
<p>Private GLSL issue 32: Remove <strong>length</strong>() method contradiction:
Non runtime-sized arrays only support <strong>length</strong>() on explicitly
sized arrays.</p>
</li>
<li>
<p>Private GLSL issue 21: Clarified the l-value restriction on <strong>interpolateAt</strong>.</p>
</li>
<li>
<p>Private OpenGL-API issue 53: Clarified bit-width requirements for location aliasing.</p>
</li>
<li>
<p>Public GLSL issue 15: <strong>gl_in</strong> can be redeclared using unsized-array syntax.</p>
</li>
<li>
<p>Clarification of the formats needed for DEPTH_COMPONENT and
STENCIL_COMPONENT for depth/stencil textures.</p>
</li>
<li>
<p>Added image formats to the layout-qualifier table in the
<a href="#layout-qualifiers">Layout Qualifiers</a> section.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_changes_from_revision_3_of_glsl_4_6">1.1.4. Changes from Revision 3 of GLSL 4.6</h4>
<div class="ulist">
<ul>
<li>
<p>Private GLSL issue 13: Fix misspelling of <strong>allInvocationsEqual</strong>().
(The one in the table was incorrectly listed as <strong>anyInvocationsEqual</strong>(),
other spellings were correct.)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_summary_of_changes_from_revision_7_of_glsl_version_4_50">1.1.5. Summary of Changes from Revision 7 of GLSL Version 4.50</h4>
<div class="ulist">
<ul>
<li>
<p>Incorporated the GL_ARB_shader_atomic_counter_ops extension.</p>
</li>
<li>
<p>Incorporated the GL_ARB_shader_draw_parameters extension.</p>
</li>
<li>
<p>Incorporated the GL_ARB_shader_group_vote extension.</p>
</li>
<li>
<p>Incorporated the GL_ARB_gl_spirv extension.</p>
</li>
<li>
<p>Private Bug 16070: Allow extra semi-colons at global scope.</p>
</li>
<li>
<p>Private GLSL Issue 5: Be explicit that &#8220;fail to link&#8221; is really
&#8220;compile-time or link-time error&#8221;, for some forms of error.</p>
</li>
<li>
<p>Private GLSL Issue 7: Change <em>gl_MaxComputeUniformComponents</em> to 1024.</p>
</li>
<li>
<p>Private OpenGL API Issue 35: Require location on transparent individual
uniform variables for SPIR-V.</p>
</li>
<li>
<p>Private GLSL Issue 8: Be more clear an <strong>interpolateAt</strong>() interpolant can
be a structure member.</p>
</li>
<li>
<p>Private GLSL Issue 9: Specify how <strong>xfb_buffer</strong> interacts with a block
array: the capturing buffer increments for each block array element.</p>
</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 Shading Language, version 4.60</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,
completely creating one or more of the programmable stages of the
API pipeline.
All the shaders for a single programmable stage must be within the same
program.
A complete set of programmable stages can be put into a single program or
the stages can be partitioned across multiple programs.
The aim of this document is to thoroughly specify the programming language.
The <a href="#references">normative references</a> will specify the API entry points
used to manipulate and communicate with programs and shaders.</p>
</div>
</div>
<div class="sect2">
<h3 id="error-handling">1.3. Error Handling</h3>
<div class="paragraph">
<p>Compilers, in general, accept programs that are ill-formed, due to the
impossibility of detecting all ill-formed programs.
Portability is only ensured for well-formed programs, which this
specification describes.
Compilers are encouraged to detect ill-formed programs and issue diagnostic
messages, but are not required to do so for all cases.
Compile-time errors must be returned for lexically or grammatically
incorrect shaders.
Other errors are reported at compile time or link time as indicated.
Code that is &#8220;dead&#8221; must still be error checked.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">if</span> (<span class="predefined-constant">false</span>) <span class="comment">// changing false to true cannot uncover additional errors</span>
statement; <span class="comment">// statement must be error checked regardless</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="typographical-conventions">1.4. Typographical Conventions</h3>
<div class="paragraph">
<p>Italic, bold, and font choices have been used in this specification
primarily to improve readability.
Code fragments use a fixed width font.
Identifiers embedded in text are italicized.
Keywords embedded in text are bold.
Operators are called by their name, followed by their symbol in bold in
parentheses.
The clarifying grammar fragments in the text use bold for literals and
italics for non-terminals.
The official grammar in &#8220;<a href="#shading-language-grammar">Shading Language
Grammar</a>&#8221; uses all capitals for terminals and lower case for
non-terminals.</p>
</div>
</div>
<div class="sect2">
<h3 id="deprecation">1.5. Deprecation</h3>
<div class="paragraph">
<p>The OpenGL Shading Language has deprecated some features.
These are clearly called out in this specification as &#8220;deprecated&#8221;.
They are still present in this version of the language, but are targeted for
potential removal in a future version of the shading language.
The OpenGL API has a forward compatibility mode that will disallow use of
deprecated features.
If compiling in a mode where use of deprecated features is disallowed, their
use causes compile-time or link-time errors.
See the <a href="#references">OpenGL Specification</a> for details on what causes deprecated
language features to be accepted or to return an error.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="overview-of-opengl-shading">2. Overview of Shading</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The OpenGL Shading Language is actually several closely related languages.
These languages are used to create shaders for each of the programmable
processors contained in the API&#8217;s processing pipeline.
Currently, these processors are the vertex, tessellation control,
tessellation evaluation, geometry, fragment, and compute processors.</p>
</div>
<div class="paragraph">
<p>Unless otherwise noted in this paper, a language feature applies to all
languages, and common usage will refer to these languages as a single
language.
The specific languages will be referred to by the name of the processor they
target: vertex, tessellation control, tessellation evaluation, geometry,
fragment, or compute.</p>
</div>
<div class="paragraph">
<p>Most API state is not tracked or made available to shaders.
Typically, user-defined variables will be used for communicating between
different stages of the API pipeline.
However, a small amount of state is still tracked and automatically made
available to shaders, and there are a few built-in variables for interfaces
between different stages of the API pipeline.</p>
</div>
<div class="sect2">
<h3 id="vertex-processor">2.1. Vertex Processor</h3>
<div class="paragraph">
<p>The <em>vertex processor</em> is a programmable unit that operates on incoming
vertices and their associated data.
Compilation units written in the OpenGL Shading Language to run on this processor are called
<em>vertex shaders</em>.
When a set of vertex shaders are successfully compiled and linked, they
result in a <em>vertex shader executable</em> that runs on the vertex processor.</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 Shading Language to run on this processor are called
tessellation control shaders.
When a set of tessellation control shaders are successfully compiled and
linked, they result in a <em>tessellation control shader executable</em> that runs
on the tessellation control processor.</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
32-bit component
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 Shading Language to run on this processor are called
tessellation evaluation shaders.
When a set of tessellation evaluation shaders are successfully compiled and
linked, they result in a <em>tessellation evaluation shader executable</em> that
runs on the tessellation evaluation processor.</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 Shading Language to run on this processor are called
<em>geometry shaders</em>.
When a set of geometry shaders are successfully compiled and linked, they
result in a <em>geometry shader executable</em> that runs on the geometry
processor.</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 Shading Language to run on this processor are called
<em>fragment shaders</em>.
When a set of fragment shaders are successfully compiled and linked, they
result in a <em>fragment shader executable</em> that runs on the fragment
processor.</p>
</div>
<div class="paragraph">
<p>A fragment shader cannot change a fragment&#8217;s (<em>x</em>, <em>y</em>) position.
Access to neighboring fragments is not allowed.
The values computed by the fragment shader are ultimately used to update
framebuffer memory or texture memory, depending on the current API
state and the API command that caused the fragments to be generated.</p>
</div>
</div>
<div class="sect2">
<h3 id="compute-processor">2.6. Compute Processor</h3>
<div class="paragraph">
<p>The <em>compute processor</em> is a programmable unit that operates independently
from the other shader processors.
Compilation units written in the OpenGL Shading Language to run on this processor are called
<em>compute shaders</em>.
When a set of compute shaders are successfully compiled and linked, they
result in a <em>compute shader executable</em> that runs on the compute processor.</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 and Phases of Compilation</h3>
<div class="paragraph">
<p>The source character set used for the OpenGL Shading Language is Unicode in the UTF-8
encoding scheme.</p>
</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>&lt;</strong> and <strong>&gt;</strong>), square brackets
(<strong>[</strong> and <strong>]</strong>), parentheses (<strong>(</strong> and <strong>)</strong>), braces (<strong>{</strong> and <strong>}</strong>), caret
(<strong>^</strong>), vertical bar (<strong>|</strong>), ampersand (<strong>&amp;</strong>), tilde (<strong>~</strong>), equals (<strong>=</strong>),
exclamation point (<strong>!</strong>), colon (<strong>:</strong>), semicolon (<strong>;</strong>), comma (<strong>,</strong>), and
question mark (<strong>?</strong>).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A compile-time error will be given if any other character is used in a GLSL
token.</p>
</div>
<div class="paragraph">
<p>There are no digraphs or trigraphs.
There are no escape sequences or other uses of the backslash beyond use as
the line-continuation character.</p>
</div>
<div class="paragraph">
<p>Lines are relevant for compiler diagnostic messages and the preprocessor.
They are terminated by carriage-return or line-feed.
If both are used together, it will count as only a single line termination.
For the remainder of this document, any of these combinations is simply
referred to as a new-line.
Lines may be of arbitrary length.</p>
</div>
<div class="paragraph">
<p>In general, the language&#8217;s use of this character set is case sensitive.</p>
</div>
<div class="paragraph">
<p>There are no character or string data types, so no quoting characters are
included.</p>
</div>
<div class="paragraph">
<p>There is no end-of-file character.</p>
</div>
<div class="paragraph">
<p>More formally, compilation happens as if the following logical phases were
executed in order:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Source strings are concatenated to form a single input.
All provided new-lines are retained.</p>
</li>
<li>
<p>Line numbering is noted, based on all present new-lines, and does not
change when new-lines are later eliminated.</p>
</li>
<li>
<p>Wherever a backslash ('\') occurs immediately before a new-line, both
are eliminated.
(Note no white space is substituted, allowing a single token to span a
new-line.) Any newly formed backslash followed by a new-line is not
eliminated; only those pairs originally occurring after phase 1 are
eliminated.</p>
</li>
<li>
<p>All comments are replaced with a single space.
(Note that '//' style comments end before their terminating new-lines
and white space is generally relevant to preprocessing.)</p>
</li>
<li>
<p>Preprocessing is done, resulting in a sequence of GLSL tokens, formed
from the character set stated above.</p>
</li>
<li>
<p>GLSL processing is done on the sequence of GLSL tokens.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Details that fully define source strings, comments, line numbering, new-line
elimination, and preprocessing are all discussed in upcoming sections.
Sections beyond those describe GLSL processing.</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.
Multiple shaders can be linked together to form a single program.</p>
</div>
<div class="paragraph">
<p>Diagnostic messages returned from compiling a shader must identify both the
line number within a string and which source string the message applies to.
Source strings are counted sequentially with the first string being string
0.
Line numbers are one more than the number of new-lines that have been
processed, including counting the new-lines that will be removed by the
line-continuation character (<strong>\</strong>).</p>
</div>
<div class="paragraph">
<p>Lines separated by the line-continuation character preceding a new-line are
concatenated together before either comment processing or preprocessing.
This means that no white space is substituted for the line-continuation
character.
That is, a single token could be formed by the concatenation by taking the
characters at the end of one line concatenating them with the characters at
the beginning of the next line.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="predefined-type">float</span> f\
oo;
<span class="comment">// forms a single line equivalent to &quot;float foo;&quot;</span>
<span class="comment">// (assuming '\' is the last character before the new-line and &quot;oo&quot; are</span>
<span class="comment">// the first two characters of the next line)</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="preprocessor">3.3. Preprocessor</h3>
<div class="paragraph">
<p>There is a preprocessor that processes the source strings as part of the
compilation process.
Except as noted below, it behaves as the C++ standard preprocessor (see
&#8220;<a href="#references">Normative References</a>&#8221;).</p>
</div>
<div class="paragraph">
<p>The complete list of preprocessor directives is as follows.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>#<br>
#define<br>
#undef<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#if<br>
#ifdef<br>
#ifndef<br>
#else<br>
#elif<br>
#endif<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#error<br>
#pragma<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#extension<br>
#version<br></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p>#line</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The following
operators are
also available:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>defined<br>
##</p>
</dd>
</dl>
</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.
Preprocessing takes places after new-lines have been removed by the
line-continuation character.</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 a compile-time 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></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 Shading Language.
The version of the shading language described in this document will have
__VERSION__ substitute the decimal integer 460.</p>
</div>
<div class="paragraph">
<p>By convention, all macro names containing two consecutive underscores (__)
are reserved for use by underlying software layers.
Defining
or undefining
such a name in a shader does not itself result in an error, but may
result in unintended behaviors that stem from having multiple definitions of
the same name.
All macro names prefixed with &#8220;GL_&#8221; (&#8220;GL&#8221; followed by a single
underscore) are also reserved, and defining
or undefining
such a name results in a compile-time error.</p>
</div>
<div class="paragraph">
<p>Implementations must support macro-name lengths of up to 1024 characters.
Implementations are allowed to generate an error for a macro name of length
greater than 1024 characters, but are also allowed to support lengths
greater than 1024.</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
further restricted to
expressions operating on literal integer constants, plus identifiers
consumed by the <strong>defined</strong> operator.</p>
</li>
<li>
<p>Character constants are not supported.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The operators available are as follows.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Precedence</th>
<th class="tableblock halign-left valign-top">Operator class</th>
<th class="tableblock halign-left valign-top">Operators</th>
<th class="tableblock halign-left valign-top">Associativity</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1 (highest)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">parenthetical grouping</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">( )</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NA</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">unary</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">defined<br>
+ - ~ !</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Right to Left</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">multiplicative</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">* / %</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">additive</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">+ -</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise shift</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;&lt; &gt;&gt;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">relational</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; &gt; &lt;= &gt;=</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">equality</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">== !=</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise and</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&amp;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise exclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">^</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">bit-wise inclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">|</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">logical and</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&amp;&amp;</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">12 (lowest)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">logical inclusive or</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">||</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Left to Right</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The <strong>defined</strong> operator can be used in either of the following ways:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++">defined identifier
defined ( identifier )</code></pre>
</div>
</div>
<div class="paragraph">
<p>Two tokens in a macro can be concatenated into one token using the token
pasting (<strong>##</strong>) operator, as is standard for C++ preprocessors.
The result must be a valid single token, which will then be subject to macro
expansion.
That is, macro expansion happens only after token pasting.
There are no other number sign based operators (e.g. no <strong>#</strong> or <strong>#@</strong>), nor is
there a <strong>sizeof</strong> operator.</p>
</div>
<div class="paragraph">
<p>The semantics of applying operators to integer literals in the preprocessor
match those standard in the C++ preprocessor, not those in the OpenGL Shading Language.</p>
</div>
<div class="paragraph">
<p>Preprocessor expressions will be evaluated according to the behavior of the
host processor, not the processor targeted by the shader.</p>
</div>
<div class="paragraph">
<p><strong>#error</strong> will cause the implementation to put a compile-time diagnostic message
into the shader object&#8217;s information log (see section 7.12 &#8220;Shader, Program
and Program Pipeline Queries&#8221; of the <a href="#references">OpenGL Specification</a> for how to
access a shader object&#8217;s information log).
The message will be the tokens following the <strong>#error</strong> directive, up to the
first new-line.
The implementation must treat the presence of a <strong>#error</strong> directive as a
compile-time error.</p>
</div>
<div class="paragraph">
<p><strong>#pragma</strong> allows implementation-dependent compiler control.
Tokens following <strong>#pragma</strong> are not subject to preprocessor macro expansion.
If an implementation does not recognize the tokens following <strong>#pragma</strong>, then
it will ignore that pragma.
The following pragmas are defined as part of the language.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> STDGL</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <strong>STDGL</strong> pragma is used to reserve pragmas for use by future revisions of
this language.
No implementation may use a pragma whose first token is <strong>STDGL</strong>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> optimize(on)
<span class="preprocessor">#pragma</span> optimize(off)</code></pre>
</div>
</div>
<div class="paragraph">
<p>can be used to turn off optimizations as an aid in developing and debugging
shaders.
It can only be used outside function definitions.
By default, optimization is turned on for all shaders.
The debug pragma</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#pragma</span> debug(on)
<span class="preprocessor">#pragma</span> debug(off)</code></pre>
</div>
</div>
<div class="paragraph">
<p>can be used to enable compiling and annotating a shader with debug
information, so that it can be used with a debugger.
It can only be used outside function definitions.
By default, debug is turned off.</p>
</div>
<div class="paragraph">
<p>Shaders should declare the version of the language they are written to.
The language version a shader is written to is specified by</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#version</span> number profile_opt</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <em>number</em> must be a version of the language, following the same
convention as __VERSION__ above.
The directive &#8220;<strong>#version 460</strong>&#8221; is required in any shader that
uses version 4.60 of the language.
Any <em>number</em> representing a version of the language a compiler does not
support will cause a compile-time error to be generated.
Version 1.10 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.10.
Shaders that specify <strong>#version</strong> 100 will be treated as targeting version
1.00 of the OpenGL ES Shading Language.
Shaders that specify <strong>#version</strong> 300 will be treated as targeting version
3.00 of the OpenGL ES Shading Language.
Shaders that specify <strong>#version</strong> 310 will be treated as targeting version
3.10 of the OpenGL ES Shading Language.</p>
</div>
<div class="paragraph">
<p>If the optional <em>profile</em> argument is provided, it must be the name of an
OpenGL profile.
Currently, there are three choices:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++">core
compatibility
es</code></pre>
</div>
</div>
<div class="paragraph">
<p>A <em>profile</em> argument can only be used with version 150 or greater.
If no profile argument is provided and the version is 150 or greater, the
default is <strong>core</strong>.
If version 300 or 310 is specified, the profile argument is not optional and
must be <strong>es</strong>, or a compile-time error results.
The Language Specification for the <strong>es</strong> profile is specified in The OpenGL
ES Shading Language specification.</p>
</div>
<div class="paragraph">
<p>Shaders for the <strong>core</strong> or <strong>compatibility</strong> profiles that declare different
versions can be linked together.
However, <strong>es</strong> profile shaders cannot be linked with non-<strong>es</strong> profile shaders
or with <strong>es</strong> profile shaders of a different version, or a link-time error
will result.
When linking shaders of versions allowed by these rules, remaining link-time
errors will be given as per the linking rules in the GLSL version
corresponding to the version of the context the shaders are linked under.
Shader compile-time errors must still be given strictly based on the version
declared (or defaulted to) within each shader.</p>
</div>
<div class="paragraph">
<p>Unless otherwise specified, this specification is documenting the core
profile, and everything specified for the core profile is also available in
the compatibility profile.
Features specified as belonging specifically to the compatibility profile
are not available in the core profile.
Compatibility-profile features are not available when generating SPIR-V.</p>
</div>
<div class="paragraph">
<p>There is a built-in macro definition for each profile the implementation
supports.
All implementations provide the following macro:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> GL_core_profile <span class="integer">1</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Implementations providing the <strong>compatibility</strong> profile provide the following
macro:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> GL_compatibility_profile <span class="integer">1</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Implementations providing the <strong>es</strong> profile provide the following macro:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> GL_es_profile <span class="integer">1</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The <strong>#version</strong> directive must occur in a shader before anything else, except
for comments and white space.</p>
</div>
<div class="paragraph">
<p>By default, compilers of this language must issue compile-time
lexical
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 a compile-time 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><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
constant integer expressions.
If these constant expressions are not integer literals then behavior is undefined.
After processing this directive (including its new-line), the implementation
will behave as if it is compiling at line number <em>line</em> and source string
number <em>source-string-number</em>.
Subsequent source strings will be numbered sequentially, until another
<strong>#line</strong> directive overrides that numbering.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="title">Note</div>
<div class="paragraph">
<p>Some implementations have allowed constant expressions in #line directives and
some have not. Even where expressions are supported the grammar is ambiguous and so
results are implementation dependent. For example,
+ #line +2 +2 // Line number set to 4, or file to 2 and line to 2</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>When shaders are compiled for OpenGL SPIR-V, the following predefined
macro is available:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> GL_SPIRV <span class="integer">100</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>When targeting Vulkan, the following predefined macro is available:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="preprocessor">#define</span> VULKAN <span class="integer">100</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="comments">3.4. Comments</h3>
<div class="paragraph">
<p>Comments are delimited by <strong>/*</strong> and <strong>*/</strong>, or by <strong>//</strong> and a new-line.
The begin comment delimiters (/* or //) are not recognized as comment
delimiters inside of a comment, hence comments cannot be nested.
A <strong>/*</strong> comment includes its terminating delimiter (*/).
However, a <strong>//</strong> comment does not include (or eliminate) its terminating new
line.</p>
</div>
<div class="paragraph">
<p>Inside comments, any byte values may be used, except a byte whose value is
0.
No errors will be given for the content of comments and no validation on the
content of comments need be done.</p>
</div>
<div class="paragraph">
<p>Removal of new-lines by the line-continuation character (<strong>\</strong>) logically
occurs before comments are processed.
That is, a single-line comment ending in the line-continuation character
(<strong>\</strong>) includes the next line in the comment.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c++"><span class="comment">// a single-line comment containing the next line \
a = b; // this is still in the first comment</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="tokens">3.5. 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.6. 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 a compile-time 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>
<strong>attribute</strong> <strong>varying</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>
<strong>noperspective</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>subroutine</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>
<strong>double</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>dvec2</strong> <strong>dvec3</strong> <strong>dvec4</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>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>lowp</strong> <strong>mediump</strong> <strong>highp</strong> <strong>precision</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>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>sampler2DRect</strong> <strong>sampler2DRectShadow</strong> <strong>isampler2DRect</strong> <strong>usampler2DRect</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>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>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>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>
<dt class="hdlist1"></dt>
<dd>
<p><strong>image3D</strong> <strong>iimage3D</strong> <strong>uimage3D</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageCube</strong> <strong>iimageCube</strong> <strong>uimageCube</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageCubeArray</strong> <strong>iimageCubeArray</strong> <strong>uimageCubeArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>imageBuffer</strong> <strong>iimageBuffer</strong> <strong>uimageBuffer</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>struct</strong></p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>In addition, when targeting Vulkan, the following keywords also exist:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture1D</strong> <strong>texture1DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>itexture1D</strong> <strong>itexture1DArray</strong> <strong>utexture1D</strong> <strong>utexture1DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2D</strong> <strong>texture2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>itexture2D</strong> <strong>itexture2DArray</strong> <strong>utexture2D</strong> <strong>utexture2DArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2DRect</strong> <strong>itexture2DRect</strong> <strong>utexture2DRect</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2DMS</strong> <strong>itexture2DMS</strong> <strong>utexture2DMS</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture2DMSArray</strong> <strong>itexture2DMSArray</strong> <strong>utexture2DMSArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>texture3D</strong> <strong>itexture3D</strong> <strong>utexture3D</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>textureCube</strong> <strong>itextureCube</strong> <strong>utextureCube</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>textureCubeArray</strong> <strong>itextureCubeArray</strong> <strong>utextureCubeArray</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>textureBuffer</strong> <strong>itextureBuffer</strong> <strong>utextureBuffer</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>sampler</strong> <strong>samplerShadow</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>subpassInput</strong> <strong>isubpassInput</strong> <strong>usubpassInput</strong></p>
</dd>
<dt class="hdlist1"></dt>
<dd>
<p><strong>subpassInputMS</strong> <strong>isubpassInputMS</strong> <strong>usubpassInputMS</strong></p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The following are the keywords reserved for future use.
Using them will result in a compile-time error:</p>
</div>
<div class="dlist">
<dl>
<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></p>
</dd>