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