2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 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.
50 #include "renderbuffer.h"
54 * Routines for get/put values in common buffer formats follow.
55 * Someday add support for arbitrary row stride to make them more
59 /**********************************************************************
60 * Functions for buffers of 1 X GLubyte values.
65 get_pointer_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
70 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
71 /* Can't assert rb->Format since these funcs may be used for serveral
72 * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
74 return (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
79 get_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
80 GLint x
, GLint y
, void *values
)
82 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
83 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
84 memcpy(values
, src
, count
* sizeof(GLubyte
));
89 get_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
90 const GLint x
[], const GLint y
[], void *values
)
92 GLubyte
*dst
= (GLubyte
*) values
;
94 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
95 for (i
= 0; i
< count
; i
++) {
96 const GLubyte
*src
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
103 put_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
104 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
106 const GLubyte
*src
= (const GLubyte
*) values
;
107 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
108 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
111 for (i
= 0; i
< count
; i
++) {
118 memcpy(dst
, values
, count
* sizeof(GLubyte
));
124 put_mono_row_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
125 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
127 const GLubyte val
= *((const GLubyte
*) value
);
128 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
* rb
->Width
+ x
;
129 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
132 for (i
= 0; i
< count
; i
++) {
140 for (i
= 0; i
< count
; i
++) {
148 put_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
149 const GLint x
[], const GLint y
[],
150 const void *values
, const GLubyte
*mask
)
152 const GLubyte
*src
= (const GLubyte
*) values
;
154 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
155 for (i
= 0; i
< count
; i
++) {
156 if (!mask
|| mask
[i
]) {
157 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
165 put_mono_values_ubyte(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
166 const GLint x
[], const GLint y
[],
167 const void *value
, const GLubyte
*mask
)
169 const GLubyte val
= *((const GLubyte
*) value
);
171 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
172 for (i
= 0; i
< count
; i
++) {
173 if (!mask
|| mask
[i
]) {
174 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
181 /**********************************************************************
182 * Functions for buffers of 1 X GLushort values.
187 get_pointer_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
192 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
193 ASSERT(rb
->Width
> 0);
194 return (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
199 get_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
200 GLint x
, GLint y
, void *values
)
202 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
203 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
204 memcpy(values
, src
, count
* sizeof(GLushort
));
209 get_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
210 const GLint x
[], const GLint y
[], void *values
)
212 GLushort
*dst
= (GLushort
*) values
;
214 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
215 for (i
= 0; i
< count
; i
++) {
216 const GLushort
*src
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
223 put_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
224 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
226 const GLushort
*src
= (const GLushort
*) values
;
227 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
228 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
231 for (i
= 0; i
< count
; i
++) {
238 memcpy(dst
, src
, count
* sizeof(GLushort
));
244 put_mono_row_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
245 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
247 const GLushort val
= *((const GLushort
*) value
);
248 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
* rb
->Width
+ x
;
249 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
252 for (i
= 0; i
< count
; i
++) {
260 for (i
= 0; i
< count
; i
++) {
268 put_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
269 const GLint x
[], const GLint y
[], const void *values
,
272 const GLushort
*src
= (const GLushort
*) values
;
274 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
275 for (i
= 0; i
< count
; i
++) {
276 if (!mask
|| mask
[i
]) {
277 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
285 put_mono_values_ushort(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
286 GLuint count
, const GLint x
[], const GLint y
[],
287 const void *value
, const GLubyte
*mask
)
289 const GLushort val
= *((const GLushort
*) value
);
290 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
);
293 for (i
= 0; i
< count
; i
++) {
295 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
302 for (i
= 0; i
< count
; i
++) {
303 GLushort
*dst
= (GLushort
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
310 /**********************************************************************
311 * Functions for buffers of 1 X GLuint values.
312 * Typically depth/Z or color index.
316 get_pointer_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
321 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
322 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
323 return (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
328 get_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
329 GLint x
, GLint y
, void *values
)
331 const void *src
= rb
->GetPointer(ctx
, rb
, x
, y
);
332 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
333 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
334 memcpy(values
, src
, count
* sizeof(GLuint
));
339 get_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
340 const GLint x
[], const GLint y
[], void *values
)
342 GLuint
*dst
= (GLuint
*) values
;
344 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
345 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
346 for (i
= 0; i
< count
; i
++) {
347 const GLuint
*src
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
354 put_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
355 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
357 const GLuint
*src
= (const GLuint
*) values
;
358 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
359 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
360 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
363 for (i
= 0; i
< count
; i
++) {
370 memcpy(dst
, src
, count
* sizeof(GLuint
));
376 put_mono_row_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
377 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
379 const GLuint val
= *((const GLuint
*) value
);
380 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
* rb
->Width
+ x
;
381 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
382 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
385 for (i
= 0; i
< count
; i
++) {
393 for (i
= 0; i
< count
; i
++) {
401 put_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
402 const GLint x
[], const GLint y
[], const void *values
,
405 const GLuint
*src
= (const GLuint
*) values
;
407 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
408 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
409 for (i
= 0; i
< count
; i
++) {
410 if (!mask
|| mask
[i
]) {
411 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
419 put_mono_values_uint(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
420 const GLint x
[], const GLint y
[], const void *value
,
423 const GLuint val
= *((const GLuint
*) value
);
425 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
||
426 rb
->DataType
== GL_UNSIGNED_INT_24_8_EXT
);
427 for (i
= 0; i
< count
; i
++) {
428 if (!mask
|| mask
[i
]) {
429 GLuint
*dst
= (GLuint
*) rb
->Data
+ y
[i
] * rb
->Width
+ x
[i
];
436 /**********************************************************************
437 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
438 * Typically color buffers.
439 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
440 * alpha values and return 255 for outgoing alpha values.
444 get_pointer_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
447 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
448 /* No direct access since this buffer is RGB but caller will be
449 * treating it as if it were RGBA.
456 get_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
457 GLint x
, GLint y
, void *values
)
459 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
460 GLubyte
*dst
= (GLubyte
*) values
;
462 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
463 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
464 for (i
= 0; i
< count
; i
++) {
465 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
466 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
467 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
468 dst
[i
* 4 + 3] = 255;
474 get_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
475 const GLint x
[], const GLint y
[], void *values
)
477 GLubyte
*dst
= (GLubyte
*) values
;
479 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
480 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
481 for (i
= 0; i
< count
; i
++) {
483 = (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
484 dst
[i
* 4 + 0] = src
[0];
485 dst
[i
* 4 + 1] = src
[1];
486 dst
[i
* 4 + 2] = src
[2];
487 dst
[i
* 4 + 3] = 255;
493 put_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
494 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
496 /* note: incoming values are RGB+A! */
497 const GLubyte
*src
= (const GLubyte
*) values
;
498 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
500 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
501 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
502 for (i
= 0; i
< count
; i
++) {
503 if (!mask
|| mask
[i
]) {
504 dst
[i
* 3 + 0] = src
[i
* 4 + 0];
505 dst
[i
* 3 + 1] = src
[i
* 4 + 1];
506 dst
[i
* 3 + 2] = src
[i
* 4 + 2];
513 put_row_rgb_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
514 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
516 /* note: incoming values are RGB+A! */
517 const GLubyte
*src
= (const GLubyte
*) values
;
518 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
520 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
521 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
522 for (i
= 0; i
< count
; i
++) {
523 if (!mask
|| mask
[i
]) {
524 dst
[i
* 3 + 0] = src
[i
* 3 + 0];
525 dst
[i
* 3 + 1] = src
[i
* 3 + 1];
526 dst
[i
* 3 + 2] = src
[i
* 3 + 2];
533 put_mono_row_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
534 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
536 /* note: incoming value is RGB+A! */
537 const GLubyte val0
= ((const GLubyte
*) value
)[0];
538 const GLubyte val1
= ((const GLubyte
*) value
)[1];
539 const GLubyte val2
= ((const GLubyte
*) value
)[2];
540 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
* rb
->Width
+ x
);
541 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
542 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
543 if (!mask
&& val0
== val1
&& val1
== val2
) {
545 memset(dst
, val0
, 3 * count
);
549 for (i
= 0; i
< count
; i
++) {
550 if (!mask
|| mask
[i
]) {
551 dst
[i
* 3 + 0] = val0
;
552 dst
[i
* 3 + 1] = val1
;
553 dst
[i
* 3 + 2] = val2
;
561 put_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
562 const GLint x
[], const GLint y
[], const void *values
,
565 /* note: incoming values are RGB+A! */
566 const GLubyte
*src
= (const GLubyte
*) values
;
568 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
569 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
570 for (i
= 0; i
< count
; i
++) {
571 if (!mask
|| mask
[i
]) {
572 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
573 dst
[0] = src
[i
* 4 + 0];
574 dst
[1] = src
[i
* 4 + 1];
575 dst
[2] = src
[i
* 4 + 2];
582 put_mono_values_ubyte3(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
583 GLuint count
, const GLint x
[], const GLint y
[],
584 const void *value
, const GLubyte
*mask
)
586 /* note: incoming value is RGB+A! */
587 const GLubyte val0
= ((const GLubyte
*) value
)[0];
588 const GLubyte val1
= ((const GLubyte
*) value
)[1];
589 const GLubyte val2
= ((const GLubyte
*) value
)[2];
591 ASSERT(rb
->Format
== MESA_FORMAT_RGB888
);
592 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
593 for (i
= 0; i
< count
; i
++) {
594 if (!mask
|| mask
[i
]) {
595 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 3 * (y
[i
] * rb
->Width
+ x
[i
]);
604 /**********************************************************************
605 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
606 * Typically color buffers.
610 get_pointer_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
615 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
616 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
617 return (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
622 get_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
623 GLint x
, GLint y
, void *values
)
625 const GLubyte
*src
= (const GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
626 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
627 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
628 memcpy(values
, src
, 4 * count
* sizeof(GLubyte
));
633 get_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
634 const GLint x
[], const GLint y
[], void *values
)
636 /* treat 4*GLubyte as 1*GLuint */
637 GLuint
*dst
= (GLuint
*) values
;
639 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
640 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
641 for (i
= 0; i
< count
; i
++) {
642 const GLuint
*src
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
649 put_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
650 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
652 /* treat 4*GLubyte as 1*GLuint */
653 const GLuint
*src
= (const GLuint
*) values
;
654 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
655 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
656 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
659 for (i
= 0; i
< count
; i
++) {
666 memcpy(dst
, src
, 4 * count
* sizeof(GLubyte
));
672 put_row_rgb_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
673 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
675 /* Store RGB values in RGBA buffer */
676 const GLubyte
*src
= (const GLubyte
*) values
;
677 GLubyte
*dst
= (GLubyte
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
679 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
680 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
681 for (i
= 0; i
< count
; i
++) {
682 if (!mask
|| mask
[i
]) {
683 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
684 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
685 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
686 dst
[i
* 4 + 3] = 0xff;
693 put_mono_row_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
694 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
696 /* treat 4*GLubyte as 1*GLuint */
697 const GLuint val
= *((const GLuint
*) value
);
698 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
* rb
->Width
+ x
);
699 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
700 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
701 if (!mask
&& val
== 0) {
703 memset(dst
, 0, count
* 4 * sizeof(GLubyte
));
709 for (i
= 0; i
< count
; i
++) {
717 for (i
= 0; i
< count
; i
++) {
726 put_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
727 const GLint x
[], const GLint y
[], const void *values
,
730 /* treat 4*GLubyte as 1*GLuint */
731 const GLuint
*src
= (const GLuint
*) values
;
733 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
734 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
735 for (i
= 0; i
< count
; i
++) {
736 if (!mask
|| mask
[i
]) {
737 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
745 put_mono_values_ubyte4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
746 GLuint count
, const GLint x
[], const GLint y
[],
747 const void *value
, const GLubyte
*mask
)
749 /* treat 4*GLubyte as 1*GLuint */
750 const GLuint val
= *((const GLuint
*) value
);
752 ASSERT(rb
->DataType
== GL_UNSIGNED_BYTE
);
753 ASSERT(rb
->Format
== MESA_FORMAT_RGBA8888
);
754 for (i
= 0; i
< count
; i
++) {
755 if (!mask
|| mask
[i
]) {
756 GLuint
*dst
= (GLuint
*) rb
->Data
+ (y
[i
] * rb
->Width
+ x
[i
]);
763 /**********************************************************************
764 * Functions for buffers of 4 X GLushort (or GLshort) values.
765 * Typically accum buffer.
769 get_pointer_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
774 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
775 return (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
780 get_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
781 GLint x
, GLint y
, void *values
)
783 const GLshort
*src
= (const GLshort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
784 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
785 memcpy(values
, src
, 4 * count
* sizeof(GLshort
));
790 get_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
791 const GLint x
[], const GLint y
[], void *values
)
793 GLushort
*dst
= (GLushort
*) values
;
795 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
796 for (i
= 0; i
< count
; i
++) {
798 = (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
805 put_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
806 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
808 const GLushort
*src
= (const GLushort
*) values
;
809 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
810 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
813 for (i
= 0; i
< count
; i
++) {
815 dst
[i
* 4 + 0] = src
[i
* 4 + 0];
816 dst
[i
* 4 + 1] = src
[i
* 4 + 1];
817 dst
[i
* 4 + 2] = src
[i
* 4 + 2];
818 dst
[i
* 4 + 3] = src
[i
* 4 + 3];
823 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
829 put_row_rgb_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
830 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
832 /* Put RGB values in RGBA buffer */
833 const GLushort
*src
= (const GLushort
*) values
;
834 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
835 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
838 for (i
= 0; i
< count
; i
++) {
840 dst
[i
* 4 + 0] = src
[i
* 3 + 0];
841 dst
[i
* 4 + 1] = src
[i
* 3 + 1];
842 dst
[i
* 4 + 2] = src
[i
* 3 + 2];
843 dst
[i
* 4 + 3] = 0xffff;
848 memcpy(dst
, src
, 4 * count
* sizeof(GLushort
));
854 put_mono_row_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
855 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
857 const GLushort val0
= ((const GLushort
*) value
)[0];
858 const GLushort val1
= ((const GLushort
*) value
)[1];
859 const GLushort val2
= ((const GLushort
*) value
)[2];
860 const GLushort val3
= ((const GLushort
*) value
)[3];
861 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
* rb
->Width
+ x
);
862 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
863 if (!mask
&& val0
== 0 && val1
== 0 && val2
== 0 && val3
== 0) {
864 /* common case for clearing accum buffer */
865 memset(dst
, 0, count
* 4 * sizeof(GLushort
));
869 for (i
= 0; i
< count
; i
++) {
870 if (!mask
|| mask
[i
]) {
871 dst
[i
* 4 + 0] = val0
;
872 dst
[i
* 4 + 1] = val1
;
873 dst
[i
* 4 + 2] = val2
;
874 dst
[i
* 4 + 3] = val3
;
882 put_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
883 const GLint x
[], const GLint y
[], const void *values
,
886 const GLushort
*src
= (const GLushort
*) values
;
888 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
889 for (i
= 0; i
< count
; i
++) {
890 if (!mask
|| mask
[i
]) {
891 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
892 dst
[0] = src
[i
* 4 + 0];
893 dst
[1] = src
[i
* 4 + 1];
894 dst
[2] = src
[i
* 4 + 2];
895 dst
[3] = src
[i
* 4 + 3];
902 put_mono_values_ushort4(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
903 GLuint count
, const GLint x
[], const GLint y
[],
904 const void *value
, const GLubyte
*mask
)
906 const GLushort val0
= ((const GLushort
*) value
)[0];
907 const GLushort val1
= ((const GLushort
*) value
)[1];
908 const GLushort val2
= ((const GLushort
*) value
)[2];
909 const GLushort val3
= ((const GLushort
*) value
)[3];
911 ASSERT(rb
->DataType
== GL_UNSIGNED_SHORT
|| rb
->DataType
== GL_SHORT
);
912 for (i
= 0; i
< count
; i
++) {
913 if (!mask
|| mask
[i
]) {
914 GLushort
*dst
= (GLushort
*) rb
->Data
+ 4 * (y
[i
] * rb
->Width
+ x
[i
]);
926 * This is a software fallback for the gl_renderbuffer->AllocStorage
928 * Device drivers will typically override this function for the buffers
929 * which it manages (typically color buffers, Z and stencil).
930 * Other buffers (like software accumulation and aux buffers) which the driver
931 * doesn't manage can be handled with this function.
933 * This one multi-purpose function can allocate stencil, depth, accum, color
934 * or color-index buffers!
936 * This function also plugs in the appropriate GetPointer, Get/PutRow and
937 * Get/PutValues functions.
940 _mesa_soft_renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
941 GLenum internalFormat
,
942 GLuint width
, GLuint height
)
946 switch (internalFormat
) {
955 rb
->Format
= MESA_FORMAT_RGB888
;
956 rb
->DataType
= GL_UNSIGNED_BYTE
;
957 rb
->GetPointer
= get_pointer_ubyte3
;
958 rb
->GetRow
= get_row_ubyte3
;
959 rb
->GetValues
= get_values_ubyte3
;
960 rb
->PutRow
= put_row_ubyte3
;
961 rb
->PutRowRGB
= put_row_rgb_ubyte3
;
962 rb
->PutMonoRow
= put_mono_row_ubyte3
;
963 rb
->PutValues
= put_values_ubyte3
;
964 rb
->PutMonoValues
= put_mono_values_ubyte3
;
965 pixelSize
= 3 * sizeof(GLubyte
);
976 rb
->Format
= MESA_FORMAT_RGBA8888
;
977 rb
->DataType
= GL_UNSIGNED_BYTE
;
978 rb
->GetPointer
= get_pointer_ubyte4
;
979 rb
->GetRow
= get_row_ubyte4
;
980 rb
->GetValues
= get_values_ubyte4
;
981 rb
->PutRow
= put_row_ubyte4
;
982 rb
->PutRowRGB
= put_row_rgb_ubyte4
;
983 rb
->PutMonoRow
= put_mono_row_ubyte4
;
984 rb
->PutValues
= put_values_ubyte4
;
985 rb
->PutMonoValues
= put_mono_values_ubyte4
;
986 pixelSize
= 4 * sizeof(GLubyte
);
989 case GL_RGBA16_SNORM
:
990 /* for accum buffer */
991 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
992 rb
->DataType
= GL_SHORT
;
993 rb
->GetPointer
= get_pointer_ushort4
;
994 rb
->GetRow
= get_row_ushort4
;
995 rb
->GetValues
= get_values_ushort4
;
996 rb
->PutRow
= put_row_ushort4
;
997 rb
->PutRowRGB
= put_row_rgb_ushort4
;
998 rb
->PutMonoRow
= put_mono_row_ushort4
;
999 rb
->PutValues
= put_values_ushort4
;
1000 rb
->PutMonoValues
= put_mono_values_ushort4
;
1001 pixelSize
= 4 * sizeof(GLushort
);
1005 rb
->Format
= MESA_FORMAT_A8
;
1006 rb
->DataType
= GL_UNSIGNED_BYTE
;
1007 rb
->GetPointer
= get_pointer_alpha8
;
1008 rb
->GetRow
= get_row_alpha8
;
1009 rb
->GetValues
= get_values_alpha8
;
1010 rb
->PutRow
= put_row_alpha8
;
1011 rb
->PutRowRGB
= NULL
;
1012 rb
->PutMonoRow
= put_mono_row_alpha8
;
1013 rb
->PutValues
= put_values_alpha8
;
1014 rb
->PutMonoValues
= put_mono_values_alpha8
;
1015 pixelSize
= sizeof(GLubyte
);
1018 case GL_STENCIL_INDEX
:
1019 case GL_STENCIL_INDEX1_EXT
:
1020 case GL_STENCIL_INDEX4_EXT
:
1021 case GL_STENCIL_INDEX8_EXT
:
1022 case GL_STENCIL_INDEX16_EXT
:
1023 rb
->Format
= MESA_FORMAT_S8
;
1024 rb
->DataType
= GL_UNSIGNED_BYTE
;
1025 rb
->GetPointer
= get_pointer_ubyte
;
1026 rb
->GetRow
= get_row_ubyte
;
1027 rb
->GetValues
= get_values_ubyte
;
1028 rb
->PutRow
= put_row_ubyte
;
1029 rb
->PutRowRGB
= NULL
;
1030 rb
->PutMonoRow
= put_mono_row_ubyte
;
1031 rb
->PutValues
= put_values_ubyte
;
1032 rb
->PutMonoValues
= put_mono_values_ubyte
;
1033 pixelSize
= sizeof(GLubyte
);
1035 case GL_DEPTH_COMPONENT
:
1036 case GL_DEPTH_COMPONENT16
:
1037 rb
->Format
= MESA_FORMAT_Z16
;
1038 rb
->DataType
= GL_UNSIGNED_SHORT
;
1039 rb
->GetPointer
= get_pointer_ushort
;
1040 rb
->GetRow
= get_row_ushort
;
1041 rb
->GetValues
= get_values_ushort
;
1042 rb
->PutRow
= put_row_ushort
;
1043 rb
->PutRowRGB
= NULL
;
1044 rb
->PutMonoRow
= put_mono_row_ushort
;
1045 rb
->PutValues
= put_values_ushort
;
1046 rb
->PutMonoValues
= put_mono_values_ushort
;
1047 pixelSize
= sizeof(GLushort
);
1049 case GL_DEPTH_COMPONENT24
:
1050 rb
->DataType
= GL_UNSIGNED_INT
;
1051 rb
->GetPointer
= get_pointer_uint
;
1052 rb
->GetRow
= get_row_uint
;
1053 rb
->GetValues
= get_values_uint
;
1054 rb
->PutRow
= put_row_uint
;
1055 rb
->PutRowRGB
= NULL
;
1056 rb
->PutMonoRow
= put_mono_row_uint
;
1057 rb
->PutValues
= put_values_uint
;
1058 rb
->PutMonoValues
= put_mono_values_uint
;
1059 rb
->Format
= MESA_FORMAT_X8_Z24
;
1060 pixelSize
= sizeof(GLuint
);
1062 case GL_DEPTH_COMPONENT32
:
1063 rb
->DataType
= GL_UNSIGNED_INT
;
1064 rb
->GetPointer
= get_pointer_uint
;
1065 rb
->GetRow
= get_row_uint
;
1066 rb
->GetValues
= get_values_uint
;
1067 rb
->PutRow
= put_row_uint
;
1068 rb
->PutRowRGB
= NULL
;
1069 rb
->PutMonoRow
= put_mono_row_uint
;
1070 rb
->PutValues
= put_values_uint
;
1071 rb
->PutMonoValues
= put_mono_values_uint
;
1072 rb
->Format
= MESA_FORMAT_Z32
;
1073 pixelSize
= sizeof(GLuint
);
1075 case GL_DEPTH_STENCIL_EXT
:
1076 case GL_DEPTH24_STENCIL8_EXT
:
1077 rb
->Format
= MESA_FORMAT_Z24_S8
;
1078 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
1079 rb
->GetPointer
= get_pointer_uint
;
1080 rb
->GetRow
= get_row_uint
;
1081 rb
->GetValues
= get_values_uint
;
1082 rb
->PutRow
= put_row_uint
;
1083 rb
->PutRowRGB
= NULL
;
1084 rb
->PutMonoRow
= put_mono_row_uint
;
1085 rb
->PutValues
= put_values_uint
;
1086 rb
->PutMonoValues
= put_mono_values_uint
;
1087 pixelSize
= sizeof(GLuint
);
1090 _mesa_problem(ctx
, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
1094 ASSERT(rb
->DataType
);
1095 ASSERT(rb
->GetPointer
);
1097 ASSERT(rb
->GetValues
);
1099 ASSERT(rb
->PutMonoRow
);
1100 ASSERT(rb
->PutValues
);
1101 ASSERT(rb
->PutMonoValues
);
1103 /* free old buffer storage */
1109 if (width
> 0 && height
> 0) {
1110 /* allocate new buffer storage */
1111 rb
->Data
= malloc(width
* height
* pixelSize
);
1113 if (rb
->Data
== NULL
) {
1116 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
1117 "software renderbuffer allocation (%d x %d x %d)",
1118 width
, height
, pixelSize
);
1124 rb
->Height
= height
;
1125 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
1126 ASSERT(rb
->_BaseFormat
);
1133 /**********************************************************************/
1134 /**********************************************************************/
1135 /**********************************************************************/
1139 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
1140 * buffer wrapper around an existing RGB renderbuffer (hw or sw).
1142 * When PutRow is called (for example), we store the alpha values in
1143 * this buffer, then pass on the PutRow call to the wrapped RGB
1149 alloc_storage_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1150 GLenum internalFormat
, GLuint width
, GLuint height
)
1152 ASSERT(arb
!= arb
->Wrapped
);
1153 ASSERT(arb
->Format
== MESA_FORMAT_A8
);
1155 /* first, pass the call to the wrapped RGB buffer */
1156 if (!arb
->Wrapped
->AllocStorage(ctx
, arb
->Wrapped
, internalFormat
,
1161 /* next, resize my alpha buffer */
1166 arb
->Data
= malloc(width
* height
* sizeof(GLubyte
));
1167 if (arb
->Data
== NULL
) {
1170 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "software alpha buffer allocation");
1175 arb
->Height
= height
;
1182 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
1185 delete_renderbuffer_alpha8(struct gl_renderbuffer
*arb
)
1190 ASSERT(arb
->Wrapped
);
1191 ASSERT(arb
!= arb
->Wrapped
);
1192 arb
->Wrapped
->Delete(arb
->Wrapped
);
1193 arb
->Wrapped
= NULL
;
1199 get_pointer_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1202 return NULL
; /* don't allow direct access! */
1207 get_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1208 GLint x
, GLint y
, void *values
)
1210 /* NOTE: 'values' is RGBA format! */
1211 const GLubyte
*src
= (const GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1212 GLubyte
*dst
= (GLubyte
*) values
;
1214 ASSERT(arb
!= arb
->Wrapped
);
1215 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1216 /* first, pass the call to the wrapped RGB buffer */
1217 arb
->Wrapped
->GetRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1218 /* second, fill in alpha values from this buffer! */
1219 for (i
= 0; i
< count
; i
++) {
1220 dst
[i
* 4 + 3] = src
[i
];
1226 get_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1227 const GLint x
[], const GLint y
[], void *values
)
1229 GLubyte
*dst
= (GLubyte
*) values
;
1231 ASSERT(arb
!= arb
->Wrapped
);
1232 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1233 /* first, pass the call to the wrapped RGB buffer */
1234 arb
->Wrapped
->GetValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
);
1235 /* second, fill in alpha values from this buffer! */
1236 for (i
= 0; i
< count
; i
++) {
1237 const GLubyte
*src
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1238 dst
[i
* 4 + 3] = *src
;
1244 put_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1245 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1247 const GLubyte
*src
= (const GLubyte
*) values
;
1248 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1250 ASSERT(arb
!= arb
->Wrapped
);
1251 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1252 /* first, pass the call to the wrapped RGB buffer */
1253 arb
->Wrapped
->PutRow(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1254 /* second, store alpha in our buffer */
1255 for (i
= 0; i
< count
; i
++) {
1256 if (!mask
|| mask
[i
]) {
1257 dst
[i
] = src
[i
* 4 + 3];
1264 put_row_rgb_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1265 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
1267 const GLubyte
*src
= (const GLubyte
*) values
;
1268 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1270 ASSERT(arb
!= arb
->Wrapped
);
1271 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1272 /* first, pass the call to the wrapped RGB buffer */
1273 arb
->Wrapped
->PutRowRGB(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1274 /* second, store alpha in our buffer */
1275 for (i
= 0; i
< count
; i
++) {
1276 if (!mask
|| mask
[i
]) {
1277 dst
[i
] = src
[i
* 4 + 3];
1284 put_mono_row_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1285 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
1287 const GLubyte val
= ((const GLubyte
*) value
)[3];
1288 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
* arb
->Width
+ x
;
1289 ASSERT(arb
!= arb
->Wrapped
);
1290 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1291 /* first, pass the call to the wrapped RGB buffer */
1292 arb
->Wrapped
->PutMonoRow(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1293 /* second, store alpha in our buffer */
1296 for (i
= 0; i
< count
; i
++) {
1303 memset(dst
, val
, count
);
1309 put_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
, GLuint count
,
1310 const GLint x
[], const GLint y
[],
1311 const void *values
, const GLubyte
*mask
)
1313 const GLubyte
*src
= (const GLubyte
*) values
;
1315 ASSERT(arb
!= arb
->Wrapped
);
1316 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1317 /* first, pass the call to the wrapped RGB buffer */
1318 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, values
, mask
);
1319 /* second, store alpha in our buffer */
1320 for (i
= 0; i
< count
; i
++) {
1321 if (!mask
|| mask
[i
]) {
1322 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1323 *dst
= src
[i
* 4 + 3];
1330 put_mono_values_alpha8(GLcontext
*ctx
, struct gl_renderbuffer
*arb
,
1331 GLuint count
, const GLint x
[], const GLint y
[],
1332 const void *value
, const GLubyte
*mask
)
1334 const GLubyte val
= ((const GLubyte
*) value
)[3];
1336 ASSERT(arb
!= arb
->Wrapped
);
1337 ASSERT(arb
->DataType
== GL_UNSIGNED_BYTE
);
1338 /* first, pass the call to the wrapped RGB buffer */
1339 arb
->Wrapped
->PutValues(ctx
, arb
->Wrapped
, count
, x
, y
, value
, mask
);
1340 /* second, store alpha in our buffer */
1341 for (i
= 0; i
< count
; i
++) {
1342 if (!mask
|| mask
[i
]) {
1343 GLubyte
*dst
= (GLubyte
*) arb
->Data
+ y
[i
] * arb
->Width
+ x
[i
];
1351 copy_buffer_alpha8(struct gl_renderbuffer
* dst
, struct gl_renderbuffer
* src
)
1353 ASSERT(dst
->Format
== MESA_FORMAT_A8
);
1354 ASSERT(src
->Format
== MESA_FORMAT_A8
);
1355 ASSERT(dst
->Width
== src
->Width
);
1356 ASSERT(dst
->Height
== src
->Height
);
1358 memcpy(dst
->Data
, src
->Data
, dst
->Width
* dst
->Height
* sizeof(GLubyte
));
1362 /**********************************************************************/
1363 /**********************************************************************/
1364 /**********************************************************************/
1368 * Default GetPointer routine. Always return NULL to indicate that
1369 * direct buffer access is not supported.
1372 nop_get_pointer(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLint x
, GLint y
)
1379 * Initialize the fields of a gl_renderbuffer to default values.
1382 _mesa_init_renderbuffer(struct gl_renderbuffer
*rb
, GLuint name
)
1384 _glthread_INIT_MUTEX(rb
->Mutex
);
1386 rb
->Magic
= RB_MAGIC
;
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
->Format
= MESA_FORMAT_NONE
;
1402 rb
->DataType
= GL_NONE
;
1405 /* Point back to ourself so that we don't have to check for Wrapped==NULL
1406 * all over the drivers.
1410 rb
->GetPointer
= nop_get_pointer
;
1412 rb
->GetValues
= NULL
;
1414 rb
->PutRowRGB
= NULL
;
1415 rb
->PutMonoRow
= NULL
;
1416 rb
->PutValues
= NULL
;
1417 rb
->PutMonoValues
= NULL
;
1422 * Allocate a new gl_renderbuffer object. This can be used for user-created
1423 * renderbuffers or window-system renderbuffers.
1425 struct gl_renderbuffer
*
1426 _mesa_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
1428 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1430 _mesa_init_renderbuffer(rb
, name
);
1437 * Delete a gl_framebuffer.
1438 * This is the default function for renderbuffer->Delete().
1441 _mesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1451 * Allocate a software-based renderbuffer. This is called via the
1452 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1454 * This would not be used for hardware-based renderbuffers.
1456 struct gl_renderbuffer
*
1457 _mesa_new_soft_renderbuffer(GLcontext
*ctx
, GLuint name
)
1459 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, name
);
1461 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1462 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1463 * But we're doing that in the _mesa_soft_renderbuffer_storage() function
1472 * Add software-based color renderbuffers to the given framebuffer.
1473 * This is a helper routine for device drivers when creating a
1474 * window system framebuffer (not a user-created render/framebuffer).
1475 * Once this function is called, you can basically forget about this
1476 * renderbuffer; core Mesa will handle all the buffer management and
1480 _mesa_add_color_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1481 GLuint rgbBits
, GLuint alphaBits
,
1482 GLboolean frontLeft
, GLboolean backLeft
,
1483 GLboolean frontRight
, GLboolean backRight
)
1487 if (rgbBits
> 16 || alphaBits
> 16) {
1489 "Unsupported bit depth in _mesa_add_color_renderbuffers");
1493 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1495 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1496 struct gl_renderbuffer
*rb
;
1498 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1500 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1502 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1504 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1507 assert(fb
->Attachment
[b
].Renderbuffer
== NULL
);
1509 rb
= _mesa_new_renderbuffer(ctx
, 0);
1511 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating color buffer");
1517 rb
->Format
= MESA_FORMAT_RGBA8888
;
1519 rb
->Format
= MESA_FORMAT_RGB888
;
1522 assert(rgbBits
<= 16);
1523 rb
->Format
= MESA_FORMAT_NONE
; /*XXX RGBA16;*/
1525 rb
->InternalFormat
= GL_RGBA
;
1527 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1528 _mesa_add_renderbuffer(fb
, b
, rb
);
1536 * Add software-based alpha 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_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1546 GLboolean frontLeft
, GLboolean backLeft
,
1547 GLboolean frontRight
, GLboolean backRight
)
1551 /* for window system framebuffers only! */
1552 assert(fb
->Name
== 0);
1554 if (alphaBits
> 8) {
1556 "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
1560 assert(MAX_COLOR_ATTACHMENTS
>= 4);
1562 /* Wrap each of the RGB color buffers with an alpha renderbuffer.
1564 for (b
= BUFFER_FRONT_LEFT
; b
<= BUFFER_BACK_RIGHT
; b
++) {
1565 struct gl_renderbuffer
*arb
;
1567 if (b
== BUFFER_FRONT_LEFT
&& !frontLeft
)
1569 else if (b
== BUFFER_BACK_LEFT
&& !backLeft
)
1571 else if (b
== BUFFER_FRONT_RIGHT
&& !frontRight
)
1573 else if (b
== BUFFER_BACK_RIGHT
&& !backRight
)
1576 /* the RGB buffer to wrap must already exist!! */
1577 assert(fb
->Attachment
[b
].Renderbuffer
);
1579 /* only GLubyte supported for now */
1580 assert(fb
->Attachment
[b
].Renderbuffer
->DataType
== GL_UNSIGNED_BYTE
);
1582 /* allocate alpha renderbuffer */
1583 arb
= _mesa_new_renderbuffer(ctx
, 0);
1585 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating alpha buffer");
1589 /* wrap the alpha renderbuffer around the RGB renderbuffer */
1590 arb
->Wrapped
= fb
->Attachment
[b
].Renderbuffer
;
1592 /* Set up my alphabuffer fields and plug in my functions.
1593 * The functions will put/get the alpha values from/to RGBA arrays
1594 * and then call the wrapped buffer's functions to handle the RGB
1597 arb
->InternalFormat
= arb
->Wrapped
->InternalFormat
;
1598 arb
->Format
= MESA_FORMAT_A8
;
1599 arb
->DataType
= arb
->Wrapped
->DataType
;
1600 arb
->AllocStorage
= alloc_storage_alpha8
;
1601 arb
->Delete
= delete_renderbuffer_alpha8
;
1602 arb
->GetPointer
= get_pointer_alpha8
;
1603 arb
->GetRow
= get_row_alpha8
;
1604 arb
->GetValues
= get_values_alpha8
;
1605 arb
->PutRow
= put_row_alpha8
;
1606 arb
->PutRowRGB
= put_row_rgb_alpha8
;
1607 arb
->PutMonoRow
= put_mono_row_alpha8
;
1608 arb
->PutValues
= put_values_alpha8
;
1609 arb
->PutMonoValues
= put_mono_values_alpha8
;
1611 /* clear the pointer to avoid assertion/sanity check failure later */
1612 fb
->Attachment
[b
].Renderbuffer
= NULL
;
1614 /* plug the alpha renderbuffer into the colorbuffer attachment */
1615 _mesa_add_renderbuffer(fb
, b
, arb
);
1623 * For framebuffers that use a software alpha channel wrapper
1624 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
1625 * copy the back buffer alpha channel into the front buffer alpha channel.
1628 _mesa_copy_soft_alpha_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
)
1630 if (fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
&&
1631 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)
1632 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
,
1633 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
1636 if (fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
&&
1637 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
)
1638 copy_buffer_alpha8(fb
->Attachment
[BUFFER_FRONT_RIGHT
].Renderbuffer
,
1639 fb
->Attachment
[BUFFER_BACK_RIGHT
].Renderbuffer
);
1644 * Add a software-based depth renderbuffer to the given framebuffer.
1645 * This is a helper routine for device drivers when creating a
1646 * window system framebuffer (not a user-created render/framebuffer).
1647 * Once this function is called, you can basically forget about this
1648 * renderbuffer; core Mesa will handle all the buffer management and
1652 _mesa_add_depth_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1655 struct gl_renderbuffer
*rb
;
1657 if (depthBits
> 32) {
1659 "Unsupported depthBits in _mesa_add_depth_renderbuffer");
1663 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
== NULL
);
1665 rb
= _mesa_new_renderbuffer(ctx
, 0);
1667 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating depth buffer");
1671 if (depthBits
<= 16) {
1672 rb
->Format
= MESA_FORMAT_Z16
;
1673 rb
->InternalFormat
= GL_DEPTH_COMPONENT16
;
1675 else if (depthBits
<= 24) {
1676 rb
->Format
= MESA_FORMAT_X8_Z24
;
1677 rb
->InternalFormat
= GL_DEPTH_COMPONENT24
;
1680 rb
->Format
= MESA_FORMAT_Z32
;
1681 rb
->InternalFormat
= GL_DEPTH_COMPONENT32
;
1684 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1685 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, rb
);
1692 * Add a software-based stencil renderbuffer to the given framebuffer.
1693 * This is a helper routine for device drivers when creating a
1694 * window system framebuffer (not a user-created render/framebuffer).
1695 * Once this function is called, you can basically forget about this
1696 * renderbuffer; core Mesa will handle all the buffer management and
1700 _mesa_add_stencil_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1703 struct gl_renderbuffer
*rb
;
1705 if (stencilBits
> 16) {
1707 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
1711 assert(fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
== NULL
);
1713 rb
= _mesa_new_renderbuffer(ctx
, 0);
1715 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating stencil buffer");
1719 assert(stencilBits
<= 8);
1720 rb
->Format
= MESA_FORMAT_S8
;
1721 rb
->InternalFormat
= GL_STENCIL_INDEX8
;
1723 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1724 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, rb
);
1731 * Add a software-based accumulation renderbuffer to the given framebuffer.
1732 * This is a helper routine for device drivers when creating a
1733 * window system framebuffer (not a user-created render/framebuffer).
1734 * Once this function is called, you can basically forget about this
1735 * renderbuffer; core Mesa will handle all the buffer management and
1739 _mesa_add_accum_renderbuffer(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1740 GLuint redBits
, GLuint greenBits
,
1741 GLuint blueBits
, GLuint alphaBits
)
1743 struct gl_renderbuffer
*rb
;
1745 if (redBits
> 16 || greenBits
> 16 || blueBits
> 16 || alphaBits
> 16) {
1747 "Unsupported accumBits in _mesa_add_accum_renderbuffer");
1751 assert(fb
->Attachment
[BUFFER_ACCUM
].Renderbuffer
== NULL
);
1753 rb
= _mesa_new_renderbuffer(ctx
, 0);
1755 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1759 rb
->Format
= MESA_FORMAT_SIGNED_RGBA_16
;
1760 rb
->InternalFormat
= GL_RGBA16_SNORM
;
1761 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1762 _mesa_add_renderbuffer(fb
, BUFFER_ACCUM
, rb
);
1770 * Add a software-based accumulation renderbuffer to the given framebuffer.
1771 * This is a helper routine for device drivers when creating a
1772 * window system framebuffer (not a user-created render/framebuffer).
1773 * Once this function is called, you can basically forget about this
1774 * renderbuffer; core Mesa will handle all the buffer management and
1777 * NOTE: color-index aux buffers not supported.
1780 _mesa_add_aux_renderbuffers(GLcontext
*ctx
, struct gl_framebuffer
*fb
,
1781 GLuint colorBits
, GLuint numBuffers
)
1785 if (colorBits
> 16) {
1787 "Unsupported accumBits in _mesa_add_aux_renderbuffers");
1791 assert(numBuffers
<= MAX_AUX_BUFFERS
);
1793 for (i
= 0; i
< numBuffers
; i
++) {
1794 struct gl_renderbuffer
*rb
= _mesa_new_renderbuffer(ctx
, 0);
1796 assert(fb
->Attachment
[BUFFER_AUX0
+ i
].Renderbuffer
== NULL
);
1799 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "Allocating accum buffer");
1803 assert (colorBits
<= 8);
1804 rb
->Format
= MESA_FORMAT_RGBA8888
;
1805 rb
->InternalFormat
= GL_RGBA
;
1807 rb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;
1808 _mesa_add_renderbuffer(fb
, BUFFER_AUX0
+ i
, rb
);
1815 * Create/attach software-based renderbuffers to the given framebuffer.
1816 * This is a helper routine for device drivers. Drivers can just as well
1817 * call the individual _mesa_add_*_renderbuffer() routines directly.
1820 _mesa_add_soft_renderbuffers(struct gl_framebuffer
*fb
,
1828 GLboolean frontLeft
= GL_TRUE
;
1829 GLboolean backLeft
= fb
->Visual
.doubleBufferMode
;
1830 GLboolean frontRight
= fb
->Visual
.stereoMode
;
1831 GLboolean backRight
= fb
->Visual
.stereoMode
&& fb
->Visual
.doubleBufferMode
;
1834 assert(fb
->Visual
.redBits
== fb
->Visual
.greenBits
);
1835 assert(fb
->Visual
.redBits
== fb
->Visual
.blueBits
);
1836 _mesa_add_color_renderbuffers(NULL
, fb
,
1838 fb
->Visual
.alphaBits
,
1839 frontLeft
, backLeft
,
1840 frontRight
, backRight
);
1844 assert(fb
->Visual
.depthBits
> 0);
1845 _mesa_add_depth_renderbuffer(NULL
, fb
, fb
->Visual
.depthBits
);
1849 assert(fb
->Visual
.stencilBits
> 0);
1850 _mesa_add_stencil_renderbuffer(NULL
, fb
, fb
->Visual
.stencilBits
);
1854 assert(fb
->Visual
.accumRedBits
> 0);
1855 assert(fb
->Visual
.accumGreenBits
> 0);
1856 assert(fb
->Visual
.accumBlueBits
> 0);
1857 _mesa_add_accum_renderbuffer(NULL
, fb
,
1858 fb
->Visual
.accumRedBits
,
1859 fb
->Visual
.accumGreenBits
,
1860 fb
->Visual
.accumBlueBits
,
1861 fb
->Visual
.accumAlphaBits
);
1865 assert(fb
->Visual
.numAuxBuffers
> 0);
1866 _mesa_add_aux_renderbuffers(NULL
, fb
, fb
->Visual
.redBits
,
1867 fb
->Visual
.numAuxBuffers
);
1871 assert(fb
->Visual
.alphaBits
> 0);
1872 _mesa_add_alpha_renderbuffers(NULL
, fb
, fb
->Visual
.alphaBits
,
1873 frontLeft
, backLeft
,
1874 frontRight
, backRight
);
1886 * Attach a renderbuffer to a framebuffer.
1889 _mesa_add_renderbuffer(struct gl_framebuffer
*fb
,
1890 GLuint bufferName
, struct gl_renderbuffer
*rb
)
1894 assert(bufferName
< BUFFER_COUNT
);
1896 /* There should be no previous renderbuffer on this attachment point,
1897 * with the exception of depth/stencil since the same renderbuffer may
1900 assert(bufferName
== BUFFER_DEPTH
||
1901 bufferName
== BUFFER_STENCIL
||
1902 fb
->Attachment
[bufferName
].Renderbuffer
== NULL
);
1904 /* winsys vs. user-created buffer cross check */
1912 fb
->Attachment
[bufferName
].Type
= GL_RENDERBUFFER_EXT
;
1913 fb
->Attachment
[bufferName
].Complete
= GL_TRUE
;
1914 _mesa_reference_renderbuffer(&fb
->Attachment
[bufferName
].Renderbuffer
, rb
);
1919 * Remove the named renderbuffer from the given framebuffer.
1922 _mesa_remove_renderbuffer(struct gl_framebuffer
*fb
, GLuint bufferName
)
1924 struct gl_renderbuffer
*rb
;
1926 assert(bufferName
< BUFFER_COUNT
);
1928 rb
= fb
->Attachment
[bufferName
].Renderbuffer
;
1932 _mesa_reference_renderbuffer(&rb
, NULL
);
1934 fb
->Attachment
[bufferName
].Renderbuffer
= NULL
;
1939 * Set *ptr to point to rb. If *ptr points to another renderbuffer,
1940 * dereference that buffer first. The new renderbuffer's refcount will
1941 * be incremented. The old renderbuffer's refcount will be decremented.
1944 _mesa_reference_renderbuffer(struct gl_renderbuffer
**ptr
,
1945 struct gl_renderbuffer
*rb
)
1954 /* Unreference the old renderbuffer */
1955 GLboolean deleteFlag
= GL_FALSE
;
1956 struct gl_renderbuffer
*oldRb
= *ptr
;
1958 assert(oldRb
->Magic
== RB_MAGIC
);
1959 _glthread_LOCK_MUTEX(oldRb
->Mutex
);
1960 assert(oldRb
->Magic
== RB_MAGIC
);
1961 ASSERT(oldRb
->RefCount
> 0);
1963 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
1964 deleteFlag
= (oldRb
->RefCount
== 0);
1965 _glthread_UNLOCK_MUTEX(oldRb
->Mutex
);
1968 oldRb
->Magic
= 0; /* now invalid memory! */
1969 oldRb
->Delete(oldRb
);
1977 assert(rb
->Magic
== RB_MAGIC
);
1978 /* reference new renderbuffer */
1979 _glthread_LOCK_MUTEX(rb
->Mutex
);
1981 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
1982 _glthread_UNLOCK_MUTEX(rb
->Mutex
);
1989 * Create a new combined depth/stencil renderbuffer for implementing
1990 * the GL_EXT_packed_depth_stencil extension.
1991 * \return new depth/stencil renderbuffer
1993 struct gl_renderbuffer
*
1994 _mesa_new_depthstencil_renderbuffer(GLcontext
*ctx
, GLuint name
)
1996 struct gl_renderbuffer
*dsrb
;
1998 dsrb
= _mesa_new_renderbuffer(ctx
, name
);
2002 /* init fields not covered by _mesa_new_renderbuffer() */
2003 dsrb
->InternalFormat
= GL_DEPTH24_STENCIL8_EXT
;
2004 dsrb
->Format
= MESA_FORMAT_Z24_S8
;
2005 dsrb
->AllocStorage
= _mesa_soft_renderbuffer_storage
;