JJ's blog

Mesa/OpenGL 源码分析:framebuffer

之前看了 Mesa 的早期版本实现之后,我又开始看 Mesa 的最近版本的 OpenGL 实现了。不过,只能说有点选择错误,OpenGL 的实现实在是有太多历史包袱,驱动有非常多替应用层做的处理、回退逻辑。其中掺杂了大量固定管线(Fixed-function pipeline)时代的遗留代码,非 OpenGL Core profile 的部分也很影响阅读体验。所以我想先转去看 Vulkan 的实现,但是在此之前,想先总结一下 framebuffer 相关的一些阅读内容:一方面算是梳理了 OpenGL 底层的一些结构;另一方面,Framebuffer 的概念在 Vulkan 中也有对应的设计,这也为后续学习 Vulkan 打下基础。

在 Mesa 中,gl_framebuffer 主要包含多个 gl_renderbuffer 作为附件 (Attachment),可以想象成 Framebuffer 有多个插槽,每个插槽可以绑定到具体的 Renderbuffer 或 Texture。

对于 default framebuffer,即关联到 Window System 的 framebuffer 有:

  1. Double Buffer 机制: 用于 Window System 的 framebuffer 包含 front / back 缓冲(如果是立体视觉 stereo 模式,还会叠加 left / right 组合)。
  2. Depth / Stencil Buffers: 深度与模板缓冲。

而 user defined framebuffer 有:

  1. Color Buffers: 支持 Multiple Render Targets (MRT) 的 color0-7。

Read more...

libglvnd 实现分析

在以前的 Linux 环境下, OpenGL 库的加载存在一个问题:多个厂商的实现没法很好地共存。具体来说,应用会用 libGL.so 这个 SONAME 去加载 OpenGL 实现,但是动态加载器的搜索路径通常是固定的(当然可以通过修改环境变量之类的方式去改变哪个 libGL.so 被加载,但是这样的方式是不现实的),因此以前没法很好地让多个厂商的实现并存,无法让多个进程选择不同的实现,甚至动态地去决定用哪个厂商的实现。
为此,现代 Linux 下的 libGL.so 的实现通常是由 libglvnd (The GL Vendor-Neutral Dispatch library) 实现的。这个实现允许多个厂商的 OpenGL 实现同时存在于机器上,允许多个进程动态地选择具体的实现。
它通过实现一个中心化的 libGL.so + 不同厂商提供的 libGLX_{vendor}.so, 根据 context 转发到对应厂商提供的 GL/GLX 实现,从而解决上述提到的问题。

┌───────────────────────────┐
│        Application        │
└─────┬────────────────────┬┘
      │                    │
      │                    │
 glXGetProcAddress         glxxx return from glXGetProcAddress
┌─────▾────────────┐     ┌─▾────────────────┐
│      libGL       ├─────▸  libGLdispatch   │
└─────┬─────────┬──┘     └─┬────────────────┘
      │         gl functions   ┌────────────────────┐
      │         └──────────┴───▸ libGLX_{vendor}.so │
      glXxxx(Display*, ...)    └─▴──────────────────┘
┌─────▾────────────┐             glX extension function
│      libGLX      ├─────────────┘ ┌────────┐
│                  ├───────────────▸ libX11 │
└──────────────────┘               └────────┘

Read more...

ELF 文件结构速查

注1:这里只是简单描述 ELF 文件最核心的结构,作为 cheat sheet 以便于快速查看。不会展开具体的字节描述,有必要请查看 Wikipedia

注2:本文只包括常见模式,可能存在特殊情况。且目前只验证了一个 .so 文件

注3:一个在线 ELF viewer, 随便找的,不保证质量。 elfy.io

文件本身的结构

一个 ELF 文件由下面几个部分组成:

  1. 三个 header: ELF header, program header table, section header table.
  2. sections, 每个 section 用于一个目的。
  3. 用于满足 align 要求的 section 之间的垃圾字节。

Read more...

Mesa/OpenGL 源码分析:Context 与 Shader 编译机制

TL;DR;
在 Mesa 早期版本的实现中,OpenGL context 其实就是一个存在 TLS 中的大结构体,保存了诸如固定管线状态、shader 源代码、已编译的 IL 之类的东西。
glShaderSource 只是复制了源代码,glCompileShader 则是对源代码进行预处理、语法语义分析,并生成 Mesa 定义的 IL 代码。

前段时间 AMD 有一个关于 AMDVLK 开源项目 discontinue 的 announcement,其中提到他们准备转向 RADV,这是一个 Mesa 下属的 Vulkan driver。于是借此机会,我也想花点时间来看看这个 Mesa 项目。

Read more...

DNS杂记:resolv.conf, zone, dig

最近因为感兴趣的东西和DNS有关,所以了解了一些零零碎碎的关于DNS的知识,并略做记录,之后又有想了解的时候再进一步补充。
目前包括的内容有:resolv.conf, zone info, dig.

Read more...