mesa: make some renderbuffer functions static
[mesa.git] / src / mesa / main / renderbuffer.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
30 *
31 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
32 * color channels. For example, Mesa may use 32-bit/float color channels
33 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
34 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
35 */
36
37
38 #include "glheader.h"
39 #include "imports.h"
40 #include "context.h"
41 #include "fbobject.h"
42 #include "formats.h"
43 #include "mtypes.h"
44 #include "renderbuffer.h"
45
46
47 /*
48 * Routines for get/put values in common buffer formats follow.
49 */
50
51 /* Returns a bytes per pixel of the DataType in the get/put span
52 * functions for at least a subset of the available combinations a
53 * renderbuffer can have.
54 *
55 * It would be nice to see gl_renderbuffer start talking about a
56 * gl_format instead of a GLenum DataType.
57 */
58 static int
59 get_datatype_bytes(struct gl_renderbuffer *rb)
60 {
61 int component_size;
62
63 switch (rb->DataType) {
64 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
65 component_size = 8;
66 break;
67 case GL_FLOAT:
68 case GL_UNSIGNED_INT:
69 case GL_UNSIGNED_INT_24_8_EXT:
70 component_size = 4;
71 break;
72 case GL_UNSIGNED_SHORT:
73 component_size = 2;
74 break;
75 case GL_UNSIGNED_BYTE:
76 component_size = 1;
77 break;
78 default:
79 component_size = 1;
80 assert(0);
81 }
82
83 switch (rb->_BaseFormat) {
84 case GL_DEPTH_COMPONENT:
85 case GL_DEPTH_STENCIL:
86 return component_size;
87 default:
88 return 4 * component_size;
89 }
90 }
91
92 /* This is commonly used by most of the accessors. */
93 static void *
94 get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
95 GLint x, GLint y)
96 {
97 if (!rb->Data)
98 return NULL;
99
100 return ((char *) rb->Data +
101 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format));
102 }
103
104 /* GetRow() implementation for formats where DataType matches the rb->Format.
105 */
106 static void
107 get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
108 GLuint count, GLint x, GLint y, void *values)
109 {
110 void *src = rb->GetPointer(ctx, rb, x, y);
111 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format));
112 }
113
114 /* Only used for float textures currently, but might also be used for
115 * RGBA8888, RGBA16, etc.
116 */
117 static void
118 get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
119 GLuint count, const GLint x[], const GLint y[], void *values)
120 {
121 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
122 GLuint i;
123
124 for (i = 0; i < count; i++) {
125 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]);
126 char *dst = (char *) values + i * format_bytes;
127 memcpy(dst, src, format_bytes);
128 }
129 }
130
131 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
132 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
133 * storing those initial components of the value per pixel into the
134 * destination.
135 */
136 static void
137 put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
138 GLuint count, GLint x, GLint y,
139 const void *values, const GLubyte *mask)
140 {
141 void *row = rb->GetPointer(ctx, rb, x, y);
142 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
143 int datatype_bytes = get_datatype_bytes(rb);
144 unsigned int i;
145
146 if (mask) {
147 for (i = 0; i < count; i++) {
148 char *dst = (char *) row + i * format_bytes;
149 const char *src = (const char *) values + i * datatype_bytes;
150
151 if (mask[i]) {
152 memcpy(dst, src, format_bytes);
153 }
154 }
155 }
156 else {
157 for (i = 0; i < count; i++) {
158 char *dst = (char *) row + i * format_bytes;
159 const char *src = (const char *) values + i * datatype_bytes;
160 memcpy(dst, src, format_bytes);
161 }
162 }
163 }
164
165 static void
166 put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
167 GLuint count, GLint x, GLint y,
168 const void *value, const GLubyte *mask)
169 {
170 void *row = rb->GetPointer(ctx, rb, x, y);
171 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
172 unsigned int i;
173
174 if (mask) {
175 for (i = 0; i < count; i++) {
176 char *dst = (char *) row + i * format_bytes;
177 if (mask[i]) {
178 memcpy(dst, value, format_bytes);
179 }
180 }
181 }
182 else {
183 for (i = 0; i < count; i++) {
184 char *dst = (char *) row + i * format_bytes;
185 memcpy(dst, value, format_bytes);
186 }
187 }
188 }
189
190
191 static void
192 put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
193 GLuint count, const GLint x[], const GLint y[],
194 const void *values, const GLubyte *mask)
195 {
196 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
197 int datatype_bytes = get_datatype_bytes(rb);
198 unsigned int i;
199
200 for (i = 0; i < count; i++) {
201 if (!mask || mask[i]) {
202 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
203 const char *src = (const char *) values + i * datatype_bytes;
204 memcpy(dst, src, format_bytes);
205 }
206 }
207 }
208
209
210 static void
211 put_mono_values_generic(struct gl_context *ctx,
212 struct gl_renderbuffer *rb,
213 GLuint count, const GLint x[], const GLint y[],
214 const void *value, const GLubyte *mask)
215 {
216 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
217 unsigned int i;
218
219 for (i = 0; i < count; i++) {
220 if (!mask || mask[i]) {
221 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
222 memcpy(dst, value, format_bytes);
223 }
224 }
225 }
226
227 /**********************************************************************
228 * Functions for buffers of 1 X GLubyte values.
229 * Typically stencil.
230 */
231
232 static void
233 get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
234 const GLint x[], const GLint y[], void *values)
235 {
236 GLubyte *dst = (GLubyte *) values;
237 GLuint i;
238 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
239 for (i = 0; i < count; i++) {
240 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
241 dst[i] = *src;
242 }
243 }
244
245
246 static void
247 put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
248 GLint x, GLint y, const void *values, const GLubyte *mask)
249 {
250 const GLubyte *src = (const GLubyte *) values;
251 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
252 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
253 if (mask) {
254 GLuint i;
255 for (i = 0; i < count; i++) {
256 if (mask[i]) {
257 dst[i] = src[i];
258 }
259 }
260 }
261 else {
262 memcpy(dst, values, count * sizeof(GLubyte));
263 }
264 }
265
266
267 static void
268 put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
269 GLint x, GLint y, const void *value, const GLubyte *mask)
270 {
271 const GLubyte val = *((const GLubyte *) value);
272 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
273 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
274 if (mask) {
275 GLuint i;
276 for (i = 0; i < count; i++) {
277 if (mask[i]) {
278 dst[i] = val;
279 }
280 }
281 }
282 else {
283 GLuint i;
284 for (i = 0; i < count; i++) {
285 dst[i] = val;
286 }
287 }
288 }
289
290
291 static void
292 put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
293 const GLint x[], const GLint y[],
294 const void *values, const GLubyte *mask)
295 {
296 const GLubyte *src = (const GLubyte *) values;
297 GLuint i;
298 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
299 for (i = 0; i < count; i++) {
300 if (!mask || mask[i]) {
301 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
302 *dst = src[i];
303 }
304 }
305 }
306
307
308 static void
309 put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
310 const GLint x[], const GLint y[],
311 const void *value, const GLubyte *mask)
312 {
313 const GLubyte val = *((const GLubyte *) value);
314 GLuint i;
315 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
316 for (i = 0; i < count; i++) {
317 if (!mask || mask[i]) {
318 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
319 *dst = val;
320 }
321 }
322 }
323
324
325 /**********************************************************************
326 * Functions for buffers of 1 X GLushort values.
327 * Typically depth/Z.
328 */
329
330 static void
331 get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
332 const GLint x[], const GLint y[], void *values)
333 {
334 GLushort *dst = (GLushort *) values;
335 GLuint i;
336 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
337 for (i = 0; i < count; i++) {
338 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
339 dst[i] = *src;
340 }
341 }
342
343
344 static void
345 put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
346 GLint x, GLint y, const void *values, const GLubyte *mask)
347 {
348 const GLushort *src = (const GLushort *) values;
349 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
350 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
351 if (mask) {
352 GLuint i;
353 for (i = 0; i < count; i++) {
354 if (mask[i]) {
355 dst[i] = src[i];
356 }
357 }
358 }
359 else {
360 memcpy(dst, src, count * sizeof(GLushort));
361 }
362 }
363
364
365 static void
366 put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
367 GLint x, GLint y, const void *value, const GLubyte *mask)
368 {
369 const GLushort val = *((const GLushort *) value);
370 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
371 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
372 if (mask) {
373 GLuint i;
374 for (i = 0; i < count; i++) {
375 if (mask[i]) {
376 dst[i] = val;
377 }
378 }
379 }
380 else {
381 GLuint i;
382 for (i = 0; i < count; i++) {
383 dst[i] = val;
384 }
385 }
386 }
387
388
389 static void
390 put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
391 const GLint x[], const GLint y[], const void *values,
392 const GLubyte *mask)
393 {
394 const GLushort *src = (const GLushort *) values;
395 GLuint i;
396 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
397 for (i = 0; i < count; i++) {
398 if (!mask || mask[i]) {
399 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
400 *dst = src[i];
401 }
402 }
403 }
404
405
406 static void
407 put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb,
408 GLuint count, const GLint x[], const GLint y[],
409 const void *value, const GLubyte *mask)
410 {
411 const GLushort val = *((const GLushort *) value);
412 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
413 if (mask) {
414 GLuint i;
415 for (i = 0; i < count; i++) {
416 if (mask[i]) {
417 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
418 *dst = val;
419 }
420 }
421 }
422 else {
423 GLuint i;
424 for (i = 0; i < count; i++) {
425 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
426 *dst = val;
427 }
428 }
429 }
430
431
432 /**********************************************************************
433 * Functions for buffers of 1 X GLuint values.
434 * Typically depth/Z or color index.
435 */
436
437 static void
438 get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
439 const GLint x[], const GLint y[], void *values)
440 {
441 GLuint *dst = (GLuint *) values;
442 GLuint i;
443 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
444 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
445 for (i = 0; i < count; i++) {
446 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
447 dst[i] = *src;
448 }
449 }
450
451
452 static void
453 put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
454 GLint x, GLint y, const void *values, const GLubyte *mask)
455 {
456 const GLuint *src = (const GLuint *) values;
457 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
458 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
459 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
460 if (mask) {
461 GLuint i;
462 for (i = 0; i < count; i++) {
463 if (mask[i]) {
464 dst[i] = src[i];
465 }
466 }
467 }
468 else {
469 memcpy(dst, src, count * sizeof(GLuint));
470 }
471 }
472
473
474 static void
475 put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
476 GLint x, GLint y, const void *value, const GLubyte *mask)
477 {
478 const GLuint val = *((const GLuint *) value);
479 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
480 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
481 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
482 if (mask) {
483 GLuint i;
484 for (i = 0; i < count; i++) {
485 if (mask[i]) {
486 dst[i] = val;
487 }
488 }
489 }
490 else {
491 GLuint i;
492 for (i = 0; i < count; i++) {
493 dst[i] = val;
494 }
495 }
496 }
497
498
499 static void
500 put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
501 const GLint x[], const GLint y[], const void *values,
502 const GLubyte *mask)
503 {
504 const GLuint *src = (const GLuint *) values;
505 GLuint i;
506 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
507 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
508 for (i = 0; i < count; i++) {
509 if (!mask || mask[i]) {
510 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
511 *dst = src[i];
512 }
513 }
514 }
515
516
517 static void
518 put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
519 const GLint x[], const GLint y[], const void *value,
520 const GLubyte *mask)
521 {
522 const GLuint val = *((const GLuint *) value);
523 GLuint i;
524 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
525 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
526 for (i = 0; i < count; i++) {
527 if (!mask || mask[i]) {
528 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
529 *dst = val;
530 }
531 }
532 }
533
534
535 /**********************************************************************
536 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
537 * Typically color buffers.
538 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
539 * alpha values and return 255 for outgoing alpha values.
540 */
541
542 static void *
543 get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
544 GLint x, GLint y)
545 {
546 ASSERT(rb->Format == MESA_FORMAT_RGB888);
547 /* No direct access since this buffer is RGB but caller will be
548 * treating it as if it were RGBA.
549 */
550 return NULL;
551 }
552
553
554 static void
555 get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
556 GLint x, GLint y, void *values)
557 {
558 const GLubyte *src = ((const GLubyte *) rb->Data) +
559 3 * (y * rb->RowStride + x);
560 GLubyte *dst = (GLubyte *) values;
561 GLuint i;
562 ASSERT(rb->Format == MESA_FORMAT_RGB888);
563 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
564 for (i = 0; i < count; i++) {
565 dst[i * 4 + 0] = src[i * 3 + 0];
566 dst[i * 4 + 1] = src[i * 3 + 1];
567 dst[i * 4 + 2] = src[i * 3 + 2];
568 dst[i * 4 + 3] = 255;
569 }
570 }
571
572
573 static void
574 get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
575 const GLint x[], const GLint y[], void *values)
576 {
577 GLubyte *dst = (GLubyte *) values;
578 GLuint i;
579 ASSERT(rb->Format == MESA_FORMAT_RGB888);
580 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
581 for (i = 0; i < count; i++) {
582 const GLubyte *src
583 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
584 dst[i * 4 + 0] = src[0];
585 dst[i * 4 + 1] = src[1];
586 dst[i * 4 + 2] = src[2];
587 dst[i * 4 + 3] = 255;
588 }
589 }
590
591
592 static void
593 put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
594 GLint x, GLint y, const void *values, const GLubyte *mask)
595 {
596 /* note: incoming values are RGB+A! */
597 const GLubyte *src = (const GLubyte *) values;
598 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
599 GLuint i;
600 ASSERT(rb->Format == MESA_FORMAT_RGB888);
601 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
602 for (i = 0; i < count; i++) {
603 if (!mask || mask[i]) {
604 dst[i * 3 + 0] = src[i * 4 + 0];
605 dst[i * 3 + 1] = src[i * 4 + 1];
606 dst[i * 3 + 2] = src[i * 4 + 2];
607 }
608 }
609 }
610
611
612 static void
613 put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
614 GLint x, GLint y, const void *values, const GLubyte *mask)
615 {
616 /* note: incoming values are RGB+A! */
617 const GLubyte *src = (const GLubyte *) values;
618 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
619 GLuint i;
620 ASSERT(rb->Format == MESA_FORMAT_RGB888);
621 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
622 for (i = 0; i < count; i++) {
623 if (!mask || mask[i]) {
624 dst[i * 3 + 0] = src[i * 3 + 0];
625 dst[i * 3 + 1] = src[i * 3 + 1];
626 dst[i * 3 + 2] = src[i * 3 + 2];
627 }
628 }
629 }
630
631
632 static void
633 put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
634 GLint x, GLint y, const void *value, const GLubyte *mask)
635 {
636 /* note: incoming value is RGB+A! */
637 const GLubyte val0 = ((const GLubyte *) value)[0];
638 const GLubyte val1 = ((const GLubyte *) value)[1];
639 const GLubyte val2 = ((const GLubyte *) value)[2];
640 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
641 ASSERT(rb->Format == MESA_FORMAT_RGB888);
642 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
643 if (!mask && val0 == val1 && val1 == val2) {
644 /* optimized case */
645 memset(dst, val0, 3 * count);
646 }
647 else {
648 GLuint i;
649 for (i = 0; i < count; i++) {
650 if (!mask || mask[i]) {
651 dst[i * 3 + 0] = val0;
652 dst[i * 3 + 1] = val1;
653 dst[i * 3 + 2] = val2;
654 }
655 }
656 }
657 }
658
659
660 static void
661 put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
662 const GLint x[], const GLint y[], const void *values,
663 const GLubyte *mask)
664 {
665 /* note: incoming values are RGB+A! */
666 const GLubyte *src = (const GLubyte *) values;
667 GLuint i;
668 ASSERT(rb->Format == MESA_FORMAT_RGB888);
669 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
670 for (i = 0; i < count; i++) {
671 if (!mask || mask[i]) {
672 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
673 dst[0] = src[i * 4 + 0];
674 dst[1] = src[i * 4 + 1];
675 dst[2] = src[i * 4 + 2];
676 }
677 }
678 }
679
680
681 static void
682 put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
683 GLuint count, const GLint x[], const GLint y[],
684 const void *value, const GLubyte *mask)
685 {
686 /* note: incoming value is RGB+A! */
687 const GLubyte val0 = ((const GLubyte *) value)[0];
688 const GLubyte val1 = ((const GLubyte *) value)[1];
689 const GLubyte val2 = ((const GLubyte *) value)[2];
690 GLuint i;
691 ASSERT(rb->Format == MESA_FORMAT_RGB888);
692 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
693 for (i = 0; i < count; i++) {
694 if (!mask || mask[i]) {
695 GLubyte *dst = ((GLubyte *) rb->Data) +
696 3 * (y[i] * rb->RowStride + x[i]);
697 dst[0] = val0;
698 dst[1] = val1;
699 dst[2] = val2;
700 }
701 }
702 }
703
704
705 /**********************************************************************
706 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
707 * Typically color buffers.
708 */
709
710 static void
711 get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
712 const GLint x[], const GLint y[], void *values)
713 {
714 /* treat 4*GLubyte as 1*GLuint */
715 GLuint *dst = (GLuint *) values;
716 GLuint i;
717 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
718 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
719 rb->Format == MESA_FORMAT_RGBA8888_REV);
720 for (i = 0; i < count; i++) {
721 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
722 dst[i] = *src;
723 }
724 }
725
726
727 static void
728 put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
729 GLint x, GLint y, const void *values, const GLubyte *mask)
730 {
731 /* treat 4*GLubyte as 1*GLuint */
732 const GLuint *src = (const GLuint *) values;
733 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
734 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
735 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
736 rb->Format == MESA_FORMAT_RGBA8888_REV);
737 if (mask) {
738 GLuint i;
739 for (i = 0; i < count; i++) {
740 if (mask[i]) {
741 dst[i] = src[i];
742 }
743 }
744 }
745 else {
746 memcpy(dst, src, 4 * count * sizeof(GLubyte));
747 }
748 }
749
750
751 static void
752 put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
753 GLint x, GLint y, const void *values, const GLubyte *mask)
754 {
755 /* Store RGB values in RGBA buffer */
756 const GLubyte *src = (const GLubyte *) values;
757 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x);
758 GLuint i;
759 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
760 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
761 rb->Format == MESA_FORMAT_RGBA8888_REV);
762 for (i = 0; i < count; i++) {
763 if (!mask || mask[i]) {
764 dst[i * 4 + 0] = src[i * 3 + 0];
765 dst[i * 4 + 1] = src[i * 3 + 1];
766 dst[i * 4 + 2] = src[i * 3 + 2];
767 dst[i * 4 + 3] = 0xff;
768 }
769 }
770 }
771
772
773 static void
774 put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
775 GLint x, GLint y, const void *value, const GLubyte *mask)
776 {
777 /* treat 4*GLubyte as 1*GLuint */
778 const GLuint val = *((const GLuint *) value);
779 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
780 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
781 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
782 rb->Format == MESA_FORMAT_RGBA8888_REV);
783 if (!mask && val == 0) {
784 /* common case */
785 memset(dst, 0, count * 4 * sizeof(GLubyte));
786 }
787 else {
788 /* general case */
789 if (mask) {
790 GLuint i;
791 for (i = 0; i < count; i++) {
792 if (mask[i]) {
793 dst[i] = val;
794 }
795 }
796 }
797 else {
798 GLuint i;
799 for (i = 0; i < count; i++) {
800 dst[i] = val;
801 }
802 }
803 }
804 }
805
806
807 static void
808 put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
809 const GLint x[], const GLint y[], const void *values,
810 const GLubyte *mask)
811 {
812 /* treat 4*GLubyte as 1*GLuint */
813 const GLuint *src = (const GLuint *) values;
814 GLuint i;
815 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
816 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
817 rb->Format == MESA_FORMAT_RGBA8888_REV);
818 for (i = 0; i < count; i++) {
819 if (!mask || mask[i]) {
820 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
821 *dst = src[i];
822 }
823 }
824 }
825
826
827 static void
828 put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb,
829 GLuint count, const GLint x[], const GLint y[],
830 const void *value, const GLubyte *mask)
831 {
832 /* treat 4*GLubyte as 1*GLuint */
833 const GLuint val = *((const GLuint *) value);
834 GLuint i;
835 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
836 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
837 rb->Format == MESA_FORMAT_RGBA8888_REV);
838 for (i = 0; i < count; i++) {
839 if (!mask || mask[i]) {
840 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
841 *dst = val;
842 }
843 }
844 }
845
846
847 /**********************************************************************
848 * Functions for buffers of 4 X GLushort (or GLshort) values.
849 * Typically accum buffer.
850 */
851
852 static void
853 get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
854 const GLint x[], const GLint y[], void *values)
855 {
856 GLushort *dst = (GLushort *) values;
857 GLuint i;
858 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
859 for (i = 0; i < count; i++) {
860 const GLushort *src
861 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]);
862 dst[i] = *src;
863 }
864 }
865
866
867 static void
868 put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
869 GLint x, GLint y, const void *values, const GLubyte *mask)
870 {
871 const GLushort *src = (const GLushort *) values;
872 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
873 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
874 if (mask) {
875 GLuint i;
876 for (i = 0; i < count; i++) {
877 if (mask[i]) {
878 dst[i * 4 + 0] = src[i * 4 + 0];
879 dst[i * 4 + 1] = src[i * 4 + 1];
880 dst[i * 4 + 2] = src[i * 4 + 2];
881 dst[i * 4 + 3] = src[i * 4 + 3];
882 }
883 }
884 }
885 else {
886 memcpy(dst, src, 4 * count * sizeof(GLushort));
887 }
888 }
889
890
891 static void
892 put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
893 GLint x, GLint y, const void *values, const GLubyte *mask)
894 {
895 /* Put RGB values in RGBA buffer */
896 const GLushort *src = (const GLushort *) values;
897 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
898 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
899 if (mask) {
900 GLuint i;
901 for (i = 0; i < count; i++) {
902 if (mask[i]) {
903 dst[i * 4 + 0] = src[i * 3 + 0];
904 dst[i * 4 + 1] = src[i * 3 + 1];
905 dst[i * 4 + 2] = src[i * 3 + 2];
906 dst[i * 4 + 3] = 0xffff;
907 }
908 }
909 }
910 else {
911 memcpy(dst, src, 4 * count * sizeof(GLushort));
912 }
913 }
914
915
916 static void
917 put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
918 GLint x, GLint y, const void *value, const GLubyte *mask)
919 {
920 const GLushort val0 = ((const GLushort *) value)[0];
921 const GLushort val1 = ((const GLushort *) value)[1];
922 const GLushort val2 = ((const GLushort *) value)[2];
923 const GLushort val3 = ((const GLushort *) value)[3];
924 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
925 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
926 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
927 /* common case for clearing accum buffer */
928 memset(dst, 0, count * 4 * sizeof(GLushort));
929 }
930 else {
931 GLuint i;
932 for (i = 0; i < count; i++) {
933 if (!mask || mask[i]) {
934 dst[i * 4 + 0] = val0;
935 dst[i * 4 + 1] = val1;
936 dst[i * 4 + 2] = val2;
937 dst[i * 4 + 3] = val3;
938 }
939 }
940 }
941 }
942
943
944 static void
945 put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
946 const GLint x[], const GLint y[], const void *values,
947 const GLubyte *mask)
948 {
949 const GLushort *src = (const GLushort *) values;
950 GLuint i;
951 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
952 for (i = 0; i < count; i++) {
953 if (!mask || mask[i]) {
954 GLushort *dst =
955 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]);
956 dst[0] = src[i * 4 + 0];
957 dst[1] = src[i * 4 + 1];
958 dst[2] = src[i * 4 + 2];
959 dst[3] = src[i * 4 + 3];
960 }
961 }
962 }
963
964
965 static void
966 put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb,
967 GLuint count, const GLint x[], const GLint y[],
968 const void *value, const GLubyte *mask)
969 {
970 const GLushort val0 = ((const GLushort *) value)[0];
971 const GLushort val1 = ((const GLushort *) value)[1];
972 const GLushort val2 = ((const GLushort *) value)[2];
973 const GLushort val3 = ((const GLushort *) value)[3];
974 GLuint i;
975 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
976 for (i = 0; i < count; i++) {
977 if (!mask || mask[i]) {
978 GLushort *dst = ((GLushort *) rb->Data) +
979 4 * (y[i] * rb->RowStride + x[i]);
980 dst[0] = val0;
981 dst[1] = val1;
982 dst[2] = val2;
983 dst[3] = val3;
984 }
985 }
986 }
987
988 /**********************************************************************
989 * Functions for MESA_FORMAT_R8.
990 */
991 static void
992 get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
993 GLint x, GLint y, void *values)
994 {
995 const GLubyte *src = rb->GetPointer(ctx, rb, x, y);
996 GLuint *dst = values;
997 GLuint i;
998
999 for (i = 0; i < count; i++) {
1000 dst[i] = 0xff000000 | src[i];
1001 }
1002 }
1003
1004 static void
1005 get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1006 const GLint x[], const GLint y[], void *values)
1007 {
1008 GLuint *dst = (GLuint *) values;
1009 GLuint i;
1010
1011 for (i = 0; i < count; i++) {
1012 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1013 dst[i] = 0xff000000 | *src;
1014 }
1015 }
1016
1017 /**********************************************************************
1018 * Functions for MESA_FORMAT_GR88.
1019 */
1020 static void
1021 get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1022 GLint x, GLint y, void *values)
1023 {
1024 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1025 GLuint *dst = values;
1026 GLuint i;
1027
1028 for (i = 0; i < count; i++) {
1029 dst[i] = 0xff000000 | src[i];
1030 }
1031 }
1032
1033 static void
1034 get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb,
1035 GLuint count, const GLint x[], const GLint y[], void *values)
1036 {
1037 GLuint *dst = (GLuint *) values;
1038 GLuint i;
1039
1040 for (i = 0; i < count; i++) {
1041 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1042 dst[i] = 0xff000000 | *src;
1043 }
1044 }
1045
1046 /**********************************************************************
1047 * Functions for MESA_FORMAT_R16.
1048 */
1049 static void
1050 get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1051 GLint x, GLint y, void *values)
1052 {
1053 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1054 GLushort *dst = values;
1055 GLuint i;
1056
1057 for (i = 0; i < count; i++) {
1058 dst[i * 4 + RCOMP] = src[i];
1059 dst[i * 4 + GCOMP] = 0;
1060 dst[i * 4 + BCOMP] = 0;
1061 dst[i * 4 + ACOMP] = 0xffff;
1062 }
1063 }
1064
1065 static void
1066 get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1067 const GLint x[], const GLint y[], void *values)
1068 {
1069 GLushort *dst = values;
1070 GLuint i;
1071
1072 for (i = 0; i < count; i++) {
1073 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1074 dst[i * 4 + RCOMP] = *src;
1075 dst[i * 4 + GCOMP] = 0;
1076 dst[i * 4 + BCOMP] = 0;
1077 dst[i * 4 + ACOMP] = 0xffff;
1078 }
1079 }
1080
1081 /**********************************************************************
1082 * Functions for MESA_FORMAT_RG1616.
1083 */
1084 static void
1085 get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
1086 GLint x, GLint y, void *values)
1087 {
1088 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
1089 GLushort *dst = values;
1090 GLuint i;
1091
1092 for (i = 0; i < count; i++) {
1093 dst[i * 4 + RCOMP] = src[i * 2];
1094 dst[i * 4 + GCOMP] = src[i * 2 + 1];
1095 dst[i * 4 + BCOMP] = 0;
1096 dst[i * 4 + ACOMP] = 0xffff;
1097 }
1098 }
1099
1100 static void
1101 get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb,
1102 GLuint count, const GLint x[], const GLint y[], void *values)
1103 {
1104 GLushort *dst = values;
1105 GLuint i;
1106
1107 for (i = 0; i < count; i++) {
1108 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1109 dst[i * 4 + RCOMP] = src[0];
1110 dst[i * 4 + GCOMP] = src[1];
1111 dst[i * 4 + BCOMP] = 0;
1112 dst[i * 4 + ACOMP] = 0xffff;
1113 }
1114 }
1115
1116 /**********************************************************************
1117 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
1118 */
1119 static void
1120 get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1121 GLuint count, GLint x, GLint y, void *values)
1122 {
1123 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1124 GLfloat *dst = values;
1125 GLuint i;
1126
1127 for (i = 0; i < count; i++) {
1128 dst[i * 4 + RCOMP] =
1129 dst[i * 4 + GCOMP] =
1130 dst[i * 4 + BCOMP] =
1131 dst[i * 4 + ACOMP] = src[i];
1132 }
1133 }
1134
1135 static void
1136 get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1137 GLuint count, const GLint x[], const GLint y[],
1138 void *values)
1139 {
1140 GLfloat *dst = values;
1141 GLuint i;
1142
1143 for (i = 0; i < count; i++) {
1144 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1145 dst[i * 4 + RCOMP] =
1146 dst[i * 4 + GCOMP] =
1147 dst[i * 4 + BCOMP] =
1148 dst[i * 4 + ACOMP] = src[0];
1149 }
1150 }
1151
1152 /**********************************************************************
1153 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
1154 */
1155 static void
1156 get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1157 GLuint count, GLint x, GLint y, void *values)
1158 {
1159 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1160 GLfloat *dst = values;
1161 GLuint i;
1162
1163 for (i = 0; i < count; i++) {
1164 dst[i * 4 + RCOMP] =
1165 dst[i * 4 + GCOMP] =
1166 dst[i * 4 + BCOMP] = src[i];
1167 dst[i * 4 + ACOMP] = 1.0;
1168 }
1169 }
1170
1171 static void
1172 get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1173 GLuint count, const GLint x[], const GLint y[],
1174 void *values)
1175 {
1176 GLfloat *dst = values;
1177 GLuint i;
1178
1179 for (i = 0; i < count; i++) {
1180 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1181 dst[i * 4 + RCOMP] =
1182 dst[i * 4 + GCOMP] =
1183 dst[i * 4 + BCOMP] = src[0];
1184 dst[i * 4 + ACOMP] = 1.0;
1185 }
1186 }
1187
1188 /**********************************************************************
1189 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
1190 */
1191 static void
1192 get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1193 GLuint count, GLint x, GLint y, void *values)
1194 {
1195 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1196 GLfloat *dst = values;
1197 GLuint i;
1198
1199 for (i = 0; i < count; i++) {
1200 dst[i * 4 + RCOMP] = 0.0;
1201 dst[i * 4 + GCOMP] = 0.0;
1202 dst[i * 4 + BCOMP] = 0.0;
1203 dst[i * 4 + ACOMP] = src[i];
1204 }
1205 }
1206
1207 static void
1208 get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1209 GLuint count, const GLint x[], const GLint y[],
1210 void *values)
1211 {
1212 GLfloat *dst = values;
1213 GLuint i;
1214
1215 for (i = 0; i < count; i++) {
1216 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1217 dst[i * 4 + RCOMP] = 0.0;
1218 dst[i * 4 + GCOMP] = 0.0;
1219 dst[i * 4 + BCOMP] = 0.0;
1220 dst[i * 4 + ACOMP] = src[0];
1221 }
1222 }
1223
1224 static void
1225 put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1226 GLuint count, GLint x, GLint y,
1227 const void *values, const GLubyte *mask)
1228 {
1229 float *dst = rb->GetPointer(ctx, rb, x, y);
1230 const float *src = values;
1231 unsigned int i;
1232
1233 if (mask) {
1234 for (i = 0; i < count; i++) {
1235 if (mask[i]) {
1236 dst[i] = src[i * 4 + ACOMP];
1237 }
1238 }
1239 }
1240 else {
1241 for (i = 0; i < count; i++) {
1242 dst[i] = src[i * 4 + ACOMP];
1243 }
1244 }
1245 }
1246
1247 static void
1248 put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1249 GLuint count, GLint x, GLint y,
1250 const void *value, const GLubyte *mask)
1251 {
1252 float *dst = rb->GetPointer(ctx, rb, x, y);
1253 const float *src = value;
1254 unsigned int i;
1255
1256 if (mask) {
1257 for (i = 0; i < count; i++) {
1258 if (mask[i]) {
1259 dst[i] = src[ACOMP];
1260 }
1261 }
1262 }
1263 else {
1264 for (i = 0; i < count; i++) {
1265 dst[i] = src[ACOMP];
1266 }
1267 }
1268 }
1269
1270 static void
1271 put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1272 GLuint count, const GLint x[], const GLint y[],
1273 const void *values, const GLubyte *mask)
1274 {
1275 const float *src = values;
1276 unsigned int i;
1277
1278 for (i = 0; i < count; i++) {
1279 if (!mask || mask[i]) {
1280 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
1281
1282 *dst = src[i * 4 + ACOMP];
1283 }
1284 }
1285 }
1286
1287 static void
1288 put_mono_values_a_float32(struct gl_context *ctx,
1289 struct gl_renderbuffer *rb,
1290 GLuint count, const GLint x[], const GLint y[],
1291 const void *value, const GLubyte *mask)
1292 {
1293 const float *src = value;
1294 unsigned int i;
1295
1296 for (i = 0; i < count; i++) {
1297 if (!mask || mask[i]) {
1298 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
1299 *dst = src[ACOMP];
1300 }
1301 }
1302 }
1303
1304 /**********************************************************************
1305 * Functions for MESA_FORMAT_R_FLOAT32.
1306 */
1307 static void
1308 get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1309 GLuint count, GLint x, GLint y, void *values)
1310 {
1311 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1312 GLfloat *dst = values;
1313 GLuint i;
1314
1315 for (i = 0; i < count; i++) {
1316 dst[i * 4 + RCOMP] = src[i];
1317 dst[i * 4 + GCOMP] = 0.0;
1318 dst[i * 4 + BCOMP] = 0.0;
1319 dst[i * 4 + ACOMP] = 1.0;
1320 }
1321 }
1322
1323 static void
1324 get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1325 GLuint count, const GLint x[], const GLint y[],
1326 void *values)
1327 {
1328 GLfloat *dst = values;
1329 GLuint i;
1330
1331 for (i = 0; i < count; i++) {
1332 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1333 dst[i * 4 + RCOMP] = src[0];
1334 dst[i * 4 + GCOMP] = 0.0;
1335 dst[i * 4 + BCOMP] = 0.0;
1336 dst[i * 4 + ACOMP] = 1.0;
1337 }
1338 }
1339
1340 /**********************************************************************
1341 * Functions for MESA_FORMAT_RG_FLOAT32.
1342 */
1343 static void
1344 get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1345 GLuint count, GLint x, GLint y, void *values)
1346 {
1347 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
1348 GLfloat *dst = values;
1349 GLuint i;
1350
1351 for (i = 0; i < count; i++) {
1352 dst[i * 4 + RCOMP] = src[i * 2 + 0];
1353 dst[i * 4 + GCOMP] = src[i * 2 + 1];
1354 dst[i * 4 + BCOMP] = 0.0;
1355 dst[i * 4 + ACOMP] = 1.0;
1356 }
1357 }
1358
1359 static void
1360 get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
1361 GLuint count, const GLint x[], const GLint y[],
1362 void *values)
1363 {
1364 GLfloat *dst = values;
1365 GLuint i;
1366
1367 for (i = 0; i < count; i++) {
1368 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
1369 dst[i * 4 + RCOMP] = src[0];
1370 dst[i * 4 + GCOMP] = src[1];
1371 dst[i * 4 + BCOMP] = 0.0;
1372 dst[i * 4 + ACOMP] = 1.0;
1373 }
1374 }
1375
1376 /**
1377 * This is the default software fallback for gl_renderbuffer's span
1378 * access functions.
1379 *
1380 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1381 * are packed in the type of rb->Format, and that subsequent rows appear
1382 * rb->RowStride pixels later.
1383 */
1384 void
1385 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb)
1386 {
1387 rb->GetPointer = get_pointer_generic;
1388 rb->GetRow = get_row_generic;
1389
1390 switch (rb->Format) {
1391 case MESA_FORMAT_RGB888:
1392 rb->DataType = GL_UNSIGNED_BYTE;
1393 rb->GetPointer = get_pointer_ubyte3;
1394 rb->GetRow = get_row_ubyte3;
1395 rb->GetValues = get_values_ubyte3;
1396 rb->PutRow = put_row_ubyte3;
1397 rb->PutRowRGB = put_row_rgb_ubyte3;
1398 rb->PutMonoRow = put_mono_row_ubyte3;
1399 rb->PutValues = put_values_ubyte3;
1400 rb->PutMonoValues = put_mono_values_ubyte3;
1401 break;
1402
1403 case MESA_FORMAT_RGBA8888:
1404 case MESA_FORMAT_RGBA8888_REV:
1405 rb->DataType = GL_UNSIGNED_BYTE;
1406 rb->GetValues = get_values_ubyte4;
1407 rb->PutRow = put_row_ubyte4;
1408 rb->PutRowRGB = put_row_rgb_ubyte4;
1409 rb->PutMonoRow = put_mono_row_ubyte4;
1410 rb->PutValues = put_values_ubyte4;
1411 rb->PutMonoValues = put_mono_values_ubyte4;
1412 break;
1413
1414 case MESA_FORMAT_R8:
1415 rb->DataType = GL_UNSIGNED_BYTE;
1416 rb->GetValues = get_values_r8;
1417 rb->GetRow = get_row_r8;
1418 rb->PutRow = put_row_generic;
1419 rb->PutRowRGB = put_row_generic;
1420 rb->PutMonoRow = put_mono_row_generic;
1421 rb->PutValues = put_values_generic;
1422 rb->PutMonoValues = put_mono_values_generic;
1423 break;
1424
1425 case MESA_FORMAT_GR88:
1426 rb->DataType = GL_UNSIGNED_BYTE;
1427 rb->GetValues = get_values_rg88;
1428 rb->GetRow = get_row_rg88;
1429 rb->PutRow = put_row_generic;
1430 rb->PutRowRGB = put_row_generic;
1431 rb->PutMonoRow = put_mono_row_generic;
1432 rb->PutValues = put_values_generic;
1433 rb->PutMonoValues = put_mono_values_generic;
1434 break;
1435
1436 case MESA_FORMAT_R16:
1437 rb->DataType = GL_UNSIGNED_SHORT;
1438 rb->GetValues = get_values_r16;
1439 rb->GetRow = get_row_r16;
1440 rb->PutRow = put_row_generic;
1441 rb->PutRowRGB = put_row_generic;
1442 rb->PutMonoRow = put_mono_row_generic;
1443 rb->PutValues = put_values_generic;
1444 rb->PutMonoValues = put_mono_values_generic;
1445 break;
1446
1447 case MESA_FORMAT_RG1616:
1448 rb->DataType = GL_UNSIGNED_SHORT;
1449 rb->GetValues = get_values_rg1616;
1450 rb->GetRow = get_row_rg1616;
1451 rb->PutRow = put_row_generic;
1452 rb->PutRowRGB = put_row_generic;
1453 rb->PutMonoRow = put_mono_row_generic;
1454 rb->PutValues = put_values_generic;
1455 rb->PutMonoValues = put_mono_values_generic;
1456 break;
1457
1458 case MESA_FORMAT_SIGNED_RGBA_16:
1459 rb->DataType = GL_SHORT;
1460 rb->GetValues = get_values_ushort4;
1461 rb->PutRow = put_row_ushort4;
1462 rb->PutRowRGB = put_row_rgb_ushort4;
1463 rb->PutMonoRow = put_mono_row_ushort4;
1464 rb->PutValues = put_values_ushort4;
1465 rb->PutMonoValues = put_mono_values_ushort4;
1466 break;
1467
1468 case MESA_FORMAT_S8:
1469 rb->DataType = GL_UNSIGNED_BYTE;
1470 rb->GetValues = get_values_ubyte;
1471 rb->PutRow = put_row_ubyte;
1472 rb->PutRowRGB = NULL;
1473 rb->PutMonoRow = put_mono_row_ubyte;
1474 rb->PutValues = put_values_ubyte;
1475 rb->PutMonoValues = put_mono_values_ubyte;
1476 break;
1477
1478 case MESA_FORMAT_Z16:
1479 rb->DataType = GL_UNSIGNED_SHORT;
1480 rb->GetValues = get_values_ushort;
1481 rb->PutRow = put_row_ushort;
1482 rb->PutRowRGB = NULL;
1483 rb->PutMonoRow = put_mono_row_ushort;
1484 rb->PutValues = put_values_ushort;
1485 rb->PutMonoValues = put_mono_values_ushort;
1486 break;
1487
1488 case MESA_FORMAT_Z32:
1489 case MESA_FORMAT_X8_Z24:
1490 case MESA_FORMAT_Z24_X8:
1491 rb->DataType = GL_UNSIGNED_INT;
1492 rb->GetValues = get_values_uint;
1493 rb->PutRow = put_row_uint;
1494 rb->PutRowRGB = NULL;
1495 rb->PutMonoRow = put_mono_row_uint;
1496 rb->PutValues = put_values_uint;
1497 rb->PutMonoValues = put_mono_values_uint;
1498 break;
1499
1500 case MESA_FORMAT_Z24_S8:
1501 case MESA_FORMAT_S8_Z24:
1502 rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
1503 rb->GetValues = get_values_uint;
1504 rb->PutRow = put_row_uint;
1505 rb->PutRowRGB = NULL;
1506 rb->PutMonoRow = put_mono_row_uint;
1507 rb->PutValues = put_values_uint;
1508 rb->PutMonoValues = put_mono_values_uint;
1509 break;
1510
1511 case MESA_FORMAT_RGBA_FLOAT32:
1512 rb->GetRow = get_row_generic;
1513 rb->GetValues = get_values_generic;
1514 rb->PutRow = put_row_generic;
1515 rb->PutRowRGB = NULL;
1516 rb->PutMonoRow = put_mono_row_generic;
1517 rb->PutValues = put_values_generic;
1518 rb->PutMonoValues = put_mono_values_generic;
1519 break;
1520
1521 case MESA_FORMAT_INTENSITY_FLOAT32:
1522 rb->GetRow = get_row_i_float32;
1523 rb->GetValues = get_values_i_float32;
1524 rb->PutRow = put_row_generic;
1525 rb->PutRowRGB = NULL;
1526 rb->PutMonoRow = put_mono_row_generic;
1527 rb->PutValues = put_values_generic;
1528 rb->PutMonoValues = put_mono_values_generic;
1529 break;
1530
1531 case MESA_FORMAT_LUMINANCE_FLOAT32:
1532 rb->GetRow = get_row_l_float32;
1533 rb->GetValues = get_values_l_float32;
1534 rb->PutRow = put_row_generic;
1535 rb->PutRowRGB = NULL;
1536 rb->PutMonoRow = put_mono_row_generic;
1537 rb->PutValues = put_values_generic;
1538 rb->PutMonoValues = put_mono_values_generic;
1539 break;
1540
1541 case MESA_FORMAT_ALPHA_FLOAT32:
1542 rb->GetRow = get_row_a_float32;
1543 rb->GetValues = get_values_a_float32;
1544 rb->PutRow = put_row_a_float32;
1545 rb->PutRowRGB = NULL;
1546 rb->PutMonoRow = put_mono_row_a_float32;
1547 rb->PutValues = put_values_a_float32;
1548 rb->PutMonoValues = put_mono_values_a_float32;
1549 break;
1550
1551 case MESA_FORMAT_RG_FLOAT32:
1552 rb->GetRow = get_row_rg_float32;
1553 rb->GetValues = get_values_rg_float32;
1554 rb->PutRow = put_row_generic;
1555 rb->PutRowRGB = NULL;
1556 rb->PutMonoRow = put_mono_row_generic;
1557 rb->PutValues = put_values_generic;
1558 rb->PutMonoValues = put_mono_values_generic;
1559 break;
1560
1561 case MESA_FORMAT_R_FLOAT32:
1562 rb->GetRow = get_row_r_float32;
1563 rb->GetValues = get_values_r_float32;
1564 rb->PutRow = put_row_generic;
1565 rb->PutRowRGB = NULL;
1566 rb->PutMonoRow = put_mono_row_generic;
1567 rb->PutValues = put_values_generic;
1568 rb->PutMonoValues = put_mono_values_generic;
1569 break;
1570
1571 default:
1572 break;
1573 }
1574 }
1575
1576 /**
1577 * This is a software fallback for the gl_renderbuffer->AllocStorage
1578 * function.
1579 * Device drivers will typically override this function for the buffers
1580 * which it manages (typically color buffers, Z and stencil).
1581 * Other buffers (like software accumulation and aux buffers) which the driver
1582 * doesn't manage can be handled with this function.
1583 *
1584 * This one multi-purpose function can allocate stencil, depth, accum, color
1585 * or color-index buffers!
1586 *
1587 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1588 * Get/PutValues functions.
1589 */
1590 static GLboolean
1591 soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
1592 GLenum internalFormat,
1593 GLuint width, GLuint height)
1594 {
1595 switch (internalFormat) {
1596 case GL_RGB:
1597 case GL_R3_G3_B2:
1598 case GL_RGB4:
1599 case GL_RGB5:
1600 case GL_RGB8:
1601 case GL_RGB10:
1602 case GL_RGB12:
1603 case GL_RGB16:
1604 rb->Format = MESA_FORMAT_RGB888;
1605 break;
1606 case GL_RGBA:
1607 case GL_RGBA2:
1608 case GL_RGBA4:
1609 case GL_RGB5_A1:
1610 case GL_RGBA8:
1611 #if 1
1612 case GL_RGB10_A2:
1613 case GL_RGBA12:
1614 #endif
1615 if (_mesa_little_endian())
1616 rb->Format = MESA_FORMAT_RGBA8888_REV;
1617 else
1618 rb->Format = MESA_FORMAT_RGBA8888;
1619 break;
1620 case GL_RGBA16:
1621 case GL_RGBA16_SNORM:
1622 /* for accum buffer */
1623 rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
1624 break;
1625 case GL_STENCIL_INDEX:
1626 case GL_STENCIL_INDEX1_EXT:
1627 case GL_STENCIL_INDEX4_EXT:
1628 case GL_STENCIL_INDEX8_EXT:
1629 case GL_STENCIL_INDEX16_EXT:
1630 rb->Format = MESA_FORMAT_S8;
1631 break;
1632 case GL_DEPTH_COMPONENT:
1633 case GL_DEPTH_COMPONENT16:
1634 rb->Format = MESA_FORMAT_Z16;
1635 break;
1636 case GL_DEPTH_COMPONENT24:
1637 rb->Format = MESA_FORMAT_X8_Z24;
1638 break;
1639 case GL_DEPTH_COMPONENT32:
1640 rb->Format = MESA_FORMAT_Z32;
1641 break;
1642 case GL_DEPTH_STENCIL_EXT:
1643 case GL_DEPTH24_STENCIL8_EXT:
1644 rb->Format = MESA_FORMAT_Z24_S8;
1645 break;
1646 default:
1647 /* unsupported format */
1648 return GL_FALSE;
1649 }
1650
1651 _mesa_set_renderbuffer_accessors(rb);
1652
1653 ASSERT(rb->DataType);
1654 ASSERT(rb->GetPointer);
1655 ASSERT(rb->GetRow);
1656 ASSERT(rb->GetValues);
1657 ASSERT(rb->PutRow);
1658 ASSERT(rb->PutMonoRow);
1659 ASSERT(rb->PutValues);
1660 ASSERT(rb->PutMonoValues);
1661
1662 /* free old buffer storage */
1663 if (rb->Data) {
1664 free(rb->Data);
1665 rb->Data = NULL;
1666 }
1667
1668 rb->RowStride = width;
1669
1670 if (width > 0 && height > 0) {
1671 /* allocate new buffer storage */
1672 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format));
1673
1674 if (rb->Data == NULL) {
1675 rb->Width = 0;
1676 rb->Height = 0;
1677 rb->RowStride = 0;
1678 _mesa_error(ctx, GL_OUT_OF_MEMORY,
1679 "software renderbuffer allocation (%d x %d x %d)",
1680 width, height, _mesa_get_format_bytes(rb->Format));
1681 return GL_FALSE;
1682 }
1683 }
1684
1685 rb->Width = width;
1686 rb->Height = height;
1687 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
1688
1689 if (rb->Name == 0 &&
1690 internalFormat == GL_RGBA16_SNORM &&
1691 rb->_BaseFormat == 0) {
1692 /* NOTE: This is a special case just for accumulation buffers.
1693 * This is a very limited use case- there's no snorm texturing or
1694 * rendering going on.
1695 */
1696 rb->_BaseFormat = GL_RGBA;
1697 }
1698 else {
1699 /* the internalFormat should have been error checked long ago */
1700 ASSERT(rb->_BaseFormat);
1701 }
1702
1703 return GL_TRUE;
1704 }
1705
1706
1707 void
1708 _mesa_map_soft_renderbuffer(struct gl_context *ctx,
1709 struct gl_renderbuffer *rb,
1710 GLuint x, GLuint y, GLuint w, GLuint h,
1711 GLbitfield mode,
1712 GLubyte **out_map,
1713 GLint *out_stride)
1714 {
1715 GLubyte *map = rb->Data;
1716 int cpp = _mesa_get_format_bytes(rb->Format);
1717 int stride = rb->RowStride * cpp;
1718
1719 ASSERT(rb->Data);
1720
1721 map += y * stride;
1722 map += x * cpp;
1723
1724 *out_map = map;
1725 *out_stride = stride;
1726 }
1727
1728 void
1729 _mesa_unmap_soft_renderbuffer(struct gl_context *ctx,
1730 struct gl_renderbuffer *rb)
1731 {
1732 }
1733
1734
1735
1736 /**********************************************************************/
1737 /**********************************************************************/
1738 /**********************************************************************/
1739
1740
1741 /**
1742 * Default GetPointer routine. Always return NULL to indicate that
1743 * direct buffer access is not supported.
1744 */
1745 static void *
1746 nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
1747 {
1748 return NULL;
1749 }
1750
1751
1752 /**
1753 * Initialize the fields of a gl_renderbuffer to default values.
1754 */
1755 void
1756 _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
1757 {
1758 _glthread_INIT_MUTEX(rb->Mutex);
1759
1760 rb->ClassID = 0;
1761 rb->Name = name;
1762 rb->RefCount = 0;
1763 rb->Delete = _mesa_delete_renderbuffer;
1764
1765 /* The rest of these should be set later by the caller of this function or
1766 * the AllocStorage method:
1767 */
1768 rb->AllocStorage = NULL;
1769
1770 rb->Width = 0;
1771 rb->Height = 0;
1772 rb->InternalFormat = GL_RGBA;
1773 rb->Format = MESA_FORMAT_NONE;
1774
1775 rb->DataType = GL_NONE;
1776 rb->Data = NULL;
1777
1778 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1779 * all over the drivers.
1780 */
1781 rb->Wrapped = rb;
1782
1783 rb->GetPointer = nop_get_pointer;
1784 rb->GetRow = NULL;
1785 rb->GetValues = NULL;
1786 rb->PutRow = NULL;
1787 rb->PutRowRGB = NULL;
1788 rb->PutMonoRow = NULL;
1789 rb->PutValues = NULL;
1790 rb->PutMonoValues = NULL;
1791 }
1792
1793
1794 /**
1795 * Allocate a new gl_renderbuffer object. This can be used for user-created
1796 * renderbuffers or window-system renderbuffers.
1797 */
1798 struct gl_renderbuffer *
1799 _mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
1800 {
1801 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
1802 if (rb) {
1803 _mesa_init_renderbuffer(rb, name);
1804 }
1805 return rb;
1806 }
1807
1808
1809 /**
1810 * Delete a gl_framebuffer.
1811 * This is the default function for renderbuffer->Delete().
1812 */
1813 void
1814 _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
1815 {
1816 if (rb->Data) {
1817 free(rb->Data);
1818 }
1819 free(rb);
1820 }
1821
1822
1823 /**
1824 * Allocate a software-based renderbuffer. This is called via the
1825 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1826 * renderbuffer.
1827 * This would not be used for hardware-based renderbuffers.
1828 */
1829 struct gl_renderbuffer *
1830 _mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
1831 {
1832 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
1833 if (rb) {
1834 rb->AllocStorage = soft_renderbuffer_storage;
1835 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1836 * But we're doing that in the soft_renderbuffer_storage() function
1837 * instead.
1838 */
1839 }
1840 return rb;
1841 }
1842
1843
1844 /**
1845 * Add software-based color renderbuffers to the given framebuffer.
1846 * This is a helper routine for device drivers when creating a
1847 * window system framebuffer (not a user-created render/framebuffer).
1848 * Once this function is called, you can basically forget about this
1849 * renderbuffer; core Mesa will handle all the buffer management and
1850 * rendering!
1851 */
1852 static GLboolean
1853 add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
1854 GLuint rgbBits, GLuint alphaBits,
1855 GLboolean frontLeft, GLboolean backLeft,
1856 GLboolean frontRight, GLboolean backRight)
1857 {
1858 gl_buffer_index b;
1859
1860 if (rgbBits > 16 || alphaBits > 16) {
1861 _mesa_problem(ctx,
1862 "Unsupported bit depth in add_color_renderbuffers");
1863 return GL_FALSE;
1864 }
1865
1866 assert(MAX_COLOR_ATTACHMENTS >= 4);
1867
1868 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1869 struct gl_renderbuffer *rb;
1870
1871 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1872 continue;
1873 else if (b == BUFFER_BACK_LEFT && !backLeft)
1874 continue;
1875 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1876 continue;
1877 else if (b == BUFFER_BACK_RIGHT && !backRight)
1878 continue;
1879
1880 assert(fb->Attachment[b].Renderbuffer == NULL);
1881
1882 rb = _mesa_new_renderbuffer(ctx, 0);
1883 if (!rb) {
1884 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1885 return GL_FALSE;
1886 }
1887
1888 rb->InternalFormat = GL_RGBA;
1889
1890 rb->AllocStorage = soft_renderbuffer_storage;
1891 _mesa_add_renderbuffer(fb, b, rb);
1892 }
1893
1894 return GL_TRUE;
1895 }
1896
1897
1898 /**
1899 * Add a software-based depth renderbuffer to the given framebuffer.
1900 * This is a helper routine for device drivers when creating a
1901 * window system framebuffer (not a user-created render/framebuffer).
1902 * Once this function is called, you can basically forget about this
1903 * renderbuffer; core Mesa will handle all the buffer management and
1904 * rendering!
1905 */
1906 static GLboolean
1907 add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1908 GLuint depthBits)
1909 {
1910 struct gl_renderbuffer *rb;
1911
1912 if (depthBits > 32) {
1913 _mesa_problem(ctx,
1914 "Unsupported depthBits in add_depth_renderbuffer");
1915 return GL_FALSE;
1916 }
1917
1918 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1919
1920 rb = _mesa_new_renderbuffer(ctx, 0);
1921 if (!rb) {
1922 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
1923 return GL_FALSE;
1924 }
1925
1926 if (depthBits <= 16) {
1927 rb->InternalFormat = GL_DEPTH_COMPONENT16;
1928 }
1929 else if (depthBits <= 24) {
1930 rb->InternalFormat = GL_DEPTH_COMPONENT24;
1931 }
1932 else {
1933 rb->InternalFormat = GL_DEPTH_COMPONENT32;
1934 }
1935
1936 rb->AllocStorage = soft_renderbuffer_storage;
1937 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1938
1939 return GL_TRUE;
1940 }
1941
1942
1943 /**
1944 * Add a software-based stencil renderbuffer to the given framebuffer.
1945 * This is a helper routine for device drivers when creating a
1946 * window system framebuffer (not a user-created render/framebuffer).
1947 * Once this function is called, you can basically forget about this
1948 * renderbuffer; core Mesa will handle all the buffer management and
1949 * rendering!
1950 */
1951 static GLboolean
1952 add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1953 GLuint stencilBits)
1954 {
1955 struct gl_renderbuffer *rb;
1956
1957 if (stencilBits > 16) {
1958 _mesa_problem(ctx,
1959 "Unsupported stencilBits in add_stencil_renderbuffer");
1960 return GL_FALSE;
1961 }
1962
1963 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1964
1965 rb = _mesa_new_renderbuffer(ctx, 0);
1966 if (!rb) {
1967 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
1968 return GL_FALSE;
1969 }
1970
1971 assert(stencilBits <= 8);
1972 rb->InternalFormat = GL_STENCIL_INDEX8;
1973
1974 rb->AllocStorage = soft_renderbuffer_storage;
1975 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1976
1977 return GL_TRUE;
1978 }
1979
1980
1981 /**
1982 * Add a software-based accumulation renderbuffer to the given framebuffer.
1983 * This is a helper routine for device drivers when creating a
1984 * window system framebuffer (not a user-created render/framebuffer).
1985 * Once this function is called, you can basically forget about this
1986 * renderbuffer; core Mesa will handle all the buffer management and
1987 * rendering!
1988 */
1989 static GLboolean
1990 add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1991 GLuint redBits, GLuint greenBits,
1992 GLuint blueBits, GLuint alphaBits)
1993 {
1994 struct gl_renderbuffer *rb;
1995
1996 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
1997 _mesa_problem(ctx,
1998 "Unsupported accumBits in add_accum_renderbuffer");
1999 return GL_FALSE;
2000 }
2001
2002 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
2003
2004 rb = _mesa_new_renderbuffer(ctx, 0);
2005 if (!rb) {
2006 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
2007 return GL_FALSE;
2008 }
2009
2010 rb->InternalFormat = GL_RGBA16_SNORM;
2011 rb->AllocStorage = soft_renderbuffer_storage;
2012 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
2013
2014 return GL_TRUE;
2015 }
2016
2017
2018
2019 /**
2020 * Add a software-based aux renderbuffer to the given framebuffer.
2021 * This is a helper routine for device drivers when creating a
2022 * window system framebuffer (not a user-created render/framebuffer).
2023 * Once this function is called, you can basically forget about this
2024 * renderbuffer; core Mesa will handle all the buffer management and
2025 * rendering!
2026 *
2027 * NOTE: color-index aux buffers not supported.
2028 */
2029 static GLboolean
2030 add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
2031 GLuint colorBits, GLuint numBuffers)
2032 {
2033 GLuint i;
2034
2035 if (colorBits > 16) {
2036 _mesa_problem(ctx,
2037 "Unsupported colorBits in add_aux_renderbuffers");
2038 return GL_FALSE;
2039 }
2040
2041 assert(numBuffers <= MAX_AUX_BUFFERS);
2042
2043 for (i = 0; i < numBuffers; i++) {
2044 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
2045
2046 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
2047
2048 if (!rb) {
2049 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
2050 return GL_FALSE;
2051 }
2052
2053 assert (colorBits <= 8);
2054 rb->InternalFormat = GL_RGBA;
2055
2056 rb->AllocStorage = soft_renderbuffer_storage;
2057 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
2058 }
2059 return GL_TRUE;
2060 }
2061
2062
2063 /**
2064 * Create/attach software-based renderbuffers to the given framebuffer.
2065 * This is a helper routine for device drivers. Drivers can just as well
2066 * call the individual _mesa_add_*_renderbuffer() routines directly.
2067 */
2068 void
2069 _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
2070 GLboolean color,
2071 GLboolean depth,
2072 GLboolean stencil,
2073 GLboolean accum,
2074 GLboolean alpha,
2075 GLboolean aux)
2076 {
2077 GLboolean frontLeft = GL_TRUE;
2078 GLboolean backLeft = fb->Visual.doubleBufferMode;
2079 GLboolean frontRight = fb->Visual.stereoMode;
2080 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
2081
2082 if (color) {
2083 assert(fb->Visual.redBits == fb->Visual.greenBits);
2084 assert(fb->Visual.redBits == fb->Visual.blueBits);
2085 add_color_renderbuffers(NULL, fb,
2086 fb->Visual.redBits,
2087 fb->Visual.alphaBits,
2088 frontLeft, backLeft,
2089 frontRight, backRight);
2090 }
2091
2092 if (depth) {
2093 assert(fb->Visual.depthBits > 0);
2094 add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
2095 }
2096
2097 if (stencil) {
2098 assert(fb->Visual.stencilBits > 0);
2099 add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
2100 }
2101
2102 if (accum) {
2103 assert(fb->Visual.accumRedBits > 0);
2104 assert(fb->Visual.accumGreenBits > 0);
2105 assert(fb->Visual.accumBlueBits > 0);
2106 add_accum_renderbuffer(NULL, fb,
2107 fb->Visual.accumRedBits,
2108 fb->Visual.accumGreenBits,
2109 fb->Visual.accumBlueBits,
2110 fb->Visual.accumAlphaBits);
2111 }
2112
2113 if (aux) {
2114 assert(fb->Visual.numAuxBuffers > 0);
2115 add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
2116 fb->Visual.numAuxBuffers);
2117 }
2118
2119 #if 0
2120 if (multisample) {
2121 /* maybe someday */
2122 }
2123 #endif
2124 }
2125
2126
2127 /**
2128 * Attach a renderbuffer to a framebuffer.
2129 * \param bufferName one of the BUFFER_x tokens
2130 */
2131 void
2132 _mesa_add_renderbuffer(struct gl_framebuffer *fb,
2133 gl_buffer_index bufferName, struct gl_renderbuffer *rb)
2134 {
2135 assert(fb);
2136 assert(rb);
2137 assert(bufferName < BUFFER_COUNT);
2138
2139 /* There should be no previous renderbuffer on this attachment point,
2140 * with the exception of depth/stencil since the same renderbuffer may
2141 * be used for both.
2142 */
2143 assert(bufferName == BUFFER_DEPTH ||
2144 bufferName == BUFFER_STENCIL ||
2145 fb->Attachment[bufferName].Renderbuffer == NULL);
2146
2147 /* winsys vs. user-created buffer cross check */
2148 if (fb->Name) {
2149 assert(rb->Name);
2150 }
2151 else {
2152 assert(!rb->Name);
2153 }
2154
2155 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
2156 fb->Attachment[bufferName].Complete = GL_TRUE;
2157 _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
2158 }
2159
2160
2161 /**
2162 * Remove the named renderbuffer from the given framebuffer.
2163 * \param bufferName one of the BUFFER_x tokens
2164 */
2165 void
2166 _mesa_remove_renderbuffer(struct gl_framebuffer *fb,
2167 gl_buffer_index bufferName)
2168 {
2169 struct gl_renderbuffer *rb;
2170
2171 assert(bufferName < BUFFER_COUNT);
2172
2173 rb = fb->Attachment[bufferName].Renderbuffer;
2174 if (!rb)
2175 return;
2176
2177 _mesa_reference_renderbuffer(&rb, NULL);
2178
2179 fb->Attachment[bufferName].Renderbuffer = NULL;
2180 }
2181
2182
2183 /**
2184 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
2185 * dereference that buffer first. The new renderbuffer's refcount will
2186 * be incremented. The old renderbuffer's refcount will be decremented.
2187 * This is normally only called from the _mesa_reference_renderbuffer() macro
2188 * when there's a real pointer change.
2189 */
2190 void
2191 _mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr,
2192 struct gl_renderbuffer *rb)
2193 {
2194 if (*ptr) {
2195 /* Unreference the old renderbuffer */
2196 GLboolean deleteFlag = GL_FALSE;
2197 struct gl_renderbuffer *oldRb = *ptr;
2198
2199 _glthread_LOCK_MUTEX(oldRb->Mutex);
2200 ASSERT(oldRb->RefCount > 0);
2201 oldRb->RefCount--;
2202 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
2203 deleteFlag = (oldRb->RefCount == 0);
2204 _glthread_UNLOCK_MUTEX(oldRb->Mutex);
2205
2206 if (deleteFlag) {
2207 oldRb->Delete(oldRb);
2208 }
2209
2210 *ptr = NULL;
2211 }
2212 assert(!*ptr);
2213
2214 if (rb) {
2215 /* reference new renderbuffer */
2216 _glthread_LOCK_MUTEX(rb->Mutex);
2217 rb->RefCount++;
2218 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
2219 _glthread_UNLOCK_MUTEX(rb->Mutex);
2220 *ptr = rb;
2221 }
2222 }