1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 5 <meta name="generator" content="AsciiDoc 8.6.9"> 6 <title>Vulkan on Android Implementor’s Guide</title> 7 <style type="text/css"> 8 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */ 9 10 /* Default font. */ 11 body { 12 font-family: Georgia,serif; 13 } 14 15 /* Title font. */ 16 h1, h2, h3, h4, h5, h6, 17 div.title, caption.title, 18 thead, p.table.header, 19 #toctitle, 20 #author, #revnumber, #revdate, #revremark, 21 #footer { 22 font-family: Arial,Helvetica,sans-serif; 23 } 24 25 body { 26 margin: 1em 5% 1em 5%; 27 } 28 29 a { 30 color: blue; 31 text-decoration: underline; 32 } 33 a:visited { 34 color: fuchsia; 35 } 36 37 em { 38 font-style: italic; 39 color: navy; 40 } 41 42 strong { 43 font-weight: bold; 44 color: #083194; 45 } 46 47 h1, h2, h3, h4, h5, h6 { 48 color: #527bbd; 49 margin-top: 1.2em; 50 margin-bottom: 0.5em; 51 line-height: 1.3; 52 } 53 54 h1, h2, h3 { 55 border-bottom: 2px solid silver; 56 } 57 h2 { 58 padding-top: 0.5em; 59 } 60 h3 { 61 float: left; 62 } 63 h3 + * { 64 clear: left; 65 } 66 h5 { 67 font-size: 1.0em; 68 } 69 70 div.sectionbody { 71 margin-left: 0; 72 } 73 74 hr { 75 border: 1px solid silver; 76 } 77 78 p { 79 margin-top: 0.5em; 80 margin-bottom: 0.5em; 81 } 82 83 ul, ol, li > p { 84 margin-top: 0; 85 } 86 ul > li { color: #aaa; } 87 ul > li > * { color: black; } 88 89 .monospaced, code, pre { 90 font-family: "Courier New", Courier, monospace; 91 font-size: inherit; 92 color: navy; 93 padding: 0; 94 margin: 0; 95 } 96 pre { 97 white-space: pre-wrap; 98 } 99 100 #author { 101 color: #527bbd; 102 font-weight: bold; 103 font-size: 1.1em; 104 } 105 #email { 106 } 107 #revnumber, #revdate, #revremark { 108 } 109 110 #footer { 111 font-size: small; 112 border-top: 2px solid silver; 113 padding-top: 0.5em; 114 margin-top: 4.0em; 115 } 116 #footer-text { 117 float: left; 118 padding-bottom: 0.5em; 119 } 120 #footer-badges { 121 float: right; 122 padding-bottom: 0.5em; 123 } 124 125 #preamble { 126 margin-top: 1.5em; 127 margin-bottom: 1.5em; 128 } 129 div.imageblock, div.exampleblock, div.verseblock, 130 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock, 131 div.admonitionblock { 132 margin-top: 1.0em; 133 margin-bottom: 1.5em; 134 } 135 div.admonitionblock { 136 margin-top: 2.0em; 137 margin-bottom: 2.0em; 138 margin-right: 10%; 139 color: #606060; 140 } 141 142 div.content { /* Block element content. */ 143 padding: 0; 144 } 145 146 /* Block element titles. */ 147 div.title, caption.title { 148 color: #527bbd; 149 font-weight: bold; 150 text-align: left; 151 margin-top: 1.0em; 152 margin-bottom: 0.5em; 153 } 154 div.title + * { 155 margin-top: 0; 156 } 157 158 td div.title:first-child { 159 margin-top: 0.0em; 160 } 161 div.content div.title:first-child { 162 margin-top: 0.0em; 163 } 164 div.content + div.title { 165 margin-top: 0.0em; 166 } 167 168 div.sidebarblock > div.content { 169 background: #ffffee; 170 border: 1px solid #dddddd; 171 border-left: 4px solid #f0f0f0; 172 padding: 0.5em; 173 } 174 175 div.listingblock > div.content { 176 border: 1px solid #dddddd; 177 border-left: 5px solid #f0f0f0; 178 background: #f8f8f8; 179 padding: 0.5em; 180 } 181 182 div.quoteblock, div.verseblock { 183 padding-left: 1.0em; 184 margin-left: 1.0em; 185 margin-right: 10%; 186 border-left: 5px solid #f0f0f0; 187 color: #888; 188 } 189 190 div.quoteblock > div.attribution { 191 padding-top: 0.5em; 192 text-align: right; 193 } 194 195 div.verseblock > pre.content { 196 font-family: inherit; 197 font-size: inherit; 198 } 199 div.verseblock > div.attribution { 200 padding-top: 0.75em; 201 text-align: left; 202 } 203 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */ 204 div.verseblock + div.attribution { 205 text-align: left; 206 } 207 208 div.admonitionblock .icon { 209 vertical-align: top; 210 font-size: 1.1em; 211 font-weight: bold; 212 text-decoration: underline; 213 color: #527bbd; 214 padding-right: 0.5em; 215 } 216 div.admonitionblock td.content { 217 padding-left: 0.5em; 218 border-left: 3px solid #dddddd; 219 } 220 221 div.exampleblock > div.content { 222 border-left: 3px solid #dddddd; 223 padding-left: 0.5em; 224 } 225 226 div.imageblock div.content { padding-left: 0; } 227 span.image img { border-style: none; vertical-align: text-bottom; } 228 a.image:visited { color: white; } 229 230 dl { 231 margin-top: 0.8em; 232 margin-bottom: 0.8em; 233 } 234 dt { 235 margin-top: 0.5em; 236 margin-bottom: 0; 237 font-style: normal; 238 color: navy; 239 } 240 dd > *:first-child { 241 margin-top: 0.1em; 242 } 243 244 ul, ol { 245 list-style-position: outside; 246 } 247 ol.arabic { 248 list-style-type: decimal; 249 } 250 ol.loweralpha { 251 list-style-type: lower-alpha; 252 } 253 ol.upperalpha { 254 list-style-type: upper-alpha; 255 } 256 ol.lowerroman { 257 list-style-type: lower-roman; 258 } 259 ol.upperroman { 260 list-style-type: upper-roman; 261 } 262 263 div.compact ul, div.compact ol, 264 div.compact p, div.compact p, 265 div.compact div, div.compact div { 266 margin-top: 0.1em; 267 margin-bottom: 0.1em; 268 } 269 270 tfoot { 271 font-weight: bold; 272 } 273 td > div.verse { 274 white-space: pre; 275 } 276 277 div.hdlist { 278 margin-top: 0.8em; 279 margin-bottom: 0.8em; 280 } 281 div.hdlist tr { 282 padding-bottom: 15px; 283 } 284 dt.hdlist1.strong, td.hdlist1.strong { 285 font-weight: bold; 286 } 287 td.hdlist1 { 288 vertical-align: top; 289 font-style: normal; 290 padding-right: 0.8em; 291 color: navy; 292 } 293 td.hdlist2 { 294 vertical-align: top; 295 } 296 div.hdlist.compact tr { 297 margin: 0; 298 padding-bottom: 0; 299 } 300 301 .comment { 302 background: yellow; 303 } 304 305 .footnote, .footnoteref { 306 font-size: 0.8em; 307 } 308 309 span.footnote, span.footnoteref { 310 vertical-align: super; 311 } 312 313 #footnotes { 314 margin: 20px 0 20px 0; 315 padding: 7px 0 0 0; 316 } 317 318 #footnotes div.footnote { 319 margin: 0 0 5px 0; 320 } 321 322 #footnotes hr { 323 border: none; 324 border-top: 1px solid silver; 325 height: 1px; 326 text-align: left; 327 margin-left: 0; 328 width: 20%; 329 min-width: 100px; 330 } 331 332 div.colist td { 333 padding-right: 0.5em; 334 padding-bottom: 0.3em; 335 vertical-align: top; 336 } 337 div.colist td img { 338 margin-top: 0.3em; 339 } 340 341 @media print { 342 #footer-badges { display: none; } 343 } 344 345 #toc { 346 margin-bottom: 2.5em; 347 } 348 349 #toctitle { 350 color: #527bbd; 351 font-size: 1.1em; 352 font-weight: bold; 353 margin-top: 1.0em; 354 margin-bottom: 0.1em; 355 } 356 357 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 { 358 margin-top: 0; 359 margin-bottom: 0; 360 } 361 div.toclevel2 { 362 margin-left: 2em; 363 font-size: 0.9em; 364 } 365 div.toclevel3 { 366 margin-left: 4em; 367 font-size: 0.9em; 368 } 369 div.toclevel4 { 370 margin-left: 6em; 371 font-size: 0.9em; 372 } 373 374 span.aqua { color: aqua; } 375 span.black { color: black; } 376 span.blue { color: blue; } 377 span.fuchsia { color: fuchsia; } 378 span.gray { color: gray; } 379 span.green { color: green; } 380 span.lime { color: lime; } 381 span.maroon { color: maroon; } 382 span.navy { color: navy; } 383 span.olive { color: olive; } 384 span.purple { color: purple; } 385 span.red { color: red; } 386 span.silver { color: silver; } 387 span.teal { color: teal; } 388 span.white { color: white; } 389 span.yellow { color: yellow; } 390 391 span.aqua-background { background: aqua; } 392 span.black-background { background: black; } 393 span.blue-background { background: blue; } 394 span.fuchsia-background { background: fuchsia; } 395 span.gray-background { background: gray; } 396 span.green-background { background: green; } 397 span.lime-background { background: lime; } 398 span.maroon-background { background: maroon; } 399 span.navy-background { background: navy; } 400 span.olive-background { background: olive; } 401 span.purple-background { background: purple; } 402 span.red-background { background: red; } 403 span.silver-background { background: silver; } 404 span.teal-background { background: teal; } 405 span.white-background { background: white; } 406 span.yellow-background { background: yellow; } 407 408 span.big { font-size: 2em; } 409 span.small { font-size: 0.6em; } 410 411 span.underline { text-decoration: underline; } 412 span.overline { text-decoration: overline; } 413 span.line-through { text-decoration: line-through; } 414 415 div.unbreakable { page-break-inside: avoid; } 416 417 418 /* 419 * xhtml11 specific 420 * 421 * */ 422 423 div.tableblock { 424 margin-top: 1.0em; 425 margin-bottom: 1.5em; 426 } 427 div.tableblock > table { 428 border: 3px solid #527bbd; 429 } 430 thead, p.table.header { 431 font-weight: bold; 432 color: #527bbd; 433 } 434 p.table { 435 margin-top: 0; 436 } 437 /* Because the table frame attribute is overriden by CSS in most browsers. */ 438 div.tableblock > table[frame="void"] { 439 border-style: none; 440 } 441 div.tableblock > table[frame="hsides"] { 442 border-left-style: none; 443 border-right-style: none; 444 } 445 div.tableblock > table[frame="vsides"] { 446 border-top-style: none; 447 border-bottom-style: none; 448 } 449 450 451 /* 452 * html5 specific 453 * 454 * */ 455 456 table.tableblock { 457 margin-top: 1.0em; 458 margin-bottom: 1.5em; 459 } 460 thead, p.tableblock.header { 461 font-weight: bold; 462 color: #527bbd; 463 } 464 p.tableblock { 465 margin-top: 0; 466 } 467 table.tableblock { 468 border-width: 3px; 469 border-spacing: 0px; 470 border-style: solid; 471 border-color: #527bbd; 472 border-collapse: collapse; 473 } 474 th.tableblock, td.tableblock { 475 border-width: 1px; 476 padding: 4px; 477 border-style: solid; 478 border-color: #527bbd; 479 } 480 481 table.tableblock.frame-topbot { 482 border-left-style: hidden; 483 border-right-style: hidden; 484 } 485 table.tableblock.frame-sides { 486 border-top-style: hidden; 487 border-bottom-style: hidden; 488 } 489 table.tableblock.frame-none { 490 border-style: hidden; 491 } 492 493 th.tableblock.halign-left, td.tableblock.halign-left { 494 text-align: left; 495 } 496 th.tableblock.halign-center, td.tableblock.halign-center { 497 text-align: center; 498 } 499 th.tableblock.halign-right, td.tableblock.halign-right { 500 text-align: right; 501 } 502 503 th.tableblock.valign-top, td.tableblock.valign-top { 504 vertical-align: top; 505 } 506 th.tableblock.valign-middle, td.tableblock.valign-middle { 507 vertical-align: middle; 508 } 509 th.tableblock.valign-bottom, td.tableblock.valign-bottom { 510 vertical-align: bottom; 511 } 512 513 514 /* 515 * manpage specific 516 * 517 * */ 518 519 body.manpage h1 { 520 padding-top: 0.5em; 521 padding-bottom: 0.5em; 522 border-top: 2px solid silver; 523 border-bottom: 2px solid silver; 524 } 525 body.manpage h2 { 526 border-style: none; 527 } 528 body.manpage div.sectionbody { 529 margin-left: 3em; 530 } 531 532 @media print { 533 body.manpage div#toc { display: none; } 534 } 535 536 537 </style> 538 <script type="text/javascript"> 539 /*<![CDATA[*/ 540 var asciidoc = { // Namespace. 541 542 ///////////////////////////////////////////////////////////////////// 543 // Table Of Contents generator 544 ///////////////////////////////////////////////////////////////////// 545 546 /* Author: Mihai Bazon, September 2002 547 * http://students.infoiasi.ro/~mishoo 548 * 549 * Table Of Content generator 550 * Version: 0.4 551 * 552 * Feel free to use this script under the terms of the GNU General Public 553 * License, as long as you do not remove or alter this notice. 554 */ 555 556 /* modified by Troy D. Hanson, September 2006. License: GPL */ 557 /* modified by Stuart Rackham, 2006, 2009. License: GPL */ 558 559 // toclevels = 1..4. 560 toc: function (toclevels) { 561 562 function getText(el) { 563 var text = ""; 564 for (var i = el.firstChild; i != null; i = i.nextSibling) { 565 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants. 566 text += i.data; 567 else if (i.firstChild != null) 568 text += getText(i); 569 } 570 return text; 571 } 572 573 function TocEntry(el, text, toclevel) { 574 this.element = el; 575 this.text = text; 576 this.toclevel = toclevel; 577 } 578 579 function tocEntries(el, toclevels) { 580 var result = new Array; 581 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])'); 582 // Function that scans the DOM tree for header elements (the DOM2 583 // nodeIterator API would be a better technique but not supported by all 584 // browsers). 585 var iterate = function (el) { 586 for (var i = el.firstChild; i != null; i = i.nextSibling) { 587 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) { 588 var mo = re.exec(i.tagName); 589 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") { 590 result[result.length] = new TocEntry(i, getText(i), mo[1]-1); 591 } 592 iterate(i); 593 } 594 } 595 } 596 iterate(el); 597 return result; 598 } 599 600 var toc = document.getElementById("toc"); 601 if (!toc) { 602 return; 603 } 604 605 // Delete existing TOC entries in case we're reloading the TOC. 606 var tocEntriesToRemove = []; 607 var i; 608 for (i = 0; i < toc.childNodes.length; i++) { 609 var entry = toc.childNodes[i]; 610 if (entry.nodeName.toLowerCase() == 'div' 611 && entry.getAttribute("class") 612 && entry.getAttribute("class").match(/^toclevel/)) 613 tocEntriesToRemove.push(entry); 614 } 615 for (i = 0; i < tocEntriesToRemove.length; i++) { 616 toc.removeChild(tocEntriesToRemove[i]); 617 } 618 619 // Rebuild TOC entries. 620 var entries = tocEntries(document.getElementById("content"), toclevels); 621 for (var i = 0; i < entries.length; ++i) { 622 var entry = entries[i]; 623 if (entry.element.id == "") 624 entry.element.id = "_toc_" + i; 625 var a = document.createElement("a"); 626 a.href = "#" + entry.element.id; 627 a.appendChild(document.createTextNode(entry.text)); 628 var div = document.createElement("div"); 629 div.appendChild(a); 630 div.className = "toclevel" + entry.toclevel; 631 toc.appendChild(div); 632 } 633 if (entries.length == 0) 634 toc.parentNode.removeChild(toc); 635 }, 636 637 638 ///////////////////////////////////////////////////////////////////// 639 // Footnotes generator 640 ///////////////////////////////////////////////////////////////////// 641 642 /* Based on footnote generation code from: 643 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html 644 */ 645 646 footnotes: function () { 647 // Delete existing footnote entries in case we're reloading the footnodes. 648 var i; 649 var noteholder = document.getElementById("footnotes"); 650 if (!noteholder) { 651 return; 652 } 653 var entriesToRemove = []; 654 for (i = 0; i < noteholder.childNodes.length; i++) { 655 var entry = noteholder.childNodes[i]; 656 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote") 657 entriesToRemove.push(entry); 658 } 659 for (i = 0; i < entriesToRemove.length; i++) { 660 noteholder.removeChild(entriesToRemove[i]); 661 } 662 663 // Rebuild footnote entries. 664 var cont = document.getElementById("content"); 665 var spans = cont.getElementsByTagName("span"); 666 var refs = {}; 667 var n = 0; 668 for (i=0; i<spans.length; i++) { 669 if (spans[i].className == "footnote") { 670 n++; 671 var note = spans[i].getAttribute("data-note"); 672 if (!note) { 673 // Use [\s\S] in place of . so multi-line matches work. 674 // Because JavaScript has no s (dotall) regex flag. 675 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1]; 676 spans[i].innerHTML = 677 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n + 678 "' title='View footnote' class='footnote'>" + n + "</a>]"; 679 spans[i].setAttribute("data-note", note); 680 } 681 noteholder.innerHTML += 682 "<div class='footnote' id='_footnote_" + n + "'>" + 683 "<a href='#_footnoteref_" + n + "' title='Return to text'>" + 684 n + "</a>. " + note + "</div>"; 685 var id =spans[i].getAttribute("id"); 686 if (id != null) refs["#"+id] = n; 687 } 688 } 689 if (n == 0) 690 noteholder.parentNode.removeChild(noteholder); 691 else { 692 // Process footnoterefs. 693 for (i=0; i<spans.length; i++) { 694 if (spans[i].className == "footnoteref") { 695 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href"); 696 href = href.match(/#.*/)[0]; // Because IE return full URL. 697 n = refs[href]; 698 spans[i].innerHTML = 699 "[<a href='#_footnote_" + n + 700 "' title='View footnote' class='footnote'>" + n + "</a>]"; 701 } 702 } 703 } 704 }, 705 706 install: function(toclevels) { 707 var timerId; 708 709 function reinstall() { 710 asciidoc.footnotes(); 711 if (toclevels) { 712 asciidoc.toc(toclevels); 713 } 714 } 715 716 function reinstallAndRemoveTimer() { 717 clearInterval(timerId); 718 reinstall(); 719 } 720 721 timerId = setInterval(reinstall, 500); 722 if (document.addEventListener) 723 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false); 724 else 725 window.onload = reinstallAndRemoveTimer; 726 } 727 728 } 729 asciidoc.install(2); 730 /*]]>*/ 731 </script> 732 </head> 733 <body class="book"> 734 <div id="header"> 735 <h1>Vulkan on Android Implementor’s Guide</h1> 736 <span id="revnumber">version 5</span> 737 <div id="toc"> 738 <div id="toctitle">Table of Contents</div> 739 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript> 740 </div> 741 </div> 742 <div id="content"> 743 <div id="preamble"> 744 <div class="sectionbody"> 745 <div class="paragraph"><p>This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.</p></div> 746 </div> 747 </div> 748 <div class="sect1"> 749 <h2 id="_architecture">1. Architecture</h2> 750 <div class="sectionbody"> 751 <div class="paragraph"><p>The primary interface between Vulkan applications and a device’s Vulkan driver is the loader, which is part of AOSP and installed at <span class="monospaced">/system/lib[64]/libvulkan.so</span>. The loader provides the core Vulkan API entry points, as well as entry points of a few extensions that are required on Android and always present. In particular, the window system integration (WSI) extensions are exported by the loader and primarily implemented in it rather than the driver. The loader also supports enumerating and loading layers which can expose additional extensions and/or intercept core API calls on their way to the driver.</p></div> 752 <div class="paragraph"><p>The NDK will include a stub <span class="monospaced">libvulkan.so</span> exporting the same symbols as the loader. Calling the Vulkan functions exported from <span class="monospaced">libvulkan.so</span> will enter trampoline functions in the loader which will dispatch to the appropriate layer or driver based on their first argument. The <span class="monospaced">vkGet*ProcAddr</span> calls will return the function pointers that the trampolines would dispatch to, so calling through these function pointers rather than the exported symbols will be slightly more efficient since it skips the trampoline and dispatch.</p></div> 753 <div class="sect2"> 754 <h3 id="_driver_enumeration_and_loading">1.1. Driver Enumeration and Loading</h3> 755 <div class="paragraph"><p>Android expects the GPUs available to the system to be known when the system image is built, so its driver enumeration process isn’t as elaborate as on other platforms. The loader will use the existing HAL mechanism for discovering and loading the driver. As of this writing, the preferred paths for 32-bit and 64-bit Vulkan drivers are:</p></div> 756 <div class="literalblock"> 757 <div class="content monospaced"> 758 <pre>/vendor/lib/hw/vulkan.<ro.product.platform>.so 759 /vendor/lib64/hw/vulkan.<ro.product.platform>.so</pre> 760 </div></div> 761 <div class="paragraph"><p>where <span class="monospaced"><ro.product.platform></span> is replaced by the value of the system property of that name. See <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c">libhardware/hardware.c</a> for details and supported alternative locations.</p></div> 762 <div class="paragraph"><p>The Vulkan <span class="monospaced">hw_module_t</span> derivative is currently trivial. If support for multiple drivers is ever added, the HAL module will export a list of strings that can be passed to the module <span class="monospaced">open</span> call. For the time being, only one driver is supported, and the constant string <span class="monospaced">HWVULKAN_DEVICE_0</span> is passed to <span class="monospaced">open</span>.</p></div> 763 <div class="paragraph"><p>The Vulkan <span class="monospaced">hw_device_t</span> derivative corresponds to a single driver, though that driver can support multiple Vulkan physical devices. The <span class="monospaced">hw_device_t</span> structure contains a function pointer for the <span class="monospaced">vkGetInstanceProcAddr</span> function. The loader finds all other driver Vulkan functions by calling that <span class="monospaced">vkGetInstanceProcAddr</span> function.</p></div> 764 </div> 765 <div class="sect2"> 766 <h3 id="_layer_discovery_and_loading">1.2. Layer Discovery and Loading</h3> 767 <div class="paragraph"><p>Android’s security model and policies differ significantly from other platforms. In particular, Android does not allow loading external code into a non-debuggable process on production (non-rooted) devices, nor does it allow external code to inspect or control the process’s memory/state/etc. This includes a prohibition on saving core dumps, API traces, etc. to disk for later inspection. So only layers delivered as part of the application will be enabled on production devices, and drivers must also not provide functionality that violates these policies.</p></div> 768 <div class="paragraph"><p>There are three major use cases for layers:</p></div> 769 <div class="olist arabic"><ol class="arabic"> 770 <li> 771 <p> 772 Development-time layers: validation layers, shims for tracing/profiling/debugging tools, etc. These shouldn’t be installed on the system image of production devices: they would be a waste of space for most users, and they should be updateable without requiring a system update. A developer wishing to use one of these during development has the ability to modify their application package (e.g. adding a file to their native libraries directory). IHV and OEM engineers who are trying to diagnose failures in shipping, unmodifiable apps are assumed to have access to non-production (rooted) builds of the system image. 773 </p> 774 </li> 775 <li> 776 <p> 777 Utility layers, such as a layer that implements a heap for device memory. These layers will almost always expose extensions. Developers choose which layers, and which versions of those layers, to use in their application; different applications that use the same layer may still use different versions. Developers will choose which of these layers to ship in their application package. 778 </p> 779 </li> 780 <li> 781 <p> 782 Injected layers, like framerate, social network, or game launcher overlays, which are provided by the user or some other application without the application’s knowledge or consent. These violate Android’s security policies and will not be supported. 783 </p> 784 </li> 785 </ol></div> 786 <div class="paragraph"><p>In the normal state the loader will only search in the application’s normal library search path (as defined by the system ClassLoader) for layers. It will attempt to load any shared library named <span class="monospaced">libVkLayer_*.so</span> as a layer library. Android does not use manifests to describe layers: because layers must have been deliberately included in the application by the developer, the motivation for manifests on other platforms don’t apply.</p></div> 787 <div class="paragraph"><p>On debuggable devices (<span class="monospaced">ro.debuggable</span> property exists and is non-zero, generally rooted or engineering builds) the loader will also search the directory <span class="monospaced">/data/local/debug/vulkan</span> and attempt to load layer libraries it finds there. This directory doesn’t exist by default. On Android N and later, because this location is writable by adb, SELinux policies prevent mapping code located here as executable. So to use layers from here, SELinux enforcement must be disabled: <span class="monospaced">adb shell setenforce 0</span>. This mechanism is not intended for application developers, only for IHV and OEM engineers working on test devices that don’t have private or sensitive data.</p></div> 788 <div class="paragraph"><p>Our goal is to allow layers to be ported with only build-environment changes between Android and other platforms. For this to work, layers must properly implement things like <span class="monospaced">vkGetInstanceLayerProperties</span> and <span class="monospaced">vkGetInstanceExtensionProperties</span>, even though the LunarG loader doesn’t use them (it gets the information from manifests instead).</p></div> 789 </div> 790 </div> 791 </div> 792 <div class="sect1"> 793 <h2 id="_window_system_integration">2. Window System Integration</h2> 794 <div class="sectionbody"> 795 <div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver’s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div> 796 <div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div> 797 <div class="listingblock"> 798 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 799 by Lorenzo Bettini 800 http://www.lorenzobettini.it 801 http://www.gnu.org/software/src-highlite --> 802 <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">enum</span></span> VkSwapchainImageUsageFlagBitsANDROID <span style="color: #FF0000">{</span> 803 VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID <span style="color: #990000">=</span> <span style="color: #993399">0x00000001</span><span style="color: #990000">,</span> 804 VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span> 805 <span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span> 806 <span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div> 807 <div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div> 808 <div class="listingblock"> 809 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 810 by Lorenzo Bettini 811 http://www.lorenzobettini.it 812 http://www.gnu.org/software/src-highlite --> 813 <pre><tt>VKAPI_ATTR <span style="color: #008080">VkResult</span> <span style="color: #008080">VKAPI_CALL</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsage2ANDROID</span></span><span style="color: #990000">(</span> 814 <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span> 815 <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span> 816 <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span> 817 <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span> 818 uint64_t<span style="color: #990000">*</span> grallocConsumerUsage<span style="color: #990000">,</span> 819 uint64_t<span style="color: #990000">*</span> grallocProducerUsage<span style="color: #990000">,</span> 820 <span style="color: #990000">);</span></tt></pre></div></div> 821 <div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div> 822 <div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div> 823 <div class="listingblock"> 824 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 825 by Lorenzo Bettini 826 http://www.lorenzobettini.it 827 http://www.gnu.org/software/src-highlite --> 828 <pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span> 829 <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span> 830 <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span> 831 <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span> 832 <span style="color: #009900">int</span><span style="color: #990000">*</span> grallocUsage 833 <span style="color: #990000">);</span></tt></pre></div></div> 834 <div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div> 835 <div class="listingblock"> 836 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 837 by Lorenzo Bettini 838 http://www.lorenzobettini.it 839 http://www.gnu.org/software/src-highlite --> 840 <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span> 841 <span style="color: #008080">VkStructureType</span> sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID</span></span> 842 <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span> pNext<span style="color: #990000">;</span> 843 844 <span style="font-style: italic"><span style="color: #9A1900">// Buffer handle and stride returned from gralloc alloc()</span></span> 845 <span style="color: #008080">buffer_handle_t</span> handle<span style="color: #990000">;</span> 846 <span style="color: #009900">int</span> stride<span style="color: #990000">;</span> 847 848 <span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span> 849 <span style="color: #009900">int</span> format<span style="color: #990000">;</span> 850 <span style="color: #009900">int</span> usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span> 851 <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span> 852 <span style="color: #008080">uint64_t</span> consumer<span style="color: #990000">;</span> 853 <span style="color: #008080">uint64_t</span> producer<span style="color: #990000">;</span> 854 <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span> 855 <span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div> 856 <div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div> 857 <div class="listingblock"> 858 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 859 by Lorenzo Bettini 860 http://www.lorenzobettini.it 861 http://www.gnu.org/software/src-highlite --> 862 <pre><tt> .imageType = VK_IMAGE_TYPE_2D 863 .format = a VkFormat matching the format requested for the gralloc buffer 864 .extent = the 2D dimensions requested for the gralloc buffer 865 .mipLevels = 1 866 .arraySize = 1 867 .samples = 1 868 .tiling = VK_IMAGE_TILING_OPTIMAL 869 .usage = VkSwapChainCreateInfoWSI::imageUsageFlags 870 .flags = 0 871 .sharingMode = VkSwapChainCreateInfoWSI::sharingMode 872 .queueFamilyCount = VkSwapChainCreateInfoWSI::queueFamilyCount 873 .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices</tt></pre></div></div> 874 <div class="paragraph"><p>Additionally, when any swapchain image usage flags are required for the swapchain, the platform will provide a <span class="monospaced">VkSwapchainImageCreateInfoANDROID</span> extension structure in the <span class="monospaced">VkImageCreateInfo</span> chain provided to <span class="monospaced">vkCreateImage</span>, containing the swapchain image usage flags:</p></div> 875 <div class="listingblock"> 876 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 877 by Lorenzo Bettini 878 http://www.lorenzobettini.it 879 http://www.gnu.org/software/src-highlite --> 880 <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span> 881 <span style="color: #008080">VkStructureType</span> sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID</span></span> 882 <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span> pNext<span style="color: #990000">;</span> 883 884 <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> usage<span style="color: #990000">;</span> 885 <span style="color: #FF0000">}</span> VkSwapchainImageCreateInfoANDROID<span style="color: #990000">;</span></tt></pre></div></div> 886 <div class="paragraph"><p><span class="monospaced">vkAcquireImageANDROID</span> acquires ownership of a swapchain image and imports an 887 externally-signalled native fence into both an existing VkSemaphore object 888 and an existing VkFence object:</p></div> 889 <div class="listingblock"> 890 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 891 by Lorenzo Bettini 892 http://www.lorenzobettini.it 893 http://www.gnu.org/software/src-highlite --> 894 <pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkAcquireImageANDROID</span></span><span style="color: #990000">(</span> 895 <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span> 896 <span style="color: #008080">VkImage</span> image<span style="color: #990000">,</span> 897 <span style="color: #009900">int</span> nativeFenceFd<span style="color: #990000">,</span> 898 <span style="color: #008080">VkSemaphore</span> semaphore<span style="color: #990000">,</span> 899 VkFence fence 900 <span style="color: #990000">);</span></tt></pre></div></div> 901 <div class="paragraph"><p>This function is called during <span class="monospaced">vkAcquireNextImageWSI</span> to import a native 902 fence into the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> objects provided by the 903 application. Both semaphore and fence objects are optional in this call. The 904 driver may also use this opportunity to recognize and handle any external 905 changes to the gralloc buffer state; many drivers won’t need to do anything 906 here. This call puts the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> into the same "pending" 907 state as <span class="monospaced">vkQueueSignalSemaphore</span> and <span class="monospaced">vkQueueSubmit</span> respectively, so queues 908 can wait on the semaphore and the application can wait on the fence. Both 909 objects become signalled when the underlying native fence signals; if the 910 native fence has already signalled, then the semaphore will be in the signalled 911 state when this function returns. The driver takes ownership of the fence fd 912 and is responsible for closing it when no longer needed. It must do so even if 913 neither a semaphore or fence object is provided, or even if 914 <span class="monospaced">vkAcquireImageANDROID</span> fails and returns an error. If <span class="monospaced">fenceFd</span> is -1, it 915 is as if the native fence was already signalled.</p></div> 916 <div class="paragraph"><p><span class="monospaced">vkQueueSignalReleaseImageANDROID</span> prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.</p></div> 917 <div class="listingblock"> 918 <div class="content"><!-- Generator: GNU source-highlight 3.1.6 919 by Lorenzo Bettini 920 http://www.lorenzobettini.it 921 http://www.gnu.org/software/src-highlite --> 922 <pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkQueueSignalReleaseImageANDROID</span></span><span style="color: #990000">(</span> 923 <span style="color: #008080">VkQueue</span> queue<span style="color: #990000">,</span> 924 <span style="color: #008080">uint32_t</span> waitSemaphoreCount<span style="color: #990000">,</span> 925 <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> VkSemaphore<span style="color: #990000">*</span> pWaitSemaphores<span style="color: #990000">,</span> 926 <span style="color: #008080">VkImage</span> image<span style="color: #990000">,</span> 927 <span style="color: #009900">int</span><span style="color: #990000">*</span> pNativeFenceFd 928 <span style="color: #990000">);</span></tt></pre></div></div> 929 <div class="paragraph"><p>This will be called during <span class="monospaced">vkQueuePresentWSI</span> on the provided queue. Effects are similar to <span class="monospaced">vkQueueSignalSemaphore</span>, except with a native fence instead of a semaphore. The native fence must: not signal until the <span class="monospaced">waitSemaphoreCount</span> semaphores in <span class="monospaced">pWaitSemaphores</span> have signaled. Unlike <span class="monospaced">vkQueueSignalSemaphore</span>, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set <span class="monospaced">*pNativeFenceFd</span> to -1. The file descriptor returned in <span class="monospaced">*pNativeFenceFd</span> is owned and will be closed by the caller. Many drivers will be able to ignore the <span class="monospaced">image</span> parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to <span class="monospaced">VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</span>.</p></div> 930 <div class="paragraph"><p>If <span class="monospaced">image</span> was created with <span class="monospaced">VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID</span>, then the driver must tolerate <span class="monospaced">vkQueueSignalReleaseImageANDROID</span> being called repeatedly without intervening calls to <span class="monospaced">vkAcquireImageANDROID</span>.</p></div> 931 </div> 932 </div> 933 <div class="sect1"> 934 <h2 id="_history">3. History</h2> 935 <div class="sectionbody"> 936 <div class="olist arabic"><ol class="arabic"> 937 <li> 938 <p> 939 <strong>2015-07-08</strong> Initial version 940 </p> 941 </li> 942 <li> 943 <p> 944 <strong>2015-08-16</strong> 945 </p> 946 <div class="ulist"><ul> 947 <li> 948 <p> 949 Renamed to Implementor’s Guide 950 </p> 951 </li> 952 <li> 953 <p> 954 Wording and formatting changes 955 </p> 956 </li> 957 <li> 958 <p> 959 Updated based on resolution of Khronos bug 14265 960 </p> 961 </li> 962 <li> 963 <p> 964 Deferred support for multiple drivers 965 </p> 966 </li> 967 </ul></div> 968 </li> 969 <li> 970 <p> 971 <strong>2015-11-04</strong> 972 </p> 973 <div class="ulist"><ul> 974 <li> 975 <p> 976 Added vkGetSwapchainGrallocUsageANDROID 977 </p> 978 </li> 979 <li> 980 <p> 981 Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID 982 with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow 983 drivers to known the ownership state of swapchain images. 984 </p> 985 </li> 986 </ul></div> 987 </li> 988 <li> 989 <p> 990 <strong>2015-12-03</strong> 991 </p> 992 <div class="ulist"><ul> 993 <li> 994 <p> 995 Added a VkFence parameter to vkAcquireImageANDROID corresponding to the 996 parameter added to vkAcquireNextImageKHR. 997 </p> 998 </li> 999 </ul></div> 1000 </li> 1001 <li> 1002 <p> 1003 <strong>2016-01-08</strong> 1004 </p> 1005 <div class="ulist"><ul> 1006 <li> 1007 <p> 1008 Added waitSemaphoreCount and pWaitSemaphores parameters to vkQueueSignalReleaseImageANDROID. 1009 </p> 1010 </li> 1011 </ul></div> 1012 </li> 1013 <li> 1014 <p> 1015 <strong>2016-06-17</strong> 1016 </p> 1017 <div class="ulist"><ul> 1018 <li> 1019 <p> 1020 Updates to reflect final behavior, closed some TBDs now that they’ve BDed. 1021 </p> 1022 </li> 1023 </ul></div> 1024 </li> 1025 <li> 1026 <p> 1027 <strong>2017-01-06</strong> 1028 </p> 1029 <div class="ulist"><ul> 1030 <li> 1031 <p> 1032 Extension version 6 1033 </p> 1034 </li> 1035 <li> 1036 <p> 1037 Added VkSwapchainImageUsageFlagBitsANDROID 1038 </p> 1039 </li> 1040 <li> 1041 <p> 1042 Added vkGetSwapchainGrallocUsage2ANDROID 1043 </p> 1044 </li> 1045 <li> 1046 <p> 1047 Added VkSwapchainImageCreateInfoANDROID 1048 </p> 1049 </li> 1050 </ul></div> 1051 </li> 1052 <li> 1053 <p> 1054 <strong>2017-02-09</strong> 1055 </p> 1056 <div class="ulist"><ul> 1057 <li> 1058 <p> 1059 Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields. 1060 </p> 1061 </li> 1062 </ul></div> 1063 </li> 1064 </ol></div> 1065 </div> 1066 </div> 1067 </div> 1068 <div id="footnotes"><hr></div> 1069 <div id="footer"> 1070 <div id="footer-text"> 1071 Version 5<br> 1072 Last updated 2017-02-09 22:40:30 PST 1073 </div> 1074 </div> 1075 </body> 1076 </html> 1077