2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 * Functions for allocating/managing renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based
32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB
33 * renderbuffer with the alpha renderbuffer. We can do this because of the
34 * OO-nature of renderbuffers.
36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
37 * color channels. For example, Mesa may use 32-bit/float color channels
38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
48 #include "renderbuffer.h"
51 /* 32-bit color index format. Not a public format. */
52 #define COLOR_INDEX32 0x424243
56 * Routines for get/put values in common buffer formats follow.
57 * Someday add support for arbitrary row stride to make them more
61 /**********************************************************************
62 * Functions for buffers of 1 X GLubyte values.
67 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
72 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
73 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
78 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
79 GLint x
, GLint y
, void *values
)
81 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
82 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
83 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
88 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
89 const GLint x
[], const GLint y
[], void *values
)
91 GLubyte
*dst
= (GLubyte
*) values
;
93 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
94 for (i
= 0; i
< count
; i
++) {
95 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
102 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
103 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
105 const GLubyte
*src
= (const GLubyte
*) values
;
106 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
107 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
110 for (i
= 0; i
< count
; i
++) {
117 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
123 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
124 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
126 const GLubyte val
= *((const GLubyte
*) value
);
127 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
128 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
131 for (i
= 0; i
< count
; i
++) {
139 for (i
= 0; i
< count
; i
++) {
147 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
148 const GLint x
[], const GLint y
[],
149 const void *values
, const GLubyte
*mask
)
151 const GLubyte
*src
= (const GLubyte
*) values
;
153 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
154 for (i
= 0; i
< count
; i
++) {
155 if (!mask
|| mask
[i
]) {
156 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
164 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
165 const GLint x
[], const GLint y
[],
166 const void *value
, const GLubyte
*mask
)
168 const GLubyte val
= *((const GLubyte
*) value
);
170 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
171 for (i
= 0; i
< count
; i
++) {
172 if (!mask
|| mask
[i
]) {
173 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
180 /**********************************************************************
181 * Functions for buffers of 1 X GLushort values.
186 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
191 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
192 ASSERT(rb
->Width
> 0);
193 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
198 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
199 GLint x
, GLint y
, void *values
)
201 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
202 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
203 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
208 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
209 const GLint x
[], const GLint y
[], void *values
)
211 GLushort
*dst
= (GLushort
*) values
;
213 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
214 for (i
= 0; i
< count
; i
++) {
215 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
222 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
223 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
225 const GLushort
*src
= (const GLushort
*) values
;
226 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
227 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
230 for (i
= 0; i
< count
; i
++) {
237 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
243 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
244 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
246 const GLushort val
= *((const GLushort
*) value
);
247 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
248 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
251 for (i
= 0; i
< count
; i
++) {
259 for (i
= 0; i
< count
; i
++) {
267 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
268 const GLint x
[], const GLint y
[], const void *values
,
271 const GLushort
*src
= (const GLushort
*) values
;
273 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
274 for (i
= 0; i
< count
; i
++) {
275 if (!mask
|| mask
[i
]) {
276 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
284 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
285 GLuint count
, const GLint x
[], const GLint y
[],
286 const void *value
, const GLubyte
*mask
)
288 const GLushort val
= *((const GLushort
*) value
);
289 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
292 for (i
= 0; i
< count
; i
++) {
294 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
301 for (i
= 0; i
< count
; i
++) {
302 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
309 /**********************************************************************
310 * Functions for buffers of 1 X GLuint values.
311 * Typically depth/Z or color index.
315 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
320 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
321 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
326 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
327 GLint x
, GLint y
, void *values
)
329 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
330 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
331 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
336 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
337 const GLint x
[], const GLint y
[], void *values
)
339 GLuint
*dst
= (GLuint
*) values
;
341 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
342 for (i
= 0; i
< count
; i
++) {
343 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
350 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
351 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
353 const GLuint
*src
= (const GLuint
*) values
;
354 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
355 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
358 for (i
= 0; i
< count
; i
++) {
365 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
371 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
372 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
374 const GLuint val
= *((const GLuint
*) value
);
375 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
376 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
379 for (i
= 0; i
< count
; i
++) {
387 for (i
= 0; i
< count
; i
++) {
395 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
396 const GLint x
[], const GLint y
[], const void *values
,
399 const GLuint
*src
= (const GLuint
*) values
;
401 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
402 for (i
= 0; i
< count
; i
++) {
403 if (!mask
|| mask
[i
]) {
404 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
412 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
413 const GLint x
[], const GLint y
[], const void *value
,
416 const GLuint val
= *((const GLuint
*) value
);
418 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
419 for (i
= 0; i
< count
; i
++) {
420 if (!mask
|| mask
[i
]) {
421 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
428 /**********************************************************************
429 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
430 * Typically color buffers.
431 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
432 * alpha values and return 255 for outgoing alpha values.
436 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
439 /* No direct access since this buffer is RGB but caller will be
440 * treating it as if it were RGBA.
447 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
448 GLint x
, GLint y
, void *values
)
450 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
451 GLubyte
*dst
= (GLubyte
*) values
;
453 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
454 for (i
= 0; i
< count
; i
++) {
455 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
456 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
457 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
458 dst
[i
* 4 + 3] = 255;
464 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
465 const GLint x
[], const GLint y
[], void *values
)
467 GLubyte
*dst
= (GLubyte
*) values
;
469 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
470 for (i
= 0; i
< count
; i
++) {
472 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
473 dst
[i
* 4 + 0] = src
[0];
474 dst
[i
* 4 + 1] = src
[1];
475 dst
[i
* 4 + 2] = src
[2];
476 dst
[i
* 4 + 3] = 255;
482 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
483 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
485 /* note: incoming values are RGB+A! */
486 const GLubyte
*src
= (const GLubyte
*) values
;
487 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
489 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
490 for (i
= 0; i
< count
; i
++) {
491 if (!mask
|| mask
[i
]) {
492 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
493 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
494 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
501 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
502 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
504 /* note: incoming values are RGB+A! */
505 const GLubyte
*src
= (const GLubyte
*) values
;
506 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
508 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
509 for (i
= 0; i
< count
; i
++) {
510 if (!mask
|| mask
[i
]) {
511 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
512 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
513 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
520 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
521 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
523 /* note: incoming value is RGB+A! */
524 const GLubyte val0
= ((const GLubyte
*) value
)[0];
525 const GLubyte val1
= ((const GLubyte
*) value
)[1];
526 const GLubyte val2
= ((const GLubyte
*) value
)[2];
527 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
528 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
529 if (!mask
&& val0
== val1
&& val1
== val2
) {
531 _mesa_memset(dst
, val0
, 3 * count
);
535 for (i
= 0; i
< count
; i
++) {
536 if (!mask
|| mask
[i
]) {
537 dst
[i
* 3 + 0] = val0
;
538 dst
[i
* 3 + 1] = val1
;
539 dst
[i
* 3 + 2] = val2
;
547 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
548 const GLint x
[], const GLint y
[], const void *values
,
551 /* note: incoming values are RGB+A! */
552 const GLubyte
*src
= (const GLubyte
*) values
;
554 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
555 for (i
= 0; i
< count
; i
++) {
556 if (!mask
|| mask
[i
]) {
557 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
558 dst
[0] = src
[i
* 4 + 0];
559 dst
[1] = src
[i
* 4 + 1];
560 dst
[2] = src
[i
* 4 + 2];
567 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
568 GLuint count
, const GLint x
[], const GLint y
[],
569 const void *value
, const GLubyte
*mask
)
571 /* note: incoming value is RGB+A! */
572 const GLubyte val0
= ((const GLubyte
*) value
)[0];
573 const GLubyte val1
= ((const GLubyte
*) value
)[1];
574 const GLubyte val2
= ((const GLubyte
*) value
)[2];
576 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
577 for (i
= 0; i
< count
; i
++) {
578 if (!mask
|| mask
[i
]) {
579 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
588 /**********************************************************************
589 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
590 * Typically color buffers.
594 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
599 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
600 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
605 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
606 GLint x
, GLint y
, void *values
)
608 const GLbyte
*src
= (const GLbyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
609 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
610 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLbyte
));
615 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
616 const GLint x
[], const GLint y
[], void *values
)
618 /* treat 4*GLubyte as 1*GLuint */
619 GLuint
*dst
= (GLuint
*) values
;
621 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
622 for (i
= 0; i
< count
; i
++) {
623 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
630 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
631 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
633 /* treat 4*GLubyte as 1*GLuint */
634 const GLuint
*src
= (const GLuint
*) values
;
635 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
636 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
639 for (i
= 0; i
< count
; i
++) {
646 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
652 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
653 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
655 /* Store RGB values in RGBA buffer */
656 const GLubyte
*src
= (const GLubyte
*) values
;
657 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
659 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
660 for (i
= 0; i
< count
; i
++) {
661 if (!mask
|| mask
[i
]) {
662 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
663 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
664 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
665 dst
[i
* 4 + 3] = 0xff;
672 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
673 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
675 /* treat 4*GLubyte as 1*GLuint */
676 const GLuint val
= *((const GLuint
*) value
);
677 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
678 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
679 if (!mask
&& val
== 0) {
681 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
687 for (i
= 0; i
< count
; i
++) {
695 for (i
= 0; i
< count
; i
++) {
704 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
705 const GLint x
[], const GLint y
[], const void *values
,
708 /* treat 4*GLubyte as 1*GLuint */
709 const GLuint
*src
= (const GLuint
*) values
;
711 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
712 for (i
= 0; i
< count
; i
++) {
713 if (!mask
|| mask
[i
]) {
714 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
722 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
723 GLuint count
, const GLint x
[], const GLint y
[],
724 const void *value
, const GLubyte
*mask
)
726 /* treat 4*GLubyte as 1*GLuint */
727 const GLuint val
= *((const GLuint
*) value
);
729 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
730 for (i
= 0; i
< count
; i
++) {
731 if (!mask
|| mask
[i
]) {
732 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
739 /**********************************************************************
740 * Functions for buffers of 4 X GLushort (or GLshort) values.
741 * Typically accum buffer.
745 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
750 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
751 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
756 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
757 GLint x
, GLint y
, void *values
)
759 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
760 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
761 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
766 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
767 const GLint x
[], const GLint y
[], void *values
)
769 GLushort
*dst
= (GLushort
*) values
;
771 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
772 for (i
= 0; i
< count
; i
++) {
774 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
781 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
782 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
784 const GLushort
*src
= (const GLushort
*) values
;
785 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
786 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
789 for (i
= 0; i
< count
; i
++) {
791 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
792 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
793 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
794 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
799 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
805 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
806 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
808 /* Put RGB values in RGBA buffer */
809 const GLushort
*src
= (const GLushort
*) values
;
810 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
811 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
814 for (i
= 0; i
< count
; i
++) {
816 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
817 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
818 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
819 dst
[i
* 4 + 3] = 0xffff;
824 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
830 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
831 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
833 const GLushort val0
= ((const GLushort
*) value
)[0];
834 const GLushort val1
= ((const GLushort
*) value
)[1];
835 const GLushort val2
= ((const GLushort
*) value
)[2];
836 const GLushort val3
= ((const GLushort
*) value
)[3];
837 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
838 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
839 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
840 /* common case for clearing accum buffer */
841 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
845 for (i
= 0; i
< count
; i
++) {
846 if (!mask
|| mask
[i
]) {
847 dst
[i
* 4 + 0] = val0
;
848 dst
[i
* 4 + 1] = val1
;
849 dst
[i
* 4 + 2] = val2
;
850 dst
[i
* 4 + 3] = val3
;
858 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
859 const GLint x
[], const GLint y
[], const void *values
,
862 const GLushort
*src
= (const GLushort
*) values
;
864 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
865 for (i
= 0; i
< count
; i
++) {
866 if (!mask
|| mask
[i
]) {
867 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
868 dst
[0] = src
[i
* 4 + 0];
869 dst
[1] = src
[i
* 4 + 1];
870 dst
[2] = src
[i
* 4 + 2];
871 dst
[3] = src
[i
* 4 + 3];
878 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
879 GLuint count
, const GLint x
[], const GLint y
[],
880 const void *value
, const GLubyte
*mask
)
882 const GLushort val0
= ((const GLushort
*) value
)[0];
883 const GLushort val1
= ((const GLushort
*) value
)[1];
884 const GLushort val2
= ((const GLushort
*) value
)[2];
885 const GLushort val3
= ((const GLushort
*) value
)[3];
887 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
888 for (i
= 0; i
< count
; i
++) {
889 if (!mask
|| mask
[i
]) {
890 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
902 * This is a software fallback for the gl_renderbuffer->AllocStorage
904 * Device drivers will typically override this function for the buffers
905 * which it manages (typically color buffers, Z and stencil).
906 * Other buffers (like software accumulation and aux buffers) which the driver
907 * doesn't manage can be handled with this function.
909 * This one multi-purpose function can allocate stencil, depth, accum, color
910 * or color-index buffers!
912 * This function also plugs in the appropriate GetPointer, Get/PutRow and
913 * Get/PutValues functions.
916 soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
917 GLenum internalFormat
, GLuint width
, GLuint height
)
921 switch (internalFormat
) {
930 rb
->_BaseFormat
= GL_RGB
;
931 rb
->DataType
= GL_UNSIGNED_BYTE
;
932 rb
->GetPointer
= get_pointer_ubyte3
;
933 rb
->GetRow
= get_row_ubyte3
;
934 rb
->GetValues
= get_values_ubyte3
;
935 rb
->PutRow
= put_row_ubyte3
;
936 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
937 rb
->PutMonoRow
= put_mono_row_ubyte3
;
938 rb
->PutValues
= put_values_ubyte3
;
939 rb
->PutMonoValues
= put_mono_values_ubyte3
;
940 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
941 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
942 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
943 rb
->ComponentSizes
[3] = 0;
944 pixelSize
= 3 * sizeof(GLubyte
);
951 rb
->_BaseFormat
= GL_RGBA
;
952 rb
->DataType
= GL_UNSIGNED_BYTE
;
953 rb
->GetPointer
= get_pointer_ubyte4
;
954 rb
->GetRow
= get_row_ubyte4
;
955 rb
->GetValues
= get_values_ubyte4
;
956 rb
->PutRow
= put_row_ubyte4
;
957 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
958 rb
->PutMonoRow
= put_mono_row_ubyte4
;
959 rb
->PutValues
= put_values_ubyte4
;
960 rb
->PutMonoValues
= put_mono_values_ubyte4
;
961 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
962 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
963 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
964 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
965 pixelSize
= 4 * sizeof(GLubyte
);
970 rb
->_BaseFormat
= GL_RGBA
;
971 rb
->DataType
= GL_UNSIGNED_SHORT
;
972 rb
->GetPointer
= get_pointer_ushort4
;
973 rb
->GetRow
= get_row_ushort4
;
974 rb
->GetValues
= get_values_ushort4
;
975 rb
->PutRow
= put_row_ushort4
;
976 rb
->PutRowRGB
= put_row_rgb_ushort4
;
977 rb
->PutMonoRow
= put_mono_row_ushort4
;
978 rb
->PutValues
= put_values_ushort4
;
979 rb
->PutMonoValues
= put_mono_values_ushort4
;
980 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
981 rb
->ComponentSizes
[1] = 8 * sizeof(GLushort
);
982 rb
->ComponentSizes
[2] = 8 * sizeof(GLushort
);
983 rb
->ComponentSizes
[3] = 8 * sizeof(GLushort
);
984 pixelSize
= 4 * sizeof(GLushort
);
988 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
989 rb
->DataType
= GL_UNSIGNED_BYTE
;
990 rb
->GetPointer
= get_pointer_alpha8
;
991 rb
->GetRow
= get_row_alpha8
;
992 rb
->GetValues
= get_values_alpha8
;
993 rb
->PutRow
= put_row_alpha8
;
994 rb
->PutRowRGB
= NULL
;
995 rb
->PutMonoRow
= put_mono_row_alpha8
;
996 rb
->PutValues
= put_values_alpha8
;
997 rb
->PutMonoValues
= put_mono_values_alpha8
;
998 rb
->ComponentSizes
[0] = 0; /*red*/
999 rb
->ComponentSizes
[1] = 0; /*green*/
1000 rb
->ComponentSizes
[2] = 0; /*blue*/
1001 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
1002 pixelSize
= sizeof(GLubyte
);
1005 case GL_STENCIL_INDEX
:
1006 case GL_STENCIL_INDEX1_EXT
:
1007 case GL_STENCIL_INDEX4_EXT
:
1008 case GL_STENCIL_INDEX8_EXT
:
1009 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1010 rb
->DataType
= GL_UNSIGNED_BYTE
;
1011 rb
->GetPointer
= get_pointer_ubyte
;
1012 rb
->GetRow
= get_row_ubyte
;
1013 rb
->GetValues
= get_values_ubyte
;
1014 rb
->PutRow
= put_row_ubyte
;
1015 rb
->PutRowRGB
= NULL
;
1016 rb
->PutMonoRow
= put_mono_row_ubyte
;
1017 rb
->PutValues
= put_values_ubyte
;
1018 rb
->PutMonoValues
= put_mono_values_ubyte
;
1019 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1020 pixelSize
= sizeof(GLubyte
);
1022 case GL_STENCIL_INDEX16_EXT
:
1023 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1024 rb
->DataType
= GL_UNSIGNED_SHORT
;
1025 rb
->GetPointer
= get_pointer_ushort
;
1026 rb
->GetRow
= get_row_ushort
;
1027 rb
->GetValues
= get_values_ushort
;
1028 rb
->PutRow
= put_row_ushort
;
1029 rb
->PutRowRGB
= NULL
;
1030 rb
->PutMonoRow
= put_mono_row_ushort
;
1031 rb
->PutValues
= put_values_ushort
;
1032 rb
->PutMonoValues
= put_mono_values_ushort
;
1033 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1034 pixelSize
= sizeof(GLushort
);
1036 case GL_DEPTH_COMPONENT
:
1037 case GL_DEPTH_COMPONENT16
:
1038 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1039 rb
->DataType
= GL_UNSIGNED_SHORT
;
1040 rb
->GetPointer
= get_pointer_ushort
;
1041 rb
->GetRow
= get_row_ushort
;
1042 rb
->GetValues
= get_values_ushort
;
1043 rb
->PutRow
= put_row_ushort
;
1044 rb
->PutRowRGB
= NULL
;
1045 rb
->PutMonoRow
= put_mono_row_ushort
;
1046 rb
->PutValues
= put_values_ushort
;
1047 rb
->PutMonoValues
= put_mono_values_ushort
;
1048 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1049 pixelSize
= sizeof(GLushort
);
1051 case GL_DEPTH_COMPONENT24
:
1052 case GL_DEPTH_COMPONENT32
:
1053 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1054 rb
->DataType
= GL_UNSIGNED_INT
;
1055 rb
->GetPointer
= get_pointer_uint
;
1056 rb
->GetRow
= get_row_uint
;
1057 rb
->GetValues
= get_values_uint
;
1058 rb
->PutRow
= put_row_uint
;
1059 rb
->PutRowRGB
= NULL
;
1060 rb
->PutMonoRow
= put_mono_row_uint
;
1061 rb
->PutValues
= put_values_uint
;
1062 rb
->PutMonoValues
= put_mono_values_uint
;
1063 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1064 pixelSize
= sizeof(GLuint
);
1066 case GL_COLOR_INDEX8_EXT
:
1067 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1068 rb
->DataType
= GL_UNSIGNED_BYTE
;
1069 rb
->GetPointer
= get_pointer_ubyte
;
1070 rb
->GetRow
= get_row_ubyte
;
1071 rb
->GetValues
= get_values_ubyte
;
1072 rb
->PutRow
= put_row_ubyte
;
1073 rb
->PutRowRGB
= NULL
;
1074 rb
->PutMonoRow
= put_mono_row_ubyte
;
1075 rb
->PutValues
= put_values_ubyte
;
1076 rb
->PutMonoValues
= put_mono_values_ubyte
;
1077 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1078 pixelSize
= sizeof(GLubyte
);
1080 case GL_COLOR_INDEX16_EXT
:
1081 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1082 rb
->DataType
= GL_UNSIGNED_SHORT
;
1083 rb
->GetPointer
= get_pointer_ushort
;
1084 rb
->GetRow
= get_row_ushort
;
1085 rb
->GetValues
= get_values_ushort
;
1086 rb
->PutRow
= put_row_ushort
;
1087 rb
->PutRowRGB
= NULL
;
1088 rb
->PutMonoRow
= put_mono_row_ushort
;
1089 rb
->PutValues
= put_values_ushort
;
1090 rb
->PutMonoValues
= put_mono_values_ushort
;
1091 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1092 pixelSize
= sizeof(GLushort
);
1095 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1096 rb
->DataType
= GL_UNSIGNED_INT
;
1097 rb
->GetPointer
= get_pointer_uint
;
1098 rb
->GetRow
= get_row_uint
;
1099 rb
->GetValues
= get_values_uint
;
1100 rb
->PutRow
= put_row_uint
;
1101 rb
->PutRowRGB
= NULL
;
1102 rb
->PutMonoRow
= put_mono_row_uint
;
1103 rb
->PutValues
= put_values_uint
;
1104 rb
->PutMonoValues
= put_mono_values_uint
;
1105 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1106 pixelSize
= sizeof(GLuint
);
1109 _mesa_problem(ctx
, "Bad internalFormat in soft_renderbuffer_storage");
1113 ASSERT(rb
->DataType
);
1114 ASSERT(rb
->GetPointer
);
1116 ASSERT(rb
->GetValues
);
1118 ASSERT(rb
->PutMonoRow
);
1119 ASSERT(rb
->PutValues
);
1120 ASSERT(rb
->PutMonoValues
);
1121 ASSERT(rb
->ComponentSizes
[0] > 0);
1123 /* free old buffer storage */
1125 _mesa_free(rb
->Data
);
1127 /* allocate new buffer storage */
1128 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1129 if (rb
->Data
== NULL
) {
1132 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software renderbuffer allocation");
1137 rb
->Height
= height
;
1138 rb
->InternalFormat
= internalFormat
;
1144 /**********************************************************************/
1145 /**********************************************************************/
1146 /**********************************************************************/
1150 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
1151 * an alpha channel. The RGB buffer can be hardware-based.
1152 * We basically wrap the RGB buffer. When PutRow is called (for example),
1153 * we store the alpha values in this buffer, then pass on the PutRow call
1154 * to the wrapped RGB buffer.
1156 struct alpha_renderbuffer
1158 struct gl_renderbuffer Base
; /* the alpha buffer */
1159 struct gl_renderbuffer
*RGBbuffer
; /* the wrapped RGB buffer */
1164 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1165 GLenum internalFormat
, GLuint width
, GLuint height
)
1167 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1169 /* first, pass the call to the wrapped RGB buffer */
1170 if (!arb
->RGBbuffer
->AllocStorage(ctx
, arb
->RGBbuffer
, internalFormat
,
1175 /* next, resize my alpha buffer */
1176 if (arb
->Base
.Data
) {
1177 _mesa_free(arb
->Base
.Data
);
1180 arb
->Base
.Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1181 if (arb
->Base
.Data
== NULL
) {
1182 arb
->Base
.Width
= 0;
1183 arb
->Base
.Height
= 0;
1184 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1188 arb
->Base
.Width
= width
;
1189 arb
->Base
.Height
= height
;
1190 arb
->Base
.InternalFormat
= internalFormat
;
1197 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1200 delete_renderbuffer_alpha8(struct gl_renderbuffer
*rb
)
1202 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1203 if (arb
->Base
.Data
) {
1204 _mesa_free(arb
->Base
.Data
);
1206 assert(arb
->RGBbuffer
);
1207 arb
->RGBbuffer
->Delete(arb
->RGBbuffer
);
1208 arb
->RGBbuffer
= NULL
;
1214 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1217 return NULL
; /* don't allow direct access! */
1222 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1223 GLint x
, GLint y
, void *values
)
1225 /* NOTE: 'values' is RGBA format! */
1226 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1227 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1228 GLubyte
*dst
= (GLubyte
*) values
;
1230 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
1231 /* first, pass the call to the wrapped RGB buffer */
1232 arb
->RGBbuffer
->GetRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1233 /* second, fill in alpha values from this buffer! */
1234 for (i
= 0; i
< count
; i
++) {
1235 dst
[i
* 4 + 3] = src
[i
];
1241 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1242 const GLint x
[], const GLint y
[], void *values
)
1244 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1245 GLubyte
*dst
= (GLubyte
*) values
;
1247 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1248 /* first, pass the call to the wrapped RGB buffer */
1249 arb
->RGBbuffer
->GetValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1250 /* second, fill in alpha values from this buffer! */
1251 for (i
= 0; i
< count
; i
++) {
1252 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1253 dst
[i
* 4 + 3] = *src
;
1259 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1260 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1262 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1263 const GLubyte
*src
= (const GLubyte
*) values
;
1264 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1266 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1267 /* first, pass the call to the wrapped RGB buffer */
1268 arb
->RGBbuffer
->PutRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1269 /* second, store alpha in our buffer */
1270 for (i
= 0; i
< count
; i
++) {
1271 if (!mask
|| mask
[i
]) {
1272 dst
[i
] = src
[i
* 4 + 3];
1279 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1280 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1282 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1283 const GLubyte
*src
= (const GLubyte
*) values
;
1284 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1286 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1287 /* first, pass the call to the wrapped RGB buffer */
1288 arb
->RGBbuffer
->PutRowRGB(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1289 /* second, store alpha in our buffer */
1290 for (i
= 0; i
< count
; i
++) {
1291 if (!mask
|| mask
[i
]) {
1292 dst
[i
] = src
[i
* 4 + 3];
1299 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1300 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1302 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1303 const GLubyte val
= ((const GLubyte
*) value
)[3];
1304 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1305 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1306 /* first, pass the call to the wrapped RGB buffer */
1307 arb
->RGBbuffer
->PutMonoRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1308 /* second, store alpha in our buffer */
1311 for (i
= 0; i
< count
; i
++) {
1318 _mesa_memset(dst
, val
, count
);
1324 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1325 const GLint x
[], const GLint y
[],
1326 const void *values
, const GLubyte
*mask
)
1328 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1329 const GLubyte
*src
= (const GLubyte
*) values
;
1331 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1332 /* first, pass the call to the wrapped RGB buffer */
1333 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1334 /* second, store alpha in our buffer */
1335 for (i
= 0; i
< count
; i
++) {
1336 if (!mask
|| mask
[i
]) {
1337 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1338 *dst
= src
[i
* 4 + 3];
1345 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1346 GLuint count
, const GLint x
[], const GLint y
[],
1347 const void *value
, const GLubyte
*mask
)
1349 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1350 const GLubyte val
= ((const GLubyte
*) value
)[3];
1352 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1353 /* first, pass the call to the wrapped RGB buffer */
1354 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1355 /* second, store alpha in our buffer */
1356 for (i
= 0; i
< count
; i
++) {
1357 if (!mask
|| mask
[i
]) {
1358 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1366 /**********************************************************************/
1367 /**********************************************************************/
1368 /**********************************************************************/
1372 * Default GetPointer routine. Always return NULL to indicate that
1373 * direct buffer access is not supported.
1376 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1383 * Initialize the fields of a gl_renderbuffer to default values.
1386 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1390 rb
->Delete
= _mesa_delete_renderbuffer
;
1392 /* The rest of these should be set later by the caller of this function or
1393 * the AllocStorage method:
1395 rb
->AllocStorage
= NULL
;
1399 rb
->InternalFormat
= GL_NONE
;
1400 rb
->_BaseFormat
= GL_NONE
;
1401 rb
->DataType
= GL_NONE
;
1402 rb
->ComponentSizes
[0] = 0;
1403 rb
->ComponentSizes
[1] = 0;
1404 rb
->ComponentSizes
[2] = 0;
1405 rb
->ComponentSizes
[3] = 0;
1408 rb
->GetPointer
= nop_get_pointer
;
1410 rb
->GetValues
= NULL
;
1412 rb
->PutRowRGB
= NULL
;
1413 rb
->PutMonoRow
= NULL
;
1414 rb
->PutValues
= NULL
;
1415 rb
->PutMonoValues
= NULL
;
1420 * Allocate a new gl_renderbuffer object. This can be used for user-created
1421 * renderbuffers or window-system renderbuffers.
1423 struct gl_renderbuffer
*
1424 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1426 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1428 _mesa_init_renderbuffer(rb
, name
);
1435 * Delete a gl_framebuffer.
1436 * This is the default function for framebuffer->Delete().
1439 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1442 _mesa_free(rb
->Data
);
1449 * Allocate a software-based renderbuffer. This is called via the
1450 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1452 * This would not be used for hardware-based renderbuffers.
1454 struct gl_renderbuffer
*
1455 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1457 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1459 rb
->AllocStorage
= soft_renderbuffer_storage
;
1460 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1461 * But we're doing that in the soft_renderbuffer_storage() function
1470 * Add software-based color renderbuffers to the given framebuffer.
1471 * This is a helper routine for device drivers when creating a
1472 * window system framebuffer (not a user-created render/framebuffer).
1473 * Once this function is called, you can basically forget about this
1474 * renderbuffer; core Mesa will handle all the buffer management and
1478 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1479 GLuint rgbBits
, GLuint alphaBits
,
1480 GLboolean frontLeft
, GLboolean backLeft
,
1481 GLboolean frontRight
, GLboolean backRight
)
1485 if (rgbBits
> 16 || alphaBits
> 16) {
1487 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1491 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1493 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1494 struct gl_renderbuffer
*rb
;
1496 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1498 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1500 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1502 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1505 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1507 rb
= _mesa_new_renderbuffer(ctx
, 0);
1509 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1515 rb
->InternalFormat
= GL_RGBA8
;
1517 rb
->InternalFormat
= GL_RGB8
;
1520 assert(rgbBits
<= 16);
1522 rb
->InternalFormat
= GL_RGBA16
;
1524 rb
->InternalFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1527 rb
->AllocStorage
= soft_renderbuffer_storage
;
1528 _mesa_add_renderbuffer(fb
, b
, rb
);
1536 * Add software-based color index renderbuffers to the given framebuffer.
1537 * This is a helper routine for device drivers when creating a
1538 * window system framebuffer (not a user-created render/framebuffer).
1539 * Once this function is called, you can basically forget about this
1540 * renderbuffer; core Mesa will handle all the buffer management and
1544 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1546 GLboolean frontLeft
, GLboolean backLeft
,
1547 GLboolean frontRight
, GLboolean backRight
)
1551 if (indexBits
> 8) {
1553 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
1557 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1559 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1560 struct gl_renderbuffer
*rb
;
1562 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1564 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1566 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1568 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1571 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1573 rb
= _mesa_new_renderbuffer(ctx
, 0);
1575 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1579 if (indexBits
<= 8) {
1580 /* only support GLuint for now */
1581 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1582 rb
->InternalFormat
= COLOR_INDEX32
;
1585 rb
->InternalFormat
= COLOR_INDEX32
;
1587 rb
->AllocStorage
= soft_renderbuffer_storage
;
1588 _mesa_add_renderbuffer(fb
, b
, rb
);
1596 * Add software-based alpha renderbuffers to the given framebuffer.
1597 * This is a helper routine for device drivers when creating a
1598 * window system framebuffer (not a user-created render/framebuffer).
1599 * Once this function is called, you can basically forget about this
1600 * renderbuffer; core Mesa will handle all the buffer management and
1604 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1606 GLboolean frontLeft
, GLboolean backLeft
,
1607 GLboolean frontRight
, GLboolean backRight
)
1611 /* for window system framebuffers only! */
1612 assert(fb
->Name
== 0);
1614 if (alphaBits
> 8) {
1616 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1620 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1622 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1623 struct alpha_renderbuffer
*arb
;
1625 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1627 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1629 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1631 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1634 /* the RGB buffer to wrap must already exist!! */
1635 assert(fb
->Attachment
[b
].Renderbuffer
);
1637 /* only GLubyte supported for now */
1638 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1640 arb
= CALLOC_STRUCT(alpha_renderbuffer
);
1642 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1646 _mesa_init_renderbuffer(&arb
->Base
, 0);
1648 /* wrap the RGB buffer */
1649 arb
->RGBbuffer
= fb
->Attachment
[b
].Renderbuffer
;
1651 /* plug in my functions */
1652 arb
->Base
.InternalFormat
= arb
->RGBbuffer
->InternalFormat
;
1653 arb
->Base
._BaseFormat
= arb
->RGBbuffer
->_BaseFormat
;
1654 arb
->Base
.DataType
= arb
->RGBbuffer
->DataType
;
1655 arb
->Base
.AllocStorage
= alloc_storage_alpha8
;
1656 arb
->Base
.Delete
= delete_renderbuffer_alpha8
;
1657 arb
->Base
.GetPointer
= get_pointer_alpha8
;
1658 arb
->Base
.GetRow
= get_row_alpha8
;
1659 arb
->Base
.GetValues
= get_values_alpha8
;
1660 arb
->Base
.PutRow
= put_row_alpha8
;
1661 arb
->Base
.PutRowRGB
= put_row_rgb_alpha8
;
1662 arb
->Base
.PutMonoRow
= put_mono_row_alpha8
;
1663 arb
->Base
.PutValues
= put_values_alpha8
;
1664 arb
->Base
.PutMonoValues
= put_mono_values_alpha8
;
1666 /* clear the pointer to avoid assertion/sanity check failure later */
1667 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1669 /* plug the alpha renderbuffer into the colorbuffer attachment */
1670 _mesa_add_renderbuffer(fb
, b
, &arb
->Base
);
1678 * Add a software-based depth renderbuffer to the given framebuffer.
1679 * This is a helper routine for device drivers when creating a
1680 * window system framebuffer (not a user-created render/framebuffer).
1681 * Once this function is called, you can basically forget about this
1682 * renderbuffer; core Mesa will handle all the buffer management and
1686 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1689 struct gl_renderbuffer
*rb
;
1691 if (depthBits
> 32) {
1693 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1697 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1699 rb
= _mesa_new_renderbuffer(ctx
, 0);
1701 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1705 if (depthBits
<= 16) {
1706 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1709 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1712 rb
->AllocStorage
= soft_renderbuffer_storage
;
1713 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1720 * Add a software-based stencil renderbuffer to the given framebuffer.
1721 * This is a helper routine for device drivers when creating a
1722 * window system framebuffer (not a user-created render/framebuffer).
1723 * Once this function is called, you can basically forget about this
1724 * renderbuffer; core Mesa will handle all the buffer management and
1728 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1731 struct gl_renderbuffer
*rb
;
1733 if (stencilBits
> 16) {
1735 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1739 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1741 rb
= _mesa_new_renderbuffer(ctx
, 0);
1743 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1747 if (stencilBits
<= 8) {
1748 rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
1751 /* not really supported (see s_stencil.c code) */
1752 rb
->InternalFormat
= GL_STENCIL_INDEX16_EXT
;
1755 rb
->AllocStorage
= soft_renderbuffer_storage
;
1756 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1763 * Add a software-based accumulation renderbuffer to the given framebuffer.
1764 * This is a helper routine for device drivers when creating a
1765 * window system framebuffer (not a user-created render/framebuffer).
1766 * Once this function is called, you can basically forget about this
1767 * renderbuffer; core Mesa will handle all the buffer management and
1771 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1772 GLuint redBits
, GLuint greenBits
,
1773 GLuint blueBits
, GLuint alphaBits
)
1775 struct gl_renderbuffer
*rb
;
1777 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1779 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1783 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1785 rb
= _mesa_new_renderbuffer(ctx
, 0);
1787 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1791 rb
->InternalFormat
= GL_RGBA16
;
1792 rb
->AllocStorage
= soft_renderbuffer_storage
;
1793 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1801 * Add a software-based accumulation renderbuffer to the given framebuffer.
1802 * This is a helper routine for device drivers when creating a
1803 * window system framebuffer (not a user-created render/framebuffer).
1804 * Once this function is called, you can basically forget about this
1805 * renderbuffer; core Mesa will handle all the buffer management and
1808 * NOTE: color-index aux buffers not supported.
1811 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1812 GLuint colorBits
, GLuint numBuffers
)
1816 if (colorBits
> 16) {
1818 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1822 assert(numBuffers
< MAX_AUX_BUFFERS
);
1824 for (i
= 0; i
< numBuffers
; i
++) {
1825 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1827 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1830 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1834 if (colorBits
<= 8) {
1835 rb
->InternalFormat
= GL_RGBA8
;
1838 rb
->InternalFormat
= GL_RGBA16
;
1841 rb
->AllocStorage
= soft_renderbuffer_storage
;
1842 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1849 * Create/attach software-based renderbuffers to the given framebuffer.
1850 * This is a helper routine for device drivers. Drivers can just as well
1851 * call the individual _mesa_add_*_renderbuffer() routines directly.
1854 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1862 GLboolean frontLeft
= GL_TRUE
;
1863 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1864 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1865 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1868 if (fb
->Visual
.rgbMode
) {
1869 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1870 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1871 _mesa_add_color_renderbuffers(NULL
, fb
,
1873 fb
->Visual
.alphaBits
,
1874 frontLeft
, backLeft
,
1875 frontRight
, backRight
);
1878 _mesa_add_color_index_renderbuffers(NULL
, fb
,
1879 fb
->Visual
.indexBits
,
1880 frontLeft
, backLeft
,
1881 frontRight
, backRight
);
1886 assert(fb
->Visual
.depthBits
> 0);
1887 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1891 assert(fb
->Visual
.stencilBits
> 0);
1892 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1896 assert(fb
->Visual
.rgbMode
);
1897 assert(fb
->Visual
.accumRedBits
> 0);
1898 assert(fb
->Visual
.accumGreenBits
> 0);
1899 assert(fb
->Visual
.accumBlueBits
> 0);
1900 _mesa_add_accum_renderbuffer(NULL
, fb
,
1901 fb
->Visual
.accumRedBits
,
1902 fb
->Visual
.accumGreenBits
,
1903 fb
->Visual
.accumBlueBits
,
1904 fb
->Visual
.accumAlphaBits
);
1908 assert(fb
->Visual
.rgbMode
);
1909 assert(fb
->Visual
.numAuxBuffers
> 0);
1910 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1911 fb
->Visual
.numAuxBuffers
);
1915 assert(fb
->Visual
.rgbMode
);
1916 assert(fb
->Visual
.alphaBits
> 0);
1917 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1918 frontLeft
, backLeft
,
1919 frontRight
, backRight
);
1931 * Attach a renderbuffer to a framebuffer.
1934 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1935 GLuint bufferName
, struct gl_renderbuffer
*rb
)
1940 /* there should be no previous renderbuffer on this attachment point! */
1941 assert(fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1943 assert(bufferName
< BUFFER_COUNT
);
1945 /* winsys vs. user-created buffer cross check */
1953 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1954 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1955 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;