Smart Pointer
smart pointer是C++11引入的,被包含在C++标准库中。smart pointer是为了管理对象的所属(object ownership)而设计的,smart pointer对象负责自动地销毁所关联对象。常见的smart pointer有:
ARB_texture_storage
ARB_texture_swizzle
ARB_shader_ballot
ARB_texture_view
vim 速查手册
Visual Block Selection
选择
{}
(curly braces) 之间的行(包括{}
)v%
选择
{}
(curly braces) 之间的行(不包括{}
)vi{
注意:光标必须放在 {
或者 }
Copy & Paste
Copy to clipboard
- Normal 模式
"+y
Paste from clipboard
X11 window system 有 3 个 selections:
- PRIMARY 表示当前的可见 selection
- SECONDARY
- CLIPBOARD 通常所说的剪贴板,用来完成剪贴,复制和粘贴操作
Vim 有两个专门的寄存器分别与 PRIMARY selection 和 CLIPBOARD selection 对应
"*
(quotestar) PRIMARY"+
(quoteplus) CLIPBOARD
如果要在 Vim 内部剪贴,复制/粘贴就使用 quotestar, 如果要将内容剪贴,复制/粘贴到系统剪贴板,就使用 quoteplus
举个例子,在 WSL Ubuntu 里如果想粘贴 Windows 剪贴板里的内容到 vim (最好是 neovim, 因为 vim 可能未使能 clipboard)
1 | echo "Hello, world!" | clip.exe |
- Normal 模式
"+p
如果想粘贴 Ubuntu 剪贴板里的内容
1 | echo "Hello, world!" | xclip |
- Normal 模式
"*p
Copy from above or below
在 Insert 模式下
<ctrl-y>
copies the character from the line above<ctrl-e>
copies the character from the line below (本行就是这样输入的)
Search & Replace
删除多行 C-style 注释
s;/\*\_.\{-}\*/;;
;
因为要匹配/
, 为了省去转义/
的麻烦,将 search 命令的分隔符由/
改为;
/\*
匹配开始的/*
\_.
匹配任意字符,包括\n
, 所以常用在多行匹配\{-}
指非贪婪 (non-greedy) 匹配,即匹配最短的字串,默认是贪婪匹配,匹配最长的字串\*/
匹配结尾的*/
;;
指使用空替换匹配结果,即删除以下是 vim 中在单行中使用的通配符 (wildcard), 这些通配符一般不能匹配换行
\n
.
匹配除了\n
的任意字符^
行首,即锚点 (anchor)$
行尾,即锚点\s
匹配 space, tab, 但不匹配\n
以上通配符加上
\_
后可以在多行匹配中使用,即也可以匹配\n
\_.
匹配任意字符,包括\n
\_^
多行中第一行行首\_$
多行中最后一行行尾\_s
匹配 space, tab 和\n
删除空白行
g/^\s*$/d
g
指所有行搜索,而不是默认的光标所在行^\s*$
匹配行首到行尾之间任意个空白字符,即空白行d
删除命令 (delete)
搜索不匹配某模式的行,即反向搜索
/^\(\(^# .*$\)\@!.\)*$
/
查找命令 (search) 的提示符^\(\(The_Regex\)\@!.\)*$
反向查找的命令固定模式,本例中The_Regex
是^# .*$
即以#
开头的行,所以整个表达式匹配的就是不以#
开头的所有行
:v/^# .*$/p
- 与上面的反向查找命令功能相同, 但会将匹配结果显示在 Visual 模式下
大小写转换
s/\(^# .*$\)/\L\1/
\(The_Regex\)
为了向前索引,即后面\1
所指的部分,本例中The_Regex
是^# .*$
, 意思同上\L\1
\L
指 Lowercase, 即将\1
匹配的结果中的所有字母都换成小写
s/\(^# .*$\)/\U\1/
- 与上面的表达式功能相反,即将
\1
匹配的结果中的所有字母都换成大写 (Uppercase)
- 与上面的表达式功能相反,即将
Debugging X11 with tcpdump
X11 is designed as client-server mode. The communication between the X client and server complies with TCP protocol. Recently I have a Windows X server VcXsrv installed on my Windows 10 and I debug an OpenGL demo glxgears on the WSL2 with tcpdump.
Environment
WSL2 is equipped with its own networking interface like a virtual machine.
1 | $ ifconfig |
1 | $ /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -C "ipconfig" |
After starting up the X server VcXsrv, you need to export the environmnet variable DISPLAY
on the WSL. In case of the vEthernet configuration changed after rebooting you’d better do it like this:
1 | export DISPLAY=$(grep 'nameserver' /etc/resolv.conf | awk '{print $2}'):0 |
NOTE: The Firewall between the host and WSL2 must be disabled or your X client can not connect VcXsrv.
Debugging
I trace the demo glxgears using gdb and tcpdump at the same time.
- gdb
1 | gdb -q -tui glxgears |
- tcpdump
1 | sudo tcpdump -vvX not icmp and not arp and not udp and portrange 37900-37999 -w x110224.pcap |
- vv: verboser than -v
- X: show the packet’s content
- not icmp: filter out icmp packets
- not arp: filter out arp packets
- not udp: filter out udp packets
- portrange 37900-37999: listening on the ports from 37900 to 37999
- w x110224.pcap: save the packet captures into the file
1 | tcpdump -X -r x110224.pcap |
1 | reading from file /home/luc/github/x110224.pcap, link-type EN10MB (Ethernet) |
what codes sends and receives these packets? The first two twenty-byted segments are IP header (20 bytes without option) and TCP header (20 bytes without option) separately in these packets.
The source code snippet:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Bool
XQueryExtension(
register Display *dpy,
_Xconst char *name,
int *major_opcode, /* RETURN */
int *first_event, /* RETURN */
int *first_error) /* RETURN */
{
xQueryExtensionReply rep;
register xQueryExtensionReq *req;
LockDisplay(dpy);
GetReq(QueryExtension, req);
req->nbytes = name ? strlen(name) : 0;
req->length += (req->nbytes+(unsigned)3)>>2;
_XSend(dpy, name, (long)req->nbytes);
(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
*major_opcode = rep.major_opcode;
*first_event = rep.first_event;
*first_error = rep.first_error;
UnlockDisplay(dpy);
SyncHandle();
return (rep.present);
}
The gdb log:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35Starting program: /mnt/c/Users/lulu/Documents/github/demos/src/xdemos/glxgears
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, XextAddDisplay (extinfo=0x7ffff7e77380 <_dri2Info_data>, dpy=0x55555555d2a0,
ext_name=0x7ffff7e76780 <dri2ExtensionName> "DRI2", hooks=0x7ffff7e767a0 <dri2ExtensionHooks>, nevents=0, data=0x0)
at extutil.c:103
XInitExtension (dpy=dpy@entry=0x55555555d2a0, name=name@entry=0x7ffff7e76780 <dri2ExtensionName> "DRI2")
at InitExt.c:44
XQueryExtension (dpy=dpy@entry=0x55555555d2a0, name=name@entry=0x7ffff7e76780 <dri2ExtensionName> "DRI2",
major_opcode=major_opcode@entry=0x7fffffffd984, first_event=first_event@entry=0x7fffffffd988,
first_error=first_error@entry=0x7fffffffd98c) at QuExt.c:39
$2 = {
reqType = 0x62,
pad = 0x0,
length = 0x3,
nbytes = 0x4,
pad1 = 0x0,
pad2 = 0x0
}
$3 = {
type = 0x1,
pad1 = 0x0,
sequenceNumber = 0xa,
length = 0x0,
present = 0x0,
major_opcode = 0x0,
first_event = 0x0,
first_error = 0x0,
pad3 = 0x0,
pad4 = 0x0,
pad5 = 0x0,
pad6 = 0x0,
pad7 = 0x0
}
$2
is Request packet content to VcXsrv, $3
is Reply packet content from VcXsrv. Even that we can notice the three-way handshake of TCP from the zero-lengthed packet in x110224.pcap.
Notes for Mesa
Overview
Mesa 包含了各种 GPU/CPU 的 OpenGL, OpenCL, Vulkan 实现(Usermode Driver), 也包括 GLX, EGL, GBM 等协议的实现。
- Vulkan 驱动
codename | directories | platforms |
---|---|---|
anv | src/intel/vulkan, src/intel/vulkan_hasvk | Alder Lake-P |
asahi | src/asahi/vulkan | Apple M1, M2 |
lpv | src/gallium/drivers/llvmpipe | CPU |
panvk | src/panfrost/vulkan | RK3399 |
v3dv | src/broadcom/vulkan | Raspberry Pi |
Build
Build Dependencies (since mesa-25.0.0)
dep | apt-get | version required | yet another install | ||
---|---|---|---|---|---|
/usr/bin/glslangValidator | glslang-tools | https://github.com/KhronosGroup/glslang | |||
/usr/bin/rustc | rustc | 1.78.0 or newer | `curl —proto ‘=https’ —tlsv1.2 -sSf https://sh.rustup.rs | sh` | |
bindgen (rust package) | cargo | 0.65 or newer | cargo install bindgen-cli |
||
libclc-dev | libclc-17-dev | not required if -Dmesa-clc=auto | |||
+ | libdrm | libdrm-dev | 2.4.121(120 ok2.0) | https://gitlab.freedesktop.org/mesa/drm | |
llvm | llvm-17-dev | (17.0.6 ok2.0) | https://github.com/llvm/llvm-project | ||
libLLVMSPIRVLib.so.17 | llvm-spirv-17 | (17.0.0 ok2.0) | https://github.com/KhronosGroup/SPIRV-LLVM-Translator | ||
+ | LLVMSPIRVLib.h | llvmspirvlib-17-dev | (absent ok2.0) | https://github.com/KhronosGroup/SPIRV-LLVM-Translator | |
clang-cpp | libclang-cpp17-dev | (17.0.6 ok2.0) | not required if -Dmesa-clc=auto | ||
* | clang-dev | libclang-17-dev | Debian package issue | ||
xshmfence | libxshmfence-dev | (1.3 ok2.0) | required if -Dplatforms=x11 | ||
xxf86vm | libxxf86vm-dev | (1.1.4 ok2.0) | required since -Dglx-direct=true by default | ||
xrandr | libxrandr-dev | (1.5.2 ok2.0) | required since -Dxlib-lease=true | ||
cbindgen (rust package) | cargo | 0.28.0 | cargo install cbindgen ; required if -Dgallium-drivers=nouveau |
NOTE:
- (*) 表示本来不需要的依赖
- (+) 在 OpenKylin 2.0 的源里没有,需要源码构建
1 | meson build -Dprefix=/usr/local -Dlibdir=lib/x86_64-linux-gnu -Dplatforms=x11 -Dgallium-drivers=nouveau |
-Dprefix=/usr/local
避免覆盖系统原来的libGL*
-Dlibdir=lib/x86_64-linux-gnu
设置库的安装路径为/etc/ld.so.conf.d/x86_64-linux-gnu.conf
中搜索第一顺位的路径- 其他默认就好, 出现的依赖在 OpenKylin 2.0 上 apt-get 基本都能解决
1 | Build targets in project: 437 |