Graphics Stack總結(三) Mesa中Driver的加載和查詢

回顧

在之前的文章中,我們解釋了Mesa時一個OpenGL driver的開發框架。正如此,Mesa提供的代碼可以在多種driver的實現中被重用。當然這部分code是跨硬件的,使得驅動開發者不用做這部分工作。這個框架也爲開發者提供了hook,用來增加於與實際硬件的交互的代碼。這種設計允許多種driver共存,並且共享很多代碼。

我也解釋了在Mesa提供的這麼多種的drivers中,我們可以找到純粹用軟件實現的software drivers(它們在CPU上工作,不依賴於GPU)和利用特定GPU優勢的hardware drivers。software drivers更慢,但是就如我們討論的那樣,某些情況下它們會派上用場(比如檢查某個issue是否與GPU hardware driver有關)。

Driver selection

所以,Mesa提供了多種driver,但是它如何在一個特定的系統裏選擇合適的driver呢?

你可能注意到mesa被部署在多個packages裏。在我的Ubuntu系統中,部署DRI drivres的package是libgl1-mesa-dri:amd64,如果你檢查它的內容,會看到這個package會爲不同的GPUs安裝OpenGL drivers。

# dpkg -L libgl1-mesa-dri:amd64 
(...)
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_radeonsi.so
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_r600.so
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_nouveau.so
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_vmwgfx.so
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_r300.so
/usr/lib/x86_64-linux-gnu/gallium-pipe/pipe_swrast.so
/usr/lib/x86_64-linux-gnu/dri/i915_dri.so
/usr/lib/x86_64-linux-gnu/dri/i965_dri.so
/usr/lib/x86_64-linux-gnu/dri/r200_dri.so
/usr/lib/x86_64-linux-gnu/dri/r600_dri.so
/usr/lib/x86_64-linux-gnu/dri/radeon_dri.so
/usr/lib/x86_64-linux-gnu/dri/r300_dri.so
/usr/lib/x86_64-linux-gnu/dri/vmwgfx_dri.so
/usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
/usr/lib/x86_64-linux-gnu/dri/nouveau_vieux_dri.so
/usr/lib/x86_64-linux-gnu/dri/nouveau_dri.so
/usr/lib/x86_64-linux-gnu/dri/radeonsi_dri.so
(...)

因爲我用的是近期的Intel GPU,所以我需要的driver是i965_dri.so。所以我們該如何告訴Mesa那個就是我們需要的driver呢?然而答案是不需要,Mesa足夠智能,它會知道對我們的GPU來說,哪個driver是正確的,並且在你load libGL.so時自動選擇它。Mesa中處理這個環節的部分我們稱之爲"loader"。

然而你也可以讓Mesa在指定的文件夾中尋找適配的driver,而不是在默認設置下,或者通過指定不同的環境變量(using various environment variables.)來強制Mesa選擇一個software driver。

What driver is Mesa actually loading?

如果你想確切的知道Mesa正在loading的時什麼,你可以指示它通過環境變量 LIBGL_DEBUG 把這個信息(或者其他信息)輸出到stderr中。

# LIBGL_DEBUG=verbose glxgears 
libGL: screen 0 does not appear to be DRI3 capable
libGL: pci id for fd 4: 8086:0126, driver i965
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/tls/i965_dri.so
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/i965_dri.so

所以我們看到Mesa檢查了現存的driver並且意識到i965 driver是要用的driver,然後它首先嚐試加載i965 driver的TLS版本,由於我沒有TLS版本,所以會fall back到我所有的i965 driver的normal版本。

src/loader/loader.c (loader_get_driver_for_fd) 裏的代碼負責檢測出哪個是正確的driver來使用(我的例子中是i965)。它收到輸入參數device fd,而device fd是之前作爲DRI bring up過程的一部分,調用DRI2Connect() 時調用所需要的輸入參數。然後實際的driver文件被加載到glx/dri_common.c (driOpenDriver)中。

通過使用mesa-utils包附帶的glxinfo程序,我們還可以獲得正在加載的驅動程序的更具描述性的指示

# glxinfo | grep -i "opengl renderer"
OpenGL renderer string: Mesa DRI Intel(R) Sandybridge Mobile 

這裏告訴我,我正在使用Intel hardware driver,而且提供了我所用的Intel的特定GPU的信息 (SandyBridge)。

Forcing a software driver

我已經提到過,software drivers有時會派上用場,但是我們如何讓load去使用它呢?Mesa提供了一個我們可以設置的環境變量,所以在hardware driver和software driver之間切換變得非常簡單:

# LIBGL_DEBUG=verbose LIBGL_ALWAYS_SOFTWARE=1 glxgears 
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/tls/swrast_dri.so
libGL: OpenDriver: trying /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so

正如你看到的,設置環境變量LIBGL_ALWAYS_SOFTWARE 可以讓loader選擇一個software driver (swrast).

如果我強制使用software driver,然後調用之間的glxinfo,那麼會得到:

# LIBGL_ALWAYS_SOFTWARE=1 glxinfo | grep -i "opengl renderer"
OpenGL renderer string: Software Rasterizer

所以在這個例子中,很清楚的看到我正在調用software driver.

Querying the driver for OpenGL features

glxinfo程序還可以方便地獲取有關driver實現的特定OpenGL feature的信息。如果要檢查硬件的Mesa驅動程序是否實現了特定的OpenGL extension,可以檢查glxinfo的輸出並查找該擴展(extension):

# glxinfo | grep GL_ARB_texture_multisample

You can also ask glxinfo to include hardware limits for certain OpenGL features including the -l switch. For example:

你還可以要求glxinfo爲包括-l switch在內的某些OpenGL feature添加硬件限制

# glxinfo -l | grep GL_MAX_TEXTURE_SIZE
GL_MAX_TEXTURE_SIZE = 8192

Coming up next

我的下篇文章將會包含Mesa repo的文件夾結構以及介紹主要的modules,這會給Mesa的初學者一些指導,這樣他們就根據需求找到想要看的那部分代碼。我們接下來將會討論現代3D hardware是如何改變了GPU drivers開發的方式,並且解釋一個現在3D graphics pipeline是如何工作的,這將爲開始研究Mesa的真正內核:着色器的實現鋪平道路。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章