DC 程式設計模型¶
在 Display Core Next (DCN) 和 DCN 塊 頁面中,您瞭解了硬體元件以及它們如何相互互動。 在此頁面上,重點轉移到顯示程式碼架構。 因此,提醒讀者 DC 中的程式碼與其他作業系統共享是合理的。 因此,DC 提供了一組抽象和操作,用於將不同的 API 與硬體配置連線起來。 將 DC 視為顯示管理器 (amdgpu_dm) 可用於訪問和配置 DCN/DCE 硬體的服務(DCE 也是 DC 的一部分,但為了簡單起見,本文件僅檢查 DCN)。
注意
對於本頁,我們將使用術語 GPU 來指代 dGPU 和 APU。
概述¶
從顯示硬體的角度來看,可以合理地預期,如果一個問題被很好地定義,它可能會在硬體層面實現。 另一方面,當有多種方法可以在沒有非常明確定義範圍的情況下實現某些目標時,解決方案通常作為 DC 級別的策略來實現。 換句話說,一些策略在 DC 核心中定義(資源管理、電源最佳化、影像質量等),而硬體中實現的其他策略透過 DC 配置啟用。
在硬體管理方面,DCN 具有相同塊的多個例項(例如,HUBP、DPP、MPC 等),並且在驅動程式執行期間,可能需要使用其中一些例項。 核心具有處理這些例項的策略。 關於資源管理,DC 的目標非常簡單:當驅動程式執行某些操作時,最大限度地減少硬體 shuffle。 當狀態從 A 變為 B 時,如果硬體資源仍用於同一組驅動程式物件,則該轉換被認為更容易操作。 通常,向 pipe_ctx(更多細節如下)新增和刪除資源不是問題; 但是,應避免將資源從一個 pipe_ctx 移動到另一個 pipe_ctx。
DC 的另一個影響領域是電源最佳化,它有無數種排列可能性。 在某種程度上,僅透過 DCN 顯示影像應該相對簡單; 但是,以最佳功耗顯示它更受歡迎,但它有許多相關的挑戰。 不幸的是,由於與此問題相關的變數種類繁多(例如,許多不同的 DCN/DCE 硬體版本、不同的顯示配置等),沒有直接的分析方法來確定配置是否最適合上下文,因此 DC 實現了一個專用庫來嘗試一些配置並驗證是否可以支援它。 這種型別的策略的建立和維護非常複雜,並且 amdgpu 驅動程式依賴於顯示模式庫 (DML) 來生成最佳決策。
總而言之,DC 必須處理處理多個場景的複雜性,並確定管理它們的策略。 傳達上述所有資訊是為了讓讀者瞭解從驅動程式的角度驅動顯示器的複雜性。 此頁面希望使讀者能夠更好地瀏覽 amdgpu 顯示程式碼。
顯示驅動程式架構概述¶
下圖提供了顯示驅動程式架構的概述; 請注意,它說明了 DC 採用的軟體層
該圖的第一層是由 dc.h 檔案表示的高階 DC API; 在它下面是由 Core 和 Link 表示的兩個大塊。 接下來是硬體配置塊; 描述它的主要檔案是 `hw_sequencer.h`,其中回撥的實現可以在硬體序列器資料夾中找到。 幾乎在最後,您可以看到塊級別 API (dc/inc/hw),它表示每個 DCN 底層塊,例如 HUBP、DPP、MPC、OPTC 等。 請注意在圖的左側,我們有一組不同的層代表與 DMUB 微控制器的互動。
基本物件¶
下圖概述了基本的顯示物件。 特別是,請注意框中的名稱,因為它們代表驅動程式中的資料結構
讓我們從影像的中心塊 dc 開始。 dc 結構體是每個 GPU 初始化一次; 例如,一個 GPU 有一個 dc 例項,兩個 GPU 有兩個 dc 例項,依此類推。 換句話說,每個“amdgpu”例項都有一個“dc”。 在某些方面,此物件類似於 Singleton 模式。
在圖中的 dc 塊之後,您可以看到 dc_link 元件,它是聯結器的底層抽象。 影像的一個有趣方面是聯結器不是 DCN 塊的一部分; 它們由平臺/板定義,而不是由 SoC 定義。 dc_link 結構體是高階資料容器,包含連線的 sink、連線狀態、訊號型別等資訊。在 dc_link 之後,是 dc_sink,它是表示連線的顯示器的物件。
注意
由於歷史原因,我們使用了名稱 dc_link,這給人一種錯誤的印象,即這種抽象只處理開發人員可以輕鬆操作的物理連線。 但是,這也涵蓋了像 eDP 這樣的連線,或者輸出連線到其他裝置的情況。
有兩個結構體沒有在圖中表示,因為它們在 DCN 概述頁面中進行了詳細說明(檢視 DCN 塊圖 Display Core Next (DCN)); 儘管如此,仍然值得帶回來進行此概述,即 dc_stream 和 dc_state。dc_stream 儲存與資料傳輸相關的許多屬性,但最重要的是,它代表從聯結器到顯示器的資料流。 接下來是 dc_state,它表示硬體在當前時刻的邏輯狀態; dc_state 由 dc_stream 和 dc_plane 組成。dc_stream 是 drm_crtc 的 DC 版本,代表後混合流水線。
說到 dc_plane 資料結構(圖的第一部分),您可以將其視為類似於 drm_plane 的抽象,它代表流水線的預混合部分。 此影像可能已由 GFX 處理,並且已準備好在 dc_stream 下進行合成。 通常,驅動程式可能有一個或多個 dc_plane 連線到同一個 dc_stream,這定義了 DC 級別的合成。
基本操作¶
現在我們已經介紹了基本物件,現在是時候檢查一些基本的硬體/軟體操作了。 讓我們從 dc_create() 函式開始,它直接處理 dc 資料結構; 此函式的作用類似於建構函式,負責基本的軟體初始化併為啟用 API 的其他部分做準備。 重要的是要強調此操作不會觸及任何硬體配置; 它只是一個軟體初始化。
接下來,我們有 dc_hardware_init(),它也依賴於 dc 資料結構。 它的主要功能是將硬體置於有效狀態。 值得強調的是,硬體可能會在未知狀態下初始化,並且需要將其置於有效狀態; 此函式具有多個特定於硬體初始化的回撥,而 dc_hardware_init 執行硬體初始化,並且是我們接觸硬體的第一個點。
dc_get_link_at_index 是一個依賴於 dc_link 資料結構的操作。 此函式檢索並列舉裝置上所有可用的 dc_links; 這是必需的,因為此資訊不是 SoC 定義的一部分,而是取決於板配置。 一旦 dc_link 被初始化,就可以使用 dc_link_detect() 函式來判斷它們中是否有任何一個已經連線到顯示器。 在驅動程式確定是否有任何顯示器連線到裝置後,具有挑戰性的階段就開始了:配置監視器以顯示某些內容。 儘管如此,處理理想配置不是 DC 的任務,因為這是顯示管理器 (amdgpu_dm) 的職責,後者又負責處理原子提交。 DC 提供給配置階段的唯一介面是函式 dc_validate_with_context,它接收配置資訊,並在此基礎上驗證硬體是否可以支援它。 重要的是要補充一點,即使顯示器支援某些特定配置,也並不意味著 DCN 硬體可以支援它。
在 DM 和 DC 就配置達成一致後,流配置階段開始。 此任務在此階段啟用一個或多個 dc_stream,並且在最佳情況下,您或許可以開啟顯示器並顯示黑屏(它還沒有顯示任何內容,因為它沒有任何與之關聯的 plane)。 最後一步是呼叫 dc_update_planes_and_stream,它將新增或刪除 plane。