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