Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gbm/main/gbm_abi_check.c
4564 views
1
/*
2
* Copyright © 2021 NVIDIA Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
* DEALINGS IN THE SOFTWARE.
23
*/
24
25
#include "gbm_backend_abi.h" /* Current GBM backend ABI implementation */
26
27
#include <stddef.h> /* offsetof */
28
#include <stdio.h> /* printf */
29
30
/*
31
* The following are previous implementations of the structures defined in
32
* gbm_backend_abi.h, with their ABI version appended.
33
*
34
* DO NOT EVER CHANGE EXISTING DEFINITIONS HERE!
35
*
36
* Changing them implies breaking the GBM backend ABI. Instead, to extend the
37
* ABI, in gbm_backend_abi.h:
38
*
39
* -Add a new versioned struct
40
* -Append it to the associated top-level object's struct
41
* -Increment GBM_BACKEND_ABI_VERSION
42
*
43
* Then, here:
44
*
45
* -Add a new block of definitions below for the new ABI content
46
* -Add a new block of checks in main()
47
*/
48
49
/* From: 49a7331cb02 - James Jones - gbm: Version the backend interface */
50
#define GBM_BACKEND_ABI_VERSION_abi0 0
51
struct gbm_device_v0_abi0 {
52
const struct gbm_backend_desc *backend_desc;
53
uint32_t backend_version;
54
int fd;
55
const char *name;
56
void (*destroy)(struct gbm_device *gbm);
57
int (*is_format_supported)(struct gbm_device *gbm,
58
uint32_t format,
59
uint32_t usage);
60
int (*get_format_modifier_plane_count)(struct gbm_device *device,
61
uint32_t format,
62
uint64_t modifier);
63
struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
64
uint32_t width, uint32_t height,
65
uint32_t format,
66
uint32_t usage,
67
const uint64_t *modifiers,
68
const unsigned int count);
69
struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
70
void *buffer, uint32_t usage);
71
void *(*bo_map)(struct gbm_bo *bo,
72
uint32_t x, uint32_t y,
73
uint32_t width, uint32_t height,
74
uint32_t flags, uint32_t *stride,
75
void **map_data);
76
void (*bo_unmap)(struct gbm_bo *bo, void *map_data);
77
int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
78
int (*bo_get_fd)(struct gbm_bo *bo);
79
int (*bo_get_planes)(struct gbm_bo *bo);
80
union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane);
81
int (*bo_get_plane_fd)(struct gbm_bo *bo, int plane);
82
uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane);
83
uint32_t (*bo_get_offset)(struct gbm_bo *bo, int plane);
84
uint64_t (*bo_get_modifier)(struct gbm_bo *bo);
85
void (*bo_destroy)(struct gbm_bo *bo);
86
struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
87
uint32_t width, uint32_t height,
88
uint32_t format, uint32_t flags,
89
const uint64_t *modifiers,
90
const unsigned count);
91
struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
92
void (*surface_release_buffer)(struct gbm_surface *surface,
93
struct gbm_bo *bo);
94
int (*surface_has_free_buffers)(struct gbm_surface *surface);
95
void (*surface_destroy)(struct gbm_surface *surface);
96
};
97
98
struct gbm_device_abi0 {
99
/* Hack to make a gbm_device detectable by its first element. */
100
struct gbm_device *(*dummy)(int);
101
struct gbm_device_v0_abi0 v0;
102
};
103
104
/**
105
* GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
106
*
107
* DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment
108
* GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo.
109
*/
110
struct gbm_bo_v0_abi0 {
111
uint32_t width;
112
uint32_t height;
113
uint32_t stride;
114
uint32_t format;
115
union gbm_bo_handle handle;
116
void *user_data;
117
void (*destroy_user_data)(struct gbm_bo *, void *);
118
};
119
120
/**
121
* The allocated buffer object.
122
*
123
* The members in this structure should not be accessed directly.
124
*
125
* To modify this structure, introduce a new gbm_bo_v<N> structure, add it to
126
* the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
127
*/
128
struct gbm_bo_abi0 {
129
struct gbm_device *gbm;
130
struct gbm_bo_v0_abi0 v0;
131
};
132
133
/**
134
* GBM surface interface corresponding to GBM_BACKEND_ABI_VERSION = 0
135
*
136
* DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_surface_v1, increment
137
* GBM_BACKEND_ABI_VERSION, and append gbm_surface_v1 to gbm_surface.
138
*/
139
struct gbm_surface_v0_abi0 {
140
uint32_t width;
141
uint32_t height;
142
uint32_t format;
143
uint32_t flags;
144
struct {
145
uint64_t *modifiers;
146
unsigned count;
147
};
148
};
149
150
/**
151
* An allocated GBM surface.
152
*
153
* To modify this structure, introduce a new gbm_surface_v<N> structure, add it
154
* to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
155
*/
156
struct gbm_surface_abi0 {
157
struct gbm_device *gbm;
158
struct gbm_surface_v0_abi0 v0;
159
};
160
161
/**
162
* GBM backend interfaces corresponding to GBM_BACKEND_ABI_VERSION = 0
163
*
164
* DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_backend_v1, increment
165
* GBM_BACKEND_ABI_VERSION, append gbm_backend_v1 to gbm_backend.
166
*/
167
struct gbm_backend_v0_abi0 {
168
/**
169
* The version of the GBM backend interface supported by this backend. This
170
* is set by the backend itself, and may be greater or less than the version
171
* supported by the loader. It is the responsibility of the GBM loader to
172
* respect this version when accessing fields in this structure.
173
*/
174
uint32_t backend_version;
175
176
const char *backend_name;
177
struct gbm_device *(*create_device)(int fd, uint32_t gbm_backend_version);
178
};
179
180
/**
181
* The interface exposed by an external GBM backend.
182
*
183
* To modify this structure, introduce a new gbm_backend_v<N> structure, add it
184
* to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
185
*/
186
struct gbm_backend_abi0 {
187
struct gbm_backend_v0_abi0 v0;
188
};
189
190
/**
191
* GBM interfaces exposed to GBM backends at GBM_BACKEND_ABI_VERSION >= 0
192
*
193
* DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_core_v1, increment
194
* GBM_BACKEND_ABI_VERSION, and append gbm_core_v1 to gbm_backend.
195
*/
196
struct gbm_core_v0_abi0 {
197
/**
198
* The version of the GBM backend interface supported by the GBM loader. This
199
* is set by the loader, and may be greater or less than the version
200
* supported by a given backend. It is the responsibility of the backend to
201
* respect this version when accessing fields in this structure and other
202
* structures allocated or modified by the loader.
203
*/
204
uint32_t core_version;
205
206
uint32_t (*format_canonicalize)(uint32_t gbm_format);
207
};
208
209
/**
210
* The interface exposed by the GBM core/loader code to GBM backends.
211
*
212
* To modify this structure, introduce a new gbm_core_v<N> structure, add it
213
* to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
214
*/
215
struct gbm_core_abi0 {
216
struct gbm_core_v0_abi0 v0;
217
};
218
219
typedef const struct gbm_backend *(*GBM_GET_BACKEND_PROC_PTR_abi0)(const struct gbm_core *gbm_core);
220
221
/*
222
* Structure/member ABI-checking helper macros
223
*/
224
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
225
226
#define CHECK_RENAMED_MEMBER_BASE(type, a_ver, b_ver, a_member, b_member) \
227
do { \
228
if (offsetof(struct type ## a_ver, a_member) != \
229
offsetof(struct type ## b_ver, b_member)) { \
230
printf("Backards incompatible change detected!\n " \
231
"offsetof(struct " #type #a_ver "::" #a_member ") != " \
232
"offsetof(struct " #type #b_ver "::" #b_member ")\n"); \
233
return 1; \
234
} \
235
\
236
if (MEMBER_SIZE(struct type ## a_ver, a_member) != \
237
MEMBER_SIZE(struct type ## b_ver, b_member)) { \
238
printf("Backards incompatible change detected!\n " \
239
"MEMBER_SIZE(struct " #type #a_ver "::" #a_member ") != " \
240
"MEMBER_SIZE(struct " #type #b_ver "::" #b_member ")\n"); \
241
return 1; \
242
} \
243
} while (0)
244
245
#define CHECK_RENAMED_MEMBER_TYPE(type, a_ver, b_ver, a_member, b_member) \
246
do { \
247
/* Compile-time type compatibility check */ \
248
struct type ## a_ver a; \
249
struct type ## b_ver b = {0}; \
250
a.a_member = b.b_member; \
251
(void)a; \
252
} while (0)
253
254
#define CHECK_RENAMED_MEMBER(type, a_ver, b_ver, a_member, b_member) \
255
do { \
256
CHECK_RENAMED_MEMBER_BASE(type, a_ver, b_ver, a_member, b_member); \
257
CHECK_RENAMED_MEMBER_TYPE(type, a_ver, b_ver, a_member, b_member); \
258
} while (0)
259
#define CHECK_RENAMED_MEMBER_NO_TYPE(type, a_ver, b_ver, a_member, b_member) \
260
CHECK_RENAMED_MEMBER_BASE(type, a_ver, b_ver, a_member, b_member);
261
262
#define CHECK_MEMBER(type, a_ver, b_ver, member) \
263
CHECK_RENAMED_MEMBER(type, a_ver, b_ver, member, member)
264
#define CHECK_MEMBER_NO_TYPE(type, a_ver, b_ver, member) \
265
CHECK_RENAMED_MEMBER_NO_TYPE(type, a_ver, b_ver, member, member)
266
#define CHECK_MEMBER_CURRENT(type, a_ver, member) \
267
CHECK_MEMBER(type, a_ver,, member)
268
#define CHECK_MEMBER_CURRENT_NO_TYPE(type, a_ver, member) \
269
CHECK_MEMBER_NO_TYPE(type, a_ver,, member)
270
271
#define CHECK_SIZE(type, a_ver, b_ver) \
272
do { \
273
if (sizeof(struct type ## a_ver) > \
274
sizeof(struct type ## b_ver)) { \
275
printf("Backards incompatible change detected!\n " \
276
"sizeof(struct " #type #a_ver ") > " \
277
"sizeof(struct " #type #b_ver ")\n"); \
278
return 1; \
279
} \
280
} while (0)
281
282
#define CHECK_SIZE_CURRENT(type, a_ver) \
283
do { \
284
if (sizeof(struct type ## a_ver) != \
285
sizeof(struct type)) { \
286
printf("Backards incompatible change detected!\n " \
287
"sizeof(struct " #type #a_ver ") != " \
288
"sizeof(struct " #type ")\n"); \
289
return 1; \
290
} \
291
} while (0)
292
293
#define CHECK_VERSION(a_ver, b_ver) \
294
do { \
295
if ((GBM_BACKEND_ABI_VERSION ## a_ver) >= \
296
(GBM_BACKEND_ABI_VERSION ## b_ver)) { \
297
printf("Backards incompatible change detected!\n " \
298
"GBM_BACKEND_ABI_VERSION" #a_ver " >= " \
299
"GBM_BACKEND_ABI_VERSION" #b_ver "\n"); \
300
return 1; \
301
} \
302
} while (0)
303
304
#define CHECK_VERSION_CURRENT(a_ver) \
305
do { \
306
if ((GBM_BACKEND_ABI_VERSION ## a_ver) != \
307
(GBM_BACKEND_ABI_VERSION)) { \
308
printf("Backards incompatible change detected!\n " \
309
"GBM_BACKEND_ABI_VERSION" #a_ver " != " \
310
"GBM_BACKEND_ABI_VERSION\n"); \
311
return 1; \
312
} \
313
} while (0)
314
315
#define CHECK_PROC(proc, a_ver, b_ver) \
316
do { \
317
proc ## a_ver a; \
318
proc ## b_ver b = NULL; \
319
a = b; \
320
(void)a; \
321
} while (0)
322
323
#define CHECK_PROC_CURRENT(proc, a_ver) \
324
CHECK_PROC(proc, a_ver,)
325
326
int main(int argc, char **argv)
327
{
328
/********************************************/
329
/*** Compare Current ABI to ABI version 0 ***/
330
/********************************************/
331
332
/* Check current gbm_device ABI against gbm_device_abi0*/
333
CHECK_MEMBER_CURRENT(gbm_device, _abi0, dummy);
334
CHECK_MEMBER_CURRENT_NO_TYPE(gbm_device, _abi0, v0);
335
336
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, backend_desc);
337
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, backend_version);
338
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, fd);
339
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, name);
340
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, destroy);
341
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, is_format_supported);
342
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, get_format_modifier_plane_count);
343
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_create);
344
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_import);
345
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_map);
346
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_unmap);
347
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_write);
348
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_fd);
349
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_planes);
350
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_handle);
351
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_plane_fd);
352
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_stride);
353
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_offset);
354
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_get_modifier);
355
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, bo_destroy);
356
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_create);
357
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_lock_front_buffer);
358
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_release_buffer);
359
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_has_free_buffers);
360
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_destroy);
361
362
/* Size of ABI-versioned substructures verified by above member checks */
363
CHECK_SIZE_CURRENT (gbm_device, _abi0);
364
365
366
/* Check current gbm_bo ABI against gbm_bo_abi0*/
367
CHECK_MEMBER_CURRENT(gbm_bo, _abi0, gbm);
368
CHECK_MEMBER_CURRENT_NO_TYPE(gbm_bo, _abi0, v0);
369
370
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, width);
371
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, height);
372
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, stride);
373
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, format);
374
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, handle);
375
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, user_data);
376
CHECK_MEMBER_CURRENT(gbm_bo_v0, _abi0, destroy_user_data);
377
378
/* Size of ABI-versioned substructures verified by above member checks */
379
CHECK_SIZE_CURRENT (gbm_bo, _abi0);
380
381
382
/* Check current gbm_surface ABI against gbm_surface_abi0 */
383
CHECK_MEMBER_CURRENT(gbm_surface, _abi0, gbm);
384
CHECK_MEMBER_CURRENT_NO_TYPE(gbm_surface, _abi0, v0);
385
386
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, width);
387
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, height);
388
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, format);
389
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, flags);
390
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, modifiers);
391
CHECK_MEMBER_CURRENT(gbm_surface_v0, _abi0, count);
392
393
/* Size of ABI-versioned substructures verified by above member checks */
394
CHECK_SIZE_CURRENT (gbm_surface, _abi0);
395
396
397
/* Check current gbm_backend ABI against gbm_backend_abi0 */
398
CHECK_MEMBER_CURRENT_NO_TYPE(gbm_backend, _abi0, v0);
399
400
CHECK_MEMBER_CURRENT(gbm_backend_v0, _abi0, backend_version);
401
CHECK_MEMBER_CURRENT(gbm_backend_v0, _abi0, backend_name);
402
CHECK_MEMBER_CURRENT(gbm_backend_v0, _abi0, create_device);
403
404
/* Size of ABI-versioned substructures verified by above member checks */
405
CHECK_SIZE_CURRENT (gbm_backend, _abi0);
406
407
408
/* Check current gbm_core ABI against gbm_core_abi0 */
409
CHECK_MEMBER_CURRENT_NO_TYPE(gbm_core, _abi0, v0);
410
411
CHECK_MEMBER_CURRENT(gbm_core_v0, _abi0, core_version);
412
CHECK_MEMBER_CURRENT(gbm_core_v0, _abi0, format_canonicalize);
413
414
/* Size of ABI-versioned substructures verified by above member checks */
415
CHECK_SIZE_CURRENT (gbm_core, _abi0);
416
417
418
CHECK_PROC_CURRENT (GBM_GET_BACKEND_PROC_PTR, _abi0);
419
420
return 0;
421
}
422
423