1 CROSS-PLATFORM PORTABILITY GUIDELINES FOR GALLIUM3D 2 3 4= General Considerations = 5 6The state tracker and winsys driver support a rather limited number of 7platforms. However, the pipe drivers are meant to run in a wide number of 8platforms. Hence the pipe drivers, the auxiliary modules, and all public 9headers in general, should strictly follow these guidelines to ensure 10 11 12= Compiler Support = 13 14* Include the p_compiler.h. 15 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 23instead. 24 25* Don't use C99 features. 26 27= Standard Library = 28 29* Avoid including standard library headers. Most standard library functions are 30not 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 36* Use align_pointer() function defined in u_memory.h for aligning pointers 37 in a portable way. 38 39== Debugging == 40 41* Use the functions/macros in p_debug.h. 42 43* Don't include assert.h, call abort, printf, etc. 44 45 46= Code Style = 47 48== Inherantice in C == 49 50The main thing we do is mimic inheritance by structure containment. 51 52Here's a silly made-up example: 53 54/* base class */ 55struct buffer 56{ 57 int size; 58 void (*validate)(struct buffer *buf); 59}; 60 61/* sub-class of bufffer */ 62struct texture_buffer 63{ 64 struct buffer base; /* the base class, MUST COME FIRST! */ 65 int format; 66 int width, height; 67}; 68 69 70Then, we'll typically have cast-wrapper functions to convert base-class 71pointers to sub-class pointers where needed: 72 73static inline struct vertex_buffer *vertex_buffer(struct buffer *buf) 74{ 75 return (struct vertex_buffer *) buf; 76} 77 78 79To create/init a sub-classed object: 80 81struct 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 92Example sub-class method: 93 94void 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 103Note that we typically do not use typedefs to make "class names"; we use 104'struct whatever' everywhere. 105 106Gallium's pipe_context and the subclassed psb_context, etc are prime examples 107of this. There's also many examples in Mesa and the Mesa state tracker. 108