diff --git a/docs/html/annotated.html b/docs/html/annotated.html new file mode 100644 index 0000000..3e5adda --- /dev/null +++ b/docs/html/annotated.html @@ -0,0 +1,81 @@ + + + + + + + +Vulkan Memory Allocator: Class List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+ + + + + +
 CVmaAllocatorCreateInfoDescription of a Allocator to be created
 CVmaMemoryRequirements
 CVmaStatInfo
 CVmaStatsGeneral statistics from current state of Allocator
+
+
+ + + + diff --git a/docs/html/bc_s.png b/docs/html/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/docs/html/bc_s.png differ diff --git a/docs/html/bdwn.png b/docs/html/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/docs/html/bdwn.png differ diff --git a/docs/html/classes.html b/docs/html/classes.html new file mode 100644 index 0000000..fb0f1ec --- /dev/null +++ b/docs/html/classes.html @@ -0,0 +1,82 @@ + + + + + + + +Vulkan Memory Allocator: Class Index + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
v
+ + + + + +
  v  
+
VmaMemoryRequirements   VmaStats   
VmaStatInfo   
VmaAllocatorCreateInfo   
+
v
+
+ + + + diff --git a/docs/html/closed.png b/docs/html/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/docs/html/closed.png differ diff --git a/docs/html/doc.png b/docs/html/doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/docs/html/doc.png differ diff --git a/docs/html/doxygen.css b/docs/html/doxygen.css new file mode 100644 index 0000000..4f1ab91 --- /dev/null +++ b/docs/html/doxygen.css @@ -0,0 +1,1596 @@ +/* The standard CSS for doxygen 1.8.13 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + + +/* @end */ diff --git a/docs/html/doxygen.png b/docs/html/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/docs/html/doxygen.png differ diff --git a/docs/html/dynsections.js b/docs/html/dynsections.js new file mode 100644 index 0000000..85e1836 --- /dev/null +++ b/docs/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +Vulkan Memory Allocator: File List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+ + +
 vk_mem_alloc.h
+
+
+ + + + diff --git a/docs/html/folderclosed.png b/docs/html/folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/docs/html/folderclosed.png differ diff --git a/docs/html/folderopen.png b/docs/html/folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/docs/html/folderopen.png differ diff --git a/docs/html/functions.html b/docs/html/functions.html new file mode 100644 index 0000000..89c1389 --- /dev/null +++ b/docs/html/functions.html @@ -0,0 +1,143 @@ + + + + + + + +Vulkan Memory Allocator: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+
+ + + + diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html new file mode 100644 index 0000000..861f8e1 --- /dev/null +++ b/docs/html/functions_vars.html @@ -0,0 +1,143 @@ + + + + + + + +Vulkan Memory Allocator: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/globals.html b/docs/html/globals.html new file mode 100644 index 0000000..bb6f645 --- /dev/null +++ b/docs/html/globals.html @@ -0,0 +1,163 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- v -

+
+ + + + diff --git a/docs/html/globals_defs.html b/docs/html/globals_defs.html new file mode 100644 index 0000000..2a81e7d --- /dev/null +++ b/docs/html/globals_defs.html @@ -0,0 +1,74 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/globals_enum.html b/docs/html/globals_enum.html new file mode 100644 index 0000000..f2866f6 --- /dev/null +++ b/docs/html/globals_enum.html @@ -0,0 +1,74 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/globals_eval.html b/docs/html/globals_eval.html new file mode 100644 index 0000000..134a524 --- /dev/null +++ b/docs/html/globals_eval.html @@ -0,0 +1,89 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/globals_func.html b/docs/html/globals_func.html new file mode 100644 index 0000000..4170d1e --- /dev/null +++ b/docs/html/globals_func.html @@ -0,0 +1,128 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/globals_type.html b/docs/html/globals_type.html new file mode 100644 index 0000000..516865d --- /dev/null +++ b/docs/html/globals_type.html @@ -0,0 +1,83 @@ + + + + + + + +Vulkan Memory Allocator: File Members + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/docs/html/group__general.html b/docs/html/group__general.html new file mode 100644 index 0000000..b2da17d --- /dev/null +++ b/docs/html/group__general.html @@ -0,0 +1,420 @@ + + + + + + + +Vulkan Memory Allocator: General + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+ +
+
General
+
+
+ + + + + + + + + + +

+Classes

struct  VmaAllocatorCreateInfo
 Description of a Allocator to be created. More...
 
struct  VmaStatInfo
 
struct  VmaStats
 General statistics from current state of Allocator. More...
 
+ + + +

+Macros

#define VMA_STATS_STRING_ENABLED   1
 
+ + + + + + +

+Typedefs

typedef struct VmaAllocatorCreateInfo VmaAllocatorCreateInfo
 Description of a Allocator to be created. More...
 
typedef struct VmaStatInfo VmaStatInfo
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Functions

VkResult vmaCreateAllocator (const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
 Creates Allocator object. More...
 
void vmaDestroyAllocator (VmaAllocator allocator)
 Destroys allocator object. More...
 
void vmaGetPhysicalDeviceProperties (VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)
 
void vmaGetMemoryProperties (VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties **ppPhysicalDeviceMemoryProperties)
 
void vmaGetMemoryTypeProperties (VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags *pFlags)
 Given Memory Type Index, returns Property Flags of this memory type. More...
 
void vmaCalculateStats (VmaAllocator allocator, VmaStats *pStats)
 Retrieves statistics from current state of the Allocator. More...
 
void vmaBuildStatsString (VmaAllocator allocator, char **ppStatsString, VkBool32 detailedMap)
 Builds and returns statistics as string in JSON format. More...
 
void vmaFreeStatsString (VmaAllocator allocator, char *pStatsString)
 
+

Detailed Description

+

Macro Definition Documentation

+ +

◆ VMA_STATS_STRING_ENABLED

+ +
+
+ + + + +
#define VMA_STATS_STRING_ENABLED   1
+
+ +
+
+

Typedef Documentation

+ +

◆ VmaAllocatorCreateInfo

+ +
+
+ +

Description of a Allocator to be created.

+ +
+
+ +

◆ VmaStatInfo

+ +
+
+ + + + +
typedef struct VmaStatInfo VmaStatInfo
+
+ +
+
+

Function Documentation

+ +

◆ vmaBuildStatsString()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void vmaBuildStatsString (VmaAllocator allocator,
char ** ppStatsString,
VkBool32 detailedMap 
)
+
+ +

Builds and returns statistics as string in JSON format.

+
Parameters
+ + +
[out]ppStatsStringMust be freed using vmaFreeStatsString() function.
+
+
+ +
+
+ +

◆ vmaCalculateStats()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaCalculateStats (VmaAllocator allocator,
VmaStatspStats 
)
+
+ +

Retrieves statistics from current state of the Allocator.

+ +
+
+ +

◆ vmaCreateAllocator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
VkResult vmaCreateAllocator (const VmaAllocatorCreateInfopCreateInfo,
VmaAllocator * pAllocator 
)
+
+ +

Creates Allocator object.

+ +
+
+ +

◆ vmaDestroyAllocator()

+ +
+
+ + + + + + + + +
void vmaDestroyAllocator (VmaAllocator allocator)
+
+ +

Destroys allocator object.

+ +
+
+ +

◆ vmaFreeStatsString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaFreeStatsString (VmaAllocator allocator,
char * pStatsString 
)
+
+ +
+
+ +

◆ vmaGetMemoryProperties()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaGetMemoryProperties (VmaAllocator allocator,
const VkPhysicalDeviceMemoryProperties ** ppPhysicalDeviceMemoryProperties 
)
+
+

PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own.

+ +
+
+ +

◆ vmaGetMemoryTypeProperties()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void vmaGetMemoryTypeProperties (VmaAllocator allocator,
uint32_t memoryTypeIndex,
VkMemoryPropertyFlags * pFlags 
)
+
+ +

Given Memory Type Index, returns Property Flags of this memory type.

+

This is just a convenience function. Same information can be obtained using vmaGetMemoryProperties().

+ +
+
+ +

◆ vmaGetPhysicalDeviceProperties()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaGetPhysicalDeviceProperties (VmaAllocator allocator,
const VkPhysicalDeviceProperties ** ppPhysicalDeviceProperties 
)
+
+

PhysicalDeviceProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own.

+ +
+
+
+ + + + diff --git a/docs/html/group__layer1.html b/docs/html/group__layer1.html new file mode 100644 index 0000000..b27b4a0 --- /dev/null +++ b/docs/html/group__layer1.html @@ -0,0 +1,217 @@ + + + + + + + +Vulkan Memory Allocator: Layer 1 Choosing Memory Type + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+ +
+
Layer 1 Choosing Memory Type
+
+
+ + + + +

+Classes

struct  VmaMemoryRequirements
 
+ + + + + +

+Typedefs

typedef enum VmaMemoryUsage VmaMemoryUsage
 
typedef struct VmaMemoryRequirements VmaMemoryRequirements
 
+ + + +

+Enumerations

enum  VmaMemoryUsage {
+  VMA_MEMORY_USAGE_UNKNOWN = 0, +VMA_MEMORY_USAGE_GPU_ONLY = 1, +VMA_MEMORY_USAGE_CPU_ONLY = 2, +VMA_MEMORY_USAGE_CPU_TO_GPU = 3, +
+  VMA_MEMORY_USAGE_GPU_TO_CPU = 4, +VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF +
+ }
 
+ + + +

+Functions

VkResult vmaFindMemoryTypeIndex (VmaAllocator allocator, uint32_t memoryTypeBits, const VmaMemoryRequirements *pMemoryRequirements, uint32_t *pMemoryTypeIndex)
 
+

Detailed Description

+

Typedef Documentation

+ +

◆ VmaMemoryRequirements

+ +
+
+ + + + +
typedef struct VmaMemoryRequirements VmaMemoryRequirements
+
+ +
+
+ +

◆ VmaMemoryUsage

+ +
+
+ + + + +
typedef enum VmaMemoryUsage VmaMemoryUsage
+
+ +
+
+

Enumeration Type Documentation

+ +

◆ VmaMemoryUsage

+ +
+
+ + + + +
enum VmaMemoryUsage
+
+ + + + + + + +
Enumerator
VMA_MEMORY_USAGE_UNKNOWN 

No intended memory usage specified.

+
VMA_MEMORY_USAGE_GPU_ONLY 

Memory will be used on device only, no need to be mapped on host.

+
VMA_MEMORY_USAGE_CPU_ONLY 

Memory will be mapped on host. Could be used for transfer to device.

+
VMA_MEMORY_USAGE_CPU_TO_GPU 

Memory will be used for frequent (dynamic) updates from host and reads on device.

+
VMA_MEMORY_USAGE_GPU_TO_CPU 

Memory will be used for writing on device and readback on host.

+
VMA_MEMORY_USAGE_MAX_ENUM 
+ +
+
+

Function Documentation

+ +

◆ vmaFindMemoryTypeIndex()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaFindMemoryTypeIndex (VmaAllocator allocator,
uint32_t memoryTypeBits,
const VmaMemoryRequirementspMemoryRequirements,
uint32_t * pMemoryTypeIndex 
)
+
+

This algorithm tries to find a memory type that:

+
    +
  • Is allowed by memoryTypeBits.
  • +
  • Contains all the flags from pMemoryRequirements->requiredFlags.
  • +
  • Matches intended usage.
  • +
  • Has as many flags from pMemoryRequirements->preferredFlags as possible.
  • +
+
Returns
Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result from this function or any other allocating function probably means that your device doesn't support any memory type with requested features for the specific type of resource you want to use it for. Please check parameters of your resource, like image layout (OPTIMAL versus LINEAR) or mip level count.
+ +
+
+
+ + + + diff --git a/docs/html/group__layer2.html b/docs/html/group__layer2.html new file mode 100644 index 0000000..18ab2b6 --- /dev/null +++ b/docs/html/group__layer2.html @@ -0,0 +1,349 @@ + + + + + + + +Vulkan Memory Allocator: Layer 2 Allocating Memory + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+ +
+
Layer 2 Allocating Memory
+
+
+ + + + + + + + + + + + + + + + + +

+Functions

VkResult vmaAllocateMemory (VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const VmaMemoryRequirements *pVmaMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 General purpose memory allocation. More...
 
VkResult vmaAllocateMemoryForBuffer (VmaAllocator allocator, VkBuffer buffer, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 
VkResult vmaAllocateMemoryForImage (VmaAllocator allocator, VkImage image, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 Function similar to vmaAllocateMemoryForBuffer(). More...
 
void vmaFreeMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
 Frees memory previously allocated using vmaAllocateMemoryForBuffer() or vmaAllocateMemoryForImage(). More...
 
VkResult vmaMapMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory, void **ppData)
 
void vmaUnmapMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
 
+

Detailed Description

+

Function Documentation

+ +

◆ vmaAllocateMemory()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaAllocateMemory (VmaAllocator allocator,
const VkMemoryRequirements * pVkMemoryRequirements,
const VmaMemoryRequirementspVmaMemoryRequirements,
VkMappedMemoryRange * pMemory,
uint32_t * pMemoryTypeIndex 
)
+
+ +

General purpose memory allocation.

+
Parameters
+ + + +
[out]pMemoryAllocated memory.
[out]pMemoryTypeIndexOptional. Index of memory type that has been chosen for this allocation.
+
+
+

You should free the memory using vmaFreeMemory().

+

All allocated memory is also automatically freed in vmaDestroyAllocator().

+

It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(), vmaCreateBuffer(), vmaCreateImage() instead whenever possible.

+ +
+
+ +

◆ vmaAllocateMemoryForBuffer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaAllocateMemoryForBuffer (VmaAllocator allocator,
VkBuffer buffer,
const VmaMemoryRequirementspMemoryRequirements,
VkMappedMemoryRange * pMemory,
uint32_t * pMemoryTypeIndex 
)
+
+
Parameters
+ + +
[out]pMemoryTypeIndexOptional. Pass null if you don't need this information.
+
+
+

You should free the memory using vmaFreeMemory().

+

All allocated memory is also automatically freed in vmaDestroyAllocator().

+ +
+
+ +

◆ vmaAllocateMemoryForImage()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaAllocateMemoryForImage (VmaAllocator allocator,
VkImage image,
const VmaMemoryRequirementspMemoryRequirements,
VkMappedMemoryRange * pMemory,
uint32_t * pMemoryTypeIndex 
)
+
+ +

Function similar to vmaAllocateMemoryForBuffer().

+ +
+
+ +

◆ vmaFreeMemory()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaFreeMemory (VmaAllocator allocator,
const VkMappedMemoryRange * pMemory 
)
+
+ +

Frees memory previously allocated using vmaAllocateMemoryForBuffer() or vmaAllocateMemoryForImage().

+ +
+
+ +

◆ vmaMapMemory()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaMapMemory (VmaAllocator allocator,
const VkMappedMemoryRange * pMemory,
void ** ppData 
)
+
+

Feel free to use vkMapMemory on these memory blocks on you own if you want, but just for convenience and to make sure correct offset and size is always specified, usage of vmaMapMemory() / vmaUnmapMemory() is recommended.

+ +
+
+ +

◆ vmaUnmapMemory()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaUnmapMemory (VmaAllocator allocator,
const VkMappedMemoryRange * pMemory 
)
+
+ +
+
+
+ + + + diff --git a/docs/html/group__layer3.html b/docs/html/group__layer3.html new file mode 100644 index 0000000..854b6e2 --- /dev/null +++ b/docs/html/group__layer3.html @@ -0,0 +1,267 @@ + + + + + + + +Vulkan Memory Allocator: Layer 3 Creating Buffers and Images + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+ +
+
Layer 3 Creating Buffers and Images
+
+
+ + + + + + + + + + + +

+Functions

VkResult vmaCreateBuffer (VmaAllocator allocator, const VkBufferCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkBuffer *pBuffer, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 
void vmaDestroyBuffer (VmaAllocator allocator, VkBuffer buffer)
 
VkResult vmaCreateImage (VmaAllocator allocator, const VkImageCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkImage *pImage, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 Function similar to vmaCreateBuffer(). More...
 
void vmaDestroyImage (VmaAllocator allocator, VkImage image)
 
+

Detailed Description

+

Function Documentation

+ +

◆ vmaCreateBuffer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaCreateBuffer (VmaAllocator allocator,
const VkBufferCreateInfo * pCreateInfo,
const VmaMemoryRequirementspMemoryRequirements,
VkBuffer * pBuffer,
VkMappedMemoryRange * pMemory,
uint32_t * pMemoryTypeIndex 
)
+
+
Parameters
+ + + +
[out]pMemoryOptional. Pass null if you don't need this information.
[out]pMemoryTypeIndexOptional. Pass null if you don't need this information.
+
+
+

This function automatically:

+
    +
  1. Creates buffer/image.
  2. +
  3. Allocates appropriate memory for it.
  4. +
  5. Binds the buffer/image with the memory.
  6. +
+

You do not (and should not) pass returned pMemory to vmaFreeMemory. Only calling vmaDestroyBuffer() / vmaDestroyImage() is required for objects created using vmaCreateBuffer() / vmaCreateImage().

+

All allocated buffers and images are also automatically destroyed in vmaDestroyAllocator(), along with their memory allocations.

+ +
+
+ +

◆ vmaCreateImage()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VkResult vmaCreateImage (VmaAllocator allocator,
const VkImageCreateInfo * pCreateInfo,
const VmaMemoryRequirementspMemoryRequirements,
VkImage * pImage,
VkMappedMemoryRange * pMemory,
uint32_t * pMemoryTypeIndex 
)
+
+ +

Function similar to vmaCreateBuffer().

+ +
+
+ +

◆ vmaDestroyBuffer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaDestroyBuffer (VmaAllocator allocator,
VkBuffer buffer 
)
+
+ +
+
+ +

◆ vmaDestroyImage()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void vmaDestroyImage (VmaAllocator allocator,
VkImage image 
)
+
+ +
+
+
+ + + + diff --git a/docs/html/index.html b/docs/html/index.html new file mode 100644 index 0000000..447953c --- /dev/null +++ b/docs/html/index.html @@ -0,0 +1,154 @@ + + + + + + + +Vulkan Memory Allocator: Vulkan Memory Allocator + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Vulkan Memory Allocator
+
+
+

Version 1.0, 2017-05-10

+

Members grouped: see Modules.

+

All members: see vk_mem_alloc.h.

+

+Problem Statement

+

Memory allocation and resource (buffer and image) creation in Vulkan is difficult (comparing to older graphics API-s, like D3D11 or OpenGL) for several reasons:

+
    +
  • It requires a lot of boilerplate code, just like everything else in Vulkan, because it is a low-level and high-performance API.
  • +
  • There is additional level of indirection: VkDeviceMemory is allocated separately from creating VkBuffer/VkImage and they must be bound together. The binding cannot be changed later - resource must be recreated.
  • +
  • Driver must be queried for supported memory heaps and memory types. Different IHV-s provide different types of it.
  • +
  • Resources that don't fit in VRAM are not automatically evicted to RAM. Developer must handle out-of-memory errors on his own.
  • +
  • It is recommended practice to allocate bigger chunks of memory and assign parts of them to particular resources.
  • +
+

+Features

+

This library is helps game developers to manage memory allocations and resource creation by offering some higher-level functions. Features of the library could be divided into several layers, low level to high level:

+
    +
  1. Functions that help to choose correct and optimal memory type based on intended usage of the memory.
      +
    • Required or preferred traits of the memory are expressed using higher-level description comparing to Vulkan flags.
    • +
    +
  2. +
  3. Functions that allocate memory blocks, reserve and return parts of them (VkDeviceMemory + offset + size) to the user.
      +
    • Library keeps track of allocated memory blocks, used and unused ranges inside them, finds best matching unused ranges for new allocations, takes all the rules of alignment into consideration.
    • +
    +
  4. +
  5. Functions that can create an image/buffer, allocate memory for it and bind them together - all in one call.
  6. +
+

+Prequisites

+
    +
  • Self-contained C++ library in single header file. No external dependencies other than standard C and C++ library and of course Vulkan.
  • +
  • Public interface in C, in same convention as Vulkan API. Implementation in C++.
  • +
  • Interface documented using Doxygen-style comments.
  • +
  • Platform-independent, but developed and tested on Windows using Visual Studio.
  • +
  • Error handling implemented by returning VkResult error codes - same way as in Vulkan.
  • +
+

+Quick Start

+

In your project code:

+
    +
  1. Include "vk_mem_alloc.h" file wherever you want to use the library.
  2. +
  3. In exacly one C++ file define following macro before include to build library implementation.
  4. +
+
#define VMA_IMPLEMENTATION
+#include "vk_mem_alloc.h"
+

At program startup:

+
    +
  1. Initialize Vulkan to have VkPhysicalDevice and VkDevice object.
  2. +
  3. Fill VmaAllocatorCreateInfo structure and create VmaAllocator object by calling vmaCreateAllocator().
  4. +
+
VmaAllocatorCreateInfo allocatorInfo = {};
+allocatorInfo.physicalDevice = physicalDevice;
+allocatorInfo.device = device;
+
+VmaAllocator allocator;
+vmaCreateAllocator(&allocatorInfo, &allocator);
+

When you want to create a buffer or image:

+
    +
  1. Fill VkBufferCreateInfo / VkImageCreateInfo structure.
  2. +
  3. Fill VmaMemoryRequirements structure.
  4. +
  5. Call vmaCreateBuffer() / vmaCreateImage() to get VkBuffer/VkImage with memory already allocated and bound to it.
  6. +
+
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+bufferInfo.size = myBufferSize;
+bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+
+VmaMemoryRequirements memReq = {};
+memReq.usage = VMA_MEMORY_USAGE_GPU_ONLY;
+
+VkBuffer buffer;
+vmaCreateBuffer(allocator, &bufferInfo, &memReq, &buffer, nullptr, nullptr);
+

+Configuration

+

Set VMA_STATS_STRING_ENABLED macro in vk_mem_alloc.h to 0 or 1 to disable/enable compilation of code for dumping internal allocator state to string in JSON format.

+

Please check "CONFIGURATION" section in vk_mem_alloc.cpp file to find macros and other definitions that you can change to connect the library to your own implementation of basic facilities like assert, min and max functions, mutex etc. C++ STL is used by default, but changing these allows you to get rid of any STL usage if you want, as many game developers tend to do.

+

+Custom memory allocator

+

You can use custom memory allocator by filling optional member VmaAllocatorCreateInfo::pAllocationCallbacks. These functions will be passed to Vulkan, as well as used by the library itself to make any CPU-side allocations.

+

+Thread safety

+

All calls to functions that take VmaAllocator as first parameter are safe to call from multiple threads simultaneously, synchronized internally when needed.

+
+ + + + diff --git a/docs/html/jquery.js b/docs/html/jquery.js new file mode 100644 index 0000000..f5343ed --- /dev/null +++ b/docs/html/jquery.js @@ -0,0 +1,87 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + +
+
+
Modules
+
+
+
Here is a list of all modules:
+
+ + + + +
 General
 Layer 1 Choosing Memory Type
 Layer 2 Allocating Memory
 Layer 3 Creating Buffers and Images
+ + + + + + diff --git a/docs/html/nav_f.png b/docs/html/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/docs/html/nav_f.png differ diff --git a/docs/html/nav_g.png b/docs/html/nav_g.png new file mode 100644 index 0000000..2093a23 Binary files /dev/null and b/docs/html/nav_g.png differ diff --git a/docs/html/nav_h.png b/docs/html/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/docs/html/nav_h.png differ diff --git a/docs/html/open.png b/docs/html/open.png new file mode 100644 index 0000000..30f75c7 Binary files /dev/null and b/docs/html/open.png differ diff --git a/docs/html/search/all_0.html b/docs/html/search/all_0.html new file mode 100644 index 0000000..f25360b --- /dev/null +++ b/docs/html/search/all_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js new file mode 100644 index 0000000..e5008cc --- /dev/null +++ b/docs/html/search/all_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['allocationcount',['AllocationCount',['../struct_vma_stat_info.html#a240402222ac6777e4079653c5d542cb0',1,'VmaStatInfo']]] +]; diff --git a/docs/html/search/all_1.html b/docs/html/search/all_1.html new file mode 100644 index 0000000..b13f0f7 --- /dev/null +++ b/docs/html/search/all_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js new file mode 100644 index 0000000..b72b6f4 --- /dev/null +++ b/docs/html/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['device',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo']]] +]; diff --git a/docs/html/search/all_2.html b/docs/html/search/all_2.html new file mode 100644 index 0000000..9543c57 --- /dev/null +++ b/docs/html/search/all_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js new file mode 100644 index 0000000..025ecae --- /dev/null +++ b/docs/html/search/all_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['general',['General',['../group__general.html',1,'']]] +]; diff --git a/docs/html/search/all_3.html b/docs/html/search/all_3.html new file mode 100644 index 0000000..03405c0 --- /dev/null +++ b/docs/html/search/all_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js new file mode 100644 index 0000000..058f893 --- /dev/null +++ b/docs/html/search/all_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['layer_201_20choosing_20memory_20type',['Layer 1 Choosing Memory Type',['../group__layer1.html',1,'']]], + ['layer_202_20allocating_20memory',['Layer 2 Allocating Memory',['../group__layer2.html',1,'']]], + ['layer_203_20creating_20buffers_20and_20images',['Layer 3 Creating Buffers and Images',['../group__layer3.html',1,'']]] +]; diff --git a/docs/html/search/all_4.html b/docs/html/search/all_4.html new file mode 100644 index 0000000..8e1f4b9 --- /dev/null +++ b/docs/html/search/all_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js new file mode 100644 index 0000000..5b8d8f2 --- /dev/null +++ b/docs/html/search/all_4.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['memoryheap',['memoryHeap',['../struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0',1,'VmaStats']]], + ['memorytype',['memoryType',['../struct_vma_stats.html#a13e3caf754be79352c42408756309331',1,'VmaStats']]] +]; diff --git a/docs/html/search/all_5.html b/docs/html/search/all_5.html new file mode 100644 index 0000000..89a879e --- /dev/null +++ b/docs/html/search/all_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js new file mode 100644 index 0000000..523d148 --- /dev/null +++ b/docs/html/search/all_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['neverallocate',['neverAllocate',['../struct_vma_memory_requirements.html#a2259df9db140839199fa43b651c58447',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/all_6.html b/docs/html/search/all_6.html new file mode 100644 index 0000000..6afac06 --- /dev/null +++ b/docs/html/search/all_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js new file mode 100644 index 0000000..44a7a9b --- /dev/null +++ b/docs/html/search/all_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ownmemory',['ownMemory',['../struct_vma_memory_requirements.html#a401cdf684f8a13c8ff3bb469a1759153',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/all_7.html b/docs/html/search/all_7.html new file mode 100644 index 0000000..de19107 --- /dev/null +++ b/docs/html/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js new file mode 100644 index 0000000..a6df7a8 --- /dev/null +++ b/docs/html/search/all_7.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['pallocationcallbacks',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo']]], + ['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]], + ['preferredflags',['preferredFlags',['../struct_vma_memory_requirements.html#a6e105f836c2288034c711815b18226dc',1,'VmaMemoryRequirements']]], + ['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]], + ['preferredsmallheapblocksize',['preferredSmallHeapBlockSize',['../struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a',1,'VmaAllocatorCreateInfo']]] +]; diff --git a/docs/html/search/all_8.html b/docs/html/search/all_8.html new file mode 100644 index 0000000..11e27cd --- /dev/null +++ b/docs/html/search/all_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js new file mode 100644 index 0000000..0a576b4 --- /dev/null +++ b/docs/html/search/all_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['requiredflags',['requiredFlags',['../struct_vma_memory_requirements.html#a8876c1b0f112e13a277f16967064cfe0',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/all_9.html b/docs/html/search/all_9.html new file mode 100644 index 0000000..f8abbbe --- /dev/null +++ b/docs/html/search/all_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js new file mode 100644 index 0000000..619cc95 --- /dev/null +++ b/docs/html/search/all_9.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['suballocationcount',['SuballocationCount',['../struct_vma_stat_info.html#a09fb04b5491661c2e838d098d51bcead',1,'VmaStatInfo']]], + ['suballocationsizeavg',['SuballocationSizeAvg',['../struct_vma_stat_info.html#abb6c3e160a136787f474a18a8264d83b',1,'VmaStatInfo']]], + ['suballocationsizemax',['SuballocationSizeMax',['../struct_vma_stat_info.html#a6be7faf2b7fcff5a9bc017d90aed9271',1,'VmaStatInfo']]], + ['suballocationsizemin',['SuballocationSizeMin',['../struct_vma_stat_info.html#a9dc0b50fab2f10ab99366b79424bf14b',1,'VmaStatInfo']]] +]; diff --git a/docs/html/search/all_a.html b/docs/html/search/all_a.html new file mode 100644 index 0000000..9601fce --- /dev/null +++ b/docs/html/search/all_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js new file mode 100644 index 0000000..f8fbe3d --- /dev/null +++ b/docs/html/search/all_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['total',['total',['../struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9',1,'VmaStats']]] +]; diff --git a/docs/html/search/all_b.html b/docs/html/search/all_b.html new file mode 100644 index 0000000..0814e4e --- /dev/null +++ b/docs/html/search/all_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js new file mode 100644 index 0000000..cc1a3e7 --- /dev/null +++ b/docs/html/search/all_b.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['unusedbytes',['UnusedBytes',['../struct_vma_stat_info.html#a394d2aef4348cb58abf73764804b4f2d',1,'VmaStatInfo']]], + ['unusedrangecount',['UnusedRangeCount',['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo']]], + ['unusedrangesizeavg',['UnusedRangeSizeAvg',['../struct_vma_stat_info.html#a88ad9bdc2b3a98964a4d0c338c0c9060',1,'VmaStatInfo']]], + ['unusedrangesizemax',['UnusedRangeSizeMax',['../struct_vma_stat_info.html#a10c52c0841f01ca704e8ddb1ea6a635d',1,'VmaStatInfo']]], + ['unusedrangesizemin',['UnusedRangeSizeMin',['../struct_vma_stat_info.html#a07c508f42a4d3424bd0c259784a7f2d6',1,'VmaStatInfo']]], + ['usage',['usage',['../struct_vma_memory_requirements.html#ab588497177a57847ed04e0a1aef54bbe',1,'VmaMemoryRequirements']]], + ['usedbytes',['UsedBytes',['../struct_vma_stat_info.html#a86f82cb9cffd456b9da63eaf26c9ff04',1,'VmaStatInfo']]] +]; diff --git a/docs/html/search/all_c.html b/docs/html/search/all_c.html new file mode 100644 index 0000000..da08c38 --- /dev/null +++ b/docs/html/search/all_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/all_c.js b/docs/html/search/all_c.js new file mode 100644 index 0000000..ad59006 --- /dev/null +++ b/docs/html/search/all_c.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['vulkan_20memory_20allocator',['Vulkan Memory Allocator',['../index.html',1,'']]], + ['vk_5fmem_5falloc_2eh',['vk_mem_alloc.h',['../vk__mem__alloc_8h.html',1,'']]], + ['vma_5fmemory_5fusage_5fcpu_5fonly',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fgpu_5fonly',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fmax_5fenum',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5funknown',['VMA_MEMORY_USAGE_UNKNOWN',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]], + ['vma_5fstats_5fstring_5fenabled',['VMA_STATS_STRING_ENABLED',['../group__general.html#gae25f0d55fd91cb166f002b63244800e1',1,'vk_mem_alloc.h']]], + ['vmaallocatememory',['vmaAllocateMemory',['../group__layer2.html#gab7d80a26f1059f60c1e3a6999b5f7be1',1,'vk_mem_alloc.h']]], + ['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../group__layer2.html#gac2d43581abef651398409ed3f71a7b95',1,'vk_mem_alloc.h']]], + ['vmaallocatememoryforimage',['vmaAllocateMemoryForImage',['../group__layer2.html#gad0d2f5b794dd454f0fa5ba308d644af3',1,'vk_mem_alloc.h']]], + ['vmaallocatorcreateinfo',['VmaAllocatorCreateInfo',['../struct_vma_allocator_create_info.html',1,'VmaAllocatorCreateInfo'],['../group__general.html#gae0f6d1d733dded220d28134da46b4283',1,'VmaAllocatorCreateInfo(): vk_mem_alloc.h']]], + ['vmabuildstatsstring',['vmaBuildStatsString',['../group__general.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]], + ['vmacalculatestats',['vmaCalculateStats',['../group__general.html#ga333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]], + ['vmacreateallocator',['vmaCreateAllocator',['../group__general.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]], + ['vmacreatebuffer',['vmaCreateBuffer',['../group__layer3.html#ga6cafa3a644324a1e0c9165494db11648',1,'vk_mem_alloc.h']]], + ['vmacreateimage',['vmaCreateImage',['../group__layer3.html#ga9646281a3d9abc9f4d0bc5632db117de',1,'vk_mem_alloc.h']]], + ['vmadestroyallocator',['vmaDestroyAllocator',['../group__general.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]], + ['vmadestroybuffer',['vmaDestroyBuffer',['../group__layer3.html#ga967857c06b8232b2a54936daf36d1535',1,'vk_mem_alloc.h']]], + ['vmadestroyimage',['vmaDestroyImage',['../group__layer3.html#ga9377799736c4a1262b41ee441e5fc877',1,'vk_mem_alloc.h']]], + ['vmafindmemorytypeindex',['vmaFindMemoryTypeIndex',['../group__layer1.html#gadf80663373e94bcef382f17534b8694e',1,'vk_mem_alloc.h']]], + ['vmafreememory',['vmaFreeMemory',['../group__layer2.html#gaf5896cec102b83ca87ae07002d96e230',1,'vk_mem_alloc.h']]], + ['vmafreestatsstring',['vmaFreeStatsString',['../group__general.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]], + ['vmagetmemoryproperties',['vmaGetMemoryProperties',['../group__general.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]], + ['vmagetmemorytypeproperties',['vmaGetMemoryTypeProperties',['../group__general.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]], + ['vmagetphysicaldeviceproperties',['vmaGetPhysicalDeviceProperties',['../group__general.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]], + ['vmamapmemory',['vmaMapMemory',['../group__layer2.html#ga17739a61a7647553258235e6142c428c',1,'vk_mem_alloc.h']]], + ['vmamemoryrequirements',['VmaMemoryRequirements',['../struct_vma_memory_requirements.html',1,'VmaMemoryRequirements'],['../group__layer1.html#gae9ee98bebd6e474aa0ef679e10f1d8ca',1,'VmaMemoryRequirements(): vk_mem_alloc.h']]], + ['vmamemoryusage',['VmaMemoryUsage',['../group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'VmaMemoryUsage(): vk_mem_alloc.h'],['../group__layer1.html#gad63b2113c0bfdbeade1cb498f5a8580d',1,'VmaMemoryUsage(): vk_mem_alloc.h']]], + ['vmastatinfo',['VmaStatInfo',['../struct_vma_stat_info.html',1,'VmaStatInfo'],['../group__general.html#ga810b009a788ee8aac72a25b42ffbe31c',1,'VmaStatInfo(): vk_mem_alloc.h']]], + ['vmastats',['VmaStats',['../struct_vma_stats.html',1,'']]], + ['vmaunmapmemory',['vmaUnmapMemory',['../group__layer2.html#gac2d386fd6ed3b7905892fc77db0b8514',1,'vk_mem_alloc.h']]] +]; diff --git a/docs/html/search/classes_0.html b/docs/html/search/classes_0.html new file mode 100644 index 0000000..1c3e406 --- /dev/null +++ b/docs/html/search/classes_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js new file mode 100644 index 0000000..7cf7430 --- /dev/null +++ b/docs/html/search/classes_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['vmaallocatorcreateinfo',['VmaAllocatorCreateInfo',['../struct_vma_allocator_create_info.html',1,'']]], + ['vmamemoryrequirements',['VmaMemoryRequirements',['../struct_vma_memory_requirements.html',1,'']]], + ['vmastatinfo',['VmaStatInfo',['../struct_vma_stat_info.html',1,'']]], + ['vmastats',['VmaStats',['../struct_vma_stats.html',1,'']]] +]; diff --git a/docs/html/search/close.png b/docs/html/search/close.png new file mode 100644 index 0000000..9342d3d Binary files /dev/null and b/docs/html/search/close.png differ diff --git a/docs/html/search/enums_0.html b/docs/html/search/enums_0.html new file mode 100644 index 0000000..ee343ac --- /dev/null +++ b/docs/html/search/enums_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enums_0.js b/docs/html/search/enums_0.js new file mode 100644 index 0000000..9c9ac7f --- /dev/null +++ b/docs/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vmamemoryusage',['VmaMemoryUsage',['../group__layer1.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'vk_mem_alloc.h']]] +]; diff --git a/docs/html/search/enumvalues_0.html b/docs/html/search/enumvalues_0.html new file mode 100644 index 0000000..9387b6a --- /dev/null +++ b/docs/html/search/enumvalues_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/enumvalues_0.js b/docs/html/search/enumvalues_0.js new file mode 100644 index 0000000..0d98b0a --- /dev/null +++ b/docs/html/search/enumvalues_0.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['vma_5fmemory_5fusage_5fcpu_5fonly',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fgpu_5fonly',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5fmax_5fenum',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]], + ['vma_5fmemory_5fusage_5funknown',['VMA_MEMORY_USAGE_UNKNOWN',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]] +]; diff --git a/docs/html/search/files_0.html b/docs/html/search/files_0.html new file mode 100644 index 0000000..4f272b8 --- /dev/null +++ b/docs/html/search/files_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/files_0.js b/docs/html/search/files_0.js new file mode 100644 index 0000000..aeac70c --- /dev/null +++ b/docs/html/search/files_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vk_5fmem_5falloc_2eh',['vk_mem_alloc.h',['../vk__mem__alloc_8h.html',1,'']]] +]; diff --git a/docs/html/search/functions_0.html b/docs/html/search/functions_0.html new file mode 100644 index 0000000..4e6d87d --- /dev/null +++ b/docs/html/search/functions_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js new file mode 100644 index 0000000..6a8494b --- /dev/null +++ b/docs/html/search/functions_0.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['vmaallocatememory',['vmaAllocateMemory',['../group__layer2.html#gab7d80a26f1059f60c1e3a6999b5f7be1',1,'vk_mem_alloc.h']]], + ['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../group__layer2.html#gac2d43581abef651398409ed3f71a7b95',1,'vk_mem_alloc.h']]], + ['vmaallocatememoryforimage',['vmaAllocateMemoryForImage',['../group__layer2.html#gad0d2f5b794dd454f0fa5ba308d644af3',1,'vk_mem_alloc.h']]], + ['vmabuildstatsstring',['vmaBuildStatsString',['../group__general.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]], + ['vmacalculatestats',['vmaCalculateStats',['../group__general.html#ga333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]], + ['vmacreateallocator',['vmaCreateAllocator',['../group__general.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]], + ['vmacreatebuffer',['vmaCreateBuffer',['../group__layer3.html#ga6cafa3a644324a1e0c9165494db11648',1,'vk_mem_alloc.h']]], + ['vmacreateimage',['vmaCreateImage',['../group__layer3.html#ga9646281a3d9abc9f4d0bc5632db117de',1,'vk_mem_alloc.h']]], + ['vmadestroyallocator',['vmaDestroyAllocator',['../group__general.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]], + ['vmadestroybuffer',['vmaDestroyBuffer',['../group__layer3.html#ga967857c06b8232b2a54936daf36d1535',1,'vk_mem_alloc.h']]], + ['vmadestroyimage',['vmaDestroyImage',['../group__layer3.html#ga9377799736c4a1262b41ee441e5fc877',1,'vk_mem_alloc.h']]], + ['vmafindmemorytypeindex',['vmaFindMemoryTypeIndex',['../group__layer1.html#gadf80663373e94bcef382f17534b8694e',1,'vk_mem_alloc.h']]], + ['vmafreememory',['vmaFreeMemory',['../group__layer2.html#gaf5896cec102b83ca87ae07002d96e230',1,'vk_mem_alloc.h']]], + ['vmafreestatsstring',['vmaFreeStatsString',['../group__general.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]], + ['vmagetmemoryproperties',['vmaGetMemoryProperties',['../group__general.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]], + ['vmagetmemorytypeproperties',['vmaGetMemoryTypeProperties',['../group__general.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]], + ['vmagetphysicaldeviceproperties',['vmaGetPhysicalDeviceProperties',['../group__general.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]], + ['vmamapmemory',['vmaMapMemory',['../group__layer2.html#ga17739a61a7647553258235e6142c428c',1,'vk_mem_alloc.h']]], + ['vmaunmapmemory',['vmaUnmapMemory',['../group__layer2.html#gac2d386fd6ed3b7905892fc77db0b8514',1,'vk_mem_alloc.h']]] +]; diff --git a/docs/html/search/groups_0.html b/docs/html/search/groups_0.html new file mode 100644 index 0000000..1ede28d --- /dev/null +++ b/docs/html/search/groups_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/groups_0.js b/docs/html/search/groups_0.js new file mode 100644 index 0000000..025ecae --- /dev/null +++ b/docs/html/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['general',['General',['../group__general.html',1,'']]] +]; diff --git a/docs/html/search/groups_1.html b/docs/html/search/groups_1.html new file mode 100644 index 0000000..3c05216 --- /dev/null +++ b/docs/html/search/groups_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/groups_1.js b/docs/html/search/groups_1.js new file mode 100644 index 0000000..058f893 --- /dev/null +++ b/docs/html/search/groups_1.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['layer_201_20choosing_20memory_20type',['Layer 1 Choosing Memory Type',['../group__layer1.html',1,'']]], + ['layer_202_20allocating_20memory',['Layer 2 Allocating Memory',['../group__layer2.html',1,'']]], + ['layer_203_20creating_20buffers_20and_20images',['Layer 3 Creating Buffers and Images',['../group__layer3.html',1,'']]] +]; diff --git a/docs/html/search/mag_sel.png b/docs/html/search/mag_sel.png new file mode 100644 index 0000000..81f6040 Binary files /dev/null and b/docs/html/search/mag_sel.png differ diff --git a/docs/html/search/nomatches.html b/docs/html/search/nomatches.html new file mode 100644 index 0000000..b1ded27 --- /dev/null +++ b/docs/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/docs/html/search/pages_0.html b/docs/html/search/pages_0.html new file mode 100644 index 0000000..4955b9e --- /dev/null +++ b/docs/html/search/pages_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/pages_0.js b/docs/html/search/pages_0.js new file mode 100644 index 0000000..61d5dd4 --- /dev/null +++ b/docs/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vulkan_20memory_20allocator',['Vulkan Memory Allocator',['../index.html',1,'']]] +]; diff --git a/docs/html/search/search.css b/docs/html/search/search.css new file mode 100644 index 0000000..3cf9df9 --- /dev/null +++ b/docs/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + float: none; + margin-top: 8px; + right: 0px; + width: 170px; + height: 24px; + z-index: 102; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:115px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:8px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/docs/html/search/search.js b/docs/html/search/search.js new file mode 100644 index 0000000..dedce3b --- /dev/null +++ b/docs/html/search/search.js @@ -0,0 +1,791 @@ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/typedefs_0.js b/docs/html/search/typedefs_0.js new file mode 100644 index 0000000..4f030fd --- /dev/null +++ b/docs/html/search/typedefs_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['vmaallocatorcreateinfo',['VmaAllocatorCreateInfo',['../group__general.html#gae0f6d1d733dded220d28134da46b4283',1,'vk_mem_alloc.h']]], + ['vmamemoryrequirements',['VmaMemoryRequirements',['../group__layer1.html#gae9ee98bebd6e474aa0ef679e10f1d8ca',1,'vk_mem_alloc.h']]], + ['vmamemoryusage',['VmaMemoryUsage',['../group__layer1.html#gad63b2113c0bfdbeade1cb498f5a8580d',1,'vk_mem_alloc.h']]], + ['vmastatinfo',['VmaStatInfo',['../group__general.html#ga810b009a788ee8aac72a25b42ffbe31c',1,'vk_mem_alloc.h']]] +]; diff --git a/docs/html/search/variables_0.html b/docs/html/search/variables_0.html new file mode 100644 index 0000000..74ce807 --- /dev/null +++ b/docs/html/search/variables_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_0.js b/docs/html/search/variables_0.js new file mode 100644 index 0000000..e5008cc --- /dev/null +++ b/docs/html/search/variables_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['allocationcount',['AllocationCount',['../struct_vma_stat_info.html#a240402222ac6777e4079653c5d542cb0',1,'VmaStatInfo']]] +]; diff --git a/docs/html/search/variables_1.html b/docs/html/search/variables_1.html new file mode 100644 index 0000000..84237b6 --- /dev/null +++ b/docs/html/search/variables_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_1.js b/docs/html/search/variables_1.js new file mode 100644 index 0000000..b72b6f4 --- /dev/null +++ b/docs/html/search/variables_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['device',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo']]] +]; diff --git a/docs/html/search/variables_2.html b/docs/html/search/variables_2.html new file mode 100644 index 0000000..5c9de1a --- /dev/null +++ b/docs/html/search/variables_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_2.js b/docs/html/search/variables_2.js new file mode 100644 index 0000000..5b8d8f2 --- /dev/null +++ b/docs/html/search/variables_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['memoryheap',['memoryHeap',['../struct_vma_stats.html#a0e6611508c29a187f0fd14ff1a0329c0',1,'VmaStats']]], + ['memorytype',['memoryType',['../struct_vma_stats.html#a13e3caf754be79352c42408756309331',1,'VmaStats']]] +]; diff --git a/docs/html/search/variables_3.html b/docs/html/search/variables_3.html new file mode 100644 index 0000000..f95e34c --- /dev/null +++ b/docs/html/search/variables_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_3.js b/docs/html/search/variables_3.js new file mode 100644 index 0000000..523d148 --- /dev/null +++ b/docs/html/search/variables_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['neverallocate',['neverAllocate',['../struct_vma_memory_requirements.html#a2259df9db140839199fa43b651c58447',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/variables_4.html b/docs/html/search/variables_4.html new file mode 100644 index 0000000..d7db285 --- /dev/null +++ b/docs/html/search/variables_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_4.js b/docs/html/search/variables_4.js new file mode 100644 index 0000000..44a7a9b --- /dev/null +++ b/docs/html/search/variables_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ownmemory',['ownMemory',['../struct_vma_memory_requirements.html#a401cdf684f8a13c8ff3bb469a1759153',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/variables_5.html b/docs/html/search/variables_5.html new file mode 100644 index 0000000..7bbceeb --- /dev/null +++ b/docs/html/search/variables_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_5.js b/docs/html/search/variables_5.js new file mode 100644 index 0000000..a6df7a8 --- /dev/null +++ b/docs/html/search/variables_5.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['pallocationcallbacks',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo']]], + ['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]], + ['preferredflags',['preferredFlags',['../struct_vma_memory_requirements.html#a6e105f836c2288034c711815b18226dc',1,'VmaMemoryRequirements']]], + ['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]], + ['preferredsmallheapblocksize',['preferredSmallHeapBlockSize',['../struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a',1,'VmaAllocatorCreateInfo']]] +]; diff --git a/docs/html/search/variables_6.html b/docs/html/search/variables_6.html new file mode 100644 index 0000000..4eb162d --- /dev/null +++ b/docs/html/search/variables_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_6.js b/docs/html/search/variables_6.js new file mode 100644 index 0000000..0a576b4 --- /dev/null +++ b/docs/html/search/variables_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['requiredflags',['requiredFlags',['../struct_vma_memory_requirements.html#a8876c1b0f112e13a277f16967064cfe0',1,'VmaMemoryRequirements']]] +]; diff --git a/docs/html/search/variables_7.html b/docs/html/search/variables_7.html new file mode 100644 index 0000000..0408829 --- /dev/null +++ b/docs/html/search/variables_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_7.js b/docs/html/search/variables_7.js new file mode 100644 index 0000000..619cc95 --- /dev/null +++ b/docs/html/search/variables_7.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['suballocationcount',['SuballocationCount',['../struct_vma_stat_info.html#a09fb04b5491661c2e838d098d51bcead',1,'VmaStatInfo']]], + ['suballocationsizeavg',['SuballocationSizeAvg',['../struct_vma_stat_info.html#abb6c3e160a136787f474a18a8264d83b',1,'VmaStatInfo']]], + ['suballocationsizemax',['SuballocationSizeMax',['../struct_vma_stat_info.html#a6be7faf2b7fcff5a9bc017d90aed9271',1,'VmaStatInfo']]], + ['suballocationsizemin',['SuballocationSizeMin',['../struct_vma_stat_info.html#a9dc0b50fab2f10ab99366b79424bf14b',1,'VmaStatInfo']]] +]; diff --git a/docs/html/search/variables_8.html b/docs/html/search/variables_8.html new file mode 100644 index 0000000..d54d096 --- /dev/null +++ b/docs/html/search/variables_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_8.js b/docs/html/search/variables_8.js new file mode 100644 index 0000000..f8fbe3d --- /dev/null +++ b/docs/html/search/variables_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['total',['total',['../struct_vma_stats.html#a2e8f5b3353f2fefef3c27f29e245a1f9',1,'VmaStats']]] +]; diff --git a/docs/html/search/variables_9.html b/docs/html/search/variables_9.html new file mode 100644 index 0000000..234dc60 --- /dev/null +++ b/docs/html/search/variables_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/docs/html/search/variables_9.js b/docs/html/search/variables_9.js new file mode 100644 index 0000000..cc1a3e7 --- /dev/null +++ b/docs/html/search/variables_9.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['unusedbytes',['UnusedBytes',['../struct_vma_stat_info.html#a394d2aef4348cb58abf73764804b4f2d',1,'VmaStatInfo']]], + ['unusedrangecount',['UnusedRangeCount',['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo']]], + ['unusedrangesizeavg',['UnusedRangeSizeAvg',['../struct_vma_stat_info.html#a88ad9bdc2b3a98964a4d0c338c0c9060',1,'VmaStatInfo']]], + ['unusedrangesizemax',['UnusedRangeSizeMax',['../struct_vma_stat_info.html#a10c52c0841f01ca704e8ddb1ea6a635d',1,'VmaStatInfo']]], + ['unusedrangesizemin',['UnusedRangeSizeMin',['../struct_vma_stat_info.html#a07c508f42a4d3424bd0c259784a7f2d6',1,'VmaStatInfo']]], + ['usage',['usage',['../struct_vma_memory_requirements.html#ab588497177a57847ed04e0a1aef54bbe',1,'VmaMemoryRequirements']]], + ['usedbytes',['UsedBytes',['../struct_vma_stat_info.html#a86f82cb9cffd456b9da63eaf26c9ff04',1,'VmaStatInfo']]] +]; diff --git a/docs/html/splitbar.png b/docs/html/splitbar.png new file mode 100644 index 0000000..fe895f2 Binary files /dev/null and b/docs/html/splitbar.png differ diff --git a/docs/html/struct_vma_allocator_create_info-members.html b/docs/html/struct_vma_allocator_create_info-members.html new file mode 100644 index 0000000..31b25c0 --- /dev/null +++ b/docs/html/struct_vma_allocator_create_info-members.html @@ -0,0 +1,81 @@ + + + + + + + +Vulkan Memory Allocator: Member List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
VmaAllocatorCreateInfo Member List
+
+ + + + + diff --git a/docs/html/struct_vma_allocator_create_info.html b/docs/html/struct_vma_allocator_create_info.html new file mode 100644 index 0000000..c60e132 --- /dev/null +++ b/docs/html/struct_vma_allocator_create_info.html @@ -0,0 +1,191 @@ + + + + + + + +Vulkan Memory Allocator: VmaAllocatorCreateInfo Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
VmaAllocatorCreateInfo Struct Reference
+
+
+ +

Description of a Allocator to be created. + More...

+ +

#include <vk_mem_alloc.h>

+ + + + + + + + + + + + + + + + + +

+Public Attributes

VkPhysicalDevice physicalDevice
 Vulkan physical device. More...
 
VkDevice device
 Vulkan device. More...
 
VkDeviceSize preferredLargeHeapBlockSize
 Size of a single memory block to allocate for resources. More...
 
VkDeviceSize preferredSmallHeapBlockSize
 Size of a single memory block to allocate for resources from a small heap <= 512 MB. More...
 
const VkAllocationCallbacks * pAllocationCallbacks
 Custom allocation callbacks. More...
 
+

Detailed Description

+

Description of a Allocator to be created.

+

Member Data Documentation

+ +

◆ device

+ +
+
+ + + + +
VkDevice VmaAllocatorCreateInfo::device
+
+ +

Vulkan device.

+

It must be valid throughout whole lifetime of created Allocator.

+ +
+
+ +

◆ pAllocationCallbacks

+ +
+
+ + + + +
const VkAllocationCallbacks* VmaAllocatorCreateInfo::pAllocationCallbacks
+
+ +

Custom allocation callbacks.

+

Optional, can be null. When specified, will also be used for all CPU-side memory allocations.

+ +
+
+ +

◆ physicalDevice

+ +
+
+ + + + +
VkPhysicalDevice VmaAllocatorCreateInfo::physicalDevice
+
+ +

Vulkan physical device.

+

It must be valid throughout whole lifetime of created Allocator.

+ +
+
+ +

◆ preferredLargeHeapBlockSize

+ +
+
+ + + + +
VkDeviceSize VmaAllocatorCreateInfo::preferredLargeHeapBlockSize
+
+ +

Size of a single memory block to allocate for resources.

+

Set to 0 to use default, which is currently 256 MB.

+ +
+
+ +

◆ preferredSmallHeapBlockSize

+ +
+
+ + + + +
VkDeviceSize VmaAllocatorCreateInfo::preferredSmallHeapBlockSize
+
+ +

Size of a single memory block to allocate for resources from a small heap <= 512 MB.

+

Set to 0 to use default, which is currently 64 MB.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/html/struct_vma_memory_requirements-members.html b/docs/html/struct_vma_memory_requirements-members.html new file mode 100644 index 0000000..1404da1 --- /dev/null +++ b/docs/html/struct_vma_memory_requirements-members.html @@ -0,0 +1,81 @@ + + + + + + + +Vulkan Memory Allocator: Member List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
VmaMemoryRequirements Member List
+
+ + + + + diff --git a/docs/html/struct_vma_memory_requirements.html b/docs/html/struct_vma_memory_requirements.html new file mode 100644 index 0000000..b3b2324 --- /dev/null +++ b/docs/html/struct_vma_memory_requirements.html @@ -0,0 +1,188 @@ + + + + + + + +Vulkan Memory Allocator: VmaMemoryRequirements Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
VmaMemoryRequirements Struct Reference
+
+
+ +

#include <vk_mem_alloc.h>

+ + + + + + + + + + + + + + + + + +

+Public Attributes

VkBool32 ownMemory
 Set to true if this allocation should have its own memory block. More...
 
VmaMemoryUsage usage
 Intended usage of memory. More...
 
VkMemoryPropertyFlags requiredFlags
 Flags that must be set in a Memory Type chosen for an allocation. More...
 
VkMemoryPropertyFlags preferredFlags
 Flags that preferably should be set in a Memory Type chosen for an allocation. More...
 
VkBool32 neverAllocate
 Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such block. More...
 
+

Member Data Documentation

+ +

◆ neverAllocate

+ +
+
+ + + + +
VkBool32 VmaMemoryRequirements::neverAllocate
+
+ +

Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such block.

+

If new allocation cannot be placed in any of the existing blocks, allocation fails with VK_ERROR_OUT_OF_DEVICE_MEMORY error.

+

It makes no sense to set ownMemory and neverAllocate at the same time.

+ +
+
+ +

◆ ownMemory

+ +
+
+ + + + +
VkBool32 VmaMemoryRequirements::ownMemory
+
+ +

Set to true if this allocation should have its own memory block.

+

Use it for special, big resources, like fullscreen images used as attachments.

+

This flag must also be used for host visible resources that you want to map simultaneously because otherwise they might end up as regions of the same VkDeviceMemory, while mapping same VkDeviceMemory multiple times is illegal.

+ +
+
+ +

◆ preferredFlags

+ +
+
+ + + + +
VkMemoryPropertyFlags VmaMemoryRequirements::preferredFlags
+
+ +

Flags that preferably should be set in a Memory Type chosen for an allocation.

+

Set to 0 if no additional flags are prefered and only requiredFlags should be used. If not 0, it must be a superset or equal to requiredFlags.

+ +
+
+ +

◆ requiredFlags

+ +
+
+ + + + +
VkMemoryPropertyFlags VmaMemoryRequirements::requiredFlags
+
+ +

Flags that must be set in a Memory Type chosen for an allocation.

+

Leave 0 if you specify requirement via usage.

+ +
+
+ +

◆ usage

+ +
+
+ + + + +
VmaMemoryUsage VmaMemoryRequirements::usage
+
+ +

Intended usage of memory.

+

Leave VMA_MEMORY_USAGE_UNKNOWN if you specify requiredFlags. You can also use both.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/html/struct_vma_stat_info-members.html b/docs/html/struct_vma_stat_info-members.html new file mode 100644 index 0000000..10ff724 --- /dev/null +++ b/docs/html/struct_vma_stat_info-members.html @@ -0,0 +1,87 @@ + + + + + + + +Vulkan Memory Allocator: Member List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
VmaStatInfo Member List
+
+ + + + + diff --git a/docs/html/struct_vma_stat_info.html b/docs/html/struct_vma_stat_info.html new file mode 100644 index 0000000..7c0a4d3 --- /dev/null +++ b/docs/html/struct_vma_stat_info.html @@ -0,0 +1,262 @@ + + + + + + + +Vulkan Memory Allocator: VmaStatInfo Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
VmaStatInfo Struct Reference
+
+
+ +

#include <vk_mem_alloc.h>

+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

uint32_t AllocationCount
 
uint32_t SuballocationCount
 
uint32_t UnusedRangeCount
 
VkDeviceSize UsedBytes
 
VkDeviceSize UnusedBytes
 
VkDeviceSize SuballocationSizeMin
 
VkDeviceSize SuballocationSizeAvg
 
VkDeviceSize SuballocationSizeMax
 
VkDeviceSize UnusedRangeSizeMin
 
VkDeviceSize UnusedRangeSizeAvg
 
VkDeviceSize UnusedRangeSizeMax
 
+

Member Data Documentation

+ +

◆ AllocationCount

+ +
+
+ + + + +
uint32_t VmaStatInfo::AllocationCount
+
+ +
+
+ +

◆ SuballocationCount

+ +
+
+ + + + +
uint32_t VmaStatInfo::SuballocationCount
+
+ +
+
+ +

◆ SuballocationSizeAvg

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::SuballocationSizeAvg
+
+ +
+
+ +

◆ SuballocationSizeMax

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::SuballocationSizeMax
+
+ +
+
+ +

◆ SuballocationSizeMin

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::SuballocationSizeMin
+
+ +
+
+ +

◆ UnusedBytes

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::UnusedBytes
+
+ +
+
+ +

◆ UnusedRangeCount

+ +
+
+ + + + +
uint32_t VmaStatInfo::UnusedRangeCount
+
+ +
+
+ +

◆ UnusedRangeSizeAvg

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::UnusedRangeSizeAvg
+
+ +
+
+ +

◆ UnusedRangeSizeMax

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::UnusedRangeSizeMax
+
+ +
+
+ +

◆ UnusedRangeSizeMin

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::UnusedRangeSizeMin
+
+ +
+
+ +

◆ UsedBytes

+ +
+
+ + + + +
VkDeviceSize VmaStatInfo::UsedBytes
+
+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/html/struct_vma_stats-members.html b/docs/html/struct_vma_stats-members.html new file mode 100644 index 0000000..ef81a09 --- /dev/null +++ b/docs/html/struct_vma_stats-members.html @@ -0,0 +1,79 @@ + + + + + + + +Vulkan Memory Allocator: Member List + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
VmaStats Member List
+
+
+ +

This is the complete list of members for VmaStats, including all inherited members.

+ + + + +
memoryHeapVmaStats
memoryTypeVmaStats
totalVmaStats
+ + + + diff --git a/docs/html/struct_vma_stats.html b/docs/html/struct_vma_stats.html new file mode 100644 index 0000000..3dcae04 --- /dev/null +++ b/docs/html/struct_vma_stats.html @@ -0,0 +1,139 @@ + + + + + + + +Vulkan Memory Allocator: VmaStats Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
VmaStats Struct Reference
+
+
+ +

General statistics from current state of Allocator. + More...

+ +

#include <vk_mem_alloc.h>

+ + + + + + + + +

+Public Attributes

VmaStatInfo memoryType [VK_MAX_MEMORY_TYPES]
 
VmaStatInfo memoryHeap [VK_MAX_MEMORY_HEAPS]
 
VmaStatInfo total
 
+

Detailed Description

+

General statistics from current state of Allocator.

+

Member Data Documentation

+ +

◆ memoryHeap

+ +
+
+ + + + +
VmaStatInfo VmaStats::memoryHeap[VK_MAX_MEMORY_HEAPS]
+
+ +
+
+ +

◆ memoryType

+ +
+
+ + + + +
VmaStatInfo VmaStats::memoryType[VK_MAX_MEMORY_TYPES]
+
+ +
+
+ +

◆ total

+ +
+
+ + + + +
VmaStatInfo VmaStats::total
+
+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/html/sync_off.png b/docs/html/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/docs/html/sync_off.png differ diff --git a/docs/html/sync_on.png b/docs/html/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/docs/html/sync_on.png differ diff --git a/docs/html/tab_a.png b/docs/html/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/docs/html/tab_a.png differ diff --git a/docs/html/tab_b.png b/docs/html/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/docs/html/tab_b.png differ diff --git a/docs/html/tab_h.png b/docs/html/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/docs/html/tab_h.png differ diff --git a/docs/html/tab_s.png b/docs/html/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/docs/html/tab_s.png differ diff --git a/docs/html/tabs.css b/docs/html/tabs.css new file mode 100644 index 0000000..a28614b --- /dev/null +++ b/docs/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#doc-content{overflow:auto;display:block;padding:0;margin:0;-webkit-overflow-scrolling:touch}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file diff --git a/docs/html/vk__mem__alloc_8h.html b/docs/html/vk__mem__alloc_8h.html new file mode 100644 index 0000000..c0df697 --- /dev/null +++ b/docs/html/vk__mem__alloc_8h.html @@ -0,0 +1,177 @@ + + + + + + + +Vulkan Memory Allocator: vk_mem_alloc.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
vk_mem_alloc.h File Reference
+
+
+
#include <vulkan/vulkan.h>
+
+

Go to the source code of this file.

+ + + + + + + + + + + + +

+Classes

struct  VmaAllocatorCreateInfo
 Description of a Allocator to be created. More...
 
struct  VmaStatInfo
 
struct  VmaStats
 General statistics from current state of Allocator. More...
 
struct  VmaMemoryRequirements
 
+ + + +

+Macros

#define VMA_STATS_STRING_ENABLED   1
 
+ + + + + + + + + + +

+Typedefs

typedef struct VmaAllocatorCreateInfo VmaAllocatorCreateInfo
 Description of a Allocator to be created. More...
 
typedef struct VmaStatInfo VmaStatInfo
 
typedef enum VmaMemoryUsage VmaMemoryUsage
 
typedef struct VmaMemoryRequirements VmaMemoryRequirements
 
+ + + +

+Enumerations

enum  VmaMemoryUsage {
+  VMA_MEMORY_USAGE_UNKNOWN = 0, +VMA_MEMORY_USAGE_GPU_ONLY = 1, +VMA_MEMORY_USAGE_CPU_ONLY = 2, +VMA_MEMORY_USAGE_CPU_TO_GPU = 3, +
+  VMA_MEMORY_USAGE_GPU_TO_CPU = 4, +VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF +
+ }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

VkResult vmaCreateAllocator (const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
 Creates Allocator object. More...
 
void vmaDestroyAllocator (VmaAllocator allocator)
 Destroys allocator object. More...
 
void vmaGetPhysicalDeviceProperties (VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)
 
void vmaGetMemoryProperties (VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties **ppPhysicalDeviceMemoryProperties)
 
void vmaGetMemoryTypeProperties (VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags *pFlags)
 Given Memory Type Index, returns Property Flags of this memory type. More...
 
void vmaCalculateStats (VmaAllocator allocator, VmaStats *pStats)
 Retrieves statistics from current state of the Allocator. More...
 
void vmaBuildStatsString (VmaAllocator allocator, char **ppStatsString, VkBool32 detailedMap)
 Builds and returns statistics as string in JSON format. More...
 
void vmaFreeStatsString (VmaAllocator allocator, char *pStatsString)
 
VkResult vmaFindMemoryTypeIndex (VmaAllocator allocator, uint32_t memoryTypeBits, const VmaMemoryRequirements *pMemoryRequirements, uint32_t *pMemoryTypeIndex)
 
VkResult vmaAllocateMemory (VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const VmaMemoryRequirements *pVmaMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 General purpose memory allocation. More...
 
VkResult vmaAllocateMemoryForBuffer (VmaAllocator allocator, VkBuffer buffer, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 
VkResult vmaAllocateMemoryForImage (VmaAllocator allocator, VkImage image, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 Function similar to vmaAllocateMemoryForBuffer(). More...
 
void vmaFreeMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
 Frees memory previously allocated using vmaAllocateMemoryForBuffer() or vmaAllocateMemoryForImage(). More...
 
VkResult vmaMapMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory, void **ppData)
 
void vmaUnmapMemory (VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
 
VkResult vmaCreateBuffer (VmaAllocator allocator, const VkBufferCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkBuffer *pBuffer, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 
void vmaDestroyBuffer (VmaAllocator allocator, VkBuffer buffer)
 
VkResult vmaCreateImage (VmaAllocator allocator, const VkImageCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkImage *pImage, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
 Function similar to vmaCreateBuffer(). More...
 
void vmaDestroyImage (VmaAllocator allocator, VkImage image)
 
+
+ + + + diff --git a/docs/html/vk__mem__alloc_8h_source.html b/docs/html/vk__mem__alloc_8h_source.html new file mode 100644 index 0000000..0f685cf --- /dev/null +++ b/docs/html/vk__mem__alloc_8h_source.html @@ -0,0 +1,130 @@ + + + + + + + +Vulkan Memory Allocator: vk_mem_alloc.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Vulkan Memory Allocator +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
vk_mem_alloc.h
+
+
+Go to the documentation of this file.
1 //
2 // Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #ifndef AMD_VULKAN_MEMORY_ALLOCATOR_H
24 #define AMD_VULKAN_MEMORY_ALLOCATOR_H
25 
149 #include <vulkan/vulkan.h>
150 
152 
156 VK_DEFINE_HANDLE(VmaAllocator)
157 
158 typedef struct VmaAllocatorCreateInfo
160 {
162 
163  VkPhysicalDevice physicalDevice;
165 
166  VkDevice device;
168 
171 
174 
175  const VkAllocationCallbacks* pAllocationCallbacks;
177 
179 VkResult vmaCreateAllocator(
180  const VmaAllocatorCreateInfo* pCreateInfo,
181  VmaAllocator* pAllocator);
182 
185  VmaAllocator allocator);
186 
192  VmaAllocator allocator,
193  const VkPhysicalDeviceProperties** ppPhysicalDeviceProperties);
194 
200  VmaAllocator allocator,
201  const VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties);
202 
210  VmaAllocator allocator,
211  uint32_t memoryTypeIndex,
212  VkMemoryPropertyFlags* pFlags);
213 
214 typedef struct VmaStatInfo
215 {
216  uint32_t AllocationCount;
219  VkDeviceSize UsedBytes;
220  VkDeviceSize UnusedBytes;
221  VkDeviceSize SuballocationSizeMin, SuballocationSizeAvg, SuballocationSizeMax;
222  VkDeviceSize UnusedRangeSizeMin, UnusedRangeSizeAvg, UnusedRangeSizeMax;
223 } VmaStatInfo;
224 
226 struct VmaStats
227 {
228  VmaStatInfo memoryType[VK_MAX_MEMORY_TYPES];
229  VmaStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS];
231 };
232 
234 void vmaCalculateStats(
235  VmaAllocator allocator,
236  VmaStats* pStats);
237 
238 #define VMA_STATS_STRING_ENABLED 1
239 
240 #if VMA_STATS_STRING_ENABLED
241 
243 
246  VmaAllocator allocator,
247  char** ppStatsString,
248  VkBool32 detailedMap);
249 
250 void vmaFreeStatsString(
251  VmaAllocator allocator,
252  char* pStatsString);
253 
254 #endif // #if VMA_STATS_STRING_ENABLED
255 
258 
263 typedef enum VmaMemoryUsage
264 {
277 
278 typedef struct VmaMemoryRequirements
279 {
288  VkBool32 ownMemory;
297  VkMemoryPropertyFlags requiredFlags;
302  VkMemoryPropertyFlags preferredFlags;
309  VkBool32 neverAllocate;
311 
326 VkResult vmaFindMemoryTypeIndex(
327  VmaAllocator allocator,
328  uint32_t memoryTypeBits,
329  const VmaMemoryRequirements* pMemoryRequirements,
330  uint32_t* pMemoryTypeIndex);
331 
334 
351 VkResult vmaAllocateMemory(
352  VmaAllocator allocator,
353  const VkMemoryRequirements* pVkMemoryRequirements,
354  const VmaMemoryRequirements* pVmaMemoryRequirements,
355  VkMappedMemoryRange* pMemory,
356  uint32_t* pMemoryTypeIndex);
357 
366  VmaAllocator allocator,
367  VkBuffer buffer,
368  const VmaMemoryRequirements* pMemoryRequirements,
369  VkMappedMemoryRange* pMemory,
370  uint32_t* pMemoryTypeIndex);
371 
374  VmaAllocator allocator,
375  VkImage image,
376  const VmaMemoryRequirements* pMemoryRequirements,
377  VkMappedMemoryRange* pMemory,
378  uint32_t* pMemoryTypeIndex);
379 
381 void vmaFreeMemory(
382  VmaAllocator allocator,
383  const VkMappedMemoryRange* pMemory);
384 
390 VkResult vmaMapMemory(
391  VmaAllocator allocator,
392  const VkMappedMemoryRange* pMemory,
393  void** ppData);
394 
395 void vmaUnmapMemory(
396  VmaAllocator allocator,
397  const VkMappedMemoryRange* pMemory);
398 
401 
423 VkResult vmaCreateBuffer(
424  VmaAllocator allocator,
425  const VkBufferCreateInfo* pCreateInfo,
426  const VmaMemoryRequirements* pMemoryRequirements,
427  VkBuffer* pBuffer,
428  VkMappedMemoryRange* pMemory,
429  uint32_t* pMemoryTypeIndex);
430 
431 void vmaDestroyBuffer(
432  VmaAllocator allocator,
433  VkBuffer buffer);
434 
436 VkResult vmaCreateImage(
437  VmaAllocator allocator,
438  const VkImageCreateInfo* pCreateInfo,
439  const VmaMemoryRequirements* pMemoryRequirements,
440  VkImage* pImage,
441  VkMappedMemoryRange* pMemory,
442  uint32_t* pMemoryTypeIndex);
443 
444 void vmaDestroyImage(
445  VmaAllocator allocator,
446  VkImage image);
447 
450 #ifdef VMA_IMPLEMENTATION
451 
452 #include <cstdlib>
453 
454 /*******************************************************************************
455 CONFIGURATION
456 
457 Change these definitions depending on your environment.
458 */
459 
460 #define VMA_USE_STL_CONTAINERS 0
461 
462 /* Set this macro to 1 to make the library including and using STL containers:
463 std::pair, std::vector, std::list, std::unordered_map.
464 
465 Set it to 0 or undefined to make the library using its own implementation of
466 the containers.
467 */
468 #if VMA_USE_STL_CONTAINERS
469 #define VMA_USE_STL_VECTOR 1
470 #define VMA_USE_STL_UNORDERED_MAP 1
471 #define VMA_USE_STL_LIST 1
472 #endif
473 
474 #if VMA_USE_STL_VECTOR
475 #include <vector>
476 #endif
477 
478 #if VMA_USE_STL_UNORDERED_MAP
479 #include <unordered_map>
480 #endif
481 
482 #if VMA_USE_STL_LIST
483 #include <list>
484 #endif
485 
486 /*
487 Following headers are used in this CONFIGURATION section only, so feel free to
488 remove them if not needed.
489 */
490 #include <cassert> // for assert
491 #include <algorithm> // for min, max
492 #include <mutex> // for std::mutex
493 
494 #ifdef _DEBUG
495  // Normal assert to check for programmer's errors, especially in Debug configuration.
496  #define VMA_ASSERT(expr) assert(expr)
497  // Assert that will be called very often, like inside data structures e.g. operator[].
498  // Making it non-empty can make program slow.
499  #define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr)
500 #else
501  #define VMA_ASSERT(expr)
502  #define VMA_HEAVY_ASSERT(expr)
503 #endif
504 
505 // Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.
506 #define VMA_NULL nullptr
507 
508 #define VMA_ALIGN_OF(type) (__alignof(type))
509 #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (_aligned_malloc((size), (alignment)))
510 #define VMA_SYSTEM_FREE(ptr) _aligned_free(ptr)
511 
512 #define VMA_MIN(v1, v2) (std::min((v1), (v2)))
513 #define VMA_MAX(v1, v2) (std::max((v1), (v2)))
514 #define VMA_SWAP(v1, v2) std::swap((v1), (v2))
515 
516 #define VMA_DEBUG_LOG(format, ...)
517 /*
518 #define VMA_DEBUG_LOG(format, ...) do { \
519  printf(format, __VA_ARGS__); \
520  printf("\n"); \
521 } while(false)
522 */
523 
524 #if VMA_STATS_STRING_ENABLED
525 
526 static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num)
527 {
528  _ultoa_s(num, outStr, strLen, 10);
529 }
530 static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)
531 {
532  _ui64toa_s(num, outStr, strLen, 10);
533 }
534 
535 #endif // #if VMA_STATS_STRING_ENABLED
536 
537 class VmaMutex
538 {
539 public:
540  VmaMutex() { }
541  ~VmaMutex() { }
542  void Lock() { m_Mutex.lock(); }
543  void Unlock() { m_Mutex.unlock(); }
544 private:
545  std::mutex m_Mutex;
546 };
547 
548 /*
549 Main parameter for function assessing how good is a free suballocation for a new
550 allocation request.
551 
552 - Set to true to use Best-Fit algorithm - prefer smaller blocks, as close to the
553  size of requested allocations as possible.
554 - Set to false to use Worst-Fit algorithm - prefer larger blocks, as large as
555  possible.
556 
557 Experiments in special testing environment showed that Best-Fit algorithm is
558 better.
559 */
560 static const bool VMA_BEST_FIT = true;
561 
562 /*
563 Every object will have its own allocation.
564 Enable for debugging purposes only.
565 */
566 static const bool VMA_DEBUG_ALWAYS_OWN_MEMORY = false;
567 
568 /*
569 Minimum alignment of all suballocations, in bytes.
570 Set to more than 1 for debugging purposes only. Must be power of two.
571 */
572 static const VkDeviceSize VMA_DEBUG_ALIGNMENT = 1;
573 
574 /*
575 Minimum margin between suballocations, in bytes.
576 Set nonzero for debugging purposes only.
577 */
578 static const VkDeviceSize VMA_DEBUG_MARGIN = 0;
579 
580 /*
581 Set this to 1 for debugging purposes only, to enable single mutex protecting all
582 entry calls to the library. Can be useful for debugging multithreading issues.
583 */
584 #define VMA_DEBUG_GLOBAL_MUTEX 0
585 
586 /*
587 Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity.
588 Set to more than 1 for debugging purposes only. Must be power of two.
589 */
590 static const VkDeviceSize VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY = 1;
591 
592 // Maximum size of a memory heap in Vulkan to consider it "small".
593 static const VkDeviceSize VMA_SMALL_HEAP_MAX_SIZE = 512 * 1024 * 1024;
594 // Default size of a block allocated as single VkDeviceMemory from a "large" heap.
595 static const VkDeviceSize VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE = 256 * 1024 * 1024;
596 // Default size of a block allocated as single VkDeviceMemory from a "small" heap.
597 static const VkDeviceSize VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE = 64 * 1024 * 1024;
598 
599 /*******************************************************************************
600 END OF CONFIGURATION
601 */
602 
603 static VkAllocationCallbacks VmaEmptyAllocationCallbacks = {
604  VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL };
605 
606 // Returns number of bits set to 1 in (v).
607 static inline uint32_t CountBitsSet(uint32_t v)
608 {
609  uint32_t c = v - ((v >> 1) & 0x55555555);
610  c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
611  c = ((c >> 4) + c) & 0x0F0F0F0F;
612  c = ((c >> 8) + c) & 0x00FF00FF;
613  c = ((c >> 16) + c) & 0x0000FFFF;
614  return c;
615 }
616 
617 // Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.
618 // Use types like uint32_t, uint64_t as T.
619 template <typename T>
620 static inline T VmaAlignUp(T val, T align)
621 {
622  return (val + align - 1) / align * align;
623 }
624 
625 // Division with mathematical rounding to nearest number.
626 template <typename T>
627 inline T VmaRoundDiv(T x, T y)
628 {
629  return (x + (y / (T)2)) / y;
630 }
631 /*
632 Returns true if two memory blocks occupy overlapping pages.
633 ResourceA must be in less memory offset than ResourceB.
634 
635 Algorithm is based on "Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)"
636 chapter 11.6 "Resource Memory Association", paragraph "Buffer-Image Granularity".
637 */
638 static inline bool VmaBlocksOnSamePage(
639  VkDeviceSize resourceAOffset,
640  VkDeviceSize resourceASize,
641  VkDeviceSize resourceBOffset,
642  VkDeviceSize pageSize)
643 {
644  VMA_ASSERT(resourceAOffset + resourceASize <= resourceBOffset && resourceASize > 0 && pageSize > 0);
645  VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;
646  VkDeviceSize resourceAEndPage = resourceAEnd & ~(pageSize - 1);
647  VkDeviceSize resourceBStart = resourceBOffset;
648  VkDeviceSize resourceBStartPage = resourceBStart & ~(pageSize - 1);
649  return resourceAEndPage == resourceBStartPage;
650 }
651 
652 enum VmaSuballocationType
653 {
654  VMA_SUBALLOCATION_TYPE_FREE = 0,
655  VMA_SUBALLOCATION_TYPE_UNKNOWN = 1,
656  VMA_SUBALLOCATION_TYPE_BUFFER = 2,
657  VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3,
658  VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4,
659  VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5,
660  VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
661 };
662 
663 /*
664 Returns true if given suballocation types could conflict and must respect
665 VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer
666 or linear image and another one is optimal image. If type is unknown, behave
667 conservatively.
668 */
669 static inline bool VmaIsBufferImageGranularityConflict(
670  VmaSuballocationType suballocType1,
671  VmaSuballocationType suballocType2)
672 {
673  if(suballocType1 > suballocType2)
674  VMA_SWAP(suballocType1, suballocType2);
675 
676  switch(suballocType1)
677  {
678  case VMA_SUBALLOCATION_TYPE_FREE:
679  return false;
680  case VMA_SUBALLOCATION_TYPE_UNKNOWN:
681  return true;
682  case VMA_SUBALLOCATION_TYPE_BUFFER:
683  return
684  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
685  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
686  case VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:
687  return
688  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
689  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||
690  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
691  case VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:
692  return
693  suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
694  case VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:
695  return false;
696  default:
697  VMA_ASSERT(0);
698  return true;
699  }
700 }
701 
702 // Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).
703 struct VmaMutexLock
704 {
705 public:
706  VmaMutexLock(VmaMutex& mutex) : m_Mutex(mutex) { mutex.Lock(); }
707  ~VmaMutexLock() { m_Mutex.Unlock(); }
708 
709 private:
710  VmaMutex& m_Mutex;
711 };
712 
713 #if VMA_DEBUG_GLOBAL_MUTEX
714  static VmaMutex gDebugGlobalMutex;
715  #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex);
716 #else
717  #define VMA_DEBUG_GLOBAL_MUTEX_LOCK
718 #endif
719 
720 // Minimum size of a free suballocation to register it in the free suballocation collection.
721 static const VkDeviceSize VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER = 16;
722 
723 /*
724 Performs binary search and returns iterator to first element that is greater or
725 equal to (key), according to comparison (cmp).
726 
727 Cmp should return true if first argument is less than second argument.
728 
729 Returned value is the found element, if present in the collection or place where
730 new element with value (key) should be inserted.
731 */
732 template <typename IterT, typename KeyT, typename CmpT>
733 static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpT cmp)
734 {
735  size_t down = 0, up = (end - beg);
736  while(down < up)
737  {
738  const size_t mid = (down + up) / 2;
739  if(cmp(*(beg+mid), key))
740  down = mid + 1;
741  else
742  up = mid;
743  }
744  return beg + down;
745 }
746 
748 // Memory allocation
749 
750 static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment)
751 {
752  if((pAllocationCallbacks != VMA_NULL) &&
753  (pAllocationCallbacks->pfnAllocation != VMA_NULL))
754  {
755  return (*pAllocationCallbacks->pfnAllocation)(
756  pAllocationCallbacks->pUserData,
757  size,
758  alignment,
759  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
760  }
761  else
762  {
763  return VMA_SYSTEM_ALIGNED_MALLOC(size, alignment);
764  }
765 }
766 
767 static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr)
768 {
769  if((pAllocationCallbacks != VMA_NULL) &&
770  (pAllocationCallbacks->pfnFree != VMA_NULL))
771  {
772  (*pAllocationCallbacks->pfnFree)(pAllocationCallbacks->pUserData, ptr);
773  }
774  else
775  {
776  VMA_SYSTEM_FREE(ptr);
777  }
778 }
779 
780 template<typename T>
781 static T* VmaAllocate(const VkAllocationCallbacks* pAllocationCallbacks)
782 {
783  return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T), VMA_ALIGN_OF(T));
784 }
785 
786 template<typename T>
787 static T* VmaAllocateArray(const VkAllocationCallbacks* pAllocationCallbacks, size_t count)
788 {
789  return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T) * count, VMA_ALIGN_OF(T));
790 }
791 
792 #define vma_new(allocator, type) new(VmaAllocate<type>(allocator))(type)
793 
794 #define vma_new_array(allocator, type, count) new(VmaAllocateArray<type>((allocator), (count)))(type)
795 
796 template<typename T>
797 static void vma_delete(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr)
798 {
799  ptr->~T();
800  VmaFree(pAllocationCallbacks, ptr);
801 }
802 
803 template<typename T>
804 static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr, size_t count)
805 {
806  if(ptr != VMA_NULL)
807  {
808  for(size_t i = count; i--; )
809  ptr[i].~T();
810  VmaFree(pAllocationCallbacks, ptr);
811  }
812 }
813 
814 // STL-compatible allocator.
815 template<typename T>
816 class VmaStlAllocator
817 {
818 public:
819  const VkAllocationCallbacks* const m_pCallbacks;
820  typedef T value_type;
821 
822  VmaStlAllocator(const VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) { }
823  template<typename U> VmaStlAllocator(const VmaStlAllocator<U>& src) : m_pCallbacks(src.m_pCallbacks) { }
824 
825  T* allocate(size_t n) { return VmaAllocateArray<T>(m_pCallbacks, n); }
826  void deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); }
827 
828  template<typename U>
829  bool operator==(const VmaStlAllocator<U>& rhs) const
830  {
831  return m_pCallbacks == rhs.m_pCallbacks;
832  }
833  template<typename U>
834  bool operator!=(const VmaStlAllocator<U>& rhs) const
835  {
836  return m_pCallbacks != rhs.m_pCallbacks;
837  }
838 };
839 
840 #if VMA_USE_STL_VECTOR
841 
842 #define VmaVector std::vector
843 
844 template<typename T, typename allocatorT>
845 static void VectorInsert(std::vector<T, allocatorT>& vec, size_t index, const T& item)
846 {
847  vec.insert(vec.begin() + index, item);
848 }
849 
850 template<typename T, typename allocatorT>
851 static void VectorRemove(std::vector<T, allocatorT>& vec, size_t index)
852 {
853  vec.erase(vec.begin() + index);
854 }
855 
856 #else // #if VMA_USE_STL_VECTOR
857 
858 /* Class with interface compatible with subset of std::vector.
859 T must be POD because constructors and destructors are not called and memcpy is
860 used for these objects. */
861 template<typename T, typename AllocatorT>
862 class VmaVector
863 {
864 public:
865  VmaVector(AllocatorT& allocator) :
866  m_Allocator(allocator),
867  m_pArray(VMA_NULL),
868  m_Count(0),
869  m_Capacity(0)
870  {
871  }
872 
873  VmaVector(size_t count, AllocatorT& allocator) :
874  m_Allocator(allocator),
875  m_pArray(count ? (T*)VmaAllocateArray<T>(allocator->m_pCallbacks, count) : VMA_NULL),
876  m_Count(count),
877  m_Capacity(count)
878  {
879  }
880 
881  VmaVector(const VmaVector<T, AllocatorT>& src) :
882  m_Allocator(src.m_Allocator),
883  m_pArray(src.m_Count ? (T*)VmaAllocateArray<T>(allocator->m_pCallbacks, src.m_Count) : VMA_NULL),
884  m_Count(src.m_Count),
885  m_Capacity(src.m_Count)
886  {
887  if(m_Count != 0)
888  memcpy(m_pArray, src.m_pArray, m_Count * sizeof(T));
889  }
890 
891  ~VmaVector()
892  {
893  VmaFree(m_Allocator.m_pCallbacks, m_pArray);
894  }
895 
896  VmaVector& operator=(const VmaVector<T, AllocatorT>& rhs)
897  {
898  if(&rhs != this)
899  {
900  Resize(rhs.m_Count);
901  if(m_Count != 0)
902  memcpy(m_pArray, rhs.m_pArray, m_Count * sizeof(T));
903  }
904  return *this;
905  }
906 
907  bool empty() const { return m_Count == 0; }
908  size_t size() const { return m_Count; }
909  T* data() { return m_pArray; }
910  const T* data() const { return m_pArray; }
911 
912  T& operator[](size_t index)
913  {
914  VMA_HEAVY_ASSERT(index < m_Count);
915  return m_pArray[index];
916  }
917  const T& operator[](size_t index) const
918  {
919  VMA_HEAVY_ASSERT(index < m_Count);
920  return m_pArray[index];
921  }
922 
923  T& front()
924  {
925  VMA_HEAVY_ASSERT(m_Count > 0);
926  return m_pArray[0];
927  }
928  const T& front() const
929  {
930  VMA_HEAVY_ASSERT(m_Count > 0);
931  return m_pArray[0];
932  }
933  T& back()
934  {
935  VMA_HEAVY_ASSERT(m_Count > 0);
936  return m_pArray[m_Count - 1];
937  }
938  const T& back() const
939  {
940  VMA_HEAVY_ASSERT(m_Count > 0);
941  return m_pArray[m_Count - 1];
942  }
943 
944  void reserve(size_t newCapacity, bool freeMemory = false)
945  {
946  newCapacity = VMA_MAX(newCapacity, m_Count);
947 
948  if((newCapacity < m_Capacity) && !freeMemory)
949  newCapacity = m_Capacity;
950 
951  if(newCapacity != m_Capacity)
952  {
953  T* const newArray = newCapacity ? VmaAllocateArray<T>(m_hAllocator, newCapacity) : VMA_NULL;
954  if(m_Count != 0)
955  memcpy(newArray, m_pArray, m_Count * sizeof(T));
956  VmaFree(m_Allocator.m_pCallbacks, m_pArray);
957  m_Capacity = newCapacity;
958  m_pArray = newArray;
959  }
960  }
961 
962  void resize(size_t newCount, bool freeMemory = false)
963  {
964  size_t newCapacity = m_Capacity;
965  if(newCount > m_Capacity)
966  newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (size_t)8));
967  else if(freeMemory)
968  newCapacity = newCount;
969 
970  if(newCapacity != m_Capacity)
971  {
972  T* const newArray = newCapacity ? VmaAllocateArray<T>(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL;
973  const size_t elementsToCopy = VMA_MIN(m_Count, newCount);
974  if(elementsToCopy != 0)
975  memcpy(newArray, m_pArray, elementsToCopy * sizeof(T));
976  VmaFree(m_Allocator.m_pCallbacks, m_pArray);
977  m_Capacity = newCapacity;
978  m_pArray = newArray;
979  }
980 
981  m_Count = newCount;
982  }
983 
984  void clear(bool freeMemory = false)
985  {
986  resize(0, freeMemory);
987  }
988 
989  void insert(size_t index, const T& src)
990  {
991  VMA_HEAVY_ASSERT(index <= m_Count);
992  const size_t oldCount = size();
993  resize(oldCount + 1);
994  if(index < oldCount)
995  memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * sizeof(T));
996  m_pArray[index] = src;
997  }
998 
999  void remove(size_t index)
1000  {
1001  VMA_HEAVY_ASSERT(index < m_Count);
1002  const size_t oldCount = size();
1003  if(index < oldCount - 1)
1004  memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * sizeof(T));
1005  resize(oldCount - 1);
1006  }
1007 
1008  void push_back(const T& src)
1009  {
1010  const size_t newIndex = size();
1011  resize(newIndex + 1);
1012  m_pArray[newIndex] = src;
1013  }
1014 
1015  void pop_back()
1016  {
1017  VMA_HEAVY_ASSERT(m_Count > 0);
1018  resize(size() - 1);
1019  }
1020 
1021  void push_front(const T& src)
1022  {
1023  insert(0, src);
1024  }
1025 
1026  void pop_front()
1027  {
1028  VMA_HEAVY_ASSERT(m_Count > 0);
1029  remove(0);
1030  }
1031 
1032  typedef T* iterator;
1033 
1034  iterator begin() { return m_pArray; }
1035  iterator end() { return m_pArray + m_Count; }
1036 
1037 private:
1038  AllocatorT m_Allocator;
1039  T* m_pArray;
1040  size_t m_Count;
1041  size_t m_Capacity;
1042 };
1043 
1044 template<typename T, typename allocatorT>
1045 static void VectorInsert(VmaVector<T, allocatorT>& vec, size_t index, const T& item)
1046 {
1047  vec.insert(index, item);
1048 }
1049 
1050 template<typename T, typename allocatorT>
1051 static void VectorRemove(VmaVector<T, allocatorT>& vec, size_t index)
1052 {
1053  vec.remove(index);
1054 }
1055 
1056 #endif // #if VMA_USE_STL_VECTOR
1057 
1059 // class VmaPoolAllocator
1060 
1061 /*
1062 Allocator for objects of type T using a list of arrays (pools) to speed up
1063 allocation. Number of elements that can be allocated is not bounded because
1064 allocator can create multiple blocks.
1065 */
1066 template<typename T>
1067 class VmaPoolAllocator
1068 {
1069 public:
1070  VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock);
1071  ~VmaPoolAllocator();
1072  void Clear();
1073  T* Alloc();
1074  void Free(T* ptr);
1075 
1076 private:
1077  union Item
1078  {
1079  uint32_t NextFreeIndex;
1080  T Value;
1081  };
1082 
1083  struct ItemBlock
1084  {
1085  Item* pItems;
1086  uint32_t FirstFreeIndex;
1087  };
1088 
1089  const VkAllocationCallbacks* m_pAllocationCallbacks;
1090  size_t m_ItemsPerBlock;
1091  VmaVector< ItemBlock, VmaStlAllocator<ItemBlock> > m_ItemBlocks;
1092 
1093  ItemBlock& CreateNewBlock();
1094 };
1095 
1096 template<typename T>
1097 VmaPoolAllocator<T>::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock) :
1098  m_pAllocationCallbacks(pAllocationCallbacks),
1099  m_ItemsPerBlock(itemsPerBlock),
1100  m_ItemBlocks(VmaStlAllocator<ItemBlock>(pAllocationCallbacks))
1101 {
1102  VMA_ASSERT(itemsPerBlock > 0);
1103 }
1104 
1105 template<typename T>
1106 VmaPoolAllocator<T>::~VmaPoolAllocator()
1107 {
1108  Clear();
1109 }
1110 
1111 template<typename T>
1112 void VmaPoolAllocator<T>::Clear()
1113 {
1114  for(size_t i = m_ItemBlocks.size(); i--; )
1115  vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemsPerBlock);
1116  m_ItemBlocks.clear();
1117 }
1118 
1119 template<typename T>
1120 T* VmaPoolAllocator<T>::Alloc()
1121 {
1122  for(size_t i = m_ItemBlocks.size(); i--; )
1123  {
1124  ItemBlock& block = m_ItemBlocks[i];
1125  // This block has some free items: Use first one.
1126  if(block.FirstFreeIndex != UINT_MAX)
1127  {
1128  Item* const pItem = &block.pItems[block.FirstFreeIndex];
1129  block.FirstFreeIndex = pItem->NextFreeIndex;
1130  return &pItem->Value;
1131  }
1132  }
1133 
1134  // No block has free item: Create new one and use it.
1135  ItemBlock& newBlock = CreateNewBlock();
1136  Item* const pItem = &newBlock.pItems[0];
1137  newBlock.FirstFreeIndex = pItem->NextFreeIndex;
1138  return &pItem->Value;
1139 }
1140 
1141 template<typename T>
1142 void VmaPoolAllocator<T>::Free(T* ptr)
1143 {
1144  // Search all memory blocks to find ptr.
1145  for(size_t i = 0; i < m_ItemBlocks.size(); ++i)
1146  {
1147  ItemBlock& block = m_ItemBlocks[i];
1148 
1149  // Casting to union.
1150  Item* pItemPtr;
1151  memcpy(&pItemPtr, &ptr, sizeof(pItemPtr));
1152 
1153  // Check if pItemPtr is in address range of this block.
1154  if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + m_ItemsPerBlock))
1155  {
1156  const uint32_t index = static_cast<uint32_t>(pItemPtr - block.pItems);
1157  pItemPtr->NextFreeIndex = block.FirstFreeIndex;
1158  block.FirstFreeIndex = index;
1159  return;
1160  }
1161  }
1162  VMA_ASSERT(0 && "Pointer doesn't belong to this memory pool.");
1163 }
1164 
1165 template<typename T>
1166 typename VmaPoolAllocator<T>::ItemBlock& VmaPoolAllocator<T>::CreateNewBlock()
1167 {
1168  ItemBlock newBlock = {
1169  vma_new_array(m_pAllocationCallbacks, Item, m_ItemsPerBlock), 0 };
1170 
1171  m_ItemBlocks.push_back(newBlock);
1172 
1173  // Setup singly-linked list of all free items in this block.
1174  for(uint32_t i = 0; i < m_ItemsPerBlock - 1; ++i)
1175  newBlock.pItems[i].NextFreeIndex = i + 1;
1176  newBlock.pItems[m_ItemsPerBlock - 1].NextFreeIndex = UINT_MAX;
1177  return m_ItemBlocks.back();
1178 }
1179 
1181 // class VmaRawList, VmaList
1182 
1183 #if VMA_USE_STL_LIST
1184 
1185 #define VmaList std::list
1186 
1187 #else // #if VMA_USE_STL_LIST
1188 
1189 template<typename T>
1190 struct VmaListItem
1191 {
1192  VmaListItem* pPrev;
1193  VmaListItem* pNext;
1194  T Value;
1195 };
1196 
1197 // Doubly linked list.
1198 template<typename T>
1199 class VmaRawList
1200 {
1201 public:
1202  typedef VmaListItem<T> ItemType;
1203 
1204  VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks);
1205  ~VmaRawList();
1206  void Clear();
1207 
1208  size_t GetCount() const { return m_Count; }
1209  bool IsEmpty() const { return m_Count == 0; }
1210 
1211  ItemType* Front() { return m_pFront; }
1212  const ItemType* Front() const { return m_pFront; }
1213  ItemType* Back() { return m_pBack; }
1214  const ItemType* Back() const { return m_pBack; }
1215 
1216  ItemType* PushBack();
1217  ItemType* PushFront();
1218  ItemType* PushBack(const T& value);
1219  ItemType* PushFront(const T& value);
1220  void PopBack();
1221  void PopFront();
1222 
1223  // Item can be null - it means PushBack.
1224  ItemType* InsertBefore(ItemType* pItem);
1225  // Item can be null - it means PushFront.
1226  ItemType* InsertAfter(ItemType* pItem);
1227 
1228  ItemType* InsertBefore(ItemType* pItem, const T& value);
1229  ItemType* InsertAfter(ItemType* pItem, const T& value);
1230 
1231  void Remove(ItemType* pItem);
1232 
1233 private:
1234  const VkAllocationCallbacks* const m_pAllocationCallbacks;
1235  VmaPoolAllocator<ItemType> m_ItemAllocator;
1236  ItemType* m_pFront;
1237  ItemType* m_pBack;
1238  size_t m_Count;
1239 
1240  // Declared not defined, to block copy constructor and assignment operator.
1241  VmaRawList(const VmaRawList<T>& src);
1242  VmaRawList<T>& operator=(const VmaRawList<T>& rhs);
1243 };
1244 
1245 template<typename T>
1246 VmaRawList<T>::VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks) :
1247  m_pAllocationCallbacks(pAllocationCallbacks),
1248  m_ItemAllocator(pAllocationCallbacks, 128),
1249  m_pFront(VMA_NULL),
1250  m_pBack(VMA_NULL),
1251  m_Count(0)
1252 {
1253 }
1254 
1255 template<typename T>
1256 VmaRawList<T>::~VmaRawList()
1257 {
1258  // Intentionally not calling Clear, because that would be unnecessary
1259  // computations to return all items to m_ItemAllocator as free.
1260 }
1261 
1262 template<typename T>
1263 void VmaRawList<T>::Clear()
1264 {
1265  if(IsEmpty() == false)
1266  {
1267  ItemType* pItem = m_pBack;
1268  while(pItem != VMA_NULL)
1269  {
1270  ItemType* const pPrevItem = pItem->pPrev;
1271  m_ItemAllocator.Free(pItem);
1272  pItem = pPrevItem;
1273  }
1274  m_pFront = VMA_NULL;
1275  m_pBack = VMA_NULL;
1276  m_Count = 0;
1277  }
1278 }
1279 
1280 template<typename T>
1281 VmaListItem<T>* VmaRawList<T>::PushBack()
1282 {
1283  ItemType* const pNewItem = m_ItemAllocator.Alloc();
1284  pNewItem->pNext = VMA_NULL;
1285  if(IsEmpty())
1286  {
1287  pNewItem->pPrev = VMA_NULL;
1288  m_pFront = pNewItem;
1289  m_pBack = pNewItem;
1290  m_Count = 1;
1291  }
1292  else
1293  {
1294  pNewItem->pPrev = m_pBack;
1295  m_pBack->pNext = pNewItem;
1296  m_pBack = pNewItem;
1297  ++m_Count;
1298  }
1299  return pNewItem;
1300 }
1301 
1302 template<typename T>
1303 VmaListItem<T>* VmaRawList<T>::PushFront()
1304 {
1305  ItemType* const pNewItem = m_ItemAllocator.Alloc();
1306  pNewItem->pPrev = VMA_NULL;
1307  if(IsEmpty())
1308  {
1309  pNewItem->pNext = VMA_NULL;
1310  m_pFront = pNewItem;
1311  m_pBack = pNewItem;
1312  m_Count = 1;
1313  }
1314  else
1315  {
1316  pNewItem->pNext = m_pFront;
1317  m_pFront->pPrev = pNewItem;
1318  m_pFront = pNewItem;
1319  ++m_Count;
1320  }
1321  return pNewItem;
1322 }
1323 
1324 template<typename T>
1325 VmaListItem<T>* VmaRawList<T>::PushBack(const T& value)
1326 {
1327  ItemType* const pNewItem = PushBack();
1328  pNewItem->Value = value;
1329  return pNewItem;
1330 }
1331 
1332 template<typename T>
1333 VmaListItem<T>* VmaRawList<T>::PushFront(const T& value)
1334 {
1335  ItemType* const pNewItem = PushFront();
1336  pNewItem->Value = value;
1337  return newItem;
1338 }
1339 
1340 template<typename T>
1341 void VmaRawList<T>::PopBack()
1342 {
1343  VMA_HEAVY_ASSERT(m_Count > 0);
1344  ItemType* const pBackItem = m_pBack;
1345  ItemType* const pPrevItem = pBackItem->pPrev;
1346  if(pPrevItem != VMA_NULL)
1347  pPrevItem->pNext = VMA_NULL;
1348  m_pBack = pPrevItem;
1349  m_ItemAllocator.Free(pBackItem);
1350  --m_Count;
1351 }
1352 
1353 template<typename T>
1354 void VmaRawList<T>::PopFront()
1355 {
1356  VMA_HEAVY_ASSERT(m_Count > 0);
1357  ItemType* const pFrontItem = m_pFront;
1358  ItemType* const pNextItem = pFrontItem->pNext;
1359  if(pNextItem != VMA_NULL)
1360  pNextItem->pPrev = VMA_NULL;
1361  m_pFront = pNextItem;
1362  m_ItemAllocator.Free(pFrontItem);
1363  --m_Count;
1364 }
1365 
1366 template<typename T>
1367 void VmaRawList<T>::Remove(ItemType* pItem)
1368 {
1369  VMA_HEAVY_ASSERT(pItem != VMA_NULL);
1370  VMA_HEAVY_ASSERT(m_Count > 0);
1371 
1372  if(pItem->pPrev != VMA_NULL)
1373  pItem->pPrev->pNext = pItem->pNext;
1374  else
1375  {
1376  VMA_HEAVY_ASSERT(m_pFront == pItem);
1377  m_pFront = pItem->pNext;
1378  }
1379 
1380  if(pItem->pNext != VMA_NULL)
1381  pItem->pNext->pPrev = pItem->pPrev;
1382  else
1383  {
1384  VMA_HEAVY_ASSERT(m_pBack == pItem);
1385  m_pBack = pItem->pPrev;
1386  }
1387 
1388  m_ItemAllocator.Free(pItem);
1389  --m_Count;
1390 }
1391 
1392 template<typename T>
1393 VmaListItem<T>* VmaRawList<T>::InsertBefore(ItemType* pItem)
1394 {
1395  if(pItem != VMA_NULL)
1396  {
1397  ItemType* const prevItem = pItem->pPrev;
1398  ItemType* const newItem = m_ItemAllocator.Alloc();
1399  newItem->pPrev = prevItem;
1400  newItem->pNext = pItem;
1401  pItem->pPrev = newItem;
1402  if(prevItem != VMA_NULL)
1403  prevItem->pNext = newItem;
1404  else
1405  {
1406  VMA_HEAVY_ASSERT(m_pFront = pItem);
1407  m_pFront = newItem;
1408  }
1409  ++m_Count;
1410  return newItem;
1411  }
1412  else
1413  return PushBack();
1414 }
1415 
1416 template<typename T>
1417 VmaListItem<T>* VmaRawList<T>::InsertAfter(ItemType* pItem)
1418 {
1419  if(pItem != VMA_NULL)
1420  {
1421  ItemType* const nextItem = pItem->pNext;
1422  ItemType* const newItem = m_ItemAllocator.Alloc();
1423  newItem->pNext = nextItem;
1424  newItem->pPrev = pItem;
1425  pItem->pNext = newItem;
1426  if(nextItem != VMA_NULL)
1427  nextItem->pPrev = newItem;
1428  else
1429  {
1430  VMA_HEAVY_ASSERT(m_pBack = pItem);
1431  m_pBack = newItem;
1432  }
1433  ++m_Count;
1434  return newItem;
1435  }
1436  else
1437  return PushFront();
1438 }
1439 
1440 template<typename T>
1441 VmaListItem<T>* VmaRawList<T>::InsertBefore(ItemType* pItem, const T& value)
1442 {
1443  ItemType* const newItem = InsertBefore(pItem);
1444  newItem->Value = value;
1445  return newItem;
1446 }
1447 
1448 template<typename T>
1449 VmaListItem<T>* VmaRawList<T>::InsertAfter(ItemType* pItem, const T& value)
1450 {
1451  ItemType* const newItem = InsertAfter(pItem);
1452  newItem->Value = value;
1453  return newItem;
1454 }
1455 
1456 template<typename T, typename AllocatorT>
1457 class VmaList
1458 {
1459 public:
1460  class iterator
1461  {
1462  public:
1463  iterator() :
1464  m_pList(VMA_NULL),
1465  m_pItem(VMA_NULL)
1466  {
1467  }
1468 
1469  T& operator*() const
1470  {
1471  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1472  return m_pItem->Value;
1473  }
1474  T* operator->() const
1475  {
1476  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1477  return &m_pItem->Value;
1478  }
1479 
1480  iterator& operator++()
1481  {
1482  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1483  m_pItem = m_pItem->pNext;
1484  return *this;
1485  }
1486  iterator& operator--()
1487  {
1488  if(m_pItem != VMA_NULL)
1489  m_pItem = m_pItem->pPrev;
1490  else
1491  {
1492  VMA_HEAVY_ASSERT(!m_pList.IsEmpty());
1493  m_pItem = m_pList->Back();
1494  }
1495  return *this;
1496  }
1497 
1498  iterator operator++(int)
1499  {
1500  iterator result = *this;
1501  ++*this;
1502  return result;
1503  }
1504  iterator operator--(int)
1505  {
1506  iterator result = *this;
1507  --*this;
1508  return result;
1509  }
1510 
1511  bool operator==(const iterator& rhs) const
1512  {
1513  VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);
1514  return m_pItem == rhs.m_pItem;
1515  }
1516  bool operator!=(const iterator& rhs) const
1517  {
1518  VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);
1519  return m_pItem != rhs.m_pItem;
1520  }
1521 
1522  private:
1523  VmaRawList<T>* m_pList;
1524  VmaListItem<T>* m_pItem;
1525 
1526  iterator(VmaRawList<T>* pList, VmaListItem<T>* pItem) :
1527  m_pList(pList),
1528  m_pItem(pItem)
1529  {
1530  }
1531 
1532  friend class VmaList<T, AllocatorT>;
1533  friend class VmaList<T, AllocatorT>:: const_iterator;
1534  };
1535 
1536  class const_iterator
1537  {
1538  public:
1539  const_iterator() :
1540  m_pList(VMA_NULL),
1541  m_pItem(VMA_NULL)
1542  {
1543  }
1544 
1545  const_iterator(const iterator& src) :
1546  m_pList(src.m_pList),
1547  m_pItem(src.m_pItem)
1548  {
1549  }
1550 
1551  const T& operator*() const
1552  {
1553  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1554  return m_pItem->Value;
1555  }
1556  const T* operator->() const
1557  {
1558  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1559  return &m_pItem->Value;
1560  }
1561 
1562  const_iterator& operator++()
1563  {
1564  VMA_HEAVY_ASSERT(m_pItem != VMA_NULL);
1565  m_pItem = m_pItem->pNext;
1566  return *this;
1567  }
1568  const_iterator& operator--()
1569  {
1570  if(m_pItem != VMA_NULL)
1571  m_pItem = m_pItem->pPrev;
1572  else
1573  {
1574  VMA_HEAVY_ASSERT(!m_pList->IsEmpty());
1575  m_pItem = m_pList->Back();
1576  }
1577  return *this;
1578  }
1579 
1580  const_iterator operator++(int)
1581  {
1582  const_iterator result = *this;
1583  ++*this;
1584  return result;
1585  }
1586  const_iterator operator--(int)
1587  {
1588  const_iterator result = *this;
1589  --*this;
1590  return result;
1591  }
1592 
1593  bool operator==(const const_iterator& rhs) const
1594  {
1595  VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);
1596  return m_pItem == rhs.m_pItem;
1597  }
1598  bool operator!=(const const_iterator& rhs) const
1599  {
1600  VMA_HEAVY_ASSERT(m_pList == rhs.m_pList);
1601  return m_pItem != rhs.m_pItem;
1602  }
1603 
1604  private:
1605  const_iterator(const VmaRawList<T>* pList, const VmaListItem<T>* pItem) :
1606  m_pList(pList),
1607  m_pItem(pItem)
1608  {
1609  }
1610 
1611  const VmaRawList<T>* m_pList;
1612  const VmaListItem<T>* m_pItem;
1613 
1614  friend class VmaList<T, AllocatorT>;
1615  };
1616 
1617  VmaList(AllocatorT& allocator) : m_RawList(allocator.m_pCallbacks) { }
1618 
1619  bool empty() const { return m_RawList.IsEmpty(); }
1620  size_t size() const { return m_RawList.GetCount(); }
1621 
1622  iterator begin() { return iterator(&m_RawList, m_RawList.Front()); }
1623  iterator end() { return iterator(&m_RawList, VMA_NULL); }
1624 
1625  const_iterator cbegin() const { return const_iterator(&m_RawList, m_RawList.Front()); }
1626  const_iterator cend() const { return const_iterator(&m_RawList, VMA_NULL); }
1627 
1628  void clear() { m_RawList.Clear(); }
1629  void push_back(const T& value) { m_RawList.PushBack(value); }
1630  void erase(iterator it) { m_RawList.Remove(it.m_pItem); }
1631  iterator insert(iterator it, const T& value) { return iterator(&m_RawList, m_RawList.InsertBefore(it.m_pItem, value)); }
1632 
1633 private:
1634  VmaRawList<T> m_RawList;
1635 };
1636 
1637 #endif // #if VMA_USE_STL_LIST
1638 
1640 // class VmaMap
1641 
1642 #if VMA_USE_STL_UNORDERED_MAP
1643 
1644 #define VmaPair std::pair
1645 
1646 #define VMA_MAP_TYPE(KeyT, ValueT) \
1647  std::unordered_map< KeyT, ValueT, std::hash<KeyT>, std::equal_to<KeyT>, VmaStlAllocator< std::pair<KeyT, ValueT> > >
1648 
1649 #else // #if VMA_USE_STL_UNORDERED_MAP
1650 
1651 template<typename T1, typename T2>
1652 struct VmaPair
1653 {
1654  T1 first;
1655  T2 second;
1656 
1657  VmaPair() : first(), second() { }
1658  VmaPair(const T1& firstSrc, const T2& secondSrc) : first(firstSrc), second(secondSrc) { }
1659 };
1660 
1661 /* Class compatible with subset of interface of std::unordered_map.
1662 KeyT, ValueT must be POD because they will be stored in VmaVector.
1663 */
1664 template<typename KeyT, typename ValueT>
1665 class VmaMap
1666 {
1667 public:
1668  typedef VmaPair<KeyT, ValueT> PairType;
1669  typedef PairType* iterator;
1670 
1671  VmaMap(VmaStlAllocator<PairType>& allocator) : m_Vector(allocator) { }
1672 
1673  iterator begin() { return m_Vector.begin(); }
1674  iterator end() { return m_Vector.end(); }
1675 
1676  void insert(const PairType& pair);
1677  iterator find(const KeyT& key);
1678  void erase(iterator it);
1679 
1680 private:
1681  VmaVector< PairType, VmaStlAllocator<PairType> > m_Vector;
1682 };
1683 
1684 #define VMA_MAP_TYPE(KeyT, ValueT) VmaMap<KeyT, ValueT>
1685 
1686 template<typename FirstT, typename SecondT>
1687 struct VmaPairFirstLess
1688 {
1689  bool operator()(const VmaPair<FirstT, SecondT>& lhs, const VmaPair<FirstT, SecondT>& rhs) const
1690  {
1691  return lhs.first < rhs.first;
1692  }
1693  bool operator()(const VmaPair<FirstT, SecondT>& lhs, const FirstT& rhsFirst) const
1694  {
1695  return lhs.first < rhsFirst;
1696  }
1697 };
1698 
1699 template<typename KeyT, typename ValueT>
1700 void VmaMap<KeyT, ValueT>::insert(const PairType& pair)
1701 {
1702  const size_t indexToInsert = VmaBinaryFindFirstNotLess(
1703  m_Vector.data(),
1704  m_Vector.data() + m_Vector.size(),
1705  pair,
1706  VmaPairFirstLess<KeyT, ValueT>()) - m_Vector.data();
1707  VectorInsert(m_Vector, indexToInsert, pair);
1708 }
1709 
1710 template<typename KeyT, typename ValueT>
1711 VmaPair<KeyT, ValueT>* VmaMap<KeyT, ValueT>::find(const KeyT& key)
1712 {
1713  PairType* it = VmaBinaryFindFirstNotLess(
1714  m_Vector.data(),
1715  m_Vector.data() + m_Vector.size(),
1716  key,
1717  VmaPairFirstLess<KeyT, ValueT>());
1718  if((it != m_Vector.end()) && (it->first == key))
1719  return it;
1720  else
1721  return m_Vector.end();
1722 }
1723 
1724 template<typename KeyT, typename ValueT>
1725 void VmaMap<KeyT, ValueT>::erase(iterator it)
1726 {
1727  VectorRemove(m_Vector, it - m_Vector.begin());
1728 }
1729 
1730 #endif // #if VMA_USE_STL_UNORDERED_MAP
1731 
1732 /*
1733 Represents a region of VmaAllocation that is either assigned and returned as
1734 allocated memory block or free.
1735 */
1736 struct VmaSuballocation
1737 {
1738  VkDeviceSize offset;
1739  VkDeviceSize size;
1740  VmaSuballocationType type;
1741 };
1742 
1743 typedef VmaList< VmaSuballocation, VmaStlAllocator<VmaSuballocation> > VmaSuballocationList;
1744 
1745 // Parameters of an allocation.
1746 struct VmaAllocationRequest
1747 {
1748  VmaSuballocationList::iterator freeSuballocationItem;
1749  VkDeviceSize offset;
1750 };
1751 
1752 /* Single block of memory - VkDeviceMemory with all the data about its regions
1753 assigned or free. */
1754 class VmaAllocation
1755 {
1756 public:
1757  VkDeviceMemory m_hMemory;
1758  VkDeviceSize m_Size;
1759  uint32_t m_FreeCount;
1760  VkDeviceSize m_SumFreeSize;
1761  VmaSuballocationList m_Suballocations;
1762  // Suballocations that are free and have size greater than certain threshold.
1763  // Sorted by size, ascending.
1764  VmaVector< VmaSuballocationList::iterator, VmaStlAllocator< VmaSuballocationList::iterator > > m_FreeSuballocationsBySize;
1765 
1766  VmaAllocation(VmaAllocator hAllocator);
1767 
1768  ~VmaAllocation()
1769  {
1770  VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
1771  }
1772 
1773  // Always call after construction.
1774  void Init(VkDeviceMemory newMemory, VkDeviceSize newSize);
1775  // Always call before destruction.
1776  void Destroy(VmaAllocator allocator);
1777 
1778  // Validates all data structures inside this object. If not valid, returns false.
1779  bool Validate() const;
1780 
1781  // Tries to find a place for suballocation with given parameters inside this allocation.
1782  // If succeeded, fills pAllocationRequest and returns true.
1783  // If failed, returns false.
1784  bool CreateAllocationRequest(
1785  VkDeviceSize bufferImageGranularity,
1786  VkDeviceSize allocSize,
1787  VkDeviceSize allocAlignment,
1788  VmaSuballocationType allocType,
1789  VmaAllocationRequest* pAllocationRequest);
1790 
1791  // Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem.
1792  // If yes, fills pOffset and returns true. If no, returns false.
1793  bool CheckAllocation(
1794  VkDeviceSize bufferImageGranularity,
1795  VkDeviceSize allocSize,
1796  VkDeviceSize allocAlignment,
1797  VmaSuballocationType allocType,
1798  VmaSuballocationList::const_iterator freeSuballocItem,
1799  VkDeviceSize* pOffset) const;
1800 
1801  // Returns true if this allocation is empty - contains only single free suballocation.
1802  bool IsEmpty() const;
1803 
1804  // Makes actual allocation based on request. Request must already be checked
1805  // and valid.
1806  void Alloc(
1807  const VmaAllocationRequest& request,
1808  VmaSuballocationType type,
1809  VkDeviceSize allocSize);
1810 
1811  // Frees suballocation assigned to given memory region.
1812  void Free(const VkMappedMemoryRange* pMemory);
1813 
1814 #if VMA_STATS_STRING_ENABLED
1815  void PrintDetailedMap(class VmaStringBuilder& sb) const;
1816 #endif
1817 
1818 private:
1819  // Given free suballocation, it merges it with following one, which must also be free.
1820  void MergeFreeWithNext(VmaSuballocationList::iterator item);
1821  // Releases given suballocation, making it free. Merges it with adjacent free
1822  // suballocations if applicable.
1823  void FreeSuballocation(VmaSuballocationList::iterator suballocItem);
1824  // Given free suballocation, it inserts it into sorted list of
1825  // m_FreeSuballocationsBySize if it's suitable.
1826  void RegisterFreeSuballocation(VmaSuballocationList::iterator item);
1827  // Given free suballocation, it removes it from sorted list of
1828  // m_FreeSuballocationsBySize if it's suitable.
1829  void UnregisterFreeSuballocation(VmaSuballocationList::iterator item);
1830 };
1831 
1832 // Allocation for an object that has its own private VkDeviceMemory.
1833 struct VmaOwnAllocation
1834 {
1835  VkDeviceMemory m_hMemory;
1836  VkDeviceSize m_Size;
1837  VmaSuballocationType m_Type;
1838 };
1839 
1840 struct VmaOwnAllocationMemoryHandleLess
1841 {
1842  bool operator()(const VmaOwnAllocation& lhs, const VmaOwnAllocation& rhs) const
1843  {
1844  return lhs.m_hMemory < rhs.m_hMemory;
1845  }
1846  bool operator()(const VmaOwnAllocation& lhs, VkDeviceMemory rhsMem) const
1847  {
1848  return lhs.m_hMemory < rhsMem;
1849  }
1850 };
1851 
1852 /* Sequence of VmaAllocation. Represents memory blocks allocated for a specific
1853 Vulkan memory type. */
1854 struct VmaAllocationVector
1855 {
1856  // Incrementally sorted by sumFreeSize, ascending.
1857  VmaVector< VmaAllocation*, VmaStlAllocator<VmaAllocation*> > m_Allocations;
1858 
1859  VmaAllocationVector(VmaAllocator hAllocator);
1860  ~VmaAllocationVector();
1861 
1862  bool IsEmpty() const { return m_Allocations.empty(); }
1863 
1864  // Tries to free memory from any if its Allocations.
1865  // Returns index of Allocation that the memory was freed from, or -1 if not found.
1866  size_t Free(const VkMappedMemoryRange* pMemory);
1867 
1868  // Performs single step in sorting m_Allocations. They may not be fully sorted
1869  // after this call.
1870  void IncrementallySortAllocations();
1871 
1872  // Adds statistics of this AllocationVector to pStats.
1873  void AddStats(VmaStats* pStats, uint32_t memTypeIndex, uint32_t memHeapIndex) const;
1874 
1875 #if VMA_STATS_STRING_ENABLED
1876  void PrintDetailedMap(class VmaStringBuilder& sb) const;
1877 #endif
1878 
1879 private:
1880  VmaAllocator m_hAllocator;
1881 };
1882 
1883 // Main allocator object.
1884 struct VmaAllocator_T
1885 {
1886  VkDevice m_hDevice;
1887  bool m_AllocationCallbacksSpecified;
1888  VkAllocationCallbacks m_AllocationCallbacks;
1889  VkDeviceSize m_PreferredLargeHeapBlockSize;
1890  VkDeviceSize m_PreferredSmallHeapBlockSize;
1891 
1892  VkPhysicalDeviceProperties m_PhysicalDeviceProperties;
1893  VkPhysicalDeviceMemoryProperties m_MemProps;
1894 
1895  VmaAllocationVector* m_pAllocations[VK_MAX_MEMORY_TYPES];
1896  /* There can be at most one allocation that is completely empty - a
1897  hysteresis to avoid pessimistic case of alternating creation and destruction
1898  of a VkDeviceMemory. */
1899  bool m_HasEmptyAllocation[VK_MAX_MEMORY_TYPES];
1900  VmaMutex m_AllocationsMutex[VK_MAX_MEMORY_TYPES];
1901 
1902  // Each vector is sorted by memory (handle value).
1903  typedef VmaVector< VmaOwnAllocation, VmaStlAllocator<VmaOwnAllocation> > OwnAllocationVectorType;
1904  OwnAllocationVectorType* m_pOwnAllocations[VK_MAX_MEMORY_TYPES];
1905  VmaMutex m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
1906 
1907  // Sorted by first (VkBuffer handle value).
1908  VMA_MAP_TYPE(VkBuffer, VkMappedMemoryRange) m_BufferToMemoryMap;
1909  VmaMutex m_BufferToMemoryMapMutex;
1910  // Sorted by first (VkImage handle value).
1911  VMA_MAP_TYPE(VkImage, VkMappedMemoryRange) m_ImageToMemoryMap;
1912  VmaMutex m_ImageToMemoryMapMutex;
1913 
1914  VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);
1915  ~VmaAllocator_T();
1916 
1917  const VkAllocationCallbacks* GetAllocationCallbacks() const
1918  {
1919  return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : 0;
1920  }
1921 
1922  VkDeviceSize GetPreferredBlockSize(uint32_t memTypeIndex) const;
1923 
1924  VkDeviceSize GetBufferImageGranularity() const
1925  {
1926  return VMA_MAX(
1927  VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,
1928  m_PhysicalDeviceProperties.limits.bufferImageGranularity);
1929  }
1930 
1931  uint32_t GetMemoryHeapCount() const { return m_MemProps.memoryHeapCount; }
1932  uint32_t GetMemoryTypeCount() const { return m_MemProps.memoryTypeCount; }
1933 
1934  // Main allocation function.
1935  VkResult AllocateMemory(
1936  const VkMemoryRequirements& vkMemReq,
1937  const VmaMemoryRequirements& vmaMemReq,
1938  VmaSuballocationType suballocType,
1939  VkMappedMemoryRange* pMemory,
1940  uint32_t* pMemoryTypeIndex);
1941 
1942  // Main deallocation function.
1943  void FreeMemory(const VkMappedMemoryRange* pMemory);
1944 
1945  void CalculateStats(VmaStats* pStats);
1946 
1947 #if VMA_STATS_STRING_ENABLED
1948  void PrintDetailedMap(class VmaStringBuilder& sb);
1949 #endif
1950 
1951 private:
1952  VkPhysicalDevice m_PhysicalDevice;
1953 
1954  VkResult AllocateMemoryOfType(
1955  const VkMemoryRequirements& vkMemReq,
1956  const VmaMemoryRequirements& vmaMemReq,
1957  uint32_t memTypeIndex,
1958  VmaSuballocationType suballocType,
1959  VkMappedMemoryRange* pMemory);
1960 
1961  // Allocates and registers new VkDeviceMemory specifically for single allocation.
1962  VkResult AllocateOwnMemory(
1963  VkDeviceSize size,
1964  VmaSuballocationType suballocType,
1965  uint32_t memTypeIndex,
1966  VkMappedMemoryRange* pMemory);
1967 
1968  // Tries to free pMemory as Own Memory. Returns true if found and freed.
1969  bool FreeOwnMemory(const VkMappedMemoryRange* pMemory);
1970 };
1971 
1973 // Memory allocation #2 after VmaAllocator_T definition
1974 
1975 static void* VmaMalloc(VmaAllocator hAllocator, size_t size, size_t alignment)
1976 {
1977  return VmaMalloc(&hAllocator->m_AllocationCallbacks, size, alignment);
1978 }
1979 
1980 static void VmaFree(VmaAllocator hAllocator, void* ptr)
1981 {
1982  VmaFree(&hAllocator->m_AllocationCallbacks, ptr);
1983 }
1984 
1985 template<typename T>
1986 static T* VmaAllocate(VmaAllocator hAllocator)
1987 {
1988  return (T*)VmaMalloc(hAllocator, sizeof(T), VMA_ALIGN_OF(T));
1989 }
1990 
1991 template<typename T>
1992 static T* VmaAllocateArray(VmaAllocator hAllocator, size_t count)
1993 {
1994  return (T*)VmaMalloc(hAllocator, sizeof(T) * count, VMA_ALIGN_OF(T));
1995 }
1996 
1997 template<typename T>
1998 static void vma_delete(VmaAllocator hAllocator, T* ptr)
1999 {
2000  if(ptr != VMA_NULL)
2001  {
2002  ptr->~T();
2003  VmaFree(hAllocator, ptr);
2004  }
2005 }
2006 
2007 template<typename T>
2008 static void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count)
2009 {
2010  if(ptr != VMA_NULL)
2011  {
2012  for(size_t i = count; i--; )
2013  ptr[i].~T();
2014  VmaFree(hAllocator, ptr);
2015  }
2016 }
2017 
2019 // VmaStringBuilder
2020 
2021 #if VMA_STATS_STRING_ENABLED
2022 
2023 class VmaStringBuilder
2024 {
2025 public:
2026  VmaStringBuilder(VmaAllocator alloc) : m_Data(VmaStlAllocator<char>(alloc->GetAllocationCallbacks())) { }
2027  size_t GetLength() const { return m_Data.size(); }
2028  const char* GetData() const { return m_Data.data(); }
2029 
2030  void Add(char ch) { m_Data.push_back(ch); }
2031  void Add(const char* pStr);
2032  void AddNewLine() { Add('\n'); }
2033  void AddNumber(uint32_t num);
2034  void AddNumber(uint64_t num);
2035  void AddBool(bool b) { Add(b ? "true" : "false"); }
2036  void AddNull() { Add("null"); }
2037  void AddString(const char* pStr);
2038 
2039 private:
2040  VmaVector< char, VmaStlAllocator<char> > m_Data;
2041 };
2042 
2043 void VmaStringBuilder::Add(const char* pStr)
2044 {
2045  const size_t strLen = strlen(pStr);
2046  if(strLen > 0)
2047  {
2048  const size_t oldCount = m_Data.size();
2049  m_Data.resize(oldCount + strLen);
2050  memcpy(m_Data.data() + oldCount, pStr, strLen);
2051  }
2052 }
2053 
2054 void VmaStringBuilder::AddNumber(uint32_t num)
2055 {
2056  char buf[11];
2057  VmaUint32ToStr(buf, sizeof(buf), num);
2058  Add(buf);
2059 }
2060 
2061 void VmaStringBuilder::AddNumber(uint64_t num)
2062 {
2063  char buf[21];
2064  VmaUint64ToStr(buf, sizeof(buf), num);
2065  Add(buf);
2066 }
2067 
2068 void VmaStringBuilder::AddString(const char* pStr)
2069 {
2070  Add('"');
2071  const size_t strLen = strlen(pStr);
2072  for(size_t i = 0; i < strLen; ++i)
2073  {
2074  char ch = pStr[i];
2075  if(ch == '\'')
2076  Add("\\\\");
2077  else if(ch == '"')
2078  Add("\\\"");
2079  else if(ch >= 32)
2080  Add(ch);
2081  else switch(ch)
2082  {
2083  case '\n':
2084  Add("\\n");
2085  break;
2086  case '\r':
2087  Add("\\r");
2088  break;
2089  case '\t':
2090  Add("\\t");
2091  break;
2092  default:
2093  VMA_ASSERT(0 && "Character not currently supported.");
2094  break;
2095  }
2096  }
2097  Add('"');
2098 }
2099 
2101 
2102 // Correspond to values of enum VmaSuballocationType.
2103 static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = {
2104  "FREE",
2105  "UNKNOWN",
2106  "BUFFER",
2107  "IMAGE_UNKNOWN",
2108  "IMAGE_LINEAR",
2109  "IMAGE_OPTIMAL",
2110 };
2111 
2112 static void VmaPrintStatInfo(VmaStringBuilder& sb, const VmaStatInfo& stat)
2113 {
2114  sb.Add("{ \"Allocations\": ");
2115  sb.AddNumber(stat.AllocationCount);
2116  sb.Add(", \"Suballocations\": ");
2117  sb.AddNumber(stat.SuballocationCount);
2118  sb.Add(", \"UnusedRanges\": ");
2119  sb.AddNumber(stat.UnusedRangeCount);
2120  sb.Add(", \"UsedBytes\": ");
2121  sb.AddNumber(stat.UsedBytes);
2122  sb.Add(", \"UnusedBytes\": ");
2123  sb.AddNumber(stat.UnusedBytes);
2124  sb.Add(", \"SuballocationSize\": { \"Min\": ");
2125  sb.AddNumber(stat.SuballocationSizeMin);
2126  sb.Add(", \"Avg\": ");
2127  sb.AddNumber(stat.SuballocationSizeAvg);
2128  sb.Add(", \"Max\": ");
2129  sb.AddNumber(stat.SuballocationSizeMax);
2130  sb.Add(" }, \"UnusedRangeSize\": { \"Min\": ");
2131  sb.AddNumber(stat.UnusedRangeSizeMin);
2132  sb.Add(", \"Avg\": ");
2133  sb.AddNumber(stat.UnusedRangeSizeAvg);
2134  sb.Add(", \"Max\": ");
2135  sb.AddNumber(stat.UnusedRangeSizeMax);
2136  sb.Add(" } }");
2137 }
2138 
2139 #endif // #if VMA_STATS_STRING_ENABLED
2140 
2141 struct VmaSuballocationItemSizeLess
2142 {
2143  bool operator()(
2144  const VmaSuballocationList::iterator lhs,
2145  const VmaSuballocationList::iterator rhs) const
2146  {
2147  return lhs->size < rhs->size;
2148  }
2149  bool operator()(
2150  const VmaSuballocationList::iterator lhs,
2151  VkDeviceSize rhsSize) const
2152  {
2153  return lhs->size < rhsSize;
2154  }
2155 };
2156 
2157 VmaAllocation::VmaAllocation(VmaAllocator hAllocator) :
2158  m_hMemory(VK_NULL_HANDLE),
2159  m_Size(0),
2160  m_FreeCount(0),
2161  m_SumFreeSize(0),
2162  m_Suballocations(VmaStlAllocator<VmaSuballocation>(hAllocator->GetAllocationCallbacks())),
2163  m_FreeSuballocationsBySize(VmaStlAllocator<VmaSuballocationList::iterator>(hAllocator->GetAllocationCallbacks()))
2164 {
2165 }
2166 
2167 void VmaAllocation::Init(VkDeviceMemory newMemory, VkDeviceSize newSize)
2168 {
2169  VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
2170 
2171  m_hMemory = newMemory;
2172  m_Size = newSize;
2173  m_FreeCount = 1;
2174  m_SumFreeSize = newSize;
2175 
2176  m_Suballocations.clear();
2177  m_FreeSuballocationsBySize.clear();
2178 
2179  VmaSuballocation suballoc = {};
2180  suballoc.offset = 0;
2181  suballoc.size = newSize;
2182  suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
2183 
2184  m_Suballocations.push_back(suballoc);
2185  VmaSuballocationList::iterator suballocItem = m_Suballocations.end();
2186  --suballocItem;
2187  m_FreeSuballocationsBySize.push_back(suballocItem);
2188 }
2189 
2190 void VmaAllocation::Destroy(VmaAllocator allocator)
2191 {
2192  VMA_ASSERT(m_hMemory != VK_NULL_HANDLE);
2193  vkFreeMemory(allocator->m_hDevice, m_hMemory, allocator->GetAllocationCallbacks());
2194  m_hMemory = VK_NULL_HANDLE;
2195 }
2196 
2197 bool VmaAllocation::Validate() const
2198 {
2199  if((m_hMemory == VK_NULL_HANDLE) ||
2200  (m_Size == 0) ||
2201  m_Suballocations.empty())
2202  {
2203  return false;
2204  }
2205 
2206  // Expected offset of new suballocation as calculates from previous ones.
2207  VkDeviceSize calculatedOffset = 0;
2208  // Expected number of free suballocations as calculated from traversing their list.
2209  uint32_t calculatedFreeCount = 0;
2210  // Expected sum size of free suballocations as calculated from traversing their list.
2211  VkDeviceSize calculatedSumFreeSize = 0;
2212  // Expected number of free suballocations that should be registered in
2213  // m_FreeSuballocationsBySize calculated from traversing their list.
2214  size_t freeSuballocationsToRegister = 0;
2215  // True if previous visisted suballocation was free.
2216  bool prevFree = false;
2217 
2218  for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();
2219  suballocItem != m_Suballocations.cend();
2220  ++suballocItem)
2221  {
2222  const VmaSuballocation& subAlloc = *suballocItem;
2223 
2224  // Actual offset of this suballocation doesn't match expected one.
2225  if(subAlloc.offset != calculatedOffset)
2226  return false;
2227 
2228  const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);
2229  // Two adjacent free suballocations are invalid. They should be merged.
2230  if(prevFree && currFree)
2231  return false;
2232  prevFree = currFree;
2233 
2234  if(currFree)
2235  {
2236  calculatedSumFreeSize += subAlloc.size;
2237  ++calculatedFreeCount;
2238  if(subAlloc.size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)
2239  ++freeSuballocationsToRegister;
2240  }
2241 
2242  calculatedOffset += subAlloc.size;
2243  }
2244 
2245  // Number of free suballocations registered in m_FreeSuballocationsBySize doesn't
2246  // match expected one.
2247  if(m_FreeSuballocationsBySize.size() != freeSuballocationsToRegister)
2248  return false;
2249 
2250  VkDeviceSize lastSize = 0;
2251  for(size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i)
2252  {
2253  VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];
2254 
2255  // Only free suballocations can be registered in m_FreeSuballocationsBySize.
2256  if(suballocItem->type != VMA_SUBALLOCATION_TYPE_FREE)
2257  return false;
2258  // They must be sorted by size ascending.
2259  if(suballocItem->size < lastSize)
2260  return false;
2261 
2262  lastSize = suballocItem->size;
2263  }
2264 
2265  // Check if totals match calculacted values.
2266  return
2267  (calculatedOffset == m_Size) &&
2268  (calculatedSumFreeSize == m_SumFreeSize) &&
2269  (calculatedFreeCount == m_FreeCount);
2270 }
2271 
2272 /*
2273 How many suitable free suballocations to analyze before choosing best one.
2274 - Set to 1 to use First-Fit algorithm - first suitable free suballocation will
2275  be chosen.
2276 - Set to UINT_MAX to use Best-Fit/Worst-Fit algorithm - all suitable free
2277  suballocations will be analized and best one will be chosen.
2278 - Any other value is also acceptable.
2279 */
2280 //static const uint32_t MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK = 8;
2281 
2282 bool VmaAllocation::CreateAllocationRequest(
2283  VkDeviceSize bufferImageGranularity,
2284  VkDeviceSize allocSize,
2285  VkDeviceSize allocAlignment,
2286  VmaSuballocationType allocType,
2287  VmaAllocationRequest* pAllocationRequest)
2288 {
2289  VMA_ASSERT(allocSize > 0);
2290  VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);
2291  VMA_ASSERT(pAllocationRequest != VMA_NULL);
2292  VMA_HEAVY_ASSERT(Validate());
2293 
2294  // There is not enough total free space in this allocation to fullfill the request: Early return.
2295  if(m_SumFreeSize < allocSize)
2296  return false;
2297 
2298  bool found = false;
2299 
2300  // Old brute-force algorithm, linearly searching suballocations.
2301  /*
2302  uint32_t suitableSuballocationsFound = 0;
2303  for(VmaSuballocationList::iterator suballocItem = suballocations.Front();
2304  suballocItem != VMA_NULL &&
2305  suitableSuballocationsFound < MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK;
2306  suballocItem = suballocItem->Next)
2307  {
2308  if(suballocItem->Value.type == VMA_SUBALLOCATION_TYPE_FREE)
2309  {
2310  VkDeviceSize offset = 0, cost = 0;
2311  if(CheckAllocation(bufferImageGranularity, allocSize, allocAlignment, allocType, suballocItem, &offset, &cost))
2312  {
2313  ++suitableSuballocationsFound;
2314  if(cost < costLimit)
2315  {
2316  pAllocationRequest->freeSuballocationItem = suballocItem;
2317  pAllocationRequest->offset = offset;
2318  pAllocationRequest->cost = cost;
2319  if(cost == 0)
2320  return true;
2321  costLimit = cost;
2322  betterSuballocationFound = true;
2323  }
2324  }
2325  }
2326  }
2327  */
2328 
2329  // New algorithm, efficiently searching freeSuballocationsBySize.
2330  const size_t freeSuballocCount = m_FreeSuballocationsBySize.size();
2331  if(freeSuballocCount > 0)
2332  {
2333  if(VMA_BEST_FIT)
2334  {
2335  // Find first free suballocation with size not less than allocSize.
2336  VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(
2337  m_FreeSuballocationsBySize.data(),
2338  m_FreeSuballocationsBySize.data() + freeSuballocCount,
2339  allocSize,
2340  VmaSuballocationItemSizeLess());
2341  size_t index = it - m_FreeSuballocationsBySize.data();
2342  for(; index < freeSuballocCount; ++index)
2343  {
2344  VkDeviceSize offset = 0;
2345  const VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[index];
2346  if(CheckAllocation(bufferImageGranularity, allocSize, allocAlignment, allocType, suballocItem, &offset))
2347  {
2348  pAllocationRequest->freeSuballocationItem = suballocItem;
2349  pAllocationRequest->offset = offset;
2350  return true;
2351  }
2352  }
2353  }
2354  else
2355  {
2356  // Search staring from biggest suballocations.
2357  for(size_t index = freeSuballocCount; index--; )
2358  {
2359  VkDeviceSize offset = 0;
2360  const VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[index];
2361  if(CheckAllocation(bufferImageGranularity, allocSize, allocAlignment, allocType, suballocItem, &offset))
2362  {
2363  pAllocationRequest->freeSuballocationItem = suballocItem;
2364  pAllocationRequest->offset = offset;
2365  return true;
2366  }
2367  }
2368  }
2369  }
2370 
2371  return false;
2372 }
2373 
2374 bool VmaAllocation::CheckAllocation(
2375  VkDeviceSize bufferImageGranularity,
2376  VkDeviceSize allocSize,
2377  VkDeviceSize allocAlignment,
2378  VmaSuballocationType allocType,
2379  VmaSuballocationList::const_iterator freeSuballocItem,
2380  VkDeviceSize* pOffset) const
2381 {
2382  VMA_ASSERT(allocSize > 0);
2383  VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);
2384  VMA_ASSERT(freeSuballocItem != m_Suballocations.cend());
2385  VMA_ASSERT(pOffset != VMA_NULL);
2386 
2387  const VmaSuballocation& suballoc = *freeSuballocItem;
2388  VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
2389 
2390  // Size of this suballocation is too small for this request: Early return.
2391  if(suballoc.size < allocSize)
2392  return false;
2393 
2394  // Start from offset equal to beginning of this suballocation.
2395  *pOffset = suballoc.offset;
2396 
2397  // Apply VMA_DEBUG_MARGIN at the beginning.
2398  if((VMA_DEBUG_MARGIN > 0) && freeSuballocItem != m_Suballocations.cbegin())
2399  *pOffset += VMA_DEBUG_MARGIN;
2400 
2401  // Apply alignment.
2402  const VkDeviceSize alignment = VMA_MAX(allocAlignment, VMA_DEBUG_ALIGNMENT);
2403  *pOffset = VmaAlignUp(*pOffset, alignment);
2404 
2405  // Check previous suballocations for BufferImageGranularity conflicts.
2406  // Make bigger alignment if necessary.
2407  if(bufferImageGranularity > 1)
2408  {
2409  bool bufferImageGranularityConflict = false;
2410  VmaSuballocationList::const_iterator prevSuballocItem = freeSuballocItem;
2411  while(prevSuballocItem != m_Suballocations.cbegin())
2412  {
2413  --prevSuballocItem;
2414  const VmaSuballocation& prevSuballoc = *prevSuballocItem;
2415  if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity))
2416  {
2417  if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))
2418  {
2419  bufferImageGranularityConflict = true;
2420  break;
2421  }
2422  }
2423  else
2424  // Already on previous page.
2425  break;
2426  }
2427  if(bufferImageGranularityConflict)
2428  *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity);
2429  }
2430 
2431  // Calculate padding at the beginning based on current offset.
2432  const VkDeviceSize paddingBegin = *pOffset - suballoc.offset;
2433 
2434  // Calculate required margin at the end if this is not last suballocation.
2435  VmaSuballocationList::const_iterator next = freeSuballocItem;
2436  ++next;
2437  const VkDeviceSize requiredEndMargin =
2438  (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0;
2439 
2440  // Fail if requested size plus margin before and after is bigger than size of this suballocation.
2441  if(paddingBegin + allocSize + requiredEndMargin > suballoc.size)
2442  return false;
2443 
2444  // Check next suballocations for BufferImageGranularity conflicts.
2445  // If conflict exists, allocation cannot be made here.
2446  if(bufferImageGranularity > 1)
2447  {
2448  VmaSuballocationList::const_iterator nextSuballocItem = freeSuballocItem;
2449  ++nextSuballocItem;
2450  while(nextSuballocItem != m_Suballocations.cend())
2451  {
2452  const VmaSuballocation& nextSuballoc = *nextSuballocItem;
2453  if(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))
2454  {
2455  if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))
2456  return false;
2457  }
2458  else
2459  // Already on next page.
2460  break;
2461  ++nextSuballocItem;
2462  }
2463  }
2464 
2465  // All tests passed: Success. pOffset is already filled.
2466  return true;
2467 }
2468 
2469 bool VmaAllocation::IsEmpty() const
2470 {
2471  return (m_Suballocations.size() == 1) && (m_FreeCount == 1);
2472 }
2473 
2474 void VmaAllocation::Alloc(
2475  const VmaAllocationRequest& request,
2476  VmaSuballocationType type,
2477  VkDeviceSize allocSize)
2478 {
2479  VMA_ASSERT(request.freeSuballocationItem != m_Suballocations.end());
2480  VmaSuballocation& suballoc = *request.freeSuballocationItem;
2481  // Given suballocation is a free block.
2482  VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
2483  // Given offset is inside this suballocation.
2484  VMA_ASSERT(request.offset >= suballoc.offset);
2485  const VkDeviceSize paddingBegin = request.offset - suballoc.offset;
2486  VMA_ASSERT(suballoc.size >= paddingBegin + allocSize);
2487  const VkDeviceSize paddingEnd = suballoc.size - paddingBegin - allocSize;
2488 
2489  // Unregister this free suballocation from m_FreeSuballocationsBySize and update
2490  // it to become used.
2491  UnregisterFreeSuballocation(request.freeSuballocationItem);
2492 
2493  suballoc.offset = request.offset;
2494  suballoc.size = allocSize;
2495  suballoc.type = type;
2496 
2497  // If there are any free bytes remaining at the end, insert new free suballocation after current one.
2498  if(paddingEnd)
2499  {
2500  VmaSuballocation paddingSuballoc = {};
2501  paddingSuballoc.offset = request.offset + allocSize;
2502  paddingSuballoc.size = paddingEnd;
2503  paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
2504  VmaSuballocationList::iterator next = request.freeSuballocationItem;
2505  ++next;
2506  const VmaSuballocationList::iterator paddingEndItem =
2507  m_Suballocations.insert(next, paddingSuballoc);
2508  RegisterFreeSuballocation(paddingEndItem);
2509  }
2510 
2511  // If there are any free bytes remaining at the beginning, insert new free suballocation before current one.
2512  if(paddingBegin)
2513  {
2514  VmaSuballocation paddingSuballoc = {};
2515  paddingSuballoc.offset = request.offset - paddingBegin;
2516  paddingSuballoc.size = paddingBegin;
2517  paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
2518  const VmaSuballocationList::iterator paddingBeginItem =
2519  m_Suballocations.insert(request.freeSuballocationItem, paddingSuballoc);
2520  RegisterFreeSuballocation(paddingBeginItem);
2521  }
2522 
2523  // Update totals.
2524  m_FreeCount = m_FreeCount - 1;
2525  if(paddingBegin > 0)
2526  ++m_FreeCount;
2527  if(paddingEnd > 0)
2528  ++m_FreeCount;
2529  m_SumFreeSize -= allocSize;
2530 }
2531 
2532 void VmaAllocation::FreeSuballocation(VmaSuballocationList::iterator suballocItem)
2533 {
2534  // Change this suballocation to be marked as free.
2535  VmaSuballocation& suballoc = *suballocItem;
2536  suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
2537 
2538  // Update totals.
2539  ++m_FreeCount;
2540  m_SumFreeSize += suballoc.size;
2541 
2542  // Merge with previous and/or next suballocation if it's also free.
2543  bool mergeWithNext = false;
2544  bool mergeWithPrev = false;
2545 
2546  VmaSuballocationList::iterator nextItem = suballocItem;
2547  ++nextItem;
2548  if((nextItem != m_Suballocations.end()) && (nextItem->type == VMA_SUBALLOCATION_TYPE_FREE))
2549  mergeWithNext = true;
2550 
2551  VmaSuballocationList::iterator prevItem = suballocItem;
2552  if(suballocItem != m_Suballocations.begin())
2553  {
2554  --prevItem;
2555  if(prevItem->type == VMA_SUBALLOCATION_TYPE_FREE)
2556  mergeWithPrev = true;
2557  }
2558 
2559  if(mergeWithNext)
2560  {
2561  UnregisterFreeSuballocation(nextItem);
2562  MergeFreeWithNext(suballocItem);
2563  }
2564 
2565  if(mergeWithPrev)
2566  {
2567  UnregisterFreeSuballocation(prevItem);
2568  MergeFreeWithNext(prevItem);
2569  RegisterFreeSuballocation(prevItem);
2570  }
2571  else
2572  RegisterFreeSuballocation(suballocItem);
2573 }
2574 
2575 void VmaAllocation::Free(const VkMappedMemoryRange* pMemory)
2576 {
2577  // If suballocation to free has offset smaller than half of allocation size, search forward.
2578  // Otherwise search backward.
2579  const bool forwardDirection = pMemory->offset < (m_Size / 2);
2580  if(forwardDirection)
2581  {
2582  for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();
2583  suballocItem != m_Suballocations.end();
2584  ++suballocItem)
2585  {
2586  VmaSuballocation& suballoc = *suballocItem;
2587  if(suballoc.offset == pMemory->offset)
2588  {
2589  FreeSuballocation(suballocItem);
2590  VMA_HEAVY_ASSERT(Validate());
2591  return;
2592  }
2593  }
2594  VMA_ASSERT(0 && "Not found!");
2595  }
2596  else
2597  {
2598  for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin();
2599  suballocItem != m_Suballocations.end();
2600  ++suballocItem)
2601  {
2602  VmaSuballocation& suballoc = *suballocItem;
2603  if(suballoc.offset == pMemory->offset)
2604  {
2605  FreeSuballocation(suballocItem);
2606  VMA_HEAVY_ASSERT(Validate());
2607  return;
2608  }
2609  }
2610  VMA_ASSERT(0 && "Not found!");
2611  }
2612 }
2613 
2614 #if VMA_STATS_STRING_ENABLED
2615 
2616 void VmaAllocation::PrintDetailedMap(class VmaStringBuilder& sb) const
2617 {
2618  sb.Add("{\n\t\t\t\"Bytes\": ");
2619  sb.AddNumber(m_Size);
2620  sb.Add(",\n\t\t\t\"FreeBytes\": ");
2621  sb.AddNumber(m_SumFreeSize);
2622  sb.Add(",\n\t\t\t\"Suballocations\": ");
2623  sb.AddNumber(m_Suballocations.size());
2624  sb.Add(",\n\t\t\t\"FreeSuballocations\": ");
2625  sb.AddNumber(m_FreeCount);
2626  sb.Add(",\n\t\t\t\"SuballocationList\": [");
2627 
2628  size_t i = 0;
2629  for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin();
2630  suballocItem != m_Suballocations.cend();
2631  ++suballocItem, ++i)
2632  {
2633  if(i > 0)
2634  sb.Add(",\n\t\t\t\t{ \"Type\": ");
2635  else
2636  sb.Add("\n\t\t\t\t{ \"Type\": ");
2637  sb.AddString(VMA_SUBALLOCATION_TYPE_NAMES[suballocItem->type]);
2638  sb.Add(", \"Size\": ");
2639  sb.AddNumber(suballocItem->size);
2640  sb.Add(", \"Offset\": ");
2641  sb.AddNumber(suballocItem->offset);
2642  sb.Add(" }");
2643  }
2644 
2645  sb.Add("\n\t\t\t]\n\t\t}");
2646 }
2647 
2648 #endif // #if VMA_STATS_STRING_ENABLED
2649 
2650 void VmaAllocation::MergeFreeWithNext(VmaSuballocationList::iterator item)
2651 {
2652  VMA_ASSERT(item != m_Suballocations.end());
2653  VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
2654 
2655  VmaSuballocationList::iterator nextItem = item;
2656  ++nextItem;
2657  VMA_ASSERT(nextItem != m_Suballocations.end());
2658  VMA_ASSERT(nextItem->type == VMA_SUBALLOCATION_TYPE_FREE);
2659 
2660  item->size += nextItem->size;
2661  --m_FreeCount;
2662  m_Suballocations.erase(nextItem);
2663 }
2664 
2665 void VmaAllocation::RegisterFreeSuballocation(VmaSuballocationList::iterator item)
2666 {
2667  VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
2668  VMA_ASSERT(item->size > 0);
2669 
2670  if(item->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)
2671  {
2672  if(m_FreeSuballocationsBySize.empty())
2673  m_FreeSuballocationsBySize.push_back(item);
2674  else
2675  {
2676  VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(
2677  m_FreeSuballocationsBySize.data(),
2678  m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(),
2679  item,
2680  VmaSuballocationItemSizeLess());
2681  size_t index = it - m_FreeSuballocationsBySize.data();
2682  VectorInsert(m_FreeSuballocationsBySize, index, item);
2683  }
2684  }
2685 }
2686 
2687 void VmaAllocation::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)
2688 {
2689  VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
2690  VMA_ASSERT(item->size > 0);
2691 
2692  if(item->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)
2693  {
2694  VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(
2695  m_FreeSuballocationsBySize.data(),
2696  m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(),
2697  item,
2698  VmaSuballocationItemSizeLess());
2699  for(size_t index = it - m_FreeSuballocationsBySize.data();
2700  index < m_FreeSuballocationsBySize.size();
2701  ++index)
2702  {
2703  if(m_FreeSuballocationsBySize[index] == item)
2704  {
2705  VectorRemove(m_FreeSuballocationsBySize, index);
2706  return;
2707  }
2708  VMA_ASSERT((m_FreeSuballocationsBySize[index]->size == item->size) && "Not found.");
2709  }
2710  VMA_ASSERT(0 && "Not found.");
2711  }
2712 }
2713 
2714 static void InitStatInfo(VmaStatInfo& outInfo)
2715 {
2716  memset(&outInfo, 0, sizeof(outInfo));
2717  outInfo.SuballocationSizeMin = UINT64_MAX;
2718  outInfo.UnusedRangeSizeMin = UINT64_MAX;
2719 }
2720 
2721 static void CalcAllocationStatInfo(VmaStatInfo& outInfo, const VmaAllocation& alloc)
2722 {
2723  outInfo.AllocationCount = 1;
2724 
2725  const uint32_t rangeCount = (uint32_t)alloc.m_Suballocations.size();
2726  outInfo.SuballocationCount = rangeCount - alloc.m_FreeCount;
2727  outInfo.UnusedRangeCount = alloc.m_FreeCount;
2728 
2729  outInfo.UnusedBytes = alloc.m_SumFreeSize;
2730  outInfo.UsedBytes = alloc.m_Size - outInfo.UnusedBytes;
2731 
2732  outInfo.SuballocationSizeMin = UINT64_MAX;
2733  outInfo.SuballocationSizeMax = 0;
2734  outInfo.UnusedRangeSizeMin = UINT64_MAX;
2735  outInfo.UnusedRangeSizeMax = 0;
2736 
2737  for(VmaSuballocationList::const_iterator suballocItem = alloc.m_Suballocations.cbegin();
2738  suballocItem != alloc.m_Suballocations.cend();
2739  ++suballocItem)
2740  {
2741  const VmaSuballocation& suballoc = *suballocItem;
2742  if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
2743  {
2744  outInfo.SuballocationSizeMin = VMA_MIN(outInfo.SuballocationSizeMin, suballoc.size);
2745  outInfo.SuballocationSizeMax = VMA_MAX(outInfo.SuballocationSizeMax, suballoc.size);
2746  }
2747  else
2748  {
2749  outInfo.UnusedRangeSizeMin = VMA_MIN(outInfo.UnusedRangeSizeMin, suballoc.size);
2750  outInfo.UnusedRangeSizeMax = VMA_MAX(outInfo.UnusedRangeSizeMax, suballoc.size);
2751  }
2752  }
2753 }
2754 
2755 // Adds statistics srcInfo into inoutInfo, like: inoutInfo += srcInfo.
2756 static void VmaAddStatInfo(VmaStatInfo& inoutInfo, const VmaStatInfo& srcInfo)
2757 {
2758  inoutInfo.AllocationCount += srcInfo.AllocationCount;
2759  inoutInfo.SuballocationCount += srcInfo.SuballocationCount;
2760  inoutInfo.UnusedRangeCount += srcInfo.UnusedRangeCount;
2761  inoutInfo.UsedBytes += srcInfo.UsedBytes;
2762  inoutInfo.UnusedBytes += srcInfo.UnusedBytes;
2763  inoutInfo.SuballocationSizeMin = VMA_MIN(inoutInfo.SuballocationSizeMin, srcInfo.SuballocationSizeMin);
2764  inoutInfo.SuballocationSizeMax = VMA_MAX(inoutInfo.SuballocationSizeMax, srcInfo.SuballocationSizeMax);
2765  inoutInfo.UnusedRangeSizeMin = VMA_MIN(inoutInfo.UnusedRangeSizeMin, srcInfo.UnusedRangeSizeMin);
2766  inoutInfo.UnusedRangeSizeMax = VMA_MAX(inoutInfo.UnusedRangeSizeMax, srcInfo.UnusedRangeSizeMax);
2767 }
2768 
2769 static void VmaPostprocessCalcStatInfo(VmaStatInfo& inoutInfo)
2770 {
2771  inoutInfo.SuballocationSizeAvg = (inoutInfo.SuballocationCount > 0) ?
2772  VmaRoundDiv<VkDeviceSize>(inoutInfo.UsedBytes, inoutInfo.SuballocationCount) : 0;
2773  inoutInfo.UnusedRangeSizeAvg = (inoutInfo.UnusedRangeCount > 0) ?
2774  VmaRoundDiv<VkDeviceSize>(inoutInfo.UnusedBytes, inoutInfo.UnusedRangeCount) : 0;
2775 }
2776 
2777 VmaAllocationVector::VmaAllocationVector(VmaAllocator hAllocator) :
2778  m_hAllocator(hAllocator),
2779  m_Allocations(VmaStlAllocator<VmaAllocation*>(hAllocator->GetAllocationCallbacks()))
2780 {
2781 }
2782 
2783 VmaAllocationVector::~VmaAllocationVector()
2784 {
2785  for(size_t i = m_Allocations.size(); i--; )
2786  {
2787  m_Allocations[i]->Destroy(m_hAllocator);
2788  vma_delete(m_hAllocator, m_Allocations[i]);
2789  }
2790 }
2791 
2792 size_t VmaAllocationVector::Free(const VkMappedMemoryRange* pMemory)
2793 {
2794  for(uint32_t allocIndex = 0; allocIndex < m_Allocations.size(); ++allocIndex)
2795  {
2796  VmaAllocation* const pAlloc = m_Allocations[allocIndex];
2797  VMA_ASSERT(pAlloc);
2798  if(pAlloc->m_hMemory == pMemory->memory)
2799  {
2800  pAlloc->Free(pMemory);
2801  VMA_HEAVY_ASSERT(pAlloc->Validate());
2802  return allocIndex;
2803  }
2804  }
2805 
2806  return (size_t)-1;
2807 }
2808 
2809 void VmaAllocationVector::IncrementallySortAllocations()
2810 {
2811  // Bubble sort only until first swap.
2812  for(size_t i = 1; i < m_Allocations.size(); ++i)
2813  {
2814  if(m_Allocations[i - 1]->m_SumFreeSize > m_Allocations[i]->m_SumFreeSize)
2815  {
2816  VMA_SWAP(m_Allocations[i - 1], m_Allocations[i]);
2817  return;
2818  }
2819  }
2820 }
2821 
2822 #if VMA_STATS_STRING_ENABLED
2823 
2824 void VmaAllocationVector::PrintDetailedMap(class VmaStringBuilder& sb) const
2825 {
2826  for(size_t i = 0; i < m_Allocations.size(); ++i)
2827  {
2828  if(i > 0)
2829  sb.Add(",\n\t\t");
2830  else
2831  sb.Add("\n\t\t");
2832  m_Allocations[i]->PrintDetailedMap(sb);
2833  }
2834 }
2835 
2836 #endif // #if VMA_STATS_STRING_ENABLED
2837 
2838 void VmaAllocationVector::AddStats(VmaStats* pStats, uint32_t memTypeIndex, uint32_t memHeapIndex) const
2839 {
2840  for(uint32_t allocIndex = 0; allocIndex < m_Allocations.size(); ++allocIndex)
2841  {
2842  const VmaAllocation* const pAlloc = m_Allocations[allocIndex];
2843  VMA_ASSERT(pAlloc);
2844  VMA_HEAVY_ASSERT(pAlloc->Validate());
2845  VmaStatInfo allocationStatInfo;
2846  CalcAllocationStatInfo(allocationStatInfo, *pAlloc);
2847  VmaAddStatInfo(pStats->total, allocationStatInfo);
2848  VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo);
2849  VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo);
2850  }
2851 }
2852 
2854 // VmaAllocator_T
2855 
2856 VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
2857  m_PhysicalDevice(pCreateInfo->physicalDevice),
2858  m_hDevice(pCreateInfo->device),
2859  m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
2860  m_AllocationCallbacks(pCreateInfo->pAllocationCallbacks ?
2861  *pCreateInfo->pAllocationCallbacks : VmaEmptyAllocationCallbacks),
2862  m_PreferredLargeHeapBlockSize(0),
2863  m_PreferredSmallHeapBlockSize(0),
2864  m_BufferToMemoryMap(VmaStlAllocator< VmaPair<VkBuffer, VkMappedMemoryRange> >(pCreateInfo->pAllocationCallbacks)),
2865  m_ImageToMemoryMap(VmaStlAllocator< VmaPair<VkImage, VkMappedMemoryRange> >(pCreateInfo->pAllocationCallbacks))
2866 {
2867  VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device);
2868 
2869  memset(&m_MemProps, 0, sizeof(m_MemProps));
2870  memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
2871 
2872  memset(&m_pAllocations, 0, sizeof(m_pAllocations));
2873  memset(&m_HasEmptyAllocation, 0, sizeof(m_HasEmptyAllocation));
2874  memset(&m_pOwnAllocations, 0, sizeof(m_pOwnAllocations));
2875 
2876  m_PreferredLargeHeapBlockSize = (pCreateInfo->preferredLargeHeapBlockSize != 0) ?
2877  pCreateInfo->preferredLargeHeapBlockSize : VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE;
2878  m_PreferredSmallHeapBlockSize = (pCreateInfo->preferredSmallHeapBlockSize != 0) ?
2879  pCreateInfo->preferredSmallHeapBlockSize : VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE;
2880 
2881  vkGetPhysicalDeviceProperties(m_PhysicalDevice, &m_PhysicalDeviceProperties);
2882  vkGetPhysicalDeviceMemoryProperties(m_PhysicalDevice, &m_MemProps);
2883 
2884  for(size_t i = 0; i < GetMemoryTypeCount(); ++i)
2885  {
2886  m_pAllocations[i] = vma_new(this, VmaAllocationVector)(this);
2887  m_pOwnAllocations[i] = vma_new(this, OwnAllocationVectorType)(VmaStlAllocator<VmaOwnAllocation>(GetAllocationCallbacks()));
2888  }
2889 }
2890 
2891 VmaAllocator_T::~VmaAllocator_T()
2892 {
2893  for(VMA_MAP_TYPE(VkImage, VkMappedMemoryRange)::iterator it = m_ImageToMemoryMap.begin();
2894  it != m_ImageToMemoryMap.end();
2895  ++it)
2896  {
2897  vkDestroyImage(m_hDevice, it->first, GetAllocationCallbacks());
2898  }
2899 
2900  for(VMA_MAP_TYPE(VkBuffer, VkMappedMemoryRange)::iterator it = m_BufferToMemoryMap.begin();
2901  it != m_BufferToMemoryMap.end();
2902  ++it)
2903  {
2904  vkDestroyBuffer(m_hDevice, it->first, GetAllocationCallbacks());
2905  }
2906 
2907  for(uint32_t typeIndex = 0; typeIndex < GetMemoryTypeCount(); ++typeIndex)
2908  {
2909  OwnAllocationVectorType* pOwnAllocations = m_pOwnAllocations[typeIndex];
2910  VMA_ASSERT(pOwnAllocations);
2911  for(size_t allocationIndex = 0; allocationIndex < pOwnAllocations->size(); ++allocationIndex)
2912  {
2913  const VmaOwnAllocation& ownAlloc = (*pOwnAllocations)[allocationIndex];
2914  vkFreeMemory(m_hDevice, ownAlloc.m_hMemory, GetAllocationCallbacks());
2915  }
2916  }
2917 
2918  for(size_t i = GetMemoryTypeCount(); i--; )
2919  {
2920  vma_delete(this, m_pAllocations[i]);
2921  vma_delete(this, m_pOwnAllocations[i]);
2922  }
2923 }
2924 
2925 VkDeviceSize VmaAllocator_T::GetPreferredBlockSize(uint32_t memTypeIndex) const
2926 {
2927  VkDeviceSize heapSize = m_MemProps.memoryHeaps[m_MemProps.memoryTypes[memTypeIndex].heapIndex].size;
2928  return (heapSize <= VMA_SMALL_HEAP_MAX_SIZE) ?
2929  m_PreferredSmallHeapBlockSize : m_PreferredLargeHeapBlockSize;
2930 }
2931 
2932 VkResult VmaAllocator_T::AllocateMemoryOfType(
2933  const VkMemoryRequirements& vkMemReq,
2934  const VmaMemoryRequirements& vmaMemReq,
2935  uint32_t memTypeIndex,
2936  VmaSuballocationType suballocType,
2937  VkMappedMemoryRange* pMemory)
2938 {
2939  VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, Size=%llu", memTypeIndex, vkMemReq.size);
2940 
2941  pMemory->sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2942  pMemory->pNext = VMA_NULL;
2943  pMemory->size = vkMemReq.size;
2944 
2945  const VkDeviceSize preferredBlockSize = GetPreferredBlockSize(memTypeIndex);
2946  // Heuristics: Allocate own memory if requested size if greater than half of preferred block size.
2947  const bool ownMemory =
2948  vmaMemReq.ownMemory ||
2949  VMA_DEBUG_ALWAYS_OWN_MEMORY ||
2950  ((vmaMemReq.neverAllocate == false) && (vkMemReq.size > preferredBlockSize / 2));
2951 
2952  if(ownMemory)
2953  {
2954  if(vmaMemReq.neverAllocate)
2955  return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2956  else
2957  return AllocateOwnMemory(vkMemReq.size, suballocType, memTypeIndex, pMemory);
2958  }
2959  else
2960  {
2961  VmaMutexLock lock(m_AllocationsMutex[memTypeIndex]);
2962  VmaAllocationVector* const allocationVector = m_pAllocations[memTypeIndex];
2963  VMA_ASSERT(allocationVector);
2964 
2965  // 1. Search existing allocations.
2966  // Forward order - prefer blocks with smallest amount of free space.
2967  for(size_t allocIndex = 0; allocIndex < allocationVector->m_Allocations.size(); ++allocIndex )
2968  {
2969  VmaAllocation* const pAlloc = allocationVector->m_Allocations[allocIndex];
2970  VMA_ASSERT(pAlloc);
2971  VmaAllocationRequest allocRequest = {};
2972  // Check if can allocate from pAlloc.
2973  if(pAlloc->CreateAllocationRequest(
2974  GetBufferImageGranularity(),
2975  vkMemReq.size,
2976  vkMemReq.alignment,
2977  suballocType,
2978  &allocRequest))
2979  {
2980  // We no longer have an empty Allocation.
2981  if(pAlloc->IsEmpty())
2982  m_HasEmptyAllocation[memTypeIndex] = false;
2983  // Allocate from this pAlloc.
2984  pAlloc->Alloc(allocRequest, suballocType, vkMemReq.size);
2985  // Return VkDeviceMemory and offset (size already filled above).
2986  pMemory->memory = pAlloc->m_hMemory;
2987  pMemory->offset = allocRequest.offset;
2988  VMA_HEAVY_ASSERT(pAlloc->Validate());
2989  VMA_DEBUG_LOG(" Returned from existing allocation #%u", (uint32_t)allocIndex);
2990  return VK_SUCCESS;
2991  }
2992  }
2993 
2994  // 2. Create new Allocation.
2995  if(vmaMemReq.neverAllocate)
2996  {
2997  VMA_DEBUG_LOG(" FAILED due to VmaMemoryRequirements::neverAllocate");
2998  return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2999  }
3000  else
3001  {
3002  // Start with full preferredBlockSize.
3003  VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
3004  allocInfo.memoryTypeIndex = memTypeIndex;
3005  allocInfo.allocationSize = preferredBlockSize;
3006  VkDeviceMemory mem = VK_NULL_HANDLE;
3007  VkResult res = vkAllocateMemory(m_hDevice, &allocInfo, GetAllocationCallbacks(), &mem);
3008  if(res < 0)
3009  {
3010  // 3. Try half the size.
3011  allocInfo.allocationSize /= 2;
3012  if(allocInfo.allocationSize >= vkMemReq.size)
3013  {
3014  res = vkAllocateMemory(m_hDevice, &allocInfo, GetAllocationCallbacks(), &mem);
3015  if(res < 0)
3016  {
3017  // 4. Try quarter the size.
3018  allocInfo.allocationSize /= 2;
3019  if(allocInfo.allocationSize >= vkMemReq.size)
3020  {
3021  res = vkAllocateMemory(m_hDevice, &allocInfo, GetAllocationCallbacks(), &mem);
3022  }
3023  }
3024  }
3025  }
3026  if(res < 0)
3027  {
3028  // 5. Try OwnAlloc.
3029  res = AllocateOwnMemory(vkMemReq.size, suballocType, memTypeIndex, pMemory);
3030  if(res == VK_SUCCESS)
3031  {
3032  // Succeeded: AllocateOwnMemory function already filld pMemory, nothing more to do here.
3033  VMA_DEBUG_LOG(" Allocated as OwnMemory");
3034  return VK_SUCCESS;
3035  }
3036  else
3037  {
3038  // Everything failed: Return error code.
3039  VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
3040  return res;
3041  }
3042  }
3043 
3044  // New VkDeviceMemory successfully created. Create new Allocation for it.
3045  VmaAllocation* const pAlloc = vma_new(this, VmaAllocation)(this);
3046  pAlloc->Init(mem, allocInfo.allocationSize);
3047 
3048  allocationVector->m_Allocations.push_back(pAlloc);
3049 
3050  // Allocate from pAlloc. Because it is empty, allocRequest can be trivially filled.
3051  VmaAllocationRequest allocRequest = {};
3052  allocRequest.freeSuballocationItem = pAlloc->m_Suballocations.begin();
3053  allocRequest.offset = 0;
3054  pAlloc->Alloc(allocRequest, suballocType, vkMemReq.size);
3055  pMemory->memory = mem;
3056  pMemory->offset = allocRequest.offset;
3057  VMA_HEAVY_ASSERT(pAlloc->Validate());
3058  VMA_DEBUG_LOG(" Created new allocation Size=%llu", allocInfo.allocationSize);
3059  return VK_SUCCESS;
3060  }
3061  }
3062 }
3063 
3064 VkResult VmaAllocator_T::AllocateOwnMemory(
3065  VkDeviceSize size,
3066  VmaSuballocationType suballocType,
3067  uint32_t memTypeIndex,
3068  VkMappedMemoryRange* pMemory)
3069 {
3070  VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
3071  allocInfo.memoryTypeIndex = memTypeIndex;
3072  allocInfo.allocationSize = size;
3073 
3074  // Allocate VkDeviceMemory.
3075  VmaOwnAllocation ownAlloc = {};
3076  ownAlloc.m_Size = size;
3077  ownAlloc.m_Type = suballocType;
3078  VkResult res = vkAllocateMemory(m_hDevice, &allocInfo, GetAllocationCallbacks(), &ownAlloc.m_hMemory);
3079  if(res < 0)
3080  {
3081  VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
3082  return res;
3083  }
3084 
3085  // Register it in m_pOwnAllocations.
3086  VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
3087  OwnAllocationVectorType* ownAllocations = m_pOwnAllocations[memTypeIndex];
3088  VMA_ASSERT(ownAllocations);
3089  VmaOwnAllocation* const pOwnAllocationsBeg = ownAllocations->data();
3090  VmaOwnAllocation* const pOwnAllocationsEnd = pOwnAllocationsBeg + ownAllocations->size();
3091  const size_t indexToInsert = VmaBinaryFindFirstNotLess(
3092  pOwnAllocationsBeg,
3093  pOwnAllocationsEnd,
3094  ownAlloc,
3095  VmaOwnAllocationMemoryHandleLess()) - pOwnAllocationsBeg;
3096  VectorInsert(*ownAllocations, indexToInsert, ownAlloc);
3097 
3098  // Return parameters of the allocation.
3099  pMemory->sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
3100  pMemory->pNext = VMA_NULL;
3101  pMemory->memory = ownAlloc.m_hMemory;
3102  pMemory->offset = 0;
3103  pMemory->size = size;
3104 
3105  VMA_DEBUG_LOG(" Allocated OwnMemory MemoryTypeIndex=#%u", memTypeIndex);
3106 
3107  return VK_SUCCESS;
3108 }
3109 
3110 VkResult VmaAllocator_T::AllocateMemory(
3111  const VkMemoryRequirements& vkMemReq,
3112  const VmaMemoryRequirements& vmaMemReq,
3113  VmaSuballocationType suballocType,
3114  VkMappedMemoryRange* pMemory,
3115  uint32_t* pMemoryTypeIndex)
3116 {
3117  if(vmaMemReq.ownMemory && vmaMemReq.neverAllocate)
3118  {
3119  VMA_ASSERT(0 && "Specifying VmaMemoryRequirements::ownMemory && VmaMemoryRequirements::neverAllocate makes no sense.");
3120  return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3121  }
3122 
3123  // Bit mask of memory Vulkan types acceptable for this allocation.
3124  uint32_t memoryTypeBits = vkMemReq.memoryTypeBits;
3125  uint32_t memTypeIndex = UINT_MAX;
3126  VkResult res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &vmaMemReq, &memTypeIndex);
3127  if(res == VK_SUCCESS)
3128  {
3129  res = AllocateMemoryOfType(vkMemReq, vmaMemReq, memTypeIndex, suballocType, pMemory);
3130  // Succeeded on first try.
3131  if(res == VK_SUCCESS)
3132  {
3133  if(pMemoryTypeIndex != VMA_NULL)
3134  *pMemoryTypeIndex = memTypeIndex;
3135  return res;
3136  }
3137  // Allocation from this memory type failed. Try other compatible memory types.
3138  else
3139  {
3140  for(;;)
3141  {
3142  // Remove old memTypeIndex from list of possibilities.
3143  memoryTypeBits &= ~(1u << memTypeIndex);
3144  // Find alternative memTypeIndex.
3145  res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &vmaMemReq, &memTypeIndex);
3146  if(res == VK_SUCCESS)
3147  {
3148  res = AllocateMemoryOfType(vkMemReq, vmaMemReq, memTypeIndex, suballocType, pMemory);
3149  // Allocation from this alternative memory type succeeded.
3150  if(res == VK_SUCCESS)
3151  {
3152  if(pMemoryTypeIndex != VMA_NULL)
3153  *pMemoryTypeIndex = memTypeIndex;
3154  return res;
3155  }
3156  // else: Allocation from this memory type failed. Try next one - next loop iteration.
3157  }
3158  // No other matching memory type index could be found.
3159  else
3160  // Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once.
3161  return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3162  }
3163  }
3164  }
3165  // Can't find any single memory type maching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT.
3166  else
3167  return res;
3168 }
3169 
3170 void VmaAllocator_T::FreeMemory(const VkMappedMemoryRange* pMemory)
3171 {
3172  uint32_t memTypeIndex = 0;
3173  bool found = false;
3174  VmaAllocation* allocationToDelete = VMA_NULL;
3175  // Check all memory types because we don't know which one does pMemory come from.
3176  for(; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
3177  {
3178  VmaMutexLock lock(m_AllocationsMutex[memTypeIndex]);
3179  VmaAllocationVector* const pAllocationVector = m_pAllocations[memTypeIndex];
3180  VMA_ASSERT(pAllocationVector);
3181  // Try to free pMemory from pAllocationVector.
3182  const size_t allocIndex = pAllocationVector->Free(pMemory);
3183  if(allocIndex != (size_t)-1)
3184  {
3185  VMA_DEBUG_LOG(" Freed from MemoryTypeIndex=%u", memTypeIndex);
3186  found = true;
3187  VmaAllocation* const pAlloc = pAllocationVector->m_Allocations[allocIndex];
3188  VMA_ASSERT(pAlloc);
3189  // pAlloc became empty after this deallocation.
3190  if(pAlloc->IsEmpty())
3191  {
3192  // Already has empty Allocation. We don't want to have two, so delete this one.
3193  if(m_HasEmptyAllocation[memTypeIndex])
3194  {
3195  allocationToDelete = pAlloc;
3196  VectorRemove(pAllocationVector->m_Allocations, allocIndex);
3197  break;
3198  }
3199  // We now have first empty Allocation.
3200  else
3201  m_HasEmptyAllocation[memTypeIndex] = true;
3202  }
3203  // Must be called after allocIndex is used, because later it may become invalid!
3204  pAllocationVector->IncrementallySortAllocations();
3205  break;
3206  }
3207  }
3208  if(found)
3209  {
3210  // Destruction of a free Allocation. Deferred until this point, outside of mutex
3211  // lock, for performance reason.
3212  if(allocationToDelete != VMA_NULL)
3213  {
3214  VMA_DEBUG_LOG(" Deleted empty allocation");
3215  allocationToDelete->Destroy(this);
3216  vma_delete(this, allocationToDelete);
3217  }
3218  return;
3219  }
3220 
3221  // pMemory not found in allocations. Try free it as Own Memory.
3222  if(FreeOwnMemory(pMemory))
3223  return;
3224 
3225  // pMemory not found as Own Memory either.
3226  VMA_ASSERT(0 && "Not found. Trying to free memory not allocated using this allocator (or some other bug).");
3227 }
3228 
3229 void VmaAllocator_T::CalculateStats(VmaStats* pStats)
3230 {
3231  InitStatInfo(pStats->total);
3232  for(size_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i)
3233  InitStatInfo(pStats->memoryType[i]);
3234  for(size_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i)
3235  InitStatInfo(pStats->memoryHeap[i]);
3236 
3237  for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
3238  {
3239  VmaMutexLock allocationsLock(m_AllocationsMutex[memTypeIndex]);
3240  const uint32_t heapIndex = m_MemProps.memoryTypes[memTypeIndex].heapIndex;
3241  const VmaAllocationVector* const allocVector = m_pAllocations[memTypeIndex];
3242  VMA_ASSERT(allocVector);
3243  allocVector->AddStats(pStats, memTypeIndex, heapIndex);
3244  }
3245 
3246  VmaPostprocessCalcStatInfo(pStats->total);
3247  for(size_t i = 0; i < GetMemoryTypeCount(); ++i)
3248  VmaPostprocessCalcStatInfo(pStats->memoryType[i]);
3249  for(size_t i = 0; i < GetMemoryHeapCount(); ++i)
3250  VmaPostprocessCalcStatInfo(pStats->memoryHeap[i]);
3251 }
3252 
3253 bool VmaAllocator_T::FreeOwnMemory(const VkMappedMemoryRange* pMemory)
3254 {
3255  VkDeviceMemory vkMemory = VK_NULL_HANDLE;
3256 
3257  // Check all memory types because we don't know which one does pMemory come from.
3258  for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
3259  {
3260  VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
3261  OwnAllocationVectorType* const pOwnAllocations = m_pOwnAllocations[memTypeIndex];
3262  VMA_ASSERT(pOwnAllocations);
3263  VmaOwnAllocation* const pOwnAllocationsBeg = pOwnAllocations->data();
3264  VmaOwnAllocation* const pOwnAllocationsEnd = pOwnAllocationsBeg + pOwnAllocations->size();
3265  VmaOwnAllocation* const pOwnAllocationIt = VmaBinaryFindFirstNotLess(
3266  pOwnAllocationsBeg,
3267  pOwnAllocationsEnd,
3268  pMemory->memory,
3269  VmaOwnAllocationMemoryHandleLess());
3270  if((pOwnAllocationIt != pOwnAllocationsEnd) &&
3271  (pOwnAllocationIt->m_hMemory == pMemory->memory))
3272  {
3273  VMA_ASSERT(pMemory->size == pOwnAllocationIt->m_Size && pMemory->offset == 0);
3274  vkMemory = pOwnAllocationIt->m_hMemory;
3275  const size_t ownAllocationIndex = pOwnAllocationIt - pOwnAllocationsBeg;
3276  VectorRemove(*pOwnAllocations, ownAllocationIndex);
3277  VMA_DEBUG_LOG(" Freed OwnMemory MemoryTypeIndex=%u", memTypeIndex);
3278  break;
3279  }
3280  }
3281 
3282  // Found. Free VkDeviceMemory deferred until this point, outside of mutex lock,
3283  // for performance reason.
3284  if(vkMemory != VK_NULL_HANDLE)
3285  {
3286  vkFreeMemory(m_hDevice, vkMemory, GetAllocationCallbacks());
3287  return true;
3288  }
3289  else
3290  return false;
3291 }
3292 
3293 #if VMA_STATS_STRING_ENABLED
3294 
3295 void VmaAllocator_T::PrintDetailedMap(VmaStringBuilder& sb)
3296 {
3297  bool ownAllocationsStarted = false;
3298  for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
3299  {
3300  VmaMutexLock ownAllocationsLock(m_OwnAllocationsMutex[memTypeIndex]);
3301  OwnAllocationVectorType* const pOwnAllocVector = m_pOwnAllocations[memTypeIndex];
3302  VMA_ASSERT(pOwnAllocVector);
3303  if(pOwnAllocVector->empty() == false)
3304  {
3305  if(ownAllocationsStarted)
3306  sb.Add(",\n\t\"Type ");
3307  else
3308  {
3309  sb.Add(",\n\"OwnAllocations\": {\n\t\"Type ");
3310  ownAllocationsStarted = true;
3311  }
3312  sb.AddNumber(memTypeIndex);
3313  sb.Add("\": [");
3314 
3315  for(size_t i = 0; i < pOwnAllocVector->size(); ++i)
3316  {
3317  const VmaOwnAllocation& ownAlloc = (*pOwnAllocVector)[i];
3318  if(i > 0)
3319  sb.Add(",\n\t\t{ \"Size\": ");
3320  else
3321  sb.Add("\n\t\t{ \"Size\": ");
3322  sb.AddNumber(ownAlloc.m_Size);
3323  sb.Add(", \"Type\": ");
3324  sb.AddString(VMA_SUBALLOCATION_TYPE_NAMES[ownAlloc.m_Type]);
3325  sb.Add(" }");
3326  }
3327 
3328  sb.Add("\n\t]");
3329  }
3330  }
3331  if(ownAllocationsStarted)
3332  sb.Add("\n}");
3333 
3334  {
3335  bool allocationsStarted = false;
3336  for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
3337  {
3338  VmaMutexLock globalAllocationsLock(m_AllocationsMutex[memTypeIndex]);
3339  if(m_pAllocations[memTypeIndex]->IsEmpty() == false)
3340  {
3341  if(allocationsStarted)
3342  sb.Add(",\n\t\"Type ");
3343  else
3344  {
3345  sb.Add(",\n\"Allocations\": {\n\t\"Type ");
3346  allocationsStarted = true;
3347  }
3348  sb.AddNumber(memTypeIndex);
3349  sb.Add("\": [");
3350 
3351  m_pAllocations[memTypeIndex]->PrintDetailedMap(sb);
3352 
3353  sb.Add("\n\t]");
3354  }
3355  }
3356  if(allocationsStarted)
3357  sb.Add("\n}");
3358  }
3359 }
3360 
3361 #endif // #if VMA_STATS_STRING_ENABLED
3362 
3363 static VkResult AllocateMemoryForImage(
3364  VmaAllocator allocator,
3365  VkImage image,
3366  const VmaMemoryRequirements* pMemoryRequirements,
3367  VmaSuballocationType suballocType,
3368  VkMappedMemoryRange* pMemory,
3369  uint32_t* pMemoryTypeIndex)
3370 {
3371  VMA_ASSERT(allocator && image != VK_NULL_HANDLE && pMemoryRequirements && pMemory);
3372 
3373  VkMemoryRequirements vkMemReq = {};
3374  vkGetImageMemoryRequirements(allocator->m_hDevice, image, &vkMemReq);
3375 
3376  return allocator->AllocateMemory(
3377  vkMemReq,
3378  *pMemoryRequirements,
3379  suballocType,
3380  pMemory,
3381  pMemoryTypeIndex);
3382 }
3383 
3385 // Public interface
3386 
3387 VkResult vmaCreateAllocator(
3388  const VmaAllocatorCreateInfo* pCreateInfo,
3389  VmaAllocator* pAllocator)
3390 {
3391  VMA_ASSERT(pCreateInfo && pAllocator);
3392  VMA_DEBUG_LOG("vmaCreateAllocator");
3393  *pAllocator = vma_new(pCreateInfo->pAllocationCallbacks, VmaAllocator_T)(pCreateInfo);
3394  return VK_SUCCESS;
3395 }
3396 
3397 void vmaDestroyAllocator(
3398  VmaAllocator allocator)
3399 {
3400  if(allocator != VK_NULL_HANDLE)
3401  {
3402  VMA_DEBUG_LOG("vmaDestroyAllocator");
3403  VkAllocationCallbacks allocationCallbacks = allocator->m_AllocationCallbacks;
3404  vma_delete(&allocationCallbacks, allocator);
3405  }
3406 }
3407 
3409  VmaAllocator allocator,
3410  const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)
3411 {
3412  VMA_ASSERT(allocator && ppPhysicalDeviceProperties);
3413  *ppPhysicalDeviceProperties = &allocator->m_PhysicalDeviceProperties;
3414 }
3415 
3417  VmaAllocator allocator,
3418  const VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties)
3419 {
3420  VMA_ASSERT(allocator && ppPhysicalDeviceMemoryProperties);
3421  *ppPhysicalDeviceMemoryProperties = &allocator->m_MemProps;
3422 }
3423 
3425  VmaAllocator allocator,
3426  uint32_t memoryTypeIndex,
3427  VkMemoryPropertyFlags* pFlags)
3428 {
3429  VMA_ASSERT(allocator && pFlags);
3430  VMA_ASSERT(memoryTypeIndex < allocator->GetMemoryTypeCount());
3431  *pFlags = allocator->m_MemProps.memoryTypes[memoryTypeIndex].propertyFlags;
3432 }
3433 
3434 void vmaCalculateStats(
3435  VmaAllocator allocator,
3436  VmaStats* pStats)
3437 {
3438  VMA_ASSERT(allocator && pStats);
3439  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3440  allocator->CalculateStats(pStats);
3441 }
3442 
3443 #if VMA_STATS_STRING_ENABLED
3444 
3445 void vmaBuildStatsString(
3446  VmaAllocator allocator,
3447  char** ppStatsString,
3448  VkBool32 detailedMap)
3449 {
3450  VMA_ASSERT(allocator && ppStatsString);
3451  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3452 
3453  VmaStringBuilder sb(allocator);
3454  {
3455  VmaStats stats;
3456  allocator->CalculateStats(&stats);
3457 
3458  sb.Add("{\n\"Total\": ");
3459  VmaPrintStatInfo(sb, stats.total);
3460 
3461  for(uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex)
3462  {
3463  sb.Add(",\n\"Heap ");
3464  sb.AddNumber(heapIndex);
3465  sb.Add("\": {\n\t\"Size\": ");
3466  sb.AddNumber(allocator->m_MemProps.memoryHeaps[heapIndex].size);
3467  sb.Add(",\n\t\"Flags\": ");
3468  if((allocator->m_MemProps.memoryHeaps[heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0)
3469  sb.AddString("DEVICE_LOCAL");
3470  else
3471  sb.AddString("");
3472  if(stats.memoryHeap[heapIndex].AllocationCount > 0)
3473  {
3474  sb.Add(",\n\t\"Stats:\": ");
3475  VmaPrintStatInfo(sb, stats.memoryHeap[heapIndex]);
3476  }
3477 
3478  for(uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex)
3479  {
3480  if(allocator->m_MemProps.memoryTypes[typeIndex].heapIndex == heapIndex)
3481  {
3482  sb.Add(",\n\t\"Type ");
3483  sb.AddNumber(typeIndex);
3484  sb.Add("\": {\n\t\t\"Flags\": \"");
3485  VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags;
3486  if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
3487  sb.Add(" DEVICE_LOCAL");
3488  if((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
3489  sb.Add(" HOST_VISIBLE");
3490  if((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0)
3491  sb.Add(" HOST_COHERENT");
3492  if((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0)
3493  sb.Add(" HOST_CACHED");
3494  if((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0)
3495  sb.Add(" LAZILY_ALLOCATED");
3496  sb.Add("\"");
3497  if(stats.memoryType[typeIndex].AllocationCount > 0)
3498  {
3499  sb.Add(",\n\t\t\"Stats\": ");
3500  VmaPrintStatInfo(sb, stats.memoryType[typeIndex]);
3501  }
3502  sb.Add("\n\t}");
3503  }
3504  }
3505  sb.Add("\n}");
3506  }
3507  if(detailedMap == VK_TRUE)
3508  allocator->PrintDetailedMap(sb);
3509  sb.Add("\n}\n");
3510  }
3511 
3512  const size_t len = sb.GetLength();
3513  char* const pChars = vma_new_array(allocator, char, len + 1);
3514  if(len > 0)
3515  memcpy(pChars, sb.GetData(), len);
3516  pChars[len] = '\0';
3517  *ppStatsString = pChars;
3518 }
3519 
3520 void vmaFreeStatsString(
3521  VmaAllocator allocator,
3522  char* pStatsString)
3523 {
3524  if(pStatsString != VMA_NULL)
3525  {
3526  VMA_ASSERT(allocator);
3527  size_t len = strlen(pStatsString);
3528  vma_delete_array(allocator, pStatsString, len + 1);
3529  }
3530 }
3531 
3532 #endif // #if VMA_STATS_STRING_ENABLED
3533 
3536 VkResult vmaFindMemoryTypeIndex(
3537  VmaAllocator allocator,
3538  uint32_t memoryTypeBits,
3539  const VmaMemoryRequirements* pMemoryRequirements,
3540  uint32_t* pMemoryTypeIndex)
3541 {
3542  VMA_ASSERT(allocator != VK_NULL_HANDLE);
3543  VMA_ASSERT(pMemoryRequirements != VMA_NULL);
3544  VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);
3545 
3546  uint32_t requiredFlags = pMemoryRequirements->requiredFlags;
3547  uint32_t preferredFlags = pMemoryRequirements->preferredFlags;
3548  if(preferredFlags == 0)
3549  preferredFlags = requiredFlags;
3550  // preferredFlags, if not 0, must be subset of requiredFlags.
3551  VMA_ASSERT((requiredFlags & ~preferredFlags) == 0);
3552 
3553  // Convert usage to requiredFlags and preferredFlags.
3554  switch(pMemoryRequirements->usage)
3555  {
3557  break;
3559  preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3560  break;
3562  requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
3563  break;
3565  requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
3566  preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3567  break;
3569  requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
3570  preferredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
3571  break;
3572  default:
3573  break;
3574  }
3575 
3576  *pMemoryTypeIndex = UINT_MAX;
3577  uint32_t minCost = UINT_MAX;
3578  for(uint32_t memTypeIndex = 0, memTypeBit = 1;
3579  memTypeIndex < allocator->GetMemoryTypeCount();
3580  ++memTypeIndex, memTypeBit <<= 1)
3581  {
3582  // This memory type is acceptable according to memoryTypeBits bitmask.
3583  if((memTypeBit & memoryTypeBits) != 0)
3584  {
3585  const VkMemoryPropertyFlags currFlags =
3586  allocator->m_MemProps.memoryTypes[memTypeIndex].propertyFlags;
3587  // This memory type contains requiredFlags.
3588  if((requiredFlags & ~currFlags) == 0)
3589  {
3590  // Calculate cost as number of bits from preferredFlags not present in this memory type.
3591  uint32_t currCost = CountBitsSet(preferredFlags & ~currFlags);
3592  // Remember memory type with lowest cost.
3593  if(currCost < minCost)
3594  {
3595  *pMemoryTypeIndex = memTypeIndex;
3596  if(currCost == 0)
3597  return VK_SUCCESS;
3598  minCost = currCost;
3599  }
3600  }
3601  }
3602  }
3603  return (*pMemoryTypeIndex != UINT_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT;
3604 }
3605 
3606 VkResult vmaAllocateMemory(
3607  VmaAllocator allocator,
3608  const VkMemoryRequirements* pVkMemoryRequirements,
3609  const VmaMemoryRequirements* pVmaMemoryRequirements,
3610  VkMappedMemoryRange* pMemory,
3611  uint32_t* pMemoryTypeIndex)
3612 {
3613  VMA_ASSERT(allocator && pVkMemoryRequirements && pVmaMemoryRequirements && pMemory);
3614 
3615  VMA_DEBUG_LOG("vmaAllocateMemory");
3616 
3617  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3618 
3619  return allocator->AllocateMemory(
3620  *pVkMemoryRequirements,
3621  *pVmaMemoryRequirements,
3622  VMA_SUBALLOCATION_TYPE_UNKNOWN,
3623  pMemory,
3624  pMemoryTypeIndex);
3625 }
3626 
3628  VmaAllocator allocator,
3629  VkBuffer buffer,
3630  const VmaMemoryRequirements* pMemoryRequirements,
3631  VkMappedMemoryRange* pMemory,
3632  uint32_t* pMemoryTypeIndex)
3633 {
3634  VMA_ASSERT(allocator && buffer != VK_NULL_HANDLE && pMemoryRequirements && pMemory);
3635 
3636  VMA_DEBUG_LOG("vmaAllocateMemoryForBuffer");
3637 
3638  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3639 
3640  VkMemoryRequirements vkMemReq = {};
3641  vkGetBufferMemoryRequirements(allocator->m_hDevice, buffer, &vkMemReq);
3642 
3643  return allocator->AllocateMemory(
3644  vkMemReq,
3645  *pMemoryRequirements,
3646  VMA_SUBALLOCATION_TYPE_BUFFER,
3647  pMemory,
3648  pMemoryTypeIndex);
3649 }
3650 
3651 VkResult vmaAllocateMemoryForImage(
3652  VmaAllocator allocator,
3653  VkImage image,
3654  const VmaMemoryRequirements* pMemoryRequirements,
3655  VkMappedMemoryRange* pMemory,
3656  uint32_t* pMemoryTypeIndex)
3657 {
3658  VMA_ASSERT(allocator && image != VK_NULL_HANDLE && pMemoryRequirements);
3659 
3660  VMA_DEBUG_LOG("vmaAllocateMemoryForImage");
3661 
3662  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3663 
3664  return AllocateMemoryForImage(
3665  allocator,
3666  image,
3667  pMemoryRequirements,
3668  VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,
3669  pMemory,
3670  pMemoryTypeIndex);
3671 }
3672 
3673 void vmaFreeMemory(
3674  VmaAllocator allocator,
3675  const VkMappedMemoryRange* pMemory)
3676 {
3677  VMA_ASSERT(allocator && pMemory);
3678 
3679  VMA_DEBUG_LOG("vmaFreeMemory");
3680 
3681  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3682 
3683  allocator->FreeMemory(pMemory);
3684 }
3685 
3686 VkResult vmaMapMemory(
3687  VmaAllocator allocator,
3688  const VkMappedMemoryRange* pMemory,
3689  void** ppData)
3690 {
3691  VMA_ASSERT(allocator && pMemory && ppData);
3692 
3693  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3694 
3695  return vkMapMemory(allocator->m_hDevice, pMemory->memory,
3696  pMemory->offset, pMemory->size, 0, ppData);
3697 }
3698 
3699 void vmaUnmapMemory(
3700  VmaAllocator allocator,
3701  const VkMappedMemoryRange* pMemory)
3702 {
3703  VMA_ASSERT(allocator && pMemory);
3704 
3705  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3706 
3707  vkUnmapMemory(allocator->m_hDevice, pMemory->memory);
3708 }
3709 
3710 VkResult vmaCreateBuffer(
3711  VmaAllocator allocator,
3712  const VkBufferCreateInfo* pCreateInfo,
3713  const VmaMemoryRequirements* pMemoryRequirements,
3714  VkBuffer* pBuffer,
3715  VkMappedMemoryRange* pMemory,
3716  uint32_t* pMemoryTypeIndex)
3717 {
3718  VMA_ASSERT(allocator && pCreateInfo && pMemoryRequirements);
3719 
3720  VMA_DEBUG_LOG("vmaCreateBuffer");
3721 
3722  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3723 
3724  // 1. Create VkBuffer.
3725  VkResult res = vkCreateBuffer(allocator->m_hDevice, pCreateInfo, allocator->GetAllocationCallbacks(), pBuffer);
3726  if(res >= 0)
3727  {
3728  VkMappedMemoryRange mem = {};
3729 
3730  // 2. vkGetBufferMemoryRequirements.
3731  VkMemoryRequirements vkMemReq = {};
3732  vkGetBufferMemoryRequirements(allocator->m_hDevice, *pBuffer, &vkMemReq);
3733 
3734  // 3. Allocate memory using allocator.
3735  res = allocator->AllocateMemory(
3736  vkMemReq,
3737  *pMemoryRequirements,
3738  VMA_SUBALLOCATION_TYPE_BUFFER,
3739  &mem,
3740  pMemoryTypeIndex);
3741  if(res >= 0)
3742  {
3743  if(pMemory != VMA_NULL)
3744  {
3745  *pMemory = mem;
3746  }
3747  // 3. Bind buffer with memory.
3748  res = vkBindBufferMemory(allocator->m_hDevice, *pBuffer, mem.memory, mem.offset);
3749  if(res >= 0)
3750  {
3751  // All steps succeeded.
3752  VmaMutexLock lock(allocator->m_BufferToMemoryMapMutex);
3753  allocator->m_BufferToMemoryMap.insert(VmaPair<VkBuffer, VkMappedMemoryRange>(*pBuffer, mem));
3754  return VK_SUCCESS;
3755  }
3756  allocator->FreeMemory(&mem);
3757  return res;
3758  }
3759  vkDestroyBuffer(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
3760  return res;
3761  }
3762  return res;
3763 }
3764 
3765 void vmaDestroyBuffer(
3766  VmaAllocator allocator,
3767  VkBuffer buffer)
3768 {
3769  if(buffer != VK_NULL_HANDLE)
3770  {
3771  VMA_ASSERT(allocator);
3772 
3773  VMA_DEBUG_LOG("vmaDestroyBuffer");
3774 
3775  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3776 
3777  VkMappedMemoryRange mem = {};
3778  {
3779  VmaMutexLock lock(allocator->m_BufferToMemoryMapMutex);
3780  VMA_MAP_TYPE(VkBuffer, VkMappedMemoryRange)::iterator it = allocator->m_BufferToMemoryMap.find(buffer);
3781  if(it == allocator->m_BufferToMemoryMap.end())
3782  {
3783  VMA_ASSERT(0 && "Trying to destroy buffer that was not created using vmaCreateBuffer or already freed.");
3784  return;
3785  }
3786  mem = it->second;
3787  allocator->m_BufferToMemoryMap.erase(it);
3788  }
3789 
3790  vkDestroyBuffer(allocator->m_hDevice, buffer, allocator->GetAllocationCallbacks());
3791 
3792  allocator->FreeMemory(&mem);
3793  }
3794 }
3795 
3796 VkResult vmaCreateImage(
3797  VmaAllocator allocator,
3798  const VkImageCreateInfo* pCreateInfo,
3799  const VmaMemoryRequirements* pMemoryRequirements,
3800  VkImage* pImage,
3801  VkMappedMemoryRange* pMemory,
3802  uint32_t* pMemoryTypeIndex)
3803 {
3804  VMA_ASSERT(allocator && pCreateInfo && pMemoryRequirements);
3805 
3806  VMA_DEBUG_LOG("vmaCreateImage");
3807 
3808  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3809 
3810  // 1. Create VkImage.
3811  VkResult res = vkCreateImage(allocator->m_hDevice, pCreateInfo, allocator->GetAllocationCallbacks(), pImage);
3812  if(res >= 0)
3813  {
3814  VkMappedMemoryRange mem = {};
3815  VmaSuballocationType suballocType = pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
3816  VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
3817  VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;
3818 
3819  // 2. Allocate memory using allocator.
3820  res = AllocateMemoryForImage(allocator, *pImage, pMemoryRequirements, suballocType, &mem, pMemoryTypeIndex);
3821  if(res >= 0)
3822  {
3823  if(pMemory != VMA_NULL)
3824  *pMemory = mem;
3825  // 3. Bind image with memory.
3826  res = vkBindImageMemory(allocator->m_hDevice, *pImage, mem.memory, mem.offset);
3827  if(res >= 0)
3828  {
3829  // All steps succeeded.
3830  VmaMutexLock lock(allocator->m_ImageToMemoryMapMutex);
3831  allocator->m_ImageToMemoryMap.insert(VmaPair<VkImage, VkMappedMemoryRange>(*pImage, mem));
3832  return VK_SUCCESS;
3833  }
3834  allocator->FreeMemory(&mem);
3835  return res;
3836  }
3837  vkDestroyImage(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
3838  return res;
3839  }
3840  return res;
3841 }
3842 
3843 void vmaDestroyImage(
3844  VmaAllocator allocator,
3845  VkImage image)
3846 {
3847  if(image != VK_NULL_HANDLE)
3848  {
3849  VMA_ASSERT(allocator);
3850 
3851  VMA_DEBUG_LOG("vmaDestroyImage");
3852 
3853  VMA_DEBUG_GLOBAL_MUTEX_LOCK
3854 
3855  VkMappedMemoryRange mem = {};
3856  {
3857  VmaMutexLock lock(allocator->m_ImageToMemoryMapMutex);
3858  VMA_MAP_TYPE(VkImage, VkMappedMemoryRange)::iterator it = allocator->m_ImageToMemoryMap.find(image);
3859  if(it == allocator->m_ImageToMemoryMap.end())
3860  {
3861  VMA_ASSERT(0 && "Trying to destroy buffer that was not created using vmaCreateBuffer or already freed.");
3862  return;
3863  }
3864  mem = it->second;
3865  allocator->m_ImageToMemoryMap.erase(it);
3866  }
3867 
3868  vkDestroyImage(allocator->m_hDevice, image, allocator->GetAllocationCallbacks());
3869 
3870  allocator->FreeMemory(&mem);
3871  }
3872 }
3873 
3874 #endif // #ifdef VMA_IMPLEMENTATION
3875 
3876 #endif // AMD_VULKAN_MEMORY_ALLOCATOR_H
struct VmaMemoryRequirements VmaMemoryRequirements
+
void vmaUnmapMemory(VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
+
VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition: vk_mem_alloc.h:163
+
VkResult vmaMapMemory(VmaAllocator allocator, const VkMappedMemoryRange *pMemory, void **ppData)
+
Memory will be used for writing on device and readback on host.
Definition: vk_mem_alloc.h:274
+
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:293
+
VkResult vmaAllocateMemoryForImage(VmaAllocator allocator, VkImage image, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
Function similar to vmaAllocateMemoryForBuffer().
+
const VkAllocationCallbacks * pAllocationCallbacks
Custom allocation callbacks.
Definition: vk_mem_alloc.h:175
+
Description of a Allocator to be created.
Definition: vk_mem_alloc.h:159
+
VkDeviceSize preferredSmallHeapBlockSize
Size of a single memory block to allocate for resources from a small heap <= 512 MB.
Definition: vk_mem_alloc.h:172
+
VmaStatInfo total
Definition: vk_mem_alloc.h:230
+
VkDevice device
Vulkan device.
Definition: vk_mem_alloc.h:166
+
VkResult vmaAllocateMemory(VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const VmaMemoryRequirements *pVmaMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
General purpose memory allocation.
+
void vmaBuildStatsString(VmaAllocator allocator, char **ppStatsString, VkBool32 detailedMap)
Builds and returns statistics as string in JSON format.
+
void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer)
+
VkResult vmaCreateImage(VmaAllocator allocator, const VkImageCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkImage *pImage, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
Function similar to vmaCreateBuffer().
+
General statistics from current state of Allocator.
Definition: vk_mem_alloc.h:226
+
VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
Creates Allocator object.
+
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a Memory Type chosen for an allocation.
Definition: vk_mem_alloc.h:302
+
VmaMemoryUsage
Definition: vk_mem_alloc.h:263
+
void vmaDestroyAllocator(VmaAllocator allocator)
Destroys allocator object.
+
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pCreateInfo, const VmaMemoryRequirements *pMemoryRequirements, VkBuffer *pBuffer, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
+
void vmaCalculateStats(VmaAllocator allocator, VmaStats *pStats)
Retrieves statistics from current state of the Allocator.
+
Definition: vk_mem_alloc.h:214
+
VkMemoryPropertyFlags requiredFlags
Flags that must be set in a Memory Type chosen for an allocation.
Definition: vk_mem_alloc.h:297
+
Definition: vk_mem_alloc.h:278
+
VkBool32 neverAllocate
Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such b...
Definition: vk_mem_alloc.h:309
+
VkDeviceSize UnusedRangeSizeMax
Definition: vk_mem_alloc.h:222
+
VkDeviceSize SuballocationSizeMax
Definition: vk_mem_alloc.h:221
+
struct VmaAllocatorCreateInfo VmaAllocatorCreateInfo
Description of a Allocator to be created.
+
VkBool32 ownMemory
Set to true if this allocation should have its own memory block.
Definition: vk_mem_alloc.h:288
+
VmaStatInfo memoryType[VK_MAX_MEMORY_TYPES]
Definition: vk_mem_alloc.h:228
+
void vmaDestroyImage(VmaAllocator allocator, VkImage image)
+
uint32_t AllocationCount
Definition: vk_mem_alloc.h:216
+
void vmaGetPhysicalDeviceProperties(VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)
+
VkDeviceSize UsedBytes
Definition: vk_mem_alloc.h:219
+
VkDeviceSize preferredLargeHeapBlockSize
Size of a single memory block to allocate for resources.
Definition: vk_mem_alloc.h:169
+
uint32_t UnusedRangeCount
Definition: vk_mem_alloc.h:218
+
Memory will be mapped on host. Could be used for transfer to device.
Definition: vk_mem_alloc.h:270
+
void vmaGetMemoryProperties(VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties **ppPhysicalDeviceMemoryProperties)
+
uint32_t SuballocationCount
Definition: vk_mem_alloc.h:217
+
VkDeviceSize UnusedRangeSizeAvg
Definition: vk_mem_alloc.h:222
+
VkDeviceSize SuballocationSizeMin
Definition: vk_mem_alloc.h:221
+
VkResult vmaAllocateMemoryForBuffer(VmaAllocator allocator, VkBuffer buffer, const VmaMemoryRequirements *pMemoryRequirements, VkMappedMemoryRange *pMemory, uint32_t *pMemoryTypeIndex)
+
VkDeviceSize SuballocationSizeAvg
Definition: vk_mem_alloc.h:221
+
void vmaFreeStatsString(VmaAllocator allocator, char *pStatsString)
+
No intended memory usage specified.
Definition: vk_mem_alloc.h:266
+
Definition: vk_mem_alloc.h:275
+
Memory will be used for frequent (dynamic) updates from host and reads on device. ...
Definition: vk_mem_alloc.h:272
+
void vmaGetMemoryTypeProperties(VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags *pFlags)
Given Memory Type Index, returns Property Flags of this memory type.
+
Memory will be used on device only, no need to be mapped on host.
Definition: vk_mem_alloc.h:268
+
struct VmaStatInfo VmaStatInfo
+
VkDeviceSize UnusedBytes
Definition: vk_mem_alloc.h:220
+
VmaStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS]
Definition: vk_mem_alloc.h:229
+
VkResult vmaFindMemoryTypeIndex(VmaAllocator allocator, uint32_t memoryTypeBits, const VmaMemoryRequirements *pMemoryRequirements, uint32_t *pMemoryTypeIndex)
+
void vmaFreeMemory(VmaAllocator allocator, const VkMappedMemoryRange *pMemory)
Frees memory previously allocated using vmaAllocateMemoryForBuffer() or vmaAllocateMemoryForImage().
+
VkDeviceSize UnusedRangeSizeMin
Definition: vk_mem_alloc.h:222
+
+ + + + diff --git a/src/Doxyfile b/src/Doxyfile index 52a4ff1..6d71733 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = ../doc +OUTPUT_DIRECTORY = ../docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and