José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 1 | CROSS-PLATFORM PORTABILITY GUIDELINES FOR GALLIUM3D |
| 2 | |
| 3 | |
| 4 | = General Considerations = |
| 5 | |
| 6 | The state tracker and winsys driver support a rather limited number of |
| 7 | platforms. However, the pipe drivers are meant to run in a wide number of |
| 8 | platforms. Hence the pipe drivers, the auxiliary modules, and all public |
José Fonseca | 820fe36 | 2008-05-17 00:12:43 +0900 | [diff] [blame] | 9 | headers in general, should strictly follow these guidelines to ensure |
José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 10 | |
| 11 | |
| 12 | = Compiler Support = |
| 13 | |
| 14 | * Include the p_compiler.h. |
| 15 | |
José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 16 | * Cast explicitly when converting to integer types of smaller sizes. |
| 17 | |
| 18 | * Cast explicitly when converting between float, double and integral types. |
| 19 | |
| 20 | * Don't use named struct initializers. |
| 21 | |
| 22 | * Don't use variable number of macro arguments. Use static inline functions |
| 23 | instead. |
| 24 | |
José Fonseca | 073bb94 | 2008-05-01 21:52:05 +0900 | [diff] [blame] | 25 | * Don't use C99 features. |
José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 26 | |
| 27 | = Standard Library = |
| 28 | |
| 29 | * Avoid including standard library headers. Most standard library functions are |
| 30 | not available in Windows Kernel Mode. Use the appropriate p_*.h include. |
| 31 | |
| 32 | == Memory Allocation == |
| 33 | |
| 34 | * Use MALLOC, CALLOC, FREE instead of the malloc, calloc, free functions. |
| 35 | |
Brian Paul | 4f25420 | 2008-08-24 17:48:55 -0600 | [diff] [blame] | 36 | * Use align_pointer() function defined in u_memory.h for aligning pointers |
| 37 | in a portable way. |
José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 38 | |
| 39 | == Debugging == |
| 40 | |
José Fonseca | 34497ea | 2008-03-10 21:15:31 +0000 | [diff] [blame] | 41 | * Use the functions/macros in p_debug.h. |
José Fonseca | 5e2d051 | 2008-02-04 17:02:08 +0900 | [diff] [blame] | 42 | |
José Fonseca | 34497ea | 2008-03-10 21:15:31 +0000 | [diff] [blame] | 43 | * Don't include assert.h, call abort, printf, etc. |
José Fonseca | 073bb94 | 2008-05-01 21:52:05 +0900 | [diff] [blame] | 44 | |
| 45 | |
| 46 | = Code Style = |
| 47 | |
| 48 | == Inherantice in C == |
| 49 | |
| 50 | The main thing we do is mimic inheritance by structure containment. |
| 51 | |
| 52 | Here's a silly made-up example: |
| 53 | |
| 54 | /* base class */ |
| 55 | struct buffer |
| 56 | { |
| 57 | int size; |
| 58 | void (*validate)(struct buffer *buf); |
| 59 | }; |
| 60 | |
| 61 | /* sub-class of bufffer */ |
| 62 | struct texture_buffer |
| 63 | { |
| 64 | struct buffer base; /* the base class, MUST COME FIRST! */ |
| 65 | int format; |
| 66 | int width, height; |
| 67 | }; |
| 68 | |
| 69 | |
| 70 | Then, we'll typically have cast-wrapper functions to convert base-class |
| 71 | pointers to sub-class pointers where needed: |
| 72 | |
| 73 | static inline struct vertex_buffer *vertex_buffer(struct buffer *buf) |
| 74 | { |
| 75 | return (struct vertex_buffer *) buf; |
| 76 | } |
| 77 | |
| 78 | |
| 79 | To create/init a sub-classed object: |
| 80 | |
| 81 | struct buffer *create_texture_buffer(int w, int h, int format) |
| 82 | { |
| 83 | struct texture_buffer *t = malloc(sizeof(*t)); |
| 84 | t->format = format; |
| 85 | t->width = w; |
| 86 | t->height = h; |
| 87 | t->base.size = w * h; |
| 88 | t->base.validate = tex_validate; |
| 89 | return &t->base; |
| 90 | } |
| 91 | |
| 92 | Example sub-class method: |
| 93 | |
| 94 | void tex_validate(struct buffer *buf) |
| 95 | { |
| 96 | struct texture_buffer *tb = texture_buffer(buf); |
| 97 | assert(tb->format); |
| 98 | assert(tb->width); |
| 99 | assert(tb->height); |
| 100 | } |
| 101 | |
| 102 | |
| 103 | Note that we typically do not use typedefs to make "class names"; we use |
| 104 | 'struct whatever' everywhere. |
| 105 | |
| 106 | Gallium's pipe_context and the subclassed psb_context, etc are prime examples |
| 107 | of this. There's also many examples in Mesa and the Mesa state tracker. |