diff options
author | Ben Skeggs | 2015-11-23 18:10:04 -0600 |
---|---|---|
committer | Ben Skeggs | 2015-12-21 21:22:14 -0600 |
commit | f6b1b5b7c9cf6667d169bad3b33a73e4fe2bc14c (patch) | |
tree | cb501fa1f27a6881053abe68baac1dcdf45b46f0 /nouveau/nouveau.c | |
parent | c00e1a92a24cb84008d90ce67218bb593396fde5 (diff) | |
download | external-libgbm-f6b1b5b7c9cf6667d169bad3b33a73e4fe2bc14c.tar.gz external-libgbm-f6b1b5b7c9cf6667d169bad3b33a73e4fe2bc14c.tar.xz external-libgbm-f6b1b5b7c9cf6667d169bad3b33a73e4fe2bc14c.zip |
nouveau: add interfaces to query information about supported classes
This will expose functionality supported by newer kernel interfaces.
Current userspace uses the chipset to determine which classes are likely
exposed, which generally works pretty well, but isn't as flexible as it
could be.
Unfortunately, the G98:GF100 video code in Mesa is still relying on the
kernel exposing incorrect vdec classes on some chipsets. The ABI16
kernel interfaces have a workaround for this in place, but that will no
longer be available once libdrm supports NVIF.
To prevent a regression when NVIF support is added, if there's no kernel
support for NVIF, libdrm will magic up a class list containing correct
vdec classes anyway instead of failing with -ENODEV.
v2.
- add description of abi16/vdec workaround
- add description of sclass/mclass
- leave client-provided pointer unmodified on abi16_sclass() failure
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Tested-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Diffstat (limited to 'nouveau/nouveau.c')
-rw-r--r-- | nouveau/nouveau.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 1871e8cd..00173034 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c | |||
@@ -66,6 +66,47 @@ nouveau_object_mthd(struct nouveau_object *obj, | |||
66 | return -ENODEV; | 66 | return -ENODEV; |
67 | } | 67 | } |
68 | 68 | ||
69 | void | ||
70 | nouveau_object_sclass_put(struct nouveau_sclass **psclass) | ||
71 | { | ||
72 | free(*psclass); | ||
73 | *psclass = NULL; | ||
74 | } | ||
75 | |||
76 | int | ||
77 | nouveau_object_sclass_get(struct nouveau_object *obj, | ||
78 | struct nouveau_sclass **psclass) | ||
79 | { | ||
80 | return abi16_sclass(obj, psclass); | ||
81 | } | ||
82 | |||
83 | int | ||
84 | nouveau_object_mclass(struct nouveau_object *obj, | ||
85 | const struct nouveau_mclass *mclass) | ||
86 | { | ||
87 | struct nouveau_sclass *sclass; | ||
88 | int ret = -ENODEV; | ||
89 | int cnt, i, j; | ||
90 | |||
91 | cnt = nouveau_object_sclass_get(obj, &sclass); | ||
92 | if (cnt < 0) | ||
93 | return cnt; | ||
94 | |||
95 | for (i = 0; ret < 0 && mclass[i].oclass; i++) { | ||
96 | for (j = 0; j < cnt; j++) { | ||
97 | if (mclass[i].oclass == sclass[j].oclass && | ||
98 | mclass[i].version >= sclass[j].minver && | ||
99 | mclass[i].version <= sclass[j].maxver) { | ||
100 | ret = i; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | nouveau_object_sclass_put(&sclass); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
69 | static void | 110 | static void |
70 | nouveau_object_fini(struct nouveau_object *obj) | 111 | nouveau_object_fini(struct nouveau_object *obj) |
71 | { | 112 | { |