使用Xcode External Build System實現Rust 項目 Capture GPU Frame 在線調試 Metal

文檔列表見:Rust 移動端跨平臺複雜圖形渲染項目開發系列總結(目錄)git

上次更新:2018.12.18github

根據kvark指導,Xcode建立External Build System項目可經過Capture GPU Frame查看gfx-hal的examples繪製過程,略出乎意料,我沒想過能夠這麼幹(浪),雖然2015年我用External Build System單步調試過FFmpeg源碼,可是我不知道Xcode也支持這種形式的Capture GPU Frame,能夠說很無知且沒有探索精神了。緩存

雖然gfx-hal有完美的日誌輸出,可是,做爲剛接觸gfx項目和Rust的初學者,有時我想確認程序流程是否符合預期(我一直在忙其餘事,不多看Rust語法,這是我的失誤),即使Rust寫日誌輸出比C++方便不少,不過圖形項目開發過程當中仍是幀回放定位問題的效率最高 。可是,折騰一番,我在3臺mac(MacBook Pro + iMac)上一執行就崩潰。劉子殊在他本地測試也崩潰。我以爲多是工程配置出錯了,緣由是,終端直接運行gfx/examples/quad等可執行文件是正常的。bash

客觀地說,隔了一段時間沒用Xcode,我不熟悉它的配置了,而後考慮並驗證了下列幾個替代方案:工具

  • Rust暴露C接口接入macOS項目。給gfx/examples填寫FFI接口,讓C/C++調用Rust實現的功能。在繪製過程當中正常使用Capture GPU Frame。
  • 利用Metal MTLCommandBuffer addCompletedHandler接口添加執行完成的日誌。缺點是,只能驗證MTLCommandBuffer確實被GPU執行完,無法查看渲染結果。用Compute Shader作數值計算場合用這個方案卻是能夠接受。
  • 相似上一方案,不輸出日誌,改成讀取MTLCommandBuffer目標紋理的像素值,經過CIImage生成圖像,經過Xcode插件進行查看。缺點,在線調試Shader沒Capture GPU Frame方便。

然而,我仍是無法放棄Capture GPU Frame by External Build System方案,由於它配置和二次開發成本最低,最合適咱們當前的團隊狀態。花了好長時間,在Josh的幫助下,終於解決了。post

問題現象: examples/三個項目以External Build System項目形式在Xcode中運行後崩潰,提示信息:測試

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 20, kind: Other, message: "Not a directory" }', libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
ERROR 2018-11-30T07:12:36Z: gfx_backend_metal::command: Command buffer not released properly!
thread 'main' panicked at 'assertion failed: !self.active', src/backend/metal/src/command.rs:55:9
複製代碼

結論: External Build Tool Configuration的Directory配置項只用於build過程,對於Rust項目,src/target/是兩個不一樣的目錄,examples/那些項目要求的編譯和執行路徑是examples/,根本緣由是,examples代碼用fs::read_to_string()經過相對路徑加載glsl源碼文件!此時相對路徑前面的完整路徑就隱式限制爲examples/ 。然而,Xcode的播放按鈕功能是Build and then run the current scheme,Build階段配置正常了,問題出在Run階段,須要傳遞正確的路徑,示例以下圖所示。ui

Working Directory的正確配置

正常的Capture GPU Frame截圖。 spa

正常的Capture GPU Frame截圖

下面覆盤當時的嘗試過程,流下了無知的淚水。插件

  • 同一個電腦(10.14 + Xcode 9.4.1 (9F2000))上依次嘗試examples/三個demo項目。運行失敗,下面簡寫成失敗。
  • 換兩臺電腦(10.13.5 + Xcode 9.4.1 (9F2000)、10.13.5 + Xcode 10 )嘗試上一步驟 ——> 失敗。
  • 重置代碼庫,獲取最新代碼,從新用Xcode運行 ——> 失敗。
  • 去掉Xcode Main Thread Checker,從新用Xcode運行 ——> 失敗。
  • 修改Rust編譯工具鏈,依次用nightly、stable,清掉編譯緩存,從新編譯,從新用Xcode運行 ——> 失敗。
  • 升級Rust編譯工具鏈,重複上一步驟 ——> 失敗。
  • 反覆修改External Build Tool Configuration的三個配置項,確認它們的值都正確 ——> 失敗。
  • 修改Xcode工程位置,重複前面全部步驟 ——> 失敗。
  • 修改當前Scheme/Run/Debug/Info的全部配置項,重複前面全部步驟 ——> 失敗。
  • 搜索更多Xcode運行Rust項目資料並逐一修改,重複前面全部步驟 ——> 失敗。
  • 和別人討論解決方案 ——> 失敗,開始接近問題本質緣由。感謝齒輪哥。
  • 在Terminal切換到target/debug/執行quad ——> 失敗,報錯和Xcode幾乎一致。
  • 查看源碼,找到fs::read_to_string() ——> 問題差很少定位。
  • 修改源碼加上完整文件路徑 ——> Xcode運行不崩潰,可是Capture GPU Frame不可用,問題徹底定位。
  • 換成MacBook Pro重複上一步驟 ——> 正常。推斷:iMac (Retina 5K, 27-inch, Late 2015)在10.14下驅動有問題。
  • 最終Josh給了更好的解決方案(見結論部分),無需修改源碼。
  • 齒輪哥建議使用concat!(env!())補全gfx-hal/examples的shader源碼路徑,我實現後提了PR,老外不一樣意合併。
相關文章
相關標籤/搜索