glmark2 是开源的对OpenGL 2.0 和 ES 2.0的基准测试程序,一般用来对GPU进行基准测试。glmark提供了一系列丰富的测试,涉及图形单元性能(缓冲,建筑,照明,纹理等)的不同方面,允许进行更全面和有意义的测试。 每次测试进行10秒,并且单独计算帧速率。
开源地址是:
https://github.com/glmark2/glmark2
但是glmark2只能在windows、安卓和linux X86上跑,如果想在arm板子上跑需要自己移植。然后在网上搜了一圈都没有人移植过。因此只能自己去移植一把了。
移植到arm实机上的代码请到我的github拉取:https://github.com/fanchenxinok/glmark2_arm
顺便点个Star哦 ^ @ ^
拉完代码就跑可不好,能学习下怎么去移植一个开源程序到自己的arm板也是蛮有意思的,知其然也要知所以然对吧,接下来我来分析下移植的过程:
在移植之前我在Linux X86虚拟机环境上跑了一把,并执行了./glmark2 --help熟悉了下glmark2的使用。这有助于我查看waf用到的一些环境变量代表的含义。在虚拟机上安装很简单,执行:sudo apt-get install glmark2 即可。
然后从开源地址拉取源代码,进入到glmark2主目录,如下图:
看一下目录结构,可以猜测 android目录存放安卓上跑的代码,data目录存放跑分的测试数据;doc存放说明文档;src存放安卓平台以外的代码;waflib存放waf工具依赖的库。
如果你用过waf帮助编译及构建系统的框架工具就明白glmark2源码是用waf编译的,学习waf工具基本 的使用可以参考我的博客:https://blog.csdn.net/u010312436/article/details/81093847
说实在的waf构建的编译环境改动起来还是蛮费劲的,我更喜欢用Makefile来构建编译系统。于是我想把glmark2用Makefile来构建。
打开主目录的"wscript"文件,一大堆变量看着就头疼,不要紧,因为我们是移植的arm板子上跑所以有关window,android的都可以不用care,找到build字段:
def build(ctx):
ctx.recurse('src')
ctx.recurse('data')
ctx.recurse('doc')
可以看出我们只要关心src目录下的代码即可,还有glmark2的模式选择:
FLAVORS = {
'dispmanx-glesv2' : 'glmark2-es2-dispmanx',
'drm-gl' : 'glmark2-drm',
'drm-glesv2' : 'glmark2-es2-drm',
'mir-gl' : 'glmark2-mir',
'mir-glesv2' : 'glmark2-es2-mir',
'wayland-gl' : 'glmark2-wayland',
'wayland-glesv2' : 'glmark2-es2-wayland',
'win32-gl': 'glmark2-win32',
'win32-glesv2': 'glmark2-es2',
'x11-gl' : 'glmark2',
'x11-glesv2' : 'glmark2-es2',
}
接下来我们进入src目录,打开wscript_build编译脚本,从头往下看:
(1)首先可以看到all_sources和platform_libs变量,可以猜测all_sources代表的是需要编译的源文件包括当前目录下的所有cpp文件,scene-ideas下的cc文件,scene-terrain下的cpp文件;platform_libs代表需要链接的系统库。
all_sources = bld.path.ant_glob('*.cpp scene-ideas/*.cc scene-terrain/*.cpp')
platform_libs = ['m', 'jpeg', 'dl']
那么我的Makefile也相应的添加如下变量(我将scene-terrain的cc文件都重命名为cpp文件):
SOURCES = $(wildcard ./*.cpp ./scene-terrain/*.cpp ./scene-ideas/*.cpp)
CLIBS = -lm -ldl -lrt -ljpeg
(2)接下来可以看到有flavor_sources的字段,跑在arm板子上我们只需要drm-gl、drm-glesv2、wayland-gl、wayland-glesv2四种模式:
flavor_sources = {
'dispmanx-glesv2' : common_flavor_sources + ['native-state-dispmanx.cpp', 'gl-state-egl.cpp'],
'drm-gl' : common_flavor_sources + ['native-state-drm.cpp', 'gl-state-egl.cpp'],
'drm-glesv2' : common_flavor_sources + ['native-state-drm.cpp', 'gl-state-egl.cpp'],
'mir-gl' : common_flavor_sources + ['native-state-mir.cpp', 'gl-state-egl.cpp'],
'mir-glesv2' : common_flavor_sources + ['native-state-mir.cpp', 'gl-state-egl.cpp'],
'wayland-gl' : common_flavor_sources + ['native-state-wayland.cpp', 'gl-state-egl.cpp'],
'wayland-glesv2' : common_flavor_sources + ['native-state-wayland.cpp', 'gl-state-egl.cpp'],
'win32-gl': common_flavor_sources + ['native-state-win32.cpp', 'gl-state-wgl.cpp'],
'win32-glesv2': common_flavor_sources + ['native-state-win32.cpp', 'gl-state-egl.cpp'],
'x11-gl' : common_flavor_sources + ['native-state-x11.cpp', 'gl-state-glx.cpp'],
'x11-glesv2' : common_flavor_sources + ['native-state-x11.cpp', 'gl-state-egl.cpp'],
}
因此我在Makefile也定义了MODULE_SELECT用来选择运行的模式,并且为SOURCES变量添加相应的native-开头的cpp文件(我把native-开头的文件都放在module_select目录下):
ifeq ($(MODULE_SELECT), drm-gl)
SOURCES += ./module_select/native-state-drm.cpp
CLIBS += -ldrm -lgbm -ludev
CFLAGS += -DGLMARK2_USE_DRM -DGLMARK2_USE_GL -DGLMARK2_USE_EGL
INCLUDE_DIRS += -I$(USR_INC)/include/EGL \
-I$(USR_INC)/include/drm \
-I$(USR_INC)/include/gbm
else ifeq ($(MODULE_SELECT), drm-glesv2)
SOURCES += ./module_select/native-state-drm.cpp
CLIBS += -ldrm -lgbm -ludev
CFLAGS += -DGLMARK2_USE_DRM -DGLMARK2_USE_GLESv2 -DGLMARK2_USE_EGL
INCLUDE_DIRS += -I$(USR_INC)/include/EGL \
-I$(USR_INC)/include/GLES2 \
-I$(USR_INC)/include/drm \
-I$(USR_INC)/include/gbm
else ifeq ($(MODULE_SELECT), wayland-gl)
SOURCES += ./module_select/native-state-wayland.cpp
CLIBS += -lwayland-client -lwayland-server -L./xdc_shell -lxdc-shell -L./wayland-egl -lwayland-egl
CFLAGS += -DGLMARK2_USE_WAYLAND -DGLMARK2_USE_GL -DGLMARK2_USE_EGL
INCLUDE_DIRS += -I$(USR_INC)/include/EGL -I./xdc_shell
SUBDIRS += ./xdc_shell ./wayland-egl
else ifeq ($(MODULE_SELECT), wayland-glesv2)
SOURCES += ./module_select/native-state-wayland.cpp
CLIBS += -lwayland-client -lwayland-server -L./xdc_shell -lxdc-shell -L./wayland-egl -lwayland-egl
CFLAGS += -DGLMARK2_USE_WAYLAND -DGLMARK2_USE_GLESv2 -DGLMARK2_USE_EGL
INCLUDE_DIRS += -I$(USR_INC)/include/EGL \
-I$(USR_INC)/include/GLES2 \
-I./xdc_shell
SUBDIRS += ./xdc_shell ./wayland-egl
else
SOURCES +=
endif
(3)接下来可以看到有flavor_uselibs定义,这表示不同的模式依赖的库不一样,将依赖的库添加到CLIBS环境变量下。
(4)往下可以看到flavor_defines定义,这表示选择不同的模式时,代码中定义的宏定义。我的Makefile中相应的在CFLAGS
编译参数后添加,如:
'drm-gl' : ['GLMARK2_USE_DRM', 'GLMARK2_USE_GL', 'GLMARK2_USE_EGL'],
则Makefile添加到CFLAGS的变量如下:
CFLAGS += -DGLMARK2_USE_DRM -DGLMARK2_USE_GL -DGLMARK2_USE_EGL
(5)还可以看到all_uselibs定义,这表示需要依赖的库有matrix-gl/glesv2、libpng-local、zlib-local、libjpeg-turbo-local、glad-gl/glesv2。这五个库都有相应的子目录分别是libmatirx、libpng、zlib、libjpeg-turbo、glad。所以只要在这五个目录下添加Makefile并且编译为*.a的静态库,在链接阶段链接到可执行文件即可。子Makefile的写法如下(以png为例):
TOP_DIR = ..
SOURCES = $(wildcard ./*.c)
INCLUDE_DIRS = -I./ -I$(TOP_DIR)/include
TARGET = libpng.a
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
$(TARGET) : $(OBJECTS)
$(AR) $(ARFLAG) $@ $^
$(OBJECTS) : %.o : %.c
$(CC) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)
.PHONY : clean
clean:
rm -rf $(TARGET) $(OBJECTS)
那么主Makefile的CLIBS环境变量就可以添加这几个库
CLIBS = -L./libmatrix/ -lmatrix -L./libpng -lpng -L./zlib -lzlib -L./glad -lglad -L./libjpeg-turbo -ljpeg-turbo -lm -ldl -lrt -ljpeg
到这里glmark2主要的编译框架已经完成,后面就是有编译报错修改下即可。
目前在我的板子上只跑了drm-glesv2模式,wayland模式还没测试成功。如果哪位仁兄将wayland模式跑起来,可以在github上提交。
运行及结果:
[root@x glmark2_arm]# ./glmark2_arm
failed to load module: /usr/lib/gbm/gbm_dri.so: cannot open shared object file: No such file or directory
failed to load module: /usr/lib/gbm/gbm_gallium_drm.so: cannot open shared object file: No such file or directory
loaded module : gbm_pvr.so
found valid GBM backend : gbm_pvr.so
PVR:(Error): Couldn't load WS module libpvrws_WAYLAND.so [0, ]
PVR:(Error): Couldn't load WS module libpvrws_WAYLAND.so [0, ]
=======================================================
glmark2 2017.07
=======================================================
OpenGL Information
GL_VENDOR: Imagination Technologies
GL_RENDERER: PowerVR SGX 544MP
GL_VERSION: OpenGL ES 2.0 build 1.14@3699939 (MAIN)
=======================================================
[build] use-vbo=false: FPS: 60 FrameTime: 16.667 ms
[build] use-vbo=true: FPS: 60 FrameTime: 16.667 ms
[texture] texture-filter=nearest: FPS: 60 FrameTime: 16.667 ms
[texture] texture-filter=linear: FPS: 60 FrameTime: 16.667 ms
[texture] texture-filter=mipmap: FPS: 60 FrameTime: 16.667 ms
[shading] shading=gouraud: FPS: 60 FrameTime: 16.667 ms
[shading] shading=blinn-phong-inf: FPS: 60 FrameTime: 16.667 ms
[shading] shading=phong: FPS: 60 FrameTime: 16.667 ms
[shading] shading=cel: FPS: 60 FrameTime: 16.667 ms
[bump] bump-render=high-poly: FPS: 60 FrameTime: 16.667 ms
[bump] bump-render=normals: FPS: 60 FrameTime: 16.667 ms
[bump] bump-render=height: FPS: 59 FrameTime: 16.949 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 60 FrameTime: 16.667 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 20 FrameTime: 50.000 ms
[pulsar] light=false:quads=5:texture=false: FPS: 60 FrameTime: 16.667 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 30 FrameTime: 33.333 ms
[desktop] effect=shadow:windows=4: FPS: 59 FrameTime: 16.949 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 30 FrameTime: 33.333 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 30 FrameTime: 33.333 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 39 FrameTime: 25.641 ms
[ideas] speed=duration: FPS: 60 FrameTime: 16.667 ms
[jellyfish] : FPS: 60 FrameTime: 16.667 ms
[terrain] : FPS: 0 FrameTime: inf ms
[shadow] : FPS: 20 FrameTime: 50.000 ms
[refract] : FPS: 10 FrameTime: 100.000 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 60 FrameTime: 16.667 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 60 FrameTime: 16.667 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 60 FrameTime: 16.667 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 60 FrameTime: 16.667 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 60 FrameTime: 16.667 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 60 FrameTime: 16.667 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 60 FrameTime: 16.667 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 60 FrameTime: 16.667 ms
=======================================================
glmark2 Score: 50
=======================================================