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