1056 lines
43 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `maplibre/src/render/mod.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>mod.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../source-script.js"></script><script defer src="../../../source-files.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../../../maplibre/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../maplibre/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><div class="sub-container"><a class="sub-logo-container" href="../../../maplibre/index.html"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></a><nav class="sub"><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><button type="button">?</button></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></div></form></nav></div><section id="main-content" class="content"><div class="example-wrap"><pre class="line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
</pre><pre class="rust"><code><span class="doccomment">//! This module implements the rendering algorithm of maplibre-rs. It manages the whole
//! communication with the GPU.
//!
//! The render in this module is largely based on the
//! [bevy_render](https://github.com/bevyengine/bevy/tree/aced6a/crates/bevy_render)
//! crate with commit `aced6a`.
//! It is dual-licensed under MIT and Apache:
//!
//! ```text
//! Bevy is dual-licensed under either
//!
//! * MIT License (docs/LICENSE-MIT or http://opensource.org/licenses/MIT)
//! * Apache License, Version 2.0 (docs/LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
//!
//! at your option.
//! ```
//!
//! We appreciate the design and implementation work which as gone into it.
//!
</span><span class="kw">use </span>std::sync::Arc;
<span class="kw">use </span>log::info;
<span class="kw">use crate</span>::{
render::{
eventually::Eventually,
render_phase::RenderPhase,
resource::{BufferPool, Globals, Head, IndexEntry, Surface, Texture, TextureView},
settings::{RendererSettings, WgpuSettings},
shaders::{ShaderFeatureStyle, ShaderLayerMetadata},
tile_view_pattern::{TileInView, TileShape, TileViewPattern},
},
tessellation::IndexDataType,
};
<span class="kw">pub mod </span>graph;
<span class="kw">pub mod </span>resource;
<span class="kw">pub mod </span>stages;
<span class="comment">// Rendering internals
</span><span class="kw">mod </span>graph_runner;
<span class="kw">mod </span>main_pass;
<span class="kw">mod </span>render_commands;
<span class="kw">mod </span>render_phase;
<span class="kw">mod </span>shaders;
<span class="kw">mod </span>tile_pipeline;
<span class="kw">mod </span>tile_view_pattern;
<span class="comment">// Public API
</span><span class="kw">pub mod </span>builder;
<span class="kw">pub mod </span>camera;
<span class="kw">pub mod </span>error;
<span class="kw">pub mod </span>eventually;
<span class="kw">pub mod </span>settings;
<span class="kw">pub use </span>shaders::ShaderVertex;
<span class="kw">pub use </span>stages::register_default_render_stages;
<span class="kw">use crate</span>::{
render::{
graph::{EmptyNode, RenderGraph, RenderGraphError},
main_pass::{MainPassDriverNode, MainPassNode},
},
window::{HeadedMapWindow, MapWindow},
};
<span class="kw">const </span>INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32; <span class="comment">// Must match IndexDataType
</span><span class="kw">pub struct </span>RenderState {
render_target: Eventually&lt;TextureView&gt;,
buffer_pool: Eventually&lt;
BufferPool&lt;
wgpu::Queue,
wgpu::Buffer,
ShaderVertex,
IndexDataType,
ShaderLayerMetadata,
ShaderFeatureStyle,
&gt;,
&gt;,
tile_view_pattern: Eventually&lt;TileViewPattern&lt;wgpu::Queue, wgpu::Buffer&gt;&gt;,
tile_pipeline: Eventually&lt;wgpu::RenderPipeline&gt;,
mask_pipeline: Eventually&lt;wgpu::RenderPipeline&gt;,
globals_bind_group: Eventually&lt;Globals&gt;,
depth_texture: Eventually&lt;Texture&gt;,
multisampling_texture: Eventually&lt;<span class="prelude-ty">Option</span>&lt;Texture&gt;&gt;,
surface: Surface,
mask_phase: RenderPhase&lt;TileInView&gt;,
tile_phase: RenderPhase&lt;(IndexEntry, TileShape)&gt;,
}
<span class="kw">impl </span>RenderState {
<span class="kw">pub fn </span>new(surface: Surface) -&gt; <span class="self">Self </span>{
<span class="self">Self </span>{
render_target: Default::default(),
buffer_pool: Default::default(),
tile_view_pattern: Default::default(),
tile_pipeline: Default::default(),
mask_pipeline: Default::default(),
globals_bind_group: Default::default(),
depth_texture: Default::default(),
multisampling_texture: Default::default(),
surface,
mask_phase: Default::default(),
tile_phase: Default::default(),
}
}
<span class="kw">pub fn </span>recreate_surface&lt;MW&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, window: <span class="kw-2">&amp;</span>MW, instance: <span class="kw-2">&amp;</span>wgpu::Instance)
<span class="kw">where
</span>MW: MapWindow + HeadedMapWindow,
{
<span class="self">self</span>.surface.recreate::&lt;MW&gt;(window, instance);
}
<span class="kw">pub fn </span>surface(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>Surface {
<span class="kw-2">&amp;</span><span class="self">self</span>.surface
}
<span class="kw">pub fn </span>buffer_pool_mut(
<span class="kw-2">&amp;mut </span><span class="self">self</span>,
) -&gt; <span class="kw-2">&amp;mut </span>Eventually&lt;
BufferPool&lt;
wgpu::Queue,
wgpu::Buffer,
ShaderVertex,
IndexDataType,
ShaderLayerMetadata,
ShaderFeatureStyle,
&gt;,
&gt; {
<span class="kw-2">&amp;mut </span><span class="self">self</span>.buffer_pool
}
}
<span class="kw">pub struct </span>Renderer {
<span class="kw">pub </span>instance: wgpu::Instance,
<span class="kw">pub </span>device: Arc&lt;wgpu::Device&gt;, <span class="comment">// TODO: Arc is needed for headless rendering. Is there a simpler solution?
</span><span class="kw">pub </span>queue: wgpu::Queue,
<span class="kw">pub </span>adapter_info: wgpu::AdapterInfo,
<span class="kw">pub </span>wgpu_settings: WgpuSettings,
<span class="kw">pub </span>settings: RendererSettings,
<span class="kw">pub </span>state: RenderState,
}
<span class="kw">impl </span>Renderer {
<span class="doccomment">/// Initializes the renderer by retrieving and preparing the GPU instance, device and queue
/// for the specified backend.
</span><span class="kw">pub async fn </span>initialize&lt;MW&gt;(
window: <span class="kw-2">&amp;</span>MW,
wgpu_settings: WgpuSettings,
settings: RendererSettings,
) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, wgpu::RequestDeviceError&gt;
<span class="kw">where
</span>MW: MapWindow + HeadedMapWindow,
{
<span class="kw">let </span>instance = wgpu::Instance::new(wgpu_settings.backends.unwrap_or(wgpu::Backends::all()));
<span class="kw">let </span>surface = Surface::from_window(<span class="kw-2">&amp;</span>instance, window, <span class="kw-2">&amp;</span>settings);
<span class="kw">let </span>compatible_surface = <span class="kw">match </span><span class="kw-2">&amp;</span>surface.head() {
Head::Headed(window_head) =&gt; <span class="prelude-val">Some</span>(window_head.surface()),
Head::Headless(<span class="kw">_</span>) =&gt; <span class="prelude-val">None</span>,
};
<span class="kw">let </span>(device, queue, adapter_info) = <span class="self">Self</span>::request_device(
<span class="kw-2">&amp;</span>instance,
<span class="kw-2">&amp;</span>wgpu_settings,
<span class="kw-2">&amp;</span>wgpu::RequestAdapterOptions {
power_preference: wgpu_settings.power_preference,
force_fallback_adapter: <span class="bool-val">false</span>,
compatible_surface,
},
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">match </span>surface.head() {
Head::Headed(window) =&gt; window.configure(<span class="kw-2">&amp;</span>device),
Head::Headless(<span class="kw">_</span>) =&gt; {}
}
<span class="prelude-val">Ok</span>(<span class="self">Self </span>{
instance,
device: Arc::new(device),
queue,
adapter_info,
wgpu_settings,
settings,
state: RenderState::new(surface),
})
}
<span class="kw">pub async fn </span>initialize_headless&lt;MW&gt;(
window: <span class="kw-2">&amp;</span>MW,
wgpu_settings: WgpuSettings,
settings: RendererSettings,
) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, wgpu::RequestDeviceError&gt;
<span class="kw">where
</span>MW: MapWindow,
{
<span class="kw">let </span>instance = wgpu::Instance::new(wgpu_settings.backends.unwrap_or(wgpu::Backends::all()));
<span class="kw">let </span>(device, queue, adapter_info) = <span class="self">Self</span>::request_device(
<span class="kw-2">&amp;</span>instance,
<span class="kw-2">&amp;</span>wgpu_settings,
<span class="kw-2">&amp;</span>wgpu::RequestAdapterOptions {
power_preference: wgpu_settings.power_preference,
force_fallback_adapter: <span class="bool-val">false</span>,
compatible_surface: <span class="prelude-val">None</span>,
},
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>surface = Surface::from_image(<span class="kw-2">&amp;</span>device, window, <span class="kw-2">&amp;</span>settings);
<span class="prelude-val">Ok</span>(<span class="self">Self </span>{
instance,
device: Arc::new(device),
queue,
adapter_info,
wgpu_settings,
settings,
state: RenderState::new(surface),
})
}
<span class="kw">pub fn </span>resize(<span class="kw-2">&amp;mut </span><span class="self">self</span>, width: u32, height: u32) {
<span class="self">self</span>.state.surface.resize(width, height)
}
<span class="doccomment">/// Requests a device
</span><span class="kw">async fn </span>request_device(
instance: <span class="kw-2">&amp;</span>wgpu::Instance,
settings: <span class="kw-2">&amp;</span>WgpuSettings,
request_adapter_options: <span class="kw-2">&amp;</span>wgpu::RequestAdapterOptions&lt;<span class="lifetime">&#39;_</span>&gt;,
) -&gt; <span class="prelude-ty">Result</span>&lt;(wgpu::Device, wgpu::Queue, wgpu::AdapterInfo), wgpu::RequestDeviceError&gt; {
<span class="kw">let </span>adapter = instance
.request_adapter(request_adapter_options)
.<span class="kw">await
</span>.expect(<span class="string">&quot;Unable to find a GPU! Make sure you have installed required drivers!&quot;</span>);
<span class="kw">let </span>adapter_info = adapter.get_info();
<span class="macro">info!</span>(<span class="string">&quot;{:?}&quot;</span>, adapter_info);
<span class="attribute">#[cfg(not(target_arch = <span class="string">&quot;wasm32&quot;</span>))]
</span><span class="kw">let </span>trace_path = <span class="kw">if </span>settings.record_trace {
<span class="kw">let </span>path = std::path::Path::new(<span class="string">&quot;wgpu_trace&quot;</span>);
<span class="comment">// ignore potential error, wgpu will log it
</span><span class="kw">let _ </span>= std::fs::create_dir(path);
<span class="prelude-val">Some</span>(path)
} <span class="kw">else </span>{
<span class="prelude-val">None
</span>};
<span class="attribute">#[cfg(target_arch = <span class="string">&quot;wasm32&quot;</span>)]
</span><span class="kw">let </span>trace_path = <span class="prelude-val">None</span>;
<span class="kw">let </span><span class="kw-2">mut </span>features =
adapter.features() | wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES;
<span class="kw">if </span>adapter_info.device_type == wgpu::DeviceType::DiscreteGpu {
<span class="comment">// `MAPPABLE_PRIMARY_BUFFERS` can have a significant, negative performance impact for
// discrete GPUs due to having to transfer data across the PCI-E bus and so it
// should not be automatically enabled in this case. It is however beneficial for
// integrated GPUs.
</span>features -= wgpu::Features::MAPPABLE_PRIMARY_BUFFERS;
}
<span class="kw">let </span><span class="kw-2">mut </span>limits = adapter.limits();
<span class="comment">// Enforce the disabled features
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(disabled_features) = settings.disabled_features {
features -= disabled_features;
}
<span class="comment">// NOTE: |= is used here to ensure that any explicitly-enabled features are respected.
</span>features |= settings.features;
<span class="comment">// Enforce the limit constraints
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(constrained_limits) = settings.constrained_limits.as_ref() {
<span class="comment">// NOTE: Respect the configured limits as an &#39;upper bound&#39;. This means for &#39;max&#39; limits, we
// take the minimum of the calculated limits according to the adapter/backend and the
// specified max_limits. For &#39;min&#39; limits, take the maximum instead. This is intended to
// err on the side of being conservative. We can&#39;t claim &#39;higher&#39; limits that are supported
// but we can constrain to &#39;lower&#39; limits.
</span>limits = wgpu::Limits {
max_texture_dimension_1d: limits
.max_texture_dimension_1d
.min(constrained_limits.max_texture_dimension_1d),
max_texture_dimension_2d: limits
.max_texture_dimension_2d
.min(constrained_limits.max_texture_dimension_2d),
max_texture_dimension_3d: limits
.max_texture_dimension_3d
.min(constrained_limits.max_texture_dimension_3d),
max_texture_array_layers: limits
.max_texture_array_layers
.min(constrained_limits.max_texture_array_layers),
max_bind_groups: limits
.max_bind_groups
.min(constrained_limits.max_bind_groups),
max_dynamic_uniform_buffers_per_pipeline_layout: limits
.max_dynamic_uniform_buffers_per_pipeline_layout
.min(constrained_limits.max_dynamic_uniform_buffers_per_pipeline_layout),
max_dynamic_storage_buffers_per_pipeline_layout: limits
.max_dynamic_storage_buffers_per_pipeline_layout
.min(constrained_limits.max_dynamic_storage_buffers_per_pipeline_layout),
max_sampled_textures_per_shader_stage: limits
.max_sampled_textures_per_shader_stage
.min(constrained_limits.max_sampled_textures_per_shader_stage),
max_samplers_per_shader_stage: limits
.max_samplers_per_shader_stage
.min(constrained_limits.max_samplers_per_shader_stage),
max_storage_buffers_per_shader_stage: limits
.max_storage_buffers_per_shader_stage
.min(constrained_limits.max_storage_buffers_per_shader_stage),
max_storage_textures_per_shader_stage: limits
.max_storage_textures_per_shader_stage
.min(constrained_limits.max_storage_textures_per_shader_stage),
max_uniform_buffers_per_shader_stage: limits
.max_uniform_buffers_per_shader_stage
.min(constrained_limits.max_uniform_buffers_per_shader_stage),
max_uniform_buffer_binding_size: limits
.max_uniform_buffer_binding_size
.min(constrained_limits.max_uniform_buffer_binding_size),
max_storage_buffer_binding_size: limits
.max_storage_buffer_binding_size
.min(constrained_limits.max_storage_buffer_binding_size),
max_vertex_buffers: limits
.max_vertex_buffers
.min(constrained_limits.max_vertex_buffers),
max_vertex_attributes: limits
.max_vertex_attributes
.min(constrained_limits.max_vertex_attributes),
max_vertex_buffer_array_stride: limits
.max_vertex_buffer_array_stride
.min(constrained_limits.max_vertex_buffer_array_stride),
max_push_constant_size: limits
.max_push_constant_size
.min(constrained_limits.max_push_constant_size),
min_uniform_buffer_offset_alignment: limits
.min_uniform_buffer_offset_alignment
.max(constrained_limits.min_uniform_buffer_offset_alignment),
min_storage_buffer_offset_alignment: limits
.min_storage_buffer_offset_alignment
.max(constrained_limits.min_storage_buffer_offset_alignment),
max_inter_stage_shader_components: limits
.max_inter_stage_shader_components
.min(constrained_limits.max_inter_stage_shader_components),
max_compute_workgroup_storage_size: limits
.max_compute_workgroup_storage_size
.min(constrained_limits.max_compute_workgroup_storage_size),
max_compute_invocations_per_workgroup: limits
.max_compute_invocations_per_workgroup
.min(constrained_limits.max_compute_invocations_per_workgroup),
max_compute_workgroup_size_x: limits
.max_compute_workgroup_size_x
.min(constrained_limits.max_compute_workgroup_size_x),
max_compute_workgroup_size_y: limits
.max_compute_workgroup_size_y
.min(constrained_limits.max_compute_workgroup_size_y),
max_compute_workgroup_size_z: limits
.max_compute_workgroup_size_z
.min(constrained_limits.max_compute_workgroup_size_z),
max_compute_workgroups_per_dimension: limits
.max_compute_workgroups_per_dimension
.min(constrained_limits.max_compute_workgroups_per_dimension),
max_buffer_size: limits
.max_buffer_size
.min(constrained_limits.max_buffer_size),
};
}
<span class="kw">let </span>(device, queue) = adapter
.request_device(
<span class="kw-2">&amp;</span>wgpu::DeviceDescriptor {
label: settings.device_label.as_ref().map(|a| a.as_ref()),
features,
limits,
},
trace_path,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>((device, queue, adapter_info))
}
<span class="kw">pub fn </span>instance(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>wgpu::Instance {
<span class="kw-2">&amp;</span><span class="self">self</span>.instance
}
<span class="kw">pub fn </span>device(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>wgpu::Device {
<span class="kw-2">&amp;</span><span class="self">self</span>.device
}
<span class="kw">pub fn </span>queue(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>wgpu::Queue {
<span class="kw-2">&amp;</span><span class="self">self</span>.queue
}
<span class="kw">pub fn </span>state(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>RenderState {
<span class="kw-2">&amp;</span><span class="self">self</span>.state
}
<span class="kw">pub fn </span>surface(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>Surface {
<span class="kw-2">&amp;</span><span class="self">self</span>.state.surface
}
}
<span class="attribute">#[cfg(test)]
</span><span class="kw">mod </span>tests {
<span class="kw">use </span><span class="kw">crate</span>::window::{MapWindow, MapWindowConfig, WindowSize};
<span class="kw">pub struct </span>HeadlessMapWindowConfig {
size: WindowSize,
}
<span class="kw">impl </span>MapWindowConfig <span class="kw">for </span>HeadlessMapWindowConfig {
<span class="kw">type </span>MapWindow = HeadlessMapWindow;
<span class="kw">fn </span>create(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="self">Self</span>::MapWindow {
<span class="self">Self</span>::MapWindow { size: <span class="self">self</span>.size }
}
}
<span class="kw">pub struct </span>HeadlessMapWindow {
size: WindowSize,
}
<span class="kw">impl </span>MapWindow <span class="kw">for </span>HeadlessMapWindow {
<span class="kw">fn </span>size(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; WindowSize {
<span class="self">self</span>.size
}
}
<span class="attribute">#[cfg(not(target_arch = <span class="string">&quot;wasm32&quot;</span>))]
#[tokio::test]
</span><span class="kw">async fn </span>test_render() {
<span class="kw">use </span>log::LevelFilter;
<span class="kw">use </span><span class="kw">crate</span>::render::{
graph::RenderGraph, graph_runner::RenderGraphRunner, resource::Surface, RenderState,
RendererSettings,
};
<span class="kw">let _ </span>= env_logger::builder()
.filter_level(LevelFilter::Trace)
.is_test(<span class="bool-val">true</span>)
.try_init();
<span class="kw">let </span>graph = RenderGraph::default();
<span class="kw">let </span>backends = wgpu::util::backend_bits_from_env().unwrap_or(wgpu::Backends::all());
<span class="kw">let </span>instance = wgpu::Instance::new(backends);
<span class="kw">let </span>adapter = wgpu::util::initialize_adapter_from_env_or_default(<span class="kw-2">&amp;</span>instance, backends, <span class="prelude-val">None</span>)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>(device, queue) = adapter
.request_device(
<span class="kw-2">&amp;</span>wgpu::DeviceDescriptor {
label: <span class="prelude-val">None</span>,
features: wgpu::Features::default(),
limits: wgpu::Limits::default(),
},
<span class="prelude-val">None</span>,
)
.<span class="kw">await
</span>.ok()
.unwrap();
<span class="kw">let </span>render_state = RenderState::new(Surface::from_image(
<span class="kw-2">&amp;</span>device,
<span class="kw-2">&amp;</span>HeadlessMapWindow {
size: WindowSize::new(<span class="number">100</span>, <span class="number">100</span>).unwrap(),
},
<span class="kw-2">&amp;</span>RendererSettings::default(),
));
RenderGraphRunner::run(<span class="kw-2">&amp;</span>graph, <span class="kw-2">&amp;</span>device, <span class="kw-2">&amp;</span>queue, <span class="kw-2">&amp;</span>render_state).unwrap();
}
}
<span class="comment">// Contributors to the RenderGraph should use the following label conventions:
// 1. Graph modules should have a NAME, input module, and node module (where relevant)
// 2. The &quot;main_graph&quot; graph is the root.
// 3. &quot;sub graph&quot; modules should be nested beneath their parent graph module
</span><span class="kw">pub mod </span>main_graph {
<span class="comment">// Labels for input nodes
</span><span class="kw">pub mod </span>input {}
<span class="comment">// Labels for non-input nodes
</span><span class="kw">pub mod </span>node {
<span class="kw">pub const </span>MAIN_PASS_DEPENDENCIES: <span class="kw-2">&amp;</span>str = <span class="string">&quot;main_pass_dependencies&quot;</span>;
<span class="kw">pub const </span>MAIN_PASS_DRIVER: <span class="kw-2">&amp;</span>str = <span class="string">&quot;main_pass_driver&quot;</span>;
}
}
<span class="doccomment">/// Labels for the &quot;draw&quot; graph
</span><span class="kw">pub mod </span>draw_graph {
<span class="kw">pub const </span>NAME: <span class="kw-2">&amp;</span>str = <span class="string">&quot;draw&quot;</span>;
<span class="comment">// Labels for input nodes
</span><span class="kw">pub mod </span>input {}
<span class="comment">// Labels for non-input nodes
</span><span class="kw">pub mod </span>node {
<span class="kw">pub const </span>MAIN_PASS: <span class="kw-2">&amp;</span>str = <span class="string">&quot;main_pass&quot;</span>;
<span class="attribute">#[cfg(feature = <span class="string">&quot;headless&quot;</span>)]
</span><span class="kw">pub const </span>COPY: <span class="kw-2">&amp;</span>str = <span class="string">&quot;copy&quot;</span>;
}
}
<span class="kw">pub fn </span>create_default_render_graph() -&gt; <span class="prelude-ty">Result</span>&lt;RenderGraph, RenderGraphError&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>graph = RenderGraph::default();
<span class="kw">let </span><span class="kw-2">mut </span>draw_graph = RenderGraph::default();
draw_graph.add_node(draw_graph::node::MAIN_PASS, MainPassNode::new());
<span class="kw">let </span>input_node_id = draw_graph.set_input(<span class="macro">vec!</span>[]);
draw_graph.add_node_edge(input_node_id, draw_graph::node::MAIN_PASS)<span class="question-mark">?</span>;
graph.add_sub_graph(draw_graph::NAME, draw_graph);
graph.add_node(main_graph::node::MAIN_PASS_DEPENDENCIES, EmptyNode);
graph.add_node(main_graph::node::MAIN_PASS_DRIVER, MainPassDriverNode);
graph.add_node_edge(
main_graph::node::MAIN_PASS_DEPENDENCIES,
main_graph::node::MAIN_PASS_DRIVER,
)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(graph)
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="maplibre" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.65.0 (897e37553 2022-11-02)" ></div></body></html>