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 #define COLOR_INDEX32 0x424243
55 * Routines for get/put values in common buffer formats follow.
56 * Someday add support for arbitrary row stride to make them more
60 /**********************************************************************
61 * Functions for buffers of 1 X GLushort values.
66 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
71 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
72 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
77 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
78 GLint x
, GLint y
, void *values
)
80 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
81 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
82 _mesa_memcpy(values
, src
, count
* sizeof(GLubyte
));
87 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
88 const GLint x
[], const GLint y
[], void *values
)
90 GLubyte
*dst
= (GLubyte
*) values
;
92 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
93 for (i
= 0; i
< count
; i
++) {
94 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
101 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
102 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
104 const GLubyte
*src
= (const GLubyte
*) values
;
105 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
106 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
109 for (i
= 0; i
< count
; i
++) {
116 _mesa_memcpy(dst
, values
, count
* sizeof(GLubyte
));
122 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
123 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
125 const GLubyte val
= *((const GLubyte
*) value
);
126 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
127 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
130 for (i
= 0; i
< count
; i
++) {
138 for (i
= 0; i
< count
; i
++) {
146 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
147 const GLint x
[], const GLint y
[],
148 const void *values
, const GLubyte
*mask
)
150 const GLubyte
*src
= (const GLubyte
*) values
;
152 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
153 for (i
= 0; i
< count
; i
++) {
154 if (!mask
|| mask
[i
]) {
155 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
163 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
164 const GLint x
[], const GLint y
[],
165 const void *value
, const GLubyte
*mask
)
167 const GLubyte val
= *((const GLubyte
*) value
);
169 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
170 for (i
= 0; i
< count
; i
++) {
171 if (!mask
|| mask
[i
]) {
172 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
179 /**********************************************************************
180 * Functions for buffers of 1 X GLushort values.
185 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
190 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
191 ASSERT(rb
->Width
> 0);
192 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
197 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
198 GLint x
, GLint y
, void *values
)
200 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
201 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
202 _mesa_memcpy(values
, src
, count
* sizeof(GLushort
));
207 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
208 const GLint x
[], const GLint y
[], void *values
)
210 GLushort
*dst
= (GLushort
*) values
;
212 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
213 for (i
= 0; i
< count
; i
++) {
214 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
221 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
222 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
224 const GLushort
*src
= (const GLushort
*) values
;
225 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
226 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
229 for (i
= 0; i
< count
; i
++) {
236 _mesa_memcpy(dst
, src
, count
* sizeof(GLushort
));
242 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
243 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
245 const GLushort val
= *((const GLushort
*) value
);
246 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
247 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
250 for (i
= 0; i
< count
; i
++) {
258 for (i
= 0; i
< count
; i
++) {
266 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
267 const GLint x
[], const GLint y
[], const void *values
,
270 const GLushort
*src
= (const GLushort
*) values
;
272 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
273 for (i
= 0; i
< count
; i
++) {
274 if (!mask
|| mask
[i
]) {
275 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
283 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
284 GLuint count
, const GLint x
[], const GLint y
[],
285 const void *value
, const GLubyte
*mask
)
287 const GLushort val
= *((const GLushort
*) value
);
288 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
291 for (i
= 0; i
< count
; i
++) {
293 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
300 for (i
= 0; i
< count
; i
++) {
301 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
308 /**********************************************************************
309 * Functions for buffers of 1 X GLuint values.
310 * Typically depth/Z or color index.
314 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
319 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
320 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
325 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
326 GLint x
, GLint y
, void *values
)
328 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
329 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
330 _mesa_memcpy(values
, src
, count
* sizeof(GLuint
));
335 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
336 const GLint x
[], const GLint y
[], void *values
)
338 GLuint
*dst
= (GLuint
*) values
;
340 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
341 for (i
= 0; i
< count
; i
++) {
342 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
349 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
350 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
352 const GLuint
*src
= (const GLuint
*) values
;
353 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
354 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
357 for (i
= 0; i
< count
; i
++) {
364 _mesa_memcpy(dst
, src
, count
* sizeof(GLuint
));
370 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
371 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
373 const GLuint val
= *((const GLuint
*) value
);
374 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
376 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
377 for (i
= 0; i
< count
; i
++) {
378 if (!mask
|| mask
[i
]) {
386 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
387 const GLint x
[], const GLint y
[], const void *values
,
390 const GLuint
*src
= (const GLuint
*) values
;
392 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
393 for (i
= 0; i
< count
; i
++) {
394 if (!mask
|| mask
[i
]) {
395 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
403 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
404 const GLint x
[], const GLint y
[], const void *value
,
407 const GLuint val
= *((const GLuint
*) value
);
409 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
410 for (i
= 0; i
< count
; i
++) {
411 if (!mask
|| mask
[i
]) {
412 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
419 /**********************************************************************
420 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
421 * Typically color buffers.
422 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
423 * alpha values and return 255 for outgoing alpha values.
427 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
430 /* No direct access since this buffer is RGB but caller will be
431 * treating it as if it were RGBA.
438 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
439 GLint x
, GLint y
, void *values
)
441 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
442 GLubyte
*dst
= (GLubyte
*) values
;
444 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
445 for (i
= 0; i
< count
; i
++) {
446 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
447 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
448 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
449 dst
[i
* 4 + 3] = 255;
455 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
456 const GLint x
[], const GLint y
[], void *values
)
458 GLubyte
*dst
= (GLubyte
*) values
;
460 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
461 for (i
= 0; i
< count
; i
++) {
463 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
464 dst
[i
* 4 + 0] = src
[0];
465 dst
[i
* 4 + 1] = src
[1];
466 dst
[i
* 4 + 2] = src
[2];
467 dst
[i
* 4 + 3] = 255;
473 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
474 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
476 /* note: incoming values are RGB+A! */
477 const GLubyte
*src
= (const GLubyte
*) values
;
478 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
480 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
481 for (i
= 0; i
< count
; i
++) {
482 if (!mask
|| mask
[i
]) {
483 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
484 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
485 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
492 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
493 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
495 /* note: incoming values are RGB+A! */
496 const GLubyte
*src
= (const GLubyte
*) values
;
497 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
499 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
500 for (i
= 0; i
< count
; i
++) {
501 if (!mask
|| mask
[i
]) {
502 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
503 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
504 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
511 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
512 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
514 /* note: incoming value is RGB+A! */
515 const GLubyte val0
= ((const GLubyte
*) value
)[0];
516 const GLubyte val1
= ((const GLubyte
*) value
)[1];
517 const GLubyte val2
= ((const GLubyte
*) value
)[2];
518 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
519 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
520 if (!mask
&& val0
== val1
&& val1
== val2
) {
522 _mesa_memset(dst
, val0
, 3 * count
);
526 for (i
= 0; i
< count
; i
++) {
527 if (!mask
|| mask
[i
]) {
528 dst
[i
* 3 + 0] = val0
;
529 dst
[i
* 3 + 1] = val1
;
530 dst
[i
* 3 + 2] = val2
;
538 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
539 const GLint x
[], const GLint y
[], const void *values
,
542 /* note: incoming values are RGB+A! */
543 const GLubyte
*src
= (const GLubyte
*) values
;
545 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
546 for (i
= 0; i
< count
; i
++) {
547 if (!mask
|| mask
[i
]) {
548 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
549 dst
[0] = src
[i
* 4 + 0];
550 dst
[1] = src
[i
* 4 + 1];
551 dst
[2] = src
[i
* 4 + 2];
558 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
559 GLuint count
, const GLint x
[], const GLint y
[],
560 const void *value
, const GLubyte
*mask
)
562 /* note: incoming value is RGB+A! */
563 const GLubyte val0
= ((const GLubyte
*) value
)[0];
564 const GLubyte val1
= ((const GLubyte
*) value
)[1];
565 const GLubyte val2
= ((const GLubyte
*) value
)[2];
567 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
568 for (i
= 0; i
< count
; i
++) {
569 if (!mask
|| mask
[i
]) {
570 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
579 /**********************************************************************
580 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
581 * Typically color buffers.
585 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
590 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
591 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
596 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
597 GLint x
, GLint y
, void *values
)
599 const GLbyte
*src
= (const GLbyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
600 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
601 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLbyte
));
606 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
607 const GLint x
[], const GLint y
[], void *values
)
609 /* treat 4*GLubyte as 1*GLuint */
610 GLuint
*dst
= (GLuint
*) values
;
612 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
613 for (i
= 0; i
< count
; i
++) {
614 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
621 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
622 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
624 /* treat 4*GLubyte as 1*GLuint */
625 const GLuint
*src
= (const GLuint
*) values
;
626 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
627 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
630 for (i
= 0; i
< count
; i
++) {
637 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
643 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
644 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
646 /* Store RGB values in RGBA buffer */
647 const GLubyte
*src
= (const GLubyte
*) values
;
648 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
650 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
651 for (i
= 0; i
< count
; i
++) {
652 if (!mask
|| mask
[i
]) {
653 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
654 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
655 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
656 dst
[i
* 4 + 3] = 0xff;
663 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
664 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
666 /* treat 4*GLubyte as 1*GLuint */
667 const GLuint val
= *((const GLuint
*) value
);
668 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
669 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
670 if (!mask
&& val
== 0) {
672 _mesa_bzero(dst
, count
* 4 * sizeof(GLubyte
));
678 for (i
= 0; i
< count
; i
++) {
686 for (i
= 0; i
< count
; i
++) {
695 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
696 const GLint x
[], const GLint y
[], const void *values
,
699 /* treat 4*GLubyte as 1*GLuint */
700 const GLuint
*src
= (const GLuint
*) values
;
702 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
703 for (i
= 0; i
< count
; i
++) {
704 if (!mask
|| mask
[i
]) {
705 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
713 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
714 GLuint count
, const GLint x
[], const GLint y
[],
715 const void *value
, const GLubyte
*mask
)
717 /* treat 4*GLubyte as 1*GLuint */
718 const GLuint val
= *((const GLuint
*) value
);
720 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
721 for (i
= 0; i
< count
; i
++) {
722 if (!mask
|| mask
[i
]) {
723 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
730 /**********************************************************************
731 * Functions for buffers of 4 X GLushort (or GLshort) values.
732 * Typically accum buffer.
736 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
741 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
742 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
747 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
748 GLint x
, GLint y
, void *values
)
750 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
751 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
752 _mesa_memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
757 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
758 const GLint x
[], const GLint y
[], void *values
)
760 GLushort
*dst
= (GLushort
*) values
;
762 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
763 for (i
= 0; i
< count
; i
++) {
765 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
772 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
773 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
775 const GLushort
*src
= (const GLushort
*) values
;
776 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
777 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
780 for (i
= 0; i
< count
; i
++) {
782 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
783 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
784 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
785 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
790 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
796 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
797 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
799 /* Put RGB values in RGBA buffer */
800 const GLushort
*src
= (const GLushort
*) values
;
801 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
802 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
805 for (i
= 0; i
< count
; i
++) {
807 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
808 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
809 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
810 dst
[i
* 4 + 3] = 0xffff;
815 _mesa_memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
821 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
822 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
824 const GLushort val0
= ((const GLushort
*) value
)[0];
825 const GLushort val1
= ((const GLushort
*) value
)[1];
826 const GLushort val2
= ((const GLushort
*) value
)[2];
827 const GLushort val3
= ((const GLushort
*) value
)[3];
828 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
829 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
830 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
831 /* common case for clearing accum buffer */
832 _mesa_bzero(dst
, count
* 4 * sizeof(GLushort
));
836 for (i
= 0; i
< count
; i
++) {
837 if (!mask
|| mask
[i
]) {
838 dst
[i
* 4 + 0] = val0
;
839 dst
[i
* 4 + 1] = val1
;
840 dst
[i
* 4 + 2] = val2
;
841 dst
[i
* 4 + 3] = val3
;
849 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
850 const GLint x
[], const GLint y
[], const void *values
,
853 const GLushort
*src
= (const GLushort
*) values
;
855 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
856 for (i
= 0; i
< count
; i
++) {
857 if (!mask
|| mask
[i
]) {
858 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
859 dst
[0] = src
[i
* 4 + 0];
860 dst
[1] = src
[i
* 4 + 1];
861 dst
[2] = src
[i
* 4 + 2];
862 dst
[3] = src
[i
* 4 + 3];
869 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
870 GLuint count
, const GLint x
[], const GLint y
[],
871 const void *value
, const GLubyte
*mask
)
873 const GLushort val0
= ((const GLushort
*) value
)[0];
874 const GLushort val1
= ((const GLushort
*) value
)[1];
875 const GLushort val2
= ((const GLushort
*) value
)[2];
876 const GLushort val3
= ((const GLushort
*) value
)[3];
878 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
879 for (i
= 0; i
< count
; i
++) {
880 if (!mask
|| mask
[i
]) {
881 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
893 * This is a software fallback for the gl_renderbuffer->AllocStorage
895 * Device drivers will typically override this function for the buffers
896 * which it manages (typically color buffers, Z and stencil).
897 * Other buffers (like software accumulation and aux buffers) which the driver
898 * doesn't manage can be handled with this function.
900 * This one multi-purpose function can allocate stencil, depth, accum, color
901 * or color-index buffers!
903 * This function also plugs in the appropriate GetPointer, Get/PutRow and
904 * Get/PutValues functions.
907 soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
908 GLenum internalFormat
, GLuint width
, GLuint height
)
912 switch (internalFormat
) {
921 rb
->_BaseFormat
= GL_RGB
;
922 rb
->DataType
= GL_UNSIGNED_BYTE
;
923 rb
->GetPointer
= get_pointer_ubyte3
;
924 rb
->GetRow
= get_row_ubyte3
;
925 rb
->GetValues
= get_values_ubyte3
;
926 rb
->PutRow
= put_row_ubyte3
;
927 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
928 rb
->PutMonoRow
= put_mono_row_ubyte3
;
929 rb
->PutValues
= put_values_ubyte3
;
930 rb
->PutMonoValues
= put_mono_values_ubyte3
;
931 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
932 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
933 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
934 rb
->ComponentSizes
[3] = 0;
935 pixelSize
= 3 * sizeof(GLchan
);
942 rb
->_BaseFormat
= GL_RGBA
;
943 rb
->DataType
= GL_UNSIGNED_BYTE
;
944 rb
->GetPointer
= get_pointer_ubyte4
;
945 rb
->GetRow
= get_row_ubyte4
;
946 rb
->GetValues
= get_values_ubyte4
;
947 rb
->PutRow
= put_row_ubyte4
;
948 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
949 rb
->PutMonoRow
= put_mono_row_ubyte4
;
950 rb
->PutValues
= put_values_ubyte4
;
951 rb
->PutMonoValues
= put_mono_values_ubyte4
;
952 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
953 rb
->ComponentSizes
[1] = 8 * sizeof(GLubyte
);
954 rb
->ComponentSizes
[2] = 8 * sizeof(GLubyte
);
955 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
956 pixelSize
= 4 * sizeof(GLubyte
);
961 rb
->_BaseFormat
= GL_RGBA
;
962 rb
->DataType
= GL_UNSIGNED_SHORT
;
963 rb
->GetPointer
= get_pointer_ushort4
;
964 rb
->GetRow
= get_row_ushort4
;
965 rb
->GetValues
= get_values_ushort4
;
966 rb
->PutRow
= put_row_ushort4
;
967 rb
->PutRowRGB
= put_row_rgb_ushort4
;
968 rb
->PutMonoRow
= put_mono_row_ushort4
;
969 rb
->PutValues
= put_values_ushort4
;
970 rb
->PutMonoValues
= put_mono_values_ushort4
;
971 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
972 rb
->ComponentSizes
[1] = 8 * sizeof(GLushort
);
973 rb
->ComponentSizes
[2] = 8 * sizeof(GLushort
);
974 rb
->ComponentSizes
[3] = 8 * sizeof(GLushort
);
975 pixelSize
= 4 * sizeof(GLushort
);
979 rb
->_BaseFormat
= GL_RGBA
; /* Yes, not GL_ALPHA! */
980 rb
->DataType
= GL_UNSIGNED_BYTE
;
981 rb
->GetPointer
= get_pointer_alpha8
;
982 rb
->GetRow
= get_row_alpha8
;
983 rb
->GetValues
= get_values_alpha8
;
984 rb
->PutRow
= put_row_alpha8
;
985 rb
->PutRowRGB
= NULL
;
986 rb
->PutMonoRow
= put_mono_row_alpha8
;
987 rb
->PutValues
= put_values_alpha8
;
988 rb
->PutMonoValues
= put_mono_values_alpha8
;
989 rb
->ComponentSizes
[0] = 0; /*red*/
990 rb
->ComponentSizes
[1] = 0; /*green*/
991 rb
->ComponentSizes
[2] = 0; /*blue*/
992 rb
->ComponentSizes
[3] = 8 * sizeof(GLubyte
);
993 pixelSize
= sizeof(GLubyte
);
996 case GL_STENCIL_INDEX
:
997 case GL_STENCIL_INDEX1_EXT
:
998 case GL_STENCIL_INDEX4_EXT
:
999 case GL_STENCIL_INDEX8_EXT
:
1000 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1001 rb
->DataType
= GL_UNSIGNED_BYTE
;
1002 rb
->GetPointer
= get_pointer_ubyte
;
1003 rb
->GetRow
= get_row_ubyte
;
1004 rb
->GetValues
= get_values_ubyte
;
1005 rb
->PutRow
= put_row_ubyte
;
1006 rb
->PutRowRGB
= NULL
;
1007 rb
->PutMonoRow
= put_mono_row_ubyte
;
1008 rb
->PutValues
= put_values_ubyte
;
1009 rb
->PutMonoValues
= put_mono_values_ubyte
;
1010 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1011 pixelSize
= sizeof(GLubyte
);
1013 case GL_STENCIL_INDEX16_EXT
:
1014 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
1015 rb
->DataType
= GL_UNSIGNED_SHORT
;
1016 rb
->GetPointer
= get_pointer_ushort
;
1017 rb
->GetRow
= get_row_ushort
;
1018 rb
->GetValues
= get_values_ushort
;
1019 rb
->PutRow
= put_row_ushort
;
1020 rb
->PutRowRGB
= NULL
;
1021 rb
->PutMonoRow
= put_mono_row_ushort
;
1022 rb
->PutValues
= put_values_ushort
;
1023 rb
->PutMonoValues
= put_mono_values_ushort
;
1024 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1025 pixelSize
= sizeof(GLushort
);
1027 case GL_DEPTH_COMPONENT
:
1028 case GL_DEPTH_COMPONENT16
:
1029 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1030 rb
->DataType
= GL_UNSIGNED_SHORT
;
1031 rb
->GetPointer
= get_pointer_ushort
;
1032 rb
->GetRow
= get_row_ushort
;
1033 rb
->GetValues
= get_values_ushort
;
1034 rb
->PutRow
= put_row_ushort
;
1035 rb
->PutRowRGB
= NULL
;
1036 rb
->PutMonoRow
= put_mono_row_ushort
;
1037 rb
->PutValues
= put_values_ushort
;
1038 rb
->PutMonoValues
= put_mono_values_ushort
;
1039 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1040 pixelSize
= sizeof(GLushort
);
1042 case GL_DEPTH_COMPONENT24
:
1043 case GL_DEPTH_COMPONENT32
:
1044 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
1045 rb
->DataType
= GL_UNSIGNED_INT
;
1046 rb
->GetPointer
= get_pointer_uint
;
1047 rb
->GetRow
= get_row_uint
;
1048 rb
->GetValues
= get_values_uint
;
1049 rb
->PutRow
= put_row_uint
;
1050 rb
->PutRowRGB
= NULL
;
1051 rb
->PutMonoRow
= put_mono_row_uint
;
1052 rb
->PutValues
= put_values_uint
;
1053 rb
->PutMonoValues
= put_mono_values_uint
;
1054 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1055 pixelSize
= sizeof(GLuint
);
1057 case GL_COLOR_INDEX8_EXT
:
1058 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1059 rb
->DataType
= GL_UNSIGNED_BYTE
;
1060 rb
->GetPointer
= get_pointer_ubyte
;
1061 rb
->GetRow
= get_row_ubyte
;
1062 rb
->GetValues
= get_values_ubyte
;
1063 rb
->PutRow
= put_row_ubyte
;
1064 rb
->PutRowRGB
= NULL
;
1065 rb
->PutMonoRow
= put_mono_row_ubyte
;
1066 rb
->PutValues
= put_values_ubyte
;
1067 rb
->PutMonoValues
= put_mono_values_ubyte
;
1068 rb
->ComponentSizes
[0] = 8 * sizeof(GLubyte
);
1069 pixelSize
= sizeof(GLubyte
);
1071 case GL_COLOR_INDEX16_EXT
:
1072 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1073 rb
->DataType
= GL_UNSIGNED_SHORT
;
1074 rb
->GetPointer
= get_pointer_ushort
;
1075 rb
->GetRow
= get_row_ushort
;
1076 rb
->GetValues
= get_values_ushort
;
1077 rb
->PutRow
= put_row_ushort
;
1078 rb
->PutRowRGB
= NULL
;
1079 rb
->PutMonoRow
= put_mono_row_ushort
;
1080 rb
->PutValues
= put_values_ushort
;
1081 rb
->PutMonoValues
= put_mono_values_ushort
;
1082 rb
->ComponentSizes
[0] = 8 * sizeof(GLushort
);
1083 pixelSize
= sizeof(GLushort
);
1086 rb
->_BaseFormat
= GL_COLOR_INDEX
;
1087 rb
->DataType
= GL_UNSIGNED_INT
;
1088 rb
->GetPointer
= get_pointer_uint
;
1089 rb
->GetRow
= get_row_uint
;
1090 rb
->GetValues
= get_values_uint
;
1091 rb
->PutRow
= put_row_uint
;
1092 rb
->PutRowRGB
= NULL
;
1093 rb
->PutMonoRow
= put_mono_row_uint
;
1094 rb
->PutValues
= put_values_uint
;
1095 rb
->PutMonoValues
= put_mono_values_uint
;
1096 rb
->ComponentSizes
[0] = 8 * sizeof(GLuint
);
1097 pixelSize
= sizeof(GLuint
);
1100 _mesa_problem(ctx
, "Bad internalFormat in soft_renderbuffer_storage");
1104 ASSERT(rb
->DataType
);
1105 ASSERT(rb
->GetPointer
);
1107 ASSERT(rb
->GetValues
);
1109 ASSERT(rb
->PutMonoRow
);
1110 ASSERT(rb
->PutValues
);
1111 ASSERT(rb
->PutMonoValues
);
1112 ASSERT(rb
->ComponentSizes
[0] > 0);
1114 /* free old buffer storage */
1116 _mesa_free(rb
->Data
);
1118 /* allocate new buffer storage */
1119 rb
->Data
= _mesa_malloc(width
* height
* pixelSize
);
1120 if (rb
->Data
== NULL
) {
1123 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software renderbuffer allocation");
1128 rb
->Height
= height
;
1129 rb
->InternalFormat
= internalFormat
;
1135 /**********************************************************************/
1136 /**********************************************************************/
1137 /**********************************************************************/
1141 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
1142 * an alpha channel. The RGB buffer can be hardware-based.
1143 * We basically wrap the RGB buffer. When PutRow is called (for example),
1144 * we store the alpha values in this buffer, then pass on the PutRow call
1145 * to the wrapped RGB buffer.
1147 struct alpha_renderbuffer
1149 struct gl_renderbuffer Base
; /* the alpha buffer */
1150 struct gl_renderbuffer
*RGBbuffer
; /* the wrapped RGB buffer */
1155 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1156 GLenum internalFormat
, GLuint width
, GLuint height
)
1158 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1160 /* first, pass the call to the wrapped RGB buffer */
1161 if (!arb
->RGBbuffer
->AllocStorage(ctx
, arb
->RGBbuffer
, internalFormat
,
1166 /* next, resize my alpha buffer */
1167 if (arb
->Base
.Data
) {
1168 _mesa_free(arb
->Base
.Data
);
1171 arb
->Base
.Data
= _mesa_malloc(width
* height
* sizeof(GLubyte
));
1172 if (arb
->Base
.Data
== NULL
) {
1173 arb
->Base
.Width
= 0;
1174 arb
->Base
.Height
= 0;
1175 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1179 arb
->Base
.Width
= width
;
1180 arb
->Base
.Height
= height
;
1181 arb
->Base
.InternalFormat
= internalFormat
;
1188 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1191 delete_renderbuffer_alpha8(struct gl_renderbuffer
*rb
)
1193 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1194 if (arb
->Base
.Data
) {
1195 _mesa_free(arb
->Base
.Data
);
1197 assert(arb
->RGBbuffer
);
1198 arb
->RGBbuffer
->Delete(arb
->RGBbuffer
);
1199 arb
->RGBbuffer
= NULL
;
1205 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1208 return NULL
; /* don't allow direct access! */
1213 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1214 GLint x
, GLint y
, void *values
)
1216 /* NOTE: 'values' is RGBA format! */
1217 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1218 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1219 GLubyte
*dst
= (GLubyte
*) values
;
1221 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
1222 /* first, pass the call to the wrapped RGB buffer */
1223 arb
->RGBbuffer
->GetRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1224 /* second, fill in alpha values from this buffer! */
1225 for (i
= 0; i
< count
; i
++) {
1226 dst
[i
* 4 + 3] = src
[i
];
1232 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1233 const GLint x
[], const GLint y
[], void *values
)
1235 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1236 GLubyte
*dst
= (GLubyte
*) values
;
1238 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1239 /* first, pass the call to the wrapped RGB buffer */
1240 arb
->RGBbuffer
->GetValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
);
1241 /* second, fill in alpha values from this buffer! */
1242 for (i
= 0; i
< count
; i
++) {
1243 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1244 dst
[i
* 4 + 3] = *src
;
1250 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1251 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1253 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1254 const GLubyte
*src
= (const GLubyte
*) values
;
1255 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1257 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1258 /* first, pass the call to the wrapped RGB buffer */
1259 arb
->RGBbuffer
->PutRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1260 /* second, store alpha in our buffer */
1261 for (i
= 0; i
< count
; i
++) {
1262 if (!mask
|| mask
[i
]) {
1263 dst
[i
] = src
[i
* 4 + 3];
1270 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1271 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1273 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1274 const GLubyte
*src
= (const GLubyte
*) values
;
1275 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1277 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1278 /* first, pass the call to the wrapped RGB buffer */
1279 arb
->RGBbuffer
->PutRowRGB(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1280 /* second, store alpha in our buffer */
1281 for (i
= 0; i
< count
; i
++) {
1282 if (!mask
|| mask
[i
]) {
1283 dst
[i
] = src
[i
* 4 + 3];
1290 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1291 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1293 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1294 const GLubyte val
= ((const GLubyte
*) value
)[3];
1295 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
1296 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1297 /* first, pass the call to the wrapped RGB buffer */
1298 arb
->RGBbuffer
->PutMonoRow(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1299 /* second, store alpha in our buffer */
1302 for (i
= 0; i
< count
; i
++) {
1309 _mesa_memset(dst
, val
, count
);
1315 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
1316 const GLint x
[], const GLint y
[],
1317 const void *values
, const GLubyte
*mask
)
1319 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1320 const GLubyte
*src
= (const GLubyte
*) values
;
1322 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1323 /* first, pass the call to the wrapped RGB buffer */
1324 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, values
, mask
);
1325 /* second, store alpha in our buffer */
1326 for (i
= 0; i
< count
; i
++) {
1327 if (!mask
|| mask
[i
]) {
1328 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1329 *dst
= src
[i
* 4 + 3];
1336 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1337 GLuint count
, const GLint x
[], const GLint y
[],
1338 const void *value
, const GLubyte
*mask
)
1340 struct alpha_renderbuffer
*arb
= (struct alpha_renderbuffer
*) rb
;
1341 const GLubyte val
= ((const GLubyte
*) value
)[3];
1343 assert(rb
->DataType
== GL_UNSIGNED_BYTE
);
1344 /* first, pass the call to the wrapped RGB buffer */
1345 arb
->RGBbuffer
->PutValues(ctx
, arb
->RGBbuffer
, count
, x
, y
, value
, mask
);
1346 /* second, store alpha in our buffer */
1347 for (i
= 0; i
< count
; i
++) {
1348 if (!mask
|| mask
[i
]) {
1349 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
1357 /**********************************************************************/
1358 /**********************************************************************/
1359 /**********************************************************************/
1363 * Default GetPointer routine. Always return NULL to indicate that
1364 * direct buffer access is not supported.
1367 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1374 * Initialize the fields of a gl_renderbuffer to default values.
1377 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1381 rb
->Delete
= _mesa_delete_renderbuffer
;
1383 /* The rest of these should be set later by the caller of this function or
1384 * the AllocStorage method:
1386 rb
->AllocStorage
= NULL
;
1390 rb
->InternalFormat
= GL_NONE
;
1391 rb
->_BaseFormat
= GL_NONE
;
1392 rb
->DataType
= GL_NONE
;
1393 rb
->ComponentSizes
[0] = 0;
1394 rb
->ComponentSizes
[1] = 0;
1395 rb
->ComponentSizes
[2] = 0;
1396 rb
->ComponentSizes
[3] = 0;
1399 rb
->GetPointer
= nop_get_pointer
;
1401 rb
->GetValues
= NULL
;
1403 rb
->PutRowRGB
= NULL
;
1404 rb
->PutMonoRow
= NULL
;
1405 rb
->PutValues
= NULL
;
1406 rb
->PutMonoValues
= NULL
;
1411 * Allocate a new gl_renderbuffer object. This can be used for user-created
1412 * renderbuffers or window-system renderbuffers.
1414 struct gl_renderbuffer
*
1415 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1417 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1419 _mesa_init_renderbuffer(rb
, name
);
1426 * Delete a gl_framebuffer.
1427 * This is the default function for framebuffer->Delete().
1430 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1433 _mesa_free(rb
->Data
);
1440 * Allocate a software-based renderbuffer. This is called via the
1441 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1444 struct gl_renderbuffer
*
1445 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1447 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1449 rb
->AllocStorage
= soft_renderbuffer_storage
;
1450 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1451 * But we're doing that in the soft_renderbuffer_storage() function
1460 * Add software-based color renderbuffers to the given framebuffer.
1461 * This is a helper routine for device drivers when creating a
1462 * window system framebuffer (not a user-created render/framebuffer).
1463 * Once this function is called, you can basically forget about this
1464 * renderbuffer; core Mesa will handle all the buffer management and
1468 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1469 GLuint rgbBits
, GLuint alphaBits
,
1470 GLboolean frontLeft
, GLboolean backLeft
,
1471 GLboolean frontRight
, GLboolean backRight
)
1475 if (rgbBits
> 16 || alphaBits
> 16) {
1477 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1481 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1483 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1484 struct gl_renderbuffer
*rb
;
1486 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1488 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1490 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1492 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1495 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1497 rb
= _mesa_new_renderbuffer(ctx
, 0);
1499 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1505 rb
->InternalFormat
= GL_RGBA8
;
1507 rb
->InternalFormat
= GL_RGB8
;
1510 assert(rgbBits
<= 16);
1512 rb
->InternalFormat
= GL_RGBA16
;
1514 rb
->InternalFormat
= GL_RGBA16
; /* don't really have RGB16 yet */
1517 rb
->AllocStorage
= soft_renderbuffer_storage
;
1518 _mesa_add_renderbuffer(fb
, b
, rb
);
1526 * Add software-based color index renderbuffers to the given framebuffer.
1527 * This is a helper routine for device drivers when creating a
1528 * window system framebuffer (not a user-created render/framebuffer).
1529 * Once this function is called, you can basically forget about this
1530 * renderbuffer; core Mesa will handle all the buffer management and
1534 _mesa_add_color_index_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1536 GLboolean frontLeft
, GLboolean backLeft
,
1537 GLboolean frontRight
, GLboolean backRight
)
1541 if (indexBits
> 8) {
1543 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1547 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1549 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1550 struct gl_renderbuffer
*rb
;
1552 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1554 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1556 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1558 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1561 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1563 rb
= _mesa_new_renderbuffer(ctx
, 0);
1565 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1569 if (indexBits
<= 8) {
1570 /* only support GLuint for now */
1571 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
1572 rb
->InternalFormat
= COLOR_INDEX32
;
1575 rb
->InternalFormat
= COLOR_INDEX32
;
1577 rb
->AllocStorage
= soft_renderbuffer_storage
;
1578 _mesa_add_renderbuffer(fb
, b
, rb
);
1586 * Add software-based alpha renderbuffers to the given framebuffer.
1587 * This is a helper routine for device drivers when creating a
1588 * window system framebuffer (not a user-created render/framebuffer).
1589 * Once this function is called, you can basically forget about this
1590 * renderbuffer; core Mesa will handle all the buffer management and
1594 _mesa_add_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1596 GLboolean frontLeft
, GLboolean backLeft
,
1597 GLboolean frontRight
, GLboolean backRight
)
1601 /* for window system framebuffers only! */
1602 assert(fb
->Name
== 0);
1604 if (alphaBits
> 8) {
1606 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1610 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1612 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1613 struct alpha_renderbuffer
*arb
;
1615 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1617 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1619 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1621 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1624 /* the RGB buffer to wrap must already exist!! */
1625 assert(fb
->Attachment
[b
].Renderbuffer
);
1627 /* only GLubyte supported for now */
1628 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1630 arb
= CALLOC_STRUCT(alpha_renderbuffer
);
1632 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1636 _mesa_init_renderbuffer(&arb
->Base
, 0);
1638 /* wrap the RGB buffer */
1639 arb
->RGBbuffer
= fb
->Attachment
[b
].Renderbuffer
;
1641 /* plug in my functions */
1642 arb
->Base
.InternalFormat
= arb
->RGBbuffer
->InternalFormat
;
1643 arb
->Base
._BaseFormat
= arb
->RGBbuffer
->_BaseFormat
;
1644 arb
->Base
.DataType
= arb
->RGBbuffer
->DataType
;
1645 arb
->Base
.AllocStorage
= alloc_storage_alpha8
;
1646 arb
->Base
.Delete
= delete_renderbuffer_alpha8
;
1647 arb
->Base
.GetPointer
= get_pointer_alpha8
;
1648 arb
->Base
.GetRow
= get_row_alpha8
;
1649 arb
->Base
.GetValues
= get_values_alpha8
;
1650 arb
->Base
.PutRow
= put_row_alpha8
;
1651 arb
->Base
.PutRowRGB
= put_row_rgb_alpha8
;
1652 arb
->Base
.PutMonoRow
= put_mono_row_alpha8
;
1653 arb
->Base
.PutValues
= put_values_alpha8
;
1654 arb
->Base
.PutMonoValues
= put_mono_values_alpha8
;
1656 /* clear the pointer to avoid assertion/sanity check failure later */
1657 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1659 /* plug the alpha renderbuffer into the colorbuffer attachment */
1660 _mesa_add_renderbuffer(fb
, b
, &arb
->Base
);
1668 * Add a software-based depth renderbuffer to the given framebuffer.
1669 * This is a helper routine for device drivers when creating a
1670 * window system framebuffer (not a user-created render/framebuffer).
1671 * Once this function is called, you can basically forget about this
1672 * renderbuffer; core Mesa will handle all the buffer management and
1676 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1679 struct gl_renderbuffer
*rb
;
1681 if (depthBits
> 32) {
1683 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1687 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1689 rb
= _mesa_new_renderbuffer(ctx
, 0);
1691 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1695 if (depthBits
<= 16) {
1696 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1699 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1702 rb
->AllocStorage
= soft_renderbuffer_storage
;
1703 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1710 * Add a software-based stencil renderbuffer to the given framebuffer.
1711 * This is a helper routine for device drivers when creating a
1712 * window system framebuffer (not a user-created render/framebuffer).
1713 * Once this function is called, you can basically forget about this
1714 * renderbuffer; core Mesa will handle all the buffer management and
1718 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1721 struct gl_renderbuffer
*rb
;
1723 if (stencilBits
> 16) {
1725 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1729 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1731 rb
= _mesa_new_renderbuffer(ctx
, 0);
1733 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1737 if (stencilBits
<= 8) {
1738 rb
->InternalFormat
= GL_STENCIL_INDEX8_EXT
;
1741 /* not really supported (see s_stencil.c code) */
1742 rb
->InternalFormat
= GL_STENCIL_INDEX16_EXT
;
1745 rb
->AllocStorage
= soft_renderbuffer_storage
;
1746 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1753 * Add a software-based accumulation renderbuffer to the given framebuffer.
1754 * This is a helper routine for device drivers when creating a
1755 * window system framebuffer (not a user-created render/framebuffer).
1756 * Once this function is called, you can basically forget about this
1757 * renderbuffer; core Mesa will handle all the buffer management and
1761 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1762 GLuint redBits
, GLuint greenBits
,
1763 GLuint blueBits
, GLuint alphaBits
)
1765 struct gl_renderbuffer
*rb
;
1767 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1769 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1773 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1775 rb
= _mesa_new_renderbuffer(ctx
, 0);
1777 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1781 rb
->InternalFormat
= GL_RGBA16
;
1782 rb
->AllocStorage
= soft_renderbuffer_storage
;
1783 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1791 * Add a software-based accumulation renderbuffer to the given framebuffer.
1792 * This is a helper routine for device drivers when creating a
1793 * window system framebuffer (not a user-created render/framebuffer).
1794 * Once this function is called, you can basically forget about this
1795 * renderbuffer; core Mesa will handle all the buffer management and
1798 * NOTE: color-index aux buffers not supported.
1801 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1802 GLuint colorBits
, GLuint numBuffers
)
1806 if (colorBits
> 16) {
1808 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1812 assert(numBuffers
< MAX_AUX_BUFFERS
);
1814 for (i
= 0; i
< numBuffers
; i
++) {
1815 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1817 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1820 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1824 if (colorBits
<= 8) {
1825 rb
->InternalFormat
= GL_RGBA8
;
1828 rb
->InternalFormat
= GL_RGBA16
;
1831 rb
->AllocStorage
= soft_renderbuffer_storage
;
1832 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1840 * Attach a renderbuffer to a framebuffer.
1843 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1844 GLuint bufferName
, struct gl_renderbuffer
*rb
)
1848 /* there should be no previous renderbuffer on this attachment point! */
1849 assert(fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1850 assert(bufferName
< BUFFER_COUNT
);
1852 /* winsys vs. user-created buffer cross check */
1860 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1861 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1862 fb
->Attachment
[bufferName
].Renderbuffer
= rb
;