17fb6456e85c46ade8b16f353eeb669f31c238c9
[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 ASSERT(rb->DataType == GL_UNSIGNED_INT);
377 if (mask) {
378 GLuint i;
379 for (i = 0; i < count; i++) {
380 if (mask[i]) {
381 dst[i] = val;
382 }
383 }
384 }
385 else {
386 GLuint i;
387 for (i = 0; i < count; i++) {
388 dst[i] = val;
389 }
390 }
391 }
392
393
394 static void
395 put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
396 const GLint x[], const GLint y[], const void *values,
397 const GLubyte *mask)
398 {
399 const GLuint *src = (const GLuint *) values;
400 GLuint i;
401 ASSERT(rb->DataType == GL_UNSIGNED_INT);
402 for (i = 0; i < count; i++) {
403 if (!mask || mask[i]) {
404 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
405 *dst = src[i];
406 }
407 }
408 }
409
410
411 static void
412 put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
413 const GLint x[], const GLint y[], const void *value,
414 const GLubyte *mask)
415 {
416 const GLuint val = *((const GLuint *) value);
417 GLuint i;
418 ASSERT(rb->DataType == GL_UNSIGNED_INT);
419 for (i = 0; i < count; i++) {
420 if (!mask || mask[i]) {
421 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
422 *dst = val;
423 }
424 }
425 }
426
427
428 /**********************************************************************
429 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
430 * Typically color buffers.
431 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
432 * alpha values and return 255 for outgoing alpha values.
433 */
434
435 static void *
436 get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
437 GLint x, GLint y)
438 {
439 /* No direct access since this buffer is RGB but caller will be
440 * treating it as if it were RGBA.
441 */
442 return NULL;
443 }
444
445
446 static void
447 get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
448 GLint x, GLint y, void *values)
449 {
450 const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
451 GLubyte *dst = (GLubyte *) values;
452 GLuint i;
453 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
454 for (i = 0; i < count; i++) {
455 dst[i * 4 + 0] = src[i * 3 + 0];
456 dst[i * 4 + 1] = src[i * 3 + 1];
457 dst[i * 4 + 2] = src[i * 3 + 2];
458 dst[i * 4 + 3] = 255;
459 }
460 }
461
462
463 static void
464 get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
465 const GLint x[], const GLint y[], void *values)
466 {
467 GLubyte *dst = (GLubyte *) values;
468 GLuint i;
469 assert(rb->DataType == GL_UNSIGNED_BYTE);
470 for (i = 0; i < count; i++) {
471 const GLubyte *src
472 = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
473 dst[i * 4 + 0] = src[0];
474 dst[i * 4 + 1] = src[1];
475 dst[i * 4 + 2] = src[2];
476 dst[i * 4 + 3] = 255;
477 }
478 }
479
480
481 static void
482 put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
483 GLint x, GLint y, const void *values, const GLubyte *mask)
484 {
485 /* note: incoming values are RGB+A! */
486 const GLubyte *src = (const GLubyte *) values;
487 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
488 GLuint i;
489 assert(rb->DataType == GL_UNSIGNED_BYTE);
490 for (i = 0; i < count; i++) {
491 if (!mask || mask[i]) {
492 dst[i * 3 + 0] = src[i * 4 + 0];
493 dst[i * 3 + 1] = src[i * 4 + 1];
494 dst[i * 3 + 2] = src[i * 4 + 2];
495 }
496 }
497 }
498
499
500 static void
501 put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
502 GLint x, GLint y, const void *values, const GLubyte *mask)
503 {
504 /* note: incoming values are RGB+A! */
505 const GLubyte *src = (const GLubyte *) values;
506 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
507 GLuint i;
508 assert(rb->DataType == GL_UNSIGNED_BYTE);
509 for (i = 0; i < count; i++) {
510 if (!mask || mask[i]) {
511 dst[i * 3 + 0] = src[i * 3 + 0];
512 dst[i * 3 + 1] = src[i * 3 + 1];
513 dst[i * 3 + 2] = src[i * 3 + 2];
514 }
515 }
516 }
517
518
519 static void
520 put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
521 GLint x, GLint y, const void *value, const GLubyte *mask)
522 {
523 /* note: incoming value is RGB+A! */
524 const GLubyte val0 = ((const GLubyte *) value)[0];
525 const GLubyte val1 = ((const GLubyte *) value)[1];
526 const GLubyte val2 = ((const GLubyte *) value)[2];
527 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
528 assert(rb->DataType == GL_UNSIGNED_BYTE);
529 if (!mask && val0 == val1 && val1 == val2) {
530 /* optimized case */
531 _mesa_memset(dst, val0, 3 * count);
532 }
533 else {
534 GLuint i;
535 for (i = 0; i < count; i++) {
536 if (!mask || mask[i]) {
537 dst[i * 3 + 0] = val0;
538 dst[i * 3 + 1] = val1;
539 dst[i * 3 + 2] = val2;
540 }
541 }
542 }
543 }
544
545
546 static void
547 put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
548 const GLint x[], const GLint y[], const void *values,
549 const GLubyte *mask)
550 {
551 /* note: incoming values are RGB+A! */
552 const GLubyte *src = (const GLubyte *) values;
553 GLuint i;
554 assert(rb->DataType == GL_UNSIGNED_BYTE);
555 for (i = 0; i < count; i++) {
556 if (!mask || mask[i]) {
557 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
558 dst[0] = src[i * 4 + 0];
559 dst[1] = src[i * 4 + 1];
560 dst[2] = src[i * 4 + 2];
561 }
562 }
563 }
564
565
566 static void
567 put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
568 GLuint count, const GLint x[], const GLint y[],
569 const void *value, const GLubyte *mask)
570 {
571 /* note: incoming value is RGB+A! */
572 const GLubyte val0 = ((const GLubyte *) value)[0];
573 const GLubyte val1 = ((const GLubyte *) value)[1];
574 const GLubyte val2 = ((const GLubyte *) value)[2];
575 GLuint i;
576 assert(rb->DataType == GL_UNSIGNED_BYTE);
577 for (i = 0; i < count; i++) {
578 if (!mask || mask[i]) {
579 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
580 dst[0] = val0;
581 dst[1] = val1;
582 dst[2] = val2;
583 }
584 }
585 }
586
587
588 /**********************************************************************
589 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
590 * Typically color buffers.
591 */
592
593 static void *
594 get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
595 GLint x, GLint y)
596 {
597 if (!rb->Data)
598 return NULL;
599 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
600 return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
601 }
602
603
604 static void
605 get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
606 GLint x, GLint y, void *values)
607 {
608 const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x);
609 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
610 _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte));
611 }
612
613
614 static void
615 get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
616 const GLint x[], const GLint y[], void *values)
617 {
618 /* treat 4*GLubyte as 1*GLuint */
619 GLuint *dst = (GLuint *) values;
620 GLuint i;
621 assert(rb->DataType == GL_UNSIGNED_BYTE);
622 for (i = 0; i < count; i++) {
623 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
624 dst[i] = *src;
625 }
626 }
627
628
629 static void
630 put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
631 GLint x, GLint y, const void *values, const GLubyte *mask)
632 {
633 /* treat 4*GLubyte as 1*GLuint */
634 const GLuint *src = (const GLuint *) values;
635 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
636 assert(rb->DataType == GL_UNSIGNED_BYTE);
637 if (mask) {
638 GLuint i;
639 for (i = 0; i < count; i++) {
640 if (mask[i]) {
641 dst[i] = src[i];
642 }
643 }
644 }
645 else {
646 _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte));
647 }
648 }
649
650
651 static void
652 put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
653 GLint x, GLint y, const void *values, const GLubyte *mask)
654 {
655 /* Store RGB values in RGBA buffer */
656 const GLubyte *src = (const GLubyte *) values;
657 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
658 GLuint i;
659 assert(rb->DataType == GL_UNSIGNED_BYTE);
660 for (i = 0; i < count; i++) {
661 if (!mask || mask[i]) {
662 dst[i * 4 + 0] = src[i * 3 + 0];
663 dst[i * 4 + 1] = src[i * 3 + 1];
664 dst[i * 4 + 2] = src[i * 3 + 2];
665 dst[i * 4 + 3] = 0xff;
666 }
667 }
668 }
669
670
671 static void
672 put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
673 GLint x, GLint y, const void *value, const GLubyte *mask)
674 {
675 /* treat 4*GLubyte as 1*GLuint */
676 const GLuint val = *((const GLuint *) value);
677 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
678 assert(rb->DataType == GL_UNSIGNED_BYTE);
679 if (!mask && val == 0) {
680 /* common case */
681 _mesa_bzero(dst, count * 4 * sizeof(GLubyte));
682 }
683 else {
684 /* general case */
685 if (mask) {
686 GLuint i;
687 for (i = 0; i < count; i++) {
688 if (mask[i]) {
689 dst[i] = val;
690 }
691 }
692 }
693 else {
694 GLuint i;
695 for (i = 0; i < count; i++) {
696 dst[i] = val;
697 }
698 }
699 }
700 }
701
702
703 static void
704 put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
705 const GLint x[], const GLint y[], const void *values,
706 const GLubyte *mask)
707 {
708 /* treat 4*GLubyte as 1*GLuint */
709 const GLuint *src = (const GLuint *) values;
710 GLuint i;
711 assert(rb->DataType == GL_UNSIGNED_BYTE);
712 for (i = 0; i < count; i++) {
713 if (!mask || mask[i]) {
714 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
715 *dst = src[i];
716 }
717 }
718 }
719
720
721 static void
722 put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
723 GLuint count, const GLint x[], const GLint y[],
724 const void *value, const GLubyte *mask)
725 {
726 /* treat 4*GLubyte as 1*GLuint */
727 const GLuint val = *((const GLuint *) value);
728 GLuint i;
729 assert(rb->DataType == GL_UNSIGNED_BYTE);
730 for (i = 0; i < count; i++) {
731 if (!mask || mask[i]) {
732 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
733 *dst = val;
734 }
735 }
736 }
737
738
739 /**********************************************************************
740 * Functions for buffers of 4 X GLushort (or GLshort) values.
741 * Typically accum buffer.
742 */
743
744 static void *
745 get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
746 GLint x, GLint y)
747 {
748 if (!rb->Data)
749 return NULL;
750 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
751 return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
752 }
753
754
755 static void
756 get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
757 GLint x, GLint y, void *values)
758 {
759 const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
760 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
761 _mesa_memcpy(values, src, 4 * count * sizeof(GLshort));
762 }
763
764
765 static void
766 get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
767 const GLint x[], const GLint y[], void *values)
768 {
769 GLushort *dst = (GLushort *) values;
770 GLuint i;
771 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
772 for (i = 0; i < count; i++) {
773 const GLushort *src
774 = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
775 dst[i] = *src;
776 }
777 }
778
779
780 static void
781 put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
782 GLint x, GLint y, const void *values, const GLubyte *mask)
783 {
784 const GLushort *src = (const GLushort *) values;
785 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
786 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
787 if (mask) {
788 GLuint i;
789 for (i = 0; i < count; i++) {
790 if (mask[i]) {
791 dst[i * 4 + 0] = src[i * 4 + 0];
792 dst[i * 4 + 1] = src[i * 4 + 1];
793 dst[i * 4 + 2] = src[i * 4 + 2];
794 dst[i * 4 + 3] = src[i * 4 + 3];
795 }
796 }
797 }
798 else {
799 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
800 }
801 }
802
803
804 static void
805 put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
806 GLint x, GLint y, const void *values, const GLubyte *mask)
807 {
808 /* Put RGB values in RGBA buffer */
809 const GLushort *src = (const GLushort *) values;
810 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
811 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
812 if (mask) {
813 GLuint i;
814 for (i = 0; i < count; i++) {
815 if (mask[i]) {
816 dst[i * 4 + 0] = src[i * 3 + 0];
817 dst[i * 4 + 1] = src[i * 3 + 1];
818 dst[i * 4 + 2] = src[i * 3 + 2];
819 dst[i * 4 + 3] = 0xffff;
820 }
821 }
822 }
823 else {
824 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
825 }
826 }
827
828
829 static void
830 put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
831 GLint x, GLint y, const void *value, const GLubyte *mask)
832 {
833 const GLushort val0 = ((const GLushort *) value)[0];
834 const GLushort val1 = ((const GLushort *) value)[1];
835 const GLushort val2 = ((const GLushort *) value)[2];
836 const GLushort val3 = ((const GLushort *) value)[3];
837 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
838 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
839 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
840 /* common case for clearing accum buffer */
841 _mesa_bzero(dst, count * 4 * sizeof(GLushort));
842 }
843 else {
844 GLuint i;
845 for (i = 0; i < count; i++) {
846 if (!mask || mask[i]) {
847 dst[i * 4 + 0] = val0;
848 dst[i * 4 + 1] = val1;
849 dst[i * 4 + 2] = val2;
850 dst[i * 4 + 3] = val3;
851 }
852 }
853 }
854 }
855
856
857 static void
858 put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
859 const GLint x[], const GLint y[], const void *values,
860 const GLubyte *mask)
861 {
862 const GLushort *src = (const GLushort *) values;
863 GLuint i;
864 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
865 for (i = 0; i < count; i++) {
866 if (!mask || mask[i]) {
867 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
868 dst[0] = src[i * 4 + 0];
869 dst[1] = src[i * 4 + 1];
870 dst[2] = src[i * 4 + 2];
871 dst[3] = src[i * 4 + 3];
872 }
873 }
874 }
875
876
877 static void
878 put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
879 GLuint count, const GLint x[], const GLint y[],
880 const void *value, const GLubyte *mask)
881 {
882 const GLushort val0 = ((const GLushort *) value)[0];
883 const GLushort val1 = ((const GLushort *) value)[1];
884 const GLushort val2 = ((const GLushort *) value)[2];
885 const GLushort val3 = ((const GLushort *) value)[3];
886 GLuint i;
887 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
888 for (i = 0; i < count; i++) {
889 if (!mask || mask[i]) {
890 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
891 dst[0] = val0;
892 dst[1] = val1;
893 dst[2] = val2;
894 dst[3] = val3;
895 }
896 }
897 }
898
899
900
901 /**
902 * This is a software fallback for the gl_renderbuffer->AllocStorage
903 * function.
904 * Device drivers will typically override this function for the buffers
905 * which it manages (typically color buffers, Z and stencil).
906 * Other buffers (like software accumulation and aux buffers) which the driver
907 * doesn't manage can be handled with this function.
908 *
909 * This one multi-purpose function can allocate stencil, depth, accum, color
910 * or color-index buffers!
911 *
912 * This function also plugs in the appropriate GetPointer, Get/PutRow and
913 * Get/PutValues functions.
914 */
915 static GLboolean
916 soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
917 GLenum internalFormat, GLuint width, GLuint height)
918 {
919 GLuint pixelSize;
920
921 switch (internalFormat) {
922 case GL_RGB:
923 case GL_R3_G3_B2:
924 case GL_RGB4:
925 case GL_RGB5:
926 case GL_RGB8:
927 case GL_RGB10:
928 case GL_RGB12:
929 case GL_RGB16:
930 rb->_BaseFormat = GL_RGB;
931 rb->DataType = GL_UNSIGNED_BYTE;
932 rb->GetPointer = get_pointer_ubyte3;
933 rb->GetRow = get_row_ubyte3;
934 rb->GetValues = get_values_ubyte3;
935 rb->PutRow = put_row_ubyte3;
936 rb->PutRowRGB = put_row_rgb_ubyte3;
937 rb->PutMonoRow = put_mono_row_ubyte3;
938 rb->PutValues = put_values_ubyte3;
939 rb->PutMonoValues = put_mono_values_ubyte3;
940 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
941 rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
942 rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
943 rb->ComponentSizes[3] = 0;
944 pixelSize = 3 * sizeof(GLubyte);
945 break;
946 case GL_RGBA:
947 case GL_RGBA2:
948 case GL_RGBA4:
949 case GL_RGB5_A1:
950 case GL_RGBA8:
951 rb->_BaseFormat = GL_RGBA;
952 rb->DataType = GL_UNSIGNED_BYTE;
953 rb->GetPointer = get_pointer_ubyte4;
954 rb->GetRow = get_row_ubyte4;
955 rb->GetValues = get_values_ubyte4;
956 rb->PutRow = put_row_ubyte4;
957 rb->PutRowRGB = put_row_rgb_ubyte4;
958 rb->PutMonoRow = put_mono_row_ubyte4;
959 rb->PutValues = put_values_ubyte4;
960 rb->PutMonoValues = put_mono_values_ubyte4;
961 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
962 rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
963 rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
964 rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
965 pixelSize = 4 * sizeof(GLubyte);
966 break;
967 case GL_RGB10_A2:
968 case GL_RGBA12:
969 case GL_RGBA16:
970 rb->_BaseFormat = GL_RGBA;
971 rb->DataType = GL_UNSIGNED_SHORT;
972 rb->GetPointer = get_pointer_ushort4;
973 rb->GetRow = get_row_ushort4;
974 rb->GetValues = get_values_ushort4;
975 rb->PutRow = put_row_ushort4;
976 rb->PutRowRGB = put_row_rgb_ushort4;
977 rb->PutMonoRow = put_mono_row_ushort4;
978 rb->PutValues = put_values_ushort4;
979 rb->PutMonoValues = put_mono_values_ushort4;
980 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
981 rb->ComponentSizes[1] = 8 * sizeof(GLushort);
982 rb->ComponentSizes[2] = 8 * sizeof(GLushort);
983 rb->ComponentSizes[3] = 8 * sizeof(GLushort);
984 pixelSize = 4 * sizeof(GLushort);
985 break;
986 #if 00
987 case ALPHA8:
988 rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
989 rb->DataType = GL_UNSIGNED_BYTE;
990 rb->GetPointer = get_pointer_alpha8;
991 rb->GetRow = get_row_alpha8;
992 rb->GetValues = get_values_alpha8;
993 rb->PutRow = put_row_alpha8;
994 rb->PutRowRGB = NULL;
995 rb->PutMonoRow = put_mono_row_alpha8;
996 rb->PutValues = put_values_alpha8;
997 rb->PutMonoValues = put_mono_values_alpha8;
998 rb->ComponentSizes[0] = 0; /*red*/
999 rb->ComponentSizes[1] = 0; /*green*/
1000 rb->ComponentSizes[2] = 0; /*blue*/
1001 rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
1002 pixelSize = sizeof(GLubyte);
1003 break;
1004 #endif
1005 case GL_STENCIL_INDEX:
1006 case GL_STENCIL_INDEX1_EXT:
1007 case GL_STENCIL_INDEX4_EXT:
1008 case GL_STENCIL_INDEX8_EXT:
1009 rb->_BaseFormat = GL_STENCIL_INDEX;
1010 rb->DataType = GL_UNSIGNED_BYTE;
1011 rb->GetPointer = get_pointer_ubyte;
1012 rb->GetRow = get_row_ubyte;
1013 rb->GetValues = get_values_ubyte;
1014 rb->PutRow = put_row_ubyte;
1015 rb->PutRowRGB = NULL;
1016 rb->PutMonoRow = put_mono_row_ubyte;
1017 rb->PutValues = put_values_ubyte;
1018 rb->PutMonoValues = put_mono_values_ubyte;
1019 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
1020 pixelSize = sizeof(GLubyte);
1021 break;
1022 case GL_STENCIL_INDEX16_EXT:
1023 rb->_BaseFormat = GL_STENCIL_INDEX;
1024 rb->DataType = GL_UNSIGNED_SHORT;
1025 rb->GetPointer = get_pointer_ushort;
1026 rb->GetRow = get_row_ushort;
1027 rb->GetValues = get_values_ushort;
1028 rb->PutRow = put_row_ushort;
1029 rb->PutRowRGB = NULL;
1030 rb->PutMonoRow = put_mono_row_ushort;
1031 rb->PutValues = put_values_ushort;
1032 rb->PutMonoValues = put_mono_values_ushort;
1033 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1034 pixelSize = sizeof(GLushort);
1035 break;
1036 case GL_DEPTH_COMPONENT:
1037 case GL_DEPTH_COMPONENT16:
1038 rb->_BaseFormat = GL_DEPTH_COMPONENT;
1039 rb->DataType = GL_UNSIGNED_SHORT;
1040 rb->GetPointer = get_pointer_ushort;
1041 rb->GetRow = get_row_ushort;
1042 rb->GetValues = get_values_ushort;
1043 rb->PutRow = put_row_ushort;
1044 rb->PutRowRGB = NULL;
1045 rb->PutMonoRow = put_mono_row_ushort;
1046 rb->PutValues = put_values_ushort;
1047 rb->PutMonoValues = put_mono_values_ushort;
1048 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1049 pixelSize = sizeof(GLushort);
1050 break;
1051 case GL_DEPTH_COMPONENT24:
1052 case GL_DEPTH_COMPONENT32:
1053 rb->_BaseFormat = GL_DEPTH_COMPONENT;
1054 rb->DataType = GL_UNSIGNED_INT;
1055 rb->GetPointer = get_pointer_uint;
1056 rb->GetRow = get_row_uint;
1057 rb->GetValues = get_values_uint;
1058 rb->PutRow = put_row_uint;
1059 rb->PutRowRGB = NULL;
1060 rb->PutMonoRow = put_mono_row_uint;
1061 rb->PutValues = put_values_uint;
1062 rb->PutMonoValues = put_mono_values_uint;
1063 rb->ComponentSizes[0] = 8 * sizeof(GLuint);
1064 pixelSize = sizeof(GLuint);
1065 break;
1066 case GL_COLOR_INDEX8_EXT:
1067 rb->_BaseFormat = GL_COLOR_INDEX;
1068 rb->DataType = GL_UNSIGNED_BYTE;
1069 rb->GetPointer = get_pointer_ubyte;
1070 rb->GetRow = get_row_ubyte;
1071 rb->GetValues = get_values_ubyte;
1072 rb->PutRow = put_row_ubyte;
1073 rb->PutRowRGB = NULL;
1074 rb->PutMonoRow = put_mono_row_ubyte;
1075 rb->PutValues = put_values_ubyte;
1076 rb->PutMonoValues = put_mono_values_ubyte;
1077 rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
1078 pixelSize = sizeof(GLubyte);
1079 break;
1080 case GL_COLOR_INDEX16_EXT:
1081 rb->_BaseFormat = GL_COLOR_INDEX;
1082 rb->DataType = GL_UNSIGNED_SHORT;
1083 rb->GetPointer = get_pointer_ushort;
1084 rb->GetRow = get_row_ushort;
1085 rb->GetValues = get_values_ushort;
1086 rb->PutRow = put_row_ushort;
1087 rb->PutRowRGB = NULL;
1088 rb->PutMonoRow = put_mono_row_ushort;
1089 rb->PutValues = put_values_ushort;
1090 rb->PutMonoValues = put_mono_values_ushort;
1091 rb->ComponentSizes[0] = 8 * sizeof(GLushort);
1092 pixelSize = sizeof(GLushort);
1093 break;
1094 case COLOR_INDEX32:
1095 rb->_BaseFormat = GL_COLOR_INDEX;
1096 rb->DataType = GL_UNSIGNED_INT;
1097 rb->GetPointer = get_pointer_uint;
1098 rb->GetRow = get_row_uint;
1099 rb->GetValues = get_values_uint;
1100 rb->PutRow = put_row_uint;
1101 rb->PutRowRGB = NULL;
1102 rb->PutMonoRow = put_mono_row_uint;
1103 rb->PutValues = put_values_uint;
1104 rb->PutMonoValues = put_mono_values_uint;
1105 rb->ComponentSizes[0] = 8 * sizeof(GLuint);
1106 pixelSize = sizeof(GLuint);
1107 break;
1108 default:
1109 _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage");
1110 return GL_FALSE;
1111 }
1112
1113 ASSERT(rb->DataType);
1114 ASSERT(rb->GetPointer);
1115 ASSERT(rb->GetRow);
1116 ASSERT(rb->GetValues);
1117 ASSERT(rb->PutRow);
1118 ASSERT(rb->PutMonoRow);
1119 ASSERT(rb->PutValues);
1120 ASSERT(rb->PutMonoValues);
1121 ASSERT(rb->ComponentSizes[0] > 0);
1122
1123 /* free old buffer storage */
1124 if (rb->Data)
1125 _mesa_free(rb->Data);
1126
1127 /* allocate new buffer storage */
1128 rb->Data = _mesa_malloc(width * height * pixelSize);
1129 if (rb->Data == NULL) {
1130 rb->Width = 0;
1131 rb->Height = 0;
1132 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation");
1133 return GL_FALSE;
1134 }
1135
1136 rb->Width = width;
1137 rb->Height = height;
1138 rb->InternalFormat = internalFormat;
1139
1140 return GL_TRUE;
1141 }
1142
1143
1144 /**********************************************************************/
1145 /**********************************************************************/
1146 /**********************************************************************/
1147
1148
1149 /**
1150 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
1151 * an alpha channel. The RGB buffer can be hardware-based.
1152 * We basically wrap the RGB buffer. When PutRow is called (for example),
1153 * we store the alpha values in this buffer, then pass on the PutRow call
1154 * to the wrapped RGB buffer.
1155 */
1156 struct alpha_renderbuffer
1157 {
1158 struct gl_renderbuffer Base; /* the alpha buffer */
1159 struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */
1160 };
1161
1162
1163 static GLboolean
1164 alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1165 GLenum internalFormat, GLuint width, GLuint height)
1166 {
1167 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1168
1169 /* first, pass the call to the wrapped RGB buffer */
1170 if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat,
1171 width, height)) {
1172 return GL_FALSE;
1173 }
1174
1175 /* next, resize my alpha buffer */
1176 if (arb->Base.Data) {
1177 _mesa_free(arb->Base.Data);
1178 }
1179
1180 arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte));
1181 if (arb->Base.Data == NULL) {
1182 arb->Base.Width = 0;
1183 arb->Base.Height = 0;
1184 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
1185 return GL_FALSE;
1186 }
1187
1188 arb->Base.Width = width;
1189 arb->Base.Height = height;
1190 arb->Base.InternalFormat = internalFormat;
1191
1192 return GL_TRUE;
1193 }
1194
1195
1196 /**
1197 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1198 */
1199 static void
1200 delete_renderbuffer_alpha8(struct gl_renderbuffer *rb)
1201 {
1202 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1203 if (arb->Base.Data) {
1204 _mesa_free(arb->Base.Data);
1205 }
1206 assert(arb->RGBbuffer);
1207 arb->RGBbuffer->Delete(arb->RGBbuffer);
1208 arb->RGBbuffer = NULL;
1209 _mesa_free(arb);
1210 }
1211
1212
1213 static void *
1214 get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1215 GLint x, GLint y)
1216 {
1217 return NULL; /* don't allow direct access! */
1218 }
1219
1220
1221 static void
1222 get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1223 GLint x, GLint y, void *values)
1224 {
1225 /* NOTE: 'values' is RGBA format! */
1226 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1227 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
1228 GLubyte *dst = (GLubyte *) values;
1229 GLuint i;
1230 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
1231 /* first, pass the call to the wrapped RGB buffer */
1232 arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values);
1233 /* second, fill in alpha values from this buffer! */
1234 for (i = 0; i < count; i++) {
1235 dst[i * 4 + 3] = src[i];
1236 }
1237 }
1238
1239
1240 static void
1241 get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1242 const GLint x[], const GLint y[], void *values)
1243 {
1244 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1245 GLubyte *dst = (GLubyte *) values;
1246 GLuint i;
1247 assert(rb->DataType == GL_UNSIGNED_BYTE);
1248 /* first, pass the call to the wrapped RGB buffer */
1249 arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values);
1250 /* second, fill in alpha values from this buffer! */
1251 for (i = 0; i < count; i++) {
1252 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1253 dst[i * 4 + 3] = *src;
1254 }
1255 }
1256
1257
1258 static void
1259 put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1260 GLint x, GLint y, const void *values, const GLubyte *mask)
1261 {
1262 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1263 const GLubyte *src = (const GLubyte *) values;
1264 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1265 GLuint i;
1266 assert(rb->DataType == GL_UNSIGNED_BYTE);
1267 /* first, pass the call to the wrapped RGB buffer */
1268 arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask);
1269 /* second, store alpha in our buffer */
1270 for (i = 0; i < count; i++) {
1271 if (!mask || mask[i]) {
1272 dst[i] = src[i * 4 + 3];
1273 }
1274 }
1275 }
1276
1277
1278 static void
1279 put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1280 GLint x, GLint y, const void *values, const GLubyte *mask)
1281 {
1282 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1283 const GLubyte *src = (const GLubyte *) values;
1284 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1285 GLuint i;
1286 assert(rb->DataType == GL_UNSIGNED_BYTE);
1287 /* first, pass the call to the wrapped RGB buffer */
1288 arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask);
1289 /* second, store alpha in our buffer */
1290 for (i = 0; i < count; i++) {
1291 if (!mask || mask[i]) {
1292 dst[i] = src[i * 4 + 3];
1293 }
1294 }
1295 }
1296
1297
1298 static void
1299 put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1300 GLint x, GLint y, const void *value, const GLubyte *mask)
1301 {
1302 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1303 const GLubyte val = ((const GLubyte *) value)[3];
1304 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
1305 assert(rb->DataType == GL_UNSIGNED_BYTE);
1306 /* first, pass the call to the wrapped RGB buffer */
1307 arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask);
1308 /* second, store alpha in our buffer */
1309 if (mask) {
1310 GLuint i;
1311 for (i = 0; i < count; i++) {
1312 if (mask[i]) {
1313 dst[i] = val;
1314 }
1315 }
1316 }
1317 else {
1318 _mesa_memset(dst, val, count);
1319 }
1320 }
1321
1322
1323 static void
1324 put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
1325 const GLint x[], const GLint y[],
1326 const void *values, const GLubyte *mask)
1327 {
1328 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1329 const GLubyte *src = (const GLubyte *) values;
1330 GLuint i;
1331 assert(rb->DataType == GL_UNSIGNED_BYTE);
1332 /* first, pass the call to the wrapped RGB buffer */
1333 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask);
1334 /* second, store alpha in our buffer */
1335 for (i = 0; i < count; i++) {
1336 if (!mask || mask[i]) {
1337 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1338 *dst = src[i * 4 + 3];
1339 }
1340 }
1341 }
1342
1343
1344 static void
1345 put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
1346 GLuint count, const GLint x[], const GLint y[],
1347 const void *value, const GLubyte *mask)
1348 {
1349 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
1350 const GLubyte val = ((const GLubyte *) value)[3];
1351 GLuint i;
1352 assert(rb->DataType == GL_UNSIGNED_BYTE);
1353 /* first, pass the call to the wrapped RGB buffer */
1354 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask);
1355 /* second, store alpha in our buffer */
1356 for (i = 0; i < count; i++) {
1357 if (!mask || mask[i]) {
1358 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
1359 *dst = val;
1360 }
1361 }
1362 }
1363
1364
1365
1366 /**********************************************************************/
1367 /**********************************************************************/
1368 /**********************************************************************/
1369
1370
1371 /**
1372 * Default GetPointer routine. Always return NULL to indicate that
1373 * direct buffer access is not supported.
1374 */
1375 static void *
1376 nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
1377 {
1378 return NULL;
1379 }
1380
1381
1382 /**
1383 * Initialize the fields of a gl_renderbuffer to default values.
1384 */
1385 void
1386 _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
1387 {
1388 rb->Name = name;
1389 rb->RefCount = 1;
1390 rb->Delete = _mesa_delete_renderbuffer;
1391
1392 /* The rest of these should be set later by the caller of this function or
1393 * the AllocStorage method:
1394 */
1395 rb->AllocStorage = NULL;
1396
1397 rb->Width = 0;
1398 rb->Height = 0;
1399 rb->InternalFormat = GL_NONE;
1400 rb->_BaseFormat = GL_NONE;
1401 rb->DataType = GL_NONE;
1402 rb->ComponentSizes[0] = 0;
1403 rb->ComponentSizes[1] = 0;
1404 rb->ComponentSizes[2] = 0;
1405 rb->ComponentSizes[3] = 0;
1406 rb->Data = NULL;
1407
1408 rb->GetPointer = nop_get_pointer;
1409 rb->GetRow = NULL;
1410 rb->GetValues = NULL;
1411 rb->PutRow = NULL;
1412 rb->PutRowRGB = NULL;
1413 rb->PutMonoRow = NULL;
1414 rb->PutValues = NULL;
1415 rb->PutMonoValues = NULL;
1416 }
1417
1418
1419 /**
1420 * Allocate a new gl_renderbuffer object. This can be used for user-created
1421 * renderbuffers or window-system renderbuffers.
1422 */
1423 struct gl_renderbuffer *
1424 _mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
1425 {
1426 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
1427 if (rb) {
1428 _mesa_init_renderbuffer(rb, name);
1429 }
1430 return rb;
1431 }
1432
1433
1434 /**
1435 * Delete a gl_framebuffer.
1436 * This is the default function for framebuffer->Delete().
1437 */
1438 void
1439 _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
1440 {
1441 if (rb->Data) {
1442 _mesa_free(rb->Data);
1443 }
1444 _mesa_free(rb);
1445 }
1446
1447
1448 /**
1449 * Allocate a software-based renderbuffer. This is called via the
1450 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1451 * renderbuffer.
1452 * This would not be used for hardware-based renderbuffers.
1453 */
1454 struct gl_renderbuffer *
1455 _mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
1456 {
1457 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
1458 if (rb) {
1459 rb->AllocStorage = soft_renderbuffer_storage;
1460 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1461 * But we're doing that in the soft_renderbuffer_storage() function
1462 * instead.
1463 */
1464 }
1465 return rb;
1466 }
1467
1468
1469 /**
1470 * Add software-based color renderbuffers to the given framebuffer.
1471 * This is a helper routine for device drivers when creating a
1472 * window system framebuffer (not a user-created render/framebuffer).
1473 * Once this function is called, you can basically forget about this
1474 * renderbuffer; core Mesa will handle all the buffer management and
1475 * rendering!
1476 */
1477 GLboolean
1478 _mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1479 GLuint rgbBits, GLuint alphaBits,
1480 GLboolean frontLeft, GLboolean backLeft,
1481 GLboolean frontRight, GLboolean backRight)
1482 {
1483 GLuint b;
1484
1485 if (rgbBits > 16 || alphaBits > 16) {
1486 _mesa_problem(ctx,
1487 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1488 return GL_FALSE;
1489 }
1490
1491 assert(MAX_COLOR_ATTACHMENTS >= 4);
1492
1493 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1494 struct gl_renderbuffer *rb;
1495
1496 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1497 continue;
1498 else if (b == BUFFER_BACK_LEFT && !backLeft)
1499 continue;
1500 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1501 continue;
1502 else if (b == BUFFER_BACK_RIGHT && !backRight)
1503 continue;
1504
1505 assert(fb->Attachment[b].Renderbuffer == NULL);
1506
1507 rb = _mesa_new_renderbuffer(ctx, 0);
1508 if (!rb) {
1509 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1510 return GL_FALSE;
1511 }
1512
1513 if (rgbBits <= 8) {
1514 if (alphaBits)
1515 rb->InternalFormat = GL_RGBA8;
1516 else
1517 rb->InternalFormat = GL_RGB8;
1518 }
1519 else {
1520 assert(rgbBits <= 16);
1521 if (alphaBits)
1522 rb->InternalFormat = GL_RGBA16;
1523 else
1524 rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */
1525 }
1526
1527 rb->AllocStorage = soft_renderbuffer_storage;
1528 _mesa_add_renderbuffer(fb, b, rb);
1529 }
1530
1531 return GL_TRUE;
1532 }
1533
1534
1535 /**
1536 * Add software-based color index renderbuffers to the given framebuffer.
1537 * This is a helper routine for device drivers when creating a
1538 * window system framebuffer (not a user-created render/framebuffer).
1539 * Once this function is called, you can basically forget about this
1540 * renderbuffer; core Mesa will handle all the buffer management and
1541 * rendering!
1542 */
1543 GLboolean
1544 _mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1545 GLuint indexBits,
1546 GLboolean frontLeft, GLboolean backLeft,
1547 GLboolean frontRight, GLboolean backRight)
1548 {
1549 GLuint b;
1550
1551 if (indexBits > 8) {
1552 _mesa_problem(ctx,
1553 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1554 return GL_FALSE;
1555 }
1556
1557 assert(MAX_COLOR_ATTACHMENTS >= 4);
1558
1559 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1560 struct gl_renderbuffer *rb;
1561
1562 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1563 continue;
1564 else if (b == BUFFER_BACK_LEFT && !backLeft)
1565 continue;
1566 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1567 continue;
1568 else if (b == BUFFER_BACK_RIGHT && !backRight)
1569 continue;
1570
1571 assert(fb->Attachment[b].Renderbuffer == NULL);
1572
1573 rb = _mesa_new_renderbuffer(ctx, 0);
1574 if (!rb) {
1575 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1576 return GL_FALSE;
1577 }
1578
1579 if (indexBits <= 8) {
1580 /* only support GLuint for now */
1581 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1582 rb->InternalFormat = COLOR_INDEX32;
1583 }
1584 else {
1585 rb->InternalFormat = COLOR_INDEX32;
1586 }
1587 rb->AllocStorage = soft_renderbuffer_storage;
1588 _mesa_add_renderbuffer(fb, b, rb);
1589 }
1590
1591 return GL_TRUE;
1592 }
1593
1594
1595 /**
1596 * Add software-based alpha renderbuffers to the given framebuffer.
1597 * This is a helper routine for device drivers when creating a
1598 * window system framebuffer (not a user-created render/framebuffer).
1599 * Once this function is called, you can basically forget about this
1600 * renderbuffer; core Mesa will handle all the buffer management and
1601 * rendering!
1602 */
1603 GLboolean
1604 _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1605 GLuint alphaBits,
1606 GLboolean frontLeft, GLboolean backLeft,
1607 GLboolean frontRight, GLboolean backRight)
1608 {
1609 GLuint b;
1610
1611 /* for window system framebuffers only! */
1612 assert(fb->Name == 0);
1613
1614 if (alphaBits > 8) {
1615 _mesa_problem(ctx,
1616 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1617 return GL_FALSE;
1618 }
1619
1620 assert(MAX_COLOR_ATTACHMENTS >= 4);
1621
1622 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1623 struct alpha_renderbuffer *arb;
1624
1625 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1626 continue;
1627 else if (b == BUFFER_BACK_LEFT && !backLeft)
1628 continue;
1629 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1630 continue;
1631 else if (b == BUFFER_BACK_RIGHT && !backRight)
1632 continue;
1633
1634 /* the RGB buffer to wrap must already exist!! */
1635 assert(fb->Attachment[b].Renderbuffer);
1636
1637 /* only GLubyte supported for now */
1638 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
1639
1640 arb = CALLOC_STRUCT(alpha_renderbuffer);
1641 if (!arb) {
1642 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
1643 return GL_FALSE;
1644 }
1645
1646 _mesa_init_renderbuffer(&arb->Base, 0);
1647
1648 /* wrap the RGB buffer */
1649 arb->RGBbuffer = fb->Attachment[b].Renderbuffer;
1650
1651 /* plug in my functions */
1652 arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat;
1653 arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat;
1654 arb->Base.DataType = arb->RGBbuffer->DataType;
1655 arb->Base.AllocStorage = alloc_storage_alpha8;
1656 arb->Base.Delete = delete_renderbuffer_alpha8;
1657 arb->Base.GetPointer = get_pointer_alpha8;
1658 arb->Base.GetRow = get_row_alpha8;
1659 arb->Base.GetValues = get_values_alpha8;
1660 arb->Base.PutRow = put_row_alpha8;
1661 arb->Base.PutRowRGB = put_row_rgb_alpha8;
1662 arb->Base.PutMonoRow = put_mono_row_alpha8;
1663 arb->Base.PutValues = put_values_alpha8;
1664 arb->Base.PutMonoValues = put_mono_values_alpha8;
1665
1666 /* clear the pointer to avoid assertion/sanity check failure later */
1667 fb->Attachment[b].Renderbuffer = NULL;
1668
1669 /* plug the alpha renderbuffer into the colorbuffer attachment */
1670 _mesa_add_renderbuffer(fb, b, &arb->Base);
1671 }
1672
1673 return GL_TRUE;
1674 }
1675
1676
1677 /**
1678 * Add a software-based depth renderbuffer to the given framebuffer.
1679 * This is a helper routine for device drivers when creating a
1680 * window system framebuffer (not a user-created render/framebuffer).
1681 * Once this function is called, you can basically forget about this
1682 * renderbuffer; core Mesa will handle all the buffer management and
1683 * rendering!
1684 */
1685 GLboolean
1686 _mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1687 GLuint depthBits)
1688 {
1689 struct gl_renderbuffer *rb;
1690
1691 if (depthBits > 32) {
1692 _mesa_problem(ctx,
1693 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1694 return GL_FALSE;
1695 }
1696
1697 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1698
1699 rb = _mesa_new_renderbuffer(ctx, 0);
1700 if (!rb) {
1701 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
1702 return GL_FALSE;
1703 }
1704
1705 if (depthBits <= 16) {
1706 rb->InternalFormat = GL_DEPTH_COMPONENT16;
1707 }
1708 else {
1709 rb->InternalFormat = GL_DEPTH_COMPONENT32;
1710 }
1711
1712 rb->AllocStorage = soft_renderbuffer_storage;
1713 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1714
1715 return GL_TRUE;
1716 }
1717
1718
1719 /**
1720 * Add a software-based stencil renderbuffer to the given framebuffer.
1721 * This is a helper routine for device drivers when creating a
1722 * window system framebuffer (not a user-created render/framebuffer).
1723 * Once this function is called, you can basically forget about this
1724 * renderbuffer; core Mesa will handle all the buffer management and
1725 * rendering!
1726 */
1727 GLboolean
1728 _mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1729 GLuint stencilBits)
1730 {
1731 struct gl_renderbuffer *rb;
1732
1733 if (stencilBits > 16) {
1734 _mesa_problem(ctx,
1735 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1736 return GL_FALSE;
1737 }
1738
1739 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1740
1741 rb = _mesa_new_renderbuffer(ctx, 0);
1742 if (!rb) {
1743 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
1744 return GL_FALSE;
1745 }
1746
1747 if (stencilBits <= 8) {
1748 rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
1749 }
1750 else {
1751 /* not really supported (see s_stencil.c code) */
1752 rb->InternalFormat = GL_STENCIL_INDEX16_EXT;
1753 }
1754
1755 rb->AllocStorage = soft_renderbuffer_storage;
1756 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1757
1758 return GL_TRUE;
1759 }
1760
1761
1762 /**
1763 * Add a software-based accumulation renderbuffer to the given framebuffer.
1764 * This is a helper routine for device drivers when creating a
1765 * window system framebuffer (not a user-created render/framebuffer).
1766 * Once this function is called, you can basically forget about this
1767 * renderbuffer; core Mesa will handle all the buffer management and
1768 * rendering!
1769 */
1770 GLboolean
1771 _mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
1772 GLuint redBits, GLuint greenBits,
1773 GLuint blueBits, GLuint alphaBits)
1774 {
1775 struct gl_renderbuffer *rb;
1776
1777 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
1778 _mesa_problem(ctx,
1779 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1780 return GL_FALSE;
1781 }
1782
1783 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
1784
1785 rb = _mesa_new_renderbuffer(ctx, 0);
1786 if (!rb) {
1787 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1788 return GL_FALSE;
1789 }
1790
1791 rb->InternalFormat = GL_RGBA16;
1792 rb->AllocStorage = soft_renderbuffer_storage;
1793 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
1794
1795 return GL_TRUE;
1796 }
1797
1798
1799
1800 /**
1801 * Add a software-based accumulation renderbuffer to the given framebuffer.
1802 * This is a helper routine for device drivers when creating a
1803 * window system framebuffer (not a user-created render/framebuffer).
1804 * Once this function is called, you can basically forget about this
1805 * renderbuffer; core Mesa will handle all the buffer management and
1806 * rendering!
1807 *
1808 * NOTE: color-index aux buffers not supported.
1809 */
1810 GLboolean
1811 _mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
1812 GLuint colorBits, GLuint numBuffers)
1813 {
1814 GLuint i;
1815
1816 if (colorBits > 16) {
1817 _mesa_problem(ctx,
1818 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1819 return GL_FALSE;
1820 }
1821
1822 assert(numBuffers < MAX_AUX_BUFFERS);
1823
1824 for (i = 0; i < numBuffers; i++) {
1825 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
1826
1827 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
1828
1829 if (!rb) {
1830 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1831 return GL_FALSE;
1832 }
1833
1834 if (colorBits <= 8) {
1835 rb->InternalFormat = GL_RGBA8;
1836 }
1837 else {
1838 rb->InternalFormat = GL_RGBA16;
1839 }
1840
1841 rb->AllocStorage = soft_renderbuffer_storage;
1842 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
1843 }
1844 return GL_TRUE;
1845 }
1846
1847
1848 /**
1849 * Create/attach software-based renderbuffers to the given framebuffer.
1850 * This is a helper routine for device drivers. Drivers can just as well
1851 * call the individual _mesa_add_*_renderbuffer() routines directly.
1852 */
1853 void
1854 _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
1855 GLboolean color,
1856 GLboolean depth,
1857 GLboolean stencil,
1858 GLboolean accum,
1859 GLboolean alpha,
1860 GLboolean aux)
1861 {
1862 GLboolean frontLeft = GL_TRUE;
1863 GLboolean backLeft = fb->Visual.doubleBufferMode;
1864 GLboolean frontRight = fb->Visual.stereoMode;
1865 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
1866
1867 if (color) {
1868 if (fb->Visual.rgbMode) {
1869 assert(fb->Visual.redBits == fb->Visual.greenBits);
1870 assert(fb->Visual.redBits == fb->Visual.blueBits);
1871 _mesa_add_color_renderbuffers(NULL, fb,
1872 fb->Visual.redBits,
1873 fb->Visual.alphaBits,
1874 frontLeft, backLeft,
1875 frontRight, backRight);
1876 }
1877 else {
1878 _mesa_add_color_index_renderbuffers(NULL, fb,
1879 fb->Visual.indexBits,
1880 frontLeft, backLeft,
1881 frontRight, backRight);
1882 }
1883 }
1884
1885 if (depth) {
1886 assert(fb->Visual.depthBits > 0);
1887 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
1888 }
1889
1890 if (stencil) {
1891 assert(fb->Visual.stencilBits > 0);
1892 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
1893 }
1894
1895 if (accum) {
1896 assert(fb->Visual.rgbMode);
1897 assert(fb->Visual.accumRedBits > 0);
1898 assert(fb->Visual.accumGreenBits > 0);
1899 assert(fb->Visual.accumBlueBits > 0);
1900 _mesa_add_accum_renderbuffer(NULL, fb,
1901 fb->Visual.accumRedBits,
1902 fb->Visual.accumGreenBits,
1903 fb->Visual.accumBlueBits,
1904 fb->Visual.accumAlphaBits);
1905 }
1906
1907 if (aux) {
1908 assert(fb->Visual.rgbMode);
1909 assert(fb->Visual.numAuxBuffers > 0);
1910 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
1911 fb->Visual.numAuxBuffers);
1912 }
1913
1914 if (alpha) {
1915 assert(fb->Visual.rgbMode);
1916 assert(fb->Visual.alphaBits > 0);
1917 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
1918 frontLeft, backLeft,
1919 frontRight, backRight);
1920 }
1921
1922 #if 0
1923 if (multisample) {
1924 /* maybe someday */
1925 }
1926 #endif
1927 }
1928
1929
1930 /**
1931 * Attach a renderbuffer to a framebuffer.
1932 */
1933 void
1934 _mesa_add_renderbuffer(struct gl_framebuffer *fb,
1935 GLuint bufferName, struct gl_renderbuffer *rb)
1936 {
1937 assert(fb);
1938 assert(rb);
1939 #if 00
1940 /* there should be no previous renderbuffer on this attachment point! */
1941 assert(fb->Attachment[bufferName].Renderbuffer == NULL);
1942 #endif
1943 assert(bufferName < BUFFER_COUNT);
1944
1945 /* winsys vs. user-created buffer cross check */
1946 if (fb->Name) {
1947 assert(rb->Name);
1948 }
1949 else {
1950 assert(!rb->Name);
1951 }
1952
1953 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
1954 fb->Attachment[bufferName].Complete = GL_TRUE;
1955 fb->Attachment[bufferName].Renderbuffer = rb;
1956 }