1a7cb36d92ab1f9122bdb28b0cecb00a82f0780d
[mesa.git] / src / mesa / swrast / s_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 software-based renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
30 */
31
32
33 #include "main/glheader.h"
34 #include "main/imports.h"
35 #include "main/context.h"
36 #include "main/fbobject.h"
37 #include "main/formats.h"
38 #include "main/mtypes.h"
39 #include "main/renderbuffer.h"
40 #include "swrast/s_renderbuffer.h"
41
42
43 /*
44 * Routines for get/put values in common buffer formats follow.
45 */
46
47 /* Returns a bytes per pixel of the DataType in the get/put span
48 * functions for at least a subset of the available combinations a
49 * renderbuffer can have.
50 *
51 * It would be nice to see gl_renderbuffer start talking about a
52 * gl_format instead of a GLenum DataType.
53 */
54 static int
55 get_datatype_bytes(struct gl_renderbuffer *rb)
56 {
57 int component_size;
58
59 switch (rb->DataType) {
60 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
61 component_size = 8;
62 break;
63 case GL_FLOAT:
64 case GL_UNSIGNED_INT:
65 case GL_UNSIGNED_INT_24_8_EXT:
66 component_size = 4;
67 break;
68 case GL_UNSIGNED_SHORT:
69 component_size = 2;
70 break;
71 case GL_UNSIGNED_BYTE:
72 component_size = 1;
73 break;
74 default:
75 component_size = 1;
76 assert(0);
77 }
78
79 switch (rb->_BaseFormat) {
80 case GL_DEPTH_COMPONENT:
81 case GL_DEPTH_STENCIL:
82 return component_size;
83 default:
84 return 4 * component_size;
85 }
86 }
87
88 /* This is commonly used by most of the accessors. */
89 static void *
90 get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
91 GLint x, GLint y)
92 {
93 if (!rb->Data)
94 return NULL;
95
96 return ((char *) rb->Data +
97 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format));
98 }
99
100 /* GetRow() implementation for formats where DataType matches the rb->Format.
101 */
102 static void
103 get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
104 GLuint count, GLint x, GLint y, void *values)
105 {
106 void *src = rb->GetPointer(ctx, rb, x, y);
107 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format));
108 }
109
110 /* Only used for float textures currently, but might also be used for
111 * RGBA8888, RGBA16, etc.
112 */
113 static void
114 get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
115 GLuint count, const GLint x[], const GLint y[], void *values)
116 {
117 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
118 GLuint i;
119
120 for (i = 0; i < count; i++) {
121 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]);
122 char *dst = (char *) values + i * format_bytes;
123 memcpy(dst, src, format_bytes);
124 }
125 }
126
127 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
128 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
129 * storing those initial components of the value per pixel into the
130 * destination.
131 */
132 static void
133 put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
134 GLuint count, GLint x, GLint y,
135 const void *values, const GLubyte *mask)
136 {
137 void *row = rb->GetPointer(ctx, rb, x, y);
138 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
139 int datatype_bytes = get_datatype_bytes(rb);
140 unsigned int i;
141
142 if (mask) {
143 for (i = 0; i < count; i++) {
144 char *dst = (char *) row + i * format_bytes;
145 const char *src = (const char *) values + i * datatype_bytes;
146
147 if (mask[i]) {
148 memcpy(dst, src, format_bytes);
149 }
150 }
151 }
152 else {
153 for (i = 0; i < count; i++) {
154 char *dst = (char *) row + i * format_bytes;
155 const char *src = (const char *) values + i * datatype_bytes;
156 memcpy(dst, src, format_bytes);
157 }
158 }
159 }
160
161
162 static void
163 put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
164 GLuint count, const GLint x[], const GLint y[],
165 const void *values, const GLubyte *mask)
166 {
167 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
168 int datatype_bytes = get_datatype_bytes(rb);
169 unsigned int i;
170
171 for (i = 0; i < count; i++) {
172 if (!mask || mask[i]) {
173 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
174 const char *src = (const char *) values + i * datatype_bytes;
175 memcpy(dst, src, format_bytes);
176 }
177 }
178 }
179
180
181
182 /**********************************************************************
183 * Functions for buffers of 1 X GLubyte values.
184 * Typically stencil.
185 */
186
187 static void
188 get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
189 const GLint x[], const GLint y[], void *values)
190 {
191 GLubyte *dst = (GLubyte *) values;
192 GLuint i;
193 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
194 for (i = 0; i < count; i++) {
195 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
196 dst[i] = *src;
197 }
198 }
199
200
201 static void
202 put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
203 GLint x, GLint y, const void *values, const GLubyte *mask)
204 {
205 const GLubyte *src = (const GLubyte *) values;
206 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
207 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
208 if (mask) {
209 GLuint i;
210 for (i = 0; i < count; i++) {
211 if (mask[i]) {
212 dst[i] = src[i];
213 }
214 }
215 }
216 else {
217 memcpy(dst, values, count * sizeof(GLubyte));
218 }
219 }
220
221
222 static void
223 put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
224 const GLint x[], const GLint y[],
225 const void *values, const GLubyte *mask)
226 {
227 const GLubyte *src = (const GLubyte *) values;
228 GLuint i;
229 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
230 for (i = 0; i < count; i++) {
231 if (!mask || mask[i]) {
232 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
233 *dst = src[i];
234 }
235 }
236 }
237
238
239 /**********************************************************************
240 * Functions for buffers of 1 X GLushort values.
241 * Typically depth/Z.
242 */
243
244 static void
245 get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
246 const GLint x[], const GLint y[], void *values)
247 {
248 GLushort *dst = (GLushort *) values;
249 GLuint i;
250 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
251 for (i = 0; i < count; i++) {
252 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
253 dst[i] = *src;
254 }
255 }
256
257
258 static void
259 put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
260 GLint x, GLint y, const void *values, const GLubyte *mask)
261 {
262 const GLushort *src = (const GLushort *) values;
263 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
264 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
265 if (mask) {
266 GLuint i;
267 for (i = 0; i < count; i++) {
268 if (mask[i]) {
269 dst[i] = src[i];
270 }
271 }
272 }
273 else {
274 memcpy(dst, src, count * sizeof(GLushort));
275 }
276 }
277
278
279 static void
280 put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
281 const GLint x[], const GLint y[], const void *values,
282 const GLubyte *mask)
283 {
284 const GLushort *src = (const GLushort *) values;
285 GLuint i;
286 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
287 for (i = 0; i < count; i++) {
288 if (!mask || mask[i]) {
289 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
290 *dst = src[i];
291 }
292 }
293 }
294
295
296 /**********************************************************************
297 * Functions for buffers of 1 X GLuint values.
298 * Typically depth/Z or color index.
299 */
300
301 static void
302 get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
303 const GLint x[], const GLint y[], void *values)
304 {
305 GLuint *dst = (GLuint *) values;
306 GLuint i;
307 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
308 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
309 for (i = 0; i < count; i++) {
310 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
311 dst[i] = *src;
312 }
313 }
314
315
316 static void
317 put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
318 GLint x, GLint y, const void *values, const GLubyte *mask)
319 {
320 const GLuint *src = (const GLuint *) values;
321 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
322 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
323 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
324 if (mask) {
325 GLuint i;
326 for (i = 0; i < count; i++) {
327 if (mask[i]) {
328 dst[i] = src[i];
329 }
330 }
331 }
332 else {
333 memcpy(dst, src, count * sizeof(GLuint));
334 }
335 }
336
337
338 static void
339 put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
340 const GLint x[], const GLint y[], const void *values,
341 const GLubyte *mask)
342 {
343 const GLuint *src = (const GLuint *) values;
344 GLuint i;
345 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
346 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
347 for (i = 0; i < count; i++) {
348 if (!mask || mask[i]) {
349 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
350 *dst = src[i];
351 }
352 }
353 }
354
355
356 /**********************************************************************
357 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
358 * Typically color buffers.
359 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
360 * alpha values and return 255 for outgoing alpha values.
361 */
362
363 static void *
364 get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
365 GLint x, GLint y)
366 {
367 ASSERT(rb->Format == MESA_FORMAT_RGB888);
368 /* No direct access since this buffer is RGB but caller will be
369 * treating it as if it were RGBA.
370 */
371 return NULL;
372 }
373
374
375 static void
376 get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
377 GLint x, GLint y, void *values)
378 {
379 const GLubyte *src = ((const GLubyte *) rb->Data) +
380 3 * (y * rb->RowStride + x);
381 GLubyte *dst = (GLubyte *) values;
382 GLuint i;
383 ASSERT(rb->Format == MESA_FORMAT_RGB888);
384 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
385 for (i = 0; i < count; i++) {
386 dst[i * 4 + 0] = src[i * 3 + 0];
387 dst[i * 4 + 1] = src[i * 3 + 1];
388 dst[i * 4 + 2] = src[i * 3 + 2];
389 dst[i * 4 + 3] = 255;
390 }
391 }
392
393
394 static void
395 get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
396 const GLint x[], const GLint y[], void *values)
397 {
398 GLubyte *dst = (GLubyte *) values;
399 GLuint i;
400 ASSERT(rb->Format == MESA_FORMAT_RGB888);
401 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
402 for (i = 0; i < count; i++) {
403 const GLubyte *src
404 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
405 dst[i * 4 + 0] = src[0];
406 dst[i * 4 + 1] = src[1];
407 dst[i * 4 + 2] = src[2];
408 dst[i * 4 + 3] = 255;
409 }
410 }
411
412
413 static void
414 put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
415 GLint x, GLint y, const void *values, const GLubyte *mask)
416 {
417 /* note: incoming values are RGB+A! */
418 const GLubyte *src = (const GLubyte *) values;
419 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
420 GLuint i;
421 ASSERT(rb->Format == MESA_FORMAT_RGB888);
422 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
423 for (i = 0; i < count; i++) {
424 if (!mask || mask[i]) {
425 dst[i * 3 + 0] = src[i * 4 + 0];
426 dst[i * 3 + 1] = src[i * 4 + 1];
427 dst[i * 3 + 2] = src[i * 4 + 2];
428 }
429 }
430 }
431
432
433 static void
434 put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
435 const GLint x[], const GLint y[], const void *values,
436 const GLubyte *mask)
437 {
438 /* note: incoming values are RGB+A! */
439 const GLubyte *src = (const GLubyte *) values;
440 GLuint i;
441 ASSERT(rb->Format == MESA_FORMAT_RGB888);
442 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
443 for (i = 0; i < count; i++) {
444 if (!mask || mask[i]) {
445 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
446 dst[0] = src[i * 4 + 0];
447 dst[1] = src[i * 4 + 1];
448 dst[2] = src[i * 4 + 2];
449 }
450 }
451 }
452
453
454 /**********************************************************************
455 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
456 * Typically color buffers.
457 */
458
459 static void
460 get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
461 const GLint x[], const GLint y[], void *values)
462 {
463 /* treat 4*GLubyte as 1*GLuint */
464 GLuint *dst = (GLuint *) values;
465 GLuint i;
466 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
467 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
468 rb->Format == MESA_FORMAT_RGBA8888_REV);
469 for (i = 0; i < count; i++) {
470 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
471 dst[i] = *src;
472 }
473 }
474
475
476 static void
477 put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
478 GLint x, GLint y, const void *values, const GLubyte *mask)
479 {
480 /* treat 4*GLubyte as 1*GLuint */
481 const GLuint *src = (const GLuint *) values;
482 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
483 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
484 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
485 rb->Format == MESA_FORMAT_RGBA8888_REV);
486 if (mask) {
487 GLuint i;
488 for (i = 0; i < count; i++) {
489 if (mask[i]) {
490 dst[i] = src[i];
491 }
492 }
493 }
494 else {
495 memcpy(dst, src, 4 * count * sizeof(GLubyte));
496 }
497 }
498
499
500 static void
501 put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
502 const GLint x[], const GLint y[], const void *values,
503 const GLubyte *mask)
504 {
505 /* treat 4*GLubyte as 1*GLuint */
506 const GLuint *src = (const GLuint *) values;
507 GLuint i;
508 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
509 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
510 rb->Format == MESA_FORMAT_RGBA8888_REV);
511 for (i = 0; i < count; i++) {
512 if (!mask || mask[i]) {
513 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
514 *dst = src[i];
515 }
516 }
517 }
518
519
520 /**********************************************************************
521 * Functions for buffers of 4 X GLushort (or GLshort) values.
522 * Typically accum buffer.
523 */
524
525 static void
526 get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
527 const GLint x[], const GLint y[], void *values)
528 {
529 GLushort *dst = (GLushort *) values;
530 GLuint i;
531 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
532 for (i = 0; i < count; i++) {
533 const GLushort *src
534 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]);
535 dst[i] = *src;
536 }
537 }
538
539
540 static void
541 put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
542 GLint x, GLint y, const void *values, const GLubyte *mask)
543 {
544 const GLushort *src = (const GLushort *) values;
545 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
546 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
547 if (mask) {
548 GLuint i;
549 for (i = 0; i < count; i++) {
550 if (mask[i]) {
551 dst[i * 4 + 0] = src[i * 4 + 0];
552 dst[i * 4 + 1] = src[i * 4 + 1];
553 dst[i * 4 + 2] = src[i * 4 + 2];
554 dst[i * 4 + 3] = src[i * 4 + 3];
555 }
556 }
557 }
558 else {
559 memcpy(dst, src, 4 * count * sizeof(GLushort));
560 }
561 }
562
563
564 static void
565 put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
566 const GLint x[], const GLint y[], const void *values,
567 const GLubyte *mask)
568 {
569 const GLushort *src = (const GLushort *) values;
570 GLuint i;
571 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
572 for (i = 0; i < count; i++) {
573 if (!mask || mask[i]) {
574 GLushort *dst =
575 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]);
576 dst[0] = src[i * 4 + 0];
577 dst[1] = src[i * 4 + 1];
578 dst[2] = src[i * 4 + 2];
579 dst[3] = src[i * 4 + 3];
580 }
581 }
582 }
583
584
585 /**********************************************************************
586 * Functions for MESA_FORMAT_R8.
587 */
588 static void
589 get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
590 GLint x, GLint y, void *values)
591 {
592 const GLubyte *src = rb->GetPointer(ctx, rb, x, y);
593 GLuint *dst = values;
594 GLuint i;
595
596 for (i = 0; i < count; i++) {
597 dst[i] = 0xff000000 | src[i];
598 }
599 }
600
601 static void
602 get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
603 const GLint x[], const GLint y[], void *values)
604 {
605 GLuint *dst = (GLuint *) values;
606 GLuint i;
607
608 for (i = 0; i < count; i++) {
609 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]);
610 dst[i] = 0xff000000 | *src;
611 }
612 }
613
614 /**********************************************************************
615 * Functions for MESA_FORMAT_GR88.
616 */
617 static void
618 get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
619 GLint x, GLint y, void *values)
620 {
621 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
622 GLuint *dst = values;
623 GLuint i;
624
625 for (i = 0; i < count; i++) {
626 dst[i] = 0xff000000 | src[i];
627 }
628 }
629
630 static void
631 get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb,
632 GLuint count, const GLint x[], const GLint y[], void *values)
633 {
634 GLuint *dst = (GLuint *) values;
635 GLuint i;
636
637 for (i = 0; i < count; i++) {
638 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
639 dst[i] = 0xff000000 | *src;
640 }
641 }
642
643 /**********************************************************************
644 * Functions for MESA_FORMAT_R16.
645 */
646 static void
647 get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
648 GLint x, GLint y, void *values)
649 {
650 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
651 GLushort *dst = values;
652 GLuint i;
653
654 for (i = 0; i < count; i++) {
655 dst[i * 4 + RCOMP] = src[i];
656 dst[i * 4 + GCOMP] = 0;
657 dst[i * 4 + BCOMP] = 0;
658 dst[i * 4 + ACOMP] = 0xffff;
659 }
660 }
661
662 static void
663 get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
664 const GLint x[], const GLint y[], void *values)
665 {
666 GLushort *dst = values;
667 GLuint i;
668
669 for (i = 0; i < count; i++) {
670 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
671 dst[i * 4 + RCOMP] = *src;
672 dst[i * 4 + GCOMP] = 0;
673 dst[i * 4 + BCOMP] = 0;
674 dst[i * 4 + ACOMP] = 0xffff;
675 }
676 }
677
678 /**********************************************************************
679 * Functions for MESA_FORMAT_RG1616.
680 */
681 static void
682 get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
683 GLint x, GLint y, void *values)
684 {
685 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
686 GLushort *dst = values;
687 GLuint i;
688
689 for (i = 0; i < count; i++) {
690 dst[i * 4 + RCOMP] = src[i * 2];
691 dst[i * 4 + GCOMP] = src[i * 2 + 1];
692 dst[i * 4 + BCOMP] = 0;
693 dst[i * 4 + ACOMP] = 0xffff;
694 }
695 }
696
697 static void
698 get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb,
699 GLuint count, const GLint x[], const GLint y[], void *values)
700 {
701 GLushort *dst = values;
702 GLuint i;
703
704 for (i = 0; i < count; i++) {
705 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
706 dst[i * 4 + RCOMP] = src[0];
707 dst[i * 4 + GCOMP] = src[1];
708 dst[i * 4 + BCOMP] = 0;
709 dst[i * 4 + ACOMP] = 0xffff;
710 }
711 }
712
713 /**********************************************************************
714 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
715 */
716 static void
717 get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
718 GLuint count, GLint x, GLint y, void *values)
719 {
720 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
721 GLfloat *dst = values;
722 GLuint i;
723
724 for (i = 0; i < count; i++) {
725 dst[i * 4 + RCOMP] =
726 dst[i * 4 + GCOMP] =
727 dst[i * 4 + BCOMP] =
728 dst[i * 4 + ACOMP] = src[i];
729 }
730 }
731
732 static void
733 get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
734 GLuint count, const GLint x[], const GLint y[],
735 void *values)
736 {
737 GLfloat *dst = values;
738 GLuint i;
739
740 for (i = 0; i < count; i++) {
741 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
742 dst[i * 4 + RCOMP] =
743 dst[i * 4 + GCOMP] =
744 dst[i * 4 + BCOMP] =
745 dst[i * 4 + ACOMP] = src[0];
746 }
747 }
748
749 /**********************************************************************
750 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
751 */
752 static void
753 get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
754 GLuint count, GLint x, GLint y, void *values)
755 {
756 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
757 GLfloat *dst = values;
758 GLuint i;
759
760 for (i = 0; i < count; i++) {
761 dst[i * 4 + RCOMP] =
762 dst[i * 4 + GCOMP] =
763 dst[i * 4 + BCOMP] = src[i];
764 dst[i * 4 + ACOMP] = 1.0;
765 }
766 }
767
768 static void
769 get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
770 GLuint count, const GLint x[], const GLint y[],
771 void *values)
772 {
773 GLfloat *dst = values;
774 GLuint i;
775
776 for (i = 0; i < count; i++) {
777 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
778 dst[i * 4 + RCOMP] =
779 dst[i * 4 + GCOMP] =
780 dst[i * 4 + BCOMP] = src[0];
781 dst[i * 4 + ACOMP] = 1.0;
782 }
783 }
784
785 /**********************************************************************
786 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
787 */
788 static void
789 get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
790 GLuint count, GLint x, GLint y, void *values)
791 {
792 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
793 GLfloat *dst = values;
794 GLuint i;
795
796 for (i = 0; i < count; i++) {
797 dst[i * 4 + RCOMP] = 0.0;
798 dst[i * 4 + GCOMP] = 0.0;
799 dst[i * 4 + BCOMP] = 0.0;
800 dst[i * 4 + ACOMP] = src[i];
801 }
802 }
803
804 static void
805 get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
806 GLuint count, const GLint x[], const GLint y[],
807 void *values)
808 {
809 GLfloat *dst = values;
810 GLuint i;
811
812 for (i = 0; i < count; i++) {
813 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
814 dst[i * 4 + RCOMP] = 0.0;
815 dst[i * 4 + GCOMP] = 0.0;
816 dst[i * 4 + BCOMP] = 0.0;
817 dst[i * 4 + ACOMP] = src[0];
818 }
819 }
820
821 static void
822 put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
823 GLuint count, GLint x, GLint y,
824 const void *values, const GLubyte *mask)
825 {
826 float *dst = rb->GetPointer(ctx, rb, x, y);
827 const float *src = values;
828 unsigned int i;
829
830 if (mask) {
831 for (i = 0; i < count; i++) {
832 if (mask[i]) {
833 dst[i] = src[i * 4 + ACOMP];
834 }
835 }
836 }
837 else {
838 for (i = 0; i < count; i++) {
839 dst[i] = src[i * 4 + ACOMP];
840 }
841 }
842 }
843
844 static void
845 put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
846 GLuint count, const GLint x[], const GLint y[],
847 const void *values, const GLubyte *mask)
848 {
849 const float *src = values;
850 unsigned int i;
851
852 for (i = 0; i < count; i++) {
853 if (!mask || mask[i]) {
854 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
855
856 *dst = src[i * 4 + ACOMP];
857 }
858 }
859 }
860
861 /**********************************************************************
862 * Functions for MESA_FORMAT_R_FLOAT32.
863 */
864 static void
865 get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
866 GLuint count, GLint x, GLint y, void *values)
867 {
868 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
869 GLfloat *dst = values;
870 GLuint i;
871
872 for (i = 0; i < count; i++) {
873 dst[i * 4 + RCOMP] = src[i];
874 dst[i * 4 + GCOMP] = 0.0;
875 dst[i * 4 + BCOMP] = 0.0;
876 dst[i * 4 + ACOMP] = 1.0;
877 }
878 }
879
880 static void
881 get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
882 GLuint count, const GLint x[], const GLint y[],
883 void *values)
884 {
885 GLfloat *dst = values;
886 GLuint i;
887
888 for (i = 0; i < count; i++) {
889 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
890 dst[i * 4 + RCOMP] = src[0];
891 dst[i * 4 + GCOMP] = 0.0;
892 dst[i * 4 + BCOMP] = 0.0;
893 dst[i * 4 + ACOMP] = 1.0;
894 }
895 }
896
897 /**********************************************************************
898 * Functions for MESA_FORMAT_RG_FLOAT32.
899 */
900 static void
901 get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
902 GLuint count, GLint x, GLint y, void *values)
903 {
904 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
905 GLfloat *dst = values;
906 GLuint i;
907
908 for (i = 0; i < count; i++) {
909 dst[i * 4 + RCOMP] = src[i * 2 + 0];
910 dst[i * 4 + GCOMP] = src[i * 2 + 1];
911 dst[i * 4 + BCOMP] = 0.0;
912 dst[i * 4 + ACOMP] = 1.0;
913 }
914 }
915
916 static void
917 get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
918 GLuint count, const GLint x[], const GLint y[],
919 void *values)
920 {
921 GLfloat *dst = values;
922 GLuint i;
923
924 for (i = 0; i < count; i++) {
925 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
926 dst[i * 4 + RCOMP] = src[0];
927 dst[i * 4 + GCOMP] = src[1];
928 dst[i * 4 + BCOMP] = 0.0;
929 dst[i * 4 + ACOMP] = 1.0;
930 }
931 }
932
933 /**
934 * This is the default software fallback for gl_renderbuffer's span
935 * access functions.
936 *
937 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
938 * are packed in the type of rb->Format, and that subsequent rows appear
939 * rb->RowStride pixels later.
940 */
941 void
942 _swrast_set_renderbuffer_accessors(struct gl_renderbuffer *rb)
943 {
944 rb->GetPointer = get_pointer_generic;
945 rb->GetRow = get_row_generic;
946
947 switch (rb->Format) {
948 case MESA_FORMAT_RGB888:
949 rb->DataType = GL_UNSIGNED_BYTE;
950 rb->GetPointer = get_pointer_ubyte3;
951 rb->GetRow = get_row_ubyte3;
952 rb->GetValues = get_values_ubyte3;
953 rb->PutRow = put_row_ubyte3;
954 rb->PutValues = put_values_ubyte3;
955 break;
956
957 case MESA_FORMAT_RGBA8888:
958 case MESA_FORMAT_RGBA8888_REV:
959 rb->DataType = GL_UNSIGNED_BYTE;
960 rb->GetValues = get_values_ubyte4;
961 rb->PutRow = put_row_ubyte4;
962 rb->PutValues = put_values_ubyte4;
963 break;
964
965 case MESA_FORMAT_R8:
966 rb->DataType = GL_UNSIGNED_BYTE;
967 rb->GetValues = get_values_r8;
968 rb->GetRow = get_row_r8;
969 rb->PutRow = put_row_generic;
970 rb->PutValues = put_values_generic;
971 break;
972
973 case MESA_FORMAT_GR88:
974 rb->DataType = GL_UNSIGNED_BYTE;
975 rb->GetValues = get_values_rg88;
976 rb->GetRow = get_row_rg88;
977 rb->PutRow = put_row_generic;
978 rb->PutValues = put_values_generic;
979 break;
980
981 case MESA_FORMAT_R16:
982 rb->DataType = GL_UNSIGNED_SHORT;
983 rb->GetValues = get_values_r16;
984 rb->GetRow = get_row_r16;
985 rb->PutRow = put_row_generic;
986 rb->PutValues = put_values_generic;
987 break;
988
989 case MESA_FORMAT_RG1616:
990 rb->DataType = GL_UNSIGNED_SHORT;
991 rb->GetValues = get_values_rg1616;
992 rb->GetRow = get_row_rg1616;
993 rb->PutRow = put_row_generic;
994 rb->PutValues = put_values_generic;
995 break;
996
997 case MESA_FORMAT_SIGNED_RGBA_16:
998 rb->DataType = GL_SHORT;
999 rb->GetValues = get_values_ushort4;
1000 rb->PutRow = put_row_ushort4;
1001 rb->PutValues = put_values_ushort4;
1002 break;
1003
1004 case MESA_FORMAT_S8:
1005 rb->DataType = GL_UNSIGNED_BYTE;
1006 rb->GetValues = get_values_ubyte;
1007 rb->PutRow = put_row_ubyte;
1008 rb->PutValues = put_values_ubyte;
1009 break;
1010
1011 case MESA_FORMAT_Z16:
1012 rb->DataType = GL_UNSIGNED_SHORT;
1013 rb->GetValues = get_values_ushort;
1014 rb->PutRow = put_row_ushort;
1015 rb->PutValues = put_values_ushort;
1016 break;
1017
1018 case MESA_FORMAT_Z32:
1019 case MESA_FORMAT_X8_Z24:
1020 case MESA_FORMAT_Z24_X8:
1021 rb->DataType = GL_UNSIGNED_INT;
1022 rb->GetValues = get_values_uint;
1023 rb->PutRow = put_row_uint;
1024 rb->PutValues = put_values_uint;
1025 break;
1026
1027 case MESA_FORMAT_Z24_S8:
1028 case MESA_FORMAT_S8_Z24:
1029 rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
1030 rb->GetValues = get_values_uint;
1031 rb->PutRow = put_row_uint;
1032 rb->PutValues = put_values_uint;
1033 break;
1034
1035 case MESA_FORMAT_RGBA_FLOAT32:
1036 rb->GetRow = get_row_generic;
1037 rb->GetValues = get_values_generic;
1038 rb->PutRow = put_row_generic;
1039 rb->PutValues = put_values_generic;
1040 break;
1041
1042 case MESA_FORMAT_INTENSITY_FLOAT32:
1043 rb->GetRow = get_row_i_float32;
1044 rb->GetValues = get_values_i_float32;
1045 rb->PutRow = put_row_generic;
1046 rb->PutValues = put_values_generic;
1047 break;
1048
1049 case MESA_FORMAT_LUMINANCE_FLOAT32:
1050 rb->GetRow = get_row_l_float32;
1051 rb->GetValues = get_values_l_float32;
1052 rb->PutRow = put_row_generic;
1053 rb->PutValues = put_values_generic;
1054 break;
1055
1056 case MESA_FORMAT_ALPHA_FLOAT32:
1057 rb->GetRow = get_row_a_float32;
1058 rb->GetValues = get_values_a_float32;
1059 rb->PutRow = put_row_a_float32;
1060 rb->PutValues = put_values_a_float32;
1061 break;
1062
1063 case MESA_FORMAT_RG_FLOAT32:
1064 rb->GetRow = get_row_rg_float32;
1065 rb->GetValues = get_values_rg_float32;
1066 rb->PutRow = put_row_generic;
1067 rb->PutValues = put_values_generic;
1068 break;
1069
1070 case MESA_FORMAT_R_FLOAT32:
1071 rb->GetRow = get_row_r_float32;
1072 rb->GetValues = get_values_r_float32;
1073 rb->PutRow = put_row_generic;
1074 rb->PutValues = put_values_generic;
1075 break;
1076
1077 default:
1078 break;
1079 }
1080 }
1081
1082 /**
1083 * This is a software fallback for the gl_renderbuffer->AllocStorage
1084 * function.
1085 * Device drivers will typically override this function for the buffers
1086 * which it manages (typically color buffers, Z and stencil).
1087 * Other buffers (like software accumulation and aux buffers) which the driver
1088 * doesn't manage can be handled with this function.
1089 *
1090 * This one multi-purpose function can allocate stencil, depth, accum, color
1091 * or color-index buffers!
1092 *
1093 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1094 * Get/PutValues functions.
1095 */
1096 static GLboolean
1097 soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
1098 GLenum internalFormat,
1099 GLuint width, GLuint height)
1100 {
1101 switch (internalFormat) {
1102 case GL_RGB:
1103 case GL_R3_G3_B2:
1104 case GL_RGB4:
1105 case GL_RGB5:
1106 case GL_RGB8:
1107 case GL_RGB10:
1108 case GL_RGB12:
1109 case GL_RGB16:
1110 rb->Format = MESA_FORMAT_RGB888;
1111 break;
1112 case GL_RGBA:
1113 case GL_RGBA2:
1114 case GL_RGBA4:
1115 case GL_RGB5_A1:
1116 case GL_RGBA8:
1117 #if 1
1118 case GL_RGB10_A2:
1119 case GL_RGBA12:
1120 #endif
1121 if (_mesa_little_endian())
1122 rb->Format = MESA_FORMAT_RGBA8888_REV;
1123 else
1124 rb->Format = MESA_FORMAT_RGBA8888;
1125 break;
1126 case GL_RGBA16:
1127 case GL_RGBA16_SNORM:
1128 /* for accum buffer */
1129 rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
1130 break;
1131 case GL_STENCIL_INDEX:
1132 case GL_STENCIL_INDEX1_EXT:
1133 case GL_STENCIL_INDEX4_EXT:
1134 case GL_STENCIL_INDEX8_EXT:
1135 case GL_STENCIL_INDEX16_EXT:
1136 rb->Format = MESA_FORMAT_S8;
1137 break;
1138 case GL_DEPTH_COMPONENT:
1139 case GL_DEPTH_COMPONENT16:
1140 rb->Format = MESA_FORMAT_Z16;
1141 break;
1142 case GL_DEPTH_COMPONENT24:
1143 rb->Format = MESA_FORMAT_X8_Z24;
1144 break;
1145 case GL_DEPTH_COMPONENT32:
1146 rb->Format = MESA_FORMAT_Z32;
1147 break;
1148 case GL_DEPTH_STENCIL_EXT:
1149 case GL_DEPTH24_STENCIL8_EXT:
1150 rb->Format = MESA_FORMAT_Z24_S8;
1151 break;
1152 default:
1153 /* unsupported format */
1154 return GL_FALSE;
1155 }
1156
1157 _swrast_set_renderbuffer_accessors(rb);
1158
1159 ASSERT(rb->DataType);
1160 ASSERT(rb->GetPointer);
1161 ASSERT(rb->GetRow);
1162 ASSERT(rb->GetValues);
1163 ASSERT(rb->PutRow);
1164 ASSERT(rb->PutValues);
1165
1166 /* free old buffer storage */
1167 if (rb->Data) {
1168 free(rb->Data);
1169 rb->Data = NULL;
1170 }
1171
1172 rb->RowStride = width;
1173
1174 if (width > 0 && height > 0) {
1175 /* allocate new buffer storage */
1176 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format));
1177
1178 if (rb->Data == NULL) {
1179 rb->Width = 0;
1180 rb->Height = 0;
1181 rb->RowStride = 0;
1182 _mesa_error(ctx, GL_OUT_OF_MEMORY,
1183 "software renderbuffer allocation (%d x %d x %d)",
1184 width, height, _mesa_get_format_bytes(rb->Format));
1185 return GL_FALSE;
1186 }
1187 }
1188
1189 rb->Width = width;
1190 rb->Height = height;
1191 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
1192
1193 if (rb->Name == 0 &&
1194 internalFormat == GL_RGBA16_SNORM &&
1195 rb->_BaseFormat == 0) {
1196 /* NOTE: This is a special case just for accumulation buffers.
1197 * This is a very limited use case- there's no snorm texturing or
1198 * rendering going on.
1199 */
1200 rb->_BaseFormat = GL_RGBA;
1201 }
1202 else {
1203 /* the internalFormat should have been error checked long ago */
1204 ASSERT(rb->_BaseFormat);
1205 }
1206
1207 return GL_TRUE;
1208 }
1209
1210
1211 void
1212 _swrast_map_soft_renderbuffer(struct gl_context *ctx,
1213 struct gl_renderbuffer *rb,
1214 GLuint x, GLuint y, GLuint w, GLuint h,
1215 GLbitfield mode,
1216 GLubyte **out_map,
1217 GLint *out_stride)
1218 {
1219 GLubyte *map = rb->Data;
1220 int cpp = _mesa_get_format_bytes(rb->Format);
1221 int stride = rb->RowStride * cpp;
1222
1223 ASSERT(rb->Data);
1224
1225 map += y * stride;
1226 map += x * cpp;
1227
1228 *out_map = map;
1229 *out_stride = stride;
1230 }
1231
1232
1233 void
1234 _swrast_unmap_soft_renderbuffer(struct gl_context *ctx,
1235 struct gl_renderbuffer *rb)
1236 {
1237 }
1238
1239
1240
1241 /**
1242 * Allocate a software-based renderbuffer. This is called via the
1243 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1244 * renderbuffer.
1245 * This would not be used for hardware-based renderbuffers.
1246 */
1247 struct gl_renderbuffer *
1248 _swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
1249 {
1250 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
1251 if (rb) {
1252 rb->AllocStorage = soft_renderbuffer_storage;
1253 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1254 * But we're doing that in the soft_renderbuffer_storage() function
1255 * instead.
1256 */
1257 }
1258 return rb;
1259 }
1260
1261
1262 /**
1263 * Add software-based color renderbuffers to the given framebuffer.
1264 * This is a helper routine for device drivers when creating a
1265 * window system framebuffer (not a user-created render/framebuffer).
1266 * Once this function is called, you can basically forget about this
1267 * renderbuffer; core Mesa will handle all the buffer management and
1268 * rendering!
1269 */
1270 static GLboolean
1271 add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
1272 GLuint rgbBits, GLuint alphaBits,
1273 GLboolean frontLeft, GLboolean backLeft,
1274 GLboolean frontRight, GLboolean backRight)
1275 {
1276 gl_buffer_index b;
1277
1278 if (rgbBits > 16 || alphaBits > 16) {
1279 _mesa_problem(ctx,
1280 "Unsupported bit depth in add_color_renderbuffers");
1281 return GL_FALSE;
1282 }
1283
1284 assert(MAX_COLOR_ATTACHMENTS >= 4);
1285
1286 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1287 struct gl_renderbuffer *rb;
1288
1289 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1290 continue;
1291 else if (b == BUFFER_BACK_LEFT && !backLeft)
1292 continue;
1293 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1294 continue;
1295 else if (b == BUFFER_BACK_RIGHT && !backRight)
1296 continue;
1297
1298 assert(fb->Attachment[b].Renderbuffer == NULL);
1299
1300 rb = _mesa_new_renderbuffer(ctx, 0);
1301 if (!rb) {
1302 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1303 return GL_FALSE;
1304 }
1305
1306 rb->InternalFormat = GL_RGBA;
1307
1308 rb->AllocStorage = soft_renderbuffer_storage;
1309 _mesa_add_renderbuffer(fb, b, rb);
1310 }
1311
1312 return GL_TRUE;
1313 }
1314
1315
1316 /**
1317 * Add a software-based depth renderbuffer to the given framebuffer.
1318 * This is a helper routine for device drivers when creating a
1319 * window system framebuffer (not a user-created render/framebuffer).
1320 * Once this function is called, you can basically forget about this
1321 * renderbuffer; core Mesa will handle all the buffer management and
1322 * rendering!
1323 */
1324 static GLboolean
1325 add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1326 GLuint depthBits)
1327 {
1328 struct gl_renderbuffer *rb;
1329
1330 if (depthBits > 32) {
1331 _mesa_problem(ctx,
1332 "Unsupported depthBits in add_depth_renderbuffer");
1333 return GL_FALSE;
1334 }
1335
1336 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1337
1338 rb = _mesa_new_renderbuffer(ctx, 0);
1339 if (!rb) {
1340 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
1341 return GL_FALSE;
1342 }
1343
1344 if (depthBits <= 16) {
1345 rb->InternalFormat = GL_DEPTH_COMPONENT16;
1346 }
1347 else if (depthBits <= 24) {
1348 rb->InternalFormat = GL_DEPTH_COMPONENT24;
1349 }
1350 else {
1351 rb->InternalFormat = GL_DEPTH_COMPONENT32;
1352 }
1353
1354 rb->AllocStorage = soft_renderbuffer_storage;
1355 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1356
1357 return GL_TRUE;
1358 }
1359
1360
1361 /**
1362 * Add a software-based stencil renderbuffer to the given framebuffer.
1363 * This is a helper routine for device drivers when creating a
1364 * window system framebuffer (not a user-created render/framebuffer).
1365 * Once this function is called, you can basically forget about this
1366 * renderbuffer; core Mesa will handle all the buffer management and
1367 * rendering!
1368 */
1369 static GLboolean
1370 add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1371 GLuint stencilBits)
1372 {
1373 struct gl_renderbuffer *rb;
1374
1375 if (stencilBits > 16) {
1376 _mesa_problem(ctx,
1377 "Unsupported stencilBits in add_stencil_renderbuffer");
1378 return GL_FALSE;
1379 }
1380
1381 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1382
1383 rb = _mesa_new_renderbuffer(ctx, 0);
1384 if (!rb) {
1385 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
1386 return GL_FALSE;
1387 }
1388
1389 assert(stencilBits <= 8);
1390 rb->InternalFormat = GL_STENCIL_INDEX8;
1391
1392 rb->AllocStorage = soft_renderbuffer_storage;
1393 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1394
1395 return GL_TRUE;
1396 }
1397
1398
1399 static GLboolean
1400 add_depth_stencil_renderbuffer(struct gl_context *ctx,
1401 struct gl_framebuffer *fb)
1402 {
1403 struct gl_renderbuffer *rb;
1404
1405 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1406 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1407
1408 rb = _mesa_new_renderbuffer(ctx, 0);
1409 if (!rb) {
1410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer");
1411 return GL_FALSE;
1412 }
1413
1414 rb->InternalFormat = GL_DEPTH_STENCIL;
1415
1416 rb->AllocStorage = soft_renderbuffer_storage;
1417 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1418 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1419
1420 return GL_TRUE;
1421 }
1422
1423
1424 /**
1425 * Add a software-based accumulation renderbuffer to the given framebuffer.
1426 * This is a helper routine for device drivers when creating a
1427 * window system framebuffer (not a user-created render/framebuffer).
1428 * Once this function is called, you can basically forget about this
1429 * renderbuffer; core Mesa will handle all the buffer management and
1430 * rendering!
1431 */
1432 static GLboolean
1433 add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1434 GLuint redBits, GLuint greenBits,
1435 GLuint blueBits, GLuint alphaBits)
1436 {
1437 struct gl_renderbuffer *rb;
1438
1439 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
1440 _mesa_problem(ctx,
1441 "Unsupported accumBits in add_accum_renderbuffer");
1442 return GL_FALSE;
1443 }
1444
1445 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
1446
1447 rb = _mesa_new_renderbuffer(ctx, 0);
1448 if (!rb) {
1449 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1450 return GL_FALSE;
1451 }
1452
1453 rb->InternalFormat = GL_RGBA16_SNORM;
1454 rb->AllocStorage = soft_renderbuffer_storage;
1455 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
1456
1457 return GL_TRUE;
1458 }
1459
1460
1461
1462 /**
1463 * Add a software-based aux renderbuffer to the given framebuffer.
1464 * This is a helper routine for device drivers when creating a
1465 * window system framebuffer (not a user-created render/framebuffer).
1466 * Once this function is called, you can basically forget about this
1467 * renderbuffer; core Mesa will handle all the buffer management and
1468 * rendering!
1469 *
1470 * NOTE: color-index aux buffers not supported.
1471 */
1472 static GLboolean
1473 add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
1474 GLuint colorBits, GLuint numBuffers)
1475 {
1476 GLuint i;
1477
1478 if (colorBits > 16) {
1479 _mesa_problem(ctx,
1480 "Unsupported colorBits in add_aux_renderbuffers");
1481 return GL_FALSE;
1482 }
1483
1484 assert(numBuffers <= MAX_AUX_BUFFERS);
1485
1486 for (i = 0; i < numBuffers; i++) {
1487 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
1488
1489 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
1490
1491 if (!rb) {
1492 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
1493 return GL_FALSE;
1494 }
1495
1496 assert (colorBits <= 8);
1497 rb->InternalFormat = GL_RGBA;
1498
1499 rb->AllocStorage = soft_renderbuffer_storage;
1500 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
1501 }
1502 return GL_TRUE;
1503 }
1504
1505
1506 /**
1507 * Create/attach software-based renderbuffers to the given framebuffer.
1508 * This is a helper routine for device drivers. Drivers can just as well
1509 * call the individual _mesa_add_*_renderbuffer() routines directly.
1510 */
1511 void
1512 _swrast_add_soft_renderbuffers(struct gl_framebuffer *fb,
1513 GLboolean color,
1514 GLboolean depth,
1515 GLboolean stencil,
1516 GLboolean accum,
1517 GLboolean alpha,
1518 GLboolean aux)
1519 {
1520 GLboolean frontLeft = GL_TRUE;
1521 GLboolean backLeft = fb->Visual.doubleBufferMode;
1522 GLboolean frontRight = fb->Visual.stereoMode;
1523 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
1524
1525 if (color) {
1526 assert(fb->Visual.redBits == fb->Visual.greenBits);
1527 assert(fb->Visual.redBits == fb->Visual.blueBits);
1528 add_color_renderbuffers(NULL, fb,
1529 fb->Visual.redBits,
1530 fb->Visual.alphaBits,
1531 frontLeft, backLeft,
1532 frontRight, backRight);
1533 }
1534
1535 #if 0
1536 /* This is pretty much for debugging purposes only since there's a perf
1537 * hit for using combined depth/stencil in swrast.
1538 */
1539 if (depth && fb->Visual.depthBits == 24 &&
1540 stencil && fb->Visual.stencilBits == 8) {
1541 /* use combined depth/stencil buffer */
1542 add_depth_stencil_renderbuffer(NULL, fb);
1543 }
1544 else
1545 #else
1546 (void) add_depth_stencil_renderbuffer;
1547 #endif
1548 {
1549 if (depth) {
1550 assert(fb->Visual.depthBits > 0);
1551 add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
1552 }
1553
1554 if (stencil) {
1555 assert(fb->Visual.stencilBits > 0);
1556 add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
1557 }
1558 }
1559
1560 if (accum) {
1561 assert(fb->Visual.accumRedBits > 0);
1562 assert(fb->Visual.accumGreenBits > 0);
1563 assert(fb->Visual.accumBlueBits > 0);
1564 add_accum_renderbuffer(NULL, fb,
1565 fb->Visual.accumRedBits,
1566 fb->Visual.accumGreenBits,
1567 fb->Visual.accumBlueBits,
1568 fb->Visual.accumAlphaBits);
1569 }
1570
1571 if (aux) {
1572 assert(fb->Visual.numAuxBuffers > 0);
1573 add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
1574 fb->Visual.numAuxBuffers);
1575 }
1576
1577 #if 0
1578 if (multisample) {
1579 /* maybe someday */
1580 }
1581 #endif
1582 }