glxinfo之Video Memory大小

mesa中的显存大小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$glxinfo -B
name of display: :0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: X.Org (0x1002)
Device: AMD OLAND (DRM 2.50.0, 5.3.8-050308-generic, LLVM 8.0.0) (0x6611)
Version: 19.1.6
Accelerated: yes
Video memory: 1024MB <----------- 显存
Unified memory: no
Preferred profile: core (0x1)
Max core profile version: 4.5
Max compat profile version: 4.5
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.2

glxinfo

源码文件:

1
git clone https://gitlab.freedesktop.org/mesa/demos.git

获取显存大小:queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, v)

1
2
3
4
5
6
queryInteger(GLX_RENDERER_ACCELERATED_MESA, v);
printf(" Accelerated: %s\n", *v ? "yes" : "no");
queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, v);
printf(" Video memory: %dMB\n", *v);
queryInteger(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, v);
printf(" Unified memory: %s\n", *v ? "yes" : "no");

file: glxinfo.c

mesa

queryInteger在mesa中的实现:

1
2
3
glXQueryCurrentRendererIntegerMESA
\->__glXQueryRendererInteger --- GLX_RENDERER_VIDEO_MEMORY_MESA
-> psc->vtable->query_renderer_integer()
  • dri3
    1
    2
    3
    4
    5
    6
    static const struct glx_screen_vtable dri3_screen_vtable = {
    .create_context = dri3_create_context,
    .create_context_attribs = dri3_create_context_attribs,
    .query_renderer_integer = dri3_query_renderer_integer,
    .query_renderer_string = dri3_query_renderer_string,
    };
1
2
3
4
5
dri3_query_renderer_integer
\-> dri2_convert_glx_query_renderer_attribs
\/
dri_attribute = __DRI2_RENDERER_VIDEO_MEMORY <--GLX_RENDERER_VIDEO_MEMORY_MESA
\->psc->rendererQuery->queryInteger((psc->driScreen, dri_attribute, value)
1
2
3
4
5
6
const __DRI2rendererQueryExtension dri2RendererQueryExtension = {
.base = { __DRI2_RENDERER_QUERY, 1 },

.queryInteger = dri2_query_renderer_integer,
.queryString = dri2_query_renderer_string
};

fire: src/gallium/state_trackers/dri/dri_query_renderer.c

1
2
3
dri2_query_renderer_integer
\-> __DRI2_RENDERER_VIDEO_MEMORY
> screen->base.screen->get_param(screen->base.screen, PIPE_CAP_VIDEO_MEMORY)
  • get_param接口是struct pipe_screen提供给驱动的接口,需要各个驱动自己实现。

virgl

1
2
3
4
5
6
7
8
9
10
struct pipe_screen *
virgl_create_screen(struct virgl_winsys *vws)
{
struct virgl_screen *screen = CALLOC_STRUCT(virgl_screen);

screen->base.get_name = virgl_get_name;
screen->base.get_vendor = virgl_get_vendor;
screen->base.get_param = virgl_get_param;
...
}
1
2
3
4
5
6
virgl_get_param <- PIPE_CAP_VIDEO_MEMORY
\-> {
...
case PIPE_CAP_VIDEO_MEMORY:
return 0;
}

在virgl中没有实现显存接口,默认为0,无法通过glxinfo获取

在virgl中的部分其他参数是获取host端的参数,通过struct virgl_winsys结构体中的get_caps接口。

  • drm: DRM_IOCTL_VIRTGPU_GET_CAPS
  • vtest: VCMD_GET_CAPS+VCMD_GET_CAPS2

radeonsi

1
2
3
4
5
6
7
8
void si_init_screen_get_functions(struct si_screen *sscreen)
{
sscreen->b.get_name = si_get_name;
sscreen->b.get_vendor = si_get_vendor;
sscreen->b.get_device_vendor = si_get_device_vendor;
sscreen->b.get_param = si_get_param;
...
}
1
2
3
4
5
6
7
8
static int si_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
switch (param) {
case PIPE_CAP_VIDEO_MEMORY:
return sscreen->info.vram_size >> 20;
}
...
}

在Radeon驱动中通过drmCommandWriteRead接口获取DRM_RADEON_GEM_INFO中的配置参数

1
2
3
/* Get GEM info. */
retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
&gem_info, sizeof(gem_info));