dri: Fix write/read depth buffer issue under 16bpp mode. See bug #16646
[mesa.git] / src / mesa / drivers / dri / common / depthtmp.h
1
2 /*
3 * Notes:
4 * 1. These functions plug into the gl_renderbuffer structure.
5 * 2. The 'values' parameter always points to GLuint values, regardless of
6 * the actual Z buffer depth.
7 */
8
9
10 #include "spantmp_common.h"
11
12 #ifndef DBG
13 #define DBG 0
14 #endif
15
16 #ifndef HAVE_HW_DEPTH_SPANS
17 #define HAVE_HW_DEPTH_SPANS 0
18 #endif
19
20 #ifndef HAVE_HW_DEPTH_PIXELS
21 #define HAVE_HW_DEPTH_PIXELS 0
22 #endif
23
24 static void TAG(WriteDepthSpan)( GLcontext *ctx,
25 struct gl_renderbuffer *rb,
26 GLuint n, GLint x, GLint y,
27 const void *values,
28 const GLubyte mask[] )
29 {
30 HW_WRITE_LOCK()
31 {
32 const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
33 GLint x1;
34 GLint n1;
35 LOCAL_DEPTH_VARS;
36
37 y = Y_FLIP( y );
38
39 #if HAVE_HW_DEPTH_SPANS
40 (void) x1; (void) n1;
41
42 if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
43 (int)n, (int)x );
44
45 WRITE_DEPTH_SPAN();
46 #else
47 HW_CLIPLOOP()
48 {
49 GLint i = 0;
50 CLIPSPAN( x, y, n, x1, n1, i );
51
52 if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
53 (int)i, (int)n1, (int)x1, mask );
54
55 if ( mask ) {
56 for ( ; n1>0 ; i++, x1++, n1-- ) {
57 if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
58 }
59 } else {
60 for ( ; n1>0 ; i++, x1++, n1-- ) {
61 WRITE_DEPTH( x1, y, depth[i] );
62 }
63 }
64 }
65 HW_ENDCLIPLOOP();
66 #endif
67 }
68 HW_WRITE_UNLOCK();
69 }
70
71
72 #if HAVE_HW_DEPTH_SPANS
73 /* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
74 static void
75 TAG(WriteMonoDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb,
76 GLuint n, GLint x, GLint y,
77 const void *value, const GLubyte mask[] )
78 {
79 const GLuint depthVal = *((GLuint *) value);
80 GLuint depths[MAX_WIDTH];
81 GLuint i;
82 for (i = 0; i < n; i++)
83 depths[i] = depthVal;
84 TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
85 }
86 #else
87 static void TAG(WriteMonoDepthSpan)( GLcontext *ctx,
88 struct gl_renderbuffer *rb,
89 GLuint n, GLint x, GLint y,
90 const void *value,
91 const GLubyte mask[] )
92 {
93 HW_WRITE_LOCK()
94 {
95 const GLuint depth = *((GLuint *) value);
96 GLint x1;
97 GLint n1;
98 LOCAL_DEPTH_VARS;
99
100 y = Y_FLIP( y );
101
102 HW_CLIPLOOP()
103 {
104 GLint i = 0;
105 CLIPSPAN( x, y, n, x1, n1, i );
106
107 if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
108 __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
109
110 if ( mask ) {
111 for ( ; n1>0 ; i++, x1++, n1-- ) {
112 if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
113 }
114 } else {
115 for ( ; n1>0 ; x1++, n1-- ) {
116 WRITE_DEPTH( x1, y, depth );
117 }
118 }
119 }
120 HW_ENDCLIPLOOP();
121 }
122 HW_WRITE_UNLOCK();
123 }
124 #endif
125
126
127 static void TAG(WriteDepthPixels)( GLcontext *ctx,
128 struct gl_renderbuffer *rb,
129 GLuint n,
130 const GLint x[],
131 const GLint y[],
132 const void *values,
133 const GLubyte mask[] )
134 {
135 HW_WRITE_LOCK()
136 {
137 const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
138 GLuint i;
139 LOCAL_DEPTH_VARS;
140
141 if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
142
143 #if HAVE_HW_DEPTH_PIXELS
144 (void) i;
145
146 WRITE_DEPTH_PIXELS();
147 #else
148 HW_CLIPLOOP()
149 {
150 if ( mask ) {
151 for ( i = 0 ; i < n ; i++ ) {
152 if ( mask[i] ) {
153 const int fy = Y_FLIP( y[i] );
154 if ( CLIPPIXEL( x[i], fy ) )
155 WRITE_DEPTH( x[i], fy, depth[i] );
156 }
157 }
158 }
159 else {
160 for ( i = 0 ; i < n ; i++ ) {
161 const int fy = Y_FLIP( y[i] );
162 if ( CLIPPIXEL( x[i], fy ) )
163 WRITE_DEPTH( x[i], fy, depth[i] );
164 }
165 }
166 }
167 HW_ENDCLIPLOOP();
168 #endif
169 }
170 HW_WRITE_UNLOCK();
171 }
172
173
174 /* Read depth spans and pixels
175 */
176 static void TAG(ReadDepthSpan)( GLcontext *ctx,
177 struct gl_renderbuffer *rb,
178 GLuint n, GLint x, GLint y,
179 void *values )
180 {
181 HW_READ_LOCK()
182 {
183 VALUE_TYPE *depth = (VALUE_TYPE *) values;
184 GLint x1, n1;
185 LOCAL_DEPTH_VARS;
186
187 y = Y_FLIP( y );
188
189 if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
190
191 #if HAVE_HW_DEPTH_SPANS
192 (void) x1; (void) n1;
193
194 READ_DEPTH_SPAN();
195 #else
196 HW_CLIPLOOP()
197 {
198 GLint i = 0;
199 CLIPSPAN( x, y, n, x1, n1, i );
200 for ( ; n1>0 ; i++, n1-- ) {
201 READ_DEPTH( depth[i], x+i, y );
202 }
203 }
204 HW_ENDCLIPLOOP();
205 #endif
206 }
207 HW_READ_UNLOCK();
208 }
209
210 static void TAG(ReadDepthPixels)( GLcontext *ctx,
211 struct gl_renderbuffer *rb,
212 GLuint n,
213 const GLint x[], const GLint y[],
214 void *values )
215 {
216 HW_READ_LOCK()
217 {
218 VALUE_TYPE *depth = (VALUE_TYPE *) values;
219 GLuint i;
220 LOCAL_DEPTH_VARS;
221
222 if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
223
224 #if HAVE_HW_DEPTH_PIXELS
225 (void) i;
226
227 READ_DEPTH_PIXELS();
228 #else
229 HW_CLIPLOOP()
230 {
231 for ( i = 0 ; i < n ;i++ ) {
232 int fy = Y_FLIP( y[i] );
233 if ( CLIPPIXEL( x[i], fy ) )
234 READ_DEPTH( depth[i], x[i], fy );
235 }
236 }
237 HW_ENDCLIPLOOP();
238 #endif
239 }
240 HW_READ_UNLOCK();
241 }
242
243
244 /**
245 * Initialize the given renderbuffer's span routines to point to
246 * the depth/z functions we generated above.
247 */
248 static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
249 {
250 rb->GetRow = TAG(ReadDepthSpan);
251 rb->GetValues = TAG(ReadDepthPixels);
252 rb->PutRow = TAG(WriteDepthSpan);
253 rb->PutRowRGB = NULL;
254 rb->PutMonoRow = TAG(WriteMonoDepthSpan);
255 rb->PutValues = TAG(WriteDepthPixels);
256 rb->PutMonoValues = NULL;
257 }
258
259
260 #if HAVE_HW_DEPTH_SPANS
261 #undef WRITE_DEPTH_SPAN
262 #undef WRITE_DEPTH_PIXELS
263 #undef READ_DEPTH_SPAN
264 #undef READ_DEPTH_PIXELS
265 #else
266 #undef WRITE_DEPTH
267 #undef READ_DEPTH
268 #endif
269 #undef TAG
270 #undef VALUE_TYPE