diff options
author | Chad Versace <chadversary@chromium.org> | 2017-03-06 11:12:41 -0800 |
---|---|---|
committer | Chad Versace <chadversary@chromium.org> | 2017-03-06 11:21:23 -0800 |
commit | 7b3444054145da63a6471d72509538d27d9b0734 (patch) | |
tree | 044ad764d2b87539f6ff2e3a89c2f3072f5fa1ab | |
parent | b4609e747bd46a70b9714992f898b4f1c3a306ea (diff) | |
download | vulkan-spec-7b3444054145da63a6471d72509538d27d9b0734.zip vulkan-spec-7b3444054145da63a6471d72509538d27d9b0734.tar.xz |
Update branches/wip/1.0-VK_MESAX_external
Built from commit eb5f501b9547fc823a16d28955816a6e727a11c5
of 'refs/heads/wip/1.0-VK_MESAX_external'.
89 files changed, 128836 insertions, 0 deletions
diff --git a/branches/wip/1.0-VK_MESAX_external/1.0-extensions/html/vkspec.html b/branches/wip/1.0-VK_MESAX_external/1.0-extensions/html/vkspec.html new file mode 100644 index 0000000..8ec4da9 --- /dev/null +++ b/branches/wip/1.0-VK_MESAX_external/1.0-extensions/html/vkspec.html @@ -0,0 +1,106584 @@ +<!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.5"> +<meta name="author" content="The Khronos Vulkan Working Group"> +<title>Vulkan® 1.0.42 - A Specification (with all published extensions)</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 */ +/* Remove comment around @import statement below when using as a 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} +[hidden],template{display:none} +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} +input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box} +input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none} +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} +.spread{width:100%} +p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6} +.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,ul.no-bullet,ol.no-bullet{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} +ul.no-bullet{list-style:none} +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 only 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;font-weight:bold} +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,.menu{color:rgba(0,0,0,.8)} +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 only 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 only 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} +.sect1{padding-bottom:.625em} +@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}} +.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>caption.title{white-space:nowrap;overflow:visible;max-width:0} +.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)} +table.tableblock #preamble>.sectionbody>.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 only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}} +@media only 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 1em} +.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 0 1.25em 0;display:block} +.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0} +.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none} +table.tableblock{max-width:100%;border-collapse:separate} +table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0} +table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} +table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0} +table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0} +table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0} +table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0} +table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0} +table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0} +table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0} +table.frame-all{border-width:1px} +table.frame-sides{border-width:0 1px} +table.frame-topbot{border-width:1px 0} +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.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none} +ul.unstyled,ol.unnumbered,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:1em;font-size:.85em} +ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px} +ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden} +ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block} +ul.inline>li>*{display:block} +.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>table tr>td:first-of-type{padding:0 .75em;line-height:1} +.colist>table tr>td:last-of-type{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 0;border-width:1px 0 0 0} +#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em} +#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none} +#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} +.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} +@media print{@page{margin:1.25cm .75cm} +*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} +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} +.sect1{padding-bottom:0!important} +.sect1+.sect1{border:0!important} +#header>h1:first-child{margin-top:1.25rem} +body.book #header{text-align:center} +body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0} +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{background:none!important;padding:0 .9375em} +#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em} +.hide-on-print{display:none!important} +.print-only{display:block!important} +.hide-for-print{display:none!important} +.show-for-print{display:inherit!important}} +</style> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/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>Vulkan<sup>®</sup> 1.0.42 - A Specification (with all published extensions)</h1> +<div class="details"> +<span id="author" class="author">The Khronos Vulkan Working Group</span><br> +<span id="revnumber">version 1.0.42,</span> +<span id="revdate">Mon, 06 Mar 2017 19:08:08 +0000</span> +<br><span id="revremark">from git branch: wip/1.0-VK_MESAX_external commit: eb5f501b9547fc823a16d28955816a6e727a11c5</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="#introduction-whatis">1.1. What is the Vulkan Graphics System?</a></li> +<li><a href="#introduction-bugs">1.2. Filing Bug Reports</a></li> +<li><a href="#introduction-terminology">1.3. Terminology</a></li> +<li><a href="#introduction-normative">1.4. Normative References</a></li> +</ul> +</li> +<li><a href="#fundamentals">2. Fundamentals</a> +<ul class="sectlevel2"> +<li><a href="#fundamentals-architecture-model">2.1. Architecture Model</a></li> +<li><a href="#fundamentals-execmodel">2.2. Execution Model</a></li> +<li><a href="#fundamentals-objectmodel-overview">2.3. Object Model</a></li> +<li><a href="#fundamentals-commandsyntax">2.4. Command Syntax and Duration</a></li> +<li><a href="#fundamentals-threadingbehavior">2.5. Threading Behavior</a></li> +<li><a href="#fundamentals-errors">2.6. Errors</a></li> +<li><a href="#fundamentals-numerics">2.7. Numeric Representation and Computation</a></li> +<li><a href="#fundamentals-fixedconv">2.8. Fixed-Point Data Conversions</a></li> +<li><a href="#fundamentals-versionnum">2.9. API Version Numbers and Semantics</a></li> +<li><a href="#fundamentals-common-objects">2.10. Common Object Types</a></li> +</ul> +</li> +<li><a href="#initialization">3. Initialization</a> +<ul class="sectlevel2"> +<li><a href="#initialization-functionpointers">3.1. Command Function Pointers</a></li> +<li><a href="#initialization-instances">3.2. Instances</a></li> +</ul> +</li> +<li><a href="#devsandqueues">4. Devices and Queues</a> +<ul class="sectlevel2"> +<li><a href="#devsandqueues-physical-device-enumeration">4.1. Physical Devices</a></li> +<li><a href="#devsandqueues-devices">4.2. Devices</a></li> +<li><a href="#devsandqueues-queues">4.3. Queues</a></li> +</ul> +</li> +<li><a href="#commandbuffers">5. Command Buffers</a> +<ul class="sectlevel2"> +<li><a href="#commandbuffers-pools">5.1. Command Pools</a></li> +<li><a href="#commandbuffer-allocation">5.2. Command Buffer Allocation and Management</a></li> +<li><a href="#commandbuffers-recording">5.3. Command Buffer Recording</a></li> +<li><a href="#commandbuffers-submission">5.4. Command Buffer Submission</a></li> +<li><a href="#commandbuffers-submission-progress">5.5. Queue Forward Progress</a></li> +<li><a href="#commandbuffers-secondary">5.6. Secondary Command Buffer Execution</a></li> +<li><a href="#commandbuffers-devicemask">5.7. Command Buffer Device Mask</a></li> +</ul> +</li> +<li><a href="#synchronization">6. Synchronization and Cache Control</a> +<ul class="sectlevel2"> +<li><a href="#synchronization-dependencies">6.1. Execution and Memory Dependencies</a></li> +<li><a href="#synchronization-implicit">6.2. Implicit Synchronization Guarantees</a></li> +<li><a href="#synchronization-fences">6.3. Fences</a></li> +<li><a href="#synchronization-semaphores">6.4. Semaphores</a></li> +<li><a href="#synchronization-events">6.5. Events</a></li> +<li><a href="#synchronization-pipeline-barriers">6.6. Pipeline Barriers</a></li> +<li><a href="#synchronization-memory-barriers">6.7. Memory Barriers</a></li> +<li><a href="#synchronization-wait-idle">6.8. Wait Idle Operations</a></li> +<li><a href="#synchronization-submission-host-writes">6.9. Host Write Ordering Guarantees</a></li> +<li><a href="#synchronization-device-group">6.10. Synchronization and Multiple Physical Devices</a></li> +</ul> +</li> +<li><a href="#renderpass">7. Render Pass</a> +<ul class="sectlevel2"> +<li><a href="#renderpass-creation">7.1. Render Pass Creation</a></li> +<li><a href="#renderpass-compatibility">7.2. Render Pass Compatibility</a></li> +<li><a href="#_framebuffers">7.3. Framebuffers</a></li> +<li><a href="#renderpass-commands">7.4. Render Pass Commands</a></li> +</ul> +</li> +<li><a href="#shaders">8. Shaders</a> +<ul class="sectlevel2"> +<li><a href="#shader-modules">8.1. Shader Modules</a></li> +<li><a href="#shaders-execution">8.2. Shader Execution</a></li> +<li><a href="#shaders-execution-memory-ordering">8.3. Shader Memory Access Ordering</a></li> +<li><a href="#shaders-inputs">8.4. Shader Inputs and Outputs</a></li> +<li><a href="#shaders-vertex">8.5. Vertex Shaders</a></li> +<li><a href="#shaders-tessellation-control">8.6. Tessellation Control Shaders</a></li> +<li><a href="#shaders-tessellation-evaluation">8.7. Tessellation Evaluation Shaders</a></li> +<li><a href="#shaders-geometry">8.8. Geometry Shaders</a></li> +<li><a href="#shaders-fragment">8.9. Fragment Shaders</a></li> +<li><a href="#shaders-compute">8.10. Compute Shaders</a></li> +<li><a href="#shaders-interpolation-decorations">8.11. Interpolation Decorations</a></li> +<li><a href="#shaders-staticuse">8.12. Static Use</a></li> +<li><a href="#shaders-invocationgroups">8.13. Invocation and Derivative Groups</a></li> +</ul> +</li> +<li><a href="#pipelines">9. Pipelines</a> +<ul class="sectlevel2"> +<li><a href="#pipelines-compute">9.1. Compute Pipelines</a></li> +<li><a href="#pipelines-graphics">9.2. Graphics Pipelines</a></li> +<li><a href="#pipelines-destruction">9.3. Pipeline destruction</a></li> +<li><a href="#pipelines-multiple">9.4. Multiple Pipeline Creation</a></li> +<li><a href="#pipelines-pipeline-derivatives">9.5. Pipeline Derivatives</a></li> +<li><a href="#pipelines-cache">9.6. Pipeline Cache</a></li> +<li><a href="#pipelines-specialization-constants">9.7. Specialization Constants</a></li> +<li><a href="#pipelines-binding">9.8. Pipeline Binding</a></li> +</ul> +</li> +<li><a href="#memory">10. Memory Allocation</a> +<ul class="sectlevel2"> +<li><a href="#memory-host">10.1. Host Memory</a></li> +<li><a href="#memory-device">10.2. Device Memory</a></li> +</ul> +</li> +<li><a href="#resources">11. Resource Creation</a> +<ul class="sectlevel2"> +<li><a href="#resources-buffers">11.1. Buffers</a></li> +<li><a href="#resources-buffer-views">11.2. Buffer Views</a></li> +<li><a href="#resources-images">11.3. Images</a></li> +<li><a href="#resources-image-layouts">11.4. Image Layouts</a></li> +<li><a href="#resources-image-views">11.5. Image Views</a></li> +<li><a href="#resources-association">11.6. Resource Memory Association</a></li> +<li><a href="#resources-sharing">11.7. Resource Sharing Mode</a></li> +<li><a href="#resources-memory-aliasing">11.8. Memory Aliasing</a></li> +</ul> +</li> +<li><a href="#samplers">12. Samplers</a></li> +<li><a href="#descriptorsets">13. Resource Descriptors</a> +<ul class="sectlevel2"> +<li><a href="#descriptorsets-types">13.1. Descriptor Types</a></li> +<li><a href="#descriptorsets-sets">13.2. Descriptor Sets</a></li> +</ul> +</li> +<li><a href="#interfaces">14. Shader Interfaces</a> +<ul class="sectlevel2"> +<li><a href="#interfaces-iointerfaces">14.1. Shader Input and Output Interfaces</a></li> +<li><a href="#interfaces-vertexinput">14.2. Vertex Input Interface</a></li> +<li><a href="#interfaces-fragmentoutput">14.3. Fragment Output Interface</a></li> +<li><a href="#interfaces-inputattachment">14.4. Fragment Input Attachment Interface</a></li> +<li><a href="#interfaces-resources">14.5. Shader Resource Interface</a></li> +<li><a href="#interfaces-builtin-variables">14.6. Built-In Variables</a></li> +</ul> +</li> +<li><a href="#textures">15. Image Operations</a> +<ul class="sectlevel2"> +<li><a href="#_image_operations_overview">15.1. Image Operations Overview</a></li> +<li><a href="#_conversion_formulas">15.2. Conversion Formulas</a></li> +<li><a href="#_texel_input_operations">15.3. Texel Input Operations</a></li> +<li><a href="#_texel_output_operations">15.4. Texel Output Operations</a></li> +<li><a href="#_derivative_operations">15.5. Derivative Operations</a></li> +<li><a href="#textures-normalized-operations">15.6. Normalized Texel Coordinate Operations</a></li> +<li><a href="#_unnormalized_texel_coordinate_operations">15.7. Unnormalized Texel Coordinate Operations</a></li> +<li><a href="#textures-sample-operations">15.8. Image Sample Operations</a></li> +<li><a href="#textures-instructions">15.9. Image Operation Steps</a></li> +</ul> +</li> +<li><a href="#queries">16. Queries</a> +<ul class="sectlevel2"> +<li><a href="#queries-pools">16.1. Query Pools</a></li> +<li><a href="#queries-operation">16.2. Query Operation</a></li> +<li><a href="#queries-occlusion">16.3. Occlusion Queries</a></li> +<li><a href="#queries-pipestats">16.4. Pipeline Statistics Queries</a></li> +<li><a href="#queries-timestamps">16.5. Timestamp Queries</a></li> +</ul> +</li> +<li><a href="#clears">17. Clear Commands</a> +<ul class="sectlevel2"> +<li><a href="#clears-outside">17.1. Clearing Images Outside A Render Pass Instance</a></li> +<li><a href="#clears-inside">17.2. Clearing Images Inside A Render Pass Instance</a></li> +<li><a href="#clears-values">17.3. Clear Values</a></li> +<li><a href="#clears-filling-buffers">17.4. Filling Buffers</a></li> +<li><a href="#clears-updating-buffers">17.5. Updating Buffers</a></li> +</ul> +</li> +<li><a href="#copies">18. Copy Commands</a> +<ul class="sectlevel2"> +<li><a href="#_common_operation">18.1. Common Operation</a></li> +<li><a href="#copies-buffers">18.2. Copying Data Between Buffers</a></li> +<li><a href="#copies-images">18.3. Copying Data Between Images</a></li> +<li><a href="#copies-buffers-images">18.4. Copying Data Between Buffers and Images</a></li> +<li><a href="#copies-imagescaling">18.5. Image Copies with Scaling</a></li> +<li><a href="#copies-resolve">18.6. Resolving Multisample Images</a></li> +</ul> +</li> +<li><a href="#drawing">19. Drawing Commands</a> +<ul class="sectlevel2"> +<li><a href="#drawing-primitive-topologies">19.1. Primitive Topologies</a></li> +<li><a href="#drawing-primitive-order">19.2. Primitive Order</a></li> +<li><a href="#_programmable_primitive_shading">19.3. Programmable Primitive Shading</a></li> +</ul> +</li> +<li><a href="#fxvertex">20. Fixed-Function Vertex Processing</a> +<ul class="sectlevel2"> +<li><a href="#fxvertex-attrib">20.1. Vertex Attributes</a></li> +<li><a href="#fxvertex-input">20.2. Vertex Input Description</a></li> +<li><a href="#fxvertex-example">20.3. Example</a></li> +</ul> +</li> +<li><a href="#tessellation">21. Tessellation</a> +<ul class="sectlevel2"> +<li><a href="#_tessellator">21.1. Tessellator</a></li> +<li><a href="#_tessellator_patch_discard">21.2. Tessellator Patch Discard</a></li> +<li><a href="#tessellation-tessellator-spacing">21.3. Tessellator Spacing</a></li> +<li><a href="#tessellation-primitive-order">21.4. Tessellation Primitive Ordering</a></li> +<li><a href="#tessellation-triangle-tessellation">21.5. Triangle Tessellation</a></li> +<li><a href="#tessellation-quad-tessellation">21.6. Quad Tessellation</a></li> +<li><a href="#tessellation-isoline-tessellation">21.7. Isoline Tessellation</a></li> +<li><a href="#_tessellation_pipeline_state">21.8. Tessellation Pipeline State</a></li> +</ul> +</li> +<li><a href="#geometry">22. Geometry Shading</a> +<ul class="sectlevel2"> +<li><a href="#geometry-input">22.1. Geometry Shader Input Primitives</a></li> +<li><a href="#geometry-output">22.2. Geometry Shader Output Primitives</a></li> +<li><a href="#geometry-invocations">22.3. Multiple Invocations of Geometry Shaders</a></li> +<li><a href="#geometry-ordering">22.4. Geometry Shader Primitive Ordering</a></li> +<li><a href="#geometry-passthrough">22.5. Geometry Shader Passthrough</a></li> +</ul> +</li> +<li><a href="#vertexpostproc">23. Fixed-Function Vertex Post-Processing</a> +<ul class="sectlevel2"> +<li><a href="#vertexpostproc-viewport-swizzle">23.1. Viewport Swizzle</a></li> +<li><a href="#vertexpostproc-flatshading">23.2. Flat Shading</a></li> +<li><a href="#vertexpostproc-clipping">23.3. Primitive Clipping</a></li> +<li><a href="#vertexpostproc-clipping-shader-outputs">23.4. Clipping Shader Outputs</a></li> +<li><a href="#vertexpostproc-viewportwscaling">23.5. Controlling Viewport W Scaling</a></li> +<li><a href="#vertexpostproc-coord-transform">23.6. Coordinate Transformations</a></li> +<li><a href="#vertexpostproc-viewport">23.7. Controlling the Viewport</a></li> +</ul> +</li> +<li><a href="#primsrast">24. Rasterization</a> +<ul class="sectlevel2"> +<li><a href="#primsrast-discard">24.1. Discarding Primitives Before Rasterization</a></li> +<li><a href="#primrast-order">24.2. Rasterization Order</a></li> +<li><a href="#primsrast-multisampling">24.3. Multisampling</a></li> +<li><a href="#primsrast-sampleshading">24.4. Sample Shading</a></li> +<li><a href="#primsrast-points">24.5. Points</a></li> +<li><a href="#primsrast-lines">24.6. Line Segments</a></li> +<li><a href="#primsrast-polygons">24.7. Polygons</a></li> +</ul> +</li> +<li><a href="#fragops">25. Fragment Operations</a> +<ul class="sectlevel2"> +<li><a href="#fragops-early">25.1. Early Per-Fragment Tests</a></li> +<li><a href="#fragops-discard-rectangles">25.2. Discard Rectangles Test</a></li> +<li><a href="#fragops-scissor">25.3. Scissor Test</a></li> +<li><a href="#fragops-samplemask">25.4. Sample Mask</a></li> +<li><a href="#fragops-early-mode">25.5. Early Fragment Test Mode</a></li> +<li><a href="#fragops-late">25.6. Late Per-Fragment Tests</a></li> +<li><a href="#fragops-covg">25.7. Multisample Coverage</a></li> +<li><a href="#fragops-ds-state">25.8. Depth and Stencil Operations</a></li> +<li><a href="#fragops-dbt">25.9. Depth Bounds Test</a></li> +<li><a href="#fragops-stencil">25.10. Stencil Test</a></li> +<li><a href="#fragops-depth">25.11. Depth Test</a></li> +<li><a href="#fragops-samplecount">25.12. Sample Counting</a></li> +</ul> +</li> +<li><a href="#framebuffer">26. The Framebuffer</a> +<ul class="sectlevel2"> +<li><a href="#framebuffer-blending">26.1. Blending</a></li> +<li><a href="#framebuffer-logicop">26.2. Logical Operations</a></li> +</ul> +</li> +<li><a href="#dispatch">27. Dispatching Commands</a></li> +<li><a href="#device-generated-commands">28. Device-Generated Commands</a> +<ul class="sectlevel2"> +<li><a href="#_features_and_limitations">28.1. Features and Limitations</a></li> +<li><a href="#_binding_object_table">28.2. Binding Object Table</a></li> +<li><a href="#indirectmdslayout">28.3. Indirect Commands Layout</a></li> +<li><a href="#_indirect_commands_generation">28.4. Indirect Commands Generation</a></li> +</ul> +</li> +<li><a href="#sparsememory">29. Sparse Resources</a> +<ul class="sectlevel2"> +<li><a href="#sparsememory-sparseresourcefeatures">29.1. Sparse Resource Features</a></li> +<li><a href="#sparsememory-fully-resident">29.2. Sparse Buffers and Fully-Resident Images</a></li> +<li><a href="#sparsememory-partially-resident-buffers">29.3. Sparse Partially-Resident Buffers</a></li> +<li><a href="#sparsememory-partially-resident-images">29.4. Sparse Partially-Resident Images</a></li> +<li><a href="#sparsememory-sparse-memory-aliasing">29.5. Sparse Memory Aliasing</a></li> +<li><a href="#_sparse_resource_implementation_guidelines">29.6. Sparse Resource Implementation Guidelines</a></li> +<li><a href="#sparsememory-resourceapi">29.7. Sparse Resource API</a></li> +<li><a href="#sparsememory-examples">29.8. Examples</a></li> +</ul> +</li> +<li><a href="#wsi">30. Window System Integration (WSI)</a> +<ul class="sectlevel2"> +<li><a href="#_wsi_platform">30.1. WSI Platform</a></li> +<li><a href="#_wsi_surface">30.2. WSI Surface</a></li> +<li><a href="#display">30.3. Presenting Directly to Display Devices</a></li> +<li><a href="#_querying_for_wsi_support">30.4. Querying for WSI Support</a></li> +<li><a href="#_surface_queries">30.5. Surface Queries</a></li> +<li><a href="#_device_group_queries">30.6. Device Group Queries</a></li> +<li><a href="#_wsi_swapchain">30.7. WSI Swapchain</a></li> +</ul> +</li> +<li><a href="#extended-functionality">31. Extended Functionality</a> +<ul class="sectlevel2"> +<li><a href="#extended-functionality-layers">31.1. Layers</a></li> +<li><a href="#extended-functionality-extensions">31.2. Extensions</a></li> +</ul> +</li> +<li><a href="#features">32. Features, Limits, and Formats</a> +<ul class="sectlevel2"> +<li><a href="#features-features">32.1. Features</a></li> +<li><a href="#features-limits">32.2. Limits</a></li> +<li><a href="#features-formats">32.3. Formats</a></li> +<li><a href="#_additional_image_capabilities">32.4. Additional Image Capabilities</a></li> +<li><a href="#_additional_buffer_capabilities">32.5. Additional Buffer Capabilities</a></li> +<li><a href="#_optional_semaphore_capabilities">32.6. Optional Semaphore Capabilities</a></li> +</ul> +</li> +<li><a href="#_debugging">33. Debugging</a> +<ul class="sectlevel2"> +<li><a href="#debugging-debug-markers">33.1. Debug Markers</a></li> +<li><a href="#debugging-debug-report-callbacks">33.2. Debug Report Callbacks</a></li> +</ul> +</li> +<li><a href="#spirvenv">Appendix A: Vulkan Environment for SPIR-V</a> +<ul class="sectlevel2"> +<li><a href="#_required_versions_and_formats">Required Versions and Formats</a></li> +<li><a href="#spirvenv-capabilities">Capabilities</a></li> +<li><a href="#spirvenv-module-validation">Validation Rules within a Module</a></li> +<li><a href="#spirvenv-precision-operation">Precision and Operation of SPIR-V Instructions</a></li> +</ul> +</li> +<li><a href="#_compressed_image_formats">Appendix B: Compressed Image Formats</a> +<ul class="sectlevel2"> +<li><a href="#appendix-compressedtex-bc">Block-Compressed Image Formats</a></li> +<li><a href="#appendix-compressedtex-etc2">ETC Compressed Image Formats</a></li> +<li><a href="#appendix-compressedtex-astc">ASTC Compressed Image Formats</a></li> +</ul> +</li> +<li><a href="#extensions">Appendix C: Layers & Extensions</a> +<ul class="sectlevel2"> +<li><a href="#VK_KHR_android_surface">VK_KHR_android_surface</a></li> +<li><a href="#VK_KHR_descriptor_update_template">VK_KHR_descriptor_update_template</a></li> +<li><a href="#VK_KHR_display">VK_KHR_display</a></li> +<li><a href="#VK_KHR_display_swapchain">VK_KHR_display_swapchain</a></li> +<li><a href="#VK_KHR_get_physical_device_properties2">VK_KHR_get_physical_device_properties2</a></li> +<li><a href="#VK_KHR_maintenance1">VK_KHR_maintenance1</a></li> +<li><a href="#VK_KHR_mir_surface">VK_KHR_mir_surface</a></li> +<li><a href="#VK_KHR_push_descriptor">VK_KHR_push_descriptor</a></li> +<li><a href="#VK_KHR_sampler_mirror_clamp_to_edge">VK_KHR_sampler_mirror_clamp_to_edge</a></li> +<li><a href="#VK_KHR_shader_draw_parameters">VK_KHR_shader_draw_parameters</a></li> +<li><a href="#VK_KHR_surface">VK_KHR_surface</a></li> +<li><a href="#VK_KHR_swapchain">VK_KHR_swapchain</a></li> +<li><a href="#VK_KHR_wayland_surface">VK_KHR_wayland_surface</a></li> +<li><a href="#VK_KHR_win32_surface">VK_KHR_win32_surface</a></li> +<li><a href="#VK_KHR_xcb_surface">VK_KHR_xcb_surface</a></li> +<li><a href="#VK_KHR_xlib_surface">VK_KHR_xlib_surface</a></li> +<li><a href="#VK_KHX_device_group">VK_KHX_device_group</a></li> +<li><a href="#VK_KHX_device_group_creation">VK_KHX_device_group_creation</a></li> +<li><a href="#VK_KHX_external_memory_capabilities">VK_KHX_external_memory_capabilities</a></li> +<li><a href="#VK_KHX_external_memory">VK_KHX_external_memory</a></li> +<li><a href="#VK_KHX_external_memory_win32">VK_KHX_external_memory_win32</a></li> +<li><a href="#VK_KHX_external_memory_fd">VK_KHX_external_memory_fd</a></li> +<li><a href="#VK_KHX_win32_keyed_mutex">VK_KHX_win32_keyed_mutex</a></li> +<li><a href="#VK_KHX_external_semaphore_capabilities">VK_KHX_external_semaphore_capabilities</a></li> +<li><a href="#VK_KHX_external_semaphore">VK_KHX_external_semaphore</a></li> +<li><a href="#VK_KHX_external_semaphore_win32">VK_KHX_external_semaphore_win32</a></li> +<li><a href="#VK_KHX_external_semaphore_fd">VK_KHX_external_semaphore_fd</a></li> +<li><a href="#VK_KHX_multiview">VK_KHX_multiview</a></li> +<li><a href="#VK_EXT_debug_marker">VK_EXT_debug_marker</a></li> +<li><a href="#VK_EXT_debug_report">VK_EXT_debug_report</a></li> +<li><a href="#VK_EXT_validation_flags">VK_EXT_validation_flags</a></li> +<li><a href="#VK_EXT_direct_mode_display">VK_EXT_direct_mode_display</a></li> +<li><a href="#VK_EXT_acquire_xlib_display">VK_EXT_acquire_xlib_display</a></li> +<li><a href="#VK_EXT_discard_rectangles">VK_EXT_discard_rectangles</a></li> +<li><a href="#VK_EXT_display_surface_counter">VK_EXT_display_surface_counter</a></li> +<li><a href="#VK_EXT_display_control">VK_EXT_display_control</a></li> +<li><a href="#VK_EXT_get_image_properties">VK_EXT_get_image_properties</a></li> +<li><a href="#VK_EXT_shader_subgroup_ballot">VK_EXT_shader_subgroup_ballot</a></li> +<li><a href="#VK_EXT_shader_subgroup_vote">VK_EXT_shader_subgroup_vote</a></li> +<li><a href="#VK_AMD_draw_indirect_count">VK_AMD_draw_indirect_count</a></li> +<li><a href="#VK_AMD_gcn_shader">VK_AMD_gcn_shader</a></li> +<li><a href="#VK_AMD_gpu_shader_half_float">VK_AMD_gpu_shader_half_float</a></li> +<li><a href="#VK_AMD_rasterization_order">VK_AMD_rasterization_order</a></li> +<li><a href="#VK_AMD_shader_ballot">VK_AMD_shader_ballot</a></li> +<li><a href="#VK_AMD_shader_explicit_vertex_parameter">VK_AMD_shader_explicit_vertex_parameter</a></li> +<li><a href="#VK_AMD_shader_trinary_minmax">VK_AMD_shader_trinary_minmax</a></li> +<li><a href="#VK_AMD_negative_viewport_height">VK_AMD_negative_viewport_height</a></li> +<li><a href="#VK_IMG_filter_cubic">VK_IMG_filter_cubic</a></li> +<li><a href="#VK_MVK_ios_surface">VK_MVK_ios_surface</a></li> +<li><a href="#VK_MVK_macos_surface">VK_MVK_macos_surface</a></li> +<li><a href="#VK_NN_vi_surface">VK_NN_vi_surface</a></li> +<li><a href="#VK_MESAX_external_memory_dma_buf">VK_MESAX_external_memory_dma_buf</a></li> +<li><a href="#VK_MESAX_external_image_dma_buf">VK_MESAX_external_image_dma_buf</a></li> +<li><a href="#VK_NV_clip_space_w_scaling">VK_NV_clip_space_w_scaling</a></li> +<li><a href="#VK_NV_dedicated_allocation">VK_NV_dedicated_allocation</a></li> +<li><a href="#VK_NV_external_memory_capabilities">VK_NV_external_memory_capabilities</a></li> +<li><a href="#VK_NV_external_memory">VK_NV_external_memory</a></li> +<li><a href="#VK_NV_external_memory_win32">VK_NV_external_memory_win32</a></li> +<li><a href="#VK_NV_geometry_shader_passthrough">VK_NV_geometry_shader_passthrough</a></li> +<li><a href="#VK_NV_glsl_shader">VK_NV_glsl_shader</a></li> +<li><a href="#VK_NV_viewport_array2">VK_NV_viewport_array2</a></li> +<li><a href="#VK_NV_viewport_swizzle">VK_NV_viewport_swizzle</a></li> +<li><a href="#VK_NV_win32_keyed_mutex">VK_NV_win32_keyed_mutex</a></li> +<li><a href="#VK_NV_sample_mask_override_coverage">VK_NV_sample_mask_override_coverage</a></li> +<li><a href="#VK_NVX_device_generated_commands">VK_NVX_device_generated_commands</a></li> +<li><a href="#VK_NVX_multiview_per_view_attributes">VK_NVX_multiview_per_view_attributes</a></li> +</ul> +</li> +<li><a href="#boilerplate">Appendix D: API Boilerplate</a> +<ul class="sectlevel2"> +<li><a href="#boilerplate-sType">Structure Types</a></li> +<li><a href="#boilerplate-flags">Flag Types</a></li> +<li><a href="#boilerplate-macros">Macro Definitions in vulkan.h</a></li> +<li><a href="#boilerplate-platform-macros">Platform-Specific Macro Definitions in vk_platform.h</a></li> +</ul> +</li> +<li><a href="#invariance">Appendix E: Invariance</a> +<ul class="sectlevel2"> +<li><a href="#_repeatability">Repeatability</a></li> +<li><a href="#_multi_pass_algorithms">Multi-pass Algorithms</a></li> +<li><a href="#_invariance_rules">Invariance Rules</a></li> +<li><a href="#_tessellation_invariance">Tessellation Invariance</a></li> +</ul> +</li> +<li><a href="#_glossary">Glossary</a></li> +<li><a href="#_common_abbreviations">Common Abbreviations</a></li> +<li><a href="#_prefixes">Prefixes</a></li> +<li><a href="#credits">Appendix F: Credits</a></li> +</ul> +</div> +</div> +<div id="content"> +<div id="preamble"> +<div class="sectionbody"> +<div style="page-break-after: always;"></div> +<div class="paragraph"> +<p>Copyright © 2014-2017 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 web-site should +be included whenever possible with specification distributions.</p> +</div> +<div class="paragraph"> +<p>This specification has been created under the Khronos Intellectual Property Rights Policy, +which is Attachment A of the Khronos Group Membership Agreement available at +www.khronos.org/files/member_agreement.pdf. This specification contains substantially +unmodified functionality from, and is a successor to, Khronos specifications including +OpenGL, OpenGL ES and OpenCL.</p> +</div> +<div class="paragraph"> +<p>Some parts of this Specification are purely informative and do not define requirements +necessary for compliance and so are outside the Scope of this Specification. These +parts of the Specification are marked by the “Note” icon or designated “Informative”.</p> +</div> +<div class="paragraph"> +<p>Where this Specification uses terms, defined in the Glossary or otherwise, that refer to +enabling technologies that are not expressly set forth as being required for compliance, +those enabling technologies are outside the Scope of this Specification.</p> +</div> +<div class="paragraph"> +<p>Where this Specification uses the terms “may”, or “optional”, such features or +behaviors do not define requirements necessary for compliance and so are outside the +Scope of this Specification.</p> +</div> +<div class="paragraph"> +<p>Where this Specification uses the terms “not required”, such features or +behaviors may be omitted from certain implementations, but when they are included, they +define requirements necessary for compliance and so are INCLUDED in the Scope of this +Specification.</p> +</div> +<div class="paragraph"> +<p>Where this Specification includes normative references to external documents, the +specifically identified sections and functionality of those external documents are in +Scope. Requirements defined by external documents not created by Khronos may contain +contributions from non-members of Khronos not covered by the Khronos Intellectual +Property Rights Policy.</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 non-infringement 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 is a trademark, and Vulkan is a registered trademark of The Khronos +Group Inc. OpenCL is a trademark of Apple Inc. and OpenGL is a registered +trademark of Silicon Graphics International, both used under license by +Khronos.</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 chapter is Informative except for the sections on Terminology and +Normative References.</p> +</div> +<div class="paragraph"> +<p>This document, referred to as the “Vulkan Specification” or just the +“Specification” hereafter, describes the Vulkan graphics system: what it +is, how it acts, and what is required to implement it. +We assume that the reader has at least a rudimentary understanding of +computer graphics. +This means familiarity with the essentials of computer graphics algorithms +and terminology as well as with modern GPUs (Graphic Processing Units).</p> +</div> +<div class="paragraph"> +<p>The canonical version of the Specification is available in the official +Vulkan Registry, located at URL</p> +</div> +<div class="paragraph"> +<p><a href="http://www.khronos.org/registry/vulkan/" class="bare">http://www.khronos.org/registry/vulkan/</a></p> +</div> +<div class="sect2"> +<h3 id="introduction-whatis">1.1. What is the Vulkan Graphics System?</h3> +<div class="paragraph"> +<p>Vulkan is an API (Application Programming Interface) for graphics and +compute hardware. +The API consists of many commands that allow a programmer to specify shader +programs, compute kernels, objects, and operations involved in producing +high-quality graphical images, specifically color images of +three-dimensional objects.</p> +</div> +<div class="sect3"> +<h4 id="introduction-programmer">1.1.1. The Programmer’s View of Vulkan</h4> +<div class="paragraph"> +<p>To the programmer, Vulkan is a set of commands that allow the specification +of <em>shader programs</em> or <em>shaders</em>, <em>kernels</em>, data used by kernels or +shaders, and state controlling aspects of Vulkan outside of shader +execution. +Typically, the data represents geometry in two or three dimensions and +texture images, while the shaders and kernels control the processing of the +data, rasterization of the geometry, and the lighting and shading of +<em>fragments</em> generated by rasterization, resulting in the rendering of +geometry into the framebuffer.</p> +</div> +<div class="paragraph"> +<p>A typical Vulkan program begins with platform-specific calls to open a +window or otherwise prepare a display device onto which the program will +draw. +Then, calls are made to open <em>queues</em> to which <em>command buffers</em> are +submitted. +The command buffers contain lists of commands which will be executed by the +underlying hardware. +The application <strong class="purple">can</strong> also allocate device memory, associate <em>resources</em> with +memory and refer to these resources from within command buffers. +Drawing commands cause application-defined shader programs to be invoked, +which <strong class="purple">can</strong> then consume the data in the resources and use them to produce +graphical images. +To display the resulting images, further platform-specific commands are made +to transfer the resulting image to a display device or window.</p> +</div> +</div> +<div class="sect3"> +<h4 id="introduction-implementor">1.1.2. The Implementor’s View of Vulkan</h4> +<div class="paragraph"> +<p>To the implementor, Vulkan is a set of commands that allow the construction +and submission of command buffers to a device. +Modern devices accelerate virtually all Vulkan operations, storing data and +framebuffer images in high-speed memory and executing shaders in dedicated +GPU processing resources.</p> +</div> +<div class="paragraph"> +<p>The implementor’s task is to provide a software library on the host which +implements the Vulkan API, while mapping the work for each Vulkan command to +the graphics hardware as appropriate for the capabilities of the device.</p> +</div> +</div> +<div class="sect3"> +<h4 id="introduction-ourview">1.1.3. Our View of Vulkan</h4> +<div class="paragraph"> +<p>We view Vulkan as a pipeline having some programmable stages and some +state-driven fixed-function stages that are invoked by a set of specific +drawing operations. +We expect this model to result in a specification that satisfies the needs +of both programmers and implementors. +It does not, however, necessarily provide a model for implementation. +An implementation <strong class="purple">must</strong> produce results conforming to those produced by the +specified methods, but <strong class="purple">may</strong> carry out particular computations in ways that +are more efficient than the one specified.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="introduction-bugs">1.2. Filing Bug Reports</h3> +<div class="paragraph"> +<p>Issues with and bug reports on the Vulkan Specification and the API Registry +<strong class="purple">can</strong> be filed in the Khronos Vulkan GitHub repository, located at URL</p> +</div> +<div class="paragraph"> +<p><a href="http://github.com/KhronosGroup/Vulkan-Docs" class="bare">http://github.com/KhronosGroup/Vulkan-Docs</a></p> +</div> +<div class="paragraph"> +<p>Please tag issues with appropriate labels, such as “Specification”, “Ref +Pages” or “Registry”, to help us triage and assign them appropriately. +Unfortunately, GitHub does not currently let users who do not have write +access to the repository set GitHub labels on issues. +In the meantime, they <strong class="purple">can</strong> be added to the title line of the issue set in +brackets, e.g. ''[Specification]''.</p> +</div> +</div> +<div class="sect2"> +<h3 id="introduction-terminology">1.3. Terminology</h3> +<div class="paragraph"> +<p>The key words <strong>must</strong>, <strong>required</strong>, <strong>shall</strong>, <strong>should</strong>, <strong>recommend</strong>, <strong>may</strong>, and +<strong>optional</strong> in this document are to be interpreted as described in RFC 2119:</p> +</div> +<div class="paragraph"> +<p><a href="http://www.ietf.org/rfc/rfc2119.txt" class="bare">http://www.ietf.org/rfc/rfc2119.txt</a></p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><strong>must</strong></dt> +<dd> +<p>When used alone, this word, or the term <strong>required</strong>, means that the +definition is an absolute requirement of the specification. +When followed by <strong>not</strong> (“<strong class="purple">must</strong> not” ), the phrase means that the +definition is an absolute prohibition of the specification.</p> +</dd> +<dt class="hdlist1"><strong>should</strong></dt> +<dd> +<p>When used alone, this word, or the adjective <strong>recommended</strong>, means that there +may exist valid reasons in particular circumstances to ignore a particular +item, but the full implications must be understood and carefully weighed +before choosing a different course. +When followed by <strong>not</strong> (“<strong class="purple">should</strong> not”), the phrase means that there may +exist valid reasons in particular circumstances when the particular behavior +is acceptable or even useful, but the full implications <strong class="purple">should</strong> be +understood and the case carefully weighed before implementing any behavior +described with this label.</p> +</dd> +<dt class="hdlist1"><strong>may</strong></dt> +<dd> +<p>This word, or the adjective <strong>optional</strong>, means that an item is truly +optional. +One vendor may choose to include the item because a particular marketplace +requires it or because the vendor feels that it enhances the product while +another vendor may omit the same item. +An implementation which does not include a particular option must be +prepared to interoperate with another implementation which does include the +option, though perhaps with reduced functionality. +In the same vein an implementation which does include a particular option +must be prepared to interoperate with another implementation which does not +include the option (except, of course, for the feature the option provides).</p> +</dd> +</dl> +</div> +<div class="paragraph"> +<p>The additional terms <strong>can</strong> and <strong>cannot</strong> are to be interpreted as follows:</p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><strong>can</strong></dt> +<dd> +<p>This word means that the particular behavior described is a valid choice for +an application, and is never used to refer to implementation behavior.</p> +</dd> +<dt class="hdlist1"><strong>cannot</strong></dt> +<dd> +<p>This word means that the particular behavior described is not achievable by +an application. +For example, an entry point does not exist, or shader code is not capable of +expressing an operation.</p> +</dd> +</dl> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>There is an important distinction between <strong>cannot</strong> and <strong>must not</strong>, as used +in this Specification. +<strong>Cannot</strong> means something the application literally is unable to express or +accomplish through the API, while <strong>must not</strong> means something that the +application is capable of expressing through the API, but that the +consequences of doing so are undefined and potentially unrecoverable for the +implementation.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">editing-note</div> +<div class="paragraph"> +<p>TODO (Jon) - We might need to augment the RFC 2119 definition of <strong>must not</strong> +to include some of the previous note, since at present it is defined solely +in terms of implementation behavior. +See Gitlab issue #9.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect2"> +<h3 id="introduction-normative">1.4. Normative References</h3> +<div class="paragraph"> +<p>Normative references are references to external documents or resources to +which implementers of Vulkan <strong class="purple">must</strong> comply.</p> +</div> +<div id="ieee-754" class="paragraph"> +<p><em>IEEE Standard for Floating-Point Arithmetic</em>, IEEE Std 754-2008, +<a href="http://dx.doi.org/10.1109/IEEESTD.2008.4610935" class="bare">http://dx.doi.org/10.1109/IEEESTD.2008.4610935</a>, August, 2008.</p> +</div> +<div class="paragraph"> +<p><a id="data-format"></a> A. +Garrard, <em>Khronos Data Format Specification, version 1.1</em>, +<a href="https://www.khronos.org/registry/dataformat/specs/1.1/dataformat.1.1.html" class="bare">https://www.khronos.org/registry/dataformat/specs/1.1/dataformat.1.1.html</a>, +June, 2016.</p> +</div> +<div class="paragraph"> +<p><a id="spirv-extended"></a> J. +Kessenich, <em>SPIR-V Extended Instructions for GLSL, Version 1.00</em>, +<a href="https://www.khronos.org/registry/spir-v/" class="bare">https://www.khronos.org/registry/spir-v/</a>, February 10, 2016.</p> +</div> +<div class="paragraph"> +<p><a id="spirv-spec"></a> J. +Kessenich and B. +Ouriel, <em>The Khronos SPIR-V Specification, Version 1.00</em>, +<a href="https://www.khronos.org/registry/spir-v/" class="bare">https://www.khronos.org/registry/spir-v/</a>, February 10, 2016.</p> +</div> +<div class="paragraph"> +<p><a id="vulkan-styleguide"></a> J. +Leech and T. +Hector, <em>Vulkan Documentation and Extensions: Procedures and Conventions</em>, +<a href="https://www.khronos.org/registry/vulkan/" class="bare">https://www.khronos.org/registry/vulkan/</a>, July 11, 2016</p> +</div> +<div id="LoaderAndValidationLayers" class="paragraph"> +<p><em>Vulkan Loader Specification and Architecture Overview</em>, +<a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md" class="bare">https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md</a>, +August, 2016.</p> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="fundamentals">2. Fundamentals</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>This chapter introduces fundamental concepts including the Vulkan +architecture and execution model, API syntax, queues, pipeline +configurations, numeric representation, state and state queries, and the +different types of objects and shaders. +It provides a framework for interpreting more specific descriptions of +commands and behavior in the remainder of the Specification.</p> +</div> +<div class="sect2"> +<h3 id="fundamentals-architecture-model">2.1. Architecture Model</h3> +<div class="paragraph"> +<p>Vulkan is designed for, and the API is written for, CPU, GPU, and other +hardware accelerator architectures with the following properties:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Runtime support for 8, 16, 32 and 64-bit signed and unsigned +twos-complement integers, all addressable at the granularity of their +size in bytes.</p> +</li> +<li> +<p>Runtime support for 32- and 64-bit floating-point types satisfying the +range and precision constraints in the +<a href="#fundamentals-floatingpoint">Floating Point Computation</a> section.</p> +</li> +<li> +<p>The representation and endianness of these types <strong class="purple">must</strong> be identical for +the host and the physical devices.</p> +</li> +</ul> +</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>Since a variety of data types and structures in Vulkan <strong class="purple">may</strong> be mapped back +and forth between host and physical device memory, host and device +architectures <strong class="purple">must</strong> both be able to access such data efficiently in order to +write portable and performant applications.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Where the Specification leaves choices open that would affect Application +Binary Interface compatibility on a given platform supporting Vulkan, those +choices are usually made to be compliant to the preferred ABI defined by the +platform vendor. +Some choices, such as function calling conventions, <strong class="purple">may</strong> be made in +platform-specific portions of the vk_platform.h header file.</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>For example, the Android ABI is defined by Google, and the Linux ABI is +defined by a combination of gcc defaults, distribution vendor choices, and +external standards such as the Linux Standard Base.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-execmodel">2.2. Execution Model</h3> +<div class="paragraph"> +<p>This section outlines the execution model of a Vulkan system.</p> +</div> +<div class="paragraph"> +<p>Vulkan exposes one or more <em>devices</em>, each of which exposes one or more +<em>queues</em> which <strong class="purple">may</strong> process work asynchronously to one another. +The set of queues supported by a device is partitioned into <em>families</em>. +Each family supports one or more types of functionality and <strong class="purple">may</strong> contain +multiple queues with similar characteristics. +Queues within a single family are considered <em>compatible</em> with one another, +and work produced for a family of queues <strong class="purple">can</strong> be executed on any queue +within that family. +This specification defines four types of functionality that queues <strong class="purple">may</strong> +support: graphics, compute, transfer, and sparse memory management.</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>A single device <strong class="purple">may</strong> report multiple similar queue families rather than, or +as well as, reporting multiple members of one or more of those families. +This indicates that while members of those families have similar +capabilities, they are <em>not</em> directly compatible with one another.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Device memory is explicitly managed by the application. +Each device <strong class="purple">may</strong> advertise one or more heaps, representing different areas +of memory. +Memory heaps are either device local or host local, but are always visible +to the device. +Further detail about memory heaps is exposed via memory types available on +that heap. +Examples of memory areas that <strong class="purple">may</strong> be available on an implementation +include:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><em>device local</em> is memory that is physically connected to the device.</p> +</li> +<li> +<p><em>device local, host visible</em> is device local memory that is visible to +the host.</p> +</li> +<li> +<p><em>host local, host visible</em> is memory that is local to the host and +visible to the device and host.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>On other architectures, there <strong class="purple">may</strong> only be a single heap that <strong class="purple">can</strong> be used +for any purpose.</p> +</div> +<div class="paragraph"> +<p>A Vulkan application controls a set of devices through the submission of +command buffers which have recorded device commands issued via Vulkan +library calls. +The content of command buffers is specific to the underlying hardware and is +opaque to the application. +Once constructed, a command buffer <strong class="purple">can</strong> be submitted once or many times to a +queue for execution. +Multiple command buffers <strong class="purple">can</strong> be built in parallel by employing multiple +threads within the application.</p> +</div> +<div class="paragraph"> +<p>Command buffers submitted to different queues <strong class="purple">may</strong> execute in parallel or +even out of order with respect to one another. +Command buffers submitted to a single queue respect +<a href="#synchronization-submission-order">submission order</a>, as described further +in <a href="#synchronization">synchronization chapter</a>. +Command buffer execution by the device is also asynchronous to host +execution. +Once a command buffer is submitted to a queue, control <strong class="purple">may</strong> return to the +application immediately. +Synchronization between the device and host, and between different queues is +the responsibility of the application.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-queueoperation">2.2.1. Queue Operation</h4> +<div class="paragraph"> +<p>Vulkan queues provide an interface to the execution engines of a device. +Commands for these execution engines are recorded into command buffers ahead +of execution time. +These command buffers are then submitted to queues with a <em>queue submission</em> +command for execution in a number of <em>batches</em>. +Once submitted to a queue, these commands will begin and complete execution +without further application intervention, though the order of this execution +is dependent on a number of <a href="#synchronization">implicit and explicit +ordering constraints</a>.</p> +</div> +<div class="paragraph"> +<p>Work is submitted to queues using queue submission commands that typically +take the form <code>vkQueue</code>* (e.g. <a href="#vkQueueSubmit">vkQueueSubmit</a>, +<a href="#vkQueueBindSparse">vkQueueBindSparse</a>), and optionally take a list of semaphores upon +which to wait before work begins and a list of semaphores to signal once +work has completed. +The work itself, as well as signaling and waiting on the semaphores are all +<em>queue operations</em>.</p> +</div> +<div class="paragraph"> +<p>Queue operations on different queues have no implicit ordering constraints, +and <strong class="purple">may</strong> execute in any order. +Explicit ordering constraints between queues <strong class="purple">can</strong> be expressed with +<a href="#synchronization-semaphores">semaphores</a> and +<a href="#synchronization-fences">fences</a>.</p> +</div> +<div class="paragraph"> +<p>Command buffer submissions to a single queue respect +<a href="#synchronization-submission-order">submission order</a> and other +<a href="#synchronization-implicit">implicit ordering guarantees</a>, but otherwise +<strong class="purple">may</strong> overlap or execute out of order. +Other types of batches and queue submissions against a single queue (e.g. +<a href="#sparsemem-memory-binding">sparse memory binding</a>) have no implicit +ordering constraints with any other queue submission or batch. +Additional explicit ordering constraints between queue submissions and +individual batches can be expressed with +<a href="#synchronization-semaphores">semaphores</a> and +<a href="#synchronization-fences">fences</a>.</p> +</div> +<div class="paragraph"> +<p>Before a fence or semaphore is signaled, it is guaranteed that any +previously submitted queue operations have completed execution, and that +memory writes from those queue operations are +<a href="#synchronization-dependencies-available-and-visible">available</a> to future +queue operations. +Waiting on a signaled semaphore or fence guarantees that previous writes +that are available are also +<a href="#synchronization-dependencies-available-and-visible">visible</a> to subsequent +commands.</p> +</div> +<div class="paragraph"> +<p>Command buffer boundaries, both between primary command buffers of the same +or different batches or submissions as well as between primary and secondary +command buffers, do not introduce any additional ordering constraints. +In other words, submitting the set of command buffers (which <strong class="purple">can</strong> include +executing secondary command buffers) between any semaphore or fence +operations execute the recorded commands as if they had all been recorded +into a single primary command buffer, except that the current state is +<a href="#commandbuffers-statereset">reset</a> on each boundary. +Explicit ordering constraints <strong class="purple">can</strong> be expressed with <a href="#synchronization">explicit synchronization primitives</a>.</p> +</div> +<div class="paragraph"> +<p>There are a few <a href="#synchronization-implicit">implicit ordering guarantees</a> +between commands within a command buffer, but only covering a subset of +execution. +Additional explicit ordering constraints can be expressed with the various +<a href="#synchronization">explicit synchronization primitives</a>.</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>Implementations have significant freedom to overlap execution of work +submitted to a queue, and this is common due to deep pipelining and +parallelism in Vulkan devices.</p> +</div> +</td> +</tr> +</table> +</div> +<div id="fundamentals-queueoperation-command-types" class="paragraph"> +<p>Commands recorded in command buffers either perform actions (draw, dispatch, +clear, copy, query/timestamp operations, begin/end subpass operations), set +state (bind pipelines, descriptor sets, and buffers, set dynamic state, push +constants, set render pass/subpass state), or perform synchronization +(set/wait events, pipeline barrier, render pass/subpass dependencies). +Some commands perform more than one of these tasks. +State setting commands update the <em>current state</em> of the command buffer. +Some commands that perform actions (e.g. draw/dispatch) do so based on the +current state set cumulatively since the start of the command buffer. +The work involved in performing action commands is often allowed to overlap +or to be reordered, but doing so <strong class="purple">must</strong> not alter the state to be used by +each action command. +In general, action commands are those commands that alter framebuffer +attachments, read/write buffer or image memory, or write to query pools.</p> +</div> +<div class="paragraph"> +<p>Synchronization commands introduce explicit +<a href="#synchronization-dependencies">execution and memory dependencies</a> between +two sets of action commands, where the second set of commands depends on the +first set of commands. +These dependencies enforce that both the execution of certain +<a href="#synchronization-pipeline-stages">pipeline stages</a> in the later set occur +after the execution of certain stages in the source set, and that the +effects of <a href="#synchronization-global-memory-barriers">memory accesses</a> +performed by certain pipeline stages occur in order and are visible to each +other. +When not enforced by an explicit dependency or <a href="#synchronization-implicit">implicit ordering guarantees</a>, action commands <strong class="purple">may</strong> overlap execution or +execute out of order, and <strong class="purple">may</strong> not see the side effects of each other’s +memory accesses.</p> +</div> +<div class="paragraph"> +<p>The device executes queue operations asynchronously with respect to the +host. +Control is returned to an application immediately following command buffer +submission to a queue. +The application <strong class="purple">must</strong> synchronize work between the host and device as +needed.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-objectmodel-overview">2.3. Object Model</h3> +<div class="paragraph"> +<p>The devices, queues, and other entities in Vulkan are represented by Vulkan +objects. +At the API level, all objects are referred to by handles. +There are two classes of handles, dispatchable and non-dispatchable. +<em>Dispatchable</em> handle types are a pointer to an opaque type. +This pointer <strong class="purple">may</strong> be used by layers as part of intercepting API commands, +and thus each API command takes a dispatchable type as its first parameter. +Each object of a dispatchable type <strong class="purple">must</strong> have a unique handle value during +its lifetime.</p> +</div> +<div class="paragraph"> +<p><em>Non-dispatchable</em> handle types are a 64-bit integer type whose meaning is +implementation-dependent, and <strong class="purple">may</strong> encode object information directly in the +handle rather than pointing to a software structure. +Objects of a non-dispatchable type <strong class="purple">may</strong> not have unique handle values within +a type or across types. +If handle values are not unique, then destroying one such handle <strong class="purple">must</strong> not +cause identical handles of other types to become invalid, and <strong class="purple">must</strong> not +cause identical handles of the same type to become invalid if that handle +value has been created more times than it has been destroyed.</p> +</div> +<div class="paragraph"> +<p>All objects created or allocated from a <code>VkDevice</code> (i.e. with a +<code>VkDevice</code> as the first parameter) are private to that device, and <strong class="purple">must</strong> +not be used on other devices.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-objectmodel-lifetime">2.3.1. Object Lifetime</h4> +<div class="paragraph"> +<p>Objects are created or allocated by <code>vkCreate</code>* and <code>vkAllocate</code>* +commands, respectively. +Once an object is created or allocated, its “structure” is considered to +be immutable, though the contents of certain object types is still free to +change. +Objects are destroyed or freed by <code>vkDestroy</code>* and <code>vkFree</code>* +commands, respectively.</p> +</div> +<div class="paragraph"> +<p>Objects that are allocated (rather than created) take resources from an +existing pool object or memory heap, and when freed return resources to that +pool or heap. +While object creation and destruction are generally expected to be +low-frequency occurrences during runtime, allocating and freeing objects +<strong class="purple">can</strong> occur at high frequency. +Pool objects help accommodate improved performance of the allocations and +frees.</p> +</div> +<div class="paragraph"> +<p>It is an application’s responsibility to track the lifetime of Vulkan +objects, and not to destroy them while they are still in use.</p> +</div> +<div class="paragraph"> +<p>Application-owned memory is immediately consumed by any Vulkan command it is +passed into. +The application <strong class="purple">can</strong> alter or free this memory as soon as the commands that +consume it have returned.</p> +</div> +<div class="paragraph"> +<p>The following object types are consumed when they are passed into a Vulkan +command and not further accessed by the objects they are used to create. +They <strong class="purple">must</strong> not be destroyed in the duration of any API command they are +passed into:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VkShaderModule</code></p> +</li> +<li> +<p><code>VkPipelineCache</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>A <code>VkPipelineLayout</code> object <strong class="purple">must</strong> not be destroyed while any command +buffer that uses it is in the recording state.</p> +</div> +<div class="paragraph"> +<p><code>VkDescriptorSetLayout</code> objects <strong class="purple">may</strong> be accessed by commands that +operate on descriptor sets allocated using that layout, and those descriptor +sets <strong class="purple">must</strong> not be updated with <a href="#vkUpdateDescriptorSets">vkUpdateDescriptorSets</a> after the +descriptor set layout has been destroyed. +Otherwise, descriptor set layouts <strong class="purple">can</strong> be destroyed any time they are not in +use by an API command.</p> +</div> +<div class="paragraph"> +<p>The application <strong class="purple">must</strong> not destroy any other type of Vulkan object until all +uses of that object by the device (such as via command buffer execution) +have completed.</p> +</div> +<div class="paragraph"> +<p>The following Vulkan objects <strong class="purple">must</strong> not be destroyed while any command +buffers using the object are recording or pending execution:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VkEvent</code></p> +</li> +<li> +<p><code>VkQueryPool</code></p> +</li> +<li> +<p><code>VkBuffer</code></p> +</li> +<li> +<p><code>VkBufferView</code></p> +</li> +<li> +<p><code>VkImage</code></p> +</li> +<li> +<p><code>VkImageView</code></p> +</li> +<li> +<p><code>VkPipeline</code></p> +</li> +<li> +<p><code>VkSampler</code></p> +</li> +<li> +<p><code>VkDescriptorPool</code></p> +</li> +<li> +<p><code>VkFramebuffer</code></p> +</li> +<li> +<p><code>VkRenderPass</code></p> +</li> +<li> +<p><code>VkCommandPool</code></p> +</li> +<li> +<p><code>VkDeviceMemory</code></p> +</li> +<li> +<p><code>VkDescriptorSet</code></p> +</li> +<li> +<p><code>VkObjectTableNVX</code></p> +</li> +<li> +<p><code>VkIndirectCommandsLayout</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The following Vulkan objects <strong class="purple">must</strong> not be destroyed while any queue is +executing commands that use the object:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VkFence</code></p> +</li> +<li> +<p><code>VkSemaphore</code></p> +</li> +<li> +<p><code>VkCommandBuffer</code></p> +</li> +<li> +<p><code>VkCommandPool</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>In general, objects <strong class="purple">can</strong> be destroyed or freed in any order, even if the +object being freed is involved in the use of another object (e.g. use of a +resource in a view, use of a view in a descriptor set, use of an object in a +command buffer, binding of a memory allocation to a resource), as long as +any object that uses the freed object is not further used in any way except +to be destroyed or to be reset in such a way that it no longer uses the +other object (such as resetting a command buffer). +If the object has been reset, then it <strong class="purple">can</strong> be used as if it never used the +freed object. +An exception to this is when there is a parent/child relationship between +objects. +In this case, the application <strong class="purple">must</strong> not destroy a parent object before its +children, except when the parent is explicitly defined to free its children +when it is destroyed (e.g. for pool objects, as defined below).</p> +</div> +<div class="paragraph"> +<p><code>VkCommandPool</code> objects are parents of <code>VkCommandBuffer</code> objects. +<code>VkDescriptorPool</code> objects are parents of <code>VkDescriptorSet</code> objects. +<code>VkDevice</code> objects are parents of many object types (all that take a +<code>VkDevice</code> as a parameter to their creation).</p> +</div> +<div class="paragraph"> +<p>The following Vulkan objects have specific restrictions for when they <strong class="purple">can</strong> +be destroyed:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VkQueue</code> objects <strong class="purple">cannot</strong> be explicitly destroyed. +Instead, they are implicitly destroyed when the <code>VkDevice</code> object +they are retrieved from is destroyed.</p> +</li> +<li> +<p>Destroying a pool object implicitly frees all objects allocated from +that pool. +Specifically, destroying <code>VkCommandPool</code> frees all +<code>VkCommandBuffer</code> objects that were allocated from it, and +destroying <code>VkDescriptorPool</code> frees all <code>VkDescriptorSet</code> +objects that were allocated from it.</p> +</li> +<li> +<p><code>VkDevice</code> objects <strong class="purple">can</strong> be destroyed when all <code>VkQueue</code> objects +retrieved from them are idle, and all objects created from them have +been destroyed. +This includes the following objects:</p> +<div class="ulist"> +<ul> +<li> +<p><code>VkFence</code></p> +</li> +<li> +<p><code>VkSemaphore</code></p> +</li> +<li> +<p><code>VkEvent</code></p> +</li> +<li> +<p><code>VkQueryPool</code></p> +</li> +<li> +<p><code>VkBuffer</code></p> +</li> +<li> +<p><code>VkBufferView</code></p> +</li> +<li> +<p><code>VkImage</code></p> +</li> +<li> +<p><code>VkImageView</code></p> +</li> +<li> +<p><code>VkShaderModule</code></p> +</li> +<li> +<p><code>VkPipelineCache</code></p> +</li> +<li> +<p><code>VkPipeline</code></p> +</li> +<li> +<p><code>VkPipelineLayout</code></p> +</li> +<li> +<p><code>VkSampler</code></p> +</li> +<li> +<p><code>VkDescriptorSetLayout</code></p> +</li> +<li> +<p><code>VkDescriptorPool</code></p> +</li> +<li> +<p><code>VkFramebuffer</code></p> +</li> +<li> +<p><code>VkRenderPass</code></p> +</li> +<li> +<p><code>VkCommandPool</code></p> +</li> +<li> +<p><code>VkCommandBuffer</code></p> +</li> +<li> +<p><code>VkDeviceMemory</code></p> +</li> +</ul> +</div> +</li> +<li> +<p><code>VkPhysicalDevice</code> objects <strong class="purple">cannot</strong> be explicitly destroyed. +Instead, they are implicitly destroyed when the <code>VkInstance</code> object +they are retrieved from is destroyed.</p> +</li> +<li> +<p><code>VkInstance</code> objects <strong class="purple">can</strong> be destroyed once all <code>VkDevice</code> +objects created from any of its <code>VkPhysicalDevice</code> objects have been +destroyed.</p> +</li> +</ul> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-objectmodel-external">2.3.2. External Object Handles</h4> +<div class="paragraph"> +<p>As defined above, the scope of object handles created or allocated from a +<code>VkDevice</code> is limited to that logical device. +Objects which are not in scope are said to be external. +To bring an external object into scope, an external handle <strong class="purple">must</strong> be exported +from the object in the source scope and imported into the destination scope.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>The scope of external handles and their associated resources <strong class="purple">may</strong> vary +according to their type, but they <strong class="purple">can</strong> generally be shared across process +and API boundaries.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-commandsyntax">2.4. Command Syntax and Duration</h3> +<div class="paragraph"> +<p>The Specification describes Vulkan commands as functions or procedures using +C99 syntax. +Language bindings for other languages such as C++ and JavaScript <strong class="purple">may</strong> allow +for stricter parameter passing, or object-oriented interfaces.</p> +</div> +<div class="paragraph"> +<p>Vulkan uses the standard C types for the base type of scalar parameters +(e.g. types from stdint.h), with exceptions described below, or elsewhere +in the text when appropriate:</p> +</div> +<div class="paragraph"> +<p><code>VkBool32</code> represents boolean <code>True</code> and <code>False</code> values, since C does +not have a sufficiently portable built-in boolean type:</p> +</div> +<div id="VkBool32" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> uint32_t VkBool32;</code></pre> +</div> +</div> +<div class="paragraph"> +<p><code>VK_TRUE</code> represents a boolean <strong>True</strong> (integer 1) value, and +<code>VK_FALSE</code> a boolean <strong>False</strong> (integer 0) value.</p> +</div> +<div class="paragraph"> +<p>All values returned from a Vulkan implementation in a <code>VkBool32</code> will +be either <code>VK_TRUE</code> or <code>VK_FALSE</code>.</p> +</div> +<div class="paragraph"> +<p>Applications <strong class="purple">must</strong> not pass any other values than <code>VK_TRUE</code> or +<code>VK_FALSE</code> into a Vulkan implementation where a <code>VkBool32</code> is +expected.</p> +</div> +<div class="paragraph"> +<p><code>VkDeviceSize</code> represents device memory size and offset values:</p> +</div> +<div id="VkDeviceSize" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> uint64_t VkDeviceSize;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Commands that create Vulkan objects are of the form <code>vkCreate</code>* and take +<code>Vk</code>*CreateInfo structures with the parameters needed to create the +object. +These Vulkan objects are destroyed with commands of the form +<code>vkDestroy</code>*.</p> +</div> +<div class="paragraph"> +<p>The last in-parameter to each command that creates or destroys a Vulkan +object is <code>pAllocator</code>. +The <code>pAllocator</code> parameter <strong class="purple">can</strong> be set to a non-<code>NULL</code> value such that +allocations for the given object are delegated to an application provided +callback; refer to the <a href="#memory-allocation">Memory Allocation</a> chapter for +further details.</p> +</div> +<div class="paragraph"> +<p>Commands that allocate Vulkan objects owned by pool objects are of the form +<code>vkAllocate</code>*, and take <code>Vk</code>*AllocateInfo structures. +These Vulkan objects are freed with commands of the form <code>vkFree</code>*. +These objects do not take allocators; if host memory is needed, they will +use the allocator that was specified when their parent pool was created.</p> +</div> +<div class="paragraph"> +<p>Commands are recorded into a command buffer by calling API commands of the +form <code>vkCmd</code>*. +Each such command <strong class="purple">may</strong> have different restrictions on where it <strong class="purple">can</strong> be used: +in a primary and/or secondary command buffer, inside and/or outside a render +pass, and in one or more of the supported queue types. +These restrictions are documented together with the definition of each such +command.</p> +</div> +<div class="paragraph"> +<p>The <em>duration</em> of a Vulkan command refers to the interval between calling +the command and its return to the caller.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-commandsyntax-results-lifetime">2.4.1. Lifetime of Retrieved Results</h4> +<div class="paragraph"> +<p>Information is retrieved from the implementation with commands of the form +<code>vkGet</code>* and <code>vkEnumerate</code>*.</p> +</div> +<div class="paragraph"> +<p>Unless otherwise specified for an individual command, the results are +<em>invariant</em>; that is, they will remain unchanged when retrieved again by +calling the same command with the same parameters, so long as those +parameters themselves all remain valid.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-threadingbehavior">2.5. Threading Behavior</h3> +<div class="paragraph"> +<p>Vulkan is intended to provide scalable performance when used on multiple +host threads. +All commands support being called concurrently from multiple threads, but +certain parameters, or components of parameters are defined to be +<em>externally synchronized</em>. +This means that the caller <strong class="purple">must</strong> guarantee that no more than one thread is +using such a parameter at a given time.</p> +</div> +<div class="paragraph"> +<p>More precisely, Vulkan commands use simple stores to update software +structures representing Vulkan objects. +A parameter declared as externally synchronized <strong class="purple">may</strong> have its software +structures updated at any time during the host execution of the command. +If two commands operate on the same object and at least one of the commands +declares the object to be externally synchronized, then the caller <strong class="purple">must</strong> +guarantee not only that the commands do not execute simultaneously, but also +that the two commands are separated by an appropriate memory barrier (if +needed).</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>Memory barriers are particularly relevant on the ARM CPU architecture which +is more weakly ordered than many developers are accustomed to from x86/x64 +programming. +Fortunately, most higher-level synchronization primitives (like the pthread +library) perform memory barriers as a part of mutual exclusion, so mutexing +Vulkan objects via these primitives will have the desired effect.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Many object types are <em>immutable</em>, meaning the objects <strong class="purple">cannot</strong> change once +they have been created. +These types of objects never need external synchronization, except that they +<strong class="purple">must</strong> not be destroyed while they are in use on another thread. +In certain special cases, mutable object parameters are internally +synchronized such that they do not require external synchronization. +One example of this is the use of a <code>VkPipelineCache</code> in +<code>vkCreateGraphicsPipelines</code> and <code>vkCreateComputePipelines</code>, where +external synchronization around such a heavyweight command would be +impractical. +The implementation <strong class="purple">must</strong> internally synchronize the cache in this example, +and <strong class="purple">may</strong> be able to do so in the form of a much finer-grained mutex around +the command. +Any command parameters that are not labeled as externally synchronized are +either not mutated by the command or are internally synchronized. +Additionally, certain objects related to a command’s parameters (e.g. +command pools and descriptor pools) <strong class="purple">may</strong> be affected by a command, and <strong class="purple">must</strong> +also be externally synchronized. +These implicit parameters are documented as described below.</p> +</div> +<div class="paragraph"> +<p>Parameters of commands that are externally synchronized are listed below.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Externally Synchronized Parameters</div> +<div class="ulist"> +<ul> +<li> +<p>The <code>instance</code> parameter in <a href="#vkDestroyInstance">vkDestroyInstance</a></p> +</li> +<li> +<p>The <code>device</code> parameter in <a href="#vkDestroyDevice">vkDestroyDevice</a></p> +</li> +<li> +<p>The <code>queue</code> parameter in <a href="#vkQueueSubmit">vkQueueSubmit</a></p> +</li> +<li> +<p>The <code>fence</code> parameter in <a href="#vkQueueSubmit">vkQueueSubmit</a></p> +</li> +<li> +<p>The <code>memory</code> parameter in <a href="#vkFreeMemory">vkFreeMemory</a></p> +</li> +<li> +<p>The <code>memory</code> parameter in <a href="#vkMapMemory">vkMapMemory</a></p> +</li> +<li> +<p>The <code>memory</code> parameter in <a href="#vkUnmapMemory">vkUnmapMemory</a></p> +</li> +<li> +<p>The <code>buffer</code> parameter in <a href="#vkBindBufferMemory">vkBindBufferMemory</a></p> +</li> +<li> +<p>The <code>image</code> parameter in <a href="#vkBindImageMemory">vkBindImageMemory</a></p> +</li> +<li> +<p>The <code>queue</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>The <code>fence</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>The <code>fence</code> parameter in <a href="#vkDestroyFence">vkDestroyFence</a></p> +</li> +<li> +<p>The <code>semaphore</code> parameter in <a href="#vkDestroySemaphore">vkDestroySemaphore</a></p> +</li> +<li> +<p>The <code>event</code> parameter in <a href="#vkDestroyEvent">vkDestroyEvent</a></p> +</li> +<li> +<p>The <code>event</code> parameter in <a href="#vkSetEvent">vkSetEvent</a></p> +</li> +<li> +<p>The <code>event</code> parameter in <a href="#vkResetEvent">vkResetEvent</a></p> +</li> +<li> +<p>The <code>queryPool</code> parameter in <a href="#vkDestroyQueryPool">vkDestroyQueryPool</a></p> +</li> +<li> +<p>The <code>buffer</code> parameter in <a href="#vkDestroyBuffer">vkDestroyBuffer</a></p> +</li> +<li> +<p>The <code>bufferView</code> parameter in <a href="#vkDestroyBufferView">vkDestroyBufferView</a></p> +</li> +<li> +<p>The <code>image</code> parameter in <a href="#vkDestroyImage">vkDestroyImage</a></p> +</li> +<li> +<p>The <code>imageView</code> parameter in <a href="#vkDestroyImageView">vkDestroyImageView</a></p> +</li> +<li> +<p>The <code>shaderModule</code> parameter in <a href="#vkDestroyShaderModule">vkDestroyShaderModule</a></p> +</li> +<li> +<p>The <code>pipelineCache</code> parameter in <a href="#vkDestroyPipelineCache">vkDestroyPipelineCache</a></p> +</li> +<li> +<p>The <code>dstCache</code> parameter in <a href="#vkMergePipelineCaches">vkMergePipelineCaches</a></p> +</li> +<li> +<p>The <code>pipeline</code> parameter in <a href="#vkDestroyPipeline">vkDestroyPipeline</a></p> +</li> +<li> +<p>The <code>pipelineLayout</code> parameter in <a href="#vkDestroyPipelineLayout">vkDestroyPipelineLayout</a></p> +</li> +<li> +<p>The <code>sampler</code> parameter in <a href="#vkDestroySampler">vkDestroySampler</a></p> +</li> +<li> +<p>The <code>descriptorSetLayout</code> parameter in <a href="#vkDestroyDescriptorSetLayout">vkDestroyDescriptorSetLayout</a></p> +</li> +<li> +<p>The <code>descriptorPool</code> parameter in <a href="#vkDestroyDescriptorPool">vkDestroyDescriptorPool</a></p> +</li> +<li> +<p>The <code>descriptorPool</code> parameter in <a href="#vkResetDescriptorPool">vkResetDescriptorPool</a></p> +</li> +<li> +<p>The <code>descriptorPool</code> the <code>pAllocateInfo</code> parameter in <a href="#vkAllocateDescriptorSets">vkAllocateDescriptorSets</a></p> +</li> +<li> +<p>The <code>descriptorPool</code> parameter in <a href="#vkFreeDescriptorSets">vkFreeDescriptorSets</a></p> +</li> +<li> +<p>The <code>framebuffer</code> parameter in <a href="#vkDestroyFramebuffer">vkDestroyFramebuffer</a></p> +</li> +<li> +<p>The <code>renderPass</code> parameter in <a href="#vkDestroyRenderPass">vkDestroyRenderPass</a></p> +</li> +<li> +<p>The <code>commandPool</code> parameter in <a href="#vkDestroyCommandPool">vkDestroyCommandPool</a></p> +</li> +<li> +<p>The <code>commandPool</code> parameter in <a href="#vkResetCommandPool">vkResetCommandPool</a></p> +</li> +<li> +<p>The <code>commandPool</code> the <code>pAllocateInfo</code> parameter in <a href="#vkAllocateCommandBuffers">vkAllocateCommandBuffers</a></p> +</li> +<li> +<p>The <code>commandPool</code> parameter in <a href="#vkFreeCommandBuffers">vkFreeCommandBuffers</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkEndCommandBuffer">vkEndCommandBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkResetCommandBuffer">vkResetCommandBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBindPipeline">vkCmdBindPipeline</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetViewport">vkCmdSetViewport</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetScissor">vkCmdSetScissor</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetLineWidth">vkCmdSetLineWidth</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetDepthBias">vkCmdSetDepthBias</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetBlendConstants">vkCmdSetBlendConstants</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetDepthBounds">vkCmdSetDepthBounds</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetStencilCompareMask">vkCmdSetStencilCompareMask</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetStencilWriteMask">vkCmdSetStencilWriteMask</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetStencilReference">vkCmdSetStencilReference</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBindDescriptorSets">vkCmdBindDescriptorSets</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBindIndexBuffer">vkCmdBindIndexBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBindVertexBuffers">vkCmdBindVertexBuffers</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDraw">vkCmdDraw</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDrawIndexed">vkCmdDrawIndexed</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDrawIndirect">vkCmdDrawIndirect</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDrawIndexedIndirect">vkCmdDrawIndexedIndirect</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDispatch">vkCmdDispatch</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDispatchIndirect">vkCmdDispatchIndirect</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdCopyBuffer">vkCmdCopyBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdCopyImage">vkCmdCopyImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBlitImage">vkCmdBlitImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdCopyBufferToImage">vkCmdCopyBufferToImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdCopyImageToBuffer">vkCmdCopyImageToBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdUpdateBuffer">vkCmdUpdateBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdFillBuffer">vkCmdFillBuffer</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdClearColorImage">vkCmdClearColorImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdClearDepthStencilImage">vkCmdClearDepthStencilImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdClearAttachments">vkCmdClearAttachments</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdResolveImage">vkCmdResolveImage</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetEvent">vkCmdSetEvent</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdResetEvent">vkCmdResetEvent</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdWaitEvents">vkCmdWaitEvents</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdPipelineBarrier">vkCmdPipelineBarrier</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBeginQuery">vkCmdBeginQuery</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdEndQuery">vkCmdEndQuery</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdResetQueryPool">vkCmdResetQueryPool</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdWriteTimestamp">vkCmdWriteTimestamp</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdCopyQueryPoolResults">vkCmdCopyQueryPoolResults</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdPushConstants">vkCmdPushConstants</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdBeginRenderPass">vkCmdBeginRenderPass</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdNextSubpass">vkCmdNextSubpass</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdEndRenderPass">vkCmdEndRenderPass</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdExecuteCommands">vkCmdExecuteCommands</a></p> +</li> +<li> +<p>The <code>surface</code> parameter in <a href="#vkDestroySurfaceKHR">vkDestroySurfaceKHR</a></p> +</li> +<li> +<p>The <code>surface</code> member of the <code>pCreateInfo</code> parameter in <a href="#vkCreateSwapchainKHR">vkCreateSwapchainKHR</a></p> +</li> +<li> +<p>The <code>oldSwapchain</code> member of the <code>pCreateInfo</code> parameter in <a href="#vkCreateSwapchainKHR">vkCreateSwapchainKHR</a></p> +</li> +<li> +<p>The <code>swapchain</code> parameter in <a href="#vkDestroySwapchainKHR">vkDestroySwapchainKHR</a></p> +</li> +<li> +<p>The <code>swapchain</code> parameter in <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a></p> +</li> +<li> +<p>The <code>semaphore</code> parameter in <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a></p> +</li> +<li> +<p>The <code>fence</code> parameter in <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a></p> +</li> +<li> +<p>The <code>queue</code> parameter in <a href="#vkQueuePresentKHR">vkQueuePresentKHR</a></p> +</li> +<li> +<p>The <code>display</code> parameter in <a href="#vkCreateDisplayModeKHR">vkCreateDisplayModeKHR</a></p> +</li> +<li> +<p>The <code>mode</code> parameter in <a href="#vkGetDisplayPlaneCapabilitiesKHR">vkGetDisplayPlaneCapabilitiesKHR</a></p> +</li> +<li> +<p>The <code>commandPool</code> parameter in <a href="#vkTrimCommandPoolKHR">vkTrimCommandPoolKHR</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdPushDescriptorSetKHR">vkCmdPushDescriptorSetKHR</a></p> +</li> +<li> +<p>The <code>descriptorUpdateTemplate</code> parameter in <a href="#vkDestroyDescriptorUpdateTemplateKHR">vkDestroyDescriptorUpdateTemplateKHR</a></p> +</li> +<li> +<p>The <code>descriptorSet</code> parameter in <a href="#vkUpdateDescriptorSetWithTemplateKHR">vkUpdateDescriptorSetWithTemplateKHR</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdPushDescriptorSetWithTemplateKHR">vkCmdPushDescriptorSetWithTemplateKHR</a></p> +</li> +<li> +<p>The <code>callback</code> parameter in <a href="#vkDestroyDebugReportCallbackEXT">vkDestroyDebugReportCallbackEXT</a></p> +</li> +<li> +<p>The <code>object</code> member of the <code>pTagInfo</code> parameter in <a href="#vkDebugMarkerSetObjectTagEXT">vkDebugMarkerSetObjectTagEXT</a></p> +</li> +<li> +<p>The <code>object</code> member of the <code>pNameInfo</code> parameter in <a href="#vkDebugMarkerSetObjectNameEXT">vkDebugMarkerSetObjectNameEXT</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDrawIndirectCountAMD">vkCmdDrawIndirectCountAMD</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDrawIndexedIndirectCountAMD">vkCmdDrawIndexedIndirectCountAMD</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetDeviceMaskKHX">vkCmdSetDeviceMaskKHX</a></p> +</li> +<li> +<p>The <code>surface</code> parameter in <a href="#vkGetDeviceGroupSurfacePresentModesKHX">vkGetDeviceGroupSurfacePresentModesKHX</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdDispatchBaseKHX">vkCmdDispatchBaseKHX</a></p> +</li> +<li> +<p>The <code>surface</code> parameter in <a href="#vkGetPhysicalDevicePresentRectanglesKHX">vkGetPhysicalDevicePresentRectanglesKHX</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdReserveSpaceForCommandsNVX">vkCmdReserveSpaceForCommandsNVX</a></p> +</li> +<li> +<p>The <code>objectTable</code> parameter in <a href="#vkDestroyObjectTableNVX">vkDestroyObjectTableNVX</a></p> +</li> +<li> +<p>The <code>objectTable</code> parameter in <a href="#vkRegisterObjectsNVX">vkRegisterObjectsNVX</a></p> +</li> +<li> +<p>The <code>objectTable</code> parameter in <a href="#vkUnregisterObjectsNVX">vkUnregisterObjectsNVX</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetViewportWScalingNV">vkCmdSetViewportWScalingNV</a></p> +</li> +<li> +<p>The <code>commandBuffer</code> parameter in <a href="#vkCmdSetDiscardRectangleEXT">vkCmdSetDiscardRectangleEXT</a></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>There are also a few instances where a command <strong class="purple">can</strong> take in a user allocated +list whose contents are externally synchronized parameters. +In these cases, the caller <strong class="purple">must</strong> guarantee that at most one thread is using +a given element within the list at a given time. +These parameters are listed below.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Externally Synchronized Parameter Lists</div> +<div class="ulist"> +<ul> +<li> +<p>Each element of the <code>pWaitSemaphores</code> member of each element of the <code>pSubmits</code> parameter in <a href="#vkQueueSubmit">vkQueueSubmit</a></p> +</li> +<li> +<p>Each element of the <code>pSignalSemaphores</code> member of each element of the <code>pSubmits</code> parameter in <a href="#vkQueueSubmit">vkQueueSubmit</a></p> +</li> +<li> +<p>Each element of the <code>pWaitSemaphores</code> member of each element of the <code>pBindInfo</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>Each element of the <code>pSignalSemaphores</code> member of each element of the <code>pBindInfo</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>The <code>buffer</code> member of each element of the <code>pBufferBinds</code> member of each element of the <code>pBindInfo</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>The <code>image</code> member of each element of the <code>pImageOpaqueBinds</code> member of each element of the <code>pBindInfo</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>The <code>image</code> member of each element of the <code>pImageBinds</code> member of each element of the <code>pBindInfo</code> parameter in <a href="#vkQueueBindSparse">vkQueueBindSparse</a></p> +</li> +<li> +<p>Each element of the <code>pFences</code> parameter in <a href="#vkResetFences">vkResetFences</a></p> +</li> +<li> +<p>Each element of the <code>pDescriptorSets</code> parameter in <a href="#vkFreeDescriptorSets">vkFreeDescriptorSets</a></p> +</li> +<li> +<p>The <code>dstSet</code> member of each element of the <code>pDescriptorWrites</code> parameter in <a href="#vkUpdateDescriptorSets">vkUpdateDescriptorSets</a></p> +</li> +<li> +<p>The <code>dstSet</code> member of each element of the <code>pDescriptorCopies</code> parameter in <a href="#vkUpdateDescriptorSets">vkUpdateDescriptorSets</a></p> +</li> +<li> +<p>Each element of the <code>pCommandBuffers</code> parameter in <a href="#vkFreeCommandBuffers">vkFreeCommandBuffers</a></p> +</li> +<li> +<p>Each element of the <code>pWaitSemaphores</code> member of the <code>pPresentInfo</code> parameter in <a href="#vkQueuePresentKHR">vkQueuePresentKHR</a></p> +</li> +<li> +<p>Each element of the <code>pSwapchains</code> member of the <code>pPresentInfo</code> parameter in <a href="#vkQueuePresentKHR">vkQueuePresentKHR</a></p> +</li> +<li> +<p>The <code>surface</code> member of each element of the <code>pCreateInfos</code> parameter in <a href="#vkCreateSharedSwapchainsKHR">vkCreateSharedSwapchainsKHR</a></p> +</li> +<li> +<p>The <code>oldSwapchain</code> member of each element of the <code>pCreateInfos</code> parameter in <a href="#vkCreateSharedSwapchainsKHR">vkCreateSharedSwapchainsKHR</a></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>In addition, there are some implicit parameters that need to be externally +synchronized. +For example, all <code>commandBuffer</code> parameters that need to be externally +synchronized imply that the <code>commandPool</code> that was passed in when +creating that command buffer also needs to be externally synchronized. +The implicit parameters and their associated object are listed below.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Implicit Externally Synchronized Parameters</div> +<div class="ulist"> +<ul> +<li> +<p>All <code>VkQueue</code> objects created from <code>device</code> in <a href="#vkDeviceWaitIdle">vkDeviceWaitIdle</a></p> +</li> +<li> +<p>Any <code>VkDescriptorSet</code> objects allocated from <code>descriptorPool</code> in <a href="#vkResetDescriptorPool">vkResetDescriptorPool</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from in <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from in <a href="#vkEndCommandBuffer">vkEndCommandBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBindPipeline">vkCmdBindPipeline</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetViewport">vkCmdSetViewport</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetScissor">vkCmdSetScissor</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetLineWidth">vkCmdSetLineWidth</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetDepthBias">vkCmdSetDepthBias</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetBlendConstants">vkCmdSetBlendConstants</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetDepthBounds">vkCmdSetDepthBounds</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetStencilCompareMask">vkCmdSetStencilCompareMask</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetStencilWriteMask">vkCmdSetStencilWriteMask</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetStencilReference">vkCmdSetStencilReference</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBindDescriptorSets">vkCmdBindDescriptorSets</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBindIndexBuffer">vkCmdBindIndexBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBindVertexBuffers">vkCmdBindVertexBuffers</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDraw">vkCmdDraw</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDrawIndexed">vkCmdDrawIndexed</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDrawIndirect">vkCmdDrawIndirect</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDrawIndexedIndirect">vkCmdDrawIndexedIndirect</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDispatch">vkCmdDispatch</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDispatchIndirect">vkCmdDispatchIndirect</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdCopyBuffer">vkCmdCopyBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdCopyImage">vkCmdCopyImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBlitImage">vkCmdBlitImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdCopyBufferToImage">vkCmdCopyBufferToImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdCopyImageToBuffer">vkCmdCopyImageToBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdUpdateBuffer">vkCmdUpdateBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdFillBuffer">vkCmdFillBuffer</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdClearColorImage">vkCmdClearColorImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdClearDepthStencilImage">vkCmdClearDepthStencilImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdClearAttachments">vkCmdClearAttachments</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdResolveImage">vkCmdResolveImage</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetEvent">vkCmdSetEvent</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdResetEvent">vkCmdResetEvent</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdWaitEvents">vkCmdWaitEvents</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdPipelineBarrier">vkCmdPipelineBarrier</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBeginQuery">vkCmdBeginQuery</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdEndQuery">vkCmdEndQuery</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdResetQueryPool">vkCmdResetQueryPool</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdWriteTimestamp">vkCmdWriteTimestamp</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdCopyQueryPoolResults">vkCmdCopyQueryPoolResults</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdPushConstants">vkCmdPushConstants</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdBeginRenderPass">vkCmdBeginRenderPass</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdNextSubpass">vkCmdNextSubpass</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdEndRenderPass">vkCmdEndRenderPass</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdExecuteCommands">vkCmdExecuteCommands</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdPushDescriptorSetKHR">vkCmdPushDescriptorSetKHR</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdPushDescriptorSetWithTemplateKHR">vkCmdPushDescriptorSetWithTemplateKHR</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDebugMarkerBeginEXT">vkCmdDebugMarkerBeginEXT</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDebugMarkerEndEXT">vkCmdDebugMarkerEndEXT</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDebugMarkerInsertEXT">vkCmdDebugMarkerInsertEXT</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDrawIndirectCountAMD">vkCmdDrawIndirectCountAMD</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDrawIndexedIndirectCountAMD">vkCmdDrawIndexedIndirectCountAMD</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetDeviceMaskKHX">vkCmdSetDeviceMaskKHX</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdDispatchBaseKHX">vkCmdDispatchBaseKHX</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdReserveSpaceForCommandsNVX">vkCmdReserveSpaceForCommandsNVX</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetViewportWScalingNV">vkCmdSetViewportWScalingNV</a></p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from, in <a href="#vkCmdSetDiscardRectangleEXT">vkCmdSetDiscardRectangleEXT</a></p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-errors">2.6. Errors</h3> +<div class="paragraph"> +<p>Vulkan is a layered API. +The lowest layer is the core Vulkan layer, as defined by this Specification. +The application <strong class="purple">can</strong> use additional layers above the core for debugging, +validation, and other purposes.</p> +</div> +<div class="paragraph"> +<p>One of the core principles of Vulkan is that building and submitting command +buffers <strong class="purple">should</strong> be highly efficient. +Thus error checking and validation of state in the core layer is minimal, +although more rigorous validation <strong class="purple">can</strong> be enabled through the use of layers.</p> +</div> +<div class="paragraph"> +<p>The core layer assumes applications are using the API correctly. +Except as documented elsewhere in the Specification, the behavior of the +core layer to an application using the API incorrectly is undefined, and +<strong class="purple">may</strong> include program termination. +However, implementations <strong class="purple">must</strong> ensure that incorrect usage by an application +does not affect the integrity of the operating system, the Vulkan +implementation, or other Vulkan client applications in the system, and does +not allow one application to access data belonging to another application. +Applications <strong class="purple">can</strong> request stronger robustness guarantees by enabling the +<code>robustBufferAccess</code> feature as described in <a href="#features">Features, Limits, and Formats</a>.</p> +</div> +<div class="paragraph"> +<p>Validation of correct API usage is left to validation layers. +Applications <strong class="purple">should</strong> be developed with validation layers enabled, to help +catch and eliminate errors. +Once validated, released applications <strong class="purple">should</strong> not enable validation layers +by default.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-validusage">2.6.1. Valid Usage</h4> +<div class="paragraph"> +<p>Valid usage defines a set of conditions which <strong class="purple">must</strong> be met in order to +achieve well-defined run-time behavior in an application. +These conditions depend only on Vulkan state, and the parameters or objects +whose usage is constrained by the condition.</p> +</div> +<div class="paragraph"> +<p>Some valid usage conditions have dependencies on run-time limits or feature +availability. +It is possible to validate these conditions against Vulkan’s minimum +supported values for these limits and features, or some subset of other +known values.</p> +</div> +<div class="paragraph"> +<p>Valid usage conditions do not cover conditions where well-defined behavior +(including returning an error code) exists.</p> +</div> +<div class="paragraph"> +<p>Valid usage conditions <strong class="purple">should</strong> apply to the command or structure where +complete information about the condition would be known during execution of +an application. +This is such that a validation layer or linter <strong class="purple">can</strong> be written directly +against these statements at the point they are specified.</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>This does lead to some non-obvious places for valid usage statements. +For instance, the valid values for a structure might depend on a separate +value in the calling command. +In this case, the structure itself will not reference this valid usage as it +is impossible to determine validity from the structure that it is invalid - +instead this valid usage would be attached to the calling command.</p> +</div> +<div class="paragraph"> +<p>Another example is draw state - the state setters are independent, and can +cause a legitimately invalid state configuration between draw calls; so the +valid usage statements are attached to the place where all state needs to be +valid - at the draw command.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Valid usage conditions are described in a block labelled “Valid Usage” +following each command or structure they apply to.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-implicit-validity">2.6.2. Implicit Valid Usage</h4> +<div class="paragraph"> +<p>Some valid usage conditions apply to all commands and structures in the API, +unless explicitly denoted otherwise for a specific command or structure. +These conditions are considered <em>implicit</em>, and are described in a block +labelled “Valid Usage (Implicit)” following each command or structure they +apply to. +Implicit valid usage conditions are described in detail below.</p> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-handles">Valid Usage for Object Handles</h5> +<div class="paragraph"> +<p>Any input parameter to a command that is an object handle <strong class="purple">must</strong> be a valid +object handle, unless otherwise specified. +An object handle is valid if:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>It has been created or allocated by a previous, successful call to the +API. +Such calls are noted in the specification.</p> +</li> +<li> +<p>It has not been deleted or freed by a previous call to the API. +Such calls are noted in the specification.</p> +</li> +<li> +<p>Any objects used by that object, either as part of creation or +execution, <strong class="purple">must</strong> also be valid.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The reserved values <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a> and <code>NULL</code> <strong class="purple">can</strong> be used in place of +valid non-dispatchable handles and dispatchable handles, respectively, when +<em>explicitly called out in the specification</em>. +Any command that creates an object successfully <strong class="purple">must</strong> not return these +values. +It is valid to pass these values to <code>vkDestroy</code>* or <code>vkFree</code>* +commands, which will silently ignore these values.</p> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-pointers">Valid Usage for Pointers</h5> +<div class="paragraph"> +<p>Any parameter that is a pointer <strong class="purple">must</strong> be a valid pointer. +A pointer is valid if it points at memory containing values of the number +and type(s) expected by the command, and all fundamental types accessed +through the pointer (e.g. as elements of an array or as members of a +structure) satisfy the alignment requirements of the host processor.</p> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-enums">Valid Usage for Enumerated Types</h5> +<div class="paragraph"> +<p>Any parameter of an enumerated type <strong class="purple">must</strong> be a valid enumerant for that +type. +A enumerant is valid if:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>The enumerant is defined as part of the enumerated type.</p> +</li> +<li> +<p>The enumerant is not one of the special values defined for the +enumerated type, which are suffixed with <code>_BEGIN_RANGE</code>, +<code>_END_RANGE</code>, <code>_RANGE_SIZE</code> or <code>_MAX_ENUM</code>.</p> +</li> +</ul> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-flags">Valid Usage for Flags</h5> +<div class="paragraph"> +<p>A collection of flags is represented by a bitmask using the type +<code>VkFlags</code>:</p> +</div> +<div id="VkFlags" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> uint32_t VkFlags;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Bitmasks are passed to many commands and structures to compactly represent +options, but <code>VkFlags</code> is not used directly in the API. +Instead, a <code>Vk*Flags</code> type which is an alias of <code>VkFlags</code>, and +whose name matches the corresponding <code>Vk*FlagBits</code> that are valid for +that type, is used. +These aliases are described in the <a href="#boilerplate-flags">Flag Types</a> appendix +of the Specification.</p> +</div> +<div class="paragraph"> +<p>Any <code>Vk*Flags</code> member or parameter used in the API <strong class="purple">must</strong> be a valid +combination of bit flags. +A valid combination is either zero or the bitwise OR of valid bit flags. +A bit flag is valid if:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>The bit flag is defined as part of the <code>Vk*FlagBits</code> type, where the +bits type is obtained by taking the flag type and replacing the trailing +<code>Flags</code> with <code>FlagBits</code>. +For example, a flag value of type <a href="#VkColorComponentFlags">VkColorComponentFlags</a> <strong class="purple">must</strong> +contain only bit flags defined by <a href="#VkColorComponentFlagBits">VkColorComponentFlagBits</a>.</p> +</li> +<li> +<p>The flag is allowed in the context in which it is being used. +For example, in some cases, certain bit flags or combinations of bit +flags are mutually exclusive.</p> +</li> +</ul> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-sType">Valid Usage for Structure Types</h5> +<div class="paragraph"> +<p>Any parameter that is a structure containing a <code>sType</code> member <strong class="purple">must</strong> have +a value of <code>sType</code> which is a valid <a href="#VkStructureType">VkStructureType</a> value matching +the type of the structure. +As a general rule, the name of this value is obtained by taking the +structure name, stripping the leading <code>Vk</code>, prefixing each capital +letter with <code>_</code>, converting the entire resulting string to upper case, +and prefixing it with <code>VK_STRUCTURE_TYPE_</code>. +For example, structures of type <code>VkImageCreateInfo</code> <strong class="purple">must</strong> have a +<code>sType</code> value of <code>VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO</code>.</p> +</div> +<div class="paragraph"> +<p>The values <code>VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO</code> and +<code>VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO</code> are reserved for internal +use by the loader, and do not have corresponding Vulkan structures in this +specification.</p> +</div> +<div class="paragraph"> +<p>The list of supported <a href="#boilerplate-sType">structure types</a> is defined in an +appendix.</p> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-pNext">Valid Usage for Structure Pointer Chains</h5> +<div class="paragraph"> +<p>Any parameter that is a structure containing a <code>void*</code> <code>pNext</code> member +<strong class="purple">must</strong> have a value of <code>pNext</code> that is either <code>NULL</code>, or points to a +valid structure defined by an extension, containing <code>sType</code> and +<code>pNext</code> members as described in the <a href="#vulkan-styleguide">Vulkan +Documentation and Extensions</a> document in the section “Extension +Interactions”. +If that extension is supported by the implementation, then it <strong class="purple">must</strong> be +enabled. +Any component of the implementation (the loader, any enabled layers, and +drivers) <strong class="purple">must</strong> skip over, without processing (other than reading the +<code>sType</code> and <code>pNext</code> members) any chained structures with <code>sType</code> +values not defined by extensions supported by that component.</p> +</div> +<div class="paragraph"> +<p>Extension structures are not described in the base Vulkan specification, but +either in layered specifications incorporating those extensions, or in +separate vendor-provided documents.</p> +</div> +</div> +<div class="sect4"> +<h5 id="fundamentals-validusage-nested-structs">Valid Usage for Nested Structures</h5> +<div class="paragraph"> +<p>The above conditions also apply recursively to members of structures +provided as input to a command, either as a direct argument to the command, +or themselves a member of another structure.</p> +</div> +<div class="paragraph"> +<p>Specifics on valid usage of each command are covered in their individual +sections.</p> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-returncodes">2.6.3. Return Codes</h4> +<div class="paragraph"> +<p>While the core Vulkan API is not designed to capture incorrect usage, some +circumstances still require return codes. +Commands in Vulkan return their status via return codes that are in one of +two categories:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Successful completion codes are returned when a command needs to +communicate success or status information. +All successful completion codes are non-negative values.</p> +</li> +<li> +<p>Run time error codes are returned when a command needs to communicate a +failure that could only be detected at run time. +All run time error codes are negative values.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>All return codes in Vulkan are reported via <a href="#VkResult">VkResult</a> return values. +The possible codes are:</p> +</div> +<div id="VkResult" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkResult { + VK_SUCCESS = <span class="integer">0</span>, + VK_NOT_READY = <span class="integer">1</span>, + VK_TIMEOUT = <span class="integer">2</span>, + VK_EVENT_SET = <span class="integer">3</span>, + VK_EVENT_RESET = <span class="integer">4</span>, + VK_INCOMPLETE = <span class="integer">5</span>, + VK_ERROR_OUT_OF_HOST_MEMORY = -<span class="integer">1</span>, + VK_ERROR_OUT_OF_DEVICE_MEMORY = -<span class="integer">2</span>, + VK_ERROR_INITIALIZATION_FAILED = -<span class="integer">3</span>, + VK_ERROR_DEVICE_LOST = -<span class="integer">4</span>, + VK_ERROR_MEMORY_MAP_FAILED = -<span class="integer">5</span>, + VK_ERROR_LAYER_NOT_PRESENT = -<span class="integer">6</span>, + VK_ERROR_EXTENSION_NOT_PRESENT = -<span class="integer">7</span>, + VK_ERROR_FEATURE_NOT_PRESENT = -<span class="integer">8</span>, + VK_ERROR_INCOMPATIBLE_DRIVER = -<span class="integer">9</span>, + VK_ERROR_TOO_MANY_OBJECTS = -<span class="integer">10</span>, + VK_ERROR_FORMAT_NOT_SUPPORTED = -<span class="integer">11</span>, + VK_ERROR_FRAGMENTED_POOL = -<span class="integer">12</span>, + VK_ERROR_SURFACE_LOST_KHR = -<span class="integer">1000000000</span>, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -<span class="integer">1000000001</span>, + VK_SUBOPTIMAL_KHR = <span class="integer">1000001003</span>, + VK_ERROR_OUT_OF_DATE_KHR = -<span class="integer">1000001004</span>, + VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -<span class="integer">1000003001</span>, + VK_ERROR_VALIDATION_FAILED_EXT = -<span class="integer">1000011001</span>, + VK_ERROR_INVALID_SHADER_NV = -<span class="integer">1000012000</span>, + VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -<span class="integer">1000069000</span>, + VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX = -<span class="integer">1000072003</span>, +} VkResult;</code></pre> +</div> +</div> +<div id="fundamentals-successcodes" class="ulist"> +<div class="title">Success Codes</div> +<ul> +<li> +<p><code>VK_SUCCESS</code> Command successfully completed</p> +</li> +<li> +<p><code>VK_NOT_READY</code> A fence or query has not yet completed</p> +</li> +<li> +<p><code>VK_TIMEOUT</code> A wait operation has not completed in the specified +time</p> +</li> +<li> +<p><code>VK_EVENT_SET</code> An event is signaled</p> +</li> +<li> +<p><code>VK_EVENT_RESET</code> An event is unsignaled</p> +</li> +<li> +<p><code>VK_INCOMPLETE</code> A return array was too small for the result</p> +</li> +<li> +<p><code>VK_SUBOPTIMAL_KHR</code> A swapchain no longer matches the surface +properties exactly, but <strong class="purple">can</strong> still be used to present to the surface +successfully.</p> +</li> +</ul> +</div> +<div id="fundamentals-errorcodes" class="ulist"> +<div class="title">Error codes</div> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code> A host memory allocation has failed.</p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code> A device memory allocation has +failed.</p> +</li> +<li> +<p><code>VK_ERROR_INITIALIZATION_FAILED</code> Initialization of an object could +not be completed for implementation-specific reasons.</p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code> The logical or physical device has been lost. +See <a href="#devsandqueues-lost-device">Lost Device</a></p> +</li> +<li> +<p><code>VK_ERROR_MEMORY_MAP_FAILED</code> Mapping of a memory object has failed.</p> +</li> +<li> +<p><code>VK_ERROR_LAYER_NOT_PRESENT</code> A requested layer is not present or +could not be loaded.</p> +</li> +<li> +<p><code>VK_ERROR_EXTENSION_NOT_PRESENT</code> A requested extension is not +supported.</p> +</li> +<li> +<p><code>VK_ERROR_FEATURE_NOT_PRESENT</code> A requested feature is not supported.</p> +</li> +<li> +<p><code>VK_ERROR_INCOMPATIBLE_DRIVER</code> The requested version of Vulkan is +not supported by the driver or is otherwise incompatible for +implementation-specific reasons.</p> +</li> +<li> +<p><code>VK_ERROR_TOO_MANY_OBJECTS</code> Too many objects of the type have +already been created.</p> +</li> +<li> +<p><code>VK_ERROR_FORMAT_NOT_SUPPORTED</code> A requested format is not supported +on this device.</p> +</li> +<li> +<p><code>VK_ERROR_FRAGMENTED_POOL</code> A requested pool allocation has failed +due to fragmentation of the pool’s memory.</p> +</li> +<li> +<p><code>VK_ERROR_SURFACE_LOST_KHR</code> A surface is no longer available.</p> +</li> +<li> +<p><code>VK_ERROR_NATIVE_WINDOW_IN_USE_KHR</code> The requested window is already +in use by Vulkan or another API in a manner which prevents it from being +used again.</p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DATE_KHR</code> A surface has changed in such a way that +it is no longer compatible with the swapchain, and further presentation +requests using the swapchain will fail. +Applications <strong class="purple">must</strong> query the new surface properties and recreate their +swapchain if they wish to continue presenting to the surface.</p> +</li> +<li> +<p><code>VK_ERROR_INCOMPATIBLE_DISPLAY_KHR</code> The display used by a swapchain +does not use the same presentable image layout, or is incompatible in a +way that prevents sharing an image.</p> +</li> +<li> +<p><code>VK_ERROR_INVALID_SHADER_NV</code> One or more shaders failed to compile +or link. +More details are reported back to the application via +VK_EXT_debug_report if enabled.</p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_POOL_MEMORY_KHR</code> There is no more memory in the +descriptor set pool.</p> +</li> +<li> +<p><code>VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX</code> An external handle is not a +valid handle of the specified type.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If a command returns a run time error, it will leave any result pointers +unmodified, unless other behavior is explicitly defined in the +specification.</p> +</div> +<div class="paragraph"> +<p>Out of memory errors do not damage any currently existing Vulkan objects. +Objects that have already been successfully created <strong class="purple">can</strong> still be used by +the application.</p> +</div> +<div class="paragraph"> +<p>Performance-critical commands generally do not have return codes. +If a run time error occurs in such commands, the implementation will defer +reporting the error until a specified point. +For commands that record into command buffers (<code>vkCmd</code>*) run time errors +are reported by <code>vkEndCommandBuffer</code>.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-numerics">2.7. Numeric Representation and Computation</h3> +<div class="paragraph"> +<p>Implementations normally perform computations in floating-point, and <strong class="purple">must</strong> +meet the range and precision requirements defined under “Floating-Point +Computation” below.</p> +</div> +<div class="paragraph"> +<p>These requirements only apply to computations performed in Vulkan operations +outside of shader execution, such as texture image specification and +sampling, and per-fragment operations. +Range and precision requirements during shader execution differ and are +specified by the <a href="#spirvenv-precision-operation">Precision and Operation of +SPIR-V Instructions</a> section.</p> +</div> +<div class="paragraph"> +<p>In some cases, the representation and/or precision of operations is +implicitly limited by the specified format of vertex or texel data consumed +by Vulkan. +Specific floating-point formats are described later in this section.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-floatingpoint">2.7.1. Floating-Point Computation</h4> +<div class="paragraph"> +<p>Most floating-point computation is performed in SPIR-V shader modules. +The properties of computation within shaders are constrained as defined by +the <a href="#spirvenv-precision-operation">Precision and Operation of SPIR-V +Instructions</a> section.</p> +</div> +<div class="paragraph"> +<p>Some floating-point computation is performed outside of shaders, such as +viewport and depth range calculations. +For these computations, we do not specify how floating-point numbers are to +be represented, or the details of how operations on them are performed, but +only place minimal requirements on representation and precision as described +in the remainder of this section.</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">editing-note</div> +<div class="paragraph"> +<p>(Jon, Bug 14966) This is a rat’s nest of complexity, both in terms of +describing/enumerating places such computation <strong class="purple">may</strong> take place (other than +“not shader code”) and in how implementations <strong class="purple">may</strong> do it. +We have consciously deferred the resolution of this issue to post-1.0, and +in the meantime, the following language inherited from the OpenGL +Specification is inserted as a placeholder. +Hopefully it <strong class="purple">can</strong> be tightened up considerably.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>We require simply that numbers' floating-point parts contain enough bits and +that their exponent fields are large enough so that individual results of +floating-point operations are accurate to about 1 part in 10<sup>5</sup>. +The maximum representable magnitude for all floating-point values <strong class="purple">must</strong> be +at least 2<sup>32</sup>.</p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">x × 0 = 0 × x = 0</span> for any non-infinite and +non-<span class="eq">NaN</span> <span class="eq">x</span>.</p> +</dd> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">1 × x = x × 1 = x</span>.</p> +</dd> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">x + 0 = 0 + x = x</span>.</p> +</dd> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">0<sup>0</sup> = 1</span>.</p> +</dd> +</dl> +</div> +<div class="paragraph"> +<p>Occasionally, further requirements will be specified. +Most single-precision floating-point formats meet these requirements.</p> +</div> +<div class="paragraph"> +<p>The special values <span class="eq">Inf</span> and <span class="eq">-Inf</span> encode values with magnitudes +too large to be represented; the special value <span class="eq">NaN</span> encodes “Not +A Number” values resulting from undefined arithmetic operations such +as <span class="eq">0 / 0</span>. +Implementations <strong class="purple">may</strong> support <span class="eq">Inf</span> and <span class="eq">NaN</span> in their floating-point +computations.</p> +</div> +<div class="paragraph"> +<p>Any representable floating-point value is legal as input to a Vulkan command +that requires floating-point data. +The result of providing a value that is not a floating-point number to such +a command is unspecified, but <strong class="purple">must</strong> not lead to Vulkan interruption or +termination. +In <a href="#ieee-754">IEEE 754</a> arithmetic, for example, providing a negative zero +or a denormalized number to an Vulkan command <strong class="purple">must</strong> yield deterministic +results, while providing a <span class="eq">NaN</span> or <span class="eq">Inf</span> yields unspecified +results.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-fp16">2.7.2. 16-Bit Floating-Point Numbers</h4> +<div class="paragraph"> +<p>16-bit floating point numbers are defined in the “16-bit floating point +numbers” section of the <a href="#data-format">Khronos Data Format Specification</a>.</p> +</div> +<div class="paragraph"> +<p>Any representable 16-bit floating-point value is legal as input to a Vulkan +command that accepts 16-bit floating-point data. +The result of providing a value that is not a floating-point number (such as +<span class="eq">Inf</span> or <span class="eq">NaN</span>) to such a command is unspecified, but <strong class="purple">must</strong> not lead +to Vulkan interruption or termination. +Providing a denormalized number or negative zero to Vulkan <strong class="purple">must</strong> yield +deterministic results.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-fp11">2.7.3. Unsigned 11-Bit Floating-Point Numbers</h4> +<div class="paragraph"> +<p>Unsigned 11-bit floating point numbers are defined in the “Unsigned 11-bit +floating point numbers” section of the <a href="#data-format">Khronos Data Format +Specification</a>.</p> +</div> +<div class="paragraph"> +<p>When a floating-point value is converted to an unsigned 11-bit +floating-point representation, finite values are rounded to the closest +representable finite value.</p> +</div> +<div class="paragraph"> +<p>While less accurate, implementations are allowed to always round in the +direction of zero. +This means negative values are converted to zero. +Likewise, finite positive values greater than 65024 (the maximum finite +representable unsigned 11-bit floating-point value) are converted to 65024. +Additionally: negative infinity is converted to zero; positive infinity is +converted to positive infinity; and both positive and negative <span class="eq">NaN</span> are +converted to positive <span class="eq">NaN</span>.</p> +</div> +<div class="paragraph"> +<p>Any representable unsigned 11-bit floating-point value is legal as input to +a Vulkan command that accepts 11-bit floating-point data. +The result of providing a value that is not a floating-point number (such as +<span class="eq">Inf</span> or <span class="eq">NaN</span>) to such a command is unspecified, but <strong class="purple">must</strong> not lead +to Vulkan interruption or termination. +Providing a denormalized number to Vulkan <strong class="purple">must</strong> yield deterministic results.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-fp10">2.7.4. Unsigned 10-Bit Floating-Point Numbers</h4> +<div class="paragraph"> +<p>Unsigned 10-bit floating point numbers are defined in the “Unsigned 10-bit +floating point numbers” section of the <a href="#data-format">Khronos Data Format +Specification</a>.</p> +</div> +<div class="paragraph"> +<p>When a floating-point value is converted to an unsigned 10-bit +floating-point representation, finite values are rounded to the closest +representable finite value.</p> +</div> +<div class="paragraph"> +<p>While less accurate, implementations are allowed to always round in the +direction of zero. +This means negative values are converted to zero. +Likewise, finite positive values greater than 64512 (the maximum finite +representable unsigned 10-bit floating-point value) are converted to 64512. +Additionally: negative infinity is converted to zero; positive infinity is +converted to positive infinity; and both positive and negative <span class="eq">NaN</span> are +converted to positive <span class="eq">NaN</span>.</p> +</div> +<div class="paragraph"> +<p>Any representable unsigned 10-bit floating-point value is legal as input to +a Vulkan command that accepts 10-bit floating-point data. +The result of providing a value that is not a floating-point number (such as +<span class="eq">Inf</span> or <span class="eq">NaN</span>) to such a command is unspecified, but <strong class="purple">must</strong> not lead +to Vulkan interruption or termination. +Providing a denormalized number to Vulkan <strong class="purple">must</strong> yield deterministic results.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-general">2.7.5. General Requirements</h4> +<div class="paragraph"> +<p>Some calculations require division. +In such cases (including implied divisions performed by vector +normalization), division by zero produces an unspecified result but <strong class="purple">must</strong> +not lead to Vulkan interruption or termination.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-fixedconv">2.8. Fixed-Point Data Conversions</h3> +<div class="paragraph"> +<p>When generic vertex attributes and pixel color or depth <em>components</em> are +represented as integers, they are often (but not always) considered to be +<em>normalized</em>. +Normalized integer values are treated specially when being converted to and +from floating-point values, and are usually referred to as <em>normalized +fixed-point</em>.</p> +</div> +<div class="paragraph"> +<p>In the remainder of this section, <span class="eq">b</span> denotes the bit width of the +fixed-point integer representation. +When the integer is one of the types defined by the API, <span class="eq">b</span> is the bit +width of that type. +When the integer comes from an <a href="#resources-images">image</a> containing color +or depth component texels, <span class="eq">b</span> is the number of bits allocated to that +component in its <a href="#features-formats">specified image format</a>.</p> +</div> +<div class="paragraph"> +<p>The signed and unsigned fixed-point representations are assumed to be +<span class="eq">b</span>-bit binary two’s-complement integers and binary unsigned integers, +respectively.</p> +</div> +<div class="sect3"> +<h4 id="fundamentals-fixedfpconv">2.8.1. Conversion from Normalized Fixed-Point to Floating-Point</h4> +<div class="paragraph"> +<p>Unsigned normalized fixed-point integers represent numbers in the range +<span class="eq">[0,1]</span>. +The conversion from an unsigned normalized fixed-point value <span class="eq">c</span> to the +corresponding floating-point value <span class="eq">f</span> is defined as</p> +</div> +<div class="stemblock"> +<div class="content"> +\[f = { c \over { 2^b - 1 } }\] +</div> +</div> +<div class="paragraph"> +<p>Signed normalized fixed-point integers represent numbers in the range +<span class="eq">[-1,1]</span>. +The conversion from a signed normalized fixed-point value <span class="eq">c</span> to the +corresponding floating-point value <span class="eq">f</span> is performed using</p> +</div> +<div class="stemblock"> +<div class="content"> +\[f = \max\left( {c \over {2^{b-1} - 1}}, -1.0 \right)\] +</div> +</div> +<div class="paragraph"> +<p>Only the range <span class="eq">[-2<sup>b-1</sup> + 1, 2<sup>b-1</sup> - 1]</span> is used to represent signed +fixed-point values in the range <span class="eq">[-1,1]</span>. +For example, if <span class="eq">b = 8</span>, then the integer value <span class="eq">-127</span> corresponds +to <span class="eq">-1.0</span> and the value 127 corresponds to <span class="eq">1.0</span>. +Note that while zero is exactly expressible in this representation, one +value (<span class="eq">-128</span> in the example) is outside the representable range, and +<strong class="purple">must</strong> be clamped before use. +This equation is used everywhere that signed normalized fixed-point values +are converted to floating-point.</p> +</div> +</div> +<div class="sect3"> +<h4 id="fundamentals-fpfixedconv">2.8.2. Conversion from Floating-Point to Normalized Fixed-Point</h4> +<div class="paragraph"> +<p>The conversion from a floating-point value <span class="eq">f</span> to the corresponding +unsigned normalized fixed-point value <span class="eq">c</span> is defined by first clamping +<span class="eq">f</span> to the range <span class="eq">[0,1]</span>, then computing</p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">c = convertFloatToUint(f × (2<sup>b</sup> - 1), b)</span></p> +</dd> +</dl> +</div> +<div class="paragraph"> +<p>where <span class="eq">convertFloatToUint}(r,b)</span> returns one of the two unsigned binary +integer values with exactly <span class="eq">b</span> bits which are closest to the +floating-point value <span class="eq">r</span>. +Implementations <strong class="purple">should</strong> round to nearest. +If <span class="eq">r</span> is equal to an integer, then that integer value <strong class="purple">must</strong> be +returned. +In particular, if <span class="eq">f</span> is equal to 0.0 or 1.0, then <span class="eq">c</span> <strong class="purple">must</strong> be +assigned 0 or <span class="eq">2<sup>b</sup> - 1</span>, respectively.</p> +</div> +<div class="paragraph"> +<p>The conversion from a floating-point value <span class="eq">f</span> to the corresponding +signed normalized fixed-point value <span class="eq">c</span> is performed by clamping <span class="eq">f</span> +to the range <span class="eq">[-1,1]</span>, then computing</p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"></dt> +<dd> +<p><span class="eq">c = convertFloatToInt(f × (2<sup>b-1</sup> - 1), b)</span></p> +</dd> +</dl> +</div> +<div class="paragraph"> +<p>where <span class="eq">convertFloatToInt(r,b)</span> returns one of the two signed +two’s-complement binary integer values with exactly <span class="eq">b</span> bits which are +closest to the floating-point value <span class="eq">r</span>. +Implementations <strong class="purple">should</strong> round to nearest. +If <span class="eq">r</span> is equal to an integer, then that integer value <strong class="purple">must</strong> be +returned. +In particular, if <span class="eq">f</span> is equal to -1.0, 0.0, or 1.0, then <span class="eq">c</span> <strong class="purple">must</strong> +be assigned <span class="eq">-(2<sup>b-1</sup> - 1)</span>, 0, or <span class="eq">2<sup>b-1</sup> - 1</span>, respectively.</p> +</div> +<div class="paragraph"> +<p>This equation is used everywhere that floating-point values are converted to +signed normalized fixed-point.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-versionnum">2.9. API Version Numbers and Semantics</h3> +<div class="paragraph"> +<p>The Vulkan version number is used in several places in the API. +In each such use, the API <em>major version number</em>, <em>minor version number</em>, +and <em>patch version number</em> are packed into a 32-bit integer as follows:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>The major version number is a 10-bit integer packed into bits 31-22.</p> +</li> +<li> +<p>The minor version number is a 10-bit integer packed into bits 21-12.</p> +</li> +<li> +<p>The patch version number is a 12-bit integer packed into bits 11-0.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Differences in any of the Vulkan version numbers indicates a change to the +API in some way, with each part of the version number indicating a different +scope of changes.</p> +</div> +<div class="paragraph"> +<p>A difference in patch version numbers indicates that some usually small part +of the specification or header has been modified, typically to fix a bug, +and <strong class="purple">may</strong> have an impact on the behavior of existing functionality. +Differences in this version number <strong class="purple">should</strong> not affect either <em>full +compatibility</em> or <em>backwards compatibility</em> between two versions, or add +additional interfaces to the API.</p> +</div> +<div class="paragraph"> +<p>A difference in minor version numbers indicates that some amount of new +functionality has been added. +This will usually include new interfaces in the header, and <strong class="purple">may</strong> also +include behavior changes and bug fixes. +Functionality <strong class="purple">may</strong> be deprecated in a minor revision, but will not be +removed. +When a new minor version is introduced, the patch version is reset to 0, and +each minor revision maintains its own set of patch versions. +Differences in this version <strong class="purple">should</strong> not affect backwards compatibility, but +will affect full compatibility.</p> +</div> +<div class="paragraph"> +<p>A difference in major version numbers indicates a large set of changes to +the API, potentially including new functionality and header interfaces, +behavioral changes, removal of deprecated features, modification or outright +replacement of any feature, and is thus very likely to break any and all +compatibility. +Differences in this version will typically require significant modification +to an application in order for it to function.</p> +</div> +<div class="paragraph"> +<p>C language macros for manipulating version numbers are defined in the +<a href="#boilerplate-versions">Version Number Macros</a> appendix.</p> +</div> +</div> +<div class="sect2"> +<h3 id="fundamentals-common-objects">2.10. Common Object Types</h3> +<div class="paragraph"> +<p>Some types of Vulkan objects are used in many different structures and +command parameters, and are described here. +These types include <em>offsets</em>, <em>extents</em>, and <em>rectangles</em>.</p> +</div> +<div class="sect3"> +<h4 id="_offsets">2.10.1. Offsets</h4> +<div class="paragraph"> +<p>Offsets are used to describe a pixel location within an image or +framebuffer, as an (x,y) location for two-dimensional images, or an (x,y,z) +location for three-dimensional images.</p> +</div> +<div class="paragraph"> +<p>A two-dimensional offsets is defined by the structure:</p> +</div> +<div id="VkOffset2D" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>A three-dimensional offset is defined by the structure:</p> +</div> +<div id="VkOffset3D" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D;</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_extents">2.10.2. Extents</h4> +<div class="paragraph"> +<p>Extents are used to describe the size of a rectangular region of pixels +within an image or framebuffer, as (width,height) for two-dimensional +images, or as (width,height,depth) for three-dimensional images.</p> +</div> +<div class="paragraph"> +<p>A two-dimensional extent is defined by the structure:</p> +</div> +<div id="VkExtent2D" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>A three-dimensional extent is defined by the structure:</p> +</div> +<div id="VkExtent3D" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D;</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_rectangles">2.10.3. Rectangles</h4> +<div class="paragraph"> +<p>Rectangles are used to describe a specified rectangular region of pixels +within an image or framebuffer. +Rectangles include both an offset and an extent of the same dimensionality, +as described above. +Two-dimensional rectangles are defined by the structure</p> +</div> +<div id="VkRect2D" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D;</code></pre> +</div> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="initialization">3. Initialization</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Before using Vulkan, an application <strong class="purple">must</strong> initialize it by loading the +Vulkan commands, and creating a <code>VkInstance</code> object.</p> +</div> +<div class="sect2"> +<h3 id="initialization-functionpointers">3.1. Command Function Pointers</h3> +<div class="paragraph"> +<p>Vulkan commands are not necessarily exposed statically on a platform. +Function pointers for all Vulkan commands <strong class="purple">can</strong> be obtained with the command:</p> +</div> +<div id="vkGetInstanceProcAddr" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">PFN_vkVoidFunction vkGetInstanceProcAddr( + VkInstance instance, + <span class="directive">const</span> <span class="predefined-type">char</span>* pName);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> is the instance that the function pointer will be +compatible with, or <code>NULL</code> for commands not dependent on any instance.</p> +</li> +<li> +<p><code>pName</code> is the name of the command to obtain.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>vkGetInstanceProcAddr</code> itself is obtained in a platform- and loader- +specific manner. +Typically, the loader library will export this command as a function symbol, +so applications <strong class="purple">can</strong> link against the loader library, or load it dynamically +and look up the symbol using platform-specific APIs. +Loaders are encouraged to export function symbols for all other core Vulkan +commands as well; if this is done, then applications that use only the core +Vulkan commands have no need to use <code>vkGetInstanceProcAddr</code>.</p> +</div> +<div class="paragraph"> +<p>The table below defines the various use cases for +<code>vkGetInstanceProcAddr</code> and expected return value ("fp" is function +pointer) for each case.</p> +</div> +<div class="paragraph"> +<p>The returned function pointer is of type <a href="#PFN_vkVoidFunction">PFN_vkVoidFunction</a>, and must +be cast to the type of the command being queried.</p> +</div> +<table class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 1. vkGetInstanceProcAddr behavior</caption> +<colgroup> +<col style="width: 33.3333%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3334%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top"><code>instance</code></th> +<th class="tableblock halign-left valign-top"><code>pName</code></th> +<th class="tableblock halign-left valign-top">return value</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">*</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">undefined</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">invalid instance</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">*</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">undefined</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#vkEnumerateInstanceExtensionProperties">vkEnumerateInstanceExtensionProperties</a></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#vkEnumerateInstanceLayerProperties">vkEnumerateInstanceLayerProperties</a></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#vkCreateInstance">vkCreateInstance</a></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">* (any <code>pName</code> not covered above)</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">instance</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">core Vulkan command</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp<sup>1</sup></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">instance</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">enabled instance extension commands for <code>instance</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp<sup>1</sup></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">instance</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">available device extension<sup>2</sup> commands for <code>instance</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp<sup>1</sup></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">instance</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">* (any <code>pName</code> not covered above)</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +</tr> +</tbody> +</table> +<div class="dlist"> +<dl> +<dt class="hdlist1">1</dt> +<dd> +<p>The returned function pointer <strong class="purple">must</strong> only be called with a dispatchable +object (the first parameter) that is <code>instance</code> or a child of +<code>instance</code>. +e.g. <code>VkInstance</code>, <code>VkPhysicalDevice</code>, <code>VkDevice</code>, +<code>VkQueue</code>, or <code>VkCommandBuffer</code>.</p> +</dd> +<dt class="hdlist1">2</dt> +<dd> +<p>An “available extension” is an extension function supported by any of +the loader, driver or layer.</p> +</dd> +</dl> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p>If <code>instance</code> is not <code>NULL</code>, <code>instance</code> <strong class="purple">must</strong> be a valid <code>VkInstance</code> handle</p> +</li> +<li> +<p><code>pName</code> <strong class="purple">must</strong> be a null-terminated string</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>In order to support systems with multiple Vulkan implementations comprising +heterogeneous collections of hardware and software, the function pointers +returned by <code>vkGetInstanceProcAddr</code> <strong class="purple">may</strong> point to dispatch code, which +calls a different real implementation for different <code>VkDevice</code> objects +(and objects created from them). +The overhead of this internal dispatch <strong class="purple">can</strong> be avoided by obtaining +device-specific function pointers for any commands that use a device or +device-child object as their dispatchable object. +Such function pointers <strong class="purple">can</strong> be obtained with the command:</p> +</div> +<div id="vkGetDeviceProcAddr" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">PFN_vkVoidFunction vkGetDeviceProcAddr( + VkDevice device, + <span class="directive">const</span> <span class="predefined-type">char</span>* pName);</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The table below defines the various use cases for <code>vkGetDeviceProcAddr</code> +and expected return value for each case.</p> +</div> +<div class="paragraph"> +<p>The returned function pointer is of type <a href="#PFN_vkVoidFunction">PFN_vkVoidFunction</a>, and must +be cast to the type of the command being queried.</p> +</div> +<table class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 2. vkGetDeviceProcAddr behavior</caption> +<colgroup> +<col style="width: 33.3333%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3334%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top"><code>device</code></th> +<th class="tableblock halign-left valign-top"><code>pName</code></th> +<th class="tableblock halign-left valign-top">return value</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">*</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">undefined</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">invalid device</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">*</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">undefined</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">device</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">undefined</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">device</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">core Vulkan command</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp<sup>1</sup></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">device</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">enabled extension commands</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">fp<sup>1</sup></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">device</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">* (any <code>pName</code> not covered above)</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NULL</code></p></td> +</tr> +</tbody> +</table> +<div class="dlist"> +<dl> +<dt class="hdlist1">1</dt> +<dd> +<p>The returned function pointer <strong class="purple">must</strong> only be called with a dispatchable +object (the first parameter) that is <code>device</code> or a child of +<code>device</code>. +e.g. <code>VkDevice</code>, <code>VkQueue</code>, or <code>VkCommandBuffer</code>.</p> +</dd> +</dl> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pName</code> <strong class="purple">must</strong> be a null-terminated string</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The definition of <a href="#PFN_vkVoidFunction">PFN_vkVoidFunction</a> is:</p> +</div> +<div id="PFN_vkVoidFunction" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="directive">void</span> (VKAPI_PTR *PFN_vkVoidFunction)(<span class="directive">void</span>);</code></pre> +</div> +</div> +<div class="sect3"> +<h4 id="_extending_physical_device_from_device_extensions">3.1.1. Extending Physical Device From Device Extensions</h4> +<div class="paragraph"> +<p>When the VK_KHR_get_physical_device_properties2 extension is enabled, +physical device extension commands and structures <strong class="purple">can</strong> be used with a +physical device if the corresponding extension is enumerated by +<a href="#vkEnumerateDeviceExtensionProperties">vkEnumerateDeviceExtensionProperties</a> for that physical device, even +before a logical device has been created.</p> +</div> +<div class="paragraph"> +<p>To obtain a function pointer for a physical-device command from a device +extension, an application <strong class="purple">can</strong> use <code>vkGetInstanceProcAddr</code>. +This function pointer <strong class="purple">may</strong> point to dispatch code, which calls a different +real implementation for different <code>VkPhysicalDevice</code> objects. +Behavior is undefined if an extension physical-device command is called on a +physical device that does not support the extension.</p> +</div> +<div class="paragraph"> +<p>Device extensions <strong class="purple">may</strong> define structures that <strong class="purple">can</strong> be added to the +pNext-chain of physical-device commands. +Behavior is undefined if such an extension structure is passed to a physical +device command for a physical device that does not support the extension.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="initialization-instances">3.2. Instances</h3> +<div class="paragraph"> +<p>There is no global state in Vulkan and all per-application state is stored +in a <code>VkInstance</code> object. +Creating a <code>VkInstance</code> object initializes the Vulkan library and allows +the application to pass information about itself to the implementation.</p> +</div> +<div class="paragraph"> +<p>Instances are represented by <code>VkInstance</code> handles:</p> +</div> +<div id="VkInstance" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_HANDLE(VkInstance)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>To create an instance object, call:</p> +</div> +<div id="vkCreateInstance" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateInstance( + <span class="directive">const</span> VkInstanceCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkInstance* pInstance);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>pCreateInfo</code> points to an instance of <a href="#VkInstanceCreateInfo">VkInstanceCreateInfo</a> +controlling creation of the instance.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pInstance</code> points a <code>VkInstance</code> handle in which the resulting +instance is returned.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>vkCreateInstance</code> creates the instance, then enables and initializes +global layers and extensions requested by the application. +If an extension is provided by a layer, both the layer and extension <strong class="purple">must</strong> +be specified at <code>vkCreateInstance</code> time. +If a specified layer cannot be found, no <code>VkInstance</code> will be created +and the function will return <code>VK_ERROR_LAYER_NOT_PRESENT</code>. +Likewise, if a specified extension cannot be found the call will return +<code>VK_ERROR_EXTENSION_NOT_PRESENT</code>.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkInstanceCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pInstance</code> <strong class="purple">must</strong> be a pointer to a <code>VkInstance</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INITIALIZATION_FAILED</code></p> +</li> +<li> +<p><code>VK_ERROR_LAYER_NOT_PRESENT</code></p> +</li> +<li> +<p><code>VK_ERROR_EXTENSION_NOT_PRESENT</code></p> +</li> +<li> +<p><code>VK_ERROR_INCOMPATIBLE_DRIVER</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkInstanceCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkInstanceCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkInstanceCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkInstanceCreateFlags flags; + <span class="directive">const</span> VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + <span class="directive">const</span> <span class="predefined-type">char</span>* <span class="directive">const</span>* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + <span class="directive">const</span> <span class="predefined-type">char</span>* <span class="directive">const</span>* ppEnabledExtensionNames; +} VkInstanceCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +<li> +<p><code>pApplicationInfo</code> is <code>NULL</code> or a pointer to an instance of +<code>VkApplicationInfo</code>. +If not <code>NULL</code>, this information helps implementations recognize behavior +inherent to classes of applications. +<a href="#VkApplicationInfo">VkApplicationInfo</a> is defined in detail below.</p> +</li> +<li> +<p><code>enabledLayerCount</code> is the number of global layers to enable.</p> +</li> +<li> +<p><code>ppEnabledLayerNames</code> is a pointer to an array of +<code>enabledLayerCount</code> null-terminated UTF-8 strings containing the +names of layers to enable for the created instance. +See the <a href="#extended-functionality-layers">Layers</a> section for further +details.</p> +</li> +<li> +<p><code>enabledExtensionCount</code> is the number of global extensions to +enable.</p> +</li> +<li> +<p><code>ppEnabledExtensionNames</code> is a pointer to an array of +<code>enabledExtensionCount</code> null-terminated UTF-8 strings containing the +names of extensions to enable.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +<li> +<p>If <code>pApplicationInfo</code> is not <code>NULL</code>, <code>pApplicationInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkApplicationInfo</code> structure</p> +</li> +<li> +<p>If <code>enabledLayerCount</code> is not <code>0</code>, <code>ppEnabledLayerNames</code> <strong class="purple">must</strong> be a pointer to an array of <code>enabledLayerCount</code> null-terminated strings</p> +</li> +<li> +<p>If <code>enabledExtensionCount</code> is not <code>0</code>, <code>ppEnabledExtensionNames</code> <strong class="purple">must</strong> be a pointer to an array of <code>enabledExtensionCount</code> null-terminated strings</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>When creating a Vulkan instance for which you wish to disable validation +checks, add a <a href="#VkValidationFlagsEXT">VkValidationFlagsEXT</a> structure to the <code>pNext</code> chain +of the <a href="#VkInstanceCreateInfo">VkInstanceCreateInfo</a> structure, specifying the checks to be +disabled.</p> +</div> +<div id="VkValidationFlagsEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkValidationFlagsEXT { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t disabledValidationCheckCount; + VkValidationCheckEXT* pDisabledValidationChecks; +} VkValidationFlagsEXT;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>disabledValidationCheckCount</code> is the number of checks to disable.</p> +</li> +<li> +<p><code>pDisabledValidationChecks</code> is a pointer to an array of values +specifying the validation checks to be disabled. +Checks which <strong class="purple">may</strong> be specified include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkValidationCheckEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkValidationCheckEXT { + VK_VALIDATION_CHECK_ALL_EXT = <span class="integer">0</span>, +} VkValidationCheckEXT;</code></pre> +</div> +</div> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_VALIDATION_CHECK_ALL_EXT</code> disables all validation checks.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>pDisabledValidationChecks</code> <strong class="purple">must</strong> be a pointer to an array of <code>disabledValidationCheckCount</code> <a href="#VkValidationCheckEXT">VkValidationCheckEXT</a> values</p> +</li> +<li> +<p><code>disabledValidationCheckCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkApplicationInfo</code> structure is defined as:</p> +</div> +<div id="VkApplicationInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkApplicationInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + <span class="directive">const</span> <span class="predefined-type">char</span>* pApplicationName; + uint32_t applicationVersion; + <span class="directive">const</span> <span class="predefined-type">char</span>* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>pApplicationName</code> is a pointer to a null-terminated UTF-8 string +containing the name of the application.</p> +</li> +<li> +<p><code>applicationVersion</code> is an unsigned integer variable containing the +developer-supplied version number of the application.</p> +</li> +<li> +<p><code>pEngineName</code> is a pointer to a null-terminated UTF-8 string +containing the name of the engine (if any) used to create the +application.</p> +</li> +<li> +<p><code>engineVersion</code> is an unsigned integer variable containing the +developer-supplied version number of the engine used to create the +application.</p> +</li> +<li> +<p><code>apiVersion</code> is the version of the Vulkan API against which the +application expects to run, encoded as described in the +<a href="#fundamentals-versionnum">API Version Numbers and Semantics</a> section. +If <code>apiVersion</code> is 0 the implementation <strong class="purple">must</strong> ignore it, otherwise +if the implementation does not support the requested <code>apiVersion</code> it +<strong class="purple">must</strong> return <code>VK_ERROR_INCOMPATIBLE_DRIVER</code>. +The patch version number specified in <code>apiVersion</code> is ignored when +creating an instance object. +Only the major and minor versions of the instance <strong class="purple">must</strong> match those +requested in <code>apiVersion</code>.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>apiVersion</code> <strong class="purple">must</strong> be zero, or otherwise it <strong class="purple">must</strong> be a version that +the implementation supports, or supports an effective substitute for</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_APPLICATION_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>pApplicationName</code> is not <code>NULL</code>, <code>pApplicationName</code> <strong class="purple">must</strong> be a null-terminated string</p> +</li> +<li> +<p>If <code>pEngineName</code> is not <code>NULL</code>, <code>pEngineName</code> <strong class="purple">must</strong> be a null-terminated string</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To destroy an instance, call:</p> +</div> +<div id="vkDestroyInstance" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroyInstance( + VkInstance instance, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> is the handle of the instance to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All child objects created using <code>instance</code> <strong class="purple">must</strong> have been destroyed +prior to destroying <code>instance</code></p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>instance</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>instance</code> was +created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p>If <code>instance</code> is not <code>NULL</code>, <code>instance</code> <strong class="purple">must</strong> be a valid <code>VkInstance</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>instance</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="devsandqueues">4. Devices and Queues</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Once Vulkan is initialized, devices and queues are the primary objects used +to interact with a Vulkan implementation.</p> +</div> +<div class="paragraph"> +<p>Vulkan separates the concept of <em>physical</em> and <em>logical</em> devices. +A physical device usually represents a single device in a system (perhaps +made up of several individual hardware devices working together), of which +there are a finite number. +A logical device represents an application’s view of the device.</p> +</div> +<div class="paragraph"> +<p>Physical devices are represented by <code>VkPhysicalDevice</code> handles:</p> +</div> +<div id="VkPhysicalDevice" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_HANDLE(VkPhysicalDevice)</code></pre> +</div> +</div> +<div class="sect2"> +<h3 id="devsandqueues-physical-device-enumeration">4.1. Physical Devices</h3> +<div class="paragraph"> +<p>To retrieve a list of physical device objects representing the physical +devices installed in the system, call:</p> +</div> +<div id="vkEnumeratePhysicalDevices" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkEnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> is a handle to a Vulkan instance previously created with +<code>vkCreateInstance</code>.</p> +</li> +<li> +<p><code>pPhysicalDeviceCount</code> is a pointer to an integer related to the +number of physical devices available or queried, as described below.</p> +</li> +<li> +<p><code>pPhysicalDevices</code> is either <code>NULL</code> or a pointer to an array of +<code>VkPhysicalDevice</code> handles.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If <code>pPhysicalDevices</code> is <code>NULL</code>, then the number of physical devices +available is returned in <code>pPhysicalDeviceCount</code>. +Otherwise, <code>pPhysicalDeviceCount</code> <strong class="purple">must</strong> point to a variable set by the +user to the number of elements in the <code>pPhysicalDevices</code> array, and on +return the variable is overwritten with the number of handles actually +written to <code>pPhysicalDevices</code>. +If <code>pPhysicalDeviceCount</code> is less than the number of physical devices +available, at most <code>pPhysicalDeviceCount</code> structures will be written. +If <code>pPhysicalDeviceCount</code> is smaller than the number of physical devices +available, <code>VK_INCOMPLETE</code> will be returned instead of <code>VK_SUCCESS</code>, +to indicate that not all the available physical devices were returned.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> <strong class="purple">must</strong> be a valid <code>VkInstance</code> handle</p> +</li> +<li> +<p><code>pPhysicalDeviceCount</code> <strong class="purple">must</strong> be a pointer to a <code>uint32_t</code> value</p> +</li> +<li> +<p>If the value referenced by <code>pPhysicalDeviceCount</code> is not <code>0</code>, and <code>pPhysicalDevices</code> is not <code>NULL</code>, <code>pPhysicalDevices</code> <strong class="purple">must</strong> be a pointer to an array of <code>pPhysicalDeviceCount</code> <code>VkPhysicalDevice</code> handles</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +<li> +<p><code>VK_INCOMPLETE</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INITIALIZATION_FAILED</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>To query general properties of physical devices once enumerated, call:</p> +</div> +<div id="vkGetPhysicalDeviceProperties" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkGetPhysicalDeviceProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties* pProperties);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> is the handle to the physical device whose +properties will be queried.</p> +</li> +<li> +<p><code>pProperties</code> points to an instance of the +<a href="#VkPhysicalDeviceProperties">VkPhysicalDeviceProperties</a> structure, that will be filled with +returned information.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be a valid <code>VkPhysicalDevice</code> handle</p> +</li> +<li> +<p><code>pProperties</code> <strong class="purple">must</strong> be a pointer to a <code>VkPhysicalDeviceProperties</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkPhysicalDeviceProperties</code> structure is defined as:</p> +</div> +<div id="VkPhysicalDeviceProperties" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkPhysicalDeviceProperties { + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + <span class="predefined-type">char</span> deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>apiVersion</code> is the version of Vulkan supported by the device, +encoded as described in the <a href="#fundamentals-versionnum">API Version +Numbers and Semantics</a> section.</p> +</li> +<li> +<p><code>driverVersion</code> is the vendor-specified version of the driver.</p> +</li> +<li> +<p><code>vendorID</code> is a unique identifier for the <em>vendor</em> (see below) of +the physical device.</p> +</li> +<li> +<p><code>deviceID</code> is a unique identifier for the physical device among +devices available from the vendor.</p> +</li> +<li> +<p><code>deviceType</code> is a <a href="#VkPhysicalDeviceType">VkPhysicalDeviceType</a> specifying the type of +device.</p> +</li> +<li> +<p><code>deviceName</code> is a null-terminated UTF-8 string containing the name +of the device.</p> +</li> +<li> +<p><code>pipelineCacheUUID</code> is an array of size <code>VK_UUID_SIZE</code>, +containing 8-bit values that represent a universally unique identifier +for the device.</p> +</li> +<li> +<p><code>limits</code> is the <a href="#VkPhysicalDeviceLimits">VkPhysicalDeviceLimits</a> structure which +specifies device-specific limits of the physical device. +See <a href="#features-limits">Limits</a> for details.</p> +</li> +<li> +<p><code>sparseProperties</code> is the <a href="#VkPhysicalDeviceSparseProperties">VkPhysicalDeviceSparseProperties</a> +structure which specifies various sparse related properties of the +physical device. +See <a href="#sparsememory-physicalprops">Sparse Properties</a> for details.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The <code>vendorID</code> and <code>deviceID</code> fields are provided to allow +applications to adapt to device characteristics that are not adequately +exposed by other Vulkan queries. +These <strong class="purple">may</strong> include performance profiles, hardware errata, or other +characteristics. +In PCI-based implementations, the low sixteen bits of <code>vendorID</code> and +<code>deviceID</code> <strong class="purple">must</strong> contain (respectively) the PCI vendor and device IDs +associated with the hardware device, and the remaining bits <strong class="purple">must</strong> be set to +zero. +In non-PCI implementations, the choice of what values to return <strong class="purple">may</strong> be +dictated by operating system or platform policies. +It is otherwise at the discretion of the implementer, subject to the +following constraints and guidelines:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>For purposes of physical device identification, the <em>vendor</em> of a +physical device is the entity responsible for the most salient +characteristics of the hardware represented by the physical device +handle. +In the case of a discrete GPU, this <strong class="purple">should</strong> be the GPU chipset vendor. +In the case of a GPU or other accelerator integrated into a +system-on-chip (SoC), this <strong class="purple">should</strong> be the supplier of the silicon IP +used to create the GPU or other accelerator.</p> +</li> +<li> +<p>If the vendor of the physical device has a valid PCI vendor ID issued by +<a href="https://pcisig.com/">PCI-SIG</a>, that ID <strong class="purple">should</strong> be used to construct +<code>vendorID</code> as described above for PCI-based implementations. +Implementations that do not return a PCI vendor ID in <code>vendorID</code> +<strong class="purple">must</strong> return a valid Khronos vendor ID, obtained as described in the +<a href="#vulkan-styleguide">Vulkan Documentation and Extensions</a> document in +the section “Registering a Vendor ID with Khronos”. +Khronos vendor IDs are allocated starting at 0x10000, to distinguish +them from the PCI vendor ID namespace.</p> +</li> +<li> +<p>The vendor of the physical device is responsible for selecting +<code>deviceID</code>. +The value selected <strong class="purple">should</strong> uniquely identify both the device version and +any major configuration options (for example, core count in the case of +multicore devices). +The same device ID <strong class="purple">should</strong> be used for all physical implementations of +that device version and configuration. +For example, all uses of a specific silicon IP GPU version and +configuration <strong class="purple">should</strong> use the same device ID, even if those uses occur +in different SoCs.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The physical devices types are:</p> +</div> +<div id="VkPhysicalDeviceType" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkPhysicalDeviceType { + VK_PHYSICAL_DEVICE_TYPE_OTHER = <span class="integer">0</span>, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = <span class="integer">1</span>, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = <span class="integer">2</span>, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = <span class="integer">3</span>, + VK_PHYSICAL_DEVICE_TYPE_CPU = <span class="integer">4</span>, +} VkPhysicalDeviceType;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PHYSICAL_DEVICE_TYPE_OTHER</code> The device does not match any other +available types.</p> +</li> +<li> +<p><code>VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU</code> The device is typically one +embedded in or tightly coupled with the host.</p> +</li> +<li> +<p><code>VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU</code> The device is typically a +separate processor connected to the host via an interlink.</p> +</li> +<li> +<p><code>VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU</code> The device is typically a +virtual node in a virtualization environment.</p> +</li> +<li> +<p><code>VK_PHYSICAL_DEVICE_TYPE_CPU</code> The device is typically running on the +same processors as the host.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The physical device type is advertised for informational purposes only, and +does not directly affect the operation of the system. +However, the device type <strong class="purple">may</strong> correlate with other advertised properties or +capabilities of the system, such as how many memory heaps there are.</p> +</div> +<div class="paragraph"> +<p>To query general properties of physical devices once enumerated, call:</p> +</div> +<div id="vkGetPhysicalDeviceProperties2KHR" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkGetPhysicalDeviceProperties2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2KHR* pProperties);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> is the handle to the physical device whose +properties will be queried.</p> +</li> +<li> +<p><code>pProperties</code> points to an instance of the +<a href="#VkPhysicalDeviceProperties2KHR">VkPhysicalDeviceProperties2KHR</a> structure, that will be filled with +returned information.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Each structure in <code>pProperties</code> and its <code>pNext</code> chain contain +members corresponding to properties or implementation-dependent limits. +<code>vkGetPhysicalDeviceProperties2KHR</code> writes each member to a value +indicating the value of that property or limit.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be a valid <code>VkPhysicalDevice</code> handle</p> +</li> +<li> +<p><code>pProperties</code> <strong class="purple">must</strong> be a pointer to a <code>VkPhysicalDeviceProperties2KHR</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkPhysicalDeviceProperties2KHR</code> structure is defined as:</p> +</div> +<div id="VkPhysicalDeviceProperties2KHR" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkPhysicalDeviceProperties2KHR { + VkStructureType sType; + <span class="directive">void</span>* pNext; + VkPhysicalDeviceProperties properties; +} VkPhysicalDeviceProperties2KHR;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>properties</code> is a structure of type <a href="#VkPhysicalDeviceProperties">VkPhysicalDeviceProperties</a> +describing the properties of the physical device. +This structure is written with the same values as if it were written by +<a href="#vkGetPhysicalDeviceProperties">vkGetPhysicalDeviceProperties</a>.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The <code>pNext</code> chain of this structure is used to extend the structure with +properties defined by extensions.</p> +</div> +<div class="paragraph"> +<p>To query the UUID and LUID of a device, add +<a href="#VkPhysicalDeviceIDPropertiesKHX">VkPhysicalDeviceIDPropertiesKHX</a> to the <code>pNext</code> chain of the +<a href="#VkPhysicalDeviceProperties2KHR">VkPhysicalDeviceProperties2KHR</a> structure. +The <code>VkPhysicalDeviceIDPropertiesKHX</code> structure is defined as:</p> +</div> +<div id="VkPhysicalDeviceIDPropertiesKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkPhysicalDeviceIDPropertiesKHX { + VkStructureType sType; + <span class="directive">void</span>* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE_KHX]; + VkBool32 deviceLUIDValid; +} VkPhysicalDeviceIDPropertiesKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>deviceUUID</code> is an array of size <code>VK_UUID_SIZE</code>, containing +8-bit values that represent a universally unique identifier for the +device.</p> +</li> +<li> +<p><code>driverUUID</code> is an array of size <code>VK_UUID_SIZE</code>, containing +8-bit values that represent a universally unique identifier for the +driver build in use by the device.</p> +</li> +<li> +<p><code>deviceLUID</code> is an array of size <code>VK_LUID_SIZE_KHX</code>, containing +8-bit values that represent a locally unique identifier for the device.</p> +</li> +<li> +<p><code>deviceLUIDValid</code> is a boolean value that will be <code>VK_TRUE</code> if +<code>deviceLUID</code> contains a valid LUID, and <code>VK_FALSE</code> if it does +not.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>deviceUUID</code> <strong class="purple">must</strong> be immutable for a given device across instances, +processes, driver APIs, and system reboots.</p> +</div> +<div class="paragraph"> +<p>If a pair of driver components support sharing external objects with each other +through any handle type in <a href="#VkExternalMemoryHandleTypeFlagsKHX">VkExternalMemoryHandleTypeFlagsKHX</a>, +then <code>driverUUID</code> must be identical in both components. +(This restriction does not apply to external objects shared through +<code>VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_MESAX</code>). +Applications <strong class="purple">can</strong> compare this value across instance and process boundaries, +and <strong class="purple">can</strong> make similar queries in external APIs to determine whether they are +capable of sharing memory objects and resources using them with the device.</p> +</div> +<div class="paragraph"> +<p>If <code>deviceLUIDValid</code> is <code>VK_FALSE</code>, the contents of <code>deviceLUID</code> +are undefined. +If <code>deviceLUIDValid</code> is <code>VK_TRUE</code> and Vulkan is running on the +Windows operating system, the contents of <code>deviceLUID</code> <strong class="purple">can</strong> be cast to +an <code>LUID</code> object and <strong class="purple">must</strong> be equal to the locally unique identifier of +a <code>IDXGIAdapter1</code> object that corresponds to <code>physicalDevice</code>.</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>Although they have identical descriptions, +<a href="#VkPhysicalDeviceIDPropertiesKHX">VkPhysicalDeviceIDPropertiesKHX</a>::<code>deviceUUID</code> may differ from +<a href="#VkPhysicalDeviceProperties2KHR">VkPhysicalDeviceProperties2KHR</a>::<code>pipelineCacheUUID</code>. +The former is intended to identify and correlate devices across API and +driver boundaries, while the latter is used to identify a compatible device +and driver combination to use when serializing and de-serializing pipeline +state.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>To query properties of queues available on a physical device, call:</p> +</div> +<div id="vkGetPhysicalDeviceQueueFamilyProperties" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkGetPhysicalDeviceQueueFamilyProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties* pQueueFamilyProperties);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> is the handle to the physical device whose +properties will be queried.</p> +</li> +<li> +<p><code>pQueueFamilyPropertyCount</code> is a pointer to an integer related to +the number of queue families available or queried, as described below.</p> +</li> +<li> +<p><code>pQueueFamilyProperties</code> is either <code>NULL</code> or a pointer to an array +of <a href="#VkQueueFamilyProperties">VkQueueFamilyProperties</a> structures.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If <code>pQueueFamilyProperties</code> is <code>NULL</code>, then the number of queue families +available is returned in <code>pQueueFamilyPropertyCount</code>. +Otherwise, <code>pQueueFamilyPropertyCount</code> <strong class="purple">must</strong> point to a variable set by +the user to the number of elements in the <code>pQueueFamilyProperties</code> +array, and on return the variable is overwritten with the number of +structures actually written to <code>pQueueFamilyProperties</code>. +If <code>pQueueFamilyPropertyCount</code> is less than the number of queue families +available, at most <code>pQueueFamilyPropertyCount</code> structures will be +written.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be a valid <code>VkPhysicalDevice</code> handle</p> +</li> +<li> +<p><code>pQueueFamilyPropertyCount</code> <strong class="purple">must</strong> be a pointer to a <code>uint32_t</code> value</p> +</li> +<li> +<p>If the value referenced by <code>pQueueFamilyPropertyCount</code> is not <code>0</code>, and <code>pQueueFamilyProperties</code> is not <code>NULL</code>, <code>pQueueFamilyProperties</code> <strong class="purple">must</strong> be a pointer to an array of <code>pQueueFamilyPropertyCount</code> <code>VkQueueFamilyProperties</code> structures</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkQueueFamilyProperties</code> structure is defined as:</p> +</div> +<div id="VkQueueFamilyProperties" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkQueueFamilyProperties { + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>queueFlags</code> contains flags indicating the capabilities of the +queues in this queue family.</p> +</li> +<li> +<p><code>queueCount</code> is the unsigned integer count of queues in this queue +family.</p> +</li> +<li> +<p><code>timestampValidBits</code> is the unsigned integer count of meaningful +bits in the timestamps written via <code>vkCmdWriteTimestamp</code>. +The valid range for the count is 36..64 bits, or a value of 0, +indicating no support for timestamps. +Bits outside the valid range are guaranteed to be zeros.</p> +</li> +<li> +<p><code>minImageTransferGranularity</code> is the minimum granularity supported +for image transfer operations on the queues in this queue family.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The bits specified in <code>queueFlags</code> are:</p> +</div> +<div id="VkQueueFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = <span class="hex">0x00000001</span>, + VK_QUEUE_COMPUTE_BIT = <span class="hex">0x00000002</span>, + VK_QUEUE_TRANSFER_BIT = <span class="hex">0x00000004</span>, + VK_QUEUE_SPARSE_BINDING_BIT = <span class="hex">0x00000008</span>, +} VkQueueFlagBits;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p>if <code>VK_QUEUE_GRAPHICS_BIT</code> is set, then the queues in this queue +family support graphics operations.</p> +</li> +<li> +<p>if <code>VK_QUEUE_COMPUTE_BIT</code> is set, then the queues in this queue +family support compute operations.</p> +</li> +<li> +<p>if <code>VK_QUEUE_TRANSFER_BIT</code> is set, then the queues in this queue +family support transfer operations.</p> +</li> +<li> +<p>if <code>VK_QUEUE_SPARSE_BINDING_BIT</code> is set, then the queues in this +queue family support sparse memory management operations (see +<a href="#sparsememory">Sparse Resources</a>). +If any of the sparse resource features are enabled, then at least one +queue family <strong class="purple">must</strong> support this bit.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If an implementation exposes any queue family that supports graphics +operations, at least one queue family of at least one physical device +exposed by the implementation <strong class="purple">must</strong> support both graphics and compute +operations.</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>All commands that are allowed on a queue that supports transfer operations +are also allowed on a queue that supports either graphics or compute +operations thus if the capabilities of a queue family include +<code>VK_QUEUE_GRAPHICS_BIT</code> or <code>VK_QUEUE_COMPUTE_BIT</code> then reporting the +<code>VK_QUEUE_TRANSFER_BIT</code> capability separately for that queue family is +<strong class="purple">optional</strong>.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>For further details see <a href="#devsandqueues-queues">Queues</a>.</p> +</div> +<div class="paragraph"> +<p>The value returned in <code>minImageTransferGranularity</code> has a unit of +compressed texel blocks for images having a block-compressed format, and a +unit of texels otherwise.</p> +</div> +<div class="paragraph"> +<p>Possible values of <code>minImageTransferGranularity</code> are:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><span class="eq">(0,0,0)</span> which indicates that only whole mip levels <strong class="purple">must</strong> be +transferred using the image transfer operations on the corresponding +queues. +In this case, the following restrictions apply to all offset and extent +parameters of image transfer operations:</p> +<div class="ulist"> +<ul> +<li> +<p>The <code>x</code>, <code>y</code>, and <code>z</code> members of a <a href="#VkOffset3D">VkOffset3D</a> +parameter <strong class="purple">must</strong> always be zero.</p> +</li> +<li> +<p>The <code>width</code>, <code>height</code>, and <code>depth</code> members of a +<a href="#VkExtent3D">VkExtent3D</a> parameter <strong class="purple">must</strong> always match the width, height, and +depth of the image subresource corresponding to the parameter, +respectively.</p> +</li> +</ul> +</div> +</li> +<li> +<p><span class="eq">(A<sub>x</sub>, A<sub>y</sub>, A<sub>z</sub>)</span> where <span class="eq">A<sub>x</sub></span>, <span class="eq">A<sub>y</sub></span>, and <span class="eq">A<sub>z</sub></span> +are all integer powers of two. +In this case the following restrictions apply to all image transfer +operations:</p> +<div class="ulist"> +<ul> +<li> +<p><code>x</code>, <code>y</code>, and <code>z</code> of a <a href="#VkOffset3D">VkOffset3D</a> parameter <strong class="purple">must</strong> be +integer multiples of <span class="eq">A<sub>x</sub></span>, <span class="eq">A<sub>y</sub></span>, and <span class="eq">A<sub>z</sub></span>, +respectively.</p> +</li> +<li> +<p><code>width</code> of a <a href="#VkExtent3D">VkExtent3D</a> parameter <strong class="purple">must</strong> be an integer +multiple of <span class="eq">A<sub>x</sub></span>, or else <span class="eq"><code>x</code> + <code>width</code></span> <strong class="purple">must</strong> equal +the width of the image subresource corresponding to the parameter.</p> +</li> +<li> +<p><code>height</code> of a <a href="#VkExtent3D">VkExtent3D</a> parameter <strong class="purple">must</strong> be an integer +multiple of <span class="eq">A<sub>y</sub></span>, or else <span class="eq"><code>y</code> + <code>height</code></span> <strong class="purple">must</strong> +equal the height of the image subresource corresponding to the +parameter.</p> +</li> +<li> +<p><code>depth</code> of a <a href="#VkExtent3D">VkExtent3D</a> parameter <strong class="purple">must</strong> be an integer +multiple of <span class="eq">A<sub>z</sub></span>, or else <span class="eq"><code>z</code> + <code>depth</code></span> <strong class="purple">must</strong> equal +the depth of the image subresource corresponding to the parameter.</p> +</li> +<li> +<p>If the format of the image corresponding to the parameters is one of +the block-compressed formats then for the purposes of the above +calculations the granularity <strong class="purple">must</strong> be scaled up by the compressed texel +block dimensions.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Queues supporting graphics and/or compute operations <strong class="purple">must</strong> report +<span class="eq">(1,1,1)</span> in <code>minImageTransferGranularity</code>, meaning that there are +no additional restrictions on the granularity of image transfer operations +for these queues. +Other queues supporting image transfer operations are only <strong class="purple">required</strong> to +support whole mip level transfers, thus <code>minImageTransferGranularity</code> +for queues belonging to such queue families <strong class="purple">may</strong> be <span class="eq">(0,0,0)</span>.</p> +</div> +<div class="paragraph"> +<p>The <a href="#memory-device">Device Memory</a> section describes memory properties +queried from the physical device.</p> +</div> +<div class="paragraph"> +<p>For physical device feature queries see the <a href="#features">Features</a> chapter.</p> +</div> +<div class="paragraph"> +<p>To query properties of queues available on a physical device, call:</p> +</div> +<div id="vkGetPhysicalDeviceQueueFamilyProperties2KHR" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkGetPhysicalDeviceQueueFamilyProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties2KHR* pQueueFamilyProperties);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> is the handle to the physical device whose +properties will be queried.</p> +</li> +<li> +<p><code>pQueueFamilyPropertyCount</code> is a pointer to an integer related to +the number of queue families available or queried, as described in +<a href="#vkGetPhysicalDeviceQueueFamilyProperties">vkGetPhysicalDeviceQueueFamilyProperties</a>.</p> +</li> +<li> +<p><code>pQueueFamilyProperties</code> is either <code>NULL</code> or a pointer to an array +of <a href="#VkQueueFamilyProperties2KHR">VkQueueFamilyProperties2KHR</a> structures.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>vkGetPhysicalDeviceQueueFamilyProperties2KHR</code> behaves similarly to +<a href="#vkGetPhysicalDeviceQueueFamilyProperties">vkGetPhysicalDeviceQueueFamilyProperties</a>, with the ability to return +extended information via chained output structures.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be a valid <code>VkPhysicalDevice</code> handle</p> +</li> +<li> +<p><code>pQueueFamilyPropertyCount</code> <strong class="purple">must</strong> be a pointer to a <code>uint32_t</code> value</p> +</li> +<li> +<p>If the value referenced by <code>pQueueFamilyPropertyCount</code> is not <code>0</code>, and <code>pQueueFamilyProperties</code> is not <code>NULL</code>, <code>pQueueFamilyProperties</code> <strong class="purple">must</strong> be a pointer to an array of <code>pQueueFamilyPropertyCount</code> <code>VkQueueFamilyProperties2KHR</code> structures</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkQueueFamilyProperties2KHR</code> structure is defined as:</p> +</div> +<div id="VkQueueFamilyProperties2KHR" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkQueueFamilyProperties2KHR { + VkStructureType sType; + <span class="directive">void</span>* pNext; + VkQueueFamilyProperties queueFamilyProperties; +} VkQueueFamilyProperties2KHR;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>queueFamilyProperties</code> is a structure of type +<a href="#VkQueueFamilyProperties">VkQueueFamilyProperties</a> which is populated with the same values as +in <a href="#vkGetPhysicalDeviceQueueFamilyProperties">vkGetPhysicalDeviceQueueFamilyProperties</a>.</p> +</li> +</ul> +</div> +</div> +<div class="sect2"> +<h3 id="devsandqueues-devices">4.2. Devices</h3> +<div class="paragraph"> +<p>Device objects represent logical connections to physical devices. +Each device exposes a number of <em>queue families</em> each having one or more +<em>queues</em>. +All queues in a queue family support the same operations.</p> +</div> +<div class="paragraph"> +<p>As described in <a href="#devsandqueues-physical-device-enumeration">Physical +Devices</a>, a Vulkan application will first query for all physical devices in +a system. +Each physical device <strong class="purple">can</strong> then be queried for its capabilities, including +its queue and queue family properties. +Once an acceptable physical device is identified, an application will create +a corresponding logical device. +An application <strong class="purple">must</strong> create a separate logical device for each physical +device it will use. +The created logical device is then the primary interface to the physical +device.</p> +</div> +<div class="paragraph"> +<p>How to enumerate the physical devices in a system and query those physical +devices for their queue family properties is described in the +<a href="#devsandqueues-physical-device-enumeration">Physical Device Enumeration</a> +section above.</p> +</div> +<div class="paragraph"> +<p>A single logical device <strong class="purple">can</strong> also be created from multiple physical devices, +if those physical devices belong to the same device group. +A <em>device group</em> is a set of physical devices that support accessing each +other’s memory and recording a single command buffer that <strong class="purple">can</strong> be executed +on all the physical devices. +Device groups are enumerated by calling +<a href="#vkEnumeratePhysicalDeviceGroupsKHX">vkEnumeratePhysicalDeviceGroupsKHX</a>, and a logical device is created +from a subset of the physical devices in a device group by passing the +physical devices through <a href="#VkDeviceGroupDeviceCreateInfoKHX">VkDeviceGroupDeviceCreateInfoKHX</a>.</p> +</div> +<div class="paragraph"> +<p>To retrieve a list of the device groups present in the system, call:</p> +</div> +<div id="vkEnumeratePhysicalDeviceGroupsKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkEnumeratePhysicalDeviceGroupsKHX( + VkInstance instance, + uint32_t* pPhysicalDeviceGroupCount, + VkPhysicalDeviceGroupPropertiesKHX* pPhysicalDeviceGroupProperties);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> is a handle to a Vulkan instance previously created with +<code>vkCreateInstance</code>.</p> +</li> +<li> +<p><code>pPhysicalDeviceGroupCount</code> is a pointer to an integer related to +the number of device groups available or queried, as described below.</p> +</li> +<li> +<p><code>pPhysicalDeviceGroupProperties</code> is either <code>NULL</code> or a pointer to an +array of <a href="#VkPhysicalDeviceGroupPropertiesKHX">VkPhysicalDeviceGroupPropertiesKHX</a> structures.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If <code>pPhysicalDeviceGroupProperties</code> is <code>NULL</code>, then the number of device +groups available is returned in <code>pPhysicalDeviceGroupCount</code>. +Otherwise, <code>pPhysicalDeviceGroupCount</code> <strong class="purple">must</strong> point to a variable set by +the user to the number of elements in the +<code>pPhysicalDeviceGroupProperties</code> array, and on return the variable is +overwritten with the number of structures actually written to +<code>pPhysicalDeviceGroupProperties</code>. +If <code>pPhysicalDeviceGroupCount</code> is less than the number of device groups +available, at most <code>pPhysicalDeviceGroupCount</code> structures will be +written. +If <code>pPhysicalDeviceGroupCount</code> is smaller than the number of device +groups available, <code>VK_INCOMPLETE</code> will be returned instead of +<code>VK_SUCCESS</code>, to indicate that not all the available device groups were +returned.</p> +</div> +<div class="paragraph"> +<p>Every physical device <strong class="purple">must</strong> be in exactly one device group.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>instance</code> <strong class="purple">must</strong> be a valid <code>VkInstance</code> handle</p> +</li> +<li> +<p><code>pPhysicalDeviceGroupCount</code> <strong class="purple">must</strong> be a pointer to a <code>uint32_t</code> value</p> +</li> +<li> +<p>If the value referenced by <code>pPhysicalDeviceGroupCount</code> is not <code>0</code>, and <code>pPhysicalDeviceGroupProperties</code> is not <code>NULL</code>, <code>pPhysicalDeviceGroupProperties</code> <strong class="purple">must</strong> be a pointer to an array of <code>pPhysicalDeviceGroupCount</code> <code>VkPhysicalDeviceGroupPropertiesKHX</code> structures</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +<li> +<p><code>VK_INCOMPLETE</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INITIALIZATION_FAILED</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkPhysicalDeviceGroupPropertiesKHX</code> structure is defined as:</p> +</div> +<div id="VkPhysicalDeviceGroupPropertiesKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkPhysicalDeviceGroupPropertiesKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t physicalDeviceCount; + VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE_KHX]; + VkBool32 subsetAllocation; +} VkPhysicalDeviceGroupPropertiesKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>physicalDeviceCount</code> is the number of physical devices in the +group.</p> +</li> +<li> +<p><code>physicalDevices</code> is an array of physical device handles +representing all physical devices in the group. +The first <code>physicalDeviceCount</code> elements of the array will be valid.</p> +</li> +<li> +<p><code>subsetAllocation</code> indicates whether logical devices created from +the group support allocating device memory on a subset of devices, via +the <code>deviceMask</code> member of the <a href="#VkMemoryAllocateFlagsInfoKHX">VkMemoryAllocateFlagsInfoKHX</a>. +If this is <code>VK_FALSE</code>, then all device memory allocations are made +across all physical devices in the group. +If <code>physicalDeviceCount</code> is <code>1</code>, then <code>subsetAllocation</code> <strong class="purple">must</strong> +be <code>VK_FALSE</code>.</p> +</li> +</ul> +</div> +<div class="sect3"> +<h4 id="devsandqueues-device-creation">4.2.1. Device Creation</h4> +<div class="paragraph"> +<p>Logical devices are represented by <code>VkDevice</code> handles:</p> +</div> +<div id="VkDevice" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_HANDLE(VkDevice)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>A logical device is created as a <em>connection</em> to a physical device. +To create a logical device, call:</p> +</div> +<div id="vkCreateDevice" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateDevice( + VkPhysicalDevice physicalDevice, + <span class="directive">const</span> VkDeviceCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkDevice* pDevice);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be one of the device handles returned from a +call to <code>vkEnumeratePhysicalDevices</code> (see +<a href="#devsandqueues-physical-device-enumeration">Physical Device +Enumeration</a>).</p> +</li> +<li> +<p><code>pCreateInfo</code> is a pointer to a <a href="#VkDeviceCreateInfo">VkDeviceCreateInfo</a> structure +containing information about how to create the device.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pDevice</code> points to a handle in which the created <code>VkDevice</code> is +returned.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Multiple logical devices <strong class="purple">can</strong> be created from the same physical device. +Logical device creation <strong class="purple">may</strong> fail due to lack of device-specific resources +(in addition to the other errors). +If that occurs, <code>vkCreateDevice</code> will return +<code>VK_ERROR_TOO_MANY_OBJECTS</code>.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>physicalDevice</code> <strong class="purple">must</strong> be a valid <code>VkPhysicalDevice</code> handle</p> +</li> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkDeviceCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pDevice</code> <strong class="purple">must</strong> be a pointer to a <code>VkDevice</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INITIALIZATION_FAILED</code></p> +</li> +<li> +<p><code>VK_ERROR_EXTENSION_NOT_PRESENT</code></p> +</li> +<li> +<p><code>VK_ERROR_FEATURE_NOT_PRESENT</code></p> +</li> +<li> +<p><code>VK_ERROR_TOO_MANY_OBJECTS</code></p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkDeviceCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkDeviceCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + <span class="directive">const</span> VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + <span class="directive">const</span> <span class="predefined-type">char</span>* <span class="directive">const</span>* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + <span class="directive">const</span> <span class="predefined-type">char</span>* <span class="directive">const</span>* ppEnabledExtensionNames; + <span class="directive">const</span> VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +<li> +<p><code>queueCreateInfoCount</code> is the unsigned integer size of the +<code>pQueueCreateInfos</code> array. +Refer to the <a href="#devsandqueues-queue-creation">Queue Creation</a> section +below for further details.</p> +</li> +<li> +<p><code>pQueueCreateInfos</code> is a pointer to an array of +<a href="#VkDeviceQueueCreateInfo">VkDeviceQueueCreateInfo</a> structures describing the queues that are +requested to be created along with the logical device. +Refer to the <a href="#devsandqueues-queue-creation">Queue Creation</a> section +below for further details.</p> +</li> +<li> +<p><code>enabledLayerCount</code> is deprecated and ignored.</p> +</li> +<li> +<p><code>ppEnabledLayerNames</code> is deprecated and ignored. +See <a href="#extended-functionality-device-layer-deprecation">Device Layer +Deprecation</a>.</p> +</li> +<li> +<p><code>enabledExtensionCount</code> is the number of device extensions to +enable.</p> +</li> +<li> +<p><code>ppEnabledExtensionNames</code> is a pointer to an array of +<code>enabledExtensionCount</code> null-terminated UTF-8 strings containing the +names of extensions to enable for the created device. +See the <a href="#extended-functionality-extensions">Extensions</a> section for +further details.</p> +</li> +<li> +<p><code>pEnabledFeatures</code> is <code>NULL</code> or a pointer to a +<a href="#VkPhysicalDeviceFeatures">VkPhysicalDeviceFeatures</a> structure that contains boolean +indicators of all the features to be enabled. +Refer to the <a href="#features-features">Features</a> section for further details.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>The <code>queueFamilyIndex</code> member of any given element of +<code>pQueueCreateInfos</code> <strong class="purple">must</strong> be unique within <code>pQueueCreateInfos</code></p> +</li> +<li> +<p>If the <code>pNext</code> chain includes a <a href="#VkPhysicalDeviceFeatures2KHR">VkPhysicalDeviceFeatures2KHR</a> +structure, then <code>pEnabledFeatures</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>ppEnabledExtensionNames</code> <strong class="purple">must</strong> not contain both +<code>VK_KHR_maintenance1</code> and <code>VK_AMD_negative_viewport_height</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code>, or a pointer to a valid instance of <a href="#VkPhysicalDeviceFeatures2KHR">VkPhysicalDeviceFeatures2KHR</a>, <a href="#VkPhysicalDeviceMultiviewFeaturesKHX">VkPhysicalDeviceMultiviewFeaturesKHX</a>, or <a href="#VkDeviceGroupDeviceCreateInfoKHX">VkDeviceGroupDeviceCreateInfoKHX</a></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +<li> +<p><code>pQueueCreateInfos</code> <strong class="purple">must</strong> be a pointer to an array of <code>queueCreateInfoCount</code> valid <code>VkDeviceQueueCreateInfo</code> structures</p> +</li> +<li> +<p>If <code>enabledLayerCount</code> is not <code>0</code>, <code>ppEnabledLayerNames</code> <strong class="purple">must</strong> be a pointer to an array of <code>enabledLayerCount</code> null-terminated strings</p> +</li> +<li> +<p>If <code>enabledExtensionCount</code> is not <code>0</code>, <code>ppEnabledExtensionNames</code> <strong class="purple">must</strong> be a pointer to an array of <code>enabledExtensionCount</code> null-terminated strings</p> +</li> +<li> +<p>If <code>pEnabledFeatures</code> is not <code>NULL</code>, <code>pEnabledFeatures</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkPhysicalDeviceFeatures</code> structure</p> +</li> +<li> +<p><code>queueCreateInfoCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>A logical device <strong class="purple">can</strong> be created that connects to one or more physical +devices by including a <code>VkDeviceGroupDeviceCreateInfoKHX</code> structure in +the <code>pNext</code> chain of <a href="#VkDeviceCreateInfo">VkDeviceCreateInfo</a>. +The <code>VkDeviceGroupDeviceCreateInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkDeviceGroupDeviceCreateInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceGroupDeviceCreateInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t physicalDeviceCount; + <span class="directive">const</span> VkPhysicalDevice* pPhysicalDevices; +} VkDeviceGroupDeviceCreateInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>physicalDeviceCount</code> is the number of elements in the +<code>pPhysicalDevices</code> array.</p> +</li> +<li> +<p><code>pPhysicalDevices</code> is an array of physical device handles belonging +to the same device group.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The elements of the <code>pPhysicalDevices</code> array are an ordered list of the +physical devices that the logical device represents. +These must be a subset of a single device group, and need not be in the same +order as they were enumerated. +The order of the physical devices in the <code>pPhysicalDevices</code> array +determines the <em>device index</em> of each physical device, with element <span class="eq">i</span> +being assigned a device index of <span class="eq">i</span>. +Certain commands and structures refer to one or more physical devices by +using device indices or <em>device masks</em> formed using device indices.</p> +</div> +<div class="paragraph"> +<p>A logical device created without using +<code>VkDeviceGroupDeviceCreateInfoKHX</code>, or with <code>physicalDeviceCount</code> +equal to zero, is equivalent to a <code>physicalDeviceCount</code> of one and +<code>pPhysicalDevices</code> pointing to the <code>physicalDevice</code> parameter to +<a href="#vkCreateDevice">vkCreateDevice</a>. +In particular, the device index of that physical device is zero.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>Each element of <code>pPhysicalDevices</code> <strong class="purple">must</strong> be unique</p> +</li> +<li> +<p>All elements of <code>pPhysicalDevices</code> <strong class="purple">must</strong> be in the same device group +as enumerated by <a href="#vkEnumeratePhysicalDeviceGroupsKHX">vkEnumeratePhysicalDeviceGroupsKHX</a></p> +</li> +<li> +<p>If <code>physicalDeviceCount</code> is not <code>0</code>, the <code>physicalDevice</code> +parameter of <a href="#vkCreateDevice">vkCreateDevice</a> <strong class="purple">must</strong> be an element of +<code>pPhysicalDevices</code>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>physicalDeviceCount</code> is not <code>0</code>, <code>pPhysicalDevices</code> <strong class="purple">must</strong> be a pointer to an array of <code>physicalDeviceCount</code> valid <code>VkPhysicalDevice</code> handles</p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-use">4.2.2. Device Use</h4> +<div class="paragraph"> +<p>The following is a high-level list of <code>VkDevice</code> uses along with +references on where to find more information:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Creation of queues. +See the <a href="#devsandqueues-queues">Queues</a> section below for further +details.</p> +</li> +<li> +<p>Creation and tracking of various synchronization constructs. +See <a href="#synchronization">Synchronization and Cache Control</a> for further +details.</p> +</li> +<li> +<p>Allocating, freeing, and managing memory. +See <a href="#memory">Memory Allocation</a> and <a href="#resources">Resource Creation</a> for +further details.</p> +</li> +<li> +<p>Creation and destruction of command buffers and command buffer pools. +See <a href="#commandbuffers">Command Buffers</a> for further details.</p> +</li> +<li> +<p>Creation, destruction, and management of graphics state. +See <a href="#pipelines">Pipelines</a> and <a href="#descriptorsets">Resource Descriptors</a>, +among others, for further details.</p> +</li> +</ul> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-lost-device">4.2.3. Lost Device</h4> +<div class="paragraph"> +<p>A logical device <strong class="purple">may</strong> become <em>lost</em> because of hardware errors, execution +timeouts, power management events and/or platform-specific events. +This <strong class="purple">may</strong> cause pending and future command execution to fail and cause +hardware resources to be corrupted. +When this happens, certain commands will return <code>VK_ERROR_DEVICE_LOST</code> +(see <a href="#fundamentals-errorcodes">Error Codes</a> for a list of such commands). +After any such event, the logical device is considered <em>lost</em>. +It is not possible to reset the logical device to a non-lost state, however +the lost state is specific to a logical device (<code>VkDevice</code>), and the +corresponding physical device (<code>VkPhysicalDevice</code>) <strong class="purple">may</strong> be otherwise +unaffected. +In some cases, the physical device <strong class="purple">may</strong> also be lost, and attempting to +create a new logical device will fail, returning <code>VK_ERROR_DEVICE_LOST</code>. +This is usually indicative of a problem with the underlying hardware, or its +connection to the host. +If the physical device has not been lost, and a new logical device is +successfully created from that physical device, it <strong class="purple">must</strong> be in the non-lost +state.</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>Whilst logical device loss <strong class="purple">may</strong> be recoverable, in the case of physical +device loss, it is unlikely that an application will be able to recover +unless additional, unaffected physical devices exist on the system. +The error is largely informational and intended only to inform the user that +their hardware has probably developed a fault or become physically +disconnected, and <strong class="purple">should</strong> be investigated further. +In many cases, physical device loss <strong class="purple">may</strong> cause other more serious issues +such as the operating system crashing; in which case it <strong class="purple">may</strong> not be reported +via the Vulkan API.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>Undefined behavior caused by an application error <strong class="purple">may</strong> cause a device to +become lost. +However, such undefined behavior <strong class="purple">may</strong> also cause unrecoverable damage to the +process, and it is then not guaranteed that the API objects, including the +<code>VkPhysicalDevice</code> or the <code>VkInstance</code> are still valid or that the +error is recoverable.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>When a device is lost, its child objects are not implicitly destroyed and +their handles are still valid. +Those objects <strong class="purple">must</strong> still be destroyed before their parents or the device +<strong class="purple">can</strong> be destroyed (see the <a href="#fundamentals-objectmodel-lifetime">Object +Lifetime</a> section). +The host address space corresponding to device memory mapped using +<a href="#vkMapMemory">vkMapMemory</a> is still valid, and host memory accesses to these mapped +regions are still valid, but the contents are undefined. +It is still legal to call any API command on the device and child objects.</p> +</div> +<div class="paragraph"> +<p>Once a device is lost, command execution <strong class="purple">may</strong> fail, and commands that return +a <a href="#VkResult">VkResult</a> <strong class="purple">may</strong> return <code>VK_ERROR_DEVICE_LOST</code>. +Commands that do not allow run-time errors <strong class="purple">must</strong> still operate correctly for +valid usage and, if applicable, return valid data.</p> +</div> +<div class="paragraph"> +<p>Commands that wait indefinitely for device execution (namely +<a href="#vkDeviceWaitIdle">vkDeviceWaitIdle</a>, <a href="#vkQueueWaitIdle">vkQueueWaitIdle</a>, <a href="#vkWaitForFences">vkWaitForFences</a> +or <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a> +with a maximum <code>timeout</code>, and <a href="#vkGetQueryPoolResults">vkGetQueryPoolResults</a> with the +<code>VK_QUERY_RESULT_WAIT_BIT</code> bit set in <code>flags</code>) <strong class="purple">must</strong> return in +finite time even in the case of a lost device, and return either +<code>VK_SUCCESS</code> or <code>VK_ERROR_DEVICE_LOST</code>. +For any command that <strong class="purple">may</strong> return <code>VK_ERROR_DEVICE_LOST</code>, for the purpose +of determining whether a command buffer is pending execution, or whether +resources are considered in-use by the device, a return value of +<code>VK_ERROR_DEVICE_LOST</code> is equivalent to <code>VK_SUCCESS</code>.</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">editing-note</div> +<div class="paragraph"> +<p>TODO (piman) - I do not think we are very clear about what “in-use by the +device” means.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-destruction">4.2.4. Device Destruction</h4> +<div class="paragraph"> +<p>To destroy a device, call:</p> +</div> +<div id="vkDestroyDevice" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroyDevice( + VkDevice device, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>To ensure that no work is active on the device, <a href="#vkDeviceWaitIdle">vkDeviceWaitIdle</a> <strong class="purple">can</strong> +be used to gate the destruction of the device. +Prior to destroying a device, an application is responsible for +destroying/freeing any Vulkan objects that were created using that device as +the first parameter of the corresponding <code>vkCreate</code>* or +<code>vkAllocate</code>* command.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>The lifetime of each of these objects is bound by the lifetime of the +<code>VkDevice</code> object. +Therefore, to avoid resource leaks, it is critical that an application +explicitly free all of these resources prior to calling +<code>vkDestroyDevice</code>.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All child objects created on <code>device</code> <strong class="purple">must</strong> have been destroyed +prior to destroying <code>device</code></p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>device</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>device</code> was +created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p>If <code>device</code> is not <code>NULL</code>, <code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>device</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="devsandqueues-queues">4.3. Queues</h3> +<div class="sect3"> +<h4 id="devsandqueues-queueprops">4.3.1. Queue Family Properties</h4> +<div class="paragraph"> +<p>As discussed in the <a href="#devsandqueues-physical-device-enumeration">Physical +Device Enumeration</a> section above, the +<a href="#vkGetPhysicalDeviceQueueFamilyProperties">vkGetPhysicalDeviceQueueFamilyProperties</a> command is used to retrieve +details about the queue families and queues supported by a device.</p> +</div> +<div class="paragraph"> +<p>Each index in the <code>pQueueFamilyProperties</code> array returned by +<a href="#vkGetPhysicalDeviceQueueFamilyProperties">vkGetPhysicalDeviceQueueFamilyProperties</a> describes a unique queue +family on that physical device. +These indices are used when creating queues, and they correspond directly +with the <code>queueFamilyIndex</code> that is passed to the <a href="#vkCreateDevice">vkCreateDevice</a> +command via the <a href="#VkDeviceQueueCreateInfo">VkDeviceQueueCreateInfo</a> structure as described in the +<a href="#devsandqueues-queue-creation">Queue Creation</a> section below.</p> +</div> +<div class="paragraph"> +<p>Grouping of queue families within a physical device is +implementation-dependent.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>The general expectation is that a physical device groups all queues of +matching capabilities into a single family. +However, this is a recommendation to implementations and it is possible that +a physical device <strong class="purple">may</strong> return two separate queue families with the same +capabilities.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Once an application has identified a physical device with the queue(s) that +it desires to use, it will create those queues in conjunction with a logical +device. +This is described in the following section.</p> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-queue-creation">4.3.2. Queue Creation</h4> +<div class="paragraph"> +<p>Creating a logical device also creates the queues associated with that +device. +The queues to create are described by a set of <a href="#VkDeviceQueueCreateInfo">VkDeviceQueueCreateInfo</a> +structures that are passed to <a href="#vkCreateDevice">vkCreateDevice</a> in +<code>pQueueCreateInfos</code>.</p> +</div> +<div class="paragraph"> +<p>Queues are represented by <code>VkQueue</code> handles:</p> +</div> +<div id="VkQueue" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_HANDLE(VkQueue)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkDeviceQueueCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkDeviceQueueCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceQueueCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + <span class="directive">const</span> <span class="predefined-type">float</span>* pQueuePriorities; +} VkDeviceQueueCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +<li> +<p><code>queueFamilyIndex</code> is an unsigned integer indicating the index of +the queue family to create on this device. +This index corresponds to the index of an element of the +<code>pQueueFamilyProperties</code> array that was returned by +<code>vkGetPhysicalDeviceQueueFamilyProperties</code>.</p> +</li> +<li> +<p><code>queueCount</code> is an unsigned integer specifying the number of queues +to create in the queue family indicated by <code>queueFamilyIndex</code>.</p> +</li> +<li> +<p><code>pQueuePriorities</code> is an array of <code>queueCount</code> normalized +floating point values, specifying priorities of work that will be +submitted to each created queue. +See <a href="#devsandqueues-priority">Queue Priority</a> for more information.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>queueFamilyIndex</code> <strong class="purple">must</strong> be less than +<code>pQueueFamilyPropertyCount</code> returned by +<code>vkGetPhysicalDeviceQueueFamilyProperties</code></p> +</li> +<li> +<p><code>queueCount</code> <strong class="purple">must</strong> be less than or equal to the <code>queueCount</code> +member of the <code>VkQueueFamilyProperties</code> structure, as returned by +<code>vkGetPhysicalDeviceQueueFamilyProperties</code> in the +<code>pQueueFamilyProperties</code>[<code>queueFamilyIndex</code>]</p> +</li> +<li> +<p>Each element of <code>pQueuePriorities</code> <strong class="purple">must</strong> be between <code>0.0</code> and <code>1.0</code> +inclusive</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +<li> +<p><code>pQueuePriorities</code> <strong class="purple">must</strong> be a pointer to an array of <code>queueCount</code> <code>float</code> values</p> +</li> +<li> +<p><code>queueCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To retrieve a handle to a VkQueue object, call:</p> +</div> +<div id="vkGetDeviceQueue" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkGetDeviceQueue( + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the queue.</p> +</li> +<li> +<p><code>queueFamilyIndex</code> is the index of the queue family to which the +queue belongs.</p> +</li> +<li> +<p><code>queueIndex</code> is the index within this queue family of the queue to +retrieve.</p> +</li> +<li> +<p><code>pQueue</code> is a pointer to a <code>VkQueue</code> object that will be filled +with the handle for the requested queue.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>queueFamilyIndex</code> <strong class="purple">must</strong> be one of the queue family indices +specified when <code>device</code> was created, via the +<code>VkDeviceQueueCreateInfo</code> structure</p> +</li> +<li> +<p><code>queueIndex</code> <strong class="purple">must</strong> be less than the number of queues created for the +specified queue family index when <code>device</code> was created, via the +<code>queueCount</code> member of the <code>VkDeviceQueueCreateInfo</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pQueue</code> <strong class="purple">must</strong> be a pointer to a <code>VkQueue</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-index">4.3.3. Queue Family Index</h4> +<div class="paragraph"> +<p>The queue family index is used in multiple places in Vulkan in order to tie +operations to a specific family of queues.</p> +</div> +<div class="paragraph"> +<p>When retrieving a handle to the queue via <code>vkGetDeviceQueue</code>, the queue +family index is used to select which queue family to retrieve the +<code>VkQueue</code> handle from as described in the previous section.</p> +</div> +<div class="paragraph"> +<p>When creating a <code>VkCommandPool</code> object (see +<a href="#commandbuffers-pools">Command Pools</a>), a queue family index is specified +in the <a href="#VkCommandPoolCreateInfo">VkCommandPoolCreateInfo</a> structure. +Command buffers from this pool <strong class="purple">can</strong> only be submitted on queues +corresponding to this queue family.</p> +</div> +<div class="paragraph"> +<p>When creating <code>VkImage</code> (see <a href="#resources-images">Images</a>) and +<code>VkBuffer</code> (see <a href="#resources-buffers">Buffers</a>) resources, a set of queue +families is included in the <a href="#VkImageCreateInfo">VkImageCreateInfo</a> and +<a href="#VkBufferCreateInfo">VkBufferCreateInfo</a> structures to specify the queue families that <strong class="purple">can</strong> +access the resource.</p> +</div> +<div class="paragraph"> +<p>When inserting a <a href="#VkBufferMemoryBarrier">VkBufferMemoryBarrier</a> or <a href="#VkImageMemoryBarrier">VkImageMemoryBarrier</a> +(see <a href="#synchronization-events">Events</a>) a source and destination queue family index +is specified to allow the ownership of a buffer or image to be transferred +from one queue family to another. +See the <a href="#resources-sharing">Resource Sharing</a> section for details.</p> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-priority">4.3.4. Queue Priority</h4> +<div class="paragraph"> +<p>Each queue is assigned a priority, as set in the +<a href="#VkDeviceQueueCreateInfo">VkDeviceQueueCreateInfo</a> structures when creating the device. +The priority of each queue is a normalized floating point value between 0.0 +and 1.0, which is then translated to a discrete priority level by the +implementation. +Higher values indicate a higher priority, with 0.0 being the lowest priority +and 1.0 being the highest.</p> +</div> +<div class="paragraph"> +<p>Within the same device, queues with higher priority <strong class="purple">may</strong> be allotted more +processing time than queues with lower priority. +The implementation makes no guarantees with regards to ordering or +scheduling among queues with the same priority, other than the constraints +defined by any <a href="#synchronization">explicit synchronization primitives</a>. +The implementation make no guarantees with regards to queues across +different devices.</p> +</div> +<div class="paragraph"> +<p>An implementation <strong class="purple">may</strong> allow a higher-priority queue to starve a +lower-priority queue on the same <code>VkDevice</code> until the higher-priority +queue has no further commands to execute. +The relationship of queue priorities <strong class="purple">must</strong> not cause queues on one VkDevice +to starve queues on another <code>VkDevice</code>.</p> +</div> +<div class="paragraph"> +<p>No specific guarantees are made about higher priority queues receiving more +processing time or better quality of service than lower priority queues.</p> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-submission">4.3.5. Queue Submission</h4> +<div class="paragraph"> +<p>Work is submitted to a queue via <em>queue submission</em> commands such as +<a href="#vkQueueSubmit">vkQueueSubmit</a>. +Queue submission commands define a set of <em>queue operations</em> to be executed +by the underlying physical device, including synchronization with semaphores +and fences.</p> +</div> +<div class="paragraph"> +<p>Submission commands take as parameters a target queue, zero or more +<em>batches</em> of work, and an optional fence to signal upon completion. +Each batch consists of three distinct parts:</p> +</div> +<div class="olist arabic"> +<ol class="arabic"> +<li> +<p>Zero or more semaphores to wait on before execution of the rest of the +batch.</p> +<div class="ulist"> +<ul> +<li> +<p>If present, these describe a <a href="#synchronization-semaphores-waiting">semaphore wait operation</a>.</p> +</li> +</ul> +</div> +</li> +<li> +<p>Zero or more work items to execute.</p> +<div class="ulist"> +<ul> +<li> +<p>If present, these describe a <em>queue operation</em> matching the work +described.</p> +</li> +</ul> +</div> +</li> +<li> +<p>Zero or more semaphores to signal upon completion of the work items.</p> +<div class="ulist"> +<ul> +<li> +<p>If present, these describe a <a href="#synchronization-semaphores-signaling">semaphore signal operation</a>.</p> +</li> +</ul> +</div> +</li> +</ol> +</div> +<div class="paragraph"> +<p>If a fence is present in a queue submission, it describes a +<a href="#synchronization-fences-signaling">fence signal operation</a>.</p> +</div> +<div class="paragraph"> +<p>All work described by a queue submission command <strong class="purple">must</strong> be submitted to the +queue before the command returns.</p> +</div> +<div class="sect4"> +<h5 id="devsandqueues-sparsebinding">Sparse Memory Binding</h5> +<div class="paragraph"> +<p>In Vulkan it is possible to sparsely bind memory to buffers and images as +described in the <a href="#sparsememory">Sparse Resource</a> chapter. +Sparse memory binding is a queue operation. +A queue whose flags include the <code>VK_QUEUE_SPARSE_BINDING_BIT</code> <strong class="purple">must</strong> be +able to support the mapping of a virtual address to a physical address on +the device. +This causes an update to the page table mappings on the device. +This update <strong class="purple">must</strong> be synchronized on a queue to avoid corrupting page table +mappings during execution of graphics commands. +By binding the sparse memory resources on queues, all commands that are +dependent on the updated bindings are synchronized to only execute after the +binding is updated. +See the <a href="#synchronization">Synchronization and Cache Control</a> chapter for +how this synchronization is accomplished.</p> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="devsandqueues-queuedestruction">4.3.6. Queue Destruction</h4> +<div class="paragraph"> +<p>Queues are created along with a logical device during <code>vkCreateDevice</code>. +All queues associated with a logical device are destroyed when +<code>vkDestroyDevice</code> is called on that device.</p> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="commandbuffers">5. Command Buffers</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Command buffers are objects used to record commands which <strong class="purple">can</strong> be +subsequently submitted to a device queue for execution. +There are two levels of command buffers - <em>primary command buffers</em>, which +<strong class="purple">can</strong> execute secondary command buffers, and which are submitted to queues, +and <em>secondary command buffers</em>, which <strong class="purple">can</strong> be executed by primary command +buffers, and which are not directly submitted to queues.</p> +</div> +<div class="paragraph"> +<p>Command buffers are represented by <code>VkCommandBuffer</code> handles:</p> +</div> +<div id="VkCommandBuffer" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_HANDLE(VkCommandBuffer)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Recorded commands include commands to bind pipelines and descriptor sets to +the command buffer, commands to modify dynamic state, commands to draw (for +graphics rendering), commands to dispatch (for compute), commands to execute +secondary command buffers (for primary command buffers only), commands to +copy buffers and images, and other commands.</p> +</div> +<div id="commandbuffers-statereset" class="paragraph"> +<p>Each command buffer manages state independently of other command buffers. +There is no inheritance of state across primary and secondary command +buffers, or between secondary command buffers. +When a command buffer begins recording, all state in that command buffer is +undefined. +When secondary command buffer(s) are recorded to execute on a primary +command buffer, the secondary command buffer inherits no state from the +primary command buffer, and all state of the primary command buffer is +undefined after an execute secondary command buffer command is recorded. +There is one exception to this rule - if the primary command buffer is +inside a render pass instance, then the render pass and subpass state is not +disturbed by executing secondary command buffers. +Whenever the state of a command buffer is undefined, the application <strong class="purple">must</strong> +set all relevant state on the command buffer before any state dependent +commands such as draws and dispatches are recorded, otherwise the behavior +of executing that command buffer is undefined.</p> +</div> +<div class="paragraph"> +<p>Unless otherwise specified, and without explicit synchronization, the +various commands submitted to a queue via command buffers <strong class="purple">may</strong> execute in +arbitrary order relative to each other, and/or concurrently. +Also, the memory side-effects of those commands <strong class="purple">may</strong> not be directly visible +to other commands without explicit memory dependencies. +This is true within a command buffer, and across command buffers submitted +to a given queue. +See <a href="#synchronization">the synchronization chapter</a> for information on +<a href="#synchronization-implicit">implicit</a> and explicit synchronization between +commands.</p> +</div> +<div class="paragraph"> +<p>Each command buffer is always in one of three states:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><em>Initial state</em>: Before <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a>. +Either <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a> has never been called, or the command +buffer has been reset since it last recorded commands.</p> +</li> +<li> +<p><em>Recording state</em>: Between <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a> and +<a href="#vkEndCommandBuffer">vkEndCommandBuffer</a>. +The command buffer is in a state where it <strong class="purple">can</strong> record commands.</p> +</li> +<li> +<p><em>Executable state</em>: After <a href="#vkEndCommandBuffer">vkEndCommandBuffer</a>. +The command buffer is in a state where it has finished recording +commands and <strong class="purple">can</strong> be executed.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><em>Resetting</em> a command buffer is an operation that discards any previously +recorded commands and puts a command buffer in the initial state. +Resetting occurs as a result of <a href="#vkResetCommandBuffer">vkResetCommandBuffer</a> or +<a href="#vkResetCommandPool">vkResetCommandPool</a>, or as part of <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a> (which +additionally puts the command buffer in the recording state).</p> +</div> +<div class="sect2"> +<h3 id="commandbuffers-pools">5.1. Command Pools</h3> +<div class="paragraph"> +<p>Command pools are opaque objects that command buffer memory is allocated +from, and which allow the implementation to amortize the cost of resource +creation across multiple command buffers. +Command pools are externally synchronized, meaning that a command pool <strong class="purple">must</strong> +not be used concurrently in multiple threads. +That includes use via recording commands on any command buffers allocated +from the pool, as well as operations that allocate, free, and reset command +buffers or the pool itself.</p> +</div> +<div class="paragraph"> +<p>Command pools are represented by <code>VkCommandPool</code> handles:</p> +</div> +<div id="VkCommandPool" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>To create a command pool, call:</p> +</div> +<div id="vkCreateCommandPool" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateCommandPool( + VkDevice device, + <span class="directive">const</span> VkCommandPoolCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkCommandPool* pCommandPool);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that creates the command pool.</p> +</li> +<li> +<p><code>pCreateInfo</code> contains information used to create the command pool.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pCommandPool</code> points to a <code>VkCommandPool</code> handle in which the +created pool is returned.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkCommandPoolCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pCommandPool</code> <strong class="purple">must</strong> be a pointer to a <code>VkCommandPool</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkCommandPoolCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkCommandPoolCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkCommandPoolCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is a bitmask indicating usage behavior for the pool and +command buffers allocated from it. +Bits which <strong class="purple">can</strong> be set include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkCommandPoolCreateFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = <span class="hex">0x00000001</span>, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = <span class="hex">0x00000002</span>, +} VkCommandPoolCreateFlagBits;</code></pre> +</div> +</div> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_COMMAND_POOL_CREATE_TRANSIENT_BIT</code> indicates that command +buffers allocated from the pool will be short-lived, meaning that they +will be reset or freed in a relatively short timeframe. +This flag <strong class="purple">may</strong> be used by the implementation to control memory +allocation behavior within the pool.</p> +</li> +<li> +<p><code>VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT</code> controls whether +command buffers allocated from the pool <strong class="purple">can</strong> be individually reset. +If this flag is set, individual command buffers allocated from the pool +<strong class="purple">can</strong> be reset either explicitly, by calling <code>vkResetCommandBuffer</code>, +or implicitly, by calling <code>vkBeginCommandBuffer</code> on an executable +command buffer. +If this flag is not set, then <code>vkResetCommandBuffer</code> and +<code>vkBeginCommandBuffer</code> (on an executable command buffer) <strong class="purple">must</strong> not +be called on the command buffers allocated from the pool, and they <strong class="purple">can</strong> +only be reset in bulk by calling <code>vkResetCommandPool</code>.</p> +<div class="ulist"> +<ul> +<li> +<p><code>queueFamilyIndex</code> designates a queue family as described in section +<a href="#devsandqueues-queueprops">Queue Family Properties</a>. +All command buffers allocated from this command pool <strong class="purple">must</strong> be submitted +on queues from the same queue family.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>queueFamilyIndex</code> <strong class="purple">must</strong> be the index of a queue family available in +the calling command’s <code>device</code> parameter</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkCommandPoolCreateFlagBits">VkCommandPoolCreateFlagBits</a> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To trim a command pool, call:</p> +</div> +<div id="vkTrimCommandPoolKHR" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkTrimCommandPoolKHR( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlagsKHR flags);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the command pool.</p> +</li> +<li> +<p><code>commandPool</code> is the command pool to trim.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Trimming a command pool recycles unused memory from the command pool back to +the system. +Command buffers allocated from the pool are not affected by the command.</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>This command provides applications with some control over the internal +memory allocations used by command pools.</p> +</div> +<div class="paragraph"> +<p>Unused memory normally arises from command buffers that have been recorded +and later reset, such that they are no longer using the memory. +On reset, a command buffer can return memory to its command pool, but the +only way to release memory from a command pool to the system requires +calling <a href="#vkResetCommandPool">vkResetCommandPool</a>, which cannot be executed while any command +buffers from that pool are still in use. +Subsequent recording operations into command buffers will re-use this memory +but since total memory requirements fluctuate over time, unused memory can +accumulate.</p> +</div> +<div class="paragraph"> +<p>In this situation, trimming a command pool <strong class="purple">may</strong> be useful to return unused +memory back to the system, returning the total outstanding memory allocated +by the pool back to a more "average" value.</p> +</div> +<div class="paragraph"> +<p>Implementations utilize many internal allocation strategies that make it +impossible to guarantee that all unused memory is released back to the +system. +For instance, an implementation of a command pool <strong class="purple">may</strong> involve allocating +memory in bulk from the system and sub-allocating from that memory. +In such an implementation any live command buffer that holds a reference to +a bulk allocation would prevent that allocation from being freed, even if +only a small proportion of the bulk allocation is in use.</p> +</div> +<div class="paragraph"> +<p>In most cases trimming will result in a reduction in allocated but unused +memory, but it does not guarantee the "ideal" behaviour.</p> +</div> +<div class="paragraph"> +<p>Trimming <strong class="purple">may</strong> be an expensive operation, and <strong class="purple">should</strong> not be called +frequently. +Trimming <strong class="purple">should</strong> be treated as a way to relieve memory pressure after +application-known points when there exists enough unused memory that the +cost of trimming is "worth" it.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> be a valid <code>VkCommandPool</code> handle</p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandPool</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To reset a command pool, call:</p> +</div> +<div id="vkResetCommandPool" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkResetCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the command pool.</p> +</li> +<li> +<p><code>commandPool</code> is the command pool to reset.</p> +</li> +<li> +<p><code>flags</code> contains additional flags controlling the behavior of the +reset. +Bits which <strong class="purple">can</strong> be set include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkCommandPoolResetFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = <span class="hex">0x00000001</span>, +} VkCommandPoolResetFlagBits;</code></pre> +</div> +</div> +</div> +</div> +<div class="paragraph"> +<p>If <code>flags</code> includes <code>VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT</code>, +resetting a command pool recycles all of the resources from the command pool +back to the system.</p> +</div> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Resetting a command pool recycles all of the resources from all of the +command buffers allocated from the command pool back to the command pool. +All command buffers that have been allocated from the command pool are put +in the initial state.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All <code>VkCommandBuffer</code> objects allocated from <code>commandPool</code> <strong class="purple">must</strong> +not currently be pending execution</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> be a valid <code>VkCommandPool</code> handle</p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkCommandPoolResetFlagBits">VkCommandPoolResetFlagBits</a> values</p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandPool</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>To destroy a command pool, call:</p> +</div> +<div id="vkDestroyCommandPool" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroyCommandPool( + VkDevice device, + VkCommandPool commandPool, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that destroys the command pool.</p> +</li> +<li> +<p><code>commandPool</code> is the handle of the command pool to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When a pool is destroyed, all command buffers allocated from the pool are +implicitly freed and become invalid. +Command buffers allocated from a given pool do not need to be freed before +destroying that command pool.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All <code>VkCommandBuffer</code> objects allocated from <code>commandPool</code> <strong class="purple">must</strong> +not be pending execution</p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>commandPool</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>commandPool</code> +was created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p>If <code>commandPool</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>commandPool</code> <strong class="purple">must</strong> be a valid <code>VkCommandPool</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p>If <code>commandPool</code> is a valid handle, it <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandPool</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffer-allocation">5.2. Command Buffer Allocation and Management</h3> +<div class="paragraph"> +<p>To allocate command buffers, call:</p> +</div> +<div id="vkAllocateCommandBuffers" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkAllocateCommandBuffers( + VkDevice device, + <span class="directive">const</span> VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the command pool.</p> +</li> +<li> +<p><code>pAllocateInfo</code> is a pointer to an instance of the +<code>VkCommandBufferAllocateInfo</code> structure describing parameters of the +allocation.</p> +</li> +<li> +<p><code>pCommandBuffers</code> is a pointer to an array of <code>VkCommandBuffer</code> +handles in which the resulting command buffer objects are returned. +The array <strong class="purple">must</strong> be at least the length specified by the +<code>commandBufferCount</code> member of <code>pAllocateInfo</code>. +Each allocated command buffer begins in the initial state.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>vkAllocateCommandBuffers</code> <strong class="purple">can</strong> be used to create multiple command +buffers. +If the creation of any of those command buffers fails, the implementation +<strong class="purple">must</strong> destroy all successfully created command buffer objects from this +command, set all entries of the <code>pCommandBuffers</code> array to <code>NULL</code> and +return the error.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pAllocateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkCommandBufferAllocateInfo</code> structure</p> +</li> +<li> +<p><code>pCommandBuffers</code> <strong class="purple">must</strong> be a pointer to an array of <code>pAllocateInfo</code>::commandBufferCount <code>VkCommandBuffer</code> handles</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>pAllocateInfo</code>::commandPool <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkCommandBufferAllocateInfo</code> structure is defined as:</p> +</div> +<div id="VkCommandBufferAllocateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkCommandBufferAllocateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>commandPool</code> is the command pool from which the command buffers are +allocated.</p> +</li> +<li> +<p><code>level</code> determines whether the command buffers are primary or +secondary command buffers. +Possible values include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkCommandBufferLevel" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = <span class="integer">0</span>, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = <span class="integer">1</span>, +} VkCommandBufferLevel;</code></pre> +</div> +</div> +</div> +</div> +</li> +<li> +<p><code>commandBufferCount</code> is the number of command buffers to allocate +from the pool.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBufferCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> be a valid <code>VkCommandPool</code> handle</p> +</li> +<li> +<p><code>level</code> <strong class="purple">must</strong> be a valid <a href="#VkCommandBufferLevel">VkCommandBufferLevel</a> value</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To reset command buffers, call:</p> +</div> +<div id="vkResetCommandBuffer" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkResetCommandBuffer( + VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is the command buffer to reset. +The command buffer <strong class="purple">can</strong> be in any state, and is put in the initial +state.</p> +</li> +<li> +<p><code>flags</code> is a bitmask controlling the reset operation. +Bits which <strong class="purple">can</strong> be set include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkCommandBufferResetFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = <span class="hex">0x00000001</span>, +} VkCommandBufferResetFlagBits;</code></pre> +</div> +</div> +</div> +</div> +<div class="paragraph"> +<p>If <code>flags</code> includes <code>VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT</code>, +then most or all memory resources currently owned by the command buffer +<strong class="purple">should</strong> be returned to the parent command pool. +If this flag is not set, then the command buffer <strong class="purple">may</strong> hold onto memory +resources and reuse them when recording commands.</p> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> not currently be pending execution</p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> have been allocated from a pool that was +created with the <code>VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkCommandBufferResetFlagBits">VkCommandBufferResetFlagBits</a> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandBuffer</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>To free command buffers, call:</p> +</div> +<div id="vkFreeCommandBuffers" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkFreeCommandBuffers( + VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + <span class="directive">const</span> VkCommandBuffer* pCommandBuffers);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the command pool.</p> +</li> +<li> +<p><code>commandPool</code> is the command pool from which the command buffers +were allocated.</p> +</li> +<li> +<p><code>commandBufferCount</code> is the length of the <code>pCommandBuffers</code> +array.</p> +</li> +<li> +<p><code>pCommandBuffers</code> is an array of handles of command buffers to free.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All elements of <code>pCommandBuffers</code> <strong class="purple">must</strong> not be pending execution</p> +</li> +<li> +<p><code>pCommandBuffers</code> <strong class="purple">must</strong> be a pointer to an array of +<code>commandBufferCount</code> <code>VkCommandBuffer</code> handles, each element of +which <strong class="purple">must</strong> either be a valid handle or <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> be a valid <code>VkCommandPool</code> handle</p> +</li> +<li> +<p><code>commandBufferCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +<li> +<p><code>commandPool</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +<li> +<p>Each element of <code>pCommandBuffers</code> that is a valid handle <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>commandPool</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandPool</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to each member of <code>pCommandBuffers</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffers-recording">5.3. Command Buffer Recording</h3> +<div class="paragraph"> +<p>To begin recording a command buffer, call:</p> +</div> +<div id="vkBeginCommandBuffer" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkBeginCommandBuffer( + VkCommandBuffer commandBuffer, + <span class="directive">const</span> VkCommandBufferBeginInfo* pBeginInfo);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is the handle of the command buffer which is to be +put in the recording state.</p> +</li> +<li> +<p><code>pBeginInfo</code> is an instance of the <code>VkCommandBufferBeginInfo</code> +structure, which defines additional information about how the command +buffer begins recording.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> not be in the recording state</p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> not currently be pending execution</p> +</li> +<li> +<p>If <code>commandBuffer</code> was allocated from a <code>VkCommandPool</code> which +did not have the <code>VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT</code> +flag set, <code>commandBuffer</code> <strong class="purple">must</strong> be in the initial state</p> +</li> +<li> +<p>If <code>commandBuffer</code> is a secondary command buffer, the +<code>pInheritanceInfo</code> member of <code>pBeginInfo</code> <strong class="purple">must</strong> be a valid +<code>VkCommandBufferInheritanceInfo</code> structure</p> +</li> +<li> +<p>If <code>commandBuffer</code> is a secondary command buffer and either the +<code>occlusionQueryEnable</code> member of the <code>pInheritanceInfo</code> member +of <code>pBeginInfo</code> is <code>VK_FALSE</code>, or the precise occlusion queries +feature is not enabled, the <code>queryFlags</code> member of the +<code>pInheritanceInfo</code> member <code>pBeginInfo</code> <strong class="purple">must</strong> not contain +<code>VK_QUERY_CONTROL_PRECISE_BIT</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +<li> +<p><code>pBeginInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkCommandBufferBeginInfo</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandBuffer</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to the <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkCommandBufferBeginInfo</code> structure is defined as:</p> +</div> +<div id="VkCommandBufferBeginInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkCommandBufferBeginInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkCommandBufferUsageFlags flags; + <span class="directive">const</span> VkCommandBufferInheritanceInfo* pInheritanceInfo; +} VkCommandBufferBeginInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is a bitmask indicating usage behavior for the command +buffer. +Bits which <strong class="purple">can</strong> be set include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkCommandBufferUsageFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkCommandBufferUsageFlagBits { + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = <span class="hex">0x00000001</span>, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = <span class="hex">0x00000002</span>, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = <span class="hex">0x00000004</span>, +} VkCommandBufferUsageFlagBits;</code></pre> +</div> +</div> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT</code> indicates that each +recording of the command buffer will only be submitted once, and the +command buffer will be reset and recorded again between each +submission.</p> +</li> +<li> +<p><code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code> indicates that a +secondary command buffer is considered to be entirely inside a render +pass. +If this is a primary command buffer, then this bit is ignored.</p> +</li> +<li> +<p>Setting <code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> allows the +command buffer to be resubmitted to a queue or recorded into a primary +command buffer while it is pending execution.</p> +<div class="ulist"> +<ul> +<li> +<p><code>pInheritanceInfo</code> is a pointer to a +<code>VkCommandBufferInheritanceInfo</code> structure, which is used if +<code>commandBuffer</code> is a secondary command buffer. +If this is a primary command buffer, then this value is ignored.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>If <code>flags</code> contains +<code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code>, the +<code>renderPass</code> member of <code>pInheritanceInfo</code> <strong class="purple">must</strong> be a valid +<code>VkRenderPass</code></p> +</li> +<li> +<p>If <code>flags</code> contains +<code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code>, the +<code>subpass</code> member of <code>pInheritanceInfo</code> <strong class="purple">must</strong> be a valid subpass +index within the <code>renderPass</code> member of <code>pInheritanceInfo</code></p> +</li> +<li> +<p>If <code>flags</code> contains +<code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code>, the +<code>framebuffer</code> member of <code>pInheritanceInfo</code> <strong class="purple">must</strong> be either +<a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, or a valid <code>VkFramebuffer</code> that is compatible +with the <code>renderPass</code> member of <code>pInheritanceInfo</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code>, or a pointer to a valid instance of <a href="#VkDeviceGroupCommandBufferBeginInfoKHX">VkDeviceGroupCommandBufferBeginInfoKHX</a></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkCommandBufferUsageFlagBits">VkCommandBufferUsageFlagBits</a> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>If the command buffer is a secondary command buffer, then the +<code>VkCommandBufferInheritanceInfo</code> structure defines any state that will +be inherited from the primary command buffer:</p> +</div> +<div id="VkCommandBufferInheritanceInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkCommandBufferInheritanceInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkRenderPass renderPass; + uint32_t subpass; + VkFramebuffer framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>renderPass</code> is a <code>VkRenderPass</code> object defining which render +passes the <code>VkCommandBuffer</code> will be <a href="#renderpass-compatibility">compatible</a> with and <strong class="purple">can</strong> be executed within. +If the <code>VkCommandBuffer</code> will not be executed within a render pass +instance, <code>renderPass</code> is ignored.</p> +</li> +<li> +<p><code>subpass</code> is the index of the subpass within the render pass +instance that the <code>VkCommandBuffer</code> will be executed within. +If the <code>VkCommandBuffer</code> will not be executed within a render pass +instance, <code>subpass</code> is ignored.</p> +</li> +<li> +<p><code>framebuffer</code> optionally refers to the <code>VkFramebuffer</code> object +that the <code>VkCommandBuffer</code> will be rendering to if it is executed +within a render pass instance. +It <strong class="purple">can</strong> be <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a> if the framebuffer is not known, or if +the <code>VkCommandBuffer</code> will not be executed within a render pass +instance.</p> +<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>Specifying the exact framebuffer that the secondary command buffer will be +executed with <strong class="purple">may</strong> result in better performance at command buffer execution +time.</p> +</div> +</td> +</tr> +</table> +</div> +</li> +<li> +<p><code>occlusionQueryEnable</code> indicates whether the command buffer <strong class="purple">can</strong> be +executed while an occlusion query is active in the primary command +buffer. +If this is <code>VK_TRUE</code>, then this command buffer <strong class="purple">can</strong> be executed +whether the primary command buffer has an occlusion query active or not. +If this is <code>VK_FALSE</code>, then the primary command buffer <strong class="purple">must</strong> not +have an occlusion query active.</p> +</li> +<li> +<p><code>queryFlags</code> indicates the query flags that <strong class="purple">can</strong> be used by an +active occlusion query in the primary command buffer when this secondary +command buffer is executed. +If this value includes the <code>VK_QUERY_CONTROL_PRECISE_BIT</code> bit, then +the active query <strong class="purple">can</strong> return boolean results or actual sample counts. +If this bit is not set, then the active query <strong class="purple">must</strong> not use the +<code>VK_QUERY_CONTROL_PRECISE_BIT</code> bit.</p> +</li> +<li> +<p><code>pipelineStatistics</code> indicates the set of pipeline statistics that +<strong class="purple">can</strong> be counted by an active query in the primary command buffer when +this secondary command buffer is executed. +If this value includes a given bit, then this command buffer <strong class="purple">can</strong> be +executed whether the primary command buffer has a pipeline statistics +query active that includes this bit or not. +If this value excludes a given bit, then the active pipeline statistics +query <strong class="purple">must</strong> not be from a query pool that counts that statistic.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>If the <a href="#features-features-inheritedQueries">inherited queries</a> feature +is not enabled, <code>occlusionQueryEnable</code> <strong class="purple">must</strong> be <code>VK_FALSE</code></p> +</li> +<li> +<p>If the <a href="#features-features-inheritedQueries">inherited queries</a> feature +is enabled, <code>queryFlags</code> <strong class="purple">must</strong> be a valid combination of +<a href="#VkQueryControlFlagBits">VkQueryControlFlagBits</a> values</p> +</li> +<li> +<p>If the <a href="#features-features-pipelineStatisticsQuery">pipeline statistics +queries</a> feature is not enabled, <code>pipelineStatistics</code> <strong class="purple">must</strong> be +<code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>Both of <code>framebuffer</code>, and <code>renderPass</code> that are valid handles <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>A primary command buffer is considered to be pending execution from the time +it is submitted via <code>vkQueueSubmit</code> until that submission completes.</p> +</div> +<div class="paragraph"> +<p>A secondary command buffer is considered to be pending execution from the +time its execution is recorded into a primary buffer (via +<code>vkCmdExecuteCommands</code>) until the final time that primary buffer’s +submission to a queue completes. +If, after the primary buffer completes, the secondary command buffer is +recorded to execute on a different primary buffer, the first primary buffer +<strong class="purple">must</strong> not be resubmitted until after it is reset with +<a href="#vkResetCommandBuffer">vkResetCommandBuffer</a> unless the secondary command buffer was recorded +with <code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code>.</p> +</div> +<div class="paragraph"> +<p>If <code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> is not set on a +secondary command buffer, that command buffer <strong class="purple">must</strong> not be used more than +once in a given primary command buffer. +Furthermore, if a secondary command buffer without +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> set is recorded to +execute in a primary command buffer with +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> set, the primary command +buffer <strong class="purple">must</strong> not be pending execution more than once at a time.</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>On some implementations, not using the +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> bit enables command +buffers to be patched in-place if needed, rather than creating a copy of the +command buffer.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>If a command buffer is in the executable state and the command buffer was +allocated from a command pool with the +<code>VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT</code> flag set, then +<code>vkBeginCommandBuffer</code> implicitly resets the command buffer, behaving as +if <code>vkResetCommandBuffer</code> had been called with +<code>VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT</code> not set. +It then puts the command buffer in the recording state.</p> +</div> +<div class="paragraph"> +<p>Once recording starts, an application records a sequence of commands +(<code>vkCmd</code>*) to set state in the command buffer, draw, dispatch, and other +commands.</p> +</div> +<div class="paragraph"> +<p>Several commands can also be recorded indirectly from <code>VkBuffer</code> +content, see <a href="#device-generated-commands">Device-Generated Commands</a>.</p> +</div> +<div class="paragraph"> +<p>To complete recording of a command buffer, call:</p> +</div> +<div id="vkEndCommandBuffer" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkEndCommandBuffer( + VkCommandBuffer commandBuffer);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is the command buffer to complete recording. +The command buffer <strong class="purple">must</strong> have been in the recording state, and is moved +to the executable state.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If there was an error during recording, the application will be notified by +an unsuccessful return code returned by <code>vkEndCommandBuffer</code>. +If the application wishes to further use the command buffer, the command +buffer <strong class="purple">must</strong> be reset.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be in the recording state</p> +</li> +<li> +<p>If <code>commandBuffer</code> is a primary command buffer, there <strong class="purple">must</strong> not be +an active render pass instance</p> +</li> +<li> +<p>All queries made <a href="#queries-operation-active">active</a> during the +recording of <code>commandBuffer</code> <strong class="purple">must</strong> have been made inactive</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandBuffer</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to the <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>When a command buffer is in the executable state, it <strong class="purple">can</strong> be submitted to a +queue for execution.</p> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffers-submission">5.4. Command Buffer Submission</h3> +<div class="paragraph"> +<p>To submit command buffers to a queue, call:</p> +</div> +<div id="vkQueueSubmit" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkQueueSubmit( + VkQueue queue, + uint32_t submitCount, + <span class="directive">const</span> VkSubmitInfo* pSubmits, + VkFence fence);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>queue</code> is the queue that the command buffers will be submitted to.</p> +</li> +<li> +<p><code>submitCount</code> is the number of elements in the <code>pSubmits</code> array.</p> +</li> +<li> +<p><code>pSubmits</code> is a pointer to an array of <a href="#VkSubmitInfo">VkSubmitInfo</a> +structures, each specifying a command buffer submission batch.</p> +</li> +<li> +<p><code>fence</code> is an optional handle to a fence to be signaled. +If <code>fence</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, it defines a +<a href="#synchronization-fences-signaling">fence signal operation</a>.</p> +</li> +</ul> +</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>Submission can be a high overhead operation, and applications <strong class="purple">should</strong> +attempt to batch work together into as few calls to <code>vkQueueSubmit</code> as +possible.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p><code>vkQueueSubmit</code> is a <a href="#devsandqueues-submission">queue submission +command</a>, with each batch defined by an element of <code>pSubmits</code> as an +instance of the <a href="#VkSubmitInfo">VkSubmitInfo</a> structure. +Batches begin execution in the order they appear in <code>pSubmits</code>, but <strong class="purple">may</strong> +complete out of order.</p> +</div> +<div class="paragraph"> +<p>Fence and semaphore operations submitted with <a href="#vkQueueSubmit">vkQueueSubmit</a> have +additional ordering constraints compared to other submission commands, with +dependencies involving previous and subsequent queue operations. +Information about these additional constraints can be found in the +<a href="#synchronization-semaphores">semaphore</a> and <a href="#synchronization-fences">fence</a> sections of <a href="#synchronization">the synchronization chapter</a>.</p> +</div> +<div class="paragraph"> +<p>Details on the interaction of <code>pWaitDstStageMask</code> with synchronization +are described in the <a href="#synchronization-semaphores-waiting">semaphore wait +operation</a> section of <a href="#synchronization">the synchronization chapter</a>.</p> +</div> +<div class="paragraph"> +<p>The order that batches appear in <code>pSubmits</code> is used to determine +<a href="#synchronization-submission-order">submission order</a>, and thus all the +<a href="#synchronization-implicit">implicit ordering guarantees</a> that respect it. +Other than these implicit ordering guarantees and any <a href="#synchronization">explicit synchronization primitives</a>, these batches <strong class="purple">may</strong> overlap or +otherwise execute out of order.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>If <code>fence</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>fence</code> <strong class="purple">must</strong> be +unsignaled</p> +</li> +<li> +<p>If <code>fence</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>fence</code> <strong class="purple">must</strong> not be +associated with any other queue command that has not yet completed +execution on that queue</p> +</li> +<li> +<p>Any calls to <a href="#vkCmdSetEvent">vkCmdSetEvent</a>, <a href="#vkCmdResetEvent">vkCmdResetEvent</a> or +<a href="#vkCmdWaitEvents">vkCmdWaitEvents</a> that have been recorded into any of the command +buffer elements of the <code>pCommandBuffers</code> member of any element of +<code>pSubmits</code>, <strong class="purple">must</strong> not reference any <a href="#VkEvent">VkEvent</a> that is referenced +by any of those commands that is pending execution on another queue.</p> +</li> +<li> +<p>Any stage flag included in any element of the <code>pWaitDstStageMask</code> +member of any element of <code>pSubmits</code> <strong class="purple">must</strong> be a pipeline stage +supported by one of the capabilities of <code>queue</code>, as specified in the +<a href="#synchronization-pipeline-stages-supported">table of supported pipeline +stages</a>.</p> +</li> +<li> +<p>Any given element of the <code>pSignalSemaphores</code> member of any element +of <code>pSubmits</code> <strong class="purple">must</strong> be unsignaled when the semaphore signal +operation it defines is executed on the device</p> +</li> +<li> +<p>When a semaphore unsignal operation defined by any element of the +<code>pWaitSemaphores</code> member of any element of <code>pSubmits</code> executes +on <code>queue</code>, no other queue <strong class="purple">must</strong> be waiting on the same semaphore.</p> +</li> +<li> +<p>All elements of the <code>pWaitSemaphores</code> member of all elements of +<code>pSubmits</code> <strong class="purple">must</strong> be semaphores that are signaled, or have +<a href="#synchronization-semaphores-signaling">semaphore signal operations</a> +previously submitted for execution.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>queue</code> <strong class="purple">must</strong> be a valid <code>VkQueue</code> handle</p> +</li> +<li> +<p>If <code>submitCount</code> is not <code>0</code>, <code>pSubmits</code> <strong class="purple">must</strong> be a pointer to an array of <code>submitCount</code> valid <code>VkSubmitInfo</code> structures</p> +</li> +<li> +<p>If <code>fence</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>fence</code> <strong class="purple">must</strong> be a valid <code>VkFence</code> handle</p> +</li> +<li> +<p>Both of <code>fence</code>, and <code>queue</code> that are valid handles <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>queue</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to <code>pSubmits</code>[].pWaitSemaphores[] <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to <code>pSubmits</code>[].pSignalSemaphores[] <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to <code>fence</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Command Properties</div> +<table class="tableblock frame-all grid-all spread"> +<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"><a href="#VkCommandBufferLevel">Command Buffer Levels</a></th> +<th class="tableblock halign-left valign-top"><a href="#vkCmdBeginRenderPass">Render Pass Scope</a></th> +<th class="tableblock halign-left valign-top"><a href="#VkQueueFlagBits">Supported Queue Types</a></th> +<th class="tableblock halign-left valign-top"><a href="#synchronization-pipeline-stages-types">Pipeline Type</a></th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Any</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td> +</tr> +</tbody> +</table> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkSubmitInfo</code> structure is defined as:</p> +</div> +<div id="VkSubmitInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkSubmitInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t waitSemaphoreCount; + <span class="directive">const</span> VkSemaphore* pWaitSemaphores; + <span class="directive">const</span> VkPipelineStageFlags* pWaitDstStageMask; + uint32_t commandBufferCount; + <span class="directive">const</span> VkCommandBuffer* pCommandBuffers; + uint32_t signalSemaphoreCount; + <span class="directive">const</span> VkSemaphore* pSignalSemaphores; +} VkSubmitInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>waitSemaphoreCount</code> is the number of semaphores upon which to wait +before executing the command buffers for the batch.</p> +</li> +<li> +<p><code>pWaitSemaphores</code> is a pointer to an array of semaphores upon which +to wait before the command buffers for this batch begin execution. +If semaphores to wait on are provided, they define a +<a href="#synchronization-semaphores-waiting">semaphore wait operation</a>.</p> +</li> +<li> +<p><code>pWaitDstStageMask</code> is a pointer to an array of pipeline stages at +which each corresponding semaphore wait will occur.</p> +</li> +<li> +<p><code>commandBufferCount</code> is the number of command buffers to execute in +the batch.</p> +</li> +<li> +<p><code>pCommandBuffers</code> is a pointer to an array of command buffers to +execute in the batch.</p> +</li> +<li> +<p><code>signalSemaphoreCount</code> is the number of semaphores to be signaled +once the commands specified in <code>pCommandBuffers</code> have completed +execution.</p> +</li> +<li> +<p><code>pSignalSemaphores</code> is a pointer to an array of semaphores which +will be signaled when the command buffers for this batch have completed +execution. +If semaphores to be signaled are provided, they define a +<a href="#synchronization-semaphores-signaling">semaphore signal operation</a>.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The order that command buffers appear in <code>pCommandBuffers</code> is used to +determine <a href="#synchronization-submission-order">submission order</a>, and thus +all the <a href="#synchronization-implicit">implicit ordering guarantees</a> that +respect it. +Other than these implicit ordering guarantees and any <a href="#synchronization">explicit synchronization primitives</a>, these command buffers <strong class="purple">may</strong> overlap or +otherwise execute out of order.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> either have been +recorded with the <code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code>, or +not currently be executing on the device</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> be in the executable +state</p> +</li> +<li> +<p>If any given element of <code>pCommandBuffers</code> contains commands that +execute secondary command buffers, those secondary command buffers <strong class="purple">must</strong> +have been recorded with the +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code>, or not currently be +executing on the device</p> +</li> +<li> +<p>If any given element of <code>pCommandBuffers</code> was recorded with +<code>VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT</code>, it <strong class="purple">must</strong> not have +been previously submitted without re-recording that command buffer</p> +</li> +<li> +<p>If any given element of <code>pCommandBuffers</code> contains commands that +execute secondary command buffers recorded with +<code>VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT</code>, each such secondary +command buffer <strong class="purple">must</strong> not have been previously submitted without +re-recording that command buffer</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not contain commands +that execute a secondary command buffer, if that secondary command +buffer has been recorded in another primary command buffer after it was +recorded into this <code>VkCommandBuffer</code></p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been allocated +from a <code>VkCommandPool</code> that was created for the same queue family +that the calling command’s <code>queue</code> belongs to</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not have been allocated +with <code>VK_COMMAND_BUFFER_LEVEL_SECONDARY</code></p> +</li> +<li> +<p>If the <a href="#features-features-geometryShader">geometry shaders</a> feature is +not enabled, any given element of <code>pWaitDstStageMask</code> <strong class="purple">must</strong> not +contain <code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code></p> +</li> +<li> +<p>If the <a href="#features-features-tessellationShader">tessellation shaders</a> +feature is not enabled, any given element of <code>pWaitDstStageMask</code> +<strong class="purple">must</strong> not contain +<code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code> or +<code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code></p> +</li> +<li> +<p>Any given element of <code>pWaitDstStageMask</code> <strong class="purple">must</strong> not include +<code>VK_PIPELINE_STAGE_HOST_BIT</code>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_SUBMIT_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code>, or a pointer to a valid instance of <a href="#VkWin32KeyedMutexAcquireReleaseInfoNV">VkWin32KeyedMutexAcquireReleaseInfoNV</a>, <a href="#VkWin32KeyedMutexAcquireReleaseInfoKHX">VkWin32KeyedMutexAcquireReleaseInfoKHX</a>, <a href="#VkD3D12FenceSubmitInfoKHX">VkD3D12FenceSubmitInfoKHX</a>, or <a href="#VkDeviceGroupSubmitInfoKHX">VkDeviceGroupSubmitInfoKHX</a></p> +</li> +<li> +<p>If <code>waitSemaphoreCount</code> is not <code>0</code>, <code>pWaitSemaphores</code> <strong class="purple">must</strong> be a pointer to an array of <code>waitSemaphoreCount</code> valid <code>VkSemaphore</code> handles</p> +</li> +<li> +<p>If <code>waitSemaphoreCount</code> is not <code>0</code>, <code>pWaitDstStageMask</code> <strong class="purple">must</strong> be a pointer to an array of <code>waitSemaphoreCount</code> valid combinations of <a href="#VkPipelineStageFlagBits">VkPipelineStageFlagBits</a> values</p> +</li> +<li> +<p>Each element of <code>pWaitDstStageMask</code> <strong class="purple">must</strong> not be <code>0</code></p> +</li> +<li> +<p>If <code>commandBufferCount</code> is not <code>0</code>, <code>pCommandBuffers</code> <strong class="purple">must</strong> be a pointer to an array of <code>commandBufferCount</code> valid <code>VkCommandBuffer</code> handles</p> +</li> +<li> +<p>If <code>signalSemaphoreCount</code> is not <code>0</code>, <code>pSignalSemaphores</code> <strong class="purple">must</strong> be a pointer to an array of <code>signalSemaphoreCount</code> valid <code>VkSemaphore</code> handles</p> +</li> +<li> +<p>Each of the elements of <code>pCommandBuffers</code>, the elements of <code>pSignalSemaphores</code>, and the elements of <code>pWaitSemaphores</code> that are valid handles <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To specify the values to use when waiting for and signaling semaphores whose +current state is shared with a Direct3D 12 fence, add the +<a href="#VkD3D12FenceSubmitInfoKHX">VkD3D12FenceSubmitInfoKHX</a> structure to the <code>pNext</code> chain of the +<a href="#VkSubmitInfo">VkSubmitInfo</a> structure. +The <code>VkD3D12FenceSubmitInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkD3D12FenceSubmitInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkD3D12FenceSubmitInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t waitSemaphoreValuesCount; + <span class="directive">const</span> uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValuesCount; + <span class="directive">const</span> uint64_t* pSignalSemaphoreValues; +} VkD3D12FenceSubmitInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>waitSemaphoreValuesCount</code> is the number of semaphore wait values +specified in <code>pWaitSemaphoreValues</code>.</p> +</li> +<li> +<p><code>pWaitSemaphoreValues</code> is an array of length +<code>waitSemaphoreValuesCount</code> containing values for the corresponding +semaphores in <a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pWaitSemaphores</code> to wait for.</p> +</li> +<li> +<p><code>signalSemaphoreValuesCount</code> is the number of semaphore signal +values specified in <code>pSignalSemaphoreValues</code>.</p> +</li> +<li> +<p><code>pSignalSemaphoreValues</code> is an array of length +<code>signalSemaphoreValuesCount</code> containing values for the corresponding +semaphores in <a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pSignalSemaphores</code> to set when +signaled.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If the semaphore in <a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pWaitSemaphores</code> or +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pSignalSemaphore</code> corresponding to an entry in +<code>pWaitSemaphoreValues</code> or <code>pSignalSemaphoreValues</code> respectively does +not currently have state imported from a Direct3D 12 fence, the value in the +<code>pWaitSemaphoreValues</code> or <code>pSignalSemaphoreValues</code> entry is ignored.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>waitSemaphoreValuesCount</code> <strong class="purple">must</strong> be the same value as +<code>VkSubmitInfo</code>::<code>waitSemaphoreCount</code>, where <code>SubmitInfo</code> is +in the pNext-chain of this <code>VkD3D12FenceSubmitInfoKHX</code> structure.</p> +</li> +<li> +<p><code>signalSemaphoreValuesCount</code> <strong class="purple">must</strong> be the same value as +<code>VkSubmitInfo</code>::<code>signalSemaphoreCount</code>, where <code>SubmitInfo</code> +is in the pNext-chain of this <code>VkD3D12FenceSubmitInfoKHX</code> structure.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>waitSemaphoreValuesCount</code> is not <code>0</code>, and <code>pWaitSemaphoreValues</code> is not <code>NULL</code>, <code>pWaitSemaphoreValues</code> <strong class="purple">must</strong> be a pointer to an array of <code>waitSemaphoreValuesCount</code> <code>uint64_t</code> values</p> +</li> +<li> +<p>If <code>signalSemaphoreValuesCount</code> is not <code>0</code>, and <code>pSignalSemaphoreValues</code> is not <code>NULL</code>, <code>pSignalSemaphoreValues</code> <strong class="purple">must</strong> be a pointer to an array of <code>signalSemaphoreValuesCount</code> <code>uint64_t</code> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>When submitting work that operates on memory imported from a Direct3D 11 +resource to a queue, the keyed mutex mechanism <strong class="purple">may</strong> be used in addition to +Vulkan semaphores to synchronize the work. +Keyed mutexes are a property of a properly created shareable Direct3D 11 +resource. +They <strong class="purple">can</strong> only be used if the imported resource was created with the +<code>D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX</code> flag.</p> +</div> +<div class="paragraph"> +<p>To acquire keyed mutexes before submitted work and/or release them after, +add a <a href="#VkWin32KeyedMutexAcquireReleaseInfoKHX">VkWin32KeyedMutexAcquireReleaseInfoKHX</a> structure to the +<code>pNext</code> chain of the <a href="#VkSubmitInfo">VkSubmitInfo</a> structure.</p> +</div> +<div class="paragraph"> +<p>The <code>VkWin32KeyedMutexAcquireReleaseInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkWin32KeyedMutexAcquireReleaseInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkWin32KeyedMutexAcquireReleaseInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t acquireCount; + <span class="directive">const</span> VkDeviceMemory* pAcquireSyncs; + <span class="directive">const</span> uint64_t* pAcquireKeys; + <span class="directive">const</span> uint32_t* pAcquireTimeouts; + uint32_t releaseCount; + <span class="directive">const</span> VkDeviceMemory* pReleaseSyncs; + <span class="directive">const</span> uint64_t* pReleaseKeys; +} VkWin32KeyedMutexAcquireReleaseInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>acquireCount</code> is the number of entries in the <code>pAcquireSyncs</code>, +<code>pAcquireKeys</code>, and <code>pAcquireTimeoutMilliseconds</code> arrays.</p> +</li> +<li> +<p><code>pAcquireSyncs</code> is a pointer to an array of <a href="#VkDeviceMemory">VkDeviceMemory</a> +objects which were imported from Direct3D 11 resources.</p> +</li> +<li> +<p><code>pAcquireKeys</code> is a pointer to an array of mutex key values to wait +for prior to beginning the submitted work. +Entries refer to the keyed mutex associated with the corresponding +entries in <code>pAcquireSyncs</code>.</p> +</li> +<li> +<p><code>pAcquireTimeoutMilliseconds</code> is an array of timeout values, in +millisecond units, for each acquire specified in <code>pAcquireKeys</code>.</p> +</li> +<li> +<p><code>releaseCount</code> is the number of entries in the <code>pReleaseSyncs</code> +and <code>pReleaseKeys</code> arrays.</p> +</li> +<li> +<p><code>pReleaseSyncs</code> is a pointer to an array of <a href="#VkDeviceMemory">VkDeviceMemory</a> +objects which were imported from Direct3D 11 resources.</p> +</li> +<li> +<p><code>pReleaseKeys</code> is a pointer to an array of mutex key values to set +when the submitted work has completed. +Entries refer to the keyed mutex associated with the corresponding +entries in <code>pReleaseSyncs</code>.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>Each member of <code>pAcquireSyncs</code> and <code>pReleaseSyncs</code> must be a +device memory object imported by setting +<a href="#VkImportMemoryWin32HandleInfoKHX">VkImportMemoryWin32HandleInfoKHX</a>::<code>handleType</code> to +<code>VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHX</code> or +<code>VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHX</code>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireSyncs</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> valid <code>VkDeviceMemory</code> handles</p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireKeys</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> <code>uint64_t</code> values</p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireTimeouts</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> <code>uint32_t</code> values</p> +</li> +<li> +<p>If <code>releaseCount</code> is not <code>0</code>, <code>pReleaseSyncs</code> <strong class="purple">must</strong> be a pointer to an array of <code>releaseCount</code> valid <code>VkDeviceMemory</code> handles</p> +</li> +<li> +<p>If <code>releaseCount</code> is not <code>0</code>, <code>pReleaseKeys</code> <strong class="purple">must</strong> be a pointer to an array of <code>releaseCount</code> <code>uint64_t</code> values</p> +</li> +<li> +<p>Both of the elements of <code>pAcquireSyncs</code>, and the elements of <code>pReleaseSyncs</code> that are valid handles <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>When submitting work that operates on memory imported from a Direct3D 11 +resource to a queue, the keyed mutex mechanism <strong class="purple">may</strong> be used in addition to +Vulkan semaphores to synchronize the work. +Keyed mutexes are a property of a properly created shareable Direct3D 11 +resource. +They <strong class="purple">can</strong> only be used if the imported resource was created with the +<code>D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX</code> flag.</p> +</div> +<div class="paragraph"> +<p>To acquire keyed mutexes before submitted work and/or release them after, +add a <a href="#VkWin32KeyedMutexAcquireReleaseInfoNV">VkWin32KeyedMutexAcquireReleaseInfoNV</a> structure to the +<code>pNext</code> chain of the <a href="#VkSubmitInfo">VkSubmitInfo</a> structure.</p> +</div> +<div class="paragraph"> +<p>The <code>VkWin32KeyedMutexAcquireReleaseInfoNV</code> structure is defined as:</p> +</div> +<div id="VkWin32KeyedMutexAcquireReleaseInfoNV" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkWin32KeyedMutexAcquireReleaseInfoNV { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t acquireCount; + <span class="directive">const</span> VkDeviceMemory* pAcquireSyncs; + <span class="directive">const</span> uint64_t* pAcquireKeys; + <span class="directive">const</span> uint32_t* pAcquireTimeoutMilliseconds; + uint32_t releaseCount; + <span class="directive">const</span> VkDeviceMemory* pReleaseSyncs; + <span class="directive">const</span> uint64_t* pReleaseKeys; +} VkWin32KeyedMutexAcquireReleaseInfoNV;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>acquireCount</code> is the number of entries in the +<code>pAcquireSyncs</code>, <code>pAcquireKeys</code>, and +<code>pAcquireTimeoutMilliseconds</code> arrays.</p> +</li> +<li> +<p><code>pAcquireSyncs</code> is a pointer to an array of <a href="#VkDeviceMemory">VkDeviceMemory</a> +objects which were imported from Direct3D 11 resources.</p> +</li> +<li> +<p><code>pAcquireKeys</code> is a pointer to an array of mutex key values to +wait for prior to beginning the submitted work. +Entries refer to the keyed mutex associated with the corresponding +entries in <code>pAcquireSyncs</code>.</p> +</li> +<li> +<p><code>pAcquireTimeoutMilliseconds</code> is an array of timeout values, in +millisecond units, for each acquire specified in <code>pAcquireKeys</code>.</p> +</li> +<li> +<p><code>releaseCount</code> is the number of entries in the <code>pReleaseSyncs</code> +and <code>pReleaseKeys</code> arrays.</p> +</li> +<li> +<p><code>pReleaseSyncs</code> is a pointer to an array of <a href="#VkDeviceMemory">VkDeviceMemory</a> +objects which were imported from Direct3D 11 resources.</p> +</li> +<li> +<p><code>pReleaseKeys</code> is a pointer to an array of mutex key values to set +when the submitted work has completed. +Entries refer to the keyed mutex associated with the corresponding +entries in <code>pReleaseSyncs</code>.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireSyncs</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> valid <code>VkDeviceMemory</code> handles</p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireKeys</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> <code>uint64_t</code> values</p> +</li> +<li> +<p>If <code>acquireCount</code> is not <code>0</code>, <code>pAcquireTimeoutMilliseconds</code> <strong class="purple">must</strong> be a pointer to an array of <code>acquireCount</code> <code>uint32_t</code> values</p> +</li> +<li> +<p>If <code>releaseCount</code> is not <code>0</code>, <code>pReleaseSyncs</code> <strong class="purple">must</strong> be a pointer to an array of <code>releaseCount</code> valid <code>VkDeviceMemory</code> handles</p> +</li> +<li> +<p>If <code>releaseCount</code> is not <code>0</code>, <code>pReleaseKeys</code> <strong class="purple">must</strong> be a pointer to an array of <code>releaseCount</code> <code>uint64_t</code> values</p> +</li> +<li> +<p>Both of the elements of <code>pAcquireSyncs</code>, and the elements of <code>pReleaseSyncs</code> that are valid handles <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>If the <code>pNext</code> list of <a href="#VkSubmitInfo">VkSubmitInfo</a> includes a +<code>VkDeviceGroupSubmitInfoKHX</code> structure, then that structure includes +device indices and masks specifying which physical devices execute semaphore +operations and command buffers.</p> +</div> +<div class="paragraph"> +<p>The <code>VkDeviceGroupSubmitInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkDeviceGroupSubmitInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceGroupSubmitInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t waitSemaphoreCount; + <span class="directive">const</span> uint32_t* pWaitSemaphoreDeviceIndices; + uint32_t commandBufferCount; + <span class="directive">const</span> uint32_t* pCommandBufferDeviceMasks; + uint32_t signalSemaphoreCount; + <span class="directive">const</span> uint32_t* pSignalSemaphoreDeviceIndices; +} VkDeviceGroupSubmitInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>waitSemaphoreCount</code> is the number of elements in the +<code>pWaitSemaphoreDeviceIndices</code> array.</p> +</li> +<li> +<p><code>pWaitSemaphoreDeviceIndices</code> is an array of device indices +indicating which physical device executes the semaphore wait operation +in the corresponding element of +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pWaitSemaphores</code>.</p> +</li> +<li> +<p><code>commandBufferCount</code> is the number of elements in the +<code>pCommandBufferDeviceMasks</code> array.</p> +</li> +<li> +<p><code>pCommandBufferDeviceMasks</code> is an array of device masks indicating +which physical devices execute the command buffer in the corresponding +element of <a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pCommandBuffers</code>. +A physical device executes the command buffer if the corresponding bit +is set in the mask.</p> +</li> +<li> +<p><code>signalSemaphoreCount</code> is the number of elements in the +<code>pSignalSemaphoreDeviceIndices</code> array.</p> +</li> +<li> +<p><code>pSignalSemaphoreDeviceIndices</code> is an array of device indices +indicating which physical device executes the semaphore signal operation +in the corresponding element of +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>pSignalSemaphores</code>.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If this structure is not present, semaphore operations and command buffers +execute on device index zero.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>waitSemaphoreCount</code> <strong class="purple">must</strong> equal +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>waitSemaphoreCount</code></p> +</li> +<li> +<p><code>commandBufferCount</code> <strong class="purple">must</strong> equal +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>commandBufferCount</code></p> +</li> +<li> +<p><code>signalSemaphoreCount</code> <strong class="purple">must</strong> equal +<a href="#VkSubmitInfo">VkSubmitInfo</a>::<code>signalSemaphoreCount</code></p> +</li> +<li> +<p>All elements of <code>pWaitSemaphoreDeviceIndices</code> and +<code>pSignalSemaphoreDeviceIndices</code> <strong class="purple">must</strong> be valid device indices</p> +</li> +<li> +<p>All elements of <code>pCommandBufferDeviceMasks</code> <strong class="purple">must</strong> be valid device +masks</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>waitSemaphoreCount</code> is not <code>0</code>, <code>pWaitSemaphoreDeviceIndices</code> <strong class="purple">must</strong> be a pointer to an array of <code>waitSemaphoreCount</code> <code>uint32_t</code> values</p> +</li> +<li> +<p>If <code>commandBufferCount</code> is not <code>0</code>, <code>pCommandBufferDeviceMasks</code> <strong class="purple">must</strong> be a pointer to an array of <code>commandBufferCount</code> <code>uint32_t</code> values</p> +</li> +<li> +<p>If <code>signalSemaphoreCount</code> is not <code>0</code>, <code>pSignalSemaphoreDeviceIndices</code> <strong class="purple">must</strong> be a pointer to an array of <code>signalSemaphoreCount</code> <code>uint32_t</code> values</p> +</li> +</ul> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffers-submission-progress">5.5. Queue Forward Progress</h3> +<div class="paragraph"> +<p>The application <strong class="purple">must</strong> ensure that command buffer submissions will be able to +complete without any subsequent operations by the application on any queue. +After any call to <code>vkQueueSubmit</code>, for every queued wait on a semaphore +there <strong class="purple">must</strong> be a prior signal of that semaphore that will not be consumed by +a different wait on the semaphore.</p> +</div> +<div class="paragraph"> +<p>Command buffers in the submission <strong class="purple">can</strong> include <a href="#vkCmdWaitEvents">vkCmdWaitEvents</a> +commands that wait on events that will not be signaled by earlier commands +in the queue. +Such events <strong class="purple">must</strong> be signaled by the application using <a href="#vkSetEvent">vkSetEvent</a>, and +the <code>vkCmdWaitEvents</code> commands that wait upon them <strong class="purple">must</strong> not be inside a +render pass instance. +Implementations <strong class="purple">may</strong> have limits on how long the command buffer will wait, +in order to avoid interfering with progress of other clients of the device. +If the event is not signaled within these limits, results are undefined and +<strong class="purple">may</strong> include device loss.</p> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffers-secondary">5.6. Secondary Command Buffer Execution</h3> +<div class="paragraph"> +<p>A secondary command buffer <strong class="purple">must</strong> not be directly submitted to a queue. +Instead, secondary command buffers are recorded to execute as part of a +primary command buffer with the command:</p> +</div> +<div id="vkCmdExecuteCommands" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + <span class="directive">const</span> VkCommandBuffer* pCommandBuffers);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is a handle to a primary command buffer that the +secondary command buffers are executed in.</p> +</li> +<li> +<p><code>commandBufferCount</code> is the length of the <code>pCommandBuffers</code> +array.</p> +</li> +<li> +<p><code>pCommandBuffers</code> is an array of secondary command buffer handles, +which are recorded to execute in the primary command buffer in the order +they are listed in the array.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Once <code>vkCmdExecuteCommands</code> has been called, any prior executions of the +secondary command buffers specified by <code>pCommandBuffers</code> in any other +primary command buffer become invalidated, unless those secondary command +buffers were recorded with +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code>.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> have been allocated with a <code>level</code> of +<code>VK_COMMAND_BUFFER_LEVEL_PRIMARY</code></p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been allocated +with a <code>level</code> of <code>VK_COMMAND_BUFFER_LEVEL_SECONDARY</code></p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not be already pending +execution in <code>commandBuffer</code>, or appear twice in +<code>pCommandBuffers</code>, unless it was recorded with the +<code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> flag</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not be already pending +execution in any other <code>VkCommandBuffer</code>, unless it was recorded +with the <code>VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT</code> flag</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> be in the executable +state</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been allocated +from a <code>VkCommandPool</code> that was created for the same queue family as +the <code>VkCommandPool</code> from which <code>commandBuffer</code> was allocated</p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is being called within a render pass +instance, that render pass instance <strong class="purple">must</strong> have been begun with the +<code>contents</code> parameter of <code>vkCmdBeginRenderPass</code> set to +<code>VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS</code></p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is being called within a render pass +instance, any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been +recorded with the <code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code></p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is being called within a render pass +instance, any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been +recorded with <code>VkCommandBufferInheritanceInfo</code>::<code>subpass</code> set to +the index of the subpass which the given command buffer will be executed +in</p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is being called within a render pass +instance, the render passes specified in the +pname::pBeginInfo::<code>pInheritanceInfo</code>::<code>renderPass</code> members of +the <a href="#vkBeginCommandBuffer">vkBeginCommandBuffer</a> commands used to begin recording each +element of <code>pCommandBuffers</code> <strong class="purple">must</strong> be +<a href="#renderpass-compatibility">compatible</a> with the current render pass.</p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is being called within a render pass +instance, and any given element of <code>pCommandBuffers</code> was recorded +with <code>VkCommandBufferInheritanceInfo</code>::<code>framebuffer</code> not equal +to <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, that <code>VkFramebuffer</code> <strong class="purple">must</strong> match the +<code>VkFramebuffer</code> used in the current render pass instance</p> +</li> +<li> +<p>If <code>vkCmdExecuteCommands</code> is not being called within a render pass +instance, any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not have been +recorded with the <code>VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</code></p> +</li> +<li> +<p>If the <a href="#features-features-inheritedQueries">inherited queries</a> feature +is not enabled, <code>commandBuffer</code> <strong class="purple">must</strong> not have any queries +<a href="#queries-operation-active">active</a></p> +</li> +<li> +<p>If <code>commandBuffer</code> has a <code>VK_QUERY_TYPE_OCCLUSION</code> query +<a href="#queries-operation-active">active</a>, then each element of +<code>pCommandBuffers</code> <strong class="purple">must</strong> have been recorded with +<code>VkCommandBufferInheritanceInfo</code>::<code>occlusionQueryEnable</code> set to +<code>VK_TRUE</code></p> +</li> +<li> +<p>If <code>commandBuffer</code> has a <code>VK_QUERY_TYPE_OCCLUSION</code> query +<a href="#queries-operation-active">active</a>, then each element of +<code>pCommandBuffers</code> <strong class="purple">must</strong> have been recorded with +<code>VkCommandBufferInheritanceInfo</code>::<code>queryFlags</code> having all bits +set that are set for the query</p> +</li> +<li> +<p>If <code>commandBuffer</code> has a <code>VK_QUERY_TYPE_PIPELINE_STATISTICS</code> +query <a href="#queries-operation-active">active</a>, then each element of +<code>pCommandBuffers</code> <strong class="purple">must</strong> have been recorded with +<code>VkCommandBufferInheritanceInfo</code>::<code>pipelineStatistics</code> having +all bits set that are set in the <code>VkQueryPool</code> the query uses</p> +</li> +<li> +<p>Any given element of <code>pCommandBuffers</code> <strong class="purple">must</strong> not begin any query +types that are <a href="#queries-operation-active">active</a> in +<code>commandBuffer</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +<li> +<p><code>pCommandBuffers</code> <strong class="purple">must</strong> be a pointer to an array of <code>commandBufferCount</code> valid <code>VkCommandBuffer</code> handles</p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be in the recording state</p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> support transfer, graphics, or compute operations</p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a primary <code>VkCommandBuffer</code></p> +</li> +<li> +<p><code>commandBufferCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +<li> +<p>Both of <code>commandBuffer</code>, and the elements of <code>pCommandBuffers</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandBuffer</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to the <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Command Properties</div> +<table class="tableblock frame-all grid-all spread"> +<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"><a href="#VkCommandBufferLevel">Command Buffer Levels</a></th> +<th class="tableblock halign-left valign-top"><a href="#vkCmdBeginRenderPass">Render Pass Scope</a></th> +<th class="tableblock halign-left valign-top"><a href="#VkQueueFlagBits">Supported Queue Types</a></th> +<th class="tableblock halign-left valign-top"><a href="#synchronization-pipeline-stages-types">Pipeline Type</a></th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">Primary</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Both</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Transfer<br> +graphics<br> +compute</p></td> +<td class="tableblock halign-left valign-top"></td> +</tr> +</tbody> +</table> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="commandbuffers-devicemask">5.7. Command Buffer Device Mask</h3> +<div class="paragraph"> +<p>Each command buffer has a piece of state storing the current device mask of +the command buffer. +This mask controls which physical devices within the logical device all +subsequent commands will execute on, including state-setting commands, +action commands, and synchronization commands.</p> +</div> +<div class="paragraph"> +<p>Scissor and viewport state <strong class="purple">can</strong> be set to different values on each physical +device (only when set as dynamic state), and each physical device will +render using its local copy of the state. +Other state is shared between physical devices, such that all physical +devices use the most recently set values for the state. +However, when recording an action command that uses a piece of state, the +most recent command that set that state <strong class="purple">must</strong> have included all physical +devices that execute the action command in its current device mask.</p> +</div> +<div class="paragraph"> +<p>The command buffer’s device mask is orthogonal to the +<code>pCommandBufferDeviceMasks</code> member of <a href="#VkDeviceGroupSubmitInfoKHX">VkDeviceGroupSubmitInfoKHX</a>. +Commands only execute on a physical device if the device index is set in +both device masks.</p> +</div> +<div class="paragraph"> +<p>If the <code>pNext</code> list of <a href="#VkCommandBufferBeginInfo">VkCommandBufferBeginInfo</a> includes a +<code>VkDeviceGroupCommandBufferBeginInfoKHX</code> structure, then that structure +includes an initial device mask for the command buffer.</p> +</div> +<div class="paragraph"> +<p>The <code>VkDeviceGroupCommandBufferBeginInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkDeviceGroupCommandBufferBeginInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceGroupCommandBufferBeginInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + uint32_t deviceMask; +} VkDeviceGroupCommandBufferBeginInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>deviceMask</code> is the initial value of the command buffer’s device +mask.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The initial device mask also acts as an upper bound on the set of devices +that <strong class="purple">can</strong> ever be in the device mask in the command buffer.</p> +</div> +<div class="paragraph"> +<p>If this structure is not present, the initial value of a command buffer’s +device mask is set to include all physical devices in the logical device +when the command buffer begins recording.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>deviceMask</code> <strong class="purple">must</strong> be a valid device mask value</p> +</li> +<li> +<p><code>deviceMask</code> <strong class="purple">must</strong> not be zero</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To update the current device mask of a command buffer, call:</p> +</div> +<div id="vkCmdSetDeviceMaskKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkCmdSetDeviceMaskKHX( + VkCommandBuffer commandBuffer, + uint32_t deviceMask);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is command buffer whose current device mask is +modified.</p> +</li> +<li> +<p><code>deviceMask</code> is the new value of the current device mask.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p><code>deviceMask</code> is used to filter out subsequent commands from executing on +all physical devices whose bit indices are not set in the mask.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>deviceMask</code> <strong class="purple">must</strong> be a valid device mask value</p> +</li> +<li> +<p><code>deviceMask</code> <strong class="purple">must</strong> not be zero</p> +</li> +<li> +<p><code>deviceMask</code> <strong class="purple">must</strong> not include any set bits that were not in the +<a href="#VkDeviceGroupCommandBufferBeginInfoKHX">VkDeviceGroupCommandBufferBeginInfoKHX</a>::<code>deviceMask</code> value +when the command buffer began recording.</p> +</li> +<li> +<p>If <code>vkCmdSetDeviceMaskKHX</code> is called inside a render pass instance, +<code>deviceMask</code> <strong class="purple">must</strong> not include any set bits that were not in the +<a href="#VkDeviceGroupRenderPassBeginInfoKHX">VkDeviceGroupRenderPassBeginInfoKHX</a>::<code>deviceMask</code> value when +the render pass instance began recording.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be in the recording state</p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> support graphics, compute, or transfer operations</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>commandBuffer</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +<li> +<p>Host access to the <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Command Properties</div> +<table class="tableblock frame-all grid-all spread"> +<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"><a href="#VkCommandBufferLevel">Command Buffer Levels</a></th> +<th class="tableblock halign-left valign-top"><a href="#vkCmdBeginRenderPass">Render Pass Scope</a></th> +<th class="tableblock halign-left valign-top"><a href="#VkQueueFlagBits">Supported Queue Types</a></th> +<th class="tableblock halign-left valign-top"><a href="#synchronization-pipeline-stages-types">Pipeline Type</a></th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">Primary<br> +Secondary</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Both</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Graphics<br> +compute<br> +transfer</p></td> +<td class="tableblock halign-left valign-top"></td> +</tr> +</tbody> +</table> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="synchronization">6. Synchronization and Cache Control</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Synchronization of access to resources is primarily the responsibility of +the application in Vulkan. +The order of execution of commands with respect to the host and other +commands on the device has few implicit guarantees, and needs to be +explicitly specified. +Memory caches and other optimizations are also explicitly managed, requiring +that the flow of data through the system is largely under application +control.</p> +</div> +<div class="paragraph"> +<p>Whilst some implicit guarantees exist between commands, four explicit +synchronization primitives are exposed by Vulkan:</p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#synchronization-fences">Fences</a></dt> +<dd> +<p>Fences <strong class="purple">can</strong> be used to communicate to the host that execution of some +task on the device has completed.</p> +</dd> +<dt class="hdlist1"><a href="#synchronization-semaphores">Semaphores</a></dt> +<dd> +<p>Semaphores <strong class="purple">can</strong> be used to control resource access across multiple +queues.</p> +</dd> +<dt class="hdlist1"><a href="#synchronization-events">Events</a></dt> +<dd> +<p>Events provide a fine-grained synchronization primitive which <strong class="purple">can</strong> be +signaled either within a command buffer or by the host, and <strong class="purple">can</strong> be +waited upon within a command buffer or queried on the host.</p> +</dd> +<dt class="hdlist1"><a href="#synchronization-pipeline-barriers">Pipeline Barriers</a></dt> +<dd> +<p>Pipeline barriers also provide synchronization control within a command +buffer, but at a single point, rather than with separate signal and wait +operations.</p> +</dd> +</dl> +</div> +<div class="paragraph"> +<p>In addition to the base primitives provided here, <a href="#renderpass">Render +Passes</a> provide a useful synchronization framework for most rendering +tasks, built upon the concepts in this chapter. +Many cases that would otherwise need an application to use synchronization +primitives in this chapter <strong class="purple">can</strong> be expressed more efficiently as part of a +render pass.</p> +</div> +<div class="sect2"> +<h3 id="synchronization-dependencies">6.1. Execution and Memory Dependencies</h3> +<div class="paragraph"> +<p>An <em>operation</em> is an arbitrary amount of work to be executed on the host, a +device, or an external entity such as a presentation engine. +Synchronization commands introduce explicit <em>execution dependencies</em>, and +<em>memory dependencies</em> between two sets of operations defined by the +command’s two <em>synchronization scopes</em>.</p> +</div> +<div id="synchronization-dependencies-scopes" class="paragraph"> +<p>The synchronization scopes define which other operations a synchronization +command is able to create execution dependencies with. +Any type of operation that is not in a synchronization command’s +synchronization scopes will not be included in the resulting dependency. +For example, for many synchronization commands, the synchronization scopes +<strong class="purple">can</strong> be limited to just operations executing in specific +<a href="#synchronization-pipeline-stages">pipeline stages</a>, which allows other +pipeline stages to be excluded from a dependency. +Other scoping options are possible, depending on the particular command.</p> +</div> +<div id="synchronization-dependencies-execution" class="paragraph"> +<p>An <em>execution dependency</em> is a guarantee that for two sets of operations, +the first set <strong class="purple">must</strong> <em>happen-before</em> the second set. +If an operation happens-before another operation, then the first operation +<strong class="purple">must</strong> complete before the second operation is initiated. +More precisely:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Let <strong>A</strong> and <strong>B</strong> be separate sets of operations.</p> +</li> +<li> +<p>Let <strong>S</strong> be a synchronization command.</p> +</li> +<li> +<p>Let <strong>A<sub>S</sub></strong> and <strong>B<sub>S</sub></strong> be the synchronization scopes of <strong>S</strong>.</p> +</li> +<li> +<p>Let <strong>A'</strong> be the intersection of sets <strong>A</strong> and <strong>A<sub>S</sub></strong>.</p> +</li> +<li> +<p>Let <strong>B'</strong> be the intersection of sets <strong>B</strong> and <strong>B<sub>S</sub></strong>.</p> +</li> +<li> +<p>Submitting <strong>A</strong>, <strong>S</strong> and <strong>B</strong> for execution, in that order, will result in +execution dependency <strong>E</strong> between <strong>A'</strong> and <strong>B'</strong>.</p> +</li> +<li> +<p>Execution dependency <strong>E</strong> guarantees that <strong>A'</strong> happens-before <strong>B'</strong>.</p> +</li> +</ul> +</div> +<div id="synchronization-dependencies-chains" class="paragraph"> +<p>An <em>execution dependency chain</em> is a sequence of execution dependencies that +form a happens-before relation between the first dependency’s <strong>A'</strong> and the +final dependency’s <strong>B'</strong>. +For each consecutive pair of execution dependencies, a chain exists if the +intersection of <strong>B<sub>S</sub></strong> in the first dependency and <strong>A<sub>S</sub></strong> in the second +dependency is not an empty set. +The formation of a single execution dependency from an execution dependency +chain can be described by substituting the following in the description of +execution dependencies:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Let <strong>S</strong> be a set of synchronization commands that generate an execution +dependency chain.</p> +</li> +<li> +<p>Let <strong>A<sub>S</sub></strong> be the first synchronization scope of the first command in +<strong>S</strong>.</p> +</li> +<li> +<p>Let <strong>B<sub>S</sub></strong> be the second synchronization scope of the last command in +<strong>S</strong>.</p> +</li> +</ul> +</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>An execution dependency is inherently also multiple execution dependencies - +a dependency exists between each subset of <strong>A'</strong> and each subset of <strong>B'</strong>, and +the same is true for execution dependency chains. +For example, a synchronization command with multiple +<a href="#synchronization-pipeline-stages">pipeline stages</a> in its stage masks +effectively generates one dependency between each source stage and each +destination stage. +This can be useful to think about when considering how execution chains are +formed if they do not involve all parts of a synchronization command’s +dependency. +Similarly, any set of adjacent dependencies in an execution dependency chain +<strong class="purple">can</strong> be considered an execution dependency chain in its own right.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Execution dependencies alone are not sufficient to guarantee that values +resulting from writes in one set of operations <strong class="purple">can</strong> be read from another set +of operations.</p> +</div> +<div id="synchronization-dependencies-available-and-visible" class="paragraph"> +<p>Two additional types of operation are used to control memory access. +<em>Availability operations</em> cause the values generated by specified memory +write accesses to become <em>available</em> for future access. +Any available value remains available until a subsequent write to the same +memory location occurs (whether it is made available or not) or the memory +is freed. +<em>Visibility operations</em> cause any available values to become <em>visible</em> to +specified memory accesses.</p> +</div> +<div id="synchronization-dependencies-memory" class="paragraph"> +<p>A <em>memory dependency</em> is an execution dependency which includes availability +and visibility operations such that:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>The first set of operations happens-before the availability operation.</p> +</li> +<li> +<p>The availability operation happens-before the visibility operation.</p> +</li> +<li> +<p>The visibility operation happens-before the second set of operations.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Once written values are made visible to a particular type of memory access, +they <strong class="purple">can</strong> be read or written by that type of memory access. +Most synchronization commands in Vulkan define a memory dependency.</p> +</div> +<div id="synchronization-dependencies-access-scopes" class="paragraph"> +<p>The specific memory accesses that are made available and visible are defined +by the <em>access scopes</em> of a memory dependency. +Any type of access that is in a memory dependency’s first access scope and +occurs in <strong>A'</strong> is made available. +Any type of access that is in a memory dependency’s second access scope and +occurs in <strong>B'</strong> has any available writes made visible to it. +Any type of operation that is not in a synchronization command’s access +scopes will not be included in the resulting dependency.</p> +</div> +<div class="paragraph"> +<p>A memory dependency enforces availability and visibility of memory accesses +and execution order between two sets of operations. +Adding to the description of <a href="#synchronization-dependencies-chains">execution dependency chains</a>:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Let <strong>a</strong> be the set of memory accesses performed by <strong>A'</strong>.</p> +</li> +<li> +<p>Let <strong>b</strong> be the set of memory accesses performed by <strong>B'</strong>.</p> +</li> +<li> +<p>Let <strong>a<sub>S</sub></strong> be the first access scope of the first command in <strong>S</strong>.</p> +</li> +<li> +<p>Let <strong>b<sub>S</sub></strong> be the second access scope of the last command in <strong>S</strong>.</p> +</li> +<li> +<p>Let <strong>a'</strong> be the intersection of sets <strong>a</strong> and <strong>a<sub>S</sub></strong>.</p> +</li> +<li> +<p>Let <strong>b'</strong> be the intersection of sets <strong>b</strong> and <strong>b<sub>S</sub></strong>.</p> +</li> +<li> +<p>Submitting <strong>A</strong>, <strong>S</strong> and <strong>B</strong> for execution, in that order, will result in +a memory dependency <strong>m</strong> between <strong>A'</strong> and <strong>B'</strong>.</p> +</li> +<li> +<p>Memory dependency <strong>m</strong> guarantees that:</p> +<div class="ulist"> +<ul> +<li> +<p>Memory writes in <strong>a'</strong> are made available.</p> +</li> +<li> +<p>Available memory writes, including those from <strong>a'</strong>, are made visible to +<strong>b'</strong>.</p> +</li> +</ul> +</div> +</li> +</ul> +</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>Execution and memory dependencies are used to solve data hazards, i.e. to +ensure that read and write operations occur in a well-defined order. +Write-after-read hazards can be solved with just an execution dependency, +but read-after-write and write-after-write hazards need appropriate memory +dependencies to be included between them. +If an application does not include dependencies to solve these hazards, the +results and execution orders of memory accesses are undefined.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="sect3"> +<h4 id="synchronization-image-layout-transitions">6.1.1. Image Layout Transitions</h4> +<div class="paragraph"> +<p>Image subresources <strong class="purple">can</strong> be transitioned from one <a href="#resources-image-layouts">layout</a> to another as part of a <a href="#synchronization-dependencies-memory">memory dependency</a> (e.g. by using an +<a href="#synchronization-image-memory-barriers">image memory barrier</a>). +When a layout transition is specified in a memory dependency, it +happens-after the availability operations in the memory dependency, and +happens-before the visibility operations. +Image layout transitions <strong class="purple">may</strong> perform read and write accesses on all memory +bound to the image subresource range, so applications <strong class="purple">must</strong> ensure that all +memory writes have been made +<a href="#synchronization-dependencies-available-and-visible">available</a> before a +layout transition is executed. +Available memory is automatically made visible to a layout transition, and +writes performed by a layout transition are automatically made available.</p> +</div> +<div class="paragraph"> +<p>Layout transitions always apply to a particular image subresource range, and +specify both an old layout and new layout. +If the old layout does not match the new layout, a transition occurs. +The old layout <strong class="purple">must</strong> match the current layout of the image subresource +range, with one exception. +The old layout <strong class="purple">can</strong> always be specified as <code>VK_IMAGE_LAYOUT_UNDEFINED</code>, +though doing so invalidates the contents of the image subresource range.</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>Setting the old layout to <code>VK_IMAGE_LAYOUT_UNDEFINED</code> implies that the +contents of the image subresource need not be preserved. +Implementations <strong class="purple">may</strong> use this information to avoid performing expensive data +transition operations.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>Applications <strong class="purple">must</strong> ensure that layout transitions happen-after all +operations accessing the image with the old layout, and happen-before any +operations that will access the image with the new layout. +Layout transitions are potentially read/write operations, so not defining +appropriate memory dependencies to guarantee this will result in a data +race.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>The contents of any portion of another resource which aliases memory that is +bound to the transitioned image subresource range are undefined after an +image layout transition.</p> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-pipeline-stages">6.1.2. Pipeline Stages</h4> +<div class="paragraph"> +<p>The work performed by an <a href="#fundamentals-queueoperation-command-types">action +command</a> consists of multiple operations, which are performed by a sequence +of logically independent execution units known as <em>pipeline stages</em>. +The exact pipeline stages executed depend on the particular action command +that is used, and current command buffer state when the action command was +recorded. +<a href="#drawing">Drawing commands</a>, <a href="#dispatch">dispatching commands</a>, +<a href="#copies">copy commands</a>, and <a href="#clears">clear commands</a> all execute in +different sets of <a href="#synchronization-pipeline-stages-types">pipeline stages</a>.</p> +</div> +<div class="paragraph"> +<p>Execution of operations across pipeline stages <strong class="purple">must</strong> adhere to +<a href="#synchronization-implicit">implicit ordering guarantees</a>, particularly +including <a href="#synchronization-pipeline-stages-order">pipeline stage order</a>. +Otherwise, execution across pipeline stages <strong class="purple">may</strong> overlap or execute out of +order with regards to other stages, unless otherwise enforced by an +execution dependency.</p> +</div> +<div class="paragraph"> +<p>Several of the synchronization commands include pipeline stage parameters, +restricting the <a href="#synchronization-dependencies-scopes">synchronization +scopes</a> for that command to just those stages. +This allows fine grained control over the exact execution dependencies and +accesses performed by action commands. +Implementations <strong class="purple">should</strong> use these pipeline stages to avoid unnecessary +stalls or cache flushing.</p> +</div> +<div class="paragraph"> +<p>Pipeline stages are specified using a bitmask:</p> +</div> +<div id="VkPipelineStageFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkPipelineStageFlagBits { + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = <span class="hex">0x00000001</span>, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = <span class="hex">0x00000002</span>, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = <span class="hex">0x00000004</span>, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = <span class="hex">0x00000008</span>, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = <span class="hex">0x00000010</span>, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = <span class="hex">0x00000020</span>, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = <span class="hex">0x00000040</span>, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = <span class="hex">0x00000080</span>, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = <span class="hex">0x00000100</span>, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = <span class="hex">0x00000200</span>, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = <span class="hex">0x00000400</span>, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = <span class="hex">0x00000800</span>, + VK_PIPELINE_STAGE_TRANSFER_BIT = <span class="hex">0x00001000</span>, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = <span class="hex">0x00002000</span>, + VK_PIPELINE_STAGE_HOST_BIT = <span class="hex">0x00004000</span>, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = <span class="hex">0x00008000</span>, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = <span class="hex">0x00010000</span>, + VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = <span class="hex">0x00020000</span>, +} VkPipelineStageFlagBits;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The meaning of each bit is:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code>: Stage of the pipeline where any +commands are initially received by the queue.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX</code>: Stage of the pipeline +where device-side generation of commands via +<a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a> is handled.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code>: Stage of the pipeline where +Draw/DispatchIndirect data structures are consumed. +This stage also includes reading commands written by +<a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a>.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code>: Stage of the pipeline where +vertex and index buffers are consumed.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code>: Vertex shader stage.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code>: Tessellation +control shader stage.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code>: Tessellation +evaluation shader stage.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code>: Geometry shader stage.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code>: Fragment shader stage.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code>: Stage of the pipeline +where early fragment tests (depth and stencil tests before fragment +shading) are performed. +This stage also includes <a href="#renderpass-load-store-ops">subpass load +operations</a> for framebuffer attachments with a depth/stencil format.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code>: Stage of the pipeline +where late fragment tests (depth and stencil tests after fragment +shading) are performed. +This stage also includes <a href="#renderpass-load-store-ops">subpass store +operations</a> for framebuffer attachments with a depth/stencil format.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code>: Stage of the +pipeline after blending where the final color values are output from the +pipeline. +This stage also includes <a href="#renderpass-load-store-ops">subpass load and +store operations</a> and multisample resolve operations for framebuffer +attachments with a color format.</p> +</li> +<li> +<p><a id="synchronization-pipeline-stages-transfer"></a> +<code>VK_PIPELINE_STAGE_TRANSFER_BIT</code>: Execution of copy commands. +This includes the operations resulting from all <a href="#copies">copy +commands</a>, <a href="#clears">clear commands</a> (with the exception of +<a href="#vkCmdClearAttachments">vkCmdClearAttachments</a>), and <a href="#vkCmdCopyQueryPoolResults">vkCmdCopyQueryPoolResults</a>.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code>: Execution of a compute +shader.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code>: Final stage in the pipeline +where operations generated by all commands complete execution.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_HOST_BIT</code>: A pseudo-stage indicating execution on +the host of reads/writes of device memory. +This stage is not invoked by any commands recorded in a command buffer.</p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT</code>: Execution of all graphics +pipeline stages. +Equivalent to the logical or of:</p> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p> +</li> +</ul> +</div> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_ALL_COMMANDS_BIT</code>: Equivalent to the logical or +of every other pipeline stage flag that is supported on the queue it is +used with.</p> +</li> +</ul> +</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>An execution dependency with only <code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code> +in the destination stage mask will only prevent that stage from executing in +subsequently submitted commands. +As this stage does not perform any actual execution, this is not observable +- in effect, it does not delay processing of subsequent commands. +Similarly an execution dependency with only +<code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code> in the source stage mask will +effectively not wait for any prior commands to complete.</p> +</div> +<div class="paragraph"> +<p>When defining a memory dependency, using only +<code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code> or +<code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code> would never make any accesses +available and/or visible because these stages do not access memory.</p> +</div> +<div class="paragraph"> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code> and +<code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code> are useful for accomplishing layout +transitions and queue ownership operations when the required execution +dependency is satisfied by other means - for example, semaphore operations +between queues.</p> +</div> +</td> +</tr> +</table> +</div> +<div id="synchronization-pipeline-stages-masks" class="paragraph"> +<p>If a synchronization command includes a source stage mask, its first +<a href="#synchronization-dependencies-scopes">synchronization scope</a> only includes +execution of the pipeline stages specified in that mask, as well as any +<a href="#synchronization-pipeline-stages-order">logically earlier</a> stages. +If a synchronization command includes a destination stage mask, its second +<a href="#synchronization-dependencies-scopes">synchronization scope</a> only includes +execution of the pipeline stages specified in that mask, as well as any +<a href="#synchronization-pipeline-stages-order">logically later</a> stages.</p> +</div> +<div class="paragraph"> +<p><a href="#synchronization-dependencies-access-scopes">Access scopes</a> are affected +in a similar way. +If a synchronization command includes a source stage mask, its first +<a href="#synchronization-dependencies-access-scopes">access scope</a> only includes +memory access performed by pipeline stages specified in that mask. +If a synchronization command includes a destination stage mask, its second +<a href="#synchronization-dependencies-access-scopes">access scope</a> only includes +memory access performed by pipeline stages specified in that mask.</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>Implementations <strong class="purple">may</strong> not support synchronization at every pipeline stage for +every synchronization operation. +If a pipeline stage that an implementation does not support synchronization +for appears in a source stage mask, then it <strong class="purple">may</strong> substitute that stage for +any logically later stage. +If a pipeline stage that an implementation does not support synchronization +for appears in a destination stage mask, then it <strong class="purple">may</strong> substitute that stage +for any logically earlier stage.</p> +</div> +<div class="paragraph"> +<p>For example, if an implementation is unable to signal an event immediately +after vertex shader execution is complete, it <strong class="purple">may</strong> instead signal the event +after color attachment output has completed.</p> +</div> +<div class="paragraph"> +<p>If an implementation makes such a substitution, it <strong class="purple">must</strong> not affect the +semantics of execution or memory dependencies or image and buffer memory +barriers.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Certain pipeline stages are only available on queues that support a +particular set of operations. +The following table lists, for each pipeline stage flag, which queue +capability flag <strong class="purple">must</strong> be supported by the queue. +When multiple flags are enumerated in the second column of the table, it +means that the pipeline stage is supported on the queue if it supports any +of the listed capability flags. +For further details on queue capabilities see +<a href="#devsandqueues-physical-device-enumeration">Physical Device Enumeration</a> +and <a href="#devsandqueues-queues">Queues</a>.</p> +</div> +<table id="synchronization-pipeline-stages-supported" class="tableblock frame-all grid-all spread"> +<caption class="title">Table 3. Supported pipeline stage flags</caption> +<colgroup> +<col style="width: 60%;"> +<col style="width: 40%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Pipeline stage flag</th> +<th class="tableblock halign-left valign-top">Required queue capability flag</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">None required</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code> or <code>VK_QUEUE_COMPUTE_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_COMPUTE_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TRANSFER_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code>, <code>VK_QUEUE_COMPUTE_BIT</code> or <code>VK_QUEUE_TRANSFER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">None required</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_HOST_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">None required</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_ALL_COMMANDS_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">None required</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_QUEUE_GRAPHICS_BIT</code> or <code>VK_QUEUE_COMPUTE_BIT</code></p></td> +</tr> +</tbody> +</table> +<div id="synchronization-pipeline-stages-order" class="paragraph"> +<p>Pipeline stages that execute as a result of a command logically complete +execution in a specific order, such that completion of a logically later +pipeline stage <strong class="purple">must</strong> not happen-before completion of a logically earlier +stage. +This means that including any given stage in the source stage mask for a +particular synchronization command also implies that any logically earlier +stages are included in <strong>A<sub>S</sub></strong> for that command.</p> +</div> +<div class="paragraph"> +<p>Similarly, initiation of a logically earlier pipeline stage <strong class="purple">must</strong> not +happen-after initiation of a logically later pipeline stage. +Including any given stage in the destination stage mask for a particular +synchronization command also implies that any logically later stages are +included in <strong>B<sub>S</sub></strong> for that command.</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>Logically earlier/later stages are not included when defining the +<a href="#synchronization-dependencies-access-scopes">access scopes</a> of a +<a href="#synchronization-memory-barriers">memory barrier</a>.</p> +</div> +</td> +</tr> +</table> +</div> +<div id="synchronization-pipeline-stages-types" class="paragraph"> +<p>The order of pipeline stages depends on the particular pipeline; graphics, +compute, transfer or host.</p> +</div> +<div class="paragraph"> +<p>For the graphics pipeline, the following stages occur in this order:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>For the compute pipeline, the following stages occur in this order:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>For the transfer pipeline, the following stages occur in this order:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_TRANSFER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>For host operations, only one pipeline stage occurs, so no order is +guaranteed:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_HOST_BIT</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>For the command processing pipeline, the following stages occur in this +order:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT</code></p> +</li> +</ul> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-access-types">6.1.3. Access Types</h4> +<div class="paragraph"> +<p>Memory in Vulkan <strong class="purple">can</strong> be accessed from within shader invocations and via +some fixed-function stages of the pipeline. +The <em>access type</em> is a function of the <a href="#descriptorsets">descriptor type</a> +used, or how a fixed-function stage accesses memory. +Each access type corresponds to a bit flag in <a href="#VkAccessFlagBits">VkAccessFlagBits</a>.</p> +</div> +<div id="synchronization-access-masks" class="paragraph"> +<p>Some synchronization commands take sets of access types as parameters to +define the <a href="#synchronization-dependencies-access-scopes">access scopes</a> of +a memory dependency. +If a synchronization command includes a source access mask, its first +<a href="#synchronization-dependencies-access-scopes">access scope</a> only includes +accesses via the access types specified in that mask. +Similarly, if a synchronization command includes a destination access mask, +its second <a href="#synchronization-dependencies-access-scopes">access scope</a> only +includes accesses via the access types specified in that mask.</p> +</div> +<div class="paragraph"> +<p>Access types that can be set in an access mask include:</p> +</div> +<div id="VkAccessFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = <span class="hex">0x00000001</span>, + VK_ACCESS_INDEX_READ_BIT = <span class="hex">0x00000002</span>, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = <span class="hex">0x00000004</span>, + VK_ACCESS_UNIFORM_READ_BIT = <span class="hex">0x00000008</span>, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = <span class="hex">0x00000010</span>, + VK_ACCESS_SHADER_READ_BIT = <span class="hex">0x00000020</span>, + VK_ACCESS_SHADER_WRITE_BIT = <span class="hex">0x00000040</span>, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = <span class="hex">0x00000080</span>, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = <span class="hex">0x00000100</span>, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = <span class="hex">0x00000200</span>, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = <span class="hex">0x00000400</span>, + VK_ACCESS_TRANSFER_READ_BIT = <span class="hex">0x00000800</span>, + VK_ACCESS_TRANSFER_WRITE_BIT = <span class="hex">0x00001000</span>, + VK_ACCESS_HOST_READ_BIT = <span class="hex">0x00002000</span>, + VK_ACCESS_HOST_WRITE_BIT = <span class="hex">0x00004000</span>, + VK_ACCESS_MEMORY_READ_BIT = <span class="hex">0x00008000</span>, + VK_ACCESS_MEMORY_WRITE_BIT = <span class="hex">0x00010000</span>, + VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = <span class="hex">0x00020000</span>, + VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = <span class="hex">0x00040000</span>, +} VkAccessFlagBits;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ACCESS_INDIRECT_COMMAND_READ_BIT</code>: Read access to an indirect +command structure read as part of an indirect drawing or dispatch +command.</p> +</li> +<li> +<p><code>VK_ACCESS_INDEX_READ_BIT</code>: Read access to an index buffer as part +of an indexed drawing command, bound by <a href="#vkCmdBindIndexBuffer">vkCmdBindIndexBuffer</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT</code>: Read access to a vertex +buffer as part of a drawing command, bound by +<a href="#vkCmdBindVertexBuffers">vkCmdBindVertexBuffers</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_UNIFORM_READ_BIT</code>: Read access to a +<a href="#descriptorsets-uniformbuffer">uniform buffer</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_INPUT_ATTACHMENT_READ_BIT</code>: Read access to an +<a href="#renderpass">input attachment</a> within a renderpass during fragment +shading.</p> +</li> +<li> +<p><code>VK_ACCESS_SHADER_READ_BIT</code>: Read access to a +<a href="#descriptorsets-storagebuffer">storage buffer</a>, +<a href="#descriptorsets-uniformtexelbuffer">uniform texel buffer</a>, +<a href="#descriptorsets-storagetexelbuffer">storage texel buffer</a>, +<a href="#descriptorsets-sampledimage">sampled image</a>, or +<a href="#descriptorsets-storageimage">storage image</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_SHADER_WRITE_BIT</code>: Write access to a +<a href="#descriptorsets-storagebuffer">storage buffer</a>, +<a href="#descriptorsets-storagetexelbuffer">storage texel buffer</a>, or +<a href="#descriptorsets-storageimage">storage image</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_COLOR_ATTACHMENT_READ_BIT</code>: Read access to a +<a href="#renderpass">color attachment</a>, such as via <a href="#framebuffer-blending">blending</a>, <a href="#framebuffer-logicop">logic operations</a>, or via certain +<a href="#renderpass-load-store-ops">subpass load operations</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT</code>: Write access to a +<a href="#renderpass">color or resolve attachment</a> during a <a href="#renderpass">render pass</a> or via certain <a href="#renderpass-load-store-ops">subpass load +and store operations</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT</code>: Read access to a +<a href="#renderpass">depth/stencil attachment</a>, via <a href="#fragops-ds-state">depth +or stencil operations</a> or via certain <a href="#renderpass-load-store-ops">subpass load operations</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT</code>: Write access to a +<a href="#renderpass">depth/stencil attachment</a>, via <a href="#fragops-ds-state">depth +or stencil operations</a> or via certain <a href="#renderpass-load-store-ops">subpass load and store operations</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_TRANSFER_READ_BIT</code>: Read access to an image or buffer in +a <a href="#copies">copy</a> operation.</p> +</li> +<li> +<p><code>VK_ACCESS_TRANSFER_WRITE_BIT</code>: Write access to an image or buffer +in a <a href="#clears">clear</a> or <a href="#copies">copy</a> operation.</p> +</li> +<li> +<p><code>VK_ACCESS_HOST_READ_BIT</code>: Read access by a host operation. +Accesses of this type are not performed through a resource, but directly +on memory.</p> +</li> +<li> +<p><code>VK_ACCESS_HOST_WRITE_BIT</code>: Write access by a host operation. +Accesses of this type are not performed through a resource, but directly +on memory.</p> +</li> +<li> +<p><code>VK_ACCESS_MEMORY_READ_BIT</code>: Read access via non-specific entities. +These entities include the Vulkan device and host, but <strong class="purple">may</strong> also include +entities external to the Vulkan device or otherwise not part of the core +Vulkan pipeline. +When included in a destination access mask, makes all available writes +visible to all future read accesses on entities known to the Vulkan +device.</p> +</li> +<li> +<p><code>VK_ACCESS_MEMORY_WRITE_BIT</code>: Write access via non-specific +entities. +These entities include the Vulkan device and host, but <strong class="purple">may</strong> also include +entities external to the Vulkan device or otherwise not part of the core +Vulkan pipeline. +When included in a source access mask, all writes that are performed by +entities known to the Vulkan device are made available. +When included in a destination access mask, makes all available writes +visible to all future write accesses on entities known to the Vulkan +device.</p> +</li> +<li> +<p><code>VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX</code>: Reads from <code>VkBuffer</code> +inputs to <a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a>.</p> +</li> +<li> +<p><code>VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX</code>: Writes to the target +command buffer in <a href="#vkCmdProcessCommandsNVX">vkCmdProcessCommandsNVX</a>.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Certain access types are only performed by a subset of pipeline stages. +Any synchronization command that takes both stage masks and access masks +uses both to define the <a href="#synchronization-dependencies-access-scopes">access +scopes</a> - only the specified access types performed by the specified stages +are included in the access scope. +An application <strong class="purple">must</strong> not specify an access flag in a synchronization command +if it does not include a pipeline stage in the corresponding stage mask that +is able to perform accesses of that type. +The following table lists, for each access flag, which pipeline stages <strong class="purple">can</strong> +perform that type of access.</p> +</div> +<table id="synchronization-access-types-supported" class="tableblock frame-all grid-all spread"> +<caption class="title">Table 4. Supported access types</caption> +<colgroup> +<col style="width: 50%;"> +<col style="width: 50%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Access flag</th> +<th class="tableblock halign-left valign-top">Supported pipeline stages</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_INDIRECT_COMMAND_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_INDEX_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_INPUT_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_UNIFORM_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code>, or <code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_INPUT_ATTACHMENT_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_SHADER_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code>, or <code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_SHADER_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_VERTEX_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code>, <code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code>, or <code>VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_COLOR_ATTACHMENT_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code>, or <code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code>, or <code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_TRANSFER_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TRANSFER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_TRANSFER_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_TRANSFER_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_HOST_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_HOST_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_HOST_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_HOST_BIT</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_MEMORY_READ_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_MEMORY_WRITE_BIT</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX</code></p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX</code></p></td> +</tr> +</tbody> +</table> +<div id="synchronization-host-access-types" class="paragraph"> +<p>If a memory object does not have the +<code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> property, then +<a href="#vkFlushMappedMemoryRanges">vkFlushMappedMemoryRanges</a> <strong class="purple">must</strong> be called in order to guarantee that +writes to the memory object from the host are made visible to the +<code>VK_ACCESS_HOST_WRITE_BIT</code> <a href="#synchronization-access-types">access +type</a>, where it <strong class="purple">can</strong> be further made available to the device by +<a href="#synchronization">synchronization commands</a>. +Similarly, <a href="#vkInvalidateMappedMemoryRanges">vkInvalidateMappedMemoryRanges</a> <strong class="purple">must</strong> be called to guarantee +that writes which are visible to the <code>VK_ACCESS_HOST_READ_BIT</code> +<a href="#synchronization-access-types">access type</a> are made visible to host +operations.</p> +</div> +<div class="paragraph"> +<p>If the memory object does have the +<code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> property flag, writes to the +memory object from the host are automatically made visible to the +<code>VK_ACCESS_HOST_WRITE_BIT</code> <a href="#synchronization-access-types">access type</a>. +Similarly, writes made visible to the <code>VK_ACCESS_HOST_READ_BIT</code> +<a href="#synchronization-access-types">access type</a> are automatically made visible +to the host.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>The <a href="#vkQueueSubmit">vkQueueSubmit</a> command <a href="#synchronization-submission-host-writes">automatically guarantees that host writes flushed to +<code>VK_ACCESS_HOST_WRITE_BIT</code> are made available</a> if they were flushed +before the command executed, so in most cases an explicit memory barrier is +not needed for this case. +In the few circumstances where a submit does not occur between the host +write and the device read access, writes <strong class="purple">can</strong> be made available by using an +explicit memory barrier.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-framebuffer-regions">6.1.4. Framebuffer Region Dependencies</h4> +<div class="paragraph"> +<p><a href="#synchronization-pipeline-stages">Pipeline stages</a> that operate on, or +with respect to, the framebuffer are collectively the <em>framebuffer-space</em> +pipeline stages. +These stages are:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT</code></p> +</li> +<li> +<p><code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>For these pipeline stages, an execution or memory dependency from the first +set of operations to the second set <strong class="purple">can</strong> either be a single +<em>framebuffer-global</em> dependency, or split into multiple <em>framebuffer-local</em> +dependencies. +A dependency with non-framebuffer-space pipeline stages is neither +framebuffer-global nor framebuffer-local.</p> +</div> +<div class="paragraph"> +<p>A <em>framebuffer region</em> is a set of sample (x, y, layer, sample) coordinates +that is a subset of the entire framebuffer.</p> +</div> +<div class="paragraph"> +<p>A single framebuffer-local dependency guarantees that only for a single +framebuffer region, the first set of operations and availability operations +happen-before visibility operations and the second set of operations. +No ordering guarantees are made between framebuffer regions for a +framebuffer-local dependency.</p> +</div> +<div class="paragraph"> +<p>A framebuffer-global dependency guarantees that the first set of operations +for all framebuffer regions happens-before the second set of operations for +any framebuffer region.</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>Since fragment invocations are not specified to run in any particular +groupings, the size of a framebuffer region is implementation-dependent, not +known to the application, and <strong class="purple">must</strong> be assumed to be no larger than a single +sample.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>If a synchronization command includes a <code>dependencyFlags</code> parameter, and +specifies the <code>VK_DEPENDENCY_BY_REGION_BIT</code> flag, then it defines +framebuffer-local dependencies for the framebuffer-space pipeline stages in +that synchronization command, for all framebuffer regions. +If no <code>dependencyFlags</code> parameter is included, or the +<code>VK_DEPENDENCY_BY_REGION_BIT</code> flag is not specified, then a +framebuffer-global dependency is specified for those stages. +The <code>VK_DEPENDENCY_BY_REGION_BIT</code> flag does not affect the dependencies +between non-framebuffer-space pipeline stages, nor does it affect the +dependencies between framebuffer-space and non-framebuffer-space pipeline +stages.</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>Framebuffer-local dependencies are more optimal for most architectures; +particularly tile-based architectures - which can keep framebuffer-regions +entirely in on-chip registers and thus avoid external bandwidth across such +a dependency. +Including a framebuffer-global dependency in your rendering will usually +force all implementations to flush data to memory, or to a higher level +cache, breaking any potential locality optimizations.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-view-local-dependencies">6.1.5. View-Local Dependencies</h4> +<div class="paragraph"> +<p>In a render pass instance that has <a href="#renderpass-multiview">multiview</a> +enabled, dependencies can be either view-local or view-global.</p> +</div> +<div class="paragraph"> +<p>A view-local dependency only includes operations from a single +<a href="#renderpass-multiview-view-local">source view</a> from the source subpass in +the first synchronization scope, and only includes operations from a single +<a href="#renderpass-multiview-view-local">destination view</a> from the destination +subpass in the second synchronization scope. +A view-global dependency includes all views in the view mask of the source +and destination subpasses in the corresponding synchronization scopes.</p> +</div> +<div class="paragraph"> +<p>If a synchronization command includes a <code>dependencyFlags</code> parameter and +specifies the <code>VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX</code> flag, then it defines +view-local dependencies for that synchronization command, for all views. +If no <code>dependencyFlags</code> parameter is included or the +<code>VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX</code> flag is not specified, then a +view-global dependency is specified.</p> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-device-local-dependencies">6.1.6. Device-Local Dependencies</h4> +<div class="paragraph"> +<p>Dependencies <strong class="purple">can</strong> be either device-local or non-device-local. +A device-local dependency acts as multiple separate dependencies, one for +each physical device that executes the synchronization command, where each +dependency only includes operations from that physical device in both +synchronization scopes. +A non-device-local dependency is a single dependency where both +synchronization scopes include operations from all physical devices that +participate in the synchronization command. +For subpass dependencies, all physical devices in the +<a href="#VkDeviceGroupRenderPassBeginInfoKHX">VkDeviceGroupRenderPassBeginInfoKHX</a>::<code>deviceMask</code> participate in +the dependency, and for pipeline barriers all physical devices that are set +in the command buffer’s current device mask participate in the dependency.</p> +</div> +<div class="paragraph"> +<p>If a synchronization command includes a <code>dependencyFlags</code> parameter and +specifies the <code>VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX</code> flag, then it defines +a non-device-local dependency for that synchronization command. +If no <code>dependencyFlags</code> parameter is included or the +<code>VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX</code> flag is not specified, then it +defines device-local dependencies for that synchronization command, for all +participating physical devices.</p> +</div> +<div class="paragraph"> +<p>Semaphore and event dependencies are device-local and only execute on the +one physical device that performs the dependency.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="synchronization-implicit">6.2. Implicit Synchronization Guarantees</h3> +<div class="paragraph"> +<p>A small number of implicit ordering guarantees are provided by Vulkan, +ensuring that the order in which commands are submitted is meaningful, and +avoiding unnecessary complexity in common operations.</p> +</div> +<div id="synchronization-submission-order" class="paragraph"> +<p><em>Submission order</em> is a fundamental ordering in Vulkan, giving meaning to +the order in which <a href="#fundamentals-queueoperation-command-types">action and +synchronization commands</a> are recorded and submitted to a single queue. +Explicit and implicit ordering guarantees between commands in Vulkan all +work on the premise that this ordering is meaningful.</p> +</div> +<div class="paragraph"> +<p>Submission order for any given set of commands is based on the order in +which they were recorded to command buffers and then submitted. +This order is determined as follows:</p> +</div> +<div class="olist arabic"> +<ol class="arabic"> +<li> +<p>The initial order is determined by the order in which +<a href="#vkQueueSubmit">vkQueueSubmit</a> commands are executed on the host, for a single +queue, from first to last.</p> +</li> +<li> +<p>The order in which <a href="#VkSubmitInfo">VkSubmitInfo</a> structures are specified in the +<code>pSubmits</code> parameter of <a href="#vkQueueSubmit">vkQueueSubmit</a>, from lowest index to +highest.</p> +</li> +<li> +<p>The order in which command buffers are specified in the +<code>pCommandBuffers</code> member of <a href="#VkSubmitInfo">VkSubmitInfo</a>, from lowest index to +highest.</p> +</li> +<li> +<p>The order in which commands were recorded to a command buffer on the +host, from first to last:</p> +<div class="ulist"> +<ul> +<li> +<p>For commands recorded outside a render pass, this includes all other +commands recorded outside a renderpass, including +<a href="#vkCmdBeginRenderPass">vkCmdBeginRenderPass</a> and <a href="#vkCmdEndRenderPass">vkCmdEndRenderPass</a> commands; it +does not directly include commands inside a render pass.</p> +</li> +<li> +<p>For commands recorded inside a render pass, this includes all other +commands recorded inside the same subpass, including the +<a href="#vkCmdBeginRenderPass">vkCmdBeginRenderPass</a> and <a href="#vkCmdEndRenderPass">vkCmdEndRenderPass</a> commands that +delimit the same renderpass instance; it does not include commands +recorded to other subpasses.</p> +</li> +</ul> +</div> +</li> +</ol> +</div> +<div class="paragraph"> +<p><a href="#fundamentals-queueoperation-command-types">Action and synchronization +commands</a> recorded to a command buffer execute the +<code>VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT</code> pipeline stage in +<a href="#synchronization-submission-order">submission order</a> - forming an implicit +execution dependency between this stage in each command.</p> +</div> +<div class="paragraph"> +<p><a href="#fundamentals-queueoperation-command-types">State commands</a> do not execute +any operations on the device, instead they set the state of the command +buffer when they execute on the host, in the order that they are recorded. +<a href="#fundamentals-queueoperation-command-types">Action commands</a> consume the +current state of the command buffer when they are recorded, and will execute +state changes on the device as required to match the recorded state.</p> +</div> +<div class="paragraph"> +<p><a href="#queries-order">Query commands</a>, <a href="#drawing-primitive-order">the order of +primitives passing through the graphics pipeline</a> and +<a href="#synchronization-image-barrier-layout-transition-order">image layout +transitions as part of an image memory barrier</a> provide additional +guarantees based on submission order.</p> +</div> +<div class="paragraph"> +<p>Execution of <a href="#synchronization-pipeline-stages-order">pipeline stages</a> +within a given command also has a loose ordering, dependent only on a single +command.</p> +</div> +</div> +<div class="sect2"> +<h3 id="synchronization-fences">6.3. Fences</h3> +<div class="paragraph"> +<p>Fences are a synchronization primitive that <strong class="purple">can</strong> be used to insert a +dependency from a queue to the host. +Fences have two states - signaled and unsignaled. +A fence <strong class="purple">can</strong> be signaled as part of the execution of a +<a href="#devsandqueues-submission">queue submission</a> command. +Fences <strong class="purple">can</strong> be unsignaled on the host with <a href="#vkResetFences">vkResetFences</a>. +Fences <strong class="purple">can</strong> be waited on by the host with the <a href="#vkWaitForFences">vkWaitForFences</a> command, +and the current state <strong class="purple">can</strong> be queried with <a href="#vkGetFenceStatus">vkGetFenceStatus</a>.</p> +</div> +<div class="paragraph"> +<p>Fences are represented by <code>VkFence</code> handles:</p> +</div> +<div id="VkFence" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>To create a fence, call:</p> +</div> +<div id="vkCreateFence" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateFence( + VkDevice device, + <span class="directive">const</span> VkFenceCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkFence* pFence);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that creates the fence.</p> +</li> +<li> +<p><code>pCreateInfo</code> is a pointer to an instance of the +<code>VkFenceCreateInfo</code> structure which contains information about how +the fence is to be created.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pFence</code> points to a handle in which the resulting fence object is +returned.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkFenceCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pFence</code> <strong class="purple">must</strong> be a pointer to a <code>VkFence</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkFenceCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkFenceCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkFenceCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> defines the initial state and behavior of the fence. +Bits which <strong class="purple">can</strong> be set include:</p> +<div class="openblock"> +<div class="content"> +<div id="VkFenceCreateFlagBits" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkFenceCreateFlagBits { + VK_FENCE_CREATE_SIGNALED_BIT = <span class="hex">0x00000001</span>, +} VkFenceCreateFlagBits;</code></pre> +</div> +</div> +</div> +</div> +<div class="paragraph"> +<p>If <code>flags</code> contains <code>VK_FENCE_CREATE_SIGNALED_BIT</code> then the fence +object is created in the signaled state; otherwise it is created in the +unsignaled state.</p> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_FENCE_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkFenceCreateFlagBits">VkFenceCreateFlagBits</a> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To destroy a fence, call:</p> +</div> +<div id="vkDestroyFence" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroyFence( + VkDevice device, + VkFence fence, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that destroys the fence.</p> +</li> +<li> +<p><code>fence</code> is the handle of the fence to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All <a href="#devsandqueues-submission">queue submission</a> commands that refer +to <code>fence</code> <strong class="purple">must</strong> have completed execution</p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>fence</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>fence</code> was +created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p>If <code>fence</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>fence</code> <strong class="purple">must</strong> be a valid <code>VkFence</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p>If <code>fence</code> is a valid handle, it <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>fence</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To query the status of a fence from the host, call:</p> +</div> +<div id="vkGetFenceStatus" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkGetFenceStatus( + VkDevice device, + VkFence fence);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the fence.</p> +</li> +<li> +<p><code>fence</code> is the handle of the fence to query.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Upon success, <code>vkGetFenceStatus</code> returns the status of the fence object, +with the following return codes:</p> +</div> +<table class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 5. Fence Object Status Codes</caption> +<colgroup> +<col style="width: 50%;"> +<col style="width: 50%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Status</th> +<th class="tableblock halign-left valign-top">Meaning</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_SUCCESS</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">The fence specified by <code>fence</code> is signaled.</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_NOT_READY</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">The fence specified by <code>fence</code> is unsignaled.</p></td> +</tr> +</tbody> +</table> +<div class="paragraph"> +<p>If a <a href="#devsandqueues-submission">queue submission</a> command is pending +execution, then the value returned by this command <strong class="purple">may</strong> immediately be out +of date.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>fence</code> <strong class="purple">must</strong> be a valid <code>VkFence</code> handle</p> +</li> +<li> +<p><code>fence</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +<li> +<p><code>VK_NOT_READY</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div id="synchronization-fences-unsignaling" class="paragraph"> +<p>To set the state of fences to unsignaled from the host, call:</p> +</div> +<div id="vkResetFences" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkResetFences( + VkDevice device, + uint32_t fenceCount, + <span class="directive">const</span> VkFence* pFences);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the fences.</p> +</li> +<li> +<p><code>fenceCount</code> is the number of fences to reset.</p> +</li> +<li> +<p><code>pFences</code> is a pointer to an array of fence handles to reset.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When <a href="#vkResetFences">vkResetFences</a> is executed on the host, it defines a <em>fence +unsignal operation</em> for each fence, which resets the fence to the unsignaled +state.</p> +</div> +<div class="paragraph"> +<p>If any member of <code>pFences</code> is already in the unsignaled state when +<a href="#vkResetFences">vkResetFences</a> is executed, then <a href="#vkResetFences">vkResetFences</a> has no effect on +that fence.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>Any given element of <code>pFences</code> <strong class="purple">must</strong> not currently be associated +with any queue command that has not yet completed execution on that +queue</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pFences</code> <strong class="purple">must</strong> be a pointer to an array of <code>fenceCount</code> valid <code>VkFence</code> handles</p> +</li> +<li> +<p><code>fenceCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +<li> +<p>Each element of <code>pFences</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to each member of <code>pFences</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div id="synchronization-fences-signaling" class="paragraph"> +<p>When a fence is submitted to a queue as part of a +<a href="#devsandqueues-submission">queue submission</a> command, it defines a memory +dependency on the batches that were submitted as part of that command, and +defines a <em>fence signal operation</em> which sets the fence to the signaled +state.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes every batch submitted in the same <a href="#devsandqueues-submission">queue +submission</a> command. +Fence signal operations that are defined by <a href="#vkQueueSubmit">vkQueueSubmit</a> additionally +include in the first synchronization scope all previous queue submissions to +the same queue via <a href="#vkQueueSubmit">vkQueueSubmit</a>.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-scopes">synchronization scope</a> +only includes the fence signal operation.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-access-scopes">access scope</a> +includes all memory access performed by the device.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-access-scopes">access scope</a> is +empty.</p> +</div> +<div class="paragraph"> +<p>To wait for one or more fences to enter the signaled state on the host, +call:</p> +</div> +<div id="vkWaitForFences" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkWaitForFences( + VkDevice device, + uint32_t fenceCount, + <span class="directive">const</span> VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the fences.</p> +</li> +<li> +<p><code>fenceCount</code> is the number of fences to wait on.</p> +</li> +<li> +<p><code>pFences</code> is a pointer to an array of <code>fenceCount</code> fence +handles.</p> +</li> +<li> +<p><code>waitAll</code> is the condition that <strong class="purple">must</strong> be satisfied to successfully +unblock the wait. +If <code>waitAll</code> is <code>VK_TRUE</code>, then the condition is that all fences +in <code>pFences</code> are signaled. +Otherwise, the condition is that at least one fence in <code>pFences</code> is +signaled.</p> +</li> +<li> +<p><code>timeout</code> is the timeout period in units of nanoseconds. +<code>timeout</code> is adjusted to the closest value allowed by the +implementation-dependent timeout accuracy, which <strong class="purple">may</strong> be substantially +longer than one nanosecond, and <strong class="purple">may</strong> be longer than the requested +period.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If the condition is satisfied when <code>vkWaitForFences</code> is called, then +<code>vkWaitForFences</code> returns immediately. +If the condition is not satisfied at the time <code>vkWaitForFences</code> is +called, then <code>vkWaitForFences</code> will block and wait up to <code>timeout</code> +nanoseconds for the condition to become satisfied.</p> +</div> +<div class="paragraph"> +<p>If <code>timeout</code> is zero, then <code>vkWaitForFences</code> does not wait, but +simply returns the current state of the fences. +<code>VK_TIMEOUT</code> will be returned in this case if the condition is not +satisfied, even though no actual wait was performed.</p> +</div> +<div class="paragraph"> +<p>If the specified timeout period expires before the condition is satisfied, +<code>vkWaitForFences</code> returns <code>VK_TIMEOUT</code>. +If the condition is satisfied before <code>timeout</code> nanoseconds has expired, +<code>vkWaitForFences</code> returns <code>VK_SUCCESS</code>.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pFences</code> <strong class="purple">must</strong> be a pointer to an array of <code>fenceCount</code> valid <code>VkFence</code> handles</p> +</li> +<li> +<p><code>fenceCount</code> <strong class="purple">must</strong> be greater than <code>0</code></p> +</li> +<li> +<p>Each element of <code>pFences</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +<li> +<p><code>VK_TIMEOUT</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div id="synchronization-fences-waiting" class="paragraph"> +<p>An execution dependency is defined by waiting for a fence to become +signaled, either via <a href="#vkWaitForFences">vkWaitForFences</a> or by polling on +<a href="#vkGetFenceStatus">vkGetFenceStatus</a>.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes only the fence signal operation.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes the host operations of <a href="#vkWaitForFences">vkWaitForFences</a> or +<a href="#vkGetFenceStatus">vkGetFenceStatus</a> indicating that the fence has become signaled.</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>Signaling a fence and waiting on the host does not guarantee that the +results of memory accesses will be visible to the host, as the access scope +of a memory dependency defined by a fence only includes device access. +A <a href="#synchronization-memory-barriers">memory barrier</a> or other memory +dependency <strong class="purple">must</strong> be used to guarantee this. +See the description of <a href="#synchronization-host-access-types">host access +types</a> for more information.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="sect3"> +<h4 id="_alternate_methods_to_signal_fences">6.3.1. Alternate Methods to Signal Fences</h4> +<div class="paragraph"> +<p>Besides submitting a fence to a queue as part of a +<a href="#devsandqueues-submission">queue submission</a> command, a fence <strong class="purple">may</strong> also be +signaled when a particular event occurs on a device or display.</p> +</div> +<div class="paragraph"> +<p>To create a fence that will be signaled when an event occurs on a device, +call:</p> +</div> +<div id="vkRegisterDeviceEventEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkRegisterDeviceEventEXT( + VkDevice device, + <span class="directive">const</span> VkDeviceEventInfoEXT* pDeviceEventInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkFence* pFence);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is a logical device on which the event <strong class="purple">may</strong> occur.</p> +</li> +<li> +<p><code>pDeviceEventInfo</code> is a pointer to an instance of the +<a href="#VkDeviceEventInfoEXT">VkDeviceEventInfoEXT</a> structure describing the event of interest to +the application.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pFence</code> points to a handle in which the resulting fence object is +returned.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pDeviceEventInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkDeviceEventInfoEXT</code> structure</p> +</li> +<li> +<p><code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pFence</code> <strong class="purple">must</strong> be a pointer to a <code>VkFence</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkDeviceEventInfoEXT</code> structure is defined as:</p> +</div> +<div id="VkDeviceEventInfoEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDeviceEventInfoEXT { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkDeviceEventTypeEXT deviceEvent; +} VkDeviceEventInfoEXT;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>device</code> specifies when the fence will be signaled. +Possible values are:</p> +<div class="openblock"> +<div class="content"> +<div id="VkDeviceEventTypeEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkDeviceEventTypeEXT { + VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = <span class="integer">0</span>, +} VkDeviceEventTypeEXT;</code></pre> +</div> +</div> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT</code> occurs when a display is +plugged into or unplugged from the specified device. +Applications <strong class="purple">can</strong> use this notification to determine when they need to +re-enumerate the available displays on a device.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>deviceEvent</code> <strong class="purple">must</strong> be a valid <a href="#VkDeviceEventTypeEXT">VkDeviceEventTypeEXT</a> value</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To create a fence that will be signaled when an event occurs on a +VkDisplayKHR object, call:</p> +</div> +<div id="vkRegisterDisplayEventEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkRegisterDisplayEventEXT( + VkDevice device, + VkDisplayKHR display, + <span class="directive">const</span> VkDisplayEventInfoEXT* pDisplayEventInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkFence* pFence);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is a logical device associated with <code>display</code></p> +</li> +<li> +<p><code>display</code> is the display on which the event <strong class="purple">may</strong> occur.</p> +</li> +<li> +<p><code>pDisplayEventInfo</code> is a pointer to an instance of the +<a href="#VkDisplayEventInfoEXT">VkDisplayEventInfoEXT</a> structure describing the event of interest +to the application.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pFence</code> points to a handle in which the resulting fence object is +returned.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>display</code> <strong class="purple">must</strong> be a valid <code>VkDisplayKHR</code> handle</p> +</li> +<li> +<p><code>pDisplayEventInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkDisplayEventInfoEXT</code> structure</p> +</li> +<li> +<p><code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pFence</code> <strong class="purple">must</strong> be a pointer to a <code>VkFence</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkDisplayEventInfoEXT</code> structure is defined as:</p> +</div> +<div id="VkDisplayEventInfoEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkDisplayEventInfoEXT { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkDisplayEventTypeEXT displayEvent; +} VkDisplayEventInfoEXT;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>displayEvent</code> specifies when the fence will be signaled. +Possible values are:</p> +<div class="openblock"> +<div class="content"> +<div id="VkDisplayEventTypeEXT" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">enum</span> VkDisplayEventTypeEXT { + VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = <span class="integer">0</span>, +} VkDisplayEventTypeEXT;</code></pre> +</div> +</div> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT</code> occurs when the first +pixel of the next display refresh cycle leaves the display engine for +the display.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>displayEvent</code> <strong class="purple">must</strong> be a valid <a href="#VkDisplayEventTypeEXT">VkDisplayEventTypeEXT</a> value</p> +</li> +</ul> +</div> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="synchronization-semaphores">6.4. Semaphores</h3> +<div class="paragraph"> +<p>Semaphores are a synchronization primitive that <strong class="purple">can</strong> be used to insert a +dependency between batches submitted to queues. +Semaphores have two states - signaled and unsignaled. +The state of a semaphore <strong class="purple">can</strong> be signaled after execution of a batch of +commands is completed. +A batch <strong class="purple">can</strong> wait for a semaphore to become signaled before it begins +execution, and the semaphore is also unsignaled before the batch begins +execution.</p> +</div> +<div class="paragraph"> +<p>Semaphores are represented by <code>VkSemaphore</code> handles:</p> +</div> +<div id="VkSemaphore" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>To create a semaphore, call:</p> +</div> +<div id="vkCreateSemaphore" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateSemaphore( + VkDevice device, + <span class="directive">const</span> VkSemaphoreCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkSemaphore* pSemaphore);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that creates the semaphore.</p> +</li> +<li> +<p><code>pCreateInfo</code> is a pointer to an instance of the +<code>VkSemaphoreCreateInfo</code> structure which contains information about +how the semaphore is to be created.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pSemaphore</code> points to a handle in which the resulting semaphore +object is returned.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When created, the semaphore is in the unsignaled state.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkSemaphoreCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pSemaphore</code> <strong class="purple">must</strong> be a pointer to a <code>VkSemaphore</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkSemaphoreCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkSemaphoreCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkSemaphoreCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To create a semaphore object that can be exported to external handles, add +the <a href="#VkExportSemaphoreCreateInfoKHX">VkExportSemaphoreCreateInfoKHX</a> structure to the <code>pNext</code> chain +of the <a href="#VkSemaphoreCreateInfo">VkSemaphoreCreateInfo</a> structure. +The <code>VkExportSemaphoreCreateInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkExportSemaphoreCreateInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkExportSemaphoreCreateInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkExternalSemaphoreHandleTypeFlagsKHX handleTypes; +} VkExportSemaphoreCreateInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>handleTypes</code> is a bitmask of +<a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> specifying one or more +semaphore handle types the application <strong class="purple">can</strong> export from the resulting +allocation. +The application <strong class="purple">can</strong> request multiple handle types for the same +semaphore.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>The bits in <code>handleTypes</code> must be supported and compatible, as +reported by <a href="#VkExternalSemaphorePropertiesKHX">VkExternalSemaphorePropertiesKHX</a>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>handleTypes</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> values</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To specify additional attributes of NT handles exported from a semaphore, +add the <a href="#VkExportSemaphoreWin32HandleInfoKHX">VkExportSemaphoreWin32HandleInfoKHX</a> structure to the +<code>pNext</code> chain of the <a href="#VkSemaphoreCreateInfo">VkSemaphoreCreateInfo</a> structure. +The <code>VkExportSemaphoreWin32HandleInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkExportSemaphoreWin32HandleInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkExportSemaphoreWin32HandleInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + <span class="directive">const</span> SECURITY_ATTRIBUTES* pAttributes; + DWORD dwAccess; + LPCWSTR name; +} VkExportSemaphoreWin32HandleInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>pAttributes</code> is a pointer to a Windows <code>SECURITY_ATTRIBUTES</code> +structure specifying security attributes of the handle.</p> +</li> +<li> +<p><code>dwAccess</code> is a <code>DWORD</code> specifying access rights of the handle.</p> +</li> +<li> +<p><code>name</code> is a NULL-terminated UNICODE string to associate with the +underlying synchronization primitive referenced by NT handles exported +from the created semaphore.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>If this structure is not present, or if <code>pAttributes</code> is set to <code>NULL</code>, +default security descriptor values will be used, and child processes created +by the application will not inherit the handle, as described in the MSDN +documentation for “Synchronization Object Security and Access Rights”<sup>1</sup>. +Further, if the structure is not present, the access rights will be</p> +</div> +<div class="paragraph"> +<p><code>DXGI_SHARED_RESOURCE_READ</code> | <code>DXGI_SHARED_RESOURCE_WRITE</code></p> +</div> +<div class="paragraph"> +<p>for handles of the following types:</p> +</div> +<div class="paragraph"> +<p><code>VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHX</code></p> +</div> +<div class="paragraph"> +<p>And</p> +</div> +<div class="paragraph"> +<p><code>GENERIC_ALL</code></p> +</div> +<div class="paragraph"> +<p>for handles of the following types:</p> +</div> +<div class="paragraph"> +<p><code>VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHX</code></p> +</div> +<div class="dlist"> +<dl> +<dt class="hdlist1">1</dt> +<dd> +<p><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx" class="bare">https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx</a></p> +</dd> +</dl> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>If <a href="#VkExportSemaphoreCreateInfoKHX">VkExportSemaphoreCreateInfoKHX</a>::<code>handleTypes</code> does not +include <code>VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHX</code> or +VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHX, +VkExportSemaphoreWin32HandleInfoKHX <strong class="purple">must</strong> not be in the <code>pNext</code> +chain of <a href="#VkSemaphoreCreateInfo">VkSemaphoreCreateInfo</a>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p>If <code>pAttributes</code> is not <code>NULL</code>, <code>pAttributes</code> <strong class="purple">must</strong> be a pointer to a valid <code>SECURITY_ATTRIBUTES</code> value</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To export a Windows handle representing the state of a semaphore, call:</p> +</div> +<div id="vkGetSemaphoreWin32HandleKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkGetSemaphoreWin32HandleKHX( + VkDevice device, + VkSemaphore semaphore, + VkExternalSemaphoreHandleTypeFlagBitsKHX handleType, + HANDLE* pHandle);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that created <code>semaphore</code>.</p> +</li> +<li> +<p><code>semaphore</code> is the semaphore from which state will be exported.</p> +</li> +<li> +<p><code>handleType</code> is the type of handle requested.</p> +</li> +<li> +<p><code>pHandle</code> will return the Windows handle representing the semaphore +state.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The properties of the handle returned depend on the value of +<code>handleType</code>. +See <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> for a description of the +properties of the defined external semaphore handle types.</p> +</div> +<div class="paragraph"> +<p>For handle types defined as NT handles, the handles returned by +<code>vkGetSemaphoreWin32HandleKHX</code> are owned by the application. +To avoid leaking resources, the application <strong class="purple">must</strong> release ownership of them +using the <code>CloseHandle</code> system call when they are no longer needed.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> have been included in +<a href="#VkExportSemaphoreCreateInfoKHX">VkExportSemaphoreCreateInfoKHX</a>::<code>handleTypes</code> when +<code>semaphore</code>’s current state was created.</p> +</li> +<li> +<p>If <code>handleType</code> is defined as an NT handle, +<a href="#vkGetSemaphoreWin32HandleKHX">vkGetSemaphoreWin32HandleKHX</a> <strong class="purple">must</strong> be called no more than once for +each valid unique combination of <code>semaphore</code> and <code>handleType</code>.</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> not currently have its state replaced by imported +semaphore state as described below in +<a href="#synchronization-semaphores-importing">Importing Semaphore State</a> +unless that imported semaphore state’s handle type was included in +<a href="#VkExternalSemaphorePropertiesKHX">VkExternalSemaphorePropertiesKHX</a>::<code>exportFromImportedHandleTypes</code>.</p> +</li> +<li> +<p>If <code>handleType</code> refers to a handle type with temporary import +semantics, as defined below in +<a href="#synchronization-semaphores-importing">Importing Semaphore State</a>, +there <strong class="purple">must</strong> be no queue waiting on <code>semaphore</code>.</p> +</li> +<li> +<p>If <code>handleType</code> refers to a handle type with temporary import +semantics, <code>semaphore</code> must be signaled, or have an associated +<a href="#synchronization-semaphores-signaling">semaphore signal operation</a> +pending execution.</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be defined as an NT handle or a global share +handle.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> be a valid <code>VkSemaphore</code> handle</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a valid <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> value</p> +</li> +<li> +<p><code>pHandle</code> <strong class="purple">must</strong> be a pointer to a <code>HANDLE</code> value</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_TOO_MANY_OBJECTS</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>To export a POSIX file descriptor representing the state of a semaphore, +call:</p> +</div> +<div id="vkGetSemaphoreFdKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkGetSemaphoreFdKHX( + VkDevice device, + VkSemaphore semaphore, + VkExternalSemaphoreHandleTypeFlagBitsKHX handleType, + <span class="predefined-type">int</span>* pFd);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that created <code>semaphore</code>.</p> +</li> +<li> +<p><code>semaphore</code> is the semaphore from which state will be exported.</p> +</li> +<li> +<p><code>handleType</code> is the type of handle requested.</p> +</li> +<li> +<p><code>pFd</code> will return the file descriptor representing the semaphore +state.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The properties of the file descriptor returned depend on the value of +<code>handleType</code>. +See <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> for a description of the +properties of the defined external semaphore handle types.</p> +</div> +<div class="paragraph"> +<p>Each call to <code>vkGetSemaphoreFdKHX</code> <strong class="purple">must</strong> create a new file descriptor +and transfer ownership of it to the application. +To avoid leaking resources, the application <strong class="purple">must</strong> release ownership of the +file descriptor using the <code>close</code> system call when it is no longer +needed, or by importing Vulkan semaphore state from it.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> have been included in +<a href="#VkExportSemaphoreCreateInfoKHX">VkExportSemaphoreCreateInfoKHX</a>::<code>handleTypes</code> when +<code>semaphore</code>’s current state was created.</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> not currently have its state replaced by imported +semaphore state as described below in +<a href="#synchronization-semaphores-importing">Importing Semaphore State</a> +unless that imported semaphore state’s handle type was included in +<a href="#VkExternalSemaphorePropertiesKHX">VkExternalSemaphorePropertiesKHX</a>::<code>exportFromImportedHandleTypes</code>.</p> +</li> +<li> +<p>If <code>handleType</code> refers to a handle type with temporary import +semantics, as defined below in +<a href="#synchronization-semaphores-importing">Importing Semaphore State</a>, +there <strong class="purple">must</strong> be no queue waiting on <code>semaphore</code>.</p> +</li> +<li> +<p>If <code>handleType</code> refers to a handle type with temporary import +semantics, <code>semaphore</code> must be signaled, or have an associated +<a href="#synchronization-semaphores-signaling">semaphore signal operation</a> +pending execution.</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be defined as a POSIX file descriptor handle.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> be a valid <code>VkSemaphore</code> handle</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a valid <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> value</p> +</li> +<li> +<p><code>pFd</code> <strong class="purple">must</strong> be a pointer to a <code>int</code> value</p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_TOO_MANY_OBJECTS</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>To destroy a semaphore, call:</p> +</div> +<div id="vkDestroySemaphore" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroySemaphore( + VkDevice device, + VkSemaphore semaphore, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that destroys the semaphore.</p> +</li> +<li> +<p><code>semaphore</code> is the handle of the semaphore to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All submitted batches that refer to <code>semaphore</code> <strong class="purple">must</strong> have completed +execution</p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>semaphore</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>semaphore</code> was +created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p>If <code>semaphore</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>semaphore</code> <strong class="purple">must</strong> be a valid <code>VkSemaphore</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p>If <code>semaphore</code> is a valid handle, it <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>semaphore</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-semaphores-signaling">6.4.1. Semaphore Signaling</h4> +<div class="paragraph"> +<p>When a batch is submitted to a queue via a <a href="#devsandqueues-submission">queue +submission</a>, and it includes semaphores to be signaled, it defines a memory +dependency on the batch, and defines <em>semaphore signal operations</em> which set +the semaphores to the signaled state.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes every command submitted in the same batch. +Semaphore signal operations that are defined by <a href="#vkQueueSubmit">vkQueueSubmit</a> +additionally include all batches previously submitted to the same queue via +<a href="#vkQueueSubmit">vkQueueSubmit</a>, including batches that are submitted in the same +<a href="#devsandqueues-submission">queue submission</a> command, but at a lower index +within the array of batches.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes only the semaphore signal operation.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-access-scopes">access scope</a> +includes all memory access performed by the device.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-access-scopes">access scope</a> is +empty.</p> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-semaphores-waiting">6.4.2. Semaphore Waiting & Unsignaling</h4> +<div class="paragraph"> +<p>When a batch is submitted to a queue via a <a href="#devsandqueues-submission">queue +submission</a>, and it includes semaphores to be waited on, it defines a +memory dependency between prior semaphore signal operations and the batch, +and defines <em>semaphore unsignal operations</em> which set the semaphores to the +unsignaled state.</p> +</div> +<div class="paragraph"> +<p>The first synchronization scope includes all semaphore signal operations +that operate on semaphores waited on in the same batch, and that +happen-before the wait completes.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes every command submitted in the same batch. +In the case of <a href="#vkQueueSubmit">vkQueueSubmit</a>, the second synchronization scope is +limited to operations on the pipeline stages determined by the +<a href="#synchronization-pipeline-stages-masks">destination stage mask</a> specified +by the corresponding element of <code>pWaitDstStageMask</code>. +Also, in the case of <a href="#vkQueueSubmit">vkQueueSubmit</a>, the second synchronization scope +additionally includes all batches subsequently submitted to the same queue +via <a href="#vkQueueSubmit">vkQueueSubmit</a>, including batches that are submitted in the same +<a href="#devsandqueues-submission">queue submission</a> command, but at a higher +index within the array of batches.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-access-scopes">access scope</a> is +empty.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-access-scopes">access scope</a> +includes all memory access performed by the device.</p> +</div> +<div class="paragraph"> +<p>The semaphore unsignal operation happens-after the first set of operations +in the execution dependency, and happens-before the second set of operations +in the execution dependency.</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>Unlike fences or events, the act of waiting for a semaphore also unsignals +that semaphore. +If two operations are separately specified to wait for the same semaphore, +and there are no other execution dependencies between those operations, +behaviour is undefined. +An execution dependency <strong class="purple">must</strong> be present that guarantees that the semaphore +unsignal operation for the first of those waits, happens-before the +semaphore is signalled again, and before the second unsignal operation. +Semaphore waits and signals should thus occur in discrete 1:1 pairs.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +<div class="title">Note</div> +<div class="paragraph"> +<p>A common scenario for using <code>pWaitDstStageMask</code> with values other than +<code>VK_PIPELINE_STAGE_ALL_COMMANDS_BIT</code> is when synchronizing a window +system presentation operation against subsequent command buffers which +render the next frame. +In this case, a presentation image <strong class="purple">must</strong> not be overwritten until the +presentation operation completes, but other pipeline stages <strong class="purple">can</strong> execute +without waiting. +A mask of <code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code> prevents +subsequent color attachment writes from executing until the semaphore +signals. +Some implementations <strong class="purple">may</strong> be able to execute transfer operations and/or +vertex processing work before the semaphore is signaled.</p> +</div> +<div class="paragraph"> +<p>If an image layout transition needs to be performed on a presentable image +before it is used in a framebuffer, that <strong class="purple">can</strong> be performed as the first +operation submitted to the queue after acquiring the image, and <strong class="purple">should</strong> not +prevent other work from overlapping with the presentation operation. +For example, a <code>VkImageMemoryBarrier</code> could use:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>srcStageMask</code> = <code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p> +</li> +<li> +<p><code>srcAccessMask</code> = 0</p> +</li> +<li> +<p><code>dstStageMask</code> = <code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code></p> +</li> +<li> +<p><code>dstAccessMask</code> = <code>VK_ACCESS_COLOR_ATTACHMENT_READ_BIT</code> | +<code>VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT</code>.</p> +</li> +<li> +<p><code>oldLayout</code> = <code>VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</code></p> +</li> +<li> +<p><code>newLayout</code> = <code>VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL</code></p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Alternatively, <code>oldLayout</code> <strong class="purple">can</strong> be <code>VK_IMAGE_LAYOUT_UNDEFINED</code>, if +the image’s contents need not be preserved.</p> +</div> +<div class="paragraph"> +<p>This barrier accomplishes a dependency chain between previous presentation +operations and subsequent color attachment output operations, with the +layout transition performed in between, and does not introduce a dependency +between previous work and any vertex processing stages. +More precisely, the semaphore signals after the presentation operation +completes, the semaphore wait stalls the +<code>VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT</code> stage, and there is a +dependency from that same stage to itself with the layout transition +performed in between.</p> +</div> +</td> +</tr> +</table> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-semaphores-waiting-state">6.4.3. Semaphore State Requirements For Wait Operations</h4> +<div class="paragraph"> +<p>Before waiting on a semaphore, the application <strong class="purple">must</strong> ensure the semaphore is +in a valid state for a wait operation. +Specifically, when a <a href="#synchronization-semaphores-waiting">semaphore wait and +unsignal operation</a> is submitted to a queue:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>The semaphore <strong class="purple">must</strong> be signaled, or have an associated +<a href="#synchronization-semaphores-signaling">semaphore signal operation</a> that +is pending execution.</p> +</li> +<li> +<p>There <strong class="purple">must</strong> be no other queue waiting on the same semaphore when the +operation executes.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Generally, the implementation behavior will be undefined when applications +fail to ensure these requirements are met. +However, to avoid requiring Vulkan instances that import semaphore state to +trust the source of that state, the side effects of violating the +requirements are better defined in certain cases. +When the semaphore that violates the requirements is using imported state at +the time of the violation, the implementation <strong class="purple">must</strong> ensure side effects are +limited to one or more of the following:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Returning the error code <code>VK_ERROR_INITIALIZATION_FAILED</code> from the +command which resulted in the violation.</p> +</li> +<li> +<p>Allowing the logical device on which the violation occured to enter an +undefined state immediately or in the future and returning the error +code VK_ERROR_DEVICE_LOST from any subsequent command, including the one +causing the violation, after the device enters such a state.</p> +</li> +<li> +<p>Continuing execution of the violating command or operation as if the +semaphore wait completed successfully after an implementation-dependent +timeout. +In this case, the state of the semaphore becomes undefined. +The semaphore <strong class="purple">must</strong> be destroyed or have its state replaced by an import +operation to again meet valid usage requirements.</p> +</li> +</ul> +</div> +</div> +<div class="sect3"> +<h4 id="synchronization-semaphores-importing">6.4.4. Importing Semaphore State</h4> +<div class="paragraph"> +<p>Applications <strong class="purple">may</strong> import semaphore state into an existing semaphore using an +external semaphore handle. +Doing so releases any existing state as if <a href="#vkDestroySemaphore">vkDestroySemaphore</a> had been +called on the target semaphore. +As such, similar usage restrictions to those applied to +<code>vkDestroySemaphore</code> are applied to any command that imports semaphore +state. +The effects of the import operation will be either temporary or permanent, +depending on the type of handle used to perform the import. +If the import is temporary, the implementation <strong class="purple">must</strong> restore the semaphore +to its prior permanent state when executing the next semaphore signal +operation. +If the import is permanent, the signaled status of all semaphores sharing +the same semaphore state <strong class="purple">must</strong> be equivalent. +Semaphore signaling and waiting operations performed on any semaphore in the +set of semaphores sharing semaphore state <strong class="purple">must</strong> behave the same as if the +set were a single semaphore. +Passing a semaphore to <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a> is equivalent to +temporarily importing semaphore state to that semaphore. +When a semaphore is using imported state, its +<a href="#VkExportSemaphoreCreateInfoKHX">VkExportSemaphoreCreateInfoKHX</a>::<code>handleTypes</code> value is that +specified when creating the semaphore from which the state was exported, +rather than that specified when creating the semaphore.</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>Because the exportable handle types of an imported semaphore correspond to +its current imported state, and <a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a> behaves the same +as a temporary import operation for which the source semaphore is opaque to +the application, applications have no way of determining whether any +external handle types <strong class="purple">can</strong> be exported from a semaphore in this state. +Therefore, applications <strong class="purple">must</strong> not attempt to export external handles from +semaphores using temporarily imported state from +<a href="#vkAcquireNextImageKHR">vkAcquireNextImageKHR</a>.</p> +</div> +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>When importing semaphore state, it is the responsibility of the application +to ensure the external handles meet all valid usage requirements. +However, implementations must perform sufficient validation of external +handles to ensure that the operation results in valid semaphore state which +will not cause program termination, device loss, queue stalls, or corruption +of other resources when used as allowed according to its import parameters, +and excepting those side effects allowed for violations of the +<a href="#synchronization-semaphores-waiting-state">valid semaphore state for wait +operations</a> rules. +If the external handle provided does not meet these requirements, the +implementation <strong class="purple">must</strong> fail the semaphore state import operation with the +error code VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX.</p> +</div> +<div class="paragraph"> +<p>To import semaphore state from a Windows handle, call:</p> +</div> +<div id="vkImportSemaphoreWin32HandleKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkImportSemaphoreWin32HandleKHX( + VkDevice device, + <span class="directive">const</span> VkImportSemaphoreWin32HandleInfoKHX* pImportSemaphoreWin32HandleInfo);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that created the semaphore.</p> +</li> +<li> +<p><code>pImportSemaphoreWin32HandleInfo</code> points to a +<a href="#VkImportSemaphoreWin32HandleInfoKHX">VkImportSemaphoreWin32HandleInfoKHX</a> structure specifying the +semaphore and import parameters.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Importing semaphore state from Windows handles does not transfer ownership +of the handle to the Vulkan implementation. +For handle types defined as NT handles, the application <strong class="purple">must</strong> release +ownership using the <code>CloseHandle</code> system call when the handle is no +longer needed.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pImportSemaphoreWin32HandleInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkImportSemaphoreWin32HandleInfoKHX</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkImportSemaphoreWin32HandleInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkImportSemaphoreWin32HandleInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkImportSemaphoreWin32HandleInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagsKHX handleType; + HANDLE handle; +} VkImportSemaphoreWin32HandleInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>semaphore</code> is the semaphore into which the state will be imported.</p> +</li> +<li> +<p><code>handleType</code> specifies the type of <code>handle</code>.</p> +</li> +<li> +<p><code>handle</code> is the external handle to import.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The handle types supported by <code>handleType</code> are:</p> +</div> +<table id="synchronization-handletypes-win32" class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 6. Handle Type Permanence for VkImportSemaphoreWin32HandleInfoKHX</caption> +<colgroup> +<col style="width: 50%;"> +<col style="width: 50%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Handle Type</th> +<th class="tableblock halign-left valign-top">Permanence</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHX</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Permanent</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHX</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Permanent</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHX</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Permanent</p></td> +</tr> +</tbody> +</table> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a value included in the +<a href="#synchronization-handletypes-win32">Handle Type Permanence for +VkImportSemaphoreWin32HandleInfoKHX</a> table.</p> +</li> +<li> +<p>The semaphore from which <code>handleType</code> was exported <strong class="purple">must</strong> have been +created on the same underlying physical device as <code>semaphore</code>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> be a valid <code>VkSemaphore</code> handle</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> values</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> not be <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To import semaphore state from a POSIX file descriptor, call:</p> +</div> +<div id="vkImportSemaphoreFdKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkImportSemaphoreFdKHX( + VkDevice device, + <span class="directive">const</span> VkImportSemaphoreFdInfoKHX* pImportSemaphoreFdInfo);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that created the semaphore.</p> +</li> +<li> +<p><code>pImportSemaphoreFdInfo</code> points to a +<a href="#VkImportSemaphoreFdInfoKHX">VkImportSemaphoreFdInfoKHX</a> structure specifying the semaphore and +import parameters.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Importing semaphore state from a file descriptor transfers ownership of the +file descriptor from the application to the Vulkan implementation. +The application <strong class="purple">must</strong> not perform any operations on the file descriptor +after a successful import.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> not be associated with any queue command that has +not yet completed execution on that queue</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pImportSemaphoreFdInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkImportSemaphoreFdInfoKHX</code> structure</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkImportSemaphoreFdInfoKHX</code> structure is defined as:</p> +</div> +<div id="VkImportSemaphoreFdInfoKHX" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkImportSemaphoreFdInfoKHX { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBitsKHX handleType; + <span class="predefined-type">int</span> fd; +} VkImportSemaphoreFdInfoKHX;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>semaphore</code> is the semaphore into which the state will be imported.</p> +</li> +<li> +<p><code>handleType</code> specifies the type of <code>fd</code>.</p> +</li> +<li> +<p><code>fd</code> is the external handle to import.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The handle types supported by <code>handleType</code> are:</p> +</div> +<table id="synchronization-handletypes-fd" class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 7. Handle Type Permanence for VkImportSemaphoreFdInfoKHX</caption> +<colgroup> +<col style="width: 50%;"> +<col style="width: 50%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Handle Type</th> +<th class="tableblock halign-left valign-top">Permanence</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Permanent</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock">VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FENCE_FD_BIT_KHX</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Temporary</p></td> +</tr> +</tbody> +</table> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a value included in the +<a href="#synchronization-handletypes-fd">Handle Type Permanence for +VkImportSemaphoreFdInfoKHX</a> table.</p> +</li> +<li> +<p>The semaphore from which <code>handleType</code> was exported <strong class="purple">must</strong> have been +created on the same underlying physical device as <code>semaphore</code>.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHX</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>semaphore</code> <strong class="purple">must</strong> be a valid <code>VkSemaphore</code> handle</p> +</li> +<li> +<p><code>handleType</code> <strong class="purple">must</strong> be a valid <a href="#VkExternalSemaphoreHandleTypeFlagBitsKHX">VkExternalSemaphoreHandleTypeFlagBitsKHX</a> value</p> +</li> +</ul> +</div> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="synchronization-events">6.5. Events</h3> +<div class="paragraph"> +<p>Events are a synchronization primitive that <strong class="purple">can</strong> be used to insert a +fine-grained dependency between commands submitted to the same queue, or +between the host and a queue. +Events have two states - signaled and unsignaled. +An application <strong class="purple">can</strong> signal an event, or unsignal it, on either the host or +the device. +A device <strong class="purple">can</strong> wait for an event to become signaled before executing further +operations. +No command exists to wait for an event to become signaled on the host, but +the current state of an event <strong class="purple">can</strong> be queried.</p> +</div> +<div class="paragraph"> +<p>Events are represented by <code>VkEvent</code> handles:</p> +</div> +<div id="VkEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)</code></pre> +</div> +</div> +<div class="paragraph"> +<p>To create an event, call:</p> +</div> +<div id="vkCreateEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkCreateEvent( + VkDevice device, + <span class="directive">const</span> VkEventCreateInfo* pCreateInfo, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator, + VkEvent* pEvent);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that creates the event.</p> +</li> +<li> +<p><code>pCreateInfo</code> is a pointer to an instance of the +<code>VkEventCreateInfo</code> structure which contains information about how +the event is to be created.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +<li> +<p><code>pEvent</code> points to a handle in which the resulting event object is +returned.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When created, the event object is in the unsignaled state.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>pCreateInfo</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkEventCreateInfo</code> structure</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p><code>pEvent</code> <strong class="purple">must</strong> be a pointer to a <code>VkEvent</code> handle</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The <code>VkEventCreateInfo</code> structure is defined as:</p> +</div> +<div id="VkEventCreateInfo" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="keyword">typedef</span> <span class="keyword">struct</span> VkEventCreateInfo { + VkStructureType sType; + <span class="directive">const</span> <span class="directive">void</span>* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo;</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> is the type of this structure.</p> +</li> +<li> +<p><code>pNext</code> is <code>NULL</code> or a pointer to an extension-specific structure.</p> +</li> +<li> +<p><code>flags</code> is reserved for future use.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>sType</code> <strong class="purple">must</strong> be <code>VK_STRUCTURE_TYPE_EVENT_CREATE_INFO</code></p> +</li> +<li> +<p><code>pNext</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +<li> +<p><code>flags</code> <strong class="purple">must</strong> be <code>0</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To destroy an event, call:</p> +</div> +<div id="vkDestroyEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkDestroyEvent( + VkDevice device, + VkEvent event, + <span class="directive">const</span> VkAllocationCallbacks* pAllocator);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that destroys the event.</p> +</li> +<li> +<p><code>event</code> is the handle of the event to destroy.</p> +</li> +<li> +<p><code>pAllocator</code> controls host memory allocation as described in the +<a href="#memory-allocation">Memory Allocation</a> chapter.</p> +</li> +</ul> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p>All submitted commands that refer to <code>event</code> <strong class="purple">must</strong> have completed +execution</p> +</li> +<li> +<p>If <code>VkAllocationCallbacks</code> were provided when <code>event</code> was +created, a compatible set of callbacks <strong class="purple">must</strong> be provided here</p> +</li> +<li> +<p>If no <code>VkAllocationCallbacks</code> were provided when <code>event</code> was +created, <code>pAllocator</code> <strong class="purple">must</strong> be <code>NULL</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p>If <code>event</code> is not <a href="#VK_NULL_HANDLE">VK_NULL_HANDLE</a>, <code>event</code> <strong class="purple">must</strong> be a valid <code>VkEvent</code> handle</p> +</li> +<li> +<p>If <code>pAllocator</code> is not <code>NULL</code>, <code>pAllocator</code> <strong class="purple">must</strong> be a pointer to a valid <code>VkAllocationCallbacks</code> structure</p> +</li> +<li> +<p>If <code>event</code> is a valid handle, it <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>event</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="paragraph"> +<p>To query the state of an event from the host, call:</p> +</div> +<div id="vkGetEventStatus" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkGetEventStatus( + VkDevice device, + VkEvent event);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the event.</p> +</li> +<li> +<p><code>event</code> is the handle of the event to query.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Upon success, <code>vkGetEventStatus</code> returns the state of the event object +with the following return codes:</p> +</div> +<table class="tableblock frame-all grid-all" style="width: 80%;"> +<caption class="title">Table 8. Event Object Status Codes</caption> +<colgroup> +<col style="width: 50%;"> +<col style="width: 50%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Status</th> +<th class="tableblock halign-left valign-top">Meaning</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_EVENT_SET</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">The event specified by <code>event</code> is signaled.</p></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VK_EVENT_RESET</code></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">The event specified by <code>event</code> is unsignaled.</p></td> +</tr> +</tbody> +</table> +<div class="paragraph"> +<p>If a <code>vkCmdSetEvent</code> or <code>vkCmdResetEvent</code> command is pending +execution, then the value returned by this command <strong class="purple">may</strong> immediately be out +of date.</p> +</div> +<div class="paragraph"> +<p>The state of an event <strong class="purple">can</strong> be updated by the host. +The state of the event is immediately changed, and subsequent calls to +<code>vkGetEventStatus</code> will return the new state. +If an event is already in the requested state, then updating it to the same +state has no effect.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> be a valid <code>VkEvent</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_EVENT_SET</code></p> +</li> +<li> +<p><code>VK_EVENT_RESET</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_DEVICE_LOST</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div id="synchronization-events-signaling-host" class="paragraph"> +<p>To set the state of an event to signaled from the host, call:</p> +</div> +<div id="vkSetEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkSetEvent( + VkDevice device, + VkEvent event);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the event.</p> +</li> +<li> +<p><code>event</code> is the event to set.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When <a href="#vkSetEvent">vkSetEvent</a> is executed on the host, it defines an <em>event signal +operation</em> which sets the event to the signaled state.</p> +</div> +<div class="paragraph"> +<p>If <code>event</code> is already in the signaled state when <a href="#vkSetEvent">vkSetEvent</a> is +executed, then <a href="#vkSetEvent">vkSetEvent</a> has no effect, and no event signal operation +occurs.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> be a valid <code>VkEvent</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>event</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div id="synchronization-events-unsignaling-host" class="paragraph"> +<p>To set the state of an event to unsignaled from the host, call:</p> +</div> +<div id="vkResetEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++">VkResult vkResetEvent( + VkDevice device, + VkEvent event);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> is the logical device that owns the event.</p> +</li> +<li> +<p><code>event</code> is the event to reset.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When <a href="#vkResetEvent">vkResetEvent</a> is executed on the host, it defines an <em>event +unsignal operation</em> which resets the event to the unsignaled state.</p> +</div> +<div class="paragraph"> +<p>If <code>event</code> is already in the unsignaled state when <a href="#vkResetEvent">vkResetEvent</a> is +executed, then <a href="#vkResetEvent">vkResetEvent</a> has no effect, and no event unsignal +operation occurs.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>event</code> <strong class="purple">must</strong> not be waited on by a <code>vkCmdWaitEvents</code> command +that is currently executing</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>device</code> <strong class="purple">must</strong> be a valid <code>VkDevice</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> be a valid <code>VkEvent</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from <code>device</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> +<li> +<p>Host access to <code>event</code> <strong class="purple">must</strong> be externally synchronized</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Return Codes</div> +<div class="dlist"> +<dl> +<dt class="hdlist1"><a href="#fundamentals-successcodes">Success</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_SUCCESS</code></p> +</li> +</ul> +</div> +</dd> +<dt class="hdlist1"><a href="#fundamentals-errorcodes">Failure</a></dt> +<dd> +<div class="ulist"> +<ul> +<li> +<p><code>VK_ERROR_OUT_OF_HOST_MEMORY</code></p> +</li> +<li> +<p><code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code></p> +</li> +</ul> +</div> +</dd> +</dl> +</div> +</div> +</div> +<div class="paragraph"> +<p>The state of an event <strong class="purple">can</strong> also be updated on the device by commands +inserted in command buffers.</p> +</div> +<div id="synchronization-events-signaling-device" class="paragraph"> +<p>To set the state of an event to signaled from a device, call:</p> +</div> +<div id="vkCmdSetEvent" class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="c++"><span class="directive">void</span> vkCmdSetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask);</code></pre> +</div> +</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> is the command buffer into which the command is +recorded.</p> +</li> +<li> +<p><code>event</code> is the event that will be signaled.</p> +</li> +<li> +<p><code>stageMask</code> specifies the <a href="#synchronization-pipeline-stages">source +stage mask</a> used to determine when the <code>event</code> is signaled.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>When <a href="#vkCmdSetEvent">vkCmdSetEvent</a> is submitted to a queue, it defines an execution +dependency on commands that were submitted before it, and defines an event +signal operation which sets the event to the signaled state.</p> +</div> +<div class="paragraph"> +<p>The first <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes every command previously submitted to the same queue, including +those in the same command buffer and batch. +The synchronization scope is limited to operations on the pipeline stages +determined by the <a href="#synchronization-pipeline-stages-masks">source stage +mask</a> specified by <code>stageMask</code>.</p> +</div> +<div class="paragraph"> +<p>The second <a href="#synchronization-dependencies-scopes">synchronization scope</a> +includes only the event signal operation.</p> +</div> +<div class="paragraph"> +<p>If <code>event</code> is already in the signaled state when <a href="#vkCmdSetEvent">vkCmdSetEvent</a> is +executed on the device, then <a href="#vkCmdSetEvent">vkCmdSetEvent</a> has no effect, no event +signal operation occurs, and no execution dependency is generated.</p> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage</div> +<div class="ulist"> +<ul> +<li> +<p><code>stageMask</code> <strong class="purple">must</strong> not include <code>VK_PIPELINE_STAGE_HOST_BIT</code></p> +</li> +<li> +<p>If the <a href="#features-features-geometryShader">geometry shaders</a> feature is +not enabled, <code>stageMask</code> <strong class="purple">must</strong> not contain +<code>VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</code></p> +</li> +<li> +<p>If the <a href="#features-features-tessellationShader">tessellation shaders</a> +feature is not enabled, <code>stageMask</code> <strong class="purple">must</strong> not contain +<code>VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT</code> or +<code>VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</code></p> +</li> +<li> +<p><code>commandBuffer</code>’s current device mask <strong class="purple">must</strong> include exactly one +physical device.</p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Valid Usage (Implicit)</div> +<div class="ulist"> +<ul> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be a valid <code>VkCommandBuffer</code> handle</p> +</li> +<li> +<p><code>event</code> <strong class="purple">must</strong> be a valid <code>VkEvent</code> handle</p> +</li> +<li> +<p><code>stageMask</code> <strong class="purple">must</strong> be a valid combination of <a href="#VkPipelineStageFlagBits">VkPipelineStageFlagBits</a> values</p> +</li> +<li> +<p><code>stageMask</code> <strong class="purple">must</strong> not be <code>0</code></p> +</li> +<li> +<p><code>commandBuffer</code> <strong class="purple">must</strong> be in the recording state</p> +</li> +<li> +<p>The <code>VkCommandPool</code> that <code>commandBuffer</code> was allocated from <strong class="purple">must</strong> support graphics, or compute operations</p> +</li> +<li> +<p>This command <strong class="purple">must</strong> only be called outside of a render pass instance</p> +</li> +<li> +<p>Both of <code>commandBuffer</code>, and <code>event</code> <strong class="purple">must</strong> have been created, allocated, or retrieved from the same <code>VkDevice</code></p> +</li> +</ul> +</div> +</div> +</div> +<div class="sidebarblock"> +<div class="content"> +<div class="title">Host Synchronization</div> +<div class="ulist"> +<ul> |