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* Don't use the 'inline' keyword, use the INLINE macro in p_compiler.h instead. 17 18* Cast explicitly when converting to integer types of smaller sizes. 19 20* Cast explicitly when converting between float, double and integral types. 21 22* Don't use named struct initializers. 23 24* Don't use variable number of macro arguments. Use static inline functions 25instead. 26 27* Don't use C99 features. 28 29= Standard Library = 30 31* Avoid including standard library headers. Most standard library functions are 32not available in Windows Kernel Mode. Use the appropriate p_*.h include. 33 34== Memory Allocation == 35 36* Use MALLOC, CALLOC, FREE instead of the malloc, calloc, free functions. 37 38* Use align_pointer() function defined in u_memory.h for aligning pointers 39 in a portable way. 40 41== Debugging == 42 43* Use the functions/macros in p_debug.h. 44 45* Don't include assert.h, call abort, printf, etc. 46 47 48= Code Style = 49 50== Inherantice in C == 51 52The main thing we do is mimic inheritance by structure containment. 53 54Here's a silly made-up example: 55 56/* base class */ 57struct buffer 58{ 59 int size; 60 void (*validate)(struct buffer *buf); 61}; 62 63/* sub-class of bufffer */ 64struct texture_buffer 65{ 66 struct buffer base; /* the base class, MUST COME FIRST! */ 67 int format; 68 int width, height; 69}; 70 71 72Then, we'll typically have cast-wrapper functions to convert base-class 73pointers to sub-class pointers where needed: 74 75static inline struct vertex_buffer *vertex_buffer(struct buffer *buf) 76{ 77 return (struct vertex_buffer *) buf; 78} 79 80 81To create/init a sub-classed object: 82 83struct buffer *create_texture_buffer(int w, int h, int format) 84{ 85 struct texture_buffer *t = malloc(sizeof(*t)); 86 t->format = format; 87 t->width = w; 88 t->height = h; 89 t->base.size = w * h; 90 t->base.validate = tex_validate; 91 return &t->base; 92} 93 94Example sub-class method: 95 96void tex_validate(struct buffer *buf) 97{ 98 struct texture_buffer *tb = texture_buffer(buf); 99 assert(tb->format); 100 assert(tb->width); 101 assert(tb->height); 102} 103 104 105Note that we typically do not use typedefs to make "class names"; we use 106'struct whatever' everywhere. 107 108Gallium's pipe_context and the subclassed psb_context, etc are prime examples 109of this. There's also many examples in Mesa and the Mesa state tracker. 110