前言
不必害怕未知,無需恐懼犯錯,做一個Creator!
一、總體框架圖
暫時無法在飛書文檔外展示此內容
二、Mesa API 處理 OpenGL 函數調用
Mesa API 負責實現 OpenGL 和其他圖形 API 的函數接口。Mesa API 表是一個重要的數據結構,用于存儲 OpenGL 函數的指針、版本信息、擴展支持等。_glapi_table 包含了大量的函數指針,每個指針對應于一個特定的 OpenGL 函數。這些指針在運行時被動態設置為對應的實現函數,例如 glCompileShader()、glLinkProgram() 等。
src/mesa/shaderapi.c:實現OpenGL API和Mesa函數接口的對應。
三、State Tacker對GLSL代碼鏈接處理
在鏈接過程,state tracker層協調著色器程序的鏈接,將多個著色器鏈接為最終可執行的著色器程序,即NIR。并且將鏈接后的著色器程序最終傳遞給gallium驅動。ST層還管理著色器對象的狀態,包括編譯狀態、鏈接狀態等。
src/mesa/state_tracker/st_glsl_to_nir.c:在ST層主要實現了 GLSL 到 NIR 的轉換功能,包括 GLSL 程序的鏈接、NIR 的最終化、優化以及統一變量的處理。
四、GLSL 編譯器對GLSL代碼編譯和鏈接處理
在編譯過程,當應用程序通過OpenGL函數調用提交GLSL著色器源代碼時,Mesa API將GLSL代碼傳遞給GLSL編譯器,并進行編譯生成Mesa IR中間表示。
在鏈接過程,ST層負責將Mesa IR中間表示傳遞給GLSL編譯器,GLSL編譯器將Mesa IR轉化成NIR并回傳給ST層進行后續處理。
1、編譯過程,GLSL源碼轉化成IR
- src/compiler/glsl/glsl_parser_extras.cpp :提供了對 GLSL 源代碼的解析和語法分析所需的額外功能,包括處理預處理指令、處理注釋、管理源代碼中的位置信息
- src/compiler/glsl/ast_to_hir.cpp: 將抽象語法樹(AST)轉換為高級中間表示(HIR)的過程。
2、鏈接過程,IR轉化成NIR
src/compiler/glsl/glsl_to_nir.cpp:在Compiler層負責將GLSL源碼轉化成NIR,包括GLSL IR的釋放和NIR的創建和驗證
五、NIR轉換與優化
GLSL IR 通常會被轉換為 NIR(New Intermediate Representation)。st_glsl_to_nir.cpp 文件負責 GLSL 到 NIR 的轉換,其中 NIR 提供了更抽象和可優化的中間表示。優化后的NIR將提供給gallium層供各個硬件驅動層進行轉化。
GLSL編譯器轉化成NIR后,在ST還需進行以下處理和優化:
- NIR 統一變量處理
- 統一變量的位置分配
- 頂點著色器輸入位置分配
- 變量位置的分配
- NIR 向量化和坐標系變換
- NIR 緩存加載和存儲
- 釋放 NIR 變體
六、核心數據結構
_glapi_table 結構體:
_glapi_table 結構體是 Mesa API 層的核心數據結構,包含了 OpenGL 函數的指針、版本信息、擴展支持等。它被用于表示 OpenGL API 的實現層次。
struct _glapi_table {/* OpenGL function pointers */GET_DISPATCH_PTR();
/* Version information */GLuint Version;
/* Extension support */GLuint Extensions[32];
};
st_context結構體:
st_context 是一個表示Gallium3D狀態跟蹤上下文的結構體,負責跟蹤和管理圖形狀態、與Gallium3D框架進行交互。
struct st_context
{struct st_context_iface iface;struct gl_context *ctx;struct pipe_context *pipe;struct draw_context *draw; /< For selection/feedback/rastpos only */
** struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */struct draw_stage *selection_stage; /< For GL_SELECT rendermode */
** struct draw_stage *rastpos_stage; /**< For glRasterPos */
// 省略
};