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