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