s/GLchan/GLubyte/, fix error string, add comment
[mesa.git] / src / mesa / main / renderbuffer.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
30 *
31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based
32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB
33 * renderbuffer with the alpha renderbuffer. We can do this because of the
34 * OO-nature of renderbuffers.
35 *
36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
37 * color channels. For example, Mesa may use 32-bit/float color channels
38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
40 */
41
42
43 #include "glheader.h"
44 #include "imports.h"
45 #include "context.h"
46 #include "mtypes.h"
47 #include "fbobject.h"
48 #include "renderbuffer.h"
49
50
51 /* 32-bit color index format. Not a public format. */
52 #define COLOR_INDEX32 0x424243
53
54
55 /*
56 * Routines for get/put values in common buffer formats follow.
57 * Someday add support for arbitrary row stride to make them more
58 * flexible.
59 */
60
61 /**********************************************************************
62 * Functions for buffers of 1 X GLubyte values.
63 * Typically stencil.
64 */
65
66 static void *
67 get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
68 GLint x, GLint y)
69 {
70 if (!rb->Data)
71 return NULL;
72 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
73 return (GLubyte *) rb->Data + y * rb->Width + x;
74 }
75
76
77 static void
78 get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
79 GLint x, GLint y, void *values)
80 {
81 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
82 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
83 _mesa_memcpy(values, src, count * sizeof(GLubyte));
84 }
85
86
87 static void
88 get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
89 const GLint x[], const GLint y[], void *values)
90 {
91 GLubyte *dst = (GLubyte *) values;
92 GLuint i;
93 assert(rb->DataType == GL_UNSIGNED_BYTE);
94 for (i = 0; i < count; i++) {
95 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
96 dst[i] = *src;
97 }
98 }
99
100
101 static void
102 put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
103 GLint x, GLint y, const void *values, const GLubyte *mask)
104 {
105 const GLubyte *src = (const GLubyte *) values;
106 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
107 assert(rb->DataType == GL_UNSIGNED_BYTE);
108 if (mask) {
109 GLuint i;
110 for (i = 0; i < count; i++) {
111 if (mask[i]) {
112 dst[i] = src[i];
113 }
114 }
115 }
116 else {
117 _mesa_memcpy(dst, values, count * sizeof(GLubyte));
118 }
119 }
120
121
122 static void
123 put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
124 GLint x, GLint y, const void *value, const GLubyte *mask)
125 {
126 const GLubyte val = *((const GLubyte *) value);
127 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
128 assert(rb->DataType == GL_UNSIGNED_BYTE);
129 if (mask) {
130 GLuint i;
131 for (i = 0; i < count; i++) {
132 if (mask[i]) {
133 dst[i] = val;
134 }
135 }
136 }
137 else {
138 GLuint i;
139 for (i = 0; i < count; i++) {
140 dst[i] = val;
141 }
142 }
143 }
144
145
146 static void
147 put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
148 const GLint x[], const GLint y[],
149 const void *values, const GLubyte *mask)
150 {
151 const GLubyte *src = (const GLubyte *) values;
152 GLuint i;
153 assert(rb->DataType == GL_UNSIGNED_BYTE);
154 for (i = 0; i < count; i++) {
155 if (!mask || mask[i]) {
156 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
157 *dst = src[i];
158 }
159 }
160 }
161
162
163 static void
164 put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
165 const GLint x[], const GLint y[],
166 const void *value, const GLubyte *mask)
167 {
168 const GLubyte val = *((const GLubyte *) value);
169 GLuint i;
170 assert(rb->DataType == GL_UNSIGNED_BYTE);
171 for (i = 0; i < count; i++) {
172 if (!mask || mask[i]) {
173 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
174 *dst = val;
175 }
176 }
177 }
178
179
180 /**********************************************************************
181 * Functions for buffers of 1 X GLushort values.
182 * Typically depth/Z.
183 */
184
185 static void *
186 get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
187 GLint x, GLint y)
188 {
189 if (!rb->Data)
190 return NULL;
191 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
192 ASSERT(rb->Width > 0);
193 return (GLushort *) rb->Data + y * rb->Width + x;
194 }
195
196
197 static void
198 get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
199 GLint x, GLint y, void *values)
200 {
201 const void *src = rb->GetPointer(ctx, rb, x, y);
202 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
203 _mesa_memcpy(values, src, count * sizeof(GLushort));
204 }
205
206
207 static void
208 get_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
209 const GLint x[], const GLint y[], void *values)
210 {
211 GLushort *dst = (GLushort *) values;
212 GLuint i;
213 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
214 for (i = 0; i < count; i++) {
215 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
216 dst[i] = *src;
217 }
218 }
219
220
221 static void
222 put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
223 GLint x, GLint y, const void *values, const GLubyte *mask)
224 {
225 const GLushort *src = (const GLushort *) values;
226 GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
227 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
228 if (mask) {
229 GLuint i;
230 for (i = 0; i < count; i++) {
231 if (mask[i]) {
232 dst[i] = src[i];
233 }
234 }
235 }
236 else {
237 _mesa_memcpy(dst, src, count * sizeof(GLushort));
238 }
239 }
240
241
242 static void
243 put_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
244 GLint x, GLint y, const void *value, const GLubyte *mask)
245 {
246 const GLushort val = *((const GLushort *) value);
247 GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
248 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
249 if (mask) {
250 GLuint i;
251 for (i = 0; i < count; i++) {
252 if (mask[i]) {
253 dst[i] = val;
254 }
255 }
256 }
257 else {
258 GLuint i;
259 for (i = 0; i < count; i++) {
260 dst[i] = val;
261 }
262 }
263 }
264
265
266 static void
267 put_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
268 const GLint x[], const GLint y[], const void *values,
269 const GLubyte *mask)
270 {
271 const GLushort *src = (const GLushort *) values;
272 GLuint i;
273 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
274 for (i = 0; i < count; i++) {
275 if (!mask || mask[i]) {
276 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
277 *dst = src[i];
278 }
279 }
280 }
281
282
283 static void
284 put_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
285 GLuint count, const GLint x[], const GLint y[],
286 const void *value, const GLubyte *mask)
287 {
288 const GLushort val = *((const GLushort *) value);
289 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
290 if (mask) {
291 GLuint i;
292 for (i = 0; i < count; i++) {
293 if (mask[i]) {
294 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
295 *dst = val;
296 }
297 }
298 }
299 else {
300 GLuint i;
301 for (i = 0; i < count; i++) {
302 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
303 *dst = val;
304 }
305 }
306 }
307
308
309 /**********************************************************************
310 * Functions for buffers of 1 X GLuint values.
311 * Typically depth/Z or color index.
312 */
313
314 static void *
315 get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
316 GLint x, GLint y)
317 {
318 if (!rb->Data)
319 return NULL;
320 ASSERT(rb->DataType == GL_UNSIGNED_INT);
321 return (GLuint *) rb->Data + y * rb->Width + x;
322 }
323
324
325 static void
326 get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
327 GLint x, GLint y, void *values)
328 {
329 const void *src = rb->GetPointer(ctx, rb, x, y);
330 ASSERT(rb->DataType == GL_UNSIGNED_INT);
331 _mesa_memcpy(values, src, count * sizeof(GLuint));
332 }
333
334
335 static void
336 get_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
337 const GLint x[], const GLint y[], void *values)
338 {
339 GLuint *dst = (GLuint *) values;
340 GLuint i;
341 ASSERT(rb->DataType == GL_UNSIGNED_INT);
342 for (i = 0; i < count; i++) {
343 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
344 dst[i] = *src;
345 }
346 }
347
348
349 static void
350 put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
351 GLint x, GLint y, const void *values, const GLubyte *mask)
352 {
353 const GLuint *src = (const GLuint *) values;
354 GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
355 ASSERT(rb->DataType == GL_UNSIGNED_INT);
356 if (mask) {
357 GLuint i;
358 for (i = 0; i < count; i++) {
359 if (mask[i]) {
360 dst[i] = src[i];
361 }
362 }
363 }
364 else {
365 _mesa_memcpy(dst, src, count * sizeof(GLuint));
366 }
367 }
368
369
370 static void
371 put_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
372 GLint x, GLint y, const void *value, const GLubyte *mask)
373 {
374 const GLuint val = *((const GLuint *) value);
375 GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
376 GLuint i;
377 ASSERT(rb->DataType == GL_UNSIGNED_INT);
378 for (i = 0; i < count; i++) {
379 if (!mask || mask[i]) {
380 dst[i] = val;
381 }
382 }
383 }
384
385
386 static void
387 put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
388 const GLint x[], const GLint y[], const void *values,
389 const GLubyte *mask)
390 {
391 const GLuint *src = (const GLuint *) values;
392 GLuint i;
393 ASSERT(rb->DataType == GL_UNSIGNED_INT);
394 for (i = 0; i < count; i++) {
395 if (!mask || mask[i]) {
396 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
397 *dst = src[i];
398 }
399 }
400 }
401
402
403 static void
404 put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
405 const GLint x[], const GLint y[], const void *value,
406 const GLubyte *mask)
407 {
408 const GLuint val = *((const GLuint *) value);
409 GLuint i;
410 ASSERT(rb->DataType == GL_UNSIGNED_INT);
411 for (i = 0; i < count; i++) {
412 if (!mask || mask[i]) {
413 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
414 *dst = val;
415 }
416 }
417 }
418
419
420 /**********************************************************************
421 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
422 * Typically color buffers.
423 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
424 * alpha values and return 255 for outgoing alpha values.
425 */
426
427 static void *
428 get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
429 GLint x, GLint y)
430 {
431 /* No direct access since this buffer is RGB but caller will be
432 * treating it as if it were RGBA.
433 */
434 return NULL;
435 }
436
437
438 static void
439 get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
440 GLint x, GLint y, void *values)
441 {
442 const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
443 GLubyte *dst = (GLubyte *) values;
444 GLuint i;
445 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
446 for (i = 0; i < count; i++) {
447 dst[i * 4 + 0] = src[i * 3 + 0];
448 dst[i * 4 + 1] = src[i * 3 + 1];
449 dst[i * 4 + 2] = src[i * 3 + 2];
450 dst[i * 4 + 3] = 255;
451 }
452 }
453
454
455 static void
456 get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
457 const GLint x[], const GLint y[], void *values)
458 {
459 GLubyte *dst = (GLubyte *) values;
460 GLuint i;
461 assert(rb->DataType == GL_UNSIGNED_BYTE);
462 for (i = 0; i < count; i++) {
463 const GLubyte *src
464 = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
465 dst[i * 4 + 0] = src[0];
466 dst[i * 4 + 1] = src[1];
467 dst[i * 4 + 2] = src[2];
468 dst[i * 4 + 3] = 255;
469 }
470 }
471
472
473 static void
474 put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
475 GLint x, GLint y, const void *values, const GLubyte *mask)
476 {
477 /* note: incoming values are RGB+A! */
478 const GLubyte *src = (const GLubyte *) values;
479 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
480 GLuint i;
481 assert(rb->DataType == GL_UNSIGNED_BYTE);
482 for (i = 0; i < count; i++) {
483 if (!mask || mask[i]) {
484 dst[i * 3 + 0] = src[i * 4 + 0];
485 dst[i * 3 + 1] = src[i * 4 + 1];
486 dst[i * 3 + 2] = src[i * 4 + 2];
487 }
488 }
489 }
490
491
492 static void
493 put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
494 GLint x, GLint y, const void *values, const GLubyte *mask)
495 {
496 /* note: incoming values are RGB+A! */
497 const GLubyte *src = (const GLubyte *) values;
498 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
499 GLuint i;
500 assert(rb->DataType == GL_UNSIGNED_BYTE);
501 for (i = 0; i < count; i++) {
502 if (!mask || mask[i]) {
503 dst[i * 3 + 0] = src[i * 3 + 0];
504 dst[i * 3 + 1] = src[i * 3 + 1];
505 dst[i * 3 + 2] = src[i * 3 + 2];
506 }
507 }
508 }
509
510
511 static void
512 put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
513 GLint x, GLint y, const void *value, const GLubyte *mask)
514 {
515 /* note: incoming value is RGB+A! */
516 const GLubyte val0 = ((const GLubyte *) value)[0];
517 const GLubyte val1 = ((const GLubyte *) value)[1];
518 const GLubyte val2 = ((const GLubyte *) value)[2];
519 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
520 assert(rb->DataType == GL_UNSIGNED_BYTE);
521 if (!mask && val0 == val1 && val1 == val2) {
522 /* optimized case */
523 _mesa_memset(dst, val0, 3 * count);
524 }
525 else {
526 GLuint i;
527 for (i = 0; i < count; i++) {
528 if (!mask || mask[i]) {
529 dst[i * 3 + 0] = val0;
530 dst[i * 3 + 1] = val1;
531 dst[i * 3 + 2] = val2;
532 }
533 }
534 }
535 }
536
537
538 static void
539 put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
540 const GLint x[], const GLint y[], const void *values,
541 const GLubyte *mask)
542 {
543 /* note: incoming values are RGB+A! */
544 const GLubyte *src = (const GLubyte *) values;
545 GLuint i;
546 assert(rb->DataType == GL_UNSIGNED_BYTE);
547 for (i = 0; i < count; i++) {
548 if (!mask || mask[i]) {
549 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
550 dst[0] = src[i * 4 + 0];
551 dst[1] = src[i * 4 + 1];
552 dst[2] = src[i * 4 + 2];
553 }
554 }
555 }
556
557
558 static void
559 put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
560 GLuint count, const GLint x[], const GLint y[],
561 const void *value, const GLubyte *mask)
562 {
563 /* note: incoming value is RGB+A! */
564 const GLubyte val0 = ((const GLubyte *) value)[0];
565 const GLubyte val1 = ((const GLubyte *) value)[1];
566 const GLubyte val2 = ((const GLubyte *) value)[2];
567 GLuint i;
568 assert(rb->DataType == GL_UNSIGNED_BYTE);
569 for (i = 0; i < count; i++) {
570 if (!mask || mask[i]) {
571 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
572 dst[0] = val0;
573 dst[1] = val1;
574 dst[2] = val2;
575 }
576 }
577 }
578
579
580 /**********************************************************************
581 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
582 * Typically color buffers.
583 */
584
585 static void *
586 get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
587 GLint x, GLint y)
588 {
589 if (!rb->Data)
590 return NULL;
591 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
592 return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
593 }
594
595
596 static void
597 get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
598 GLint x, GLint y, void *values)
599 {
600 const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x);
601 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
602 _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte));
603 }
604
605
606 static void
607 get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
608 const GLint x[], const GLint y[], void *values)
609 {
610 /* treat 4*GLubyte as 1*GLuint */
611 GLuint *dst = (GLuint *) values;
612 GLuint i;
613 assert(rb->DataType == GL_UNSIGNED_BYTE);
614 for (i = 0; i < count; i++) {
615 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
616 dst[i] = *src;
617 }
618 }
619
620
621 static void
622 put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
623 GLint x, GLint y, const void *values, const GLubyte *mask)
624 {
625 /* treat 4*GLubyte as 1*GLuint */
626 const GLuint *src = (const GLuint *) values;
627 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
628 assert(rb->DataType == GL_UNSIGNED_BYTE);
629 if (mask) {
630 GLuint i;
631 for (i = 0; i < count; i++) {
632 if (mask[i]) {
633 dst[i] = src[i];
634 }
635 }
636 }
637 else {
638 _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte));
639 }
640 }
641
642
643 static void
644 put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
645 GLint x, GLint y, const void *values, const GLubyte *mask)
646 {
647 /* Store RGB values in RGBA buffer */
648 const GLubyte *src = (const GLubyte *) values;
649 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
650 GLuint i;
651 assert(rb->DataType == GL_UNSIGNED_BYTE);
652 for (i = 0; i < count; i++) {
653 if (!mask || mask[i]) {
654 dst[i * 4 + 0] = src[i * 3 + 0];
655 dst[i * 4 + 1] = src[i * 3 + 1];
656 dst[i * 4 + 2] = src[i * 3 + 2];
657 dst[i * 4 + 3] = 0xff;
658 }
659 }
660 }
661
662
663 static void
664 put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
665 GLint x, GLint y, const void *value, const GLubyte *mask)
666 {
667 /* treat 4*GLubyte as 1*GLuint */
668 const GLuint val = *((const GLuint *) value);
669 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
670 assert(rb->DataType == GL_UNSIGNED_BYTE);
671 if (!mask && val == 0) {
672 /* common case */
673 _mesa_bzero(dst, count * 4 * sizeof(GLubyte));
674 }
675 else {
676 /* general case */
677 if (mask) {
678 GLuint i;
679 for (i = 0; i < count; i++) {
680 if (mask[i]) {
681 dst[i] = val;
682 }
683 }
684 }
685 else {
686 GLuint i;
687 for (i = 0; i < count; i++) {
688 dst[i] = val;
689 }
690 }
691 }
692 }
693
694
695 static void
696 put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
697 const GLint x[], const GLint y[], const void *values,
698 const GLubyte *mask)
699 {
700 /* treat 4*GLubyte as 1*GLuint */
701 const GLuint *src = (const GLuint *) values;
702 GLuint i;
703 assert(rb->DataType == GL_UNSIGNED_BYTE);
704 for (i = 0; i < count; i++) {
705 if (!mask || mask[i]) {
706 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
707 *dst = src[i];
708 }
709 }
710 }
711
712
713 static void
714 put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
715 GLuint count, const GLint x[], const GLint y[],
716 const void *value, const GLubyte *mask)
717 {
718 /* treat 4*GLubyte as 1*GLuint */
719 const GLuint val = *((const GLuint *) value);
720 GLuint i;
721 assert(rb->DataType == GL_UNSIGNED_BYTE);
722 for (i = 0; i < count; i++) {
723 if (!mask || mask[i]) {
724 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
725 *dst = val;
726 }
727 }
728 }
729
730
731 /**********************************************************************
732 * Functions for buffers of 4 X GLushort (or GLshort) values.
733 * Typically accum buffer.
734 */
735
736 static void *
737 get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
738 GLint x, GLint y)
739 {
740 if (!rb->Data)
741 return NULL;
742 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
743 return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
744 }
745
746
747 static void
748 get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
749 GLint x, GLint y, void *values)
750 {
751 const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
752 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
753 _mesa_memcpy(values, src, 4 * count * sizeof(GLshort));
754 }
755
756
757 static void
758 get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
759 const GLint x[], const GLint y[], void *values)
760 {
761 GLushort *dst = (GLushort *) values;
762 GLuint i;
763 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
764 for (i = 0; i < count; i++) {
765 const GLushort *src
766 = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
767 dst[i] = *src;
768 }
769 }
770
771
772 static void
773 put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
774 GLint x, GLint y, const void *values, const GLubyte *mask)
775 {
776 const GLushort *src = (const GLushort *) values;
777 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
778 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
779 if (mask) {
780 GLuint i;
781 for (i = 0; i < count; i++) {
782 if (mask[i]) {
783 dst[i * 4 + 0] = src[i * 4 + 0];
784 dst[i * 4 + 1] = src[i * 4 + 1];
785 dst[i * 4 + 2] = src[i * 4 + 2];
786 dst[i * 4 + 3] = src[i * 4 + 3];
787 }
788 }
789 }
790 else {
791 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
792 }
793 }
794
795
796 static void
797 put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
798 GLint x, GLint y, const void *values, const GLubyte *mask)
799 {
800 /* Put RGB values in RGBA buffer */
801 const GLushort *src = (const GLushort *) values;
802 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
803 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
804 if (mask) {
805 GLuint i;
806 for (i = 0; i < count; i++) {
807 if (mask[i]) {
808 dst[i * 4 + 0] = src[i * 3 + 0];
809 dst[i * 4 + 1] = src[i * 3 + 1];
810 dst[i * 4 + 2] = src[i * 3 + 2];
811 dst[i * 4 + 3] = 0xffff;
812 }
813 }
814 }
815 else {
816 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
817 }
818 }
819
820
821 static void
822 put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
823 GLint x, GLint y, const void *value, const GLubyte *mask)
824 {
825 const GLushort val0 = ((const GLushort *) value)[0];
826 const GLushort val1 = ((const GLushort *) value)[1];
827 const GLushort val2 = ((const GLushort *) value)[2];
828 const GLushort val3 = ((const GLushort *) value)[3];
829 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
830 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
831 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
832 /* common case for clearing accum buffer */
833 _mesa_bzero(dst, count * 4 * sizeof(GLushort));
834 }
835 else {
836 GLuint i;
837 for (i = 0; i < count; i++) {
838 if (!mask || mask[i]) {
839 dst[i * 4 + 0] = val0;
840 dst[i * 4 + 1] = val1;
841 dst[i * 4 + 2] = val2;
842 dst[i * 4 + 3] = val3;
843 }
844 }
845 }
846 }
847
848
849 static void
850 put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
851 const GLint x[], const GLint y[], const void *values,
852 const GLubyte *mask)
853 {
854 const GLushort *src = (const GLushort *) values;
855 GLuint i;
856 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
857 for (i = 0; i < count; i++) {
858 if (!mask || mask[i]) {
859 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
860 dst[0] = src[i * 4 + 0];
861 dst[1] = src[i * 4 + 1];
862 dst[2] = src[i * 4 + 2];
863 dst[3] = src[i * 4 + 3];
864 }
865 }
866 }
867
868
869 static void
870 put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
871 GLuint count, const GLint x[], const GLint y[],
872 const void *value, const GLubyte *mask)
873 {
874 const GLushort val0 = ((const GLushort *) value)[0];
875 const GLushort val1 = ((const GLushort *) value)[1];
876 const GLushort val2 = ((const GLushort *) value)[2];
877 const GLushort val3 = ((const GLushort *) value)[3];
878 GLuint i;
879 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
880 for (i = 0; i < count; i++) {
881 if (!mask || mask[i]) {
882 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
883 dst[0] = val0;
884 dst[1] = val1;
885 dst[2] = val2;
886 dst[3] = val3;
887 }
888 }
889 }
890
891
892
893 /**
894 * This is a software fallback for the gl_renderbuffer->AllocStorage
895 * function.
896 * Device drivers will typically override this function for the buffers
897 * which it manages (typically color buffers, Z and stencil).
898 * Other buffers (like software accumulation and aux buffers) which the driver
899 * doesn't manage can be handled with this function.
900 *
901 * This one multi-purpose function can allocate stencil, depth, accum, color
902 * or color-index buffers!
903 *
904 * This function also plugs in the appropriate GetPointer, Get/PutRow and
905 * Get/PutValues functions.
906 */
907 static GLboolean
908 soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
909 GLenum internalFormat, GLuint width, GLuint height)
910 {
911 GLuint pixelSize;
912
913 switch (internalFormat) {
914 case GL_RGB:
915 case GL_R3_G3_B2:
916 case GL_RGB4:
917 case GL_RGB5:
918 case GL_RGB8:
919 case GL_RGB10:
920 case GL_RGB12:
921 case GL_RGB16:
922 rb->_BaseFormat = GL_RGB;
923 rb->DataType = GL_UNSIGNED_BYTE;
924 rb->GetPointer = get_pointer_ubyte3;
925 rb->GetRow = get_row_ubyte3;
926 rb->GetValues = get_values_ubyte3;
927 rb->PutRow = put_row_ubyte3;
928 rb->PutRowRGB = put_row_rgb_ubyte3;
929 rb->PutMonoRow = put_mono_row_ubyte3;
930 rb->PutValues = put_values_ubyte3;
931 rb->PutMonoValues = put_mono_values_ubyte3;
932 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
933 rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
934 rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
935 rb->ComponentSizes[3] = 0;
936 pixelSize = 3 * sizeof(GLubyte);
937 break;
938 case GL_RGBA:
939 case GL_RGBA2:
940 case GL_RGBA4:
941 case GL_RGB5_A1:
942 case GL_RGBA8:
943 rb->_BaseFormat = GL_RGBA;
944 rb->DataType = GL_UNSIGNED_BYTE;
945 rb->GetPointer = get_pointer_ubyte4;
946 rb->GetRow = get_row_ubyte4;
947 rb->GetValues = get_values_ubyte4;
948 rb->PutRow = put_row_ubyte4;
949 rb->PutRowRGB = put_row_rgb_ubyte4;
950 rb->PutMonoRow = put_mono_row_ubyte4;
951 rb->PutValues = put_values_ubyte4;
952 rb->PutMonoValues = put_mono_values_ubyte4;
953 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
954 rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
955 rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
956 rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
957 pixelSize = 4 * sizeof(GLubyte);
958 break;
959 case GL_RGB10_A2:
960 case GL_RGBA12:
961 case GL_RGBA16:
962 rb->_BaseFormat = GL_RGBA;
963 rb->DataType = GL_UNSIGNED_SHORT;
964 rb->GetPointer = get_pointer_ushort4;
965 rb->GetRow = get_row_ushort4;
966 rb->GetValues = get_values_ushort4;
967 rb->PutRow = put_row_ushort4;
968 rb->PutRowRGB = put_row_rgb_ushort4;
969 rb->PutMonoRow = put_mono_row_ushort4;
970 rb->PutValues = put_values_ushort4;
971 rb->PutMonoValues = put_mono_values_ushort4;
972 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
973 rb->ComponentSizes[1] = 8 * sizeof(GLushort);
974 rb->ComponentSizes[2] = 8 * sizeof(GLushort);
975 rb->ComponentSizes[3] = 8 * sizeof(GLushort);
976 pixelSize = 4 * sizeof(GLushort);
977 break;
978 #if 00
979 case ALPHA8:
980 rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
981 rb->DataType = GL_UNSIGNED_BYTE;
982 rb->GetPointer = get_pointer_alpha8;
983 rb->GetRow = get_row_alpha8;
984 rb->GetValues = get_values_alpha8;
985 rb->PutRow = put_row_alpha8;
986 rb->PutRowRGB = NULL;
987 rb->PutMonoRow = put_mono_row_alpha8;
988 rb->PutValues = put_values_alpha8;
989 rb->PutMonoValues = put_mono_values_alpha8;
990 rb->ComponentSizes[0] = 0; /*red*/
991 rb->ComponentSizes[1] = 0; /*green*/
992 rb->ComponentSizes[2] = 0; /*blue*/
993 rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
994 pixelSize = sizeof(GLubyte);
995 break;
996 #endif
997 case GL_STENCIL_INDEX:
998 case GL_STENCIL_INDEX1_EXT:
999 case GL_STENCIL_INDEX4_EXT:
1000 case GL_STENCIL_INDEX8_EXT:
1001 rb->_BaseFormat = GL_STENCIL_INDEX;
1002 rb->DataType = GL_UNSIGNED_BYTE;
1003 rb->GetPointer = get_pointer_ubyte;
1004 rb->GetRow = get_row_ubyte;
1005 rb->GetValues = get_values_ubyte;
1006 rb->PutRow = put_row_ubyte;
1007 rb->PutRowRGB = NULL;
1008 rb->PutMonoRow = put_mono_row_ubyte;
1009 rb->PutValues = put_values_ubyte;
1010 rb->PutMonoValues = put_mono_values_ubyte;
1011 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
1012 pixelSize = sizeof(GLubyte);
1013 break;
1014 case GL_STENCIL_INDEX16_EXT:
1015 rb->_BaseFormat = GL_STENCIL_INDEX;
1016 rb->DataType = GL_UNSIGNED_SHORT;
1017 rb->GetPointer = get_pointer_ushort;
1018 rb->GetRow = get_row_ushort;
1019 rb->GetValues = get_values_ushort;
1020 rb->PutRow = put_row_ushort;
1021 rb->PutRowRGB = NULL;
1022 rb->PutMonoRow = put_mono_row_ushort;
1023 rb->PutValues = put_values_ushort;
1024 rb->PutMonoValues = put_mono_values_ushort;
1025 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1026 pixelSize = sizeof(GLushort);
1027 break;
1028 case GL_DEPTH_COMPONENT:
1029 case GL_DEPTH_COMPONENT16:
1030 rb->_BaseFormat = GL_DEPTH_COMPONENT;
1031 rb->DataType = GL_UNSIGNED_SHORT;
1032 rb->GetPointer = get_pointer_ushort;
1033 rb->GetRow = get_row_ushort;
1034 rb->GetValues = get_values_ushort;
1035 rb->PutRow = put_row_ushort;
1036 rb->PutRowRGB = NULL;
1037 rb->PutMonoRow = put_mono_row_ushort;
1038 rb->PutValues = put_values_ushort;
1039 rb->PutMonoValues = put_mono_values_ushort;
1040 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1041 pixelSize = sizeof(GLushort);
1042 break;
1043 case GL_DEPTH_COMPONENT24:
1044 case GL_DEPTH_COMPONENT32:
1045 rb->_BaseFormat = GL_DEPTH_COMPONENT;
1046 rb->DataType = GL_UNSIGNED_INT;
1047 rb->GetPointer = get_pointer_uint;
1048 rb->GetRow = get_row_uint;
1049 rb->GetValues = get_values_uint;
1050 rb->PutRow = put_row_uint;
1051 rb->PutRowRGB = NULL;
1052 rb->PutMonoRow = put_mono_row_uint;
1053 rb->PutValues = put_values_uint;
1054 rb->PutMonoValues = put_mono_values_uint;
1055 rb->ComponentSizes[0] = 8 * sizeof(GLuint);
1056 pixelSize = sizeof(GLuint);
1057 break;
1058 case GL_COLOR_INDEX8_EXT:
1059 rb->_BaseFormat = GL_COLOR_INDEX;
1060 rb->DataType = GL_UNSIGNED_BYTE;
1061 rb->GetPointer = get_pointer_ubyte;
1062 rb->GetRow = get_row_ubyte;
1063 rb->GetValues = get_values_ubyte;
1064 rb->PutRow = put_row_ubyte;
1065 rb->PutRowRGB = NULL;
1066 rb->PutMonoRow = put_mono_row_ubyte;
1067 rb->PutValues = put_values_ubyte;
1068 rb->PutMonoValues = put_mono_values_ubyte;
1069 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
1070 pixelSize = sizeof(GLubyte);
1071 break;
1072 case GL_COLOR_INDEX16_EXT:
1073 rb->_BaseFormat = GL_COLOR_INDEX;
1074 rb->DataType = GL_UNSIGNED_SHORT;
1075 rb->GetPointer = get_pointer_ushort;
1076 rb->GetRow = get_row_ushort;
1077 rb->GetValues = get_values_ushort;
1078 rb->PutRow = put_row_ushort;
1079 rb->PutRowRGB = NULL;
1080 rb->PutMonoRow = put_mono_row_ushort;
1081 rb->PutValues = put_values_ushort;
1082 rb->PutMonoValues = put_mono_values_ushort;
1083 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1084 pixelSize = sizeof(GLushort);
1085 break;
1086 case COLOR_INDEX32:
1087 rb->_BaseFormat = GL_COLOR_INDEX;
1088 rb->DataType = GL_UNSIGNED_INT;
1089 rb->GetPointer = get_pointer_uint;
1090 rb->GetRow = get_row_uint;
1091 rb->GetValues = get_values_uint;
1092 rb->PutRow = put_row_uint;
1093 rb->PutRowRGB = NULL;
1094 rb->PutMonoRow = put_mono_row_uint;
1095 rb->PutValues = put_values_uint;
1096 rb->PutMonoValues = put_mono_values_uint;
1097 rb->ComponentSizes[0] = 8 * sizeof(GLuint);
1098 pixelSize = sizeof(GLuint);
1099 break;
1100 default:
1101 _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage");
1102 return GL_FALSE;
1103 }
1104
1105 ASSERT(rb->DataType);
1106 ASSERT(rb->GetPointer);
1107 ASSERT(rb->GetRow);
1108 ASSERT(rb->GetValues);
1109 ASSERT(rb->PutRow);
1110 ASSERT(rb->PutMonoRow);
1111 ASSERT(rb->PutValues);
1112 ASSERT(rb->PutMonoValues);
1113 ASSERT(rb->ComponentSizes[0] > 0);
1114
1115 /* free old buffer storage */
1116 if (rb->Data)
1117 _mesa_free(rb->Data);
1118
1119 /* allocate new buffer storage */
1120 rb->Data = _mesa_malloc(width * height * pixelSize);
1121 if (rb->Data == NULL) {
1122 rb->Width = 0;
1123 rb->Height = 0;
1124 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation");
1125 return GL_FALSE;
1126 }
1127
1128 rb->Width = width;
1129 rb->Height = height;
1130 rb->InternalFormat = internalFormat;
1131
1132 return GL_TRUE;
1133 }
1134
1135
1136 /**********************************************************************/
1137 /**********************************************************************/
1138 /**********************************************************************/
1139
1140
1141 /**
1142 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
1143 * an alpha channel. The RGB buffer can be hardware-based.
1144 * We basically wrap the RGB buffer. When PutRow is called (for example),
1145 * we store the alpha values in this buffer, then pass on the PutRow call
1146 * to the wrapped RGB buffer.
1147 */
1148 struct alpha_renderbuffer
1149 {
1150 struct gl_renderbuffer Base; /* the alpha buffer */
1151 struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */
1152 };
1153
1154
1155 static GLboolean
1156 alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1157 GLenum internalFormat, GLuint width, GLuint height)
1158 {
1159 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1160
1161 /* first, pass the call to the wrapped RGB buffer */
1162 if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat,
1163 width, height)) {
1164 return GL_FALSE;
1165 }
1166
1167 /* next, resize my alpha buffer */
1168 if (arb->Base.Data) {
1169 _mesa_free(arb->Base.Data);
1170 }
1171
1172 arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte));
1173 if (arb->Base.Data == NULL) {
1174 arb->Base.Width = 0;
1175 arb->Base.Height = 0;
1176 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
1177 return GL_FALSE;
1178 }
1179
1180 arb->Base.Width = width;
1181 arb->Base.Height = height;
1182 arb->Base.InternalFormat = internalFormat;
1183
1184 return GL_TRUE;
1185 }
1186
1187
1188 /**
1189 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1190 */
1191 static void
1192 delete_renderbuffer_alpha8(struct gl_renderbuffer *rb)
1193 {
1194 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1195 if (arb->Base.Data) {
1196 _mesa_free(arb->Base.Data);
1197 }
1198 assert(arb->RGBbuffer);
1199 arb->RGBbuffer->Delete(arb->RGBbuffer);
1200 arb->RGBbuffer = NULL;
1201 _mesa_free(arb);
1202 }
1203
1204
1205 static void *
1206 get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1207 GLint x, GLint y)
1208 {
1209 return NULL; /* don't allow direct access! */
1210 }
1211
1212
1213 static void
1214 get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1215 GLint x, GLint y, void *values)
1216 {
1217 /* NOTE: 'values' is RGBA format! */
1218 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1219 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
1220 GLubyte *dst = (GLubyte *) values;
1221 GLuint i;
1222 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1223 /* first, pass the call to the wrapped RGB buffer */
1224 arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values);
1225 /* second, fill in alpha values from this buffer! */
1226 for (i = 0; i < count; i++) {
1227 dst[i * 4 + 3] = src[i];
1228 }
1229 }
1230
1231
1232 static void
1233 get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1234 const GLint x[], const GLint y[], void *values)
1235 {
1236 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1237 GLubyte *dst = (GLubyte *) values;
1238 GLuint i;
1239 assert(rb->DataType == GL_UNSIGNED_BYTE);
1240 /* first, pass the call to the wrapped RGB buffer */
1241 arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values);
1242 /* second, fill in alpha values from this buffer! */
1243 for (i = 0; i < count; i++) {
1244 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1245 dst[i * 4 + 3] = *src;
1246 }
1247 }
1248
1249
1250 static void
1251 put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1252 GLint x, GLint y, const void *values, const GLubyte *mask)
1253 {
1254 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1255 const GLubyte *src = (const GLubyte *) values;
1256 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1257 GLuint i;
1258 assert(rb->DataType == GL_UNSIGNED_BYTE);
1259 /* first, pass the call to the wrapped RGB buffer */
1260 arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask);
1261 /* second, store alpha in our buffer */
1262 for (i = 0; i < count; i++) {
1263 if (!mask || mask[i]) {
1264 dst[i] = src[i * 4 + 3];
1265 }
1266 }
1267 }
1268
1269
1270 static void
1271 put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1272 GLint x, GLint y, const void *values, const GLubyte *mask)
1273 {
1274 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1275 const GLubyte *src = (const GLubyte *) values;
1276 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1277 GLuint i;
1278 assert(rb->DataType == GL_UNSIGNED_BYTE);
1279 /* first, pass the call to the wrapped RGB buffer */
1280 arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask);
1281 /* second, store alpha in our buffer */
1282 for (i = 0; i < count; i++) {
1283 if (!mask || mask[i]) {
1284 dst[i] = src[i * 4 + 3];
1285 }
1286 }
1287 }
1288
1289
1290 static void
1291 put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1292 GLint x, GLint y, const void *value, const GLubyte *mask)
1293 {
1294 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1295 const GLubyte val = ((const GLubyte *) value)[3];
1296 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1297 assert(rb->DataType == GL_UNSIGNED_BYTE);
1298 /* first, pass the call to the wrapped RGB buffer */
1299 arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask);
1300 /* second, store alpha in our buffer */
1301 if (mask) {
1302 GLuint i;
1303 for (i = 0; i < count; i++) {
1304 if (mask[i]) {
1305 dst[i] = val;
1306 }
1307 }
1308 }
1309 else {
1310 _mesa_memset(dst, val, count);
1311 }
1312 }
1313
1314
1315 static void
1316 put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1317 const GLint x[], const GLint y[],
1318 const void *values, const GLubyte *mask)
1319 {
1320 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1321 const GLubyte *src = (const GLubyte *) values;
1322 GLuint i;
1323 assert(rb->DataType == GL_UNSIGNED_BYTE);
1324 /* first, pass the call to the wrapped RGB buffer */
1325 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask);
1326 /* second, store alpha in our buffer */
1327 for (i = 0; i < count; i++) {
1328 if (!mask || mask[i]) {
1329 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1330 *dst = src[i * 4 + 3];
1331 }
1332 }
1333 }
1334
1335
1336 static void
1337 put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1338 GLuint count, const GLint x[], const GLint y[],
1339 const void *value, const GLubyte *mask)
1340 {
1341 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1342 const GLubyte val = ((const GLubyte *) value)[3];
1343 GLuint i;
1344 assert(rb->DataType == GL_UNSIGNED_BYTE);
1345 /* first, pass the call to the wrapped RGB buffer */
1346 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask);
1347 /* second, store alpha in our buffer */
1348 for (i = 0; i < count; i++) {
1349 if (!mask || mask[i]) {
1350 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1351 *dst = val;
1352 }
1353 }
1354 }
1355
1356
1357
1358 /**********************************************************************/
1359 /**********************************************************************/
1360 /**********************************************************************/
1361
1362
1363 /**
1364 * Default GetPointer routine. Always return NULL to indicate that
1365 * direct buffer access is not supported.
1366 */
1367 static void *
1368 nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
1369 {
1370 return NULL;
1371 }
1372
1373
1374 /**
1375 * Initialize the fields of a gl_renderbuffer to default values.
1376 */
1377 void
1378 _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
1379 {
1380 rb->Name = name;
1381 rb->RefCount = 1;
1382 rb->Delete = _mesa_delete_renderbuffer;
1383
1384 /* The rest of these should be set later by the caller of this function or
1385 * the AllocStorage method:
1386 */
1387 rb->AllocStorage = NULL;
1388
1389 rb->Width = 0;
1390 rb->Height = 0;
1391 rb->InternalFormat = GL_NONE;
1392 rb->_BaseFormat = GL_NONE;
1393 rb->DataType = GL_NONE;
1394 rb->ComponentSizes[0] = 0;
1395 rb->ComponentSizes[1] = 0;
1396 rb->ComponentSizes[2] = 0;
1397 rb->ComponentSizes[3] = 0;
1398 rb->Data = NULL;
1399
1400 rb->GetPointer = nop_get_pointer;
1401 rb->GetRow = NULL;
1402 rb->GetValues = NULL;
1403 rb->PutRow = NULL;
1404 rb->PutRowRGB = NULL;
1405 rb->PutMonoRow = NULL;
1406 rb->PutValues = NULL;
1407 rb->PutMonoValues = NULL;
1408 }
1409
1410
1411 /**
1412 * Allocate a new gl_renderbuffer object. This can be used for user-created
1413 * renderbuffers or window-system renderbuffers.
1414 */
1415 struct gl_renderbuffer *
1416 _mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
1417 {
1418 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
1419 if (rb) {
1420 _mesa_init_renderbuffer(rb, name);
1421 }
1422 return rb;
1423 }
1424
1425
1426 /**
1427 * Delete a gl_framebuffer.
1428 * This is the default function for framebuffer->Delete().
1429 */
1430 void
1431 _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
1432 {
1433 if (rb->Data) {
1434 _mesa_free(rb->Data);
1435 }
1436 _mesa_free(rb);
1437 }
1438
1439
1440 /**
1441 * Allocate a software-based renderbuffer. This is called via the
1442 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1443 * renderbuffer.
1444 * This would not be used for hardware-based renderbuffers.
1445 */
1446 struct gl_renderbuffer *
1447 _mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
1448 {
1449 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
1450 if (rb) {
1451 rb->AllocStorage = soft_renderbuffer_storage;
1452 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1453 * But we're doing that in the soft_renderbuffer_storage() function
1454 * instead.
1455 */
1456 }
1457 return rb;
1458 }
1459
1460
1461 /**
1462 * Add software-based color renderbuffers to the given framebuffer.
1463 * This is a helper routine for device drivers when creating a
1464 * window system framebuffer (not a user-created render/framebuffer).
1465 * Once this function is called, you can basically forget about this
1466 * renderbuffer; core Mesa will handle all the buffer management and
1467 * rendering!
1468 */
1469 GLboolean
1470 _mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1471 GLuint rgbBits, GLuint alphaBits,
1472 GLboolean frontLeft, GLboolean backLeft,
1473 GLboolean frontRight, GLboolean backRight)
1474 {
1475 GLuint b;
1476
1477 if (rgbBits > 16 || alphaBits > 16) {
1478 _mesa_problem(ctx,
1479 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1480 return GL_FALSE;
1481 }
1482
1483 assert(MAX_COLOR_ATTACHMENTS >= 4);
1484
1485 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1486 struct gl_renderbuffer *rb;
1487
1488 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1489 continue;
1490 else if (b == BUFFER_BACK_LEFT && !backLeft)
1491 continue;
1492 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1493 continue;
1494 else if (b == BUFFER_BACK_RIGHT && !backRight)
1495 continue;
1496
1497 assert(fb->Attachment[b].Renderbuffer == NULL);
1498
1499 rb = _mesa_new_renderbuffer(ctx, 0);
1500 if (!rb) {
1501 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1502 return GL_FALSE;
1503 }
1504
1505 if (rgbBits <= 8) {
1506 if (alphaBits)
1507 rb->InternalFormat = GL_RGBA8;
1508 else
1509 rb->InternalFormat = GL_RGB8;
1510 }
1511 else {
1512 assert(rgbBits <= 16);
1513 if (alphaBits)
1514 rb->InternalFormat = GL_RGBA16;
1515 else
1516 rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */
1517 }
1518
1519 rb->AllocStorage = soft_renderbuffer_storage;
1520 _mesa_add_renderbuffer(fb, b, rb);
1521 }
1522
1523 return GL_TRUE;
1524 }
1525
1526
1527 /**
1528 * Add software-based color index renderbuffers to the given framebuffer.
1529 * This is a helper routine for device drivers when creating a
1530 * window system framebuffer (not a user-created render/framebuffer).
1531 * Once this function is called, you can basically forget about this
1532 * renderbuffer; core Mesa will handle all the buffer management and
1533 * rendering!
1534 */
1535 GLboolean
1536 _mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1537 GLuint indexBits,
1538 GLboolean frontLeft, GLboolean backLeft,
1539 GLboolean frontRight, GLboolean backRight)
1540 {
1541 GLuint b;
1542
1543 if (indexBits > 8) {
1544 _mesa_problem(ctx,
1545 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1546 return GL_FALSE;
1547 }
1548
1549 assert(MAX_COLOR_ATTACHMENTS >= 4);
1550
1551 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1552 struct gl_renderbuffer *rb;
1553
1554 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1555 continue;
1556 else if (b == BUFFER_BACK_LEFT && !backLeft)
1557 continue;
1558 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1559 continue;
1560 else if (b == BUFFER_BACK_RIGHT && !backRight)
1561 continue;
1562
1563 assert(fb->Attachment[b].Renderbuffer == NULL);
1564
1565 rb = _mesa_new_renderbuffer(ctx, 0);
1566 if (!rb) {
1567 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1568 return GL_FALSE;
1569 }
1570
1571 if (indexBits <= 8) {
1572 /* only support GLuint for now */
1573 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1574 rb->InternalFormat = COLOR_INDEX32;
1575 }
1576 else {
1577 rb->InternalFormat = COLOR_INDEX32;
1578 }
1579 rb->AllocStorage = soft_renderbuffer_storage;
1580 _mesa_add_renderbuffer(fb, b, rb);
1581 }
1582
1583 return GL_TRUE;
1584 }
1585
1586
1587 /**
1588 * Add software-based alpha renderbuffers to the given framebuffer.
1589 * This is a helper routine for device drivers when creating a
1590 * window system framebuffer (not a user-created render/framebuffer).
1591 * Once this function is called, you can basically forget about this
1592 * renderbuffer; core Mesa will handle all the buffer management and
1593 * rendering!
1594 */
1595 GLboolean
1596 _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1597 GLuint alphaBits,
1598 GLboolean frontLeft, GLboolean backLeft,
1599 GLboolean frontRight, GLboolean backRight)
1600 {
1601 GLuint b;
1602
1603 /* for window system framebuffers only! */
1604 assert(fb->Name == 0);
1605
1606 if (alphaBits > 8) {
1607 _mesa_problem(ctx,
1608 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1609 return GL_FALSE;
1610 }
1611
1612 assert(MAX_COLOR_ATTACHMENTS >= 4);
1613
1614 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1615 struct alpha_renderbuffer *arb;
1616
1617 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1618 continue;
1619 else if (b == BUFFER_BACK_LEFT && !backLeft)
1620 continue;
1621 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1622 continue;
1623 else if (b == BUFFER_BACK_RIGHT && !backRight)
1624 continue;
1625
1626 /* the RGB buffer to wrap must already exist!! */
1627 assert(fb->Attachment[b].Renderbuffer);
1628
1629 /* only GLubyte supported for now */
1630 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
1631
1632 arb = CALLOC_STRUCT(alpha_renderbuffer);
1633 if (!arb) {
1634 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
1635 return GL_FALSE;
1636 }
1637
1638 _mesa_init_renderbuffer(&arb->Base, 0);
1639
1640 /* wrap the RGB buffer */
1641 arb->RGBbuffer = fb->Attachment[b].Renderbuffer;
1642
1643 /* plug in my functions */
1644 arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat;
1645 arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat;
1646 arb->Base.DataType = arb->RGBbuffer->DataType;
1647 arb->Base.AllocStorage = alloc_storage_alpha8;
1648 arb->Base.Delete = delete_renderbuffer_alpha8;
1649 arb->Base.GetPointer = get_pointer_alpha8;
1650 arb->Base.GetRow = get_row_alpha8;
1651 arb->Base.GetValues = get_values_alpha8;
1652 arb->Base.PutRow = put_row_alpha8;
1653 arb->Base.PutRowRGB = put_row_rgb_alpha8;
1654 arb->Base.PutMonoRow = put_mono_row_alpha8;
1655 arb->Base.PutValues = put_values_alpha8;
1656 arb->Base.PutMonoValues = put_mono_values_alpha8;
1657
1658 /* clear the pointer to avoid assertion/sanity check failure later */
1659 fb->Attachment[b].Renderbuffer = NULL;
1660
1661 /* plug the alpha renderbuffer into the colorbuffer attachment */
1662 _mesa_add_renderbuffer(fb, b, &arb->Base);
1663 }
1664
1665 return GL_TRUE;
1666 }
1667
1668
1669 /**
1670 * Add a software-based depth renderbuffer to the given framebuffer.
1671 * This is a helper routine for device drivers when creating a
1672 * window system framebuffer (not a user-created render/framebuffer).
1673 * Once this function is called, you can basically forget about this
1674 * renderbuffer; core Mesa will handle all the buffer management and
1675 * rendering!
1676 */
1677 GLboolean
1678 _mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1679 GLuint depthBits)
1680 {
1681 struct gl_renderbuffer *rb;
1682
1683 if (depthBits > 32) {
1684 _mesa_problem(ctx,
1685 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1686 return GL_FALSE;
1687 }
1688
1689 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1690
1691 rb = _mesa_new_renderbuffer(ctx, 0);
1692 if (!rb) {
1693 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
1694 return GL_FALSE;
1695 }
1696
1697 if (depthBits <= 16) {
1698 rb->InternalFormat = GL_DEPTH_COMPONENT16;
1699 }
1700 else {
1701 rb->InternalFormat = GL_DEPTH_COMPONENT32;
1702 }
1703
1704 rb->AllocStorage = soft_renderbuffer_storage;
1705 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1706
1707 return GL_TRUE;
1708 }
1709
1710
1711 /**
1712 * Add a software-based stencil renderbuffer to the given framebuffer.
1713 * This is a helper routine for device drivers when creating a
1714 * window system framebuffer (not a user-created render/framebuffer).
1715 * Once this function is called, you can basically forget about this
1716 * renderbuffer; core Mesa will handle all the buffer management and
1717 * rendering!
1718 */
1719 GLboolean
1720 _mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1721 GLuint stencilBits)
1722 {
1723 struct gl_renderbuffer *rb;
1724
1725 if (stencilBits > 16) {
1726 _mesa_problem(ctx,
1727 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1728 return GL_FALSE;
1729 }
1730
1731 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1732
1733 rb = _mesa_new_renderbuffer(ctx, 0);
1734 if (!rb) {
1735 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
1736 return GL_FALSE;
1737 }
1738
1739 if (stencilBits <= 8) {
1740 rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
1741 }
1742 else {
1743 /* not really supported (see s_stencil.c code) */
1744 rb->InternalFormat = GL_STENCIL_INDEX16_EXT;
1745 }
1746
1747 rb->AllocStorage = soft_renderbuffer_storage;
1748 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1749
1750 return GL_TRUE;
1751 }
1752
1753
1754 /**
1755 * Add a software-based accumulation renderbuffer to the given framebuffer.
1756 * This is a helper routine for device drivers when creating a
1757 * window system framebuffer (not a user-created render/framebuffer).
1758 * Once this function is called, you can basically forget about this
1759 * renderbuffer; core Mesa will handle all the buffer management and
1760 * rendering!
1761 */
1762 GLboolean
1763 _mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1764 GLuint redBits, GLuint greenBits,
1765 GLuint blueBits, GLuint alphaBits)
1766 {
1767 struct gl_renderbuffer *rb;
1768
1769 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
1770 _mesa_problem(ctx,
1771 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1772 return GL_FALSE;
1773 }
1774
1775 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
1776
1777 rb = _mesa_new_renderbuffer(ctx, 0);
1778 if (!rb) {
1779 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1780 return GL_FALSE;
1781 }
1782
1783 rb->InternalFormat = GL_RGBA16;
1784 rb->AllocStorage = soft_renderbuffer_storage;
1785 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
1786
1787 return GL_TRUE;
1788 }
1789
1790
1791
1792 /**
1793 * Add a software-based accumulation renderbuffer to the given framebuffer.
1794 * This is a helper routine for device drivers when creating a
1795 * window system framebuffer (not a user-created render/framebuffer).
1796 * Once this function is called, you can basically forget about this
1797 * renderbuffer; core Mesa will handle all the buffer management and
1798 * rendering!
1799 *
1800 * NOTE: color-index aux buffers not supported.
1801 */
1802 GLboolean
1803 _mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1804 GLuint colorBits, GLuint numBuffers)
1805 {
1806 GLuint i;
1807
1808 if (colorBits > 16) {
1809 _mesa_problem(ctx,
1810 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1811 return GL_FALSE;
1812 }
1813
1814 assert(numBuffers < MAX_AUX_BUFFERS);
1815
1816 for (i = 0; i < numBuffers; i++) {
1817 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
1818
1819 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
1820
1821 if (!rb) {
1822 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1823 return GL_FALSE;
1824 }
1825
1826 if (colorBits <= 8) {
1827 rb->InternalFormat = GL_RGBA8;
1828 }
1829 else {
1830 rb->InternalFormat = GL_RGBA16;
1831 }
1832
1833 rb->AllocStorage = soft_renderbuffer_storage;
1834 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
1835 }
1836 return GL_TRUE;
1837 }
1838
1839
1840 /**
1841 * Create/attach software-based renderbuffers to the given framebuffer.
1842 * This is a helper routine for device drivers. Drivers can just as well
1843 * call the individual _mesa_add_*_renderbuffer() routines directly.
1844 */
1845 void
1846 _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
1847 GLboolean color,
1848 GLboolean depth,
1849 GLboolean stencil,
1850 GLboolean accum,
1851 GLboolean alpha,
1852 GLboolean aux)
1853 {
1854 GLboolean frontLeft = GL_TRUE;
1855 GLboolean backLeft = fb->Visual.doubleBufferMode;
1856 GLboolean frontRight = fb->Visual.stereoMode;
1857 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
1858
1859 if (color) {
1860 if (fb->Visual.rgbMode) {
1861 assert(fb->Visual.redBits == fb->Visual.greenBits);
1862 assert(fb->Visual.redBits == fb->Visual.blueBits);
1863 _mesa_add_color_renderbuffers(NULL, fb,
1864 fb->Visual.redBits,
1865 fb->Visual.alphaBits,
1866 frontLeft, backLeft,
1867 frontRight, backRight);
1868 }
1869 else {
1870 _mesa_add_color_index_renderbuffers(NULL, fb,
1871 fb->Visual.indexBits,
1872 frontLeft, backLeft,
1873 frontRight, backRight);
1874 }
1875 }
1876
1877 if (depth) {
1878 assert(fb->Visual.depthBits > 0);
1879 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
1880 }
1881
1882 if (stencil) {
1883 assert(fb->Visual.stencilBits > 0);
1884 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
1885 }
1886
1887 if (accum) {
1888 assert(fb->Visual.rgbMode);
1889 assert(fb->Visual.accumRedBits > 0);
1890 assert(fb->Visual.accumGreenBits > 0);
1891 assert(fb->Visual.accumBlueBits > 0);
1892 _mesa_add_accum_renderbuffer(NULL, fb,
1893 fb->Visual.accumRedBits,
1894 fb->Visual.accumGreenBits,
1895 fb->Visual.accumBlueBits,
1896 fb->Visual.accumAlphaBits);
1897 }
1898
1899 if (aux) {
1900 assert(fb->Visual.rgbMode);
1901 assert(fb->Visual.numAuxBuffers > 0);
1902 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
1903 fb->Visual.numAuxBuffers);
1904 }
1905
1906 if (alpha) {
1907 assert(fb->Visual.rgbMode);
1908 assert(fb->Visual.alphaBits > 0);
1909 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
1910 frontLeft, backLeft,
1911 frontRight, backRight);
1912 }
1913
1914 #if 0
1915 if (multisample) {
1916 /* maybe someday */
1917 }
1918 #endif
1919 }
1920
1921
1922 /**
1923 * Attach a renderbuffer to a framebuffer.
1924 */
1925 void
1926 _mesa_add_renderbuffer(struct gl_framebuffer *fb,
1927 GLuint bufferName, struct gl_renderbuffer *rb)
1928 {
1929 assert(fb);
1930 assert(rb);
1931 #if 00
1932 /* there should be no previous renderbuffer on this attachment point! */
1933 assert(fb->Attachment[bufferName].Renderbuffer == NULL);
1934 #endif
1935 assert(bufferName < BUFFER_COUNT);
1936
1937 /* winsys vs. user-created buffer cross check */
1938 if (fb->Name) {
1939 assert(rb->Name);
1940 }
1941 else {
1942 assert(!rb->Name);
1943 }
1944
1945 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
1946 fb->Attachment[bufferName].Complete = GL_TRUE;
1947 fb->Attachment[bufferName].Renderbuffer = rb;
1948 }