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